@agentuity/opencode 1.0.19 → 1.0.21

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 (98) hide show
  1. package/dist/agents/expert-backend.d.ts +1 -1
  2. package/dist/agents/expert-backend.d.ts.map +1 -1
  3. package/dist/agents/expert-backend.js +0 -17
  4. package/dist/agents/expert-backend.js.map +1 -1
  5. package/dist/agents/expert.d.ts +1 -1
  6. package/dist/agents/expert.d.ts.map +1 -1
  7. package/dist/agents/expert.js +1 -1
  8. package/dist/agents/index.d.ts.map +1 -1
  9. package/dist/agents/index.js +0 -2
  10. package/dist/agents/index.js.map +1 -1
  11. package/dist/agents/lead.d.ts +1 -1
  12. package/dist/agents/lead.d.ts.map +1 -1
  13. package/dist/agents/lead.js +25 -145
  14. package/dist/agents/lead.js.map +1 -1
  15. package/dist/agents/scout.d.ts +1 -1
  16. package/dist/agents/scout.d.ts.map +1 -1
  17. package/dist/agents/scout.js +16 -0
  18. package/dist/agents/scout.js.map +1 -1
  19. package/dist/config/loader.d.ts.map +1 -1
  20. package/dist/config/loader.js +1 -33
  21. package/dist/config/loader.js.map +1 -1
  22. package/dist/index.d.ts +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/plugin/hooks/cadence.d.ts +1 -2
  26. package/dist/plugin/hooks/cadence.d.ts.map +1 -1
  27. package/dist/plugin/hooks/cadence.js +7 -33
  28. package/dist/plugin/hooks/cadence.js.map +1 -1
  29. package/dist/plugin/hooks/compaction-utils.d.ts.map +1 -1
  30. package/dist/plugin/hooks/compaction-utils.js +6 -13
  31. package/dist/plugin/hooks/compaction-utils.js.map +1 -1
  32. package/dist/plugin/hooks/session-memory.d.ts +1 -2
  33. package/dist/plugin/hooks/session-memory.d.ts.map +1 -1
  34. package/dist/plugin/hooks/session-memory.js +6 -29
  35. package/dist/plugin/hooks/session-memory.js.map +1 -1
  36. package/dist/plugin/plugin.d.ts.map +1 -1
  37. package/dist/plugin/plugin.js +8 -222
  38. package/dist/plugin/plugin.js.map +1 -1
  39. package/dist/sqlite/types.d.ts +0 -6
  40. package/dist/sqlite/types.d.ts.map +1 -1
  41. package/dist/tmux/manager.d.ts +4 -4
  42. package/dist/tmux/manager.js +4 -4
  43. package/dist/tmux/types.d.ts +1 -1
  44. package/dist/tools/index.d.ts +1 -1
  45. package/dist/tools/index.d.ts.map +1 -1
  46. package/dist/tools/index.js +1 -1
  47. package/dist/tools/index.js.map +1 -1
  48. package/dist/types.d.ts +2 -20
  49. package/dist/types.d.ts.map +1 -1
  50. package/dist/types.js +0 -9
  51. package/dist/types.js.map +1 -1
  52. package/package.json +3 -3
  53. package/src/agents/expert-backend.ts +0 -17
  54. package/src/agents/expert.ts +1 -1
  55. package/src/agents/index.ts +0 -2
  56. package/src/agents/lead.ts +25 -145
  57. package/src/agents/scout.ts +16 -0
  58. package/src/config/loader.ts +1 -45
  59. package/src/index.ts +0 -1
  60. package/src/plugin/hooks/cadence.ts +6 -39
  61. package/src/plugin/hooks/compaction-utils.ts +6 -12
  62. package/src/plugin/hooks/session-memory.ts +5 -35
  63. package/src/plugin/plugin.ts +7 -257
  64. package/src/sqlite/types.ts +0 -2
  65. package/src/tmux/manager.ts +4 -4
  66. package/src/tmux/types.ts +2 -2
  67. package/src/tools/index.ts +2 -9
  68. package/src/types.ts +0 -13
  69. package/dist/agents/monitor.d.ts +0 -4
  70. package/dist/agents/monitor.d.ts.map +0 -1
  71. package/dist/agents/monitor.js +0 -159
  72. package/dist/agents/monitor.js.map +0 -1
  73. package/dist/background/concurrency.d.ts +0 -36
  74. package/dist/background/concurrency.d.ts.map +0 -1
  75. package/dist/background/concurrency.js +0 -92
  76. package/dist/background/concurrency.js.map +0 -1
  77. package/dist/background/index.d.ts +0 -5
  78. package/dist/background/index.d.ts.map +0 -1
  79. package/dist/background/index.js +0 -4
  80. package/dist/background/index.js.map +0 -1
  81. package/dist/background/manager.d.ts +0 -123
  82. package/dist/background/manager.d.ts.map +0 -1
  83. package/dist/background/manager.js +0 -1075
  84. package/dist/background/manager.js.map +0 -1
  85. package/dist/background/types.d.ts +0 -90
  86. package/dist/background/types.d.ts.map +0 -1
  87. package/dist/background/types.js +0 -2
  88. package/dist/background/types.js.map +0 -1
  89. package/dist/tools/background.d.ts +0 -67
  90. package/dist/tools/background.d.ts.map +0 -1
  91. package/dist/tools/background.js +0 -95
  92. package/dist/tools/background.js.map +0 -1
  93. package/src/agents/monitor.ts +0 -161
  94. package/src/background/concurrency.ts +0 -116
  95. package/src/background/index.ts +0 -4
  96. package/src/background/manager.ts +0 -1215
  97. package/src/background/types.ts +0 -82
  98. package/src/tools/background.ts +0 -179
@@ -17,7 +17,6 @@ import { createCadenceHooks } from './hooks/cadence';
17
17
  import { createSessionMemoryHooks } from './hooks/session-memory';
18
18
  import { createCompletionHooks } from './hooks/completion';
19
19
  import type { AgentRole } from '../types';
20
- import { BackgroundManager } from '../background';
21
20
  import type { SessionTreeNode } from '../sqlite';
22
21
  import { OpenCodeDBReader } from '../sqlite';
23
22
  import { TmuxSessionManager } from '../tmux';
@@ -114,76 +113,18 @@ export async function createCoderPlugin(ctx: PluginInput): Promise<Hooks> {
114
113
  }),
115
114
  })
116
115
  : undefined;
117
- const backgroundManager = new BackgroundManager(
118
- ctx,
119
- coderConfig.background,
120
- {
121
- onSubagentSessionCreated: tmuxManager
122
- ? (event) => {
123
- void tmuxManager.onSessionCreated(event);
124
- }
125
- : undefined,
126
- onSubagentSessionDeleted: tmuxManager
127
- ? (event) => {
128
- void tmuxManager.onSessionDeleted(event);
129
- }
130
- : undefined,
131
- onShutdown: tmuxManager
132
- ? () => {
133
- void tmuxManager.cleanup();
134
- }
135
- : undefined,
136
- },
137
- dbReader
138
- );
139
-
140
- // Recover any background tasks from previous sessions
141
- // This allows tasks to survive plugin restarts
142
- void backgroundManager
143
- .recoverTasks()
144
- .then((count) => {
145
- if (count > 0) {
146
- ctx.client.app.log({
147
- body: {
148
- service: 'agentuity-coder',
149
- level: 'info',
150
- message: `Recovered ${count} background task(s) from previous sessions`,
151
- },
152
- });
153
- }
154
- })
155
- .catch((error) => {
156
- ctx.client.app.log({
157
- body: {
158
- service: 'agentuity-coder',
159
- level: 'warn',
160
- message: `Failed to recover background tasks: ${error}`,
161
- },
162
- });
163
- });
164
116
 
165
- // Create hooks that need backgroundManager for task reference injection during compaction
166
- const cadenceHooks = createCadenceHooks(
167
- ctx,
168
- coderConfig,
169
- backgroundManager,
170
- dbReader,
171
- lastUserMessages
172
- );
117
+ // Create hooks for session routing and compaction behavior
118
+ const cadenceHooks = createCadenceHooks(ctx, coderConfig, dbReader, lastUserMessages);
173
119
 
174
120
  // Session memory hooks handle checkpointing and compaction for non-Cadence sessions
175
121
  // Orchestration (deciding which module handles which session) happens below in the hooks
176
- const sessionMemoryHooks = createSessionMemoryHooks(
177
- ctx,
178
- coderConfig,
179
- backgroundManager,
180
- dbReader
181
- );
122
+ const sessionMemoryHooks = createSessionMemoryHooks(ctx, coderConfig, dbReader);
182
123
 
183
124
  const configHandler = createConfigHandler(coderConfig);
184
125
 
185
126
  // Create plugin tools using the @opencode-ai/plugin tool helper
186
- const tools = createTools(backgroundManager, dbReader);
127
+ const tools = createTools(dbReader);
187
128
 
188
129
  // Create a logger for shutdown handler
189
130
  const shutdownLogger = (message: string) =>
@@ -195,7 +136,7 @@ export async function createCoderPlugin(ctx: PluginInput): Promise<Hooks> {
195
136
  },
196
137
  });
197
138
 
198
- registerShutdownHandler(backgroundManager, tmuxManager, shutdownLogger, dbReader);
139
+ registerShutdownHandler(tmuxManager, shutdownLogger, dbReader);
199
140
 
200
141
  // Show startup toast (fire and forget, don't block)
201
142
  try {
@@ -245,10 +186,6 @@ export async function createCoderPlugin(ctx: PluginInput): Promise<Hooks> {
245
186
  }
246
187
  },
247
188
  event: async (input) => {
248
- const event = extractEventFromInput(input);
249
- if (event) {
250
- backgroundManager.handleEvent(event);
251
- }
252
189
  // Orchestrate: route to appropriate module based on session type
253
190
  const sessionId = extractSessionIdFromEvent(input);
254
191
  if (sessionId) {
@@ -628,7 +565,7 @@ $ARGUMENTS
628
565
  ## Lead-of-Leads (Parallel Work)
629
566
  If the task has **independent workstreams** that can run in parallel (e.g., "build auth, payments, and notifications"):
630
567
  1. Ask @Agentuity Coder Product to create PRD with workstreams
631
- 2. Spawn child Leads via \`agentuity_background_task\` for each workstream
568
+ 2. Spawn child Leads using the \`task\` tool (issue multiple task calls in a single response for parallel work)
632
569
  3. Each child Lead claims a workstream, works autonomously, marks done when complete
633
570
  4. Monitor progress via PRD workstream status
634
571
  5. Do integration work when all children complete
@@ -674,170 +611,10 @@ function normalizeBaseDir(path: string): string {
674
611
  return path.replace(/[\\/]+$/, '');
675
612
  }
676
613
 
677
- function createTools(
678
- backgroundManager: BackgroundManager,
679
- dbReader?: OpenCodeDBReader
680
- ): Hooks['tool'] {
614
+ function createTools(dbReader?: OpenCodeDBReader): Hooks['tool'] {
681
615
  // Use the schema from @opencode-ai/plugin's tool helper to avoid Zod version mismatches
682
616
  const s = tool.schema;
683
617
 
684
- const backgroundTask = tool({
685
- description: `Launch a task to run in the background. Use this for parallel execution of multiple independent tasks.
686
-
687
- IMPORTANT: Use this tool instead of the 'task' tool when:
688
- - You need to run multiple agents in parallel
689
- - Tasks are independent and don't need sequential execution
690
- - The user asks for "parallel", "background", or "concurrent" work`,
691
- args: {
692
- agent: s
693
- .enum([
694
- 'lead',
695
- 'scout',
696
- 'builder',
697
- 'architect',
698
- 'reviewer',
699
- 'memory',
700
- 'expert',
701
- 'runner',
702
- 'product',
703
- 'monitor',
704
- ])
705
- .describe('Agent role to run the task'),
706
- task: s.string().describe('Task prompt to run in the background'),
707
- description: s.string().optional().describe('Short description of the task'),
708
- },
709
- async execute(args, context) {
710
- const parentSessionId = context.sessionID;
711
- if (!parentSessionId) {
712
- return JSON.stringify({
713
- taskId: 'unknown',
714
- status: 'error',
715
- message: 'Missing session context for background task.',
716
- });
717
- }
718
-
719
- const agentName = resolveAgentName(args.agent as AgentRole);
720
- const bgTask = await backgroundManager.launch({
721
- description: args.description ?? args.task,
722
- prompt: args.task,
723
- agent: agentName,
724
- parentSessionId,
725
- parentMessageId: context.messageID,
726
- });
727
- return JSON.stringify({
728
- taskId: bgTask.id,
729
- status: bgTask.status,
730
- message:
731
- bgTask.status === 'error'
732
- ? (bgTask.error ?? 'Failed to launch background task.')
733
- : 'Background task launched.',
734
- });
735
- },
736
- });
737
-
738
- const backgroundOutput = tool({
739
- description: 'Retrieve output for a background task.',
740
- args: {
741
- task_id: s.string().describe('Background task ID'),
742
- },
743
- async execute(args) {
744
- const bgTask = backgroundManager.getTask(args.task_id);
745
- if (!bgTask) {
746
- return JSON.stringify({
747
- taskId: args.task_id,
748
- status: 'error',
749
- error: 'Task not found.',
750
- });
751
- }
752
- return JSON.stringify({
753
- taskId: bgTask.id,
754
- status: bgTask.status,
755
- result: bgTask.result,
756
- error: bgTask.error,
757
- });
758
- },
759
- });
760
-
761
- const backgroundCancel = tool({
762
- description: 'Cancel a running background task.',
763
- args: {
764
- task_id: s.string().describe('Background task ID'),
765
- },
766
- async execute(args) {
767
- const success = backgroundManager.cancel(args.task_id);
768
- return JSON.stringify({
769
- taskId: args.task_id,
770
- success,
771
- message: success ? 'Background task cancelled.' : 'Unable to cancel task.',
772
- });
773
- },
774
- });
775
-
776
- const backgroundInspect = tool({
777
- description: `Inspect a background task to see its session messages and current state. Useful for debugging or checking what a child agent is doing.`,
778
- args: {
779
- task_id: s.string().describe('Background task ID to inspect'),
780
- },
781
- async execute(args) {
782
- const inspection = await backgroundManager.inspectTask(args.task_id);
783
- if (!inspection) {
784
- return JSON.stringify({
785
- taskId: args.task_id,
786
- status: 'unknown',
787
- found: false,
788
- error: 'Task not found or session no longer exists.',
789
- });
790
- }
791
-
792
- const messages = inspection.messages ?? [];
793
- const enhanced =
794
- inspection.messageCount !== undefined ||
795
- inspection.activeTools !== undefined ||
796
- inspection.todos !== undefined ||
797
- inspection.costSummary !== undefined ||
798
- inspection.childSessionCount !== undefined;
799
-
800
- if (enhanced) {
801
- return JSON.stringify({
802
- taskId: inspection.taskId,
803
- status: inspection.status,
804
- found: true,
805
- messageCount: inspection.messageCount ?? messages.length,
806
- messages,
807
- lastActivity: inspection.lastActivity,
808
- activeTools: inspection.activeTools,
809
- todos: inspection.todos,
810
- costSummary: inspection.costSummary,
811
- childSessionCount: inspection.childSessionCount,
812
- });
813
- }
814
-
815
- // Extract last few messages for summary (fallback)
816
- const lastMessages = messages
817
- .slice(-3)
818
- .map((m) => {
819
- const parts = m.parts ?? [];
820
- const textParts = parts.filter(
821
- (p: unknown) => (p as { type?: string }).type === 'text'
822
- );
823
- return textParts
824
- .map((p: unknown) => ((p as { text?: string }).text ?? '').slice(0, 200))
825
- .join(' ')
826
- .slice(0, 300);
827
- })
828
- .filter(Boolean);
829
-
830
- return JSON.stringify({
831
- taskId: inspection.taskId,
832
- status: inspection.status,
833
- found: true,
834
- messageCount: messages.length,
835
- lastMessages,
836
- lastActivity: inspection.lastActivity,
837
- });
838
- },
839
- });
840
-
841
618
  const sessionDashboard = tool({
842
619
  description:
843
620
  'Inspect a parent session dashboard from the local OpenCode SQLite database. Useful for Lead-of-Leads monitoring and nested session visibility.',
@@ -1007,10 +784,6 @@ Returns the public URL that can be copied and used anywhere.`,
1007
784
  });
1008
785
 
1009
786
  return {
1010
- agentuity_background_task: backgroundTask,
1011
- agentuity_background_output: backgroundOutput,
1012
- agentuity_background_cancel: backgroundCancel,
1013
- agentuity_background_inspect: backgroundInspect,
1014
787
  agentuity_session_dashboard: sessionDashboard,
1015
788
  agentuity_memory_share: memoryShare,
1016
789
  };
@@ -1032,20 +805,6 @@ function extractSessionIdFromEvent(input: unknown): string | undefined {
1032
805
  );
1033
806
  }
1034
807
 
1035
- function resolveAgentName(role: AgentRole): string {
1036
- const agent = agents[role];
1037
- return agent?.displayName ?? role;
1038
- }
1039
-
1040
- function extractEventFromInput(
1041
- input: unknown
1042
- ): { type: string; properties?: Record<string, unknown> } | undefined {
1043
- if (typeof input !== 'object' || input === null) return undefined;
1044
- const inp = input as { event?: { type?: string; properties?: Record<string, unknown> } };
1045
- if (!inp.event || typeof inp.event.type !== 'string') return undefined;
1046
- return { type: inp.event.type, properties: inp.event.properties };
1047
- }
1048
-
1049
808
  function parseDisplayTitle(rawTitle: string): string {
1050
809
  try {
1051
810
  const parsed = JSON.parse(rawTitle);
@@ -1210,7 +969,6 @@ function isMemoryPath(path: string): boolean {
1210
969
  }
1211
970
 
1212
971
  function registerShutdownHandler(
1213
- manager: BackgroundManager,
1214
972
  tmuxManager?: TmuxSessionManager,
1215
973
  logger?: (msg: string) => void,
1216
974
  dbReader?: OpenCodeDBReader
@@ -1238,14 +996,6 @@ function registerShutdownHandler(
1238
996
 
1239
997
  log(`Shutdown triggered by ${signal ?? 'unknown'} signal`);
1240
998
 
1241
- try {
1242
- log('Shutting down background manager...');
1243
- manager.shutdown();
1244
- log('Background manager shutdown complete');
1245
- } catch (error) {
1246
- log(`Background manager shutdown error: ${error}`);
1247
- }
1248
-
1249
999
  if (tmuxManager) {
1250
1000
  try {
1251
1001
  log('Cleaning up tmux sessions...');
@@ -142,7 +142,6 @@ export interface DBToolCallSummary {
142
142
  /** Stats about what compaction preserved */
143
143
  export interface CompactionStats {
144
144
  planningPhasesCount: number;
145
- backgroundTasksCount: number;
146
145
  imageDescriptionsCount: number;
147
146
  toolCallSummariesCount: number;
148
147
  estimatedTokens: number;
@@ -153,7 +152,6 @@ export interface PreCompactionSnapshot {
153
152
  timestamp: string;
154
153
  sessionId: string;
155
154
  planningState?: Record<string, unknown>;
156
- backgroundTasks?: Array<{ id: string; description: string; status: string }>;
157
155
  imageDescriptions?: string[];
158
156
  toolCallSummaries?: string[];
159
157
  cadenceState?: Record<string, unknown>;
@@ -52,7 +52,7 @@ export interface TmuxSessionManagerCallbacks {
52
52
  }
53
53
 
54
54
  /**
55
- * Manages tmux panes for background agents.
55
+ * Manages tmux panes for agent sessions.
56
56
  *
57
57
  * Architecture:
58
58
  * 1. QUERY: Get actual tmux pane state (source of truth)
@@ -106,8 +106,8 @@ export class TmuxSessionManager {
106
106
  }
107
107
 
108
108
  /**
109
- * Handle a new background session being created
110
- * This is called by BackgroundManager when a background task starts
109
+ * Handle a new subagent session being created
110
+ * This is called when a delegated session starts
111
111
  *
112
112
  * Operations are queued to prevent race conditions when multiple sessions
113
113
  * are created rapidly.
@@ -251,7 +251,7 @@ export class TmuxSessionManager {
251
251
  /**
252
252
  * Handle a session being deleted
253
253
  *
254
- * Explicitly kills the pane when a background session completes.
254
+ * Explicitly kills the pane when a subagent session completes.
255
255
  * We can't rely on `opencode attach` exiting because it's an interactive
256
256
  * terminal that keeps running even after the session goes idle.
257
257
  *
package/src/tmux/types.ts CHANGED
@@ -29,11 +29,11 @@ export interface WindowState {
29
29
  windowWidth: number;
30
30
  windowHeight: number;
31
31
  mainPane: TmuxPaneInfo | null; // The pane running the main agent
32
- agentPanes: TmuxPaneInfo[]; // Panes for background agents
32
+ agentPanes: TmuxPaneInfo[]; // Panes for subagent sessions
33
33
  }
34
34
 
35
35
  /**
36
- * Tracked session for a background agent in tmux
36
+ * Tracked session for a subagent in tmux
37
37
  */
38
38
  export interface TrackedSession {
39
39
  sessionId: string; // OpenCode session ID
@@ -1,9 +1,2 @@
1
- export {
2
- createBackgroundTools,
3
- BackgroundTaskArgsSchema,
4
- BackgroundOutputArgsSchema,
5
- BackgroundCancelArgsSchema,
6
- type BackgroundTaskArgs,
7
- type BackgroundOutputArgs,
8
- type BackgroundCancelArgs,
9
- } from './background';
1
+ // Tools are registered directly in plugin/plugin.ts
2
+ export {};
package/src/types.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { z } from 'zod';
2
- import type { BackgroundTaskConfig } from './background/types';
3
2
  import type { SkillsConfig } from './skills/types';
4
3
  import type { TmuxConfig } from './tmux/types';
5
4
 
@@ -11,7 +10,6 @@ export type {
11
10
  ToolDefinition,
12
11
  } from '@opencode-ai/plugin';
13
12
 
14
- export type { BackgroundTaskConfig } from './background/types';
15
13
  export type { SkillsConfig, LoadedSkill, SkillMetadata, SkillScope } from './skills';
16
14
  export type { TmuxConfig } from './tmux/types';
17
15
 
@@ -28,7 +26,6 @@ export const AgentRoleSchema = z.enum([
28
26
  'expert-ops',
29
27
  'runner',
30
28
  'product',
31
- 'monitor',
32
29
  ]);
33
30
  export type AgentRole = z.infer<typeof AgentRoleSchema>;
34
31
 
@@ -184,20 +181,11 @@ export interface CoderConfig {
184
181
  disabledMcps?: string[];
185
182
  /** CLI command patterns to block for security (e.g., 'cloud secrets', 'auth token') */
186
183
  blockedCommands?: string[];
187
- background?: BackgroundTaskConfig;
188
184
  skills?: SkillsConfig;
189
185
  tmux?: TmuxConfig;
190
186
  compaction?: CompactionConfig;
191
187
  }
192
188
 
193
- export const BackgroundTaskConfigSchema = z.object({
194
- enabled: z.boolean(),
195
- defaultConcurrency: z.number(),
196
- staleTimeoutMs: z.number(),
197
- providerConcurrency: z.record(z.string(), z.number()).optional(),
198
- modelConcurrency: z.record(z.string(), z.number()).optional(),
199
- });
200
-
201
189
  export const SkillsConfigSchema = z.object({
202
190
  enabled: z.boolean(),
203
191
  paths: z.array(z.string()).optional(),
@@ -225,7 +213,6 @@ export const CoderConfigSchema = z.object({
225
213
  org: z.string().optional(),
226
214
  disabledMcps: z.array(z.string()).optional(),
227
215
  blockedCommands: z.array(z.string()).optional(),
228
- background: BackgroundTaskConfigSchema.optional(),
229
216
  skills: SkillsConfigSchema.optional(),
230
217
  tmux: TmuxConfigSchema.optional(),
231
218
  compaction: CompactionConfigSchema.optional(),
@@ -1,4 +0,0 @@
1
- import type { AgentDefinition } from './types';
2
- export declare const MONITOR_SYSTEM_PROMPT = "# BackgroundMonitor Agent\n\nYou are an auto-launched background task monitor. You were spawned automatically when Lead started background tasks. Your ONLY job is to watch those tasks and push a consolidated completion report back to Lead when they are all done.\n\n**Lead is not polling. Lead is not watching. You are the eyes. Lead trusts you to report.**\n\n## How You Discover Tasks\n\nYou receive a parent session ID in your prompt. Use it to discover all sibling tasks:\n\n```\nagentuity_session_dashboard({ session_id: \"<parentSessionId>\" })\n```\n\nThis is scoped to child sessions of that parent only \u2014 it does not expose unrelated sessions.\nFrom the dashboard, extract the task IDs (bg_xxx format) from session titles.\nThen use `agentuity_background_output({ task_id: \"bg_xxx\" })` to get status + progress for each.\n\nIgnore sessions that are other Monitor instances \u2014 their `displayTitle` will be \"Monitor background tasks\". Filter these out when processing the dashboard results.\n\n## Progress Signal\n\n`agentuity_background_output` now returns a `progress` object on running tasks:\n\n```json\n{\n \"status\": \"running\",\n \"progress\": {\n \"toolCalls\": 21,\n \"lastTool\": \"read\",\n \"lastToolSec\": 12,\n \"activeTools\": 1\n }\n}\n```\n\n- `toolCalls`: total tool calls completed \u2014 growing means active work\n- `lastTool`: name of the most recently completed tool\n- `lastToolSec`: seconds since last tool activity \u2014 <300 with growth means healthy\n- `activeTools`: tool calls currently in-flight\n\nA task is **stuck** only if `lastToolSec > 300` AND `activeTools === 0` AND `toolCalls` has not grown between checks.\n\n## Check Cadence \u2014 CRITICAL\n\n**You MUST wait at least 20 seconds between each check cycle.** This is a hard requirement, not a suggestion.\n\n- Minimum 20 seconds between checks \u2014 count them, do not rush\n- Maximum 10 check cycles total (covers ~3-4 minutes of typical work)\n- After EACH check, output: \"\u23F3 Waiting 20 seconds before next check...\" \u2014 this helps you pace yourself\n- Scout tasks typically take 3\u20138 minutes \u2014 be patient, checking faster does NOT make them complete faster\n- Excessive polling wastes tokens and provides no benefit\n\nFor each poll cycle (track cycle number starting at 1):\n1. Check each task ID with `agentuity_background_output({ task_id: \"bg_xxx\" })`\n2. Track the status of each task\n3. If any task is still \"pending\" or \"running\" **and cycle < 10**, wait 20 seconds and poll again\n4. When all tasks are \"completed\" or \"error\" **OR cycle reaches 10**, generate the final report\n\n## When Tasks Are Stuck\n\nIf a task shows `lastToolSec > 300` AND `activeTools === 0`:\n1. Call `agentuity_background_inspect({ task_id: \"bg_xxx\" })` for a full view\n2. Include what you found in your final report under \"Stuck Tasks\"\n3. Do NOT cancel the task \u2014 report it to Lead for a decision\n\n## Completion Condition\n\nAll work tasks are done when every non-monitor task is `completed`, `error`, or `cancelled`.\n\n## Final Report Format\n\nWhen all tasks are done (or after 20 cycles), output exactly this:\n\n```markdown\n## [ALL BACKGROUND TASKS COMPLETE]\n\n- **bg_xxx** (completed): [first 100 chars of result]\n- **bg_yyy** (error): [error message]\n- **bg_zzz** (completed): [first 100 chars of result]\n\n### Results\n\n**bg_xxx:**\n[full result text]\n\n**bg_yyy (error):**\n[error]\n```\n\nIf tasks are still running after 10 cycles, use \"## [BACKGROUND TASKS STILL RUNNING]\" as the header and list the stuck ones with their last known progress.\n\n## Timeout Errors\n\n- **Timeout errors** (\"Background task timed out (no activity).\") often occur when the model is\n generating a long text response without making tool calls. These are server-side inactivity\n timeouts, not true failures \u2014 the model was still working but appeared idle to the server.\n- If a task errors with a timeout, note this in your report. It may be worth retrying.\n\n## What You Do NOT Do\n\n- \u274C Interpret or analyze task results beyond summarizing\n- \u274C Make decisions about next steps\n- \u274C Cancel tasks (ever)\n- \u274C Interact with the user\n- \u274C Modify any files\n- \u274C Call other agents\n- \u274C Use tools other than agentuity_background_output, agentuity_background_inspect, and agentuity_session_dashboard\n\nYou are a patient, focused watcher. When work is done, you report. Nothing more.\n\n## Example Workflow\n\nGiven task: \"Monitor these tasks: bg_abc123, bg_def456\"\n\n1. Call agentuity_background_output for bg_abc123\n2. Call agentuity_background_output for bg_def456\n3. If any status is \"pending\" or \"running\" and cycle < 10, wait 20 seconds\n4. Repeat steps 1-3 until all complete or 10 cycles reached\n5. Output final report\n\n## Waiting Between Polls\n\nSince you cannot use setTimeout, after checking all tasks and finding some still running, you MUST output:\n\n\"\u23F3 Waiting 20 seconds before next check... (cycle 3/10)\"\n\nThen poll again. The conversation history serves as your \"timer\" \u2014 each response and check adds natural delay. Do NOT skip the waiting message.\n\n**After 10 cycles:** Report final status even if tasks are still running, noting which tasks did not complete within the monitoring window.\n";
3
- export declare const monitorAgent: AgentDefinition;
4
- //# sourceMappingURL=monitor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../../src/agents/monitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,eAAO,MAAM,qBAAqB,muKAkIjC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eA0B1B,CAAC"}
@@ -1,159 +0,0 @@
1
- export const MONITOR_SYSTEM_PROMPT = `# BackgroundMonitor Agent
2
-
3
- You are an auto-launched background task monitor. You were spawned automatically when Lead started background tasks. Your ONLY job is to watch those tasks and push a consolidated completion report back to Lead when they are all done.
4
-
5
- **Lead is not polling. Lead is not watching. You are the eyes. Lead trusts you to report.**
6
-
7
- ## How You Discover Tasks
8
-
9
- You receive a parent session ID in your prompt. Use it to discover all sibling tasks:
10
-
11
- \`\`\`
12
- agentuity_session_dashboard({ session_id: "<parentSessionId>" })
13
- \`\`\`
14
-
15
- This is scoped to child sessions of that parent only — it does not expose unrelated sessions.
16
- From the dashboard, extract the task IDs (bg_xxx format) from session titles.
17
- Then use \`agentuity_background_output({ task_id: "bg_xxx" })\` to get status + progress for each.
18
-
19
- Ignore sessions that are other Monitor instances — their \`displayTitle\` will be "Monitor background tasks". Filter these out when processing the dashboard results.
20
-
21
- ## Progress Signal
22
-
23
- \`agentuity_background_output\` now returns a \`progress\` object on running tasks:
24
-
25
- \`\`\`json
26
- {
27
- "status": "running",
28
- "progress": {
29
- "toolCalls": 21,
30
- "lastTool": "read",
31
- "lastToolSec": 12,
32
- "activeTools": 1
33
- }
34
- }
35
- \`\`\`
36
-
37
- - \`toolCalls\`: total tool calls completed — growing means active work
38
- - \`lastTool\`: name of the most recently completed tool
39
- - \`lastToolSec\`: seconds since last tool activity — <300 with growth means healthy
40
- - \`activeTools\`: tool calls currently in-flight
41
-
42
- A task is **stuck** only if \`lastToolSec > 300\` AND \`activeTools === 0\` AND \`toolCalls\` has not grown between checks.
43
-
44
- ## Check Cadence — CRITICAL
45
-
46
- **You MUST wait at least 20 seconds between each check cycle.** This is a hard requirement, not a suggestion.
47
-
48
- - Minimum 20 seconds between checks — count them, do not rush
49
- - Maximum 10 check cycles total (covers ~3-4 minutes of typical work)
50
- - After EACH check, output: "⏳ Waiting 20 seconds before next check..." — this helps you pace yourself
51
- - Scout tasks typically take 3–8 minutes — be patient, checking faster does NOT make them complete faster
52
- - Excessive polling wastes tokens and provides no benefit
53
-
54
- For each poll cycle (track cycle number starting at 1):
55
- 1. Check each task ID with \`agentuity_background_output({ task_id: "bg_xxx" })\`
56
- 2. Track the status of each task
57
- 3. If any task is still "pending" or "running" **and cycle < 10**, wait 20 seconds and poll again
58
- 4. When all tasks are "completed" or "error" **OR cycle reaches 10**, generate the final report
59
-
60
- ## When Tasks Are Stuck
61
-
62
- If a task shows \`lastToolSec > 300\` AND \`activeTools === 0\`:
63
- 1. Call \`agentuity_background_inspect({ task_id: "bg_xxx" })\` for a full view
64
- 2. Include what you found in your final report under "Stuck Tasks"
65
- 3. Do NOT cancel the task — report it to Lead for a decision
66
-
67
- ## Completion Condition
68
-
69
- All work tasks are done when every non-monitor task is \`completed\`, \`error\`, or \`cancelled\`.
70
-
71
- ## Final Report Format
72
-
73
- When all tasks are done (or after 20 cycles), output exactly this:
74
-
75
- \`\`\`markdown
76
- ## [ALL BACKGROUND TASKS COMPLETE]
77
-
78
- - **bg_xxx** (completed): [first 100 chars of result]
79
- - **bg_yyy** (error): [error message]
80
- - **bg_zzz** (completed): [first 100 chars of result]
81
-
82
- ### Results
83
-
84
- **bg_xxx:**
85
- [full result text]
86
-
87
- **bg_yyy (error):**
88
- [error]
89
- \`\`\`
90
-
91
- If tasks are still running after 10 cycles, use "## [BACKGROUND TASKS STILL RUNNING]" as the header and list the stuck ones with their last known progress.
92
-
93
- ## Timeout Errors
94
-
95
- - **Timeout errors** ("Background task timed out (no activity).") often occur when the model is
96
- generating a long text response without making tool calls. These are server-side inactivity
97
- timeouts, not true failures — the model was still working but appeared idle to the server.
98
- - If a task errors with a timeout, note this in your report. It may be worth retrying.
99
-
100
- ## What You Do NOT Do
101
-
102
- - ❌ Interpret or analyze task results beyond summarizing
103
- - ❌ Make decisions about next steps
104
- - ❌ Cancel tasks (ever)
105
- - ❌ Interact with the user
106
- - ❌ Modify any files
107
- - ❌ Call other agents
108
- - ❌ Use tools other than agentuity_background_output, agentuity_background_inspect, and agentuity_session_dashboard
109
-
110
- You are a patient, focused watcher. When work is done, you report. Nothing more.
111
-
112
- ## Example Workflow
113
-
114
- Given task: "Monitor these tasks: bg_abc123, bg_def456"
115
-
116
- 1. Call agentuity_background_output for bg_abc123
117
- 2. Call agentuity_background_output for bg_def456
118
- 3. If any status is "pending" or "running" and cycle < 10, wait 20 seconds
119
- 4. Repeat steps 1-3 until all complete or 10 cycles reached
120
- 5. Output final report
121
-
122
- ## Waiting Between Polls
123
-
124
- Since you cannot use setTimeout, after checking all tasks and finding some still running, you MUST output:
125
-
126
- "⏳ Waiting 20 seconds before next check... (cycle 3/10)"
127
-
128
- Then poll again. The conversation history serves as your "timer" — each response and check adds natural delay. Do NOT skip the waiting message.
129
-
130
- **After 10 cycles:** Report final status even if tasks are still running, noting which tasks did not complete within the monitoring window.
131
- `;
132
- export const monitorAgent = {
133
- role: 'monitor',
134
- id: 'ag-monitor',
135
- displayName: 'Agentuity Coder Monitor',
136
- description: 'Background task monitor - watches background tasks and reports completions',
137
- defaultModel: 'anthropic/claude-haiku-4-5-20251001', // Lightweight, fast
138
- systemPrompt: MONITOR_SYSTEM_PROMPT,
139
- mode: 'subagent', // Only used as subagent, never primary
140
- hidden: true, // Hidden from @ autocomplete, but can be invoked via Task tool
141
- tools: {
142
- // Monitor only needs the background output tool - exclude everything else
143
- exclude: [
144
- 'write',
145
- 'edit',
146
- 'apply_patch',
147
- 'bash',
148
- 'read',
149
- 'glob',
150
- 'grep',
151
- 'task',
152
- 'agentuity_background_task',
153
- 'agentuity_background_cancel',
154
- 'agentuity_memory_share',
155
- ],
156
- },
157
- temperature: 0.0, // Deterministic - just poll and report
158
- };
159
- //# sourceMappingURL=monitor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../src/agents/monitor.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkIpC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAoB;IAC5C,IAAI,EAAE,SAAS;IACf,EAAE,EAAE,YAAY;IAChB,WAAW,EAAE,yBAAyB;IACtC,WAAW,EAAE,4EAA4E;IACzF,YAAY,EAAE,qCAAqC,EAAE,oBAAoB;IACzE,YAAY,EAAE,qBAAqB;IACnC,IAAI,EAAE,UAAU,EAAE,uCAAuC;IACzD,MAAM,EAAE,IAAI,EAAE,+DAA+D;IAC7E,KAAK,EAAE;QACN,0EAA0E;QAC1E,OAAO,EAAE;YACR,OAAO;YACP,MAAM;YACN,aAAa;YACb,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,2BAA2B;YAC3B,6BAA6B;YAC7B,wBAAwB;SACxB;KACD;IACD,WAAW,EAAE,GAAG,EAAE,uCAAuC;CACzD,CAAC"}
@@ -1,36 +0,0 @@
1
- /**
2
- * Error thrown when a concurrency waiter is cancelled.
3
- */
4
- export declare const ConcurrencyCancelledError: {
5
- new (args?: ({
6
- key?: string;
7
- } & {
8
- cause?: unknown;
9
- }) | undefined): import("@agentuity/core").RichError & {
10
- readonly _tag: "ConcurrencyCancelledError";
11
- } & Readonly<{
12
- key?: string;
13
- }>;
14
- readonly defaultMessage?: string;
15
- };
16
- export interface ConcurrencyConfig {
17
- defaultLimit: number;
18
- limits?: Record<string, number>;
19
- }
20
- export declare class ConcurrencyManager {
21
- private defaultLimit;
22
- private limits;
23
- private counts;
24
- private queues;
25
- constructor(config?: Partial<ConcurrencyConfig>);
26
- getConcurrencyLimit(key: string): number;
27
- acquire(key: string): Promise<void>;
28
- release(key: string): void;
29
- cancelWaiters(key: string): void;
30
- clear(): void;
31
- getCount(key: string): number;
32
- getQueueLength(key: string): number;
33
- private getQueue;
34
- private flushQueue;
35
- }
36
- //# sourceMappingURL=concurrency.d.ts.map