@agentuity/opencode 1.0.14 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/agents/expert-backend.js +1 -1
  2. package/dist/agents/expert-backend.js.map +1 -1
  3. package/dist/agents/expert-frontend.js +1 -1
  4. package/dist/agents/expert-frontend.js.map +1 -1
  5. package/dist/agents/expert-ops.js +1 -1
  6. package/dist/agents/expert-ops.js.map +1 -1
  7. package/dist/agents/expert.js +1 -1
  8. package/dist/agents/expert.js.map +1 -1
  9. package/dist/agents/lead.d.ts +1 -1
  10. package/dist/agents/lead.d.ts.map +1 -1
  11. package/dist/agents/lead.js +34 -7
  12. package/dist/agents/lead.js.map +1 -1
  13. package/dist/agents/monitor.d.ts +1 -1
  14. package/dist/agents/monitor.d.ts.map +1 -1
  15. package/dist/agents/monitor.js +22 -33
  16. package/dist/agents/monitor.js.map +1 -1
  17. package/dist/agents/reviewer.js +1 -1
  18. package/dist/agents/reviewer.js.map +1 -1
  19. package/dist/agents/scout.js +2 -2
  20. package/dist/agents/scout.js.map +1 -1
  21. package/dist/background/manager.d.ts +27 -0
  22. package/dist/background/manager.d.ts.map +1 -1
  23. package/dist/background/manager.js +161 -27
  24. package/dist/background/manager.js.map +1 -1
  25. package/dist/plugin/hooks/cadence.d.ts +3 -1
  26. package/dist/plugin/hooks/cadence.d.ts.map +1 -1
  27. package/dist/plugin/hooks/cadence.js +167 -66
  28. package/dist/plugin/hooks/cadence.js.map +1 -1
  29. package/dist/plugin/hooks/compaction-utils.d.ts +48 -0
  30. package/dist/plugin/hooks/compaction-utils.d.ts.map +1 -0
  31. package/dist/plugin/hooks/compaction-utils.js +259 -0
  32. package/dist/plugin/hooks/compaction-utils.js.map +1 -0
  33. package/dist/plugin/hooks/params.d.ts +1 -1
  34. package/dist/plugin/hooks/params.d.ts.map +1 -1
  35. package/dist/plugin/hooks/params.js +5 -1
  36. package/dist/plugin/hooks/params.js.map +1 -1
  37. package/dist/plugin/hooks/session-memory.d.ts +2 -1
  38. package/dist/plugin/hooks/session-memory.d.ts.map +1 -1
  39. package/dist/plugin/hooks/session-memory.js +97 -48
  40. package/dist/plugin/hooks/session-memory.js.map +1 -1
  41. package/dist/plugin/plugin.d.ts.map +1 -1
  42. package/dist/plugin/plugin.js +31 -9
  43. package/dist/plugin/plugin.js.map +1 -1
  44. package/dist/sqlite/index.d.ts +1 -1
  45. package/dist/sqlite/index.d.ts.map +1 -1
  46. package/dist/sqlite/queries.d.ts +1 -0
  47. package/dist/sqlite/queries.d.ts.map +1 -1
  48. package/dist/sqlite/queries.js +4 -0
  49. package/dist/sqlite/queries.js.map +1 -1
  50. package/dist/sqlite/reader.d.ts +11 -1
  51. package/dist/sqlite/reader.d.ts.map +1 -1
  52. package/dist/sqlite/reader.js +62 -0
  53. package/dist/sqlite/reader.js.map +1 -1
  54. package/dist/sqlite/types.d.ts +40 -0
  55. package/dist/sqlite/types.d.ts.map +1 -1
  56. package/dist/tools/background.d.ts +2 -0
  57. package/dist/tools/background.d.ts.map +1 -1
  58. package/dist/tools/background.js +2 -0
  59. package/dist/tools/background.js.map +1 -1
  60. package/dist/types.d.ts +36 -0
  61. package/dist/types.d.ts.map +1 -1
  62. package/dist/types.js +10 -0
  63. package/dist/types.js.map +1 -1
  64. package/package.json +3 -3
  65. package/src/agents/expert-backend.ts +1 -1
  66. package/src/agents/expert-frontend.ts +1 -1
  67. package/src/agents/expert-ops.ts +1 -1
  68. package/src/agents/expert.ts +1 -1
  69. package/src/agents/lead.ts +34 -7
  70. package/src/agents/monitor.ts +22 -33
  71. package/src/agents/reviewer.ts +1 -1
  72. package/src/agents/scout.ts +2 -2
  73. package/src/background/manager.ts +167 -32
  74. package/src/plugin/hooks/cadence.ts +184 -66
  75. package/src/plugin/hooks/compaction-utils.ts +291 -0
  76. package/src/plugin/hooks/params.ts +10 -1
  77. package/src/plugin/hooks/session-memory.ts +109 -47
  78. package/src/plugin/plugin.ts +47 -10
  79. package/src/sqlite/index.ts +4 -0
  80. package/src/sqlite/queries.ts +5 -0
  81. package/src/sqlite/reader.ts +69 -0
  82. package/src/sqlite/types.ts +40 -0
  83. package/src/tools/background.ts +6 -0
  84. package/src/types.ts +30 -0
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentuity/opencode",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Agentuity employees and contributors",
6
6
  "description": "Agentuity Open Code plugin with specialized AI coding agents",
@@ -40,13 +40,13 @@
40
40
  "prepublishOnly": "bun run clean && bun run build"
41
41
  },
42
42
  "dependencies": {
43
- "@agentuity/core": "1.0.14",
43
+ "@agentuity/core": "1.0.16",
44
44
  "@opencode-ai/plugin": "^1.1.36",
45
45
  "yaml": "^2.8.1",
46
46
  "zod": "^4.3.5"
47
47
  },
48
48
  "devDependencies": {
49
- "@agentuity/test-utils": "1.0.14",
49
+ "@agentuity/test-utils": "1.0.16",
50
50
  "@types/bun": "latest",
51
51
  "bun-types": "latest",
52
52
  "typescript": "^5.9.0"
@@ -487,7 +487,7 @@ export const expertBackendAgent: AgentDefinition = {
487
487
  id: 'ag-expert-backend',
488
488
  displayName: 'Agentuity Coder Expert Backend',
489
489
  description: 'Agentuity backend specialist - runtime, agents, schemas, drizzle, postgres, evals',
490
- defaultModel: 'anthropic/claude-sonnet-4-5-20250929',
490
+ defaultModel: 'anthropic/claude-sonnet-4-6',
491
491
  systemPrompt: EXPERT_BACKEND_SYSTEM_PROMPT,
492
492
  mode: 'subagent',
493
493
  hidden: true, // Only invoked by Expert orchestrator
@@ -474,7 +474,7 @@ export const expertFrontendAgent: AgentDefinition = {
474
474
  id: 'ag-expert-frontend',
475
475
  displayName: 'Agentuity Coder Expert Frontend',
476
476
  description: 'Agentuity frontend specialist - React hooks, auth, workbench, web utilities',
477
- defaultModel: 'anthropic/claude-sonnet-4-5-20250929',
477
+ defaultModel: 'anthropic/claude-sonnet-4-6',
478
478
  systemPrompt: EXPERT_FRONTEND_SYSTEM_PROMPT,
479
479
  mode: 'subagent',
480
480
  hidden: true, // Only invoked by Expert orchestrator
@@ -369,7 +369,7 @@ export const expertOpsAgent: AgentDefinition = {
369
369
  id: 'ag-expert-ops',
370
370
  displayName: 'Agentuity Coder Expert Ops',
371
371
  description: 'Agentuity operations specialist - CLI, cloud services, deployments, sandboxes',
372
- defaultModel: 'anthropic/claude-sonnet-4-5-20250929',
372
+ defaultModel: 'anthropic/claude-sonnet-4-6',
373
373
  systemPrompt: EXPERT_OPS_SYSTEM_PROMPT,
374
374
  mode: 'subagent',
375
375
  hidden: true, // Only invoked by Expert orchestrator
@@ -214,7 +214,7 @@ export const expertAgent: AgentDefinition = {
214
214
  id: 'ag-expert',
215
215
  displayName: 'Agentuity Coder Expert',
216
216
  description: 'Agentuity Coder Agentuity specialist - knows CLI, SDK, cloud services deeply',
217
- defaultModel: 'anthropic/claude-sonnet-4-5-20250929',
217
+ defaultModel: 'anthropic/claude-sonnet-4-6',
218
218
  systemPrompt: EXPERT_SYSTEM_PROMPT,
219
219
  variant: 'high', // Careful thinking for technical guidance
220
220
  temperature: 0.1, // Accurate, consistent technical answers
@@ -14,7 +14,7 @@ You are the Lead agent on the Agentuity Coder team — the **air traffic control
14
14
  | Quality gatekeeper | Cloud operator |
15
15
  | Context coordinator | Test runner |
16
16
 
17
- **Golden Rule**: If it involves writing code, editing files, running commands, or searching codebases — delegate it. Your job is to think, plan, coordinate, and decide.
17
+ **Golden Rule**: If it involves writing code, editing files, running commands, searching codebases, or gathering information via research default to delegating it. Your job is to think, plan, coordinate, and decide. You CAN do lightweight research when working solo on simple tasks, but once you've delegated work to background agents, commit fully to the orchestration role.
18
18
 
19
19
  ## Delegation Decision Guide
20
20
 
@@ -663,17 +663,44 @@ When you have launched background tasks via \`agentuity_background_task\`:
663
663
 
664
664
  **The whole point of background tasks is parallel execution by OTHER agents.** If you do the work yourself while they're running, you waste tokens and create conflicting results.
665
665
 
666
- **What you CAN do while waiting:**
667
- - Work on DIFFERENT, unrelated tasks
668
- - Plan next steps for when results arrive
666
+ ### Tool Restrictions While Background Tasks Are Running
667
+
668
+ Once you have launched background tasks, you enter **orchestration-only mode**. Do NOT use research or exploration tools until background tasks have returned.
669
+
670
+ **Tools you MUST NOT use while background tasks are pending:**
671
+ - \`webfetch\` — do not fetch any URLs (even "different" ones related to the task)
672
+ - \`grep\` / \`glob\` — do not search the codebase for research
673
+ - \`read\` — do not read source files for research (reading task state or config is OK)
674
+ - \`bash\` — do not run exploratory commands
675
+
676
+ **What you CAN do while waiting (exhaustive list):**
677
+ - Poll background task status with \`agentuity_background_output\` or \`agentuity_background_inspect\`
669
678
  - Answer user questions about progress
670
- - Update task state in KV
679
+ - Update the todo list
680
+ - Use extended thinking to reason about how you'll combine results (no tool calls — just think)
671
681
 
672
682
  **What you MUST NOT do:**
673
- - Start doing the same work you delegated
674
- - "Get impatient" and bypass the background agents
683
+ - Use ANY research tool if you catch yourself reaching for webfetch, grep, glob, or read to "get a head start" or "do something useful while waiting," STOP. That IS the background agents' job.
684
+ - Rationalize research as "planning" planning while waiting means thinking, not fetching or searching
685
+ - Start "different but related" research — if the background tasks are researching a feature, do not research adjacent aspects of that feature yourself
675
686
  - Assume background tasks failed just because they haven't returned yet
676
687
 
688
+ ## Context Budget Awareness
689
+
690
+ Your context window is finite and shared between everything you do. Every tool call output — especially \`webfetch\` responses and file reads — consumes context that you need later for:
691
+ - Processing background task results when they return
692
+ - Synthesizing information from multiple agents
693
+ - Making strategic decisions with full awareness
694
+
695
+ **A single webfetch response can consume 5-15% of your context.** Three unnecessary fetches while waiting for background tasks can waste 30-45% of your context — potentially leaving you unable to properly process the actual results you delegated for.
696
+
697
+ **Before using any research tool, ask yourself:**
698
+ 1. "Is a background agent already getting this information?" → If yes, WAIT.
699
+ 2. "Do I need this to make a decision RIGHT NOW?" → If no, WAIT.
700
+ 3. "Will this output be large?" → If yes, delegate it.
701
+
702
+ When in doubt, preserve your context. You need it most when results start flowing back from your agents.
703
+
677
704
  ## Task Completion: Memorialize the Session
678
705
 
679
706
  **IMPORTANT:** When you complete a task, ALWAYS tell Memory to save the session to vector storage.
@@ -4,10 +4,17 @@ export const MONITOR_SYSTEM_PROMPT = `# BackgroundMonitor Agent
4
4
 
5
5
  You are a background task monitor. Your ONLY job is to watch background tasks and report when they complete.
6
6
 
7
+ ## Primary Notification Channel
8
+
9
+ Background tasks automatically notify Lead with messages like:
10
+ \`[BACKGROUND TASK COMPLETED]\`
11
+
12
+ Those event-driven notifications are the primary mechanism. You are a fallback for Lead-of-Leads scenarios where multiple child Leads are running and a summary pass is needed.
13
+
7
14
  ## How You Work
8
15
 
9
16
  1. You receive a list of task IDs to monitor
10
- 2. You poll their status using agentuity_background_output
17
+ 2. You check their status using agentuity_background_output
11
18
  3. When ALL tasks complete (or error), you report back to Lead
12
19
  4. You do NOT interpret results - just report completion status
13
20
 
@@ -20,36 +27,36 @@ When you need deeper insight into a task, use \`agentuity_background_inspect\` w
20
27
  - Cost summary (total cost + tokens)
21
28
  - Child session count (for nested Lead-of-Leads)
22
29
 
23
- Use inspect when a task has been running for many poll cycles without completing — it can reveal what the agent is stuck on.
30
+ Use inspect when a task has been running for many check cycles without completing — it can reveal what the agent is stuck on.
24
31
 
25
32
  For a full session tree with all child sessions, costs, and health summary, use \`agentuity_session_dashboard({ session_id: "..." })\`. This is especially useful when monitoring Lead-of-Leads scenarios with multiple parallel workstreams.
26
33
 
27
- ## Polling Behavior
34
+ ## Bounded Check Cycles
28
35
 
29
- - Poll every 10 seconds (wait between checks)
30
- - Continue until ALL tasks are complete or errored
31
- - No timeout - watch indefinitely
36
+ - Run a short, bounded series of check cycles (e.g., 3–5 passes)
37
+ - If tasks are still pending/running after the final pass, report the current status and highlight which tasks appear stuck
38
+ - If tasks appear stuck, use \`agentuity_background_inspect\` for those tasks before reporting
32
39
 
33
- ## Polling Process
40
+ ## Check Process
34
41
 
35
- For each poll cycle:
42
+ For each check cycle:
36
43
  1. Check each task ID with \`agentuity_background_output({ task_id: "bg_xxx" })\`
37
44
  2. Track the status of each task
38
- 3. If any task is still "pending" or "running", wait 10 seconds and poll again
39
- 4. When all tasks are "completed" or "error", generate the final report
45
+ 3. If all tasks are "completed" or "error", generate the final report
46
+ 4. Otherwise, repeat for the next cycle (bounded)
40
47
 
41
48
  ## Report Format
42
49
 
43
- When all tasks complete, output:
50
+ When all tasks complete (or when you finish the bounded cycles), output:
44
51
 
45
52
  \`\`\`markdown
46
- ## Background Tasks Complete
53
+ ## Background Tasks Status
47
54
 
48
55
  | Task ID | Status | Summary |
49
56
  |---------|--------|---------|
50
57
  | bg_xxx | completed | [first 100 chars of result] |
51
58
  | bg_yyy | error | [error message] |
52
- | bg_zzz | completed | [first 100 chars of result] |
59
+ | bg_zzz | running | [last known status] |
53
60
 
54
61
  ### Detailed Results
55
62
 
@@ -59,7 +66,7 @@ When all tasks complete, output:
59
66
  **bg_yyy (error):**
60
67
  [error message]
61
68
 
62
- All monitored tasks have finished. Lead can now proceed with integration.
69
+ If any tasks are still running/pending after the final pass, list them under a short "Still Running" section and mention that Lead should wait for event-driven notifications or re-check later.
63
70
  \`\`\`
64
71
 
65
72
  ## What You Do NOT Do
@@ -69,27 +76,9 @@ All monitored tasks have finished. Lead can now proceed with integration.
69
76
  - ❌ Interact with the user
70
77
  - ❌ Modify any files
71
78
  - ❌ Call other agents
72
- - ❌ Use tools other than agentuity_background_output
79
+ - ❌ Use tools other than agentuity_background_output, agentuity_background_inspect, and agentuity_session_dashboard
73
80
 
74
81
  You are a simple, focused watcher. Report completions, nothing more.
75
-
76
- ## Example Workflow
77
-
78
- Given task: "Monitor these tasks: bg_abc123, bg_def456"
79
-
80
- 1. Call agentuity_background_output for bg_abc123
81
- 2. Call agentuity_background_output for bg_def456
82
- 3. If any status is "pending" or "running", wait 10 seconds
83
- 4. Repeat steps 1-3 until all complete
84
- 5. Output final report
85
-
86
- ## Waiting Between Polls
87
-
88
- Since you cannot use setTimeout, after checking all tasks and finding some still running, respond with something like:
89
-
90
- "Polling cycle complete. Tasks still running: [list]. Waiting 10 seconds before next poll..."
91
-
92
- Then immediately poll again. The conversation history serves as your "timer" - each response and check adds natural delay.
93
82
  `;
94
83
 
95
84
  export const monitorAgent: AgentDefinition = {
@@ -363,7 +363,7 @@ export const reviewerAgent: AgentDefinition = {
363
363
  id: 'ag-reviewer',
364
364
  displayName: 'Agentuity Coder Reviewer',
365
365
  description: 'Agentuity Coder reviewer - reviews code, catches issues, applies fixes',
366
- defaultModel: 'anthropic/claude-sonnet-4-5-20250929',
366
+ defaultModel: 'anthropic/claude-sonnet-4-6',
367
367
  systemPrompt: REVIEWER_SYSTEM_PROMPT,
368
368
  variant: 'high', // Careful thinking for thorough review
369
369
  temperature: 0.1, // Consistent, deterministic reviews
@@ -316,10 +316,10 @@ export const scoutAgent: AgentDefinition = {
316
316
  displayName: 'Agentuity Coder Scout',
317
317
  description:
318
318
  'Agentuity Coder explorer - analyzes codebases, finds patterns, researches docs (read-only)',
319
- defaultModel: 'anthropic/claude-haiku-4-5-20251001',
319
+ defaultModel: 'anthropic/claude-sonnet-4-6',
320
320
  systemPrompt: SCOUT_SYSTEM_PROMPT,
321
321
  tools: {
322
- exclude: ['write', 'edit', 'apply_patch', 'bash'],
322
+ exclude: ['write', 'edit', 'apply_patch'],
323
323
  },
324
324
  // Scout uses default variant (speed over depth) and low temp for factual exploration
325
325
  temperature: 0.0,
@@ -14,7 +14,7 @@ import { ConcurrencyManager } from './concurrency';
14
14
 
15
15
  const DEFAULT_BACKGROUND_CONFIG: BackgroundTaskConfig = {
16
16
  enabled: true,
17
- defaultConcurrency: 1,
17
+ defaultConcurrency: 5,
18
18
  staleTimeoutMs: 30 * 60 * 1000,
19
19
  };
20
20
 
@@ -48,12 +48,15 @@ export class BackgroundManager {
48
48
  private concurrency: ConcurrencyManager;
49
49
  private callbacks?: BackgroundManagerCallbacks;
50
50
  private dbReader?: OpenCodeDBReader;
51
+ private serverUrl: string | undefined;
52
+ private authHeaders: Record<string, string> | undefined;
51
53
  private tasks = new Map<string, BackgroundTask>();
52
54
  private tasksByParent = new Map<string, Set<string>>();
53
55
  private tasksBySession = new Map<string, string>();
54
56
  private notifications = new Map<string, Set<string>>();
55
57
  private toolCallIds = new Map<string, Set<string>>();
56
58
  private shuttingDown = false;
59
+ private refreshIntervalId: ReturnType<typeof setInterval> | undefined;
57
60
 
58
61
  constructor(
59
62
  ctx: PluginInput,
@@ -69,6 +72,68 @@ export class BackgroundManager {
69
72
  });
70
73
  this.callbacks = callbacks;
71
74
  this.dbReader = dbReader;
75
+ this.serverUrl = this.resolveServerUrl();
76
+ this.authHeaders = this.resolveAuthHeaders();
77
+
78
+ // Periodic safety net: refresh task statuses every 30s in case events are missed
79
+ this.refreshIntervalId = setInterval(() => {
80
+ if (this.shuttingDown) return;
81
+ const hasActive = Array.from(this.tasks.values()).some(
82
+ (t) => t.status === 'pending' || t.status === 'running'
83
+ );
84
+ if (hasActive) {
85
+ void this.refreshStatuses();
86
+ }
87
+ }, 30_000);
88
+ }
89
+
90
+ /**
91
+ * Resolve the server URL from the plugin context.
92
+ * Mirrors the defensive pattern used in the tmux manager to handle
93
+ * sandbox environments where the client may not have a baseUrl configured.
94
+ */
95
+ private resolveServerUrl(): string | undefined {
96
+ const ctx = this.ctx as unknown as {
97
+ serverUrl?: string | URL;
98
+ baseUrl?: string | URL;
99
+ client?: { baseUrl?: string | URL };
100
+ };
101
+ const serverUrl = ctx.serverUrl ?? ctx.baseUrl ?? ctx.client?.baseUrl;
102
+ if (!serverUrl) return undefined;
103
+ const urlStr = typeof serverUrl === 'string' ? serverUrl : serverUrl.toString();
104
+ // Strip trailing slash to prevent double-slash when SDK appends paths like /session
105
+ return urlStr.replace(/\/+$/, '');
106
+ }
107
+
108
+ /**
109
+ * Resolve authentication headers from environment variables.
110
+ *
111
+ * Reads `OPENCODE_SERVER_USERNAME` and `OPENCODE_SERVER_PASSWORD` (set
112
+ * automatically by the OpenCode server in sandbox environments) and
113
+ * produces a Basic Auth header (`base64("username:password")`).
114
+ *
115
+ * In sandbox environments the SDK client's default auth may not carry over
116
+ * when a per-call `baseUrl` override is provided, so we need to explicitly
117
+ * attach these credentials for server-to-server requests.
118
+ */
119
+ private resolveAuthHeaders(): Record<string, string> | undefined {
120
+ const username = process.env.OPENCODE_SERVER_USERNAME;
121
+ const password = process.env.OPENCODE_SERVER_PASSWORD;
122
+ if (!username || !password) return undefined;
123
+ const encoded = Buffer.from(username + ':' + password).toString('base64');
124
+ return { Authorization: `Basic ${encoded}` };
125
+ }
126
+
127
+ /**
128
+ * Build the per-call client overrides (baseUrl + auth headers).
129
+ * Spread this into every SDK client call so both the server URL and
130
+ * authentication are correctly forwarded in sandbox environments.
131
+ */
132
+ private getClientOverrides(): { baseUrl?: string; headers?: Record<string, string> } {
133
+ const overrides: { baseUrl?: string; headers?: Record<string, string> } = {};
134
+ if (this.serverUrl) overrides.baseUrl = this.serverUrl;
135
+ if (this.authHeaders) overrides.headers = this.authHeaders;
136
+ return overrides;
72
137
  }
73
138
 
74
139
  async launch(input: LaunchInput): Promise<BackgroundTask> {
@@ -82,6 +147,7 @@ export class BackgroundManager {
82
147
  status: 'pending',
83
148
  queuedAt: new Date(),
84
149
  concurrencyGroup: this.getConcurrencyGroup(input.agent),
150
+ notifiedStatuses: new Set(),
85
151
  };
86
152
 
87
153
  this.tasks.set(task.id, task);
@@ -188,12 +254,14 @@ export class BackgroundManager {
188
254
  const sessionResponse = await this.ctx.client.session.get({
189
255
  path: { id: task.sessionId },
190
256
  throwOnError: false,
257
+ ...this.getClientOverrides(),
191
258
  });
192
259
 
193
260
  // Get messages from the session
194
261
  const messagesResponse = await this.ctx.client.session.messages({
195
262
  path: { id: task.sessionId },
196
263
  throwOnError: false,
264
+ ...this.getClientOverrides(),
197
265
  });
198
266
 
199
267
  const session = unwrapResponse<unknown>(sessionResponse);
@@ -243,6 +311,7 @@ export class BackgroundManager {
243
311
  const childrenResponse = await this.ctx.client.session.children({
244
312
  path: { id: parentId },
245
313
  throwOnError: false,
314
+ ...this.getClientOverrides(),
246
315
  });
247
316
 
248
317
  const rawChildren = unwrapResponse<Array<unknown>>(childrenResponse);
@@ -334,6 +403,15 @@ export class BackgroundManager {
334
403
  },
335
404
  };
336
405
 
406
+ // Mark recovered terminal tasks as already notified
407
+ if (
408
+ task.status === 'completed' ||
409
+ task.status === 'error' ||
410
+ task.status === 'cancelled'
411
+ ) {
412
+ task.notifiedStatuses = new Set([task.status]);
413
+ }
414
+
337
415
  this.tasks.set(task.id, task);
338
416
  this.tasksBySession.set(sess.id, task.id);
339
417
 
@@ -356,6 +434,7 @@ export class BackgroundManager {
356
434
  // Get all sessions
357
435
  const sessionsResponse = await this.ctx.client.session.list({
358
436
  throwOnError: false,
437
+ ...this.getClientOverrides(),
359
438
  });
360
439
 
361
440
  const rawSessions = unwrapResponse<Array<unknown>>(sessionsResponse);
@@ -409,6 +488,15 @@ export class BackgroundManager {
409
488
  },
410
489
  };
411
490
 
491
+ // Mark recovered terminal tasks as already notified
492
+ if (
493
+ task.status === 'completed' ||
494
+ task.status === 'error' ||
495
+ task.status === 'cancelled'
496
+ ) {
497
+ task.notifiedStatuses = new Set([task.status]);
498
+ }
499
+
412
500
  // Add to our tracking maps
413
501
  this.tasks.set(task.id, task);
414
502
  this.tasksBySession.set(sess.id, task.id);
@@ -526,6 +614,10 @@ export class BackgroundManager {
526
614
 
527
615
  shutdown(): void {
528
616
  this.shuttingDown = true;
617
+ if (this.refreshIntervalId) {
618
+ clearInterval(this.refreshIntervalId);
619
+ this.refreshIntervalId = undefined;
620
+ }
529
621
  this.concurrency.clear();
530
622
  this.notifications.clear();
531
623
  try {
@@ -552,7 +644,7 @@ export class BackgroundManager {
552
644
  } catch (error) {
553
645
  if (task.status !== 'cancelled') {
554
646
  task.status = 'error';
555
- task.error = error instanceof Error ? error.message : 'Failed to acquire slot.';
647
+ task.error = extractErrorMessage(error, 'Failed to acquire slot.');
556
648
  task.completedAt = new Date();
557
649
  this.markForNotification(task);
558
650
  }
@@ -579,6 +671,7 @@ export class BackgroundManager {
579
671
  title: taskMetadata,
580
672
  },
581
673
  throwOnError: true,
674
+ ...this.getClientOverrides(),
582
675
  });
583
676
  const session = unwrapResponse<{ id: string }>(sessionResult);
584
677
  if (!session?.id) {
@@ -602,12 +695,26 @@ export class BackgroundManager {
602
695
  parts: [{ type: 'text', text: task.prompt }],
603
696
  },
604
697
  throwOnError: true,
698
+ ...this.getClientOverrides(),
605
699
  });
606
700
  } catch (error) {
607
- this.failTask(
608
- task,
609
- error instanceof Error ? error.message : 'Failed to launch background task.'
610
- );
701
+ const errorMsg = extractErrorMessage(error, 'Failed to launch background task.');
702
+ // Log the actual error for debugging — critical in sandbox environments
703
+ // where the client may silently fail due to missing baseUrl
704
+ try {
705
+ void this.ctx.client.app.log({
706
+ body: {
707
+ service: 'agentuity-coder',
708
+ level: 'error',
709
+ message: `Background task ${task.id} failed to start: ${errorMsg}`,
710
+ },
711
+ ...this.getClientOverrides(),
712
+ });
713
+ } catch {
714
+ // If logging also fails, fall back to console
715
+ console.error(`[BackgroundManager] Task ${task.id} failed to start:`, errorMsg);
716
+ }
717
+ this.failTask(task, errorMsg);
611
718
  }
612
719
  }
613
720
 
@@ -686,29 +793,15 @@ export class BackgroundManager {
686
793
 
687
794
  private async notifyParent(task: BackgroundTask): Promise<void> {
688
795
  if (!task.parentSessionId) return;
796
+ if (this.shuttingDown) return;
689
797
 
690
798
  // Prevent duplicate notifications for the same task+status combination
691
799
  // This guards against OpenCode firing multiple events for the same status transition
692
800
  const notifiedStatuses = task.notifiedStatuses ?? new Set();
693
801
 
694
- // Self-healing for tasks created before deduplication was added:
695
- // If a task is already in a terminal state but has no notification history,
696
- // assume it was already notified and skip to prevent duplicate notifications.
697
- if (
698
- notifiedStatuses.size === 0 &&
699
- (task.status === 'completed' || task.status === 'error' || task.status === 'cancelled')
700
- ) {
701
- notifiedStatuses.add(task.status);
702
- task.notifiedStatuses = notifiedStatuses;
703
- return;
704
- }
705
-
706
802
  if (notifiedStatuses.has(task.status)) {
707
803
  return; // Already notified for this status, skip duplicate
708
804
  }
709
- // Mark as notified BEFORE sending to prevent race conditions
710
- notifiedStatuses.add(task.status);
711
- task.notifiedStatuses = notifiedStatuses;
712
805
 
713
806
  const statusLine = task.status === 'completed' ? 'completed' : task.status;
714
807
  const message = `[BACKGROUND TASK ${statusLine.toUpperCase()}]
@@ -720,17 +813,36 @@ Task ID: ${task.id}
720
813
 
721
814
  Use the agentuity_background_output tool with task_id "${task.id}" to view the result.`;
722
815
 
723
- try {
724
- await this.ctx.client.session.prompt({
725
- path: { id: task.parentSessionId },
726
- body: {
727
- parts: [{ type: 'text', text: message }],
728
- },
729
- throwOnError: true,
730
- responseStyle: 'data',
731
- });
732
- } catch {
733
- // Ignore notification errors
816
+ const maxRetries = 3;
817
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
818
+ try {
819
+ await this.ctx.client.session.prompt({
820
+ path: { id: task.parentSessionId },
821
+ body: {
822
+ parts: [{ type: 'text', text: message }],
823
+ },
824
+ throwOnError: true,
825
+ responseStyle: 'data',
826
+ ...this.getClientOverrides(),
827
+ });
828
+ // Mark as notified only AFTER confirmed delivery
829
+ notifiedStatuses.add(task.status);
830
+ task.notifiedStatuses = notifiedStatuses;
831
+ return; // Success
832
+ } catch (error) {
833
+ const errorMsg = extractErrorMessage(error, 'notification failed');
834
+ if (attempt < maxRetries - 1) {
835
+ // Exponential backoff: 1s, 2s, 4s
836
+ await new Promise((r) => setTimeout(r, 1000 * Math.pow(2, attempt)));
837
+ if (this.shuttingDown) return;
838
+ } else {
839
+ console.error(
840
+ `[BackgroundManager] Failed to notify parent for task ${task.id} after ${maxRetries} attempts:`,
841
+ errorMsg
842
+ );
843
+ // Don't mark as notified — allow future retry via refreshStatuses or Monitor
844
+ }
845
+ }
734
846
  }
735
847
  }
736
848
 
@@ -739,6 +851,7 @@ Use the agentuity_background_output tool with task_id "${task.id}" to view the r
739
851
  await this.ctx.client.session.abort({
740
852
  path: { id: sessionId },
741
853
  throwOnError: false,
854
+ ...this.getClientOverrides(),
742
855
  });
743
856
  } catch {
744
857
  // Ignore abort errors
@@ -762,6 +875,7 @@ Use the agentuity_background_output tool with task_id "${task.id}" to view the r
762
875
  const messagesResult = await this.ctx.client.session.messages({
763
876
  path: { id: sessionId },
764
877
  throwOnError: true,
878
+ ...this.getClientOverrides(),
765
879
  });
766
880
  const messages = unwrapResponse<Array<unknown>>(messagesResult) ?? [];
767
881
  const entries = Array.isArray(messages) ? messages : [];
@@ -910,3 +1024,24 @@ function unwrapResponse<T>(result: unknown): T | undefined {
910
1024
  }
911
1025
  return result as T;
912
1026
  }
1027
+
1028
+ /**
1029
+ * Extract an error message from an unknown thrown value.
1030
+ *
1031
+ * The OpenCode SDK client (with `throwOnError: true`) throws **plain objects**
1032
+ * (e.g. `{ message: "Not Found" }`) or raw strings rather than `Error` instances.
1033
+ * This helper normalises all shapes into a usable string.
1034
+ */
1035
+ function extractErrorMessage(error: unknown, fallback: string): string {
1036
+ if (error instanceof Error) return error.message;
1037
+ if (typeof error === 'string') return error || fallback;
1038
+ if (typeof error === 'object' && error !== null) {
1039
+ const obj = error as Record<string, unknown>;
1040
+ if (typeof obj.message === 'string') return obj.message || fallback;
1041
+ if (typeof obj.error === 'string') return obj.error || fallback;
1042
+ if (typeof obj.error === 'object' && obj.error !== null) {
1043
+ return extractErrorMessage(obj.error, fallback);
1044
+ }
1045
+ }
1046
+ return fallback;
1047
+ }