Agent Manager commited on
Commit
4a68cda
·
1 Parent(s): 0d13486

Skip OpenCode title generation in managed runs

Browse files
Files changed (2) hide show
  1. server/default-agent.js +29 -2
  2. test/default-agent.js +8 -2
server/default-agent.js CHANGED
@@ -309,7 +309,7 @@ async function runOpenCode(username, accessToken, prompt) {
309
  try {
310
  ;({ stdout } = await execFileAsync(
311
  OPENCODE_BIN,
312
- ['run', '--pure', '--auto', '--format', 'json', '--model', OPENCODE_MODEL, '--dir', dirs.workspace, prompt],
313
  { env, timeout: RUN_TIMEOUT_MS, maxBuffer: 6 * 1024 * 1024 }
314
  ))
315
  } catch (err) {
@@ -330,6 +330,23 @@ async function runOpenCode(username, accessToken, prompt) {
330
  return parts.join('\n')
331
  }
332
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  async function withRunSlot(run) {
334
  if (activeRuns >= MAX_CONCURRENT_RUNS) {
335
  await new Promise(resolve => runWaiters.push(resolve))
@@ -393,7 +410,17 @@ export function openCodeProcessSummary(err, secrets = []) {
393
  if (counts.size) details.push(`events=${[...counts].map(([type, count]) => `${type}:${count}`).join(',')}`)
394
  if (textParts) details.push(`text_parts=${textParts}`)
395
  if (providerErrors.length) details.push(`provider=${providerErrors.join(' | ')}`)
396
- const stderrBytes = Buffer.byteLength(String(err?.stderr || ''))
 
 
 
 
 
 
 
 
 
 
397
  if (stderrBytes) details.push(`stderr_bytes=${stderrBytes}`)
398
  if (!details.length) details.push(`process_error=${err?.name || 'unknown'}`)
399
  return safeError(details.join('; '), secrets)
 
309
  try {
310
  ;({ stdout } = await execFileAsync(
311
  OPENCODE_BIN,
312
+ openCodeArgs(dirs.workspace, prompt),
313
  { env, timeout: RUN_TIMEOUT_MS, maxBuffer: 6 * 1024 * 1024 }
314
  ))
315
  } catch (err) {
 
330
  return parts.join('\n')
331
  }
332
 
333
+ export function openCodeArgs(workspace, prompt) {
334
+ return [
335
+ 'run',
336
+ '--pure',
337
+ '--auto',
338
+ '--format', 'json',
339
+ '--print-logs',
340
+ '--log-level', 'INFO',
341
+ // Without an explicit title OpenCode makes a hidden preliminary model
342
+ // request before the actual task. That call can hang in headless workers.
343
+ '--title', 'Cowrite task',
344
+ '--model', OPENCODE_MODEL,
345
+ '--dir', workspace,
346
+ prompt,
347
+ ]
348
+ }
349
+
350
  async function withRunSlot(run) {
351
  if (activeRuns >= MAX_CONCURRENT_RUNS) {
352
  await new Promise(resolve => runWaiters.push(resolve))
 
410
  if (counts.size) details.push(`events=${[...counts].map(([type, count]) => `${type}:${count}`).join(',')}`)
411
  if (textParts) details.push(`text_parts=${textParts}`)
412
  if (providerErrors.length) details.push(`provider=${providerErrors.join(' | ')}`)
413
+ const stderr = String(err?.stderr || '')
414
+ const stagePatterns = [
415
+ ['creating instance', 'instance'],
416
+ ['bootstrapping', 'bootstrap'],
417
+ ['event connected', 'event_connected'],
418
+ ['llm runtime selected', 'llm_selected'],
419
+ ['message=process ', 'task_processing'],
420
+ ]
421
+ const stages = stagePatterns.filter(([pattern]) => stderr.includes(pattern)).map(([, stage]) => stage)
422
+ if (stages.length) details.push(`stages=${stages.join(',')}`)
423
+ const stderrBytes = Buffer.byteLength(stderr)
424
  if (stderrBytes) details.push(`stderr_bytes=${stderrBytes}`)
425
  if (!details.length) details.push(`process_error=${err?.name || 'unknown'}`)
426
  return safeError(details.join('; '), secrets)
test/default-agent.js CHANGED
@@ -5,7 +5,7 @@ import path from 'node:path'
5
 
6
  const data = fs.mkdtempSync(path.join(os.tmpdir(), 'cowrite-default-agent-'))
7
  process.env.DATA_DIR = data
8
- const { defaultAgentHandle, ensureDefaultAgent, openCodeProcessSummary, parseAgentAnswer, prepareOpenCode, safeError } = await import('../server/default-agent.js')
9
 
10
  const agents = {
11
  'alice-cowrite': { owner: 'someone-else' },
@@ -34,6 +34,11 @@ assert.equal(config.permission.websearch, 'allow')
34
  assert.equal(config.permission.webfetch, 'deny')
35
  assert.equal(config.provider['cowrite-hf'].options.apiKey, '{env:HF_OAUTH_TOKEN}', 'config references the in-memory token by environment name')
36
 
 
 
 
 
 
37
  const secret = 'hf_oauth_secret-value_with-more'
38
  assert.equal(safeError(new Error(`provider rejected ${secret}`), [secret]).includes('secret-value'), false)
39
  assert.equal(safeError(new Error('provider rejected hf_oauth_tail-with_more')).includes('tail'), false)
@@ -46,11 +51,12 @@ const processSummary = openCodeProcessSummary({
46
  JSON.stringify({ type: 'text', part: { text: 'private document output' } }),
47
  JSON.stringify({ type: 'error', error: { data: { statusCode: 429, message: `retry ${secret}` } } }),
48
  ].join('\n'),
49
- stderr: 'private stderr',
50
  }, [secret])
51
  assert.match(processSummary, /timeout_or_kill/)
52
  assert.match(processSummary, /events=step_start:1,text:1,error:1/)
53
  assert.match(processSummary, /provider=429 retry \[redacted\]/)
 
54
  assert.doesNotMatch(processSummary, /private document output|private stderr|secret-value/)
55
 
56
  assert.deepEqual(parseAgentAnswer('```json\n{"reply":"Done","suggestions":[],"dismiss":false}\n```'), {
 
5
 
6
  const data = fs.mkdtempSync(path.join(os.tmpdir(), 'cowrite-default-agent-'))
7
  process.env.DATA_DIR = data
8
+ const { defaultAgentHandle, ensureDefaultAgent, openCodeArgs, openCodeProcessSummary, parseAgentAnswer, prepareOpenCode, safeError } = await import('../server/default-agent.js')
9
 
10
  const agents = {
11
  'alice-cowrite': { owner: 'someone-else' },
 
34
  assert.equal(config.permission.webfetch, 'deny')
35
  assert.equal(config.provider['cowrite-hf'].options.apiKey, '{env:HF_OAUTH_TOKEN}', 'config references the in-memory token by environment name')
36
 
37
+ const commandArgs = openCodeArgs('/isolated/workspace', 'private prompt')
38
+ assert.deepEqual(commandArgs.slice(0, 4), ['run', '--pure', '--auto', '--format'])
39
+ assert.equal(commandArgs[commandArgs.indexOf('--title') + 1], 'Cowrite task')
40
+ assert.equal(commandArgs.at(-1), 'private prompt')
41
+
42
  const secret = 'hf_oauth_secret-value_with-more'
43
  assert.equal(safeError(new Error(`provider rejected ${secret}`), [secret]).includes('secret-value'), false)
44
  assert.equal(safeError(new Error('provider rejected hf_oauth_tail-with_more')).includes('tail'), false)
 
51
  JSON.stringify({ type: 'text', part: { text: 'private document output' } }),
52
  JSON.stringify({ type: 'error', error: { data: { statusCode: 429, message: `retry ${secret}` } } }),
53
  ].join('\n'),
54
+ stderr: 'message="creating instance"\nmessage="llm runtime selected" private stderr',
55
  }, [secret])
56
  assert.match(processSummary, /timeout_or_kill/)
57
  assert.match(processSummary, /events=step_start:1,text:1,error:1/)
58
  assert.match(processSummary, /provider=429 retry \[redacted\]/)
59
+ assert.match(processSummary, /stages=instance,llm_selected/)
60
  assert.doesNotMatch(processSummary, /private document output|private stderr|secret-value/)
61
 
62
  assert.deepEqual(parseAgentAnswer('```json\n{"reply":"Done","suggestions":[],"dismiss":false}\n```'), {