@qduc/term2 0.11.0 → 0.11.1

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 (146) hide show
  1. package/dist/agent.d.ts +11 -0
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +54 -18
  4. package/dist/agent.js.map +1 -1
  5. package/dist/components/layout/BackgroundTasksPanel.d.ts.map +1 -1
  6. package/dist/components/layout/BackgroundTasksPanel.js +35 -16
  7. package/dist/components/layout/BackgroundTasksPanel.js.map +1 -1
  8. package/dist/components/message/CommandMessage.js +4 -2
  9. package/dist/components/message/CommandMessage.js.map +1 -1
  10. package/dist/components/message/command-message-helpers.d.ts +4 -4
  11. package/dist/hooks/conversation-ui-reducer.d.ts +5 -0
  12. package/dist/hooks/conversation-ui-reducer.d.ts.map +1 -1
  13. package/dist/hooks/conversation-ui-reducer.js +8 -0
  14. package/dist/hooks/conversation-ui-reducer.js.map +1 -1
  15. package/dist/hooks/use-conversation.d.ts.map +1 -1
  16. package/dist/hooks/use-conversation.js +1 -0
  17. package/dist/hooks/use-conversation.js.map +1 -1
  18. package/dist/lib/agent-configuration.d.ts.map +1 -1
  19. package/dist/lib/agent-configuration.js +3 -0
  20. package/dist/lib/agent-configuration.js.map +1 -1
  21. package/dist/lib/agent-factory.d.ts +11 -0
  22. package/dist/lib/agent-factory.d.ts.map +1 -1
  23. package/dist/lib/agent-factory.js +3 -0
  24. package/dist/lib/agent-factory.js.map +1 -1
  25. package/dist/lib/chained-input-filter.d.ts +20 -0
  26. package/dist/lib/chained-input-filter.d.ts.map +1 -1
  27. package/dist/lib/chained-input-filter.js +75 -0
  28. package/dist/lib/chained-input-filter.js.map +1 -1
  29. package/dist/lib/subagent-bridge.d.ts +20 -1
  30. package/dist/lib/subagent-bridge.d.ts.map +1 -1
  31. package/dist/lib/subagent-bridge.js +26 -0
  32. package/dist/lib/subagent-bridge.js.map +1 -1
  33. package/dist/prompts/anthropic.md +6 -55
  34. package/dist/prompts/async-subagent-delegation.d.ts +2 -1
  35. package/dist/prompts/async-subagent-delegation.d.ts.map +1 -1
  36. package/dist/prompts/async-subagent-delegation.js +20 -6
  37. package/dist/prompts/async-subagent-delegation.js.map +1 -1
  38. package/dist/prompts/async-subagent-delegation.ts +26 -6
  39. package/dist/prompts/gpt-5.6.md +49 -0
  40. package/dist/prompts/kimi.md +25 -63
  41. package/dist/prompts/orchestrator-prompt.test.ts +77 -0
  42. package/dist/prompts/orchestrator.md +15 -1
  43. package/dist/prompts/prompt-constructor.d.ts +1 -0
  44. package/dist/prompts/prompt-constructor.d.ts.map +1 -1
  45. package/dist/prompts/prompt-constructor.js +6 -2
  46. package/dist/prompts/prompt-constructor.js.map +1 -1
  47. package/dist/prompts/prompt-constructor.test.ts +22 -1
  48. package/dist/prompts/prompt-constructor.ts +9 -1
  49. package/dist/prompts/prompt-profiles.d.ts.map +1 -1
  50. package/dist/prompts/prompt-profiles.js +5 -0
  51. package/dist/prompts/prompt-profiles.js.map +1 -1
  52. package/dist/prompts/prompt-profiles.test.ts +20 -0
  53. package/dist/prompts/prompt-profiles.ts +5 -0
  54. package/dist/prompts/search-via-shell.d.ts.map +1 -1
  55. package/dist/prompts/search-via-shell.js +8 -25
  56. package/dist/prompts/search-via-shell.js.map +1 -1
  57. package/dist/prompts/search-via-shell.test.ts +18 -0
  58. package/dist/prompts/search-via-shell.ts +8 -25
  59. package/dist/prompts/subagent-delegation.test.ts +15 -0
  60. package/dist/prompts/subagents/researcher.md +6 -0
  61. package/dist/prompts/subagents/worker-prompt.test.ts +35 -0
  62. package/dist/prompts/subagents/worker.md +8 -0
  63. package/dist/services/conversation/conversation-adapter.d.ts +11 -3
  64. package/dist/services/conversation/conversation-adapter.d.ts.map +1 -1
  65. package/dist/services/conversation/conversation-adapter.js +123 -31
  66. package/dist/services/conversation/conversation-adapter.js.map +1 -1
  67. package/dist/services/conversation/conversation-events.d.ts +25 -1
  68. package/dist/services/conversation/conversation-events.d.ts.map +1 -1
  69. package/dist/services/conversation/conversation-orchestrator.d.ts.map +1 -1
  70. package/dist/services/conversation/conversation-orchestrator.js +141 -26
  71. package/dist/services/conversation/conversation-orchestrator.js.map +1 -1
  72. package/dist/services/conversation/conversation-orchestrator.types.d.ts +2 -0
  73. package/dist/services/conversation/conversation-orchestrator.types.d.ts.map +1 -1
  74. package/dist/services/conversation/conversation-service.d.ts +3 -0
  75. package/dist/services/conversation/conversation-service.d.ts.map +1 -1
  76. package/dist/services/conversation/conversation-service.js +4 -0
  77. package/dist/services/conversation/conversation-service.js.map +1 -1
  78. package/dist/services/logging/conversation-log-events.d.ts +9 -1
  79. package/dist/services/logging/conversation-log-events.d.ts.map +1 -1
  80. package/dist/services/logging/conversation-log-events.js.map +1 -1
  81. package/dist/services/logging/conversation-log-writer.d.ts +1 -0
  82. package/dist/services/logging/conversation-log-writer.d.ts.map +1 -1
  83. package/dist/services/logging/conversation-log-writer.js +1 -1
  84. package/dist/services/logging/conversation-log-writer.js.map +1 -1
  85. package/dist/services/logging/conversation-logger.d.ts.map +1 -1
  86. package/dist/services/logging/conversation-logger.js +10 -0
  87. package/dist/services/logging/conversation-logger.js.map +1 -1
  88. package/dist/services/queue/queue-controller.d.ts +1 -0
  89. package/dist/services/queue/queue-controller.d.ts.map +1 -1
  90. package/dist/services/queue/queue-controller.js +7 -4
  91. package/dist/services/queue/queue-controller.js.map +1 -1
  92. package/dist/services/retry/retry-classifier.d.ts.map +1 -1
  93. package/dist/services/retry/retry-classifier.js +4 -2
  94. package/dist/services/retry/retry-classifier.js.map +1 -1
  95. package/dist/services/subagents/execution-runner.d.ts +3 -3
  96. package/dist/services/subagents/execution-runner.d.ts.map +1 -1
  97. package/dist/services/subagents/execution-runner.js +96 -7
  98. package/dist/services/subagents/execution-runner.js.map +1 -1
  99. package/dist/services/subagents/mentor-runner.d.ts.map +1 -1
  100. package/dist/services/subagents/mentor-runner.js +24 -5
  101. package/dist/services/subagents/mentor-runner.js.map +1 -1
  102. package/dist/services/subagents/runtime.d.ts.map +1 -1
  103. package/dist/services/subagents/runtime.js +17 -7
  104. package/dist/services/subagents/runtime.js.map +1 -1
  105. package/dist/services/subagents/subagent-async-registry.d.ts +30 -2
  106. package/dist/services/subagents/subagent-async-registry.d.ts.map +1 -1
  107. package/dist/services/subagents/subagent-async-registry.js +314 -41
  108. package/dist/services/subagents/subagent-async-registry.js.map +1 -1
  109. package/dist/services/subagents/subagent-manager.d.ts +15 -1
  110. package/dist/services/subagents/subagent-manager.d.ts.map +1 -1
  111. package/dist/services/subagents/subagent-manager.js +16 -0
  112. package/dist/services/subagents/subagent-manager.js.map +1 -1
  113. package/dist/services/subagents/subagent-notification-store.d.ts +40 -22
  114. package/dist/services/subagents/subagent-notification-store.d.ts.map +1 -1
  115. package/dist/services/subagents/subagent-notification-store.js +81 -39
  116. package/dist/services/subagents/subagent-notification-store.js.map +1 -1
  117. package/dist/services/subagents/subagent-run-control.d.ts +41 -0
  118. package/dist/services/subagents/subagent-run-control.d.ts.map +1 -0
  119. package/dist/services/subagents/subagent-run-control.js +166 -0
  120. package/dist/services/subagents/subagent-run-control.js.map +1 -0
  121. package/dist/services/subagents/tool-policy.d.ts +24 -4
  122. package/dist/services/subagents/tool-policy.d.ts.map +1 -1
  123. package/dist/services/subagents/tool-policy.js +134 -14
  124. package/dist/services/subagents/tool-policy.js.map +1 -1
  125. package/dist/services/subagents/types.d.ts +93 -0
  126. package/dist/services/subagents/types.d.ts.map +1 -1
  127. package/dist/tools/agent/ask-orchestrator.d.ts +11 -0
  128. package/dist/tools/agent/ask-orchestrator.d.ts.map +1 -0
  129. package/dist/tools/agent/ask-orchestrator.js +39 -0
  130. package/dist/tools/agent/ask-orchestrator.js.map +1 -0
  131. package/dist/tools/agent/run-subagent-async.d.ts +43 -1
  132. package/dist/tools/agent/run-subagent-async.d.ts.map +1 -1
  133. package/dist/tools/agent/run-subagent-async.js +230 -7
  134. package/dist/tools/agent/run-subagent-async.js.map +1 -1
  135. package/dist/tools/file/code-context.d.ts +1 -0
  136. package/dist/tools/file/code-context.d.ts.map +1 -1
  137. package/dist/tools/file/code-context.js +4 -4
  138. package/dist/tools/file/code-context.js.map +1 -1
  139. package/dist/tools/file/grep.d.ts +1 -0
  140. package/dist/tools/file/grep.d.ts.map +1 -1
  141. package/dist/tools/file/grep.js +16 -10
  142. package/dist/tools/file/grep.js.map +1 -1
  143. package/dist/utils/conversation/conversation-event-handler.d.ts.map +1 -1
  144. package/dist/utils/conversation/conversation-event-handler.js +6 -3
  145. package/dist/utils/conversation/conversation-event-handler.js.map +1 -1
  146. package/package.json +1 -1
@@ -1,6 +1,9 @@
1
1
  import type { ConversationEvent } from '../conversation/conversation-events.js';
2
- /** A background subagent run that finished and still owes the main agent a notification. */
3
- export interface BackgroundSubagentNotification {
2
+ /** A completed background run that still owes the main agent a notification. */
3
+ export interface BackgroundSubagentCompletionNotification {
4
+ kind: 'completion';
5
+ /** Stable per logical run, so replay cannot duplicate a completion. */
6
+ messageId: string;
4
7
  runId: string;
5
8
  role: string;
6
9
  status: 'completed' | 'failed' | 'cancelled';
@@ -8,7 +11,25 @@ export interface BackgroundSubagentNotification {
8
11
  error?: string;
9
12
  completedAt: number;
10
13
  }
14
+ /** A live execution segment's bounded request for its owning orchestrator. */
15
+ export interface BackgroundSubagentQuestionNotification {
16
+ kind: 'question';
17
+ messageId: string;
18
+ runId: string;
19
+ name?: string;
20
+ role: string;
21
+ question: string;
22
+ askedAt: number;
23
+ }
24
+ /** A message-id-keyed queue item for a background async subagent. */
25
+ export type BackgroundSubagentNotification = BackgroundSubagentCompletionNotification | BackgroundSubagentQuestionNotification;
11
26
  export type BackgroundSubagentTaskStatus = 'running' | 'completed' | 'failed' | 'cancelled';
27
+ /** The single most recent tool call observed for a live background run. */
28
+ export interface BackgroundSubagentTaskTool {
29
+ /** Display-ready command line, e.g. `grep "TODO" src/`. */
30
+ label: string;
31
+ state: 'running' | 'success' | 'failed';
32
+ }
12
33
  /** Conversation-scoped projection of one background subagent lifecycle. */
13
34
  export interface BackgroundSubagentTask {
14
35
  runId: string;
@@ -17,6 +38,8 @@ export interface BackgroundSubagentTask {
17
38
  status: BackgroundSubagentTaskStatus;
18
39
  startedAt: number;
19
40
  completedAt?: number;
41
+ /** Absent until the run calls its first tool; dropped once the run settles. */
42
+ lastTool?: BackgroundSubagentTaskTool;
20
43
  }
21
44
  /**
22
45
  * The delivery half of {@link SubagentNotificationStore}, for callers that hand
@@ -38,9 +61,9 @@ export interface SubagentNotificationStoreDeps {
38
61
  /** How long terminal tasks remain visible in the background overview. */
39
62
  recentTaskRetentionMs?: number;
40
63
  /**
41
- * Upper bound on remembered run ids. The async registry caps sessions at 50
42
- * and TTLs terminal runs out after 30 minutes, so a few hundred ids covers
43
- * every run that could still be replayed while staying O(1) in memory.
64
+ * Upper bound on remembered notification ids. The async registry caps
65
+ * sessions at 50 and TTLs terminal runs out after 30 minutes, so a few
66
+ * hundred ids covers replay protection while staying O(1) in memory.
44
67
  */
45
68
  deliveredIdCap?: number;
46
69
  }
@@ -49,36 +72,31 @@ export declare const BACKGROUND_TASK_RECENT_RETENTION_MS = 5000;
49
72
  * Pending notifications for background (async) subagent runs.
50
73
  *
51
74
  * Owns three invariants the callers must not have to re-derive:
52
- * - Only `subagent_completed` events flagged `async: true` are notifiable.
53
- * Foreground and nested runs emit the same event type without the flag and
54
- * must never surface a notification.
55
- * - A run is announced at most once, ever. The registry already guards against
56
- * double-settling a run, so the duplicates guarded here come from buffered
57
- * event flushes and conversation replay, which can re-present an event long
58
- * after it was first seen — including after it was already delivered.
75
+ * - Only async completions and async registry questions are notifiable.
76
+ * Foreground and nested activity has no async flag and never surfaces here.
77
+ * - A message is announced at most once, ever. Completion ids are stable per
78
+ * run while each question has its own id, allowing one live run to ask more
79
+ * than once over its lifetime without replaying either message.
59
80
  * - Delivery is confirmed by the caller, not by reading. `drain()` hands over
60
81
  * the pending batch and clears it; a caller whose delivery failed calls
61
82
  * `retain()` to put the batch back at the front of the queue. Drain/retain
62
83
  * was chosen over peek/commit because the common path (delivery succeeds) is
63
84
  * then a single call, and because retained notifications are handed back as
64
- * values rather than leaving the store holding provisional state. A run id
65
- * stays deduped across both paths, so a retained notification is redelivered
66
- * exactly once and a replayed event for it is still dropped.
85
+ * values rather than leaving the store holding provisional state. A message
86
+ * id stays deduped across both paths, so a retained notification is
87
+ * redelivered exactly once and a replayed event for it is still dropped.
67
88
  */
68
89
  export declare class SubagentNotificationStore implements BackgroundSubagentNotificationPort {
69
90
  #private;
70
91
  constructor(deps?: SubagentNotificationStoreDeps);
71
92
  /**
72
- * Updates the read-only task projection for async starts and completions.
73
- * Internal tool events intentionally do not enter this state.
93
+ * Updates the read-only task projection for async starts, tool activity, and
94
+ * completions. Only the newest tool call of a live run is kept: the overview
95
+ * answers "what is it doing now", not "what has it done".
74
96
  */
75
97
  recordLifecycle(event: ConversationEvent): boolean;
76
98
  getTaskSnapshot(): readonly BackgroundSubagentTask[];
77
- /**
78
- * Records a completion event when it belongs to a background run that has not
79
- * been seen before. Returns whether the notification was novel, so a caller
80
- * can act (wake a turn) only on first sight.
81
- */
99
+ /** Records one novel async completion or question, returning whether it woke the queue. */
82
100
  enqueue(event: ConversationEvent): boolean;
83
101
  get pendingCount(): number;
84
102
  /** Hands over every pending notification in completion order and clears them. */
@@ -1 +1 @@
1
- {"version":3,"file":"subagent-notification-store.d.ts","sourceRoot":"","sources":["../../../source/services/subagents/subagent-notification-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAIhF,4FAA4F;AAC5F,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,4BAA4B,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE5F,2EAA2E;AAC3E,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,4BAA4B,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,KAAK,IAAI,8BAA8B,EAAE,CAAC;IAC1C,MAAM,CAAC,aAAa,EAAE,SAAS,8BAA8B,EAAE,GAAG,IAAI,CAAC;CACxE;AAED,sEAAsE;AACtE,MAAM,WAAW,0BAA0B;IACzC,WAAW,IAAI,SAAS,sBAAsB,EAAE,CAAC;IACjD,WAAW,CAAC,QAAQ,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;CAClD;AAED,MAAM,WAAW,6BAA6B;IAC5C,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,yEAAyE;IACzE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAGD,eAAO,MAAM,mCAAmC,OAAQ,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,yBAA0B,YAAW,kCAAkC;;IASlF,YAAY,IAAI,GAAE,6BAAkC,EAInD;IAED;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CA2CjD;IAED,eAAe,IAAI,SAAS,sBAAsB,EAAE,CAQnD;IAED;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAkBzC;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,iFAAiF;IACjF,KAAK,IAAI,8BAA8B,EAAE,CAOxC;IAED,+EAA+E;IAC/E,MAAM,CAAC,aAAa,EAAE,SAAS,8BAA8B,EAAE,GAAG,IAAI,CASrE;CAiBF"}
1
+ {"version":3,"file":"subagent-notification-store.d.ts","sourceRoot":"","sources":["../../../source/services/subagents/subagent-notification-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,wCAAwC,CAAC;AAKhD,gFAAgF;AAChF,MAAM,WAAW,wCAAwC;IACvD,IAAI,EAAE,YAAY,CAAC;IACnB,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,8EAA8E;AAC9E,MAAM,WAAW,sCAAsC;IACrD,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qEAAqE;AACrE,MAAM,MAAM,8BAA8B,GACtC,wCAAwC,GACxC,sCAAsC,CAAC;AAE3C,MAAM,MAAM,4BAA4B,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE5F,2EAA2E;AAC3E,MAAM,WAAW,0BAA0B;IACzC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;CACzC;AAED,2EAA2E;AAC3E,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,4BAA4B,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,0BAA0B,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,KAAK,IAAI,8BAA8B,EAAE,CAAC;IAC1C,MAAM,CAAC,aAAa,EAAE,SAAS,8BAA8B,EAAE,GAAG,IAAI,CAAC;CACxE;AAED,sEAAsE;AACtE,MAAM,WAAW,0BAA0B;IACzC,WAAW,IAAI,SAAS,sBAAsB,EAAE,CAAC;IACjD,WAAW,CAAC,QAAQ,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;CAClD;AAED,MAAM,WAAW,6BAA6B;IAC5C,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,yEAAyE;IACzE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAGD,eAAO,MAAM,mCAAmC,OAAQ,CAAC;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,yBAA0B,YAAW,kCAAkC;;IASlF,YAAY,IAAI,GAAE,6BAAkC,EAInD;IAED;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CA+CjD;IA6BD,eAAe,IAAI,SAAS,sBAAsB,EAAE,CAQnD;IAED,2FAA2F;IAC3F,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAQzC;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,iFAAiF;IACjF,KAAK,IAAI,8BAA8B,EAAE,CAOxC;IAED,+EAA+E;IAC/E,MAAM,CAAC,aAAa,EAAE,SAAS,8BAA8B,EAAE,GAAG,IAAI,CASrE;CA+CF"}
@@ -1,3 +1,4 @@
1
+ import { formatToolCommand, parseToolArguments } from '../../utils/conversation/conversation-utils.js';
1
2
  import { truncatePreview } from './utils.js';
2
3
  const DEFAULT_DELIVERED_ID_CAP = 256;
3
4
  export const BACKGROUND_TASK_RECENT_RETENTION_MS = 5_000;
@@ -5,21 +6,19 @@ export const BACKGROUND_TASK_RECENT_RETENTION_MS = 5_000;
5
6
  * Pending notifications for background (async) subagent runs.
6
7
  *
7
8
  * Owns three invariants the callers must not have to re-derive:
8
- * - Only `subagent_completed` events flagged `async: true` are notifiable.
9
- * Foreground and nested runs emit the same event type without the flag and
10
- * must never surface a notification.
11
- * - A run is announced at most once, ever. The registry already guards against
12
- * double-settling a run, so the duplicates guarded here come from buffered
13
- * event flushes and conversation replay, which can re-present an event long
14
- * after it was first seen — including after it was already delivered.
9
+ * - Only async completions and async registry questions are notifiable.
10
+ * Foreground and nested activity has no async flag and never surfaces here.
11
+ * - A message is announced at most once, ever. Completion ids are stable per
12
+ * run while each question has its own id, allowing one live run to ask more
13
+ * than once over its lifetime without replaying either message.
15
14
  * - Delivery is confirmed by the caller, not by reading. `drain()` hands over
16
15
  * the pending batch and clears it; a caller whose delivery failed calls
17
16
  * `retain()` to put the batch back at the front of the queue. Drain/retain
18
17
  * was chosen over peek/commit because the common path (delivery succeeds) is
19
18
  * then a single call, and because retained notifications are handed back as
20
- * values rather than leaving the store holding provisional state. A run id
21
- * stays deduped across both paths, so a retained notification is redelivered
22
- * exactly once and a replayed event for it is still dropped.
19
+ * values rather than leaving the store holding provisional state. A message
20
+ * id stays deduped across both paths, so a retained notification is
21
+ * redelivered exactly once and a replayed event for it is still dropped.
23
22
  */
24
23
  export class SubagentNotificationStore {
25
24
  #pending = new Map();
@@ -35,10 +34,14 @@ export class SubagentNotificationStore {
35
34
  this.#recentTaskRetentionMs = Math.max(0, deps.recentTaskRetentionMs ?? BACKGROUND_TASK_RECENT_RETENTION_MS);
36
35
  }
37
36
  /**
38
- * Updates the read-only task projection for async starts and completions.
39
- * Internal tool events intentionally do not enter this state.
37
+ * Updates the read-only task projection for async starts, tool activity, and
38
+ * completions. Only the newest tool call of a live run is kept: the overview
39
+ * answers "what is it doing now", not "what has it done".
40
40
  */
41
41
  recordLifecycle(event) {
42
+ if (event.type === 'subagent_tool_started' || event.type === 'subagent_command_message') {
43
+ return this.#recordToolActivity(event);
44
+ }
42
45
  if (event.type === 'subagent_started' && event.async === true) {
43
46
  if (this.#settledTaskIds.has(event.agentId))
44
47
  return false;
@@ -85,6 +88,31 @@ export class SubagentNotificationStore {
85
88
  }
86
89
  return true;
87
90
  }
91
+ /**
92
+ * Projects the newest tool call of a live run. Tool events carry no `async`
93
+ * flag, so membership in the running task map is what scopes this to
94
+ * background runs — foreground and nested activity never registers a task.
95
+ */
96
+ #recordToolActivity(event) {
97
+ const task = this.#tasks.get(event.agentId);
98
+ if (!task || task.status !== 'running')
99
+ return false;
100
+ const lastTool = event.type === 'subagent_tool_started'
101
+ ? {
102
+ label: formatToolCommand(event.toolName, parseToolArguments(event.arguments)),
103
+ state: 'running',
104
+ }
105
+ : {
106
+ label: event.message?.command ?? '',
107
+ state: event.message?.success === false ? 'failed' : 'success',
108
+ };
109
+ if (!lastTool.label)
110
+ return false;
111
+ if (task.lastTool?.label === lastTool.label && task.lastTool.state === lastTool.state)
112
+ return false;
113
+ this.#tasks.set(event.agentId, { ...task, lastTool });
114
+ return true;
115
+ }
88
116
  getTaskSnapshot() {
89
117
  const now = this.#now();
90
118
  for (const [runId, task] of this.#tasks) {
@@ -94,29 +122,13 @@ export class SubagentNotificationStore {
94
122
  }
95
123
  return [...this.#tasks.values()];
96
124
  }
97
- /**
98
- * Records a completion event when it belongs to a background run that has not
99
- * been seen before. Returns whether the notification was novel, so a caller
100
- * can act (wake a turn) only on first sight.
101
- */
125
+ /** Records one novel async completion or question, returning whether it woke the queue. */
102
126
  enqueue(event) {
103
- if (event?.type !== 'subagent_completed' || event.async !== true)
104
- return false;
105
- const result = event.result;
106
- const runId = result?.agentId;
107
- if (!result || !runId)
127
+ const notification = this.#notificationFor(event);
128
+ if (!notification || this.#seen.has(notification.messageId))
108
129
  return false;
109
- if (this.#seen.has(runId))
110
- return false;
111
- this.#pending.set(runId, {
112
- runId,
113
- role: result.role,
114
- status: result.status,
115
- preview: truncatePreview(result.finalText || result.error),
116
- ...(result.error ? { error: result.error } : {}),
117
- completedAt: this.#now(),
118
- });
119
- this.#seen.add(runId);
130
+ this.#pending.set(notification.messageId, notification);
131
+ this.#seen.add(notification.messageId);
120
132
  this.#evictOldestSeen();
121
133
  return true;
122
134
  }
@@ -139,11 +151,11 @@ export class SubagentNotificationStore {
139
151
  const newer = [...this.#pending.values()];
140
152
  this.#pending.clear();
141
153
  for (const notification of notifications) {
142
- this.#pending.set(notification.runId, notification);
143
- this.#seen.add(notification.runId);
154
+ this.#pending.set(notification.messageId, notification);
155
+ this.#seen.add(notification.messageId);
144
156
  }
145
157
  for (const notification of newer)
146
- this.#pending.set(notification.runId, notification);
158
+ this.#pending.set(notification.messageId, notification);
147
159
  }
148
160
  /**
149
161
  * Drops the oldest remembered ids once the cap is exceeded, skipping runs that
@@ -155,13 +167,43 @@ export class SubagentNotificationStore {
155
167
  #evictOldestSeen() {
156
168
  if (this.#seen.size <= this.#deliveredIdCap)
157
169
  return;
158
- for (const runId of this.#seen) {
170
+ for (const messageId of this.#seen) {
159
171
  if (this.#seen.size <= this.#deliveredIdCap)
160
172
  return;
161
- if (this.#pending.has(runId))
173
+ if (this.#pending.has(messageId))
162
174
  continue;
163
- this.#seen.delete(runId);
175
+ this.#seen.delete(messageId);
176
+ }
177
+ }
178
+ #notificationFor(event) {
179
+ if (event.type === 'subagent_completed' && event.async === true) {
180
+ const result = event.result;
181
+ const runId = result?.agentId;
182
+ if (!result || !runId)
183
+ return undefined;
184
+ return {
185
+ kind: 'completion',
186
+ messageId: `completion:${runId}`,
187
+ runId,
188
+ role: result.role,
189
+ status: result.status,
190
+ preview: truncatePreview(result.finalText || result.error),
191
+ ...(result.error ? { error: result.error } : {}),
192
+ completedAt: this.#now(),
193
+ };
194
+ }
195
+ if (event.type === 'subagent_question' && event.async === true && event.messageId && event.runId) {
196
+ return {
197
+ kind: 'question',
198
+ messageId: event.messageId,
199
+ runId: event.runId,
200
+ ...(event.name !== undefined ? { name: event.name } : {}),
201
+ role: event.role,
202
+ question: event.question,
203
+ askedAt: this.#now(),
204
+ };
164
205
  }
206
+ return undefined;
165
207
  }
166
208
  }
167
209
  //# sourceMappingURL=subagent-notification-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"subagent-notification-store.js","sourceRoot":"","sources":["../../../source/services/subagents/subagent-notification-store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAqD7C,MAAM,wBAAwB,GAAG,GAAG,CAAC;AACrC,MAAM,CAAC,MAAM,mCAAmC,GAAG,KAAK,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,yBAAyB;IACpC,QAAQ,GAAG,IAAI,GAAG,EAA0C,CAAC;IAC7D,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1B,MAAM,GAAG,IAAI,GAAG,EAAkC,CAAC;IACnD,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,IAAI,CAAe;IACnB,eAAe,CAAS;IACxB,sBAAsB,CAAS;IAE/B,YAAY,IAAI,GAAkC,EAAE;QAClD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;QACjC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,IAAI,wBAAwB,CAAC,CAAC;QACpF,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,qBAAqB,IAAI,mCAAmC,CAAC,CAAC;IAC/G,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,KAAwB;QACtC,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YAC9D,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAChD,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YAC5D,IAAI,QAAQ,EAAE,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnG,OAAO,KAAK,CAAC;YACf,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE;gBAC7B,KAAK,EAAE,KAAK,CAAC,OAAO;gBACpB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,MAAM,EAAE,SAAS;gBACjB,SAAS,EAAE,QAAQ,EAAE,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE;aAC9C,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAC9E,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,OAAO;YAAE,OAAO,KAAK,CAAC;QACnC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QAE3D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAE5D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE;YAC9B,KAAK,EAAE,MAAM,CAAC,OAAO;YACrB,IAAI,EAAE,QAAQ,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI;YACnC,IAAI,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE;YAC1B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,QAAQ,EAAE,SAAS,IAAI,WAAW;YAC7C,WAAW;SACZ,CAAC,CAAC;QACH,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YACxD,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAC1D,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM;YAChC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,eAAe;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACxB,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACxC,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAC5F,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,KAAwB;QAC9B,IAAI,KAAK,EAAE,IAAI,KAAK,oBAAoB,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAC/E,MAAM,MAAM,GAAI,KAAqC,CAAC,MAAM,CAAC;QAC7D,MAAM,KAAK,GAAG,MAAM,EAAE,OAAO,CAAC;QAC9B,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACpC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAExC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE;YACvB,KAAK;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC;YAC1D,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE;SACzB,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,iFAAiF;IACjF,KAAK;QACH,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,yEAAyE;QACzE,mEAAmE;QACnE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,+EAA+E;IAC/E,MAAM,CAAC,aAAwD;QAC7D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACvC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;YACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;YACpD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,KAAK,MAAM,YAAY,IAAI,KAAK;YAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACxF,CAAC;IAED;;;;;;OAMG;IACH,gBAAgB;QACd,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,eAAe;YAAE,OAAO;QACpD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,eAAe;gBAAE,OAAO;YACpD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YACvC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"subagent-notification-store.js","sourceRoot":"","sources":["../../../source/services/subagents/subagent-notification-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export interface SubagentRunControlOptions {
2
+ maxMailboxMessages?: number;
3
+ maxMailboxCharacters?: number;
4
+ maxContinuationSegments?: number;
5
+ createQuestionId?: () => string;
6
+ }
7
+ export interface PendingSubagentQuestion {
8
+ messageId: string;
9
+ question: string;
10
+ }
11
+ export interface AskedSubagentQuestion extends PendingSubagentQuestion {
12
+ answer: Promise<string>;
13
+ }
14
+ /**
15
+ * Per-logical-run coordination state. The registry owns lifecycle and identity;
16
+ * runners receive only the narrow callbacks they need for a segment.
17
+ */
18
+ export declare class SubagentRunControl {
19
+ #private;
20
+ constructor(options?: SubagentRunControlOptions);
21
+ get currentSegmentController(): AbortController | undefined;
22
+ get activeToolCount(): number;
23
+ get cancellationRequested(): boolean;
24
+ get hasQueuedSteering(): boolean;
25
+ get currentSegmentAbortReason(): 'steer' | 'cancel' | undefined;
26
+ get continuationSegments(): number;
27
+ canStartContinuation(): boolean;
28
+ startContinuation(): boolean;
29
+ get pendingQuestion(): PendingSubagentQuestion | undefined;
30
+ beginSegment(): AbortController;
31
+ endSegment(controller: AbortController): void;
32
+ onToolStart(): void;
33
+ onToolComplete(): void;
34
+ enqueueSteering(message: string): void;
35
+ consumeSteering(): string | undefined;
36
+ ask(question: string): AskedSubagentQuestion;
37
+ answer(messageId: string, answer: string): boolean;
38
+ requestCancellation(): void;
39
+ settle(reason?: Error): void;
40
+ }
41
+ //# sourceMappingURL=subagent-run-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-run-control.d.ts","sourceRoot":"","sources":["../../../source/services/subagents/subagent-run-control.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,yBAAyB;IACxC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IACpE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CACzB;AAOD;;;GAGG;AACH,qBAAa,kBAAkB;;IAgB7B,YAAY,OAAO,GAAE,yBAA8B,EAKlD;IAED,IAAI,wBAAwB,IAAI,eAAe,GAAG,SAAS,CAE1D;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAED,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED,IAAI,yBAAyB,IAAI,OAAO,GAAG,QAAQ,GAAG,SAAS,CAE9D;IAED,IAAI,oBAAoB,IAAI,MAAM,CAEjC;IAED,oBAAoB,IAAI,OAAO,CAE9B;IAED,iBAAiB,IAAI,OAAO,CAI3B;IAED,IAAI,eAAe,IAAI,uBAAuB,GAAG,SAAS,CAEzD;IAED,YAAY,IAAI,eAAe,CAO9B;IAED,UAAU,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,CAM5C;IAED,WAAW,IAAI,IAAI,CAElB;IAED,cAAc,IAAI,IAAI,CAIrB;IAED,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAarC;IAED,eAAe,IAAI,MAAM,GAAG,SAAS,CAQpC;IAED,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CAe3C;IAED,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAMjD;IAED,mBAAmB,IAAI,IAAI,CAO1B;IAED,MAAM,CAAC,MAAM,QAA+C,GAAG,IAAI,CAKlE;CAaF"}
@@ -0,0 +1,166 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ const DEFAULT_MAX_MAILBOX_MESSAGES = 4;
3
+ const DEFAULT_MAX_MAILBOX_CHARACTERS = 4_000;
4
+ const DEFAULT_MAX_CONTINUATION_SEGMENTS = 3;
5
+ const MAX_QUESTION_CHARACTERS = 1_200;
6
+ const TRUNCATION_MARKER = '[Earlier steering omitted]';
7
+ /**
8
+ * Per-logical-run coordination state. The registry owns lifecycle and identity;
9
+ * runners receive only the narrow callbacks they need for a segment.
10
+ */
11
+ export class SubagentRunControl {
12
+ #maxMailboxMessages;
13
+ #maxMailboxCharacters;
14
+ #maxContinuationSegments;
15
+ #createQuestionId;
16
+ #controller;
17
+ #abortReason;
18
+ #activeToolCount = 0;
19
+ #interruptWhenToolsIdle = false;
20
+ #cancellationRequested = false;
21
+ #mailbox = [];
22
+ #mailboxCharacters = 0;
23
+ #mailboxTruncated = false;
24
+ #continuationSegments = 0;
25
+ #question;
26
+ constructor(options = {}) {
27
+ this.#maxMailboxMessages = options.maxMailboxMessages ?? DEFAULT_MAX_MAILBOX_MESSAGES;
28
+ this.#maxMailboxCharacters = options.maxMailboxCharacters ?? DEFAULT_MAX_MAILBOX_CHARACTERS;
29
+ this.#maxContinuationSegments = options.maxContinuationSegments ?? DEFAULT_MAX_CONTINUATION_SEGMENTS;
30
+ this.#createQuestionId = options.createQuestionId ?? randomUUID;
31
+ }
32
+ get currentSegmentController() {
33
+ return this.#controller;
34
+ }
35
+ get activeToolCount() {
36
+ return this.#activeToolCount;
37
+ }
38
+ get cancellationRequested() {
39
+ return this.#cancellationRequested;
40
+ }
41
+ get hasQueuedSteering() {
42
+ return this.#mailbox.length > 0;
43
+ }
44
+ get currentSegmentAbortReason() {
45
+ return this.#abortReason;
46
+ }
47
+ get continuationSegments() {
48
+ return this.#continuationSegments;
49
+ }
50
+ canStartContinuation() {
51
+ return !this.#cancellationRequested && this.#continuationSegments < this.#maxContinuationSegments;
52
+ }
53
+ startContinuation() {
54
+ if (!this.canStartContinuation())
55
+ return false;
56
+ this.#continuationSegments++;
57
+ return true;
58
+ }
59
+ get pendingQuestion() {
60
+ return this.#question && { messageId: this.#question.messageId, question: this.#question.question };
61
+ }
62
+ beginSegment() {
63
+ if (this.#controller)
64
+ throw new Error('A subagent segment is already active.');
65
+ const controller = new AbortController();
66
+ this.#controller = controller;
67
+ this.#abortReason = undefined;
68
+ if (this.#cancellationRequested)
69
+ this.#abortCurrentSegment('cancel');
70
+ return controller;
71
+ }
72
+ endSegment(controller) {
73
+ if (this.#controller !== controller)
74
+ return;
75
+ this.#controller = undefined;
76
+ this.#abortReason = undefined;
77
+ this.#activeToolCount = 0;
78
+ this.#interruptWhenToolsIdle = false;
79
+ }
80
+ onToolStart() {
81
+ this.#activeToolCount++;
82
+ }
83
+ onToolComplete() {
84
+ if (this.#activeToolCount === 0)
85
+ return;
86
+ this.#activeToolCount--;
87
+ if (this.#activeToolCount === 0 && this.#interruptWhenToolsIdle)
88
+ this.#abortCurrentSegment();
89
+ }
90
+ enqueueSteering(message) {
91
+ this.#mailbox.push(message);
92
+ this.#mailboxCharacters += message.length;
93
+ while (this.#mailbox.length > this.#maxMailboxMessages ||
94
+ (this.#mailbox.length > 1 && this.#mailboxCharacters > this.#maxMailboxCharacters)) {
95
+ const removed = this.#mailbox.shift();
96
+ this.#mailboxCharacters -= removed?.length ?? 0;
97
+ this.#mailboxTruncated = true;
98
+ }
99
+ this.#interruptWhenToolsIdle = true;
100
+ if (this.#activeToolCount === 0)
101
+ this.#abortCurrentSegment();
102
+ }
103
+ consumeSteering() {
104
+ if (this.#mailbox.length === 0)
105
+ return undefined;
106
+ const messages = this.#mailbox;
107
+ const truncated = this.#mailboxTruncated;
108
+ this.#mailbox = [];
109
+ this.#mailboxCharacters = 0;
110
+ this.#mailboxTruncated = false;
111
+ return [truncated ? TRUNCATION_MARKER : undefined, ...messages].filter(Boolean).join('\n');
112
+ }
113
+ ask(question) {
114
+ const boundedQuestion = question.trim();
115
+ if (boundedQuestion.length === 0)
116
+ throw new Error('A subagent question cannot be empty.');
117
+ if (boundedQuestion.length > MAX_QUESTION_CHARACTERS)
118
+ throw new Error(`Question exceeds ${MAX_QUESTION_CHARACTERS} characters.`);
119
+ if (this.#question)
120
+ throw new Error('A subagent question is already pending.');
121
+ let resolve;
122
+ let reject;
123
+ const answer = new Promise((resolveAnswer, rejectAnswer) => {
124
+ resolve = resolveAnswer;
125
+ reject = rejectAnswer;
126
+ });
127
+ const pending = { messageId: this.#createQuestionId(), question: boundedQuestion, resolve, reject };
128
+ this.#question = pending;
129
+ return { messageId: pending.messageId, question: boundedQuestion, answer };
130
+ }
131
+ answer(messageId, answer) {
132
+ if (!this.#question || this.#question.messageId !== messageId)
133
+ return false;
134
+ const pending = this.#question;
135
+ this.#question = undefined;
136
+ pending.resolve(answer);
137
+ return true;
138
+ }
139
+ requestCancellation() {
140
+ this.#cancellationRequested = true;
141
+ this.#mailbox = [];
142
+ this.#mailboxCharacters = 0;
143
+ this.#mailboxTruncated = false;
144
+ this.#rejectPendingQuestion(new Error('The subagent run was cancelled.'));
145
+ this.#abortCurrentSegment('cancel');
146
+ }
147
+ settle(reason = new Error('The subagent run was cancelled.')) {
148
+ this.#mailbox = [];
149
+ this.#mailboxCharacters = 0;
150
+ this.#mailboxTruncated = false;
151
+ this.#rejectPendingQuestion(reason);
152
+ }
153
+ #rejectPendingQuestion(reason) {
154
+ if (!this.#question)
155
+ return;
156
+ const pending = this.#question;
157
+ this.#question = undefined;
158
+ pending.reject(reason);
159
+ }
160
+ #abortCurrentSegment(reason = 'steer') {
161
+ this.#abortReason = reason;
162
+ if (this.#controller && !this.#controller.signal.aborted)
163
+ this.#controller.abort();
164
+ }
165
+ }
166
+ //# sourceMappingURL=subagent-run-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-run-control.js","sourceRoot":"","sources":["../../../source/services/subagents/subagent-run-control.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,14 @@
1
1
  import { type Tool, type RunContext } from '@openai/agents';
2
2
  import type { ILoggingService, ISettingsService, ISessionContextService } from '../service-interfaces.js';
3
3
  import type { ExecutionContext } from '../execution-context.js';
4
- import type { SubagentDefinition, SupportedSubagentRole } from './types.js';
4
+ import type { SubagentDefinition, SupportedSubagentRole, ValidationEvidence } from './types.js';
5
5
  import type { CommandMessage, ToolDefinition } from '../../tools/types.js';
6
6
  import type { SkillsService } from '../skills/skills-service.js';
7
7
  import type { ISubagentClient } from './subagent-client-types.js';
8
+ /** A mutable holder for the last validation evidence captured from a shell run. */
9
+ export interface ValidationCapture {
10
+ value?: ValidationEvidence;
11
+ }
8
12
  export type SubagentRunContext = {
9
13
  agentId: string;
10
14
  role: SupportedSubagentRole;
@@ -14,9 +18,19 @@ export type SubagentRunContext = {
14
18
  activeCommandMessages: Record<string, CommandMessage[]>;
15
19
  turnCount: number;
16
20
  maxTurns: number;
21
+ /** Per-file line deltas for diffStat, captured from editor-tool writes. */
22
+ diffDeltas?: Map<string, {
23
+ added: number;
24
+ deleted: number;
25
+ }>;
26
+ /** Last validation-shaped shell command evidence. */
27
+ lastValidation?: ValidationCapture;
17
28
  };
18
29
  export declare function getSubagentRunContext(context: unknown): SubagentRunContext | undefined;
19
30
  export declare function formatRunningCommandMessages(definition: ToolDefinition, params: unknown): CommandMessage[];
31
+ declare function isValidationCommand(command: string): boolean;
32
+ export declare function captureValidationIfMatch(capture: ValidationCapture | undefined, command: string, result: unknown): void;
33
+ export { isValidationCommand };
20
34
  export declare class SubagentToolPolicy {
21
35
  #private;
22
36
  constructor(deps: {
@@ -31,10 +45,13 @@ export declare class SubagentToolPolicy {
31
45
  extractPathsFromCommand(command: string, cwd: string): string[];
32
46
  extractSuccessfulWritePaths(result: unknown): string[];
33
47
  isYellowCommandApproved(command: string, taskContext: string): Promise<boolean>;
34
- wrapShellTool(definition: ToolDefinition, cwd: string, filesChanged: string[], taskContext: string): ToolDefinition;
48
+ wrapShellTool(definition: ToolDefinition, cwd: string, filesChanged: string[], taskContext: string, validationCapture?: ValidationCapture): ToolDefinition;
35
49
  wrapNestedShellTool(definition: ToolDefinition, cwd: string): ToolDefinition;
36
50
  wrapReadOnlyShellTool(definition: ToolDefinition): ToolDefinition;
37
- wrapWriteTool(definition: ToolDefinition, cwd: string, filesChanged: string[], extractPaths: (params: any) => string[], nestedApprovals?: boolean): ToolDefinition;
51
+ wrapWriteTool(definition: ToolDefinition, cwd: string, filesChanged: string[], extractPaths: (params: any) => string[], nestedApprovals?: boolean, diffDeltas?: Map<string, {
52
+ added: number;
53
+ deleted: number;
54
+ }>): ToolDefinition;
38
55
  /**
39
56
  * Wrap a read tool with filesystem scope enforcement.
40
57
  * When `scopePatterns` is defined (non-undefined), every path read must
@@ -89,7 +106,10 @@ export declare class SubagentToolFactory {
89
106
  toolPolicy: SubagentToolPolicy;
90
107
  skillsService?: SkillsService;
91
108
  });
92
- buildToolDefinitions(definition: SubagentDefinition, filesChanged: string[], taskContext: string, searchViaShell: boolean, nestedApprovals?: boolean): ToolDefinition[];
109
+ buildToolDefinitions(definition: SubagentDefinition, filesChanged: string[], taskContext: string, searchViaShell: boolean, nestedApprovals?: boolean, diffDeltas?: Map<string, {
110
+ added: number;
111
+ deleted: number;
112
+ }>, validationCapture?: ValidationCapture, askOrchestrator?: (question: string) => Promise<string>): ToolDefinition[];
93
113
  buildAgentTools(toolDefinitions: ToolDefinition[], options: {
94
114
  providerId: string;
95
115
  onToolStart?: (toolName: string, params: unknown, commandMessages: CommandMessage[], context?: RunContext<unknown>, details?: unknown) => void;