@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.
- package/dist/agent.d.ts +11 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +54 -18
- package/dist/agent.js.map +1 -1
- package/dist/components/layout/BackgroundTasksPanel.d.ts.map +1 -1
- package/dist/components/layout/BackgroundTasksPanel.js +35 -16
- package/dist/components/layout/BackgroundTasksPanel.js.map +1 -1
- package/dist/components/message/CommandMessage.js +4 -2
- package/dist/components/message/CommandMessage.js.map +1 -1
- package/dist/components/message/command-message-helpers.d.ts +4 -4
- package/dist/hooks/conversation-ui-reducer.d.ts +5 -0
- package/dist/hooks/conversation-ui-reducer.d.ts.map +1 -1
- package/dist/hooks/conversation-ui-reducer.js +8 -0
- package/dist/hooks/conversation-ui-reducer.js.map +1 -1
- package/dist/hooks/use-conversation.d.ts.map +1 -1
- package/dist/hooks/use-conversation.js +1 -0
- package/dist/hooks/use-conversation.js.map +1 -1
- package/dist/lib/agent-configuration.d.ts.map +1 -1
- package/dist/lib/agent-configuration.js +3 -0
- package/dist/lib/agent-configuration.js.map +1 -1
- package/dist/lib/agent-factory.d.ts +11 -0
- package/dist/lib/agent-factory.d.ts.map +1 -1
- package/dist/lib/agent-factory.js +3 -0
- package/dist/lib/agent-factory.js.map +1 -1
- package/dist/lib/chained-input-filter.d.ts +20 -0
- package/dist/lib/chained-input-filter.d.ts.map +1 -1
- package/dist/lib/chained-input-filter.js +75 -0
- package/dist/lib/chained-input-filter.js.map +1 -1
- package/dist/lib/subagent-bridge.d.ts +20 -1
- package/dist/lib/subagent-bridge.d.ts.map +1 -1
- package/dist/lib/subagent-bridge.js +26 -0
- package/dist/lib/subagent-bridge.js.map +1 -1
- package/dist/prompts/anthropic.md +6 -55
- package/dist/prompts/async-subagent-delegation.d.ts +2 -1
- package/dist/prompts/async-subagent-delegation.d.ts.map +1 -1
- package/dist/prompts/async-subagent-delegation.js +20 -6
- package/dist/prompts/async-subagent-delegation.js.map +1 -1
- package/dist/prompts/async-subagent-delegation.ts +26 -6
- package/dist/prompts/gpt-5.6.md +49 -0
- package/dist/prompts/kimi.md +25 -63
- package/dist/prompts/orchestrator-prompt.test.ts +77 -0
- package/dist/prompts/orchestrator.md +15 -1
- package/dist/prompts/prompt-constructor.d.ts +1 -0
- package/dist/prompts/prompt-constructor.d.ts.map +1 -1
- package/dist/prompts/prompt-constructor.js +6 -2
- package/dist/prompts/prompt-constructor.js.map +1 -1
- package/dist/prompts/prompt-constructor.test.ts +22 -1
- package/dist/prompts/prompt-constructor.ts +9 -1
- package/dist/prompts/prompt-profiles.d.ts.map +1 -1
- package/dist/prompts/prompt-profiles.js +5 -0
- package/dist/prompts/prompt-profiles.js.map +1 -1
- package/dist/prompts/prompt-profiles.test.ts +20 -0
- package/dist/prompts/prompt-profiles.ts +5 -0
- package/dist/prompts/search-via-shell.d.ts.map +1 -1
- package/dist/prompts/search-via-shell.js +8 -25
- package/dist/prompts/search-via-shell.js.map +1 -1
- package/dist/prompts/search-via-shell.test.ts +18 -0
- package/dist/prompts/search-via-shell.ts +8 -25
- package/dist/prompts/subagent-delegation.test.ts +15 -0
- package/dist/prompts/subagents/researcher.md +6 -0
- package/dist/prompts/subagents/worker-prompt.test.ts +35 -0
- package/dist/prompts/subagents/worker.md +8 -0
- package/dist/services/conversation/conversation-adapter.d.ts +11 -3
- package/dist/services/conversation/conversation-adapter.d.ts.map +1 -1
- package/dist/services/conversation/conversation-adapter.js +123 -31
- package/dist/services/conversation/conversation-adapter.js.map +1 -1
- package/dist/services/conversation/conversation-events.d.ts +25 -1
- package/dist/services/conversation/conversation-events.d.ts.map +1 -1
- package/dist/services/conversation/conversation-orchestrator.d.ts.map +1 -1
- package/dist/services/conversation/conversation-orchestrator.js +141 -26
- package/dist/services/conversation/conversation-orchestrator.js.map +1 -1
- package/dist/services/conversation/conversation-orchestrator.types.d.ts +2 -0
- package/dist/services/conversation/conversation-orchestrator.types.d.ts.map +1 -1
- package/dist/services/conversation/conversation-service.d.ts +3 -0
- package/dist/services/conversation/conversation-service.d.ts.map +1 -1
- package/dist/services/conversation/conversation-service.js +4 -0
- package/dist/services/conversation/conversation-service.js.map +1 -1
- package/dist/services/logging/conversation-log-events.d.ts +9 -1
- package/dist/services/logging/conversation-log-events.d.ts.map +1 -1
- package/dist/services/logging/conversation-log-events.js.map +1 -1
- package/dist/services/logging/conversation-log-writer.d.ts +1 -0
- package/dist/services/logging/conversation-log-writer.d.ts.map +1 -1
- package/dist/services/logging/conversation-log-writer.js +1 -1
- package/dist/services/logging/conversation-log-writer.js.map +1 -1
- package/dist/services/logging/conversation-logger.d.ts.map +1 -1
- package/dist/services/logging/conversation-logger.js +10 -0
- package/dist/services/logging/conversation-logger.js.map +1 -1
- package/dist/services/queue/queue-controller.d.ts +1 -0
- package/dist/services/queue/queue-controller.d.ts.map +1 -1
- package/dist/services/queue/queue-controller.js +7 -4
- package/dist/services/queue/queue-controller.js.map +1 -1
- package/dist/services/retry/retry-classifier.d.ts.map +1 -1
- package/dist/services/retry/retry-classifier.js +4 -2
- package/dist/services/retry/retry-classifier.js.map +1 -1
- package/dist/services/subagents/execution-runner.d.ts +3 -3
- package/dist/services/subagents/execution-runner.d.ts.map +1 -1
- package/dist/services/subagents/execution-runner.js +96 -7
- package/dist/services/subagents/execution-runner.js.map +1 -1
- package/dist/services/subagents/mentor-runner.d.ts.map +1 -1
- package/dist/services/subagents/mentor-runner.js +24 -5
- package/dist/services/subagents/mentor-runner.js.map +1 -1
- package/dist/services/subagents/runtime.d.ts.map +1 -1
- package/dist/services/subagents/runtime.js +17 -7
- package/dist/services/subagents/runtime.js.map +1 -1
- package/dist/services/subagents/subagent-async-registry.d.ts +30 -2
- package/dist/services/subagents/subagent-async-registry.d.ts.map +1 -1
- package/dist/services/subagents/subagent-async-registry.js +314 -41
- package/dist/services/subagents/subagent-async-registry.js.map +1 -1
- package/dist/services/subagents/subagent-manager.d.ts +15 -1
- package/dist/services/subagents/subagent-manager.d.ts.map +1 -1
- package/dist/services/subagents/subagent-manager.js +16 -0
- package/dist/services/subagents/subagent-manager.js.map +1 -1
- package/dist/services/subagents/subagent-notification-store.d.ts +40 -22
- package/dist/services/subagents/subagent-notification-store.d.ts.map +1 -1
- package/dist/services/subagents/subagent-notification-store.js +81 -39
- package/dist/services/subagents/subagent-notification-store.js.map +1 -1
- package/dist/services/subagents/subagent-run-control.d.ts +41 -0
- package/dist/services/subagents/subagent-run-control.d.ts.map +1 -0
- package/dist/services/subagents/subagent-run-control.js +166 -0
- package/dist/services/subagents/subagent-run-control.js.map +1 -0
- package/dist/services/subagents/tool-policy.d.ts +24 -4
- package/dist/services/subagents/tool-policy.d.ts.map +1 -1
- package/dist/services/subagents/tool-policy.js +134 -14
- package/dist/services/subagents/tool-policy.js.map +1 -1
- package/dist/services/subagents/types.d.ts +93 -0
- package/dist/services/subagents/types.d.ts.map +1 -1
- package/dist/tools/agent/ask-orchestrator.d.ts +11 -0
- package/dist/tools/agent/ask-orchestrator.d.ts.map +1 -0
- package/dist/tools/agent/ask-orchestrator.js +39 -0
- package/dist/tools/agent/ask-orchestrator.js.map +1 -0
- package/dist/tools/agent/run-subagent-async.d.ts +43 -1
- package/dist/tools/agent/run-subagent-async.d.ts.map +1 -1
- package/dist/tools/agent/run-subagent-async.js +230 -7
- package/dist/tools/agent/run-subagent-async.js.map +1 -1
- package/dist/tools/file/code-context.d.ts +1 -0
- package/dist/tools/file/code-context.d.ts.map +1 -1
- package/dist/tools/file/code-context.js +4 -4
- package/dist/tools/file/code-context.js.map +1 -1
- package/dist/tools/file/grep.d.ts +1 -0
- package/dist/tools/file/grep.d.ts.map +1 -1
- package/dist/tools/file/grep.js +16 -10
- package/dist/tools/file/grep.js.map +1 -1
- package/dist/utils/conversation/conversation-event-handler.d.ts.map +1 -1
- package/dist/utils/conversation/conversation-event-handler.js +6 -3
- package/dist/utils/conversation/conversation-event-handler.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ConversationEvent } from '../conversation/conversation-events.js';
|
|
2
|
-
/** A background
|
|
3
|
-
export interface
|
|
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
|
|
42
|
-
* and TTLs terminal runs out after 30 minutes, so a few
|
|
43
|
-
*
|
|
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
|
|
53
|
-
* Foreground and nested
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
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
|
|
65
|
-
* stays deduped across both paths, so a retained notification is
|
|
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
|
|
73
|
-
*
|
|
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,
|
|
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
|
|
9
|
-
* Foreground and nested
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
|
21
|
-
* stays deduped across both paths, so a retained notification is
|
|
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
|
|
39
|
-
*
|
|
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
|
-
|
|
104
|
-
|
|
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
|
-
|
|
110
|
-
|
|
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.
|
|
143
|
-
this.#seen.add(notification.
|
|
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.
|
|
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
|
|
170
|
+
for (const messageId of this.#seen) {
|
|
159
171
|
if (this.#seen.size <= this.#deliveredIdCap)
|
|
160
172
|
return;
|
|
161
|
-
if (this.#pending.has(
|
|
173
|
+
if (this.#pending.has(messageId))
|
|
162
174
|
continue;
|
|
163
|
-
this.#seen.delete(
|
|
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":"
|
|
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
|
|
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
|
|
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;
|