@gajae-code/coding-agent 0.3.0 → 0.3.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/CHANGELOG.md +18 -0
- package/dist/types/async/job-manager.d.ts +7 -0
- package/dist/types/cli/args.d.ts +1 -1
- package/dist/types/commands/deep-interview.d.ts +3 -0
- package/dist/types/config/keybindings.d.ts +5 -0
- package/dist/types/config/settings-schema.d.ts +4 -4
- package/dist/types/debug/crash-diagnostics.d.ts +45 -0
- package/dist/types/debug/runtime-gauges.d.ts +6 -0
- package/dist/types/deep-interview/render-middleware.d.ts +1 -0
- package/dist/types/eval/py/executor.d.ts +2 -0
- package/dist/types/eval/py/kernel.d.ts +2 -0
- package/dist/types/exec/bash-executor.d.ts +10 -0
- package/dist/types/gjc-runtime/cli-write-receipt.d.ts +24 -0
- package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +1 -0
- package/dist/types/gjc-runtime/state-migrations.d.ts +9 -0
- package/dist/types/gjc-runtime/state-schema.d.ts +317 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +10 -0
- package/dist/types/gjc-runtime/workflow-command-ref.d.ts +43 -0
- package/dist/types/harness-control-plane/control-endpoint.d.ts +3 -2
- package/dist/types/hooks/skill-state.d.ts +21 -0
- package/dist/types/internal-urls/agent-protocol.d.ts +2 -2
- package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
- package/dist/types/internal-urls/registry-helpers.d.ts +8 -7
- package/dist/types/internal-urls/types.d.ts +4 -0
- package/dist/types/lsp/index.d.ts +10 -10
- package/dist/types/modes/bridge/auth.d.ts +12 -0
- package/dist/types/modes/bridge/bridge-client-bridge.d.ts +9 -0
- package/dist/types/modes/bridge/bridge-mode.d.ts +44 -0
- package/dist/types/modes/bridge/bridge-ui-context.d.ts +88 -0
- package/dist/types/modes/bridge/event-stream.d.ts +8 -0
- package/dist/types/modes/components/custom-editor.d.ts +6 -0
- package/dist/types/modes/components/jobs-overlay-model.d.ts +31 -0
- package/dist/types/modes/components/jobs-overlay.d.ts +30 -0
- package/dist/types/modes/components/status-line/types.d.ts +2 -0
- package/dist/types/modes/components/status-line.d.ts +2 -0
- package/dist/types/modes/controllers/input-controller.d.ts +1 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +8 -0
- package/dist/types/modes/index.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/jobs-observer.d.ts +57 -0
- package/dist/types/modes/rpc/host-tools.d.ts +1 -16
- package/dist/types/modes/rpc/host-uris.d.ts +1 -38
- package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +20 -0
- package/dist/types/modes/shared/agent-wire/command-validation.d.ts +2 -0
- package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +24 -0
- package/dist/types/modes/shared/agent-wire/handshake.d.ts +46 -0
- package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +16 -0
- package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +17 -0
- package/dist/types/modes/shared/agent-wire/protocol.d.ts +44 -0
- package/dist/types/modes/shared/agent-wire/responses.d.ts +4 -0
- package/dist/types/modes/shared/agent-wire/scopes.d.ts +18 -0
- package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +42 -0
- package/dist/types/modes/shared/agent-wire/ui-result.d.ts +27 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/session/agent-session.d.ts +11 -1
- package/dist/types/skill-state/workflow-state-contract.d.ts +1 -2
- package/dist/types/skill-state/workflow-state-version.d.ts +3 -0
- package/dist/types/task/id.d.ts +7 -0
- package/dist/types/task/index.d.ts +5 -0
- package/dist/types/task/receipt.d.ts +85 -0
- package/dist/types/task/spawn-gate.d.ts +38 -0
- package/dist/types/task/types.d.ts +143 -11
- package/dist/types/tools/cron.d.ts +6 -0
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/path-utils.d.ts +1 -0
- package/dist/types/tools/subagent.d.ts +15 -0
- package/package.json +7 -7
- package/scripts/build-binary.ts +7 -0
- package/src/async/job-manager.ts +36 -0
- package/src/cli/args.ts +9 -2
- package/src/commands/deep-interview.ts +1 -0
- package/src/commands/harness.ts +289 -19
- package/src/commands/launch.ts +2 -2
- package/src/commands/state.ts +2 -1
- package/src/commands/team.ts +22 -4
- package/src/config/keybindings.ts +6 -0
- package/src/config/settings-schema.ts +6 -3
- package/src/dap/client.ts +17 -3
- package/src/debug/crash-diagnostics.ts +223 -0
- package/src/debug/runtime-gauges.ts +20 -0
- package/src/deep-interview/render-middleware.ts +6 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/defaults/gjc/skills/ralplan/SKILL.md +31 -2
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +28 -2
- package/src/eval/py/executor.ts +21 -1
- package/src/eval/py/kernel.ts +15 -0
- package/src/exec/bash-executor.ts +41 -0
- package/src/gjc-runtime/cli-write-receipt.ts +31 -0
- package/src/gjc-runtime/deep-interview-runtime.ts +69 -32
- package/src/gjc-runtime/ralplan-runtime.ts +213 -36
- package/src/gjc-runtime/state-migrations.ts +54 -7
- package/src/gjc-runtime/state-runtime.ts +461 -64
- package/src/gjc-runtime/state-schema.ts +192 -0
- package/src/gjc-runtime/state-writer.ts +32 -1
- package/src/gjc-runtime/team-runtime.ts +177 -105
- package/src/gjc-runtime/ultragoal-runtime.ts +114 -26
- package/src/gjc-runtime/workflow-command-ref.ts +239 -0
- package/src/gjc-runtime/workflow-manifest.generated.json +108 -4
- package/src/gjc-runtime/workflow-manifest.ts +3 -1
- package/src/harness-control-plane/control-endpoint.ts +19 -8
- package/src/harness-control-plane/owner.ts +57 -10
- package/src/harness-control-plane/state-machine.ts +2 -1
- package/src/hooks/skill-state.ts +176 -26
- package/src/internal-urls/agent-protocol.ts +68 -21
- package/src/internal-urls/artifact-protocol.ts +12 -17
- package/src/internal-urls/docs-index.generated.ts +3 -2
- package/src/internal-urls/registry-helpers.ts +19 -16
- package/src/internal-urls/types.ts +4 -0
- package/src/lsp/client.ts +18 -2
- package/src/main.ts +21 -5
- package/src/modes/bridge/auth.ts +41 -0
- package/src/modes/bridge/bridge-client-bridge.ts +47 -0
- package/src/modes/bridge/bridge-mode.ts +520 -0
- package/src/modes/bridge/bridge-ui-context.ts +200 -0
- package/src/modes/bridge/event-stream.ts +70 -0
- package/src/modes/components/custom-editor.ts +101 -0
- package/src/modes/components/hook-selector.ts +61 -18
- package/src/modes/components/jobs-overlay-model.ts +109 -0
- package/src/modes/components/jobs-overlay.ts +172 -0
- package/src/modes/components/status-line/presets.ts +7 -5
- package/src/modes/components/status-line/segments.ts +25 -0
- package/src/modes/components/status-line/types.ts +2 -0
- package/src/modes/components/status-line.ts +9 -1
- package/src/modes/controllers/extension-ui-controller.ts +39 -3
- package/src/modes/controllers/input-controller.ts +97 -9
- package/src/modes/controllers/selector-controller.ts +29 -0
- package/src/modes/index.ts +1 -0
- package/src/modes/interactive-mode.ts +27 -0
- package/src/modes/jobs-observer.ts +204 -0
- package/src/modes/rpc/host-tools.ts +1 -186
- package/src/modes/rpc/host-uris.ts +1 -235
- package/src/modes/rpc/rpc-client.ts +25 -10
- package/src/modes/rpc/rpc-mode.ts +12 -381
- package/src/modes/shared/agent-wire/command-dispatch.ts +341 -0
- package/src/modes/shared/agent-wire/command-validation.ts +131 -0
- package/src/modes/shared/agent-wire/event-envelope.ts +108 -0
- package/src/modes/shared/agent-wire/handshake.ts +117 -0
- package/src/modes/shared/agent-wire/host-tool-bridge.ts +194 -0
- package/src/modes/shared/agent-wire/host-uri-bridge.ts +236 -0
- package/src/modes/shared/agent-wire/protocol.ts +96 -0
- package/src/modes/shared/agent-wire/responses.ts +17 -0
- package/src/modes/shared/agent-wire/scopes.ts +89 -0
- package/src/modes/shared/agent-wire/ui-request-broker.ts +150 -0
- package/src/modes/shared/agent-wire/ui-result.ts +48 -0
- package/src/modes/types.ts +1 -0
- package/src/prompts/tools/subagent.md +12 -7
- package/src/prompts/tools/task-summary.md +3 -9
- package/src/prompts/tools/task.md +5 -1
- package/src/sdk.ts +4 -0
- package/src/session/agent-session.ts +214 -38
- package/src/skill-state/deep-interview-mutation-guard.ts +23 -4
- package/src/skill-state/workflow-state-contract.ts +7 -4
- package/src/skill-state/workflow-state-version.ts +3 -0
- package/src/slash-commands/builtin-registry.ts +8 -0
- package/src/task/executor.ts +29 -5
- package/src/task/id.ts +33 -0
- package/src/task/index.ts +257 -67
- package/src/task/output-manager.ts +5 -4
- package/src/task/receipt.ts +297 -0
- package/src/task/render.ts +48 -131
- package/src/task/spawn-gate.ts +132 -0
- package/src/task/types.ts +48 -7
- package/src/tools/ask.ts +73 -33
- package/src/tools/ast-edit.ts +1 -0
- package/src/tools/ast-grep.ts +1 -0
- package/src/tools/bash.ts +1 -1
- package/src/tools/cron.ts +48 -0
- package/src/tools/find.ts +4 -1
- package/src/tools/index.ts +2 -0
- package/src/tools/path-utils.ts +3 -2
- package/src/tools/read.ts +1 -0
- package/src/tools/search.ts +1 -0
- package/src/tools/skill.ts +6 -1
- package/src/tools/subagent.ts +237 -84
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport-neutral request/response broker for UI and permission surfaces.
|
|
3
|
+
*
|
|
4
|
+
* The bridge protocol has one authoritative responder per session. Requests are
|
|
5
|
+
* correlated by id, resolved exactly once, cancelled on timeout/disconnect, and
|
|
6
|
+
* protected by an owner token so observers cannot race approvals.
|
|
7
|
+
*/
|
|
8
|
+
import { randomUUID } from "node:crypto";
|
|
9
|
+
|
|
10
|
+
export type UiRequestCancelReason = "timeout" | "abort" | "disconnect";
|
|
11
|
+
|
|
12
|
+
export interface UiRequestCancelled {
|
|
13
|
+
status: "cancelled";
|
|
14
|
+
reason: UiRequestCancelReason;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type UiRequestResolution<TResponse> = TResponse | UiRequestCancelled;
|
|
18
|
+
|
|
19
|
+
export type UiBrokerResponseResult =
|
|
20
|
+
| { status: "accepted" }
|
|
21
|
+
| { status: "rejected"; code: "not_controller" | "already_resolved" | "unknown_request" };
|
|
22
|
+
|
|
23
|
+
export interface UiRequestBrokerOptions<TRequest> {
|
|
24
|
+
emitRequest: (correlationId: string, request: TRequest) => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface UiRequestOptions {
|
|
28
|
+
correlationId?: string;
|
|
29
|
+
timeoutMs?: number;
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface PendingRequest<TResponse> {
|
|
34
|
+
resolve: (value: UiRequestResolution<TResponse>) => void;
|
|
35
|
+
timer: Timer | undefined;
|
|
36
|
+
onAbort: (() => void) | undefined;
|
|
37
|
+
signal: AbortSignal | undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Broker for one active session. v1 supports one controller token at a time;
|
|
42
|
+
* other clients may observe frames but cannot answer correlated requests.
|
|
43
|
+
*/
|
|
44
|
+
export class UiRequestBroker<TRequest, TResponse> {
|
|
45
|
+
readonly #emitRequest: (correlationId: string, request: TRequest) => void;
|
|
46
|
+
#ownerToken: string | undefined;
|
|
47
|
+
#pending = new Map<string, PendingRequest<TResponse>>();
|
|
48
|
+
#resolved = new Set<string>();
|
|
49
|
+
|
|
50
|
+
constructor(options: UiRequestBrokerOptions<TRequest>) {
|
|
51
|
+
this.#emitRequest = options.emitRequest;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get ownerToken(): string | undefined {
|
|
55
|
+
return this.#ownerToken;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get pendingCount(): number {
|
|
59
|
+
return this.#pending.size;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
claimController(ownerToken: string = randomUUID()): { status: "claimed"; ownerToken: string } | { status: "busy" } {
|
|
63
|
+
if (this.#ownerToken) return { status: "busy" };
|
|
64
|
+
this.#ownerToken = ownerToken;
|
|
65
|
+
return { status: "claimed", ownerToken: this.#ownerToken };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
releaseController(ownerToken: string): boolean {
|
|
69
|
+
if (ownerToken !== this.#ownerToken) return false;
|
|
70
|
+
this.#ownerToken = undefined;
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
request(request: TRequest, options: UiRequestOptions = {}): Promise<UiRequestResolution<TResponse>> {
|
|
75
|
+
const correlationId = options.correlationId ?? randomUUID();
|
|
76
|
+
if (this.#pending.has(correlationId) || this.#resolved.has(correlationId)) {
|
|
77
|
+
throw new Error(`Duplicate UI request correlation id: ${correlationId}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const { promise, resolve } = Promise.withResolvers<UiRequestResolution<TResponse>>();
|
|
81
|
+
let timer: Timer | undefined;
|
|
82
|
+
let onAbort: (() => void) | undefined;
|
|
83
|
+
const settle = (value: UiRequestResolution<TResponse>) => {
|
|
84
|
+
const pending = this.#pending.get(correlationId);
|
|
85
|
+
if (!pending) return;
|
|
86
|
+
this.#pending.delete(correlationId);
|
|
87
|
+
this.#resolved.add(correlationId);
|
|
88
|
+
if (pending.timer) clearTimeout(pending.timer);
|
|
89
|
+
if (pending.onAbort) pending.signal?.removeEventListener("abort", pending.onAbort);
|
|
90
|
+
pending.resolve(value);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
if (options.timeoutMs !== undefined) {
|
|
94
|
+
timer = setTimeout(() => settle({ status: "cancelled", reason: "timeout" }), options.timeoutMs);
|
|
95
|
+
}
|
|
96
|
+
if (options.signal) {
|
|
97
|
+
onAbort = () => settle({ status: "cancelled", reason: "abort" });
|
|
98
|
+
if (options.signal.aborted) {
|
|
99
|
+
resolve({ status: "cancelled", reason: "abort" });
|
|
100
|
+
this.#resolved.add(correlationId);
|
|
101
|
+
return promise;
|
|
102
|
+
}
|
|
103
|
+
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
this.#pending.set(correlationId, { resolve, timer, onAbort, signal: options.signal });
|
|
107
|
+
this.#emitRequest(correlationId, request);
|
|
108
|
+
return promise;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
respond(correlationId: string, ownerToken: string, response: TResponse): UiBrokerResponseResult {
|
|
112
|
+
if (ownerToken !== this.#ownerToken) return { status: "rejected", code: "not_controller" };
|
|
113
|
+
const pending = this.#pending.get(correlationId);
|
|
114
|
+
if (!pending) {
|
|
115
|
+
return {
|
|
116
|
+
status: "rejected",
|
|
117
|
+
code: this.#resolved.has(correlationId) ? "already_resolved" : "unknown_request",
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
this.#pending.delete(correlationId);
|
|
121
|
+
this.#resolved.add(correlationId);
|
|
122
|
+
if (pending.timer) clearTimeout(pending.timer);
|
|
123
|
+
if (pending.onAbort) pending.signal?.removeEventListener("abort", pending.onAbort);
|
|
124
|
+
pending.resolve(response);
|
|
125
|
+
return { status: "accepted" };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
cancelAll(reason: UiRequestCancelReason): void {
|
|
129
|
+
for (const correlationId of [...this.#pending.keys()]) {
|
|
130
|
+
this.cancel(correlationId, reason);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
cancel(correlationId: string, reason: UiRequestCancelReason): boolean {
|
|
135
|
+
const pending = this.#pending.get(correlationId);
|
|
136
|
+
if (!pending) return false;
|
|
137
|
+
this.#pending.delete(correlationId);
|
|
138
|
+
this.#resolved.add(correlationId);
|
|
139
|
+
if (pending.timer) clearTimeout(pending.timer);
|
|
140
|
+
if (pending.onAbort) pending.signal?.removeEventListener("abort", pending.onAbort);
|
|
141
|
+
pending.resolve({ status: "cancelled", reason });
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
disconnectController(ownerToken: string): boolean {
|
|
146
|
+
if (!this.releaseController(ownerToken)) return false;
|
|
147
|
+
this.cancelAll("disconnect");
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed UI/manipulation result semantics for bridge-capability handling.
|
|
3
|
+
*
|
|
4
|
+
* `unsupported` is distinct from both a real value and user cancellation. This
|
|
5
|
+
* prevents local-only or undeclared `ExtensionUIContext` surfaces from becoming
|
|
6
|
+
* silent no-ops that look like user intent.
|
|
7
|
+
*/
|
|
8
|
+
export interface BridgeUiValue<TValue> {
|
|
9
|
+
status: "value";
|
|
10
|
+
value: TValue;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface BridgeUiCancelled {
|
|
14
|
+
status: "cancelled";
|
|
15
|
+
reason?: "user" | "timeout" | "abort" | "disconnect";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface BridgeUiUnsupported {
|
|
19
|
+
status: "unsupported";
|
|
20
|
+
capability: string;
|
|
21
|
+
reason: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type BridgeUiResult<TValue> = BridgeUiValue<TValue> | BridgeUiCancelled | BridgeUiUnsupported;
|
|
25
|
+
|
|
26
|
+
export function uiValue<TValue>(value: TValue): BridgeUiValue<TValue> {
|
|
27
|
+
return { status: "value", value };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function uiCancelled(reason?: BridgeUiCancelled["reason"]): BridgeUiCancelled {
|
|
31
|
+
return reason ? { status: "cancelled", reason } : { status: "cancelled" };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function uiUnsupported(capability: string, reason: string): BridgeUiUnsupported {
|
|
35
|
+
return { status: "unsupported", capability, reason };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function isUiUnsupported<TValue>(result: BridgeUiResult<TValue>): result is BridgeUiUnsupported {
|
|
39
|
+
return result.status === "unsupported";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function isUiCancelled<TValue>(result: BridgeUiResult<TValue>): result is BridgeUiCancelled {
|
|
43
|
+
return result.status === "cancelled";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function isUiValue<TValue>(result: BridgeUiResult<TValue>): result is BridgeUiValue<TValue> {
|
|
47
|
+
return result.status === "value";
|
|
48
|
+
}
|
package/src/modes/types.ts
CHANGED
|
@@ -249,6 +249,7 @@ export interface InteractiveModeContext {
|
|
|
249
249
|
showHookConfirm(title: string, message: string): Promise<boolean>;
|
|
250
250
|
showDebugSelector(): void;
|
|
251
251
|
showSessionObserver(): void;
|
|
252
|
+
showJobsOverlay(): void;
|
|
252
253
|
resetObserverRegistry(): void;
|
|
253
254
|
|
|
254
255
|
// Input handling
|
|
@@ -2,19 +2,22 @@ Lists, inspects, awaits, pauses, resumes, steers, or cancels detached task subag
|
|
|
2
2
|
|
|
3
3
|
Task launches return immediately. Use this tool when you need direct control over those running subagents. Prefer `subagent` for task subagents; generic `job` remains available for non-subagent jobs and compatibility fallback access.
|
|
4
4
|
|
|
5
|
+
`verbosity` controls output size: `receipt` (default) returns status metadata plus a single <=280-character result/error preview and an `agent://<id>` output ref when available; `preview` returns <=2000 characters; `full` returns <=12000 characters and requires explicit `ids`.
|
|
6
|
+
|
|
5
7
|
# Operations
|
|
6
8
|
|
|
7
9
|
## `action: "list"`
|
|
8
|
-
Snapshot your visible detached subagents, including `running`, `paused`, `queued`, and terminal subagents when retained.
|
|
10
|
+
Snapshot your visible detached subagents, including `running`, `paused`, `queued`, and terminal subagents when retained. Output is receipt-only by default; use `verbosity: "preview"` for a bounded preview or inspect explicit `ids` with `verbosity: "full"` when fuller retained text is necessary.
|
|
9
11
|
|
|
10
12
|
## `action: "inspect"`
|
|
11
|
-
Inspect selected subagents by `ids`; omit `ids` to inspect current running subagents. Terminal subagents
|
|
13
|
+
Inspect selected subagents by `ids`; omit `ids` to inspect current running subagents. Terminal subagents return receipt-only output by default, with an `agent://<id>` ref when a verified output artifact is available. `verbosity: "full"` requires explicit `ids`.
|
|
12
14
|
|
|
13
15
|
## `action: "await"`
|
|
14
16
|
Wait for selected subagents by `ids`; omit `ids` to wait for current running subagents.
|
|
15
17
|
- Always set `timeout_ms` when the result is not immediately required forever.
|
|
16
18
|
- Await timeout only bounds this tool call's wait; it does not stop the subagent and is not a failure reason.
|
|
17
19
|
- On timeout, inspect progress and keep doing independent work. Never cancel just because an await timed out; cancel only if the subagent has actually failed, gone off-track, or become unrecoverably wrong.
|
|
20
|
+
- Completed results are receipt-first by default: bounded preview plus `agent://<id>` output ref when available, not full retained output.
|
|
18
21
|
|
|
19
22
|
## `action: "pause"`
|
|
20
23
|
Request a graceful safe-boundary pause for selected subagents by `ids`.
|
|
@@ -22,18 +25,20 @@ Request a graceful safe-boundary pause for selected subagents by `ids`.
|
|
|
22
25
|
- A paused subagent keeps its session context and can be resumed later.
|
|
23
26
|
|
|
24
27
|
## `action: "resume"`
|
|
25
|
-
Resume
|
|
26
|
-
- Optional `message` is delivered into
|
|
28
|
+
Resume one subagent by `id` (preferred) or a single-item `ids` array.
|
|
29
|
+
- Optional `message` is delivered into that one resumed run.
|
|
27
30
|
- Running subagents are a no-op and return their current status snapshot.
|
|
28
31
|
- Terminal subagents require `message` to start a follow-up resume run; without `message`, the tool returns the current snapshot with guidance.
|
|
29
32
|
- `paused` subagents resume from saved context; `queued` subagents are already waiting for capacity.
|
|
33
|
+
- Multiple targets are rejected because one global `message` must not broadcast to several subagents.
|
|
30
34
|
|
|
31
35
|
## `action: "steer"`
|
|
32
|
-
Send a non-empty `message` to
|
|
33
|
-
-
|
|
36
|
+
Send a non-empty `message` to one subagent by `id` (preferred) or a single-item `ids` array.
|
|
37
|
+
- A running subagent receives the message through its live handle.
|
|
34
38
|
- Optional `pause: true` requests a safe-boundary pause after steering a running subagent.
|
|
35
39
|
- `pause` only matters while the target is running.
|
|
36
|
-
-
|
|
40
|
+
- A non-active subagent (`paused`, `queued`, or terminal) automatically resumes with the message; `pause` is ignored for that target.
|
|
41
|
+
- Multiple targets are rejected because one global `message` must not broadcast to several subagents.
|
|
37
42
|
|
|
38
43
|
## `action: "cancel"`
|
|
39
44
|
Stop selected subagents by `ids`, including running, paused, or queued subagents.
|
|
@@ -5,15 +5,9 @@
|
|
|
5
5
|
<agent id="{{id}}" agent="{{agent}}">
|
|
6
6
|
<status>{{status}}</status>
|
|
7
7
|
{{#if meta}}<meta lines="{{meta.lineCount}}" size="{{meta.charSize}}" />{{/if}}
|
|
8
|
-
{{#if
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
</preview>
|
|
12
|
-
{{else}}
|
|
13
|
-
<result>
|
|
14
|
-
{{preview}}
|
|
15
|
-
</result>
|
|
16
|
-
{{/if}}
|
|
8
|
+
<synopsis{{#if outputUri}} ref="{{outputUri}}"{{/if}}>
|
|
9
|
+
{{synopsis}}
|
|
10
|
+
</synopsis>
|
|
17
11
|
</agent>
|
|
18
12
|
{{#unless @last}}
|
|
19
13
|
---
|
|
@@ -24,13 +24,17 @@ Subagents have no conversation history. Every fact, file path, and direction the
|
|
|
24
24
|
- `.assignment`: complete self-contained instructions; one-liners and missing acceptance criteria are PROHIBITED
|
|
25
25
|
{{#if contextEnabled}}- `context`: shared background prepended to every assignment; session-specific only{{/if}}
|
|
26
26
|
{{#if contextEnabled}}
|
|
27
|
-
- `.inheritContext` (optional): `
|
|
27
|
+
- `.inheritContext` (optional): fork-context mode for seeding the subagent with sanitized parent conversation. Omit it or set `"none"` for no copied context. `"receipt"` copies a minimal receipt-sized snapshot, `"last-turn"` copies only the latest exchange, `"bounded"` copies the bounded default snapshot, and `"full"` copies a larger snapshot up to the configured/model token cap. Non-`none` modes work only when global `task.forkContext.enabled` is true and the target agent declares `forkContext: allowed`; otherwise the call is rejected. Bundled agents that support it: `executor`, `architect`. Use inherited context only when the subagent's value depends on parent context; cloned tokens are billed to the child as fresh input and surfaced in task receipts as fork-context cloned-token accounting.
|
|
28
28
|
{{/if}}
|
|
29
|
+
{{#if independentMode}}- `.inheritContext`: independent mode cannot inherit parent conversation. Omit it or set `"none"`; any non-`none` value is rejected before scheduling.{{/if}}
|
|
29
30
|
{{#if customSchemaEnabled}}- `schema`: JTD schema for expected structured output (do not put format rules in assignments){{/if}}
|
|
31
|
+
- `spawnPlan` (optional): required before any batch with more than 4 tasks, and before a reviewer agent spawns `explore`; include whyParallel, whyNotLocal, independence, expectedReceiptShape, and maxInlineTokens.
|
|
30
32
|
{{#if isolationEnabled}}- `isolated`: run in isolated env; use when tasks edit overlapping files{{/if}}
|
|
31
33
|
</parameters>
|
|
32
34
|
|
|
33
35
|
<rules>
|
|
36
|
+
- HARD runtime gate: calls with more than 4 tasks are rejected before any child launches unless `spawnPlan` is complete.
|
|
37
|
+
- Reviewer->explore gate: a `reviewer` spawning `explore` is rejected before launch unless `spawnPlan` is complete, even for a single task.
|
|
34
38
|
- NEVER assign tasks to run project-wide build/test/lint. Caller verifies after the batch.
|
|
35
39
|
- **Subagents do not verify, lint, or format.** Every assignment MUST instruct the subagent to skip all gates and formatters. You run them once at the end across the union of changed files — avoids redundant runs and racing formatter passes.
|
|
36
40
|
{{#if ircEnabled}}
|
package/src/sdk.ts
CHANGED
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
prompt,
|
|
32
32
|
Snowflake,
|
|
33
33
|
} from "@gajae-code/utils";
|
|
34
|
+
|
|
34
35
|
import { type AsyncJob, AsyncJobManager, isBackgroundJobSupportEnabled } from "./async";
|
|
35
36
|
import { loadCapability } from "./capability";
|
|
36
37
|
import { type Rule, ruleCapability, setActiveRules } from "./capability/rule";
|
|
@@ -288,6 +289,8 @@ export interface CreateAgentSessionOptions {
|
|
|
288
289
|
requireYieldTool?: boolean;
|
|
289
290
|
/** Task recursion depth (for subagent sessions). Default: 0 */
|
|
290
291
|
taskDepth?: number;
|
|
292
|
+
/** Current role-agent type/name for nested task sessions. */
|
|
293
|
+
currentAgentType?: string;
|
|
291
294
|
/** Parent Hindsight state to alias for subagent memory tools. */
|
|
292
295
|
parentHindsightSessionState?: HindsightSessionState;
|
|
293
296
|
/** Pre-allocated agent identity for IRC routing. Default: "0-Main" for top-level, parentTaskPrefix-derived for sub. */
|
|
@@ -1158,6 +1161,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1158
1161
|
outputSchema: options.outputSchema,
|
|
1159
1162
|
requireYieldTool: options.requireYieldTool,
|
|
1160
1163
|
taskDepth: options.taskDepth ?? 0,
|
|
1164
|
+
currentAgentType: options.currentAgentType,
|
|
1161
1165
|
getSessionFile: () => sessionManager.getSessionFile() ?? null,
|
|
1162
1166
|
getEvalKernelOwnerId: () => evalKernelOwnerId,
|
|
1163
1167
|
assertEvalExecutionAllowed: () => session?.assertEvalExecutionAllowed(),
|