@nuvin/session 0.3.0-rc.2 → 0.3.0-rc.4
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/{chunk-COSZ5DKO.js → chunk-6QNR3TBF.js} +1 -1
- package/dist/{chunk-B6S3CWQX.js → chunk-UKDIV6I5.js} +296 -89
- package/dist/client/index.js +21 -11
- package/dist/client/session-client.d.ts +3 -3
- package/dist/client/session-client.d.ts.map +1 -1
- package/dist/controller/agent-channel.d.ts +11 -15
- package/dist/controller/agent-channel.d.ts.map +1 -1
- package/dist/controller/index.js +156 -56
- package/dist/controller/session-controller.d.ts +9 -5
- package/dist/controller/session-controller.d.ts.map +1 -1
- package/dist/protocol/index.js +1 -1
- package/dist/protocol/types.d.ts +31 -10
- package/dist/protocol/types.d.ts.map +1 -1
- package/dist/protocol/version.d.ts +1 -1
- package/dist/state/approvals.d.ts.map +1 -1
- package/dist/state/display-text.d.ts +8 -0
- package/dist/state/display-text.d.ts.map +1 -0
- package/dist/state/index.d.ts +1 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +9 -3
- package/dist/state/messages.d.ts +14 -20
- package/dist/state/messages.d.ts.map +1 -1
- package/dist/state/questions.d.ts +1 -1
- package/dist/state/questions.d.ts.map +1 -1
- package/dist/state/session.d.ts.map +1 -1
- package/dist/state/tool-key.d.ts +1 -1
- package/dist/state/tool-key.d.ts.map +1 -1
- package/dist/state/tool-preview.d.ts.map +1 -1
- package/dist/state/tool-preview.js +6 -6
- package/dist/test-utils/index.js +1 -1
- package/package.json +2 -2
package/dist/client/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createSessionViewState,
|
|
3
3
|
reduceSessionEvent
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-UKDIV6I5.js";
|
|
5
5
|
import {
|
|
6
6
|
PROTOCOL_VERSION
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-6QNR3TBF.js";
|
|
8
8
|
|
|
9
9
|
// src/client/endpoint.ts
|
|
10
10
|
var TerminalEndpointError = class extends Error {
|
|
@@ -442,6 +442,9 @@ function createHttpDataClient(options = {}) {
|
|
|
442
442
|
}
|
|
443
443
|
|
|
444
444
|
// src/client/session-client.ts
|
|
445
|
+
function cloneNonRootToolCallPath(toolCallPath) {
|
|
446
|
+
return toolCallPath && toolCallPath.length > 0 ? [...toolCallPath] : void 0;
|
|
447
|
+
}
|
|
445
448
|
var SessionCommandError = class extends Error {
|
|
446
449
|
constructor(code, message) {
|
|
447
450
|
super(message);
|
|
@@ -633,7 +636,8 @@ function createSessionClient(transport) {
|
|
|
633
636
|
})).then(() => {
|
|
634
637
|
});
|
|
635
638
|
},
|
|
636
|
-
decideApproval(toolCallId, decision, comment, grantDir,
|
|
639
|
+
decideApproval(toolCallId, decision, comment, grantDir, toolCallPath) {
|
|
640
|
+
const commandPath = cloneNonRootToolCallPath(toolCallPath);
|
|
637
641
|
return sendCommand((id) => ({
|
|
638
642
|
id,
|
|
639
643
|
type: "decide-approval",
|
|
@@ -641,24 +645,30 @@ function createSessionClient(transport) {
|
|
|
641
645
|
decision,
|
|
642
646
|
...comment !== void 0 ? { comment } : {},
|
|
643
647
|
...grantDir !== void 0 ? { grantDir } : {},
|
|
644
|
-
...
|
|
648
|
+
...commandPath !== void 0 ? { toolCallPath: commandPath } : {}
|
|
645
649
|
})).then(() => {
|
|
646
650
|
});
|
|
647
651
|
},
|
|
648
|
-
persistBashPermission(toolCallId, request,
|
|
652
|
+
persistBashPermission(toolCallId, request, toolCallPath) {
|
|
653
|
+
const commandPath = cloneNonRootToolCallPath(toolCallPath);
|
|
649
654
|
return sendCommand((id) => ({
|
|
650
655
|
id,
|
|
651
656
|
type: "persist-bash-permission",
|
|
652
657
|
toolCallId,
|
|
653
|
-
...
|
|
658
|
+
...commandPath !== void 0 ? { toolCallPath: commandPath } : {},
|
|
654
659
|
request
|
|
655
660
|
})).then(toPersistBashPermissionResult);
|
|
656
661
|
},
|
|
657
|
-
answerQuestion(questionId, answers) {
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
+
answerQuestion(questionId, answers, toolCallPath) {
|
|
663
|
+
const commandPath = cloneNonRootToolCallPath(toolCallPath);
|
|
664
|
+
return sendCommand((id) => ({
|
|
665
|
+
id,
|
|
666
|
+
type: "answer-question",
|
|
667
|
+
questionId,
|
|
668
|
+
answers,
|
|
669
|
+
...commandPath !== void 0 ? { toolCallPath: commandPath } : {}
|
|
670
|
+
})).then(() => {
|
|
671
|
+
});
|
|
662
672
|
},
|
|
663
673
|
abort() {
|
|
664
674
|
return sendCommand((id) => ({ id, type: "abort" })).then(() => {
|
|
@@ -18,9 +18,9 @@ export interface SessionClient {
|
|
|
18
18
|
/** Raw frame hook for UI side-effects (e.g. close modals on state-reset). */
|
|
19
19
|
onEvent(listener: (event: ServerEvent) => void): () => void;
|
|
20
20
|
submit(input: AgentInput, opts: ClientSubmitOptions): Promise<void>;
|
|
21
|
-
decideApproval(toolCallId: string, decision: "a" | "n" | "y", comment?: string, grantDir?: string,
|
|
22
|
-
persistBashPermission(toolCallId: string, request: PersistBashPermissionRequest,
|
|
23
|
-
answerQuestion(questionId: string, answers: AskUserAnswers): Promise<void>;
|
|
21
|
+
decideApproval(toolCallId: string, decision: "a" | "n" | "y", comment?: string, grantDir?: string, toolCallPath?: readonly string[]): Promise<void>;
|
|
22
|
+
persistBashPermission(toolCallId: string, request: PersistBashPermissionRequest, toolCallPath?: readonly string[]): Promise<PersistBashPermissionResult>;
|
|
23
|
+
answerQuestion(questionId: string, answers: AskUserAnswers, toolCallPath?: readonly string[]): Promise<void>;
|
|
24
24
|
abort(): Promise<void>;
|
|
25
25
|
/** Cancel a queued (not-yet-running) message by its `turn-status.queued` id. */
|
|
26
26
|
dequeueMessage(queuedId: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-client.d.ts","sourceRoot":"","sources":["../../src/client/session-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAa,MAAM,0BAA0B,CAAC;AAEtF,OAAO,KAAK,EACV,iBAAiB,EACjB,WAAW,EACX,4BAA4B,EAC5B,sBAAsB,EAEtB,aAAa,EACb,WAAW,EACX,yBAAyB,EACzB,0BAA0B,EAC1B,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,SAAS,EACT,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,4BAA4B,EAC5B,2BAA2B,EAC3B,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,sBAAsB,EAEtB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-client.d.ts","sourceRoot":"","sources":["../../src/client/session-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AgentEvent, AskUserAnswers, AskUserQuestionRequest, Message, ToolPermissionClass, ToolRuntimeDispatchDecision, ToolUseBlock } from "@nuvin/agent-core/shared";
|
|
2
|
-
import type { BashPolicyApprovalDiagnostics, DirAccessRequest, PersistBashPermissionHandlerResult, PersistBashPermissionRequest, WorkflowBashPolicySummary } from "../protocol/types.ts";
|
|
1
|
+
import type { AgentEvent, AskUserAnswers, AskUserQuestionRequest, Message, ToolExecutionScope, ToolPermissionClass, ToolRuntimeDispatchDecision, ToolUseBlock } from "@nuvin/agent-core/shared";
|
|
2
|
+
import type { BashPolicyApprovalDiagnostics, DirAccessRequest, PersistBashPermissionHandlerResult, PersistBashPermissionRequest, WireAgentEventScope, WorkflowBashPolicySummary } from "../protocol/types.ts";
|
|
3
3
|
import type { TuiMessage } from "../state/messages.ts";
|
|
4
4
|
/** UI-safe transcript projection of runtime LoadedSession. */
|
|
5
5
|
export type SessionLoadedPayload = {
|
|
@@ -8,18 +8,14 @@ export type SessionLoadedPayload = {
|
|
|
8
8
|
messages: TuiMessage[];
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* tool call. Coordinator (root) callbacks omit it.
|
|
11
|
+
* Convert normalized host scope to protocol scope. Root activity stays
|
|
12
|
+
* unscoped on the wire; nested paths are copied so caller mutation cannot
|
|
13
|
+
* change a routed event or interaction after publication.
|
|
15
14
|
*/
|
|
16
|
-
export
|
|
17
|
-
agentId: string;
|
|
18
|
-
parentToolCallId: string;
|
|
19
|
-
};
|
|
15
|
+
export declare function toWireSessionScope(scope: ToolExecutionScope): WireAgentEventScope | undefined;
|
|
20
16
|
export type AgentEventPayload = {
|
|
21
17
|
event: AgentEvent;
|
|
22
|
-
scope?:
|
|
18
|
+
scope?: WireAgentEventScope;
|
|
23
19
|
};
|
|
24
20
|
export type ToolCallRequest = {
|
|
25
21
|
agentId: string;
|
|
@@ -27,8 +23,8 @@ export type ToolCallRequest = {
|
|
|
27
23
|
bashPolicy?: BashPolicyApprovalDiagnostics;
|
|
28
24
|
/** Set by the runtime pre-check when the call's path is outside allowedDirs. */
|
|
29
25
|
dirAccess?: DirAccessRequest;
|
|
30
|
-
parentToolCallId?: string;
|
|
31
26
|
permissionClass?: ToolPermissionClass;
|
|
27
|
+
toolCallPath?: readonly string[];
|
|
32
28
|
persistBashPermission?: (request: PersistBashPermissionRequest) => Promise<PersistBashPermissionHandlerResult>;
|
|
33
29
|
toolCall: ToolUseBlock;
|
|
34
30
|
workflowBashPolicy?: WorkflowBashPolicySummary;
|
|
@@ -36,7 +32,7 @@ export type ToolCallRequest = {
|
|
|
36
32
|
export type AgentEventListener = (payload: AgentEventPayload) => void;
|
|
37
33
|
export type SessionLoadedListener = (loaded: SessionLoadedPayload) => void;
|
|
38
34
|
export type ToolCallDecider = (request: ToolCallRequest) => Promise<ToolRuntimeDispatchDecision> | ToolRuntimeDispatchDecision;
|
|
39
|
-
export type UserQuestionHandler = (request: AskUserQuestionRequest, scope?:
|
|
35
|
+
export type UserQuestionHandler = (request: AskUserQuestionRequest, scope?: WireAgentEventScope) => Promise<AskUserAnswers> | AskUserAnswers;
|
|
40
36
|
/**
|
|
41
37
|
* In-process channel between the Agent (constructed in `main()`) and the
|
|
42
38
|
* React UI (`<App />`). Two distinct shapes:
|
|
@@ -51,10 +47,10 @@ export declare class AgentChannel {
|
|
|
51
47
|
private readonly emitter;
|
|
52
48
|
private decider;
|
|
53
49
|
private questionHandler;
|
|
54
|
-
publishEvent(event: AgentEvent, scope?:
|
|
50
|
+
publishEvent(event: AgentEvent, scope?: ToolExecutionScope): void;
|
|
55
51
|
publishSessionLoaded(loaded: SessionLoadedPayload): void;
|
|
56
52
|
requestToolDecision(request: ToolCallRequest): Promise<ToolRuntimeDispatchDecision> | ToolRuntimeDispatchDecision;
|
|
57
|
-
requestUserQuestion(request: AskUserQuestionRequest, scope?:
|
|
53
|
+
requestUserQuestion(request: AskUserQuestionRequest, scope?: ToolExecutionScope): Promise<AskUserAnswers>;
|
|
58
54
|
onEvent(listener: AgentEventListener): () => void;
|
|
59
55
|
onSessionLoaded(listener: SessionLoadedListener): () => void;
|
|
60
56
|
setToolDecider(decider: ToolCallDecider | null): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-channel.d.ts","sourceRoot":"","sources":["../../src/controller/agent-channel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,OAAO,EACP,mBAAmB,EACnB,2BAA2B,EAC3B,YAAY,EACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,kCAAkC,EAClC,4BAA4B,EAC5B,yBAAyB,EAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,8DAA8D;AAC9D,MAAM,MAAM,oBAAoB,GAAG;IACjC,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"agent-channel.d.ts","sourceRoot":"","sources":["../../src/controller/agent-channel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,OAAO,EACP,kBAAkB,EAClB,mBAAmB,EACnB,2BAA2B,EAC3B,YAAY,EACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,kCAAkC,EAClC,4BAA4B,EAC5B,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,8DAA8D;AAC9D,MAAM,MAAM,oBAAoB,GAAG;IACjC,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,GAAG,SAAS,CAI7F;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,6BAA6B,CAAC;IAC3C,gFAAgF;IAChF,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,qBAAqB,CAAC,EAAE,CACtB,OAAO,EAAE,4BAA4B,KAClC,OAAO,CAAC,kCAAkC,CAAC,CAAC;IACjD,QAAQ,EAAE,YAAY,CAAC;IACvB,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;AACtE,MAAM,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAC;AAE3E,MAAM,MAAM,eAAe,GAAG,CAC5B,OAAO,EAAE,eAAe,KACrB,OAAO,CAAC,2BAA2B,CAAC,GAAG,2BAA2B,CAAC;AAExE,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,sBAAsB,EAC/B,KAAK,CAAC,EAAE,mBAAmB,KACxB,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC;AAO9C;;;;;;;;;GASG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,eAAe,CAAoC;IAI3D,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,kBAAkB,GAAG,IAAI;IAOjE,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IAIxD,mBAAmB,CACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,2BAA2B,CAAC,GAAG,2BAA2B;IAerE,mBAAmB,CACjB,OAAO,EAAE,sBAAsB,EAC/B,KAAK,CAAC,EAAE,kBAAkB,GACzB,OAAO,CAAC,cAAc,CAAC;IAW1B,OAAO,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,IAAI;IAOjD,eAAe,CAAC,QAAQ,EAAE,qBAAqB,GAAG,MAAM,IAAI;IAO5D,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI;IAIrD,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,GAAG,IAAI;CAG9D"}
|
package/dist/controller/index.js
CHANGED
|
@@ -7,11 +7,16 @@ import {
|
|
|
7
7
|
createSessionViewState,
|
|
8
8
|
isToolAutoApprovedForMode,
|
|
9
9
|
reduceSessionEvent,
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
sanitizeBoundedDisplayText,
|
|
11
|
+
scopedToolKey,
|
|
12
|
+
summarizeToolCallInput
|
|
13
|
+
} from "../chunk-UKDIV6I5.js";
|
|
12
14
|
|
|
13
15
|
// src/controller/agent-channel.ts
|
|
14
16
|
import { EventEmitter } from "events";
|
|
17
|
+
function toWireSessionScope(scope) {
|
|
18
|
+
return scope.toolCallPath.length === 0 ? void 0 : { agentId: scope.agentId, toolCallPath: [...scope.toolCallPath] };
|
|
19
|
+
}
|
|
15
20
|
var NO_DECIDER_DECISION = {
|
|
16
21
|
action: "reject",
|
|
17
22
|
reason: "UI is not ready to handle tool calls."
|
|
@@ -22,7 +27,10 @@ var AgentChannel = class {
|
|
|
22
27
|
questionHandler = null;
|
|
23
28
|
// ---------- Agent-side (publishers) ----------
|
|
24
29
|
publishEvent(event, scope) {
|
|
25
|
-
this.emitter.emit("event", {
|
|
30
|
+
this.emitter.emit("event", {
|
|
31
|
+
event,
|
|
32
|
+
scope: scope === void 0 ? void 0 : toWireSessionScope(scope)
|
|
33
|
+
});
|
|
26
34
|
}
|
|
27
35
|
publishSessionLoaded(loaded) {
|
|
28
36
|
this.emitter.emit("session-loaded", loaded);
|
|
@@ -31,13 +39,23 @@ var AgentChannel = class {
|
|
|
31
39
|
if (!this.decider) {
|
|
32
40
|
return NO_DECIDER_DECISION;
|
|
33
41
|
}
|
|
34
|
-
|
|
42
|
+
const { toolCallPath, ...rootRequest } = request;
|
|
43
|
+
const scope = toWireSessionScope({
|
|
44
|
+
agentId: request.agentId,
|
|
45
|
+
toolCallPath: toolCallPath ?? []
|
|
46
|
+
});
|
|
47
|
+
return this.decider({
|
|
48
|
+
...rootRequest,
|
|
49
|
+
...scope === void 0 ? {} : { toolCallPath: scope.toolCallPath }
|
|
50
|
+
});
|
|
35
51
|
}
|
|
36
52
|
requestUserQuestion(request, scope) {
|
|
37
53
|
if (!this.questionHandler) {
|
|
38
54
|
return Promise.reject(new Error("UI is not ready to handle user questions."));
|
|
39
55
|
}
|
|
40
|
-
return Promise.resolve(
|
|
56
|
+
return Promise.resolve(
|
|
57
|
+
this.questionHandler(request, scope === void 0 ? void 0 : toWireSessionScope(scope))
|
|
58
|
+
);
|
|
41
59
|
}
|
|
42
60
|
// ---------- UI-side (subscribers) ----------
|
|
43
61
|
onEvent(listener) {
|
|
@@ -94,8 +112,8 @@ function createSessionController(deps) {
|
|
|
94
112
|
let activeTurnId;
|
|
95
113
|
let activePolicyDenial;
|
|
96
114
|
let hostBusyCount = 0;
|
|
97
|
-
let questionCounter = 0;
|
|
98
115
|
const listeners = /* @__PURE__ */ new Set();
|
|
116
|
+
const abortListeners = /* @__PURE__ */ new Set();
|
|
99
117
|
const approvalResolvers = /* @__PURE__ */ new Map();
|
|
100
118
|
const privateApprovals = /* @__PURE__ */ new Map();
|
|
101
119
|
const persistenceInFlight = /* @__PURE__ */ new Set();
|
|
@@ -171,8 +189,8 @@ function createSessionController(deps) {
|
|
|
171
189
|
});
|
|
172
190
|
});
|
|
173
191
|
deps.channel.setToolDecider((request) => {
|
|
174
|
-
const { toolCall, agentId,
|
|
175
|
-
const scope =
|
|
192
|
+
const { toolCall, agentId, toolCallPath, dirAccess, bashPolicy } = request;
|
|
193
|
+
const scope = toolCallPath === void 0 ? void 0 : { agentId, toolCallPath: [...toolCallPath] };
|
|
176
194
|
const approvalKey = request.approvalKey ?? `${agentId}:${toolCall.name}`;
|
|
177
195
|
const permissionClass = request.permissionClass ?? "always-confirm";
|
|
178
196
|
const hasBashPolicy = toolCall.name === "Bash" && bashPolicy !== void 0;
|
|
@@ -246,27 +264,30 @@ function createSessionController(deps) {
|
|
|
246
264
|
activePolicyDenial = "Tool approval is unavailable in headless mode.";
|
|
247
265
|
return { action: "reject", reason: activePolicyDenial };
|
|
248
266
|
}
|
|
249
|
-
const nickname = nicknameFor(
|
|
250
|
-
const
|
|
267
|
+
const nickname = nicknameFor(toolCallPath);
|
|
268
|
+
const ancestorDisplay = buildAncestorDisplay(toolCallPath);
|
|
269
|
+
const rawInput = asJsonObject(toolCall.input);
|
|
270
|
+
const input = toolCall.name === "Program" ? typeof rawInput?.description === "string" ? { description: sanitizeBoundedDisplayText(rawInput.description) } : void 0 : rawInput;
|
|
251
271
|
const descriptor = {
|
|
252
272
|
agentId,
|
|
253
273
|
permissionClass,
|
|
254
|
-
summary: findToolSummary(toolCall.id,
|
|
274
|
+
summary: findToolSummary(toolCall.id, toolCallPath),
|
|
255
275
|
toolCallId: toolCall.id,
|
|
256
276
|
toolName: toolCall.name,
|
|
277
|
+
...ancestorDisplay !== void 0 ? { ancestorDisplay } : {},
|
|
257
278
|
...dirAccess !== void 0 ? { dirAccess } : {},
|
|
258
279
|
...input !== void 0 ? { input } : {},
|
|
259
|
-
...
|
|
280
|
+
...toolCallPath !== void 0 ? { toolCallPath: [...toolCallPath] } : {},
|
|
260
281
|
...nickname !== void 0 ? { nickname } : {},
|
|
261
282
|
...!dirAccess && bashPolicy !== void 0 ? { bashPolicy } : {},
|
|
262
283
|
...request.workflowBashPolicy !== void 0 ? { workflowBashPolicy: request.workflowBashPolicy } : {}
|
|
263
284
|
};
|
|
264
285
|
return new Promise((resolve) => {
|
|
265
|
-
const toolKey = scopedToolKey(
|
|
286
|
+
const toolKey = scopedToolKey(toolCallPath, toolCall.id);
|
|
266
287
|
approvalResolvers.set(toolKey, {
|
|
267
288
|
resolve,
|
|
268
289
|
toolCallId: toolCall.id,
|
|
269
|
-
...
|
|
290
|
+
...toolCallPath !== void 0 ? { toolCallPath: [...toolCallPath] } : {}
|
|
270
291
|
});
|
|
271
292
|
privateApprovals.set(toolKey, {
|
|
272
293
|
approvalKey,
|
|
@@ -281,39 +302,69 @@ function createSessionController(deps) {
|
|
|
281
302
|
activePolicyDenial = "Questions are unavailable in headless mode.";
|
|
282
303
|
return Promise.reject(new Error(activePolicyDenial));
|
|
283
304
|
}
|
|
284
|
-
|
|
285
|
-
const
|
|
305
|
+
const { questionId } = request;
|
|
306
|
+
const toolCallPath = scope?.toolCallPath;
|
|
286
307
|
return new Promise((resolve, reject) => {
|
|
287
|
-
|
|
288
|
-
|
|
308
|
+
const questionKey = scopedToolKey(toolCallPath, questionId);
|
|
309
|
+
questionResolvers.set(questionKey, {
|
|
310
|
+
resolve,
|
|
311
|
+
reject,
|
|
312
|
+
questionId,
|
|
313
|
+
...toolCallPath !== void 0 ? { toolCallPath: [...toolCallPath] } : {}
|
|
314
|
+
});
|
|
315
|
+
const nickname = nicknameFor(toolCallPath);
|
|
289
316
|
emit({
|
|
290
317
|
type: "question-asked",
|
|
291
318
|
question: {
|
|
292
319
|
questionId,
|
|
293
320
|
request,
|
|
294
321
|
...scope?.agentId !== void 0 ? { agentId: scope.agentId } : {},
|
|
295
|
-
...
|
|
322
|
+
...toolCallPath !== void 0 ? { toolCallPath: [...toolCallPath] } : {},
|
|
296
323
|
...nickname !== void 0 ? { nickname } : {}
|
|
297
324
|
}
|
|
298
325
|
});
|
|
299
326
|
});
|
|
300
327
|
});
|
|
301
|
-
function
|
|
302
|
-
const messageId = state.messages.toolMessageIds[scopedToolKey(
|
|
328
|
+
function findToolMessage(toolCallId, toolCallPath) {
|
|
329
|
+
const messageId = state.messages.toolMessageIds[scopedToolKey(toolCallPath, toolCallId)];
|
|
303
330
|
const message = state.messages.messages.find((entry) => entry.id === messageId);
|
|
304
|
-
return message?.role === "tool" ? message
|
|
331
|
+
return message?.role === "tool" ? message : void 0;
|
|
305
332
|
}
|
|
306
|
-
function
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const parentMessage = state.messages.messages.find((entry) => entry.id === parentMessageId);
|
|
310
|
-
if (parentMessage?.role !== "tool") return void 0;
|
|
311
|
-
const nickname = parentMessage.input?.nickname;
|
|
312
|
-
return typeof nickname === "string" ? nickname : void 0;
|
|
333
|
+
function findToolSummary(toolCallId, toolCallPath) {
|
|
334
|
+
const summary = findToolMessage(toolCallId, toolCallPath)?.summary ?? "";
|
|
335
|
+
return sanitizeBoundedDisplayText(summary);
|
|
313
336
|
}
|
|
314
|
-
function
|
|
337
|
+
function nicknameFor(toolCallPath) {
|
|
338
|
+
if (!toolCallPath || toolCallPath.length === 0) return void 0;
|
|
339
|
+
const parentIndex = toolCallPath.length - 1;
|
|
340
|
+
const directAncestorId = toolCallPath[parentIndex];
|
|
341
|
+
if (directAncestorId === void 0) return void 0;
|
|
342
|
+
const parentMessage = findToolMessage(directAncestorId, toolCallPath.slice(0, parentIndex));
|
|
343
|
+
const nickname = parentMessage?.input?.nickname;
|
|
344
|
+
return typeof nickname === "string" ? sanitizeBoundedDisplayText(nickname) : void 0;
|
|
345
|
+
}
|
|
346
|
+
function buildAncestorDisplay(toolCallPath) {
|
|
347
|
+
if (!toolCallPath || toolCallPath.length === 0) return void 0;
|
|
348
|
+
const ancestors = [];
|
|
349
|
+
for (let index = 0; index < toolCallPath.length; index += 1) {
|
|
350
|
+
const toolCallId = toolCallPath[index];
|
|
351
|
+
if (toolCallId === void 0) return void 0;
|
|
352
|
+
const message = findToolMessage(toolCallId, toolCallPath.slice(0, index));
|
|
353
|
+
if (!message) return void 0;
|
|
354
|
+
const nickname = message.input?.nickname;
|
|
355
|
+
ancestors.push({
|
|
356
|
+
toolCallId,
|
|
357
|
+
toolName: message.toolName,
|
|
358
|
+
summary: message.toolName === "Program" ? summarizeToolCallInput(message.toolName, message.input ?? {}) : sanitizeBoundedDisplayText(message.summary),
|
|
359
|
+
...typeof nickname === "string" ? { nickname: sanitizeBoundedDisplayText(nickname) } : {}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
return ancestors;
|
|
363
|
+
}
|
|
364
|
+
function findDescriptor(toolCallId, toolCallPath) {
|
|
365
|
+
const toolKey = scopedToolKey(toolCallPath, toolCallId);
|
|
315
366
|
return [state.approval.active, ...state.approval.pending].find(
|
|
316
|
-
(entry) => entry
|
|
367
|
+
(entry) => entry !== null && scopedToolKey(entry.toolCallPath, entry.toolCallId) === toolKey
|
|
317
368
|
);
|
|
318
369
|
}
|
|
319
370
|
function rejectAllPending(reason) {
|
|
@@ -322,7 +373,7 @@ function createSessionController(deps) {
|
|
|
322
373
|
emit({
|
|
323
374
|
type: "approval-settled",
|
|
324
375
|
toolCallId: pending.toolCallId,
|
|
325
|
-
...pending.
|
|
376
|
+
...pending.toolCallPath === void 0 ? {} : { toolCallPath: [...pending.toolCallPath] },
|
|
326
377
|
status: "rejected",
|
|
327
378
|
by: "abort"
|
|
328
379
|
});
|
|
@@ -330,9 +381,13 @@ function createSessionController(deps) {
|
|
|
330
381
|
approvalResolvers.clear();
|
|
331
382
|
privateApprovals.clear();
|
|
332
383
|
persistenceInFlight.clear();
|
|
333
|
-
for (const
|
|
384
|
+
for (const { reject, questionId, toolCallPath } of questionResolvers.values()) {
|
|
334
385
|
reject(new Error(reason));
|
|
335
|
-
emit({
|
|
386
|
+
emit({
|
|
387
|
+
type: "question-settled",
|
|
388
|
+
questionId,
|
|
389
|
+
...toolCallPath === void 0 ? {} : { toolCallPath: [...toolCallPath] }
|
|
390
|
+
});
|
|
336
391
|
}
|
|
337
392
|
questionResolvers.clear();
|
|
338
393
|
}
|
|
@@ -352,7 +407,8 @@ function createSessionController(deps) {
|
|
|
352
407
|
if (closing || abortController || hostBusyCount > 0) return;
|
|
353
408
|
const next = queue.shift();
|
|
354
409
|
if (!next) return;
|
|
355
|
-
|
|
410
|
+
const coordinatorOwned = next.opts.submission?.origin === "coordinator";
|
|
411
|
+
if (!coordinatorOwned && !next.opts.silent) {
|
|
356
412
|
emit(
|
|
357
413
|
{
|
|
358
414
|
type: "user-message",
|
|
@@ -366,6 +422,7 @@ function createSessionController(deps) {
|
|
|
366
422
|
turnId: next.opts.turnId,
|
|
367
423
|
allowSteering: next.opts.turnId === void 0,
|
|
368
424
|
submission: next.opts.submission ?? { origin: "user" },
|
|
425
|
+
...coordinatorOwned ? { coordinatorDisplayText: next.opts.displayText } : {},
|
|
369
426
|
...next.opts.signal === void 0 ? {} : { signal: next.opts.signal }
|
|
370
427
|
});
|
|
371
428
|
}
|
|
@@ -401,7 +458,12 @@ function createSessionController(deps) {
|
|
|
401
458
|
}
|
|
402
459
|
if (abortController !== controller || controller.signal.aborted) return [];
|
|
403
460
|
for (const entry of accepted) {
|
|
404
|
-
if (
|
|
461
|
+
if (entry.opts.submission?.origin === "coordinator") {
|
|
462
|
+
emit({
|
|
463
|
+
type: "info",
|
|
464
|
+
message: sanitizeBoundedDisplayText(entry.opts.displayText)
|
|
465
|
+
});
|
|
466
|
+
} else if (!entry.opts.silent) {
|
|
405
467
|
emit({
|
|
406
468
|
type: "user-message",
|
|
407
469
|
text: entry.opts.displayText,
|
|
@@ -409,7 +471,9 @@ function createSessionController(deps) {
|
|
|
409
471
|
});
|
|
410
472
|
}
|
|
411
473
|
}
|
|
412
|
-
return accepted.map(
|
|
474
|
+
return accepted.map(
|
|
475
|
+
(entry) => entry.opts.submission?.origin === "coordinator" ? { input: entry.input, submission: entry.opts.submission } : entry.input
|
|
476
|
+
);
|
|
413
477
|
};
|
|
414
478
|
const previousTurnId = activeTurnId;
|
|
415
479
|
if (opts.turnId !== void 0) activeTurnId = opts.turnId;
|
|
@@ -440,6 +504,12 @@ function createSessionController(deps) {
|
|
|
440
504
|
}
|
|
441
505
|
finalInput = guarded.prompt;
|
|
442
506
|
}
|
|
507
|
+
if (opts.coordinatorDisplayText !== void 0) {
|
|
508
|
+
emit({
|
|
509
|
+
type: "info",
|
|
510
|
+
message: sanitizeBoundedDisplayText(opts.coordinatorDisplayText)
|
|
511
|
+
});
|
|
512
|
+
}
|
|
443
513
|
const compactionSend = (text) => runTurn(text, {
|
|
444
514
|
systemInitiated: true,
|
|
445
515
|
allowSteering: opts.allowSteering,
|
|
@@ -542,23 +612,40 @@ function createSessionController(deps) {
|
|
|
542
612
|
deps.channel.setToolDecider(null);
|
|
543
613
|
deps.channel.setQuestionHandler(null);
|
|
544
614
|
listeners.clear();
|
|
615
|
+
abortListeners.clear();
|
|
545
616
|
}
|
|
546
617
|
return {
|
|
547
618
|
abort() {
|
|
548
619
|
queue.length = 0;
|
|
549
|
-
|
|
620
|
+
const reason = new Error("User aborted the current turn.");
|
|
621
|
+
for (const listener of abortListeners) {
|
|
622
|
+
try {
|
|
623
|
+
listener(reason);
|
|
624
|
+
} catch {
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
abortController?.abort(reason);
|
|
550
628
|
rejectAllPending("User aborted the current turn.");
|
|
551
629
|
},
|
|
630
|
+
onAbort(listener) {
|
|
631
|
+
abortListeners.add(listener);
|
|
632
|
+
return () => abortListeners.delete(listener);
|
|
633
|
+
},
|
|
552
634
|
attachHostHooks(hooks) {
|
|
553
635
|
if (hooks.compaction) compaction = hooks.compaction;
|
|
554
636
|
if (hooks.guardPrompt) guardPrompt = hooks.guardPrompt;
|
|
555
637
|
},
|
|
556
|
-
answerQuestion(questionId, answers) {
|
|
557
|
-
const
|
|
638
|
+
answerQuestion(questionId, answers, toolCallPath) {
|
|
639
|
+
const questionKey = scopedToolKey(toolCallPath, questionId);
|
|
640
|
+
const entry = questionResolvers.get(questionKey);
|
|
558
641
|
if (!entry) return false;
|
|
559
|
-
questionResolvers.delete(
|
|
642
|
+
questionResolvers.delete(questionKey);
|
|
560
643
|
entry.resolve(answers);
|
|
561
|
-
emit({
|
|
644
|
+
emit({
|
|
645
|
+
type: "question-settled",
|
|
646
|
+
questionId,
|
|
647
|
+
...toolCallPath && toolCallPath.length > 0 ? { toolCallPath: [...toolCallPath] } : {}
|
|
648
|
+
});
|
|
562
649
|
return true;
|
|
563
650
|
},
|
|
564
651
|
appendError(message) {
|
|
@@ -591,8 +678,8 @@ function createSessionController(deps) {
|
|
|
591
678
|
emitTurnStatus();
|
|
592
679
|
return true;
|
|
593
680
|
},
|
|
594
|
-
decideApproval(toolCallId, decision, comment, grantDir,
|
|
595
|
-
const toolKey = scopedToolKey(
|
|
681
|
+
decideApproval(toolCallId, decision, comment, grantDir, toolCallPath) {
|
|
682
|
+
const toolKey = scopedToolKey(toolCallPath, toolCallId);
|
|
596
683
|
if (persistenceInFlight.has(toolKey)) {
|
|
597
684
|
return false;
|
|
598
685
|
}
|
|
@@ -600,7 +687,7 @@ function createSessionController(deps) {
|
|
|
600
687
|
if (!pending) return false;
|
|
601
688
|
approvalResolvers.delete(toolKey);
|
|
602
689
|
persistenceInFlight.delete(toolKey);
|
|
603
|
-
const descriptor = findDescriptor(toolCallId,
|
|
690
|
+
const descriptor = findDescriptor(toolCallId, toolCallPath);
|
|
604
691
|
const privateApproval = privateApprovals.get(toolKey);
|
|
605
692
|
privateApprovals.delete(toolKey);
|
|
606
693
|
if (decision === "a" && descriptor && !descriptor.dirAccess) {
|
|
@@ -643,18 +730,21 @@ function createSessionController(deps) {
|
|
|
643
730
|
emit({
|
|
644
731
|
type: "approval-settled",
|
|
645
732
|
toolCallId,
|
|
646
|
-
...
|
|
733
|
+
...toolCallPath && toolCallPath.length > 0 ? { toolCallPath: [...toolCallPath] } : {},
|
|
647
734
|
status: rejected ? "rejected" : "approved",
|
|
648
735
|
by: "client"
|
|
649
736
|
});
|
|
650
737
|
return true;
|
|
651
738
|
},
|
|
652
|
-
async persistBashPermission(toolCallId, request,
|
|
653
|
-
const
|
|
739
|
+
async persistBashPermission(toolCallId, request, toolCallPath) {
|
|
740
|
+
const persistenceToolCallPath = toolCallPath && toolCallPath.length > 0 ? [...toolCallPath] : void 0;
|
|
741
|
+
const toolKey = scopedToolKey(persistenceToolCallPath, toolCallId);
|
|
654
742
|
const descriptor = state.approval.active;
|
|
743
|
+
const descriptorKey = descriptor === null ? void 0 : scopedToolKey(descriptor.toolCallPath, descriptor.toolCallId);
|
|
655
744
|
const privateApproval = privateApprovals.get(toolKey);
|
|
656
745
|
const handler = privateApproval?.persistBashPermission;
|
|
657
|
-
|
|
746
|
+
const pending = approvalResolvers.get(toolKey);
|
|
747
|
+
if (descriptorKey !== toolKey || descriptor?.toolName !== "Bash" || descriptor.dirAccess !== void 0 || descriptor.bashPolicy?.persistence.eligible !== true || handler === void 0 || pending === void 0) {
|
|
658
748
|
return void 0;
|
|
659
749
|
}
|
|
660
750
|
if (persistenceInFlight.has(toolKey)) {
|
|
@@ -676,13 +766,13 @@ function createSessionController(deps) {
|
|
|
676
766
|
emitTurnStatus();
|
|
677
767
|
try {
|
|
678
768
|
const outcome = await handler(request);
|
|
769
|
+
const activeDescriptor = state.approval.active;
|
|
770
|
+
if (approvalResolvers.get(toolKey) !== pending || activeDescriptor === null || scopedToolKey(activeDescriptor.toolCallPath, activeDescriptor.toolCallId) !== toolKey || privateApprovals.get(toolKey) !== privateApproval) {
|
|
771
|
+
return void 0;
|
|
772
|
+
}
|
|
679
773
|
if (outcome.status === "validation-error") {
|
|
680
774
|
return outcome;
|
|
681
775
|
}
|
|
682
|
-
const pending = approvalResolvers.get(toolKey);
|
|
683
|
-
if (pending === void 0 || state.approval.active?.toolCallId !== toolCallId || state.approval.active.parentToolCallId !== parentToolCallId || privateApprovals.get(toolKey) !== privateApproval) {
|
|
684
|
-
return void 0;
|
|
685
|
-
}
|
|
686
776
|
approvalResolvers.delete(toolKey);
|
|
687
777
|
privateApprovals.delete(toolKey);
|
|
688
778
|
pending.resolve({
|
|
@@ -693,7 +783,7 @@ function createSessionController(deps) {
|
|
|
693
783
|
emit({
|
|
694
784
|
type: "approval-settled",
|
|
695
785
|
toolCallId,
|
|
696
|
-
...
|
|
786
|
+
...persistenceToolCallPath === void 0 ? {} : { toolCallPath: [...persistenceToolCallPath] },
|
|
697
787
|
status: "approved",
|
|
698
788
|
by: "client"
|
|
699
789
|
});
|
|
@@ -733,6 +823,13 @@ function createSessionController(deps) {
|
|
|
733
823
|
publishMetrics(snapshot) {
|
|
734
824
|
emit({ type: "metrics", snapshot });
|
|
735
825
|
},
|
|
826
|
+
publishBackgroundAgentStatus(status) {
|
|
827
|
+
emit({
|
|
828
|
+
type: "background-agent-status",
|
|
829
|
+
...status,
|
|
830
|
+
runningRunIds: [...status.runningRunIds]
|
|
831
|
+
});
|
|
832
|
+
},
|
|
736
833
|
publishAuthFlow(flow) {
|
|
737
834
|
emit({ type: "auth-flow", flow });
|
|
738
835
|
},
|
|
@@ -787,7 +884,8 @@ function createSessionController(deps) {
|
|
|
787
884
|
emitTurnStatus();
|
|
788
885
|
return;
|
|
789
886
|
}
|
|
790
|
-
|
|
887
|
+
const coordinatorOwned = opts.submission?.origin === "coordinator";
|
|
888
|
+
if (!coordinatorOwned && !opts.silent) {
|
|
791
889
|
emit(
|
|
792
890
|
{
|
|
793
891
|
type: "user-message",
|
|
@@ -801,6 +899,7 @@ function createSessionController(deps) {
|
|
|
801
899
|
turnId: opts.turnId,
|
|
802
900
|
allowSteering: opts.turnId === void 0,
|
|
803
901
|
submission: opts.submission ?? { origin: "user" },
|
|
902
|
+
...coordinatorOwned ? { coordinatorDisplayText: opts.displayText } : {},
|
|
804
903
|
...opts.signal === void 0 ? {} : { signal: opts.signal }
|
|
805
904
|
});
|
|
806
905
|
}
|
|
@@ -809,5 +908,6 @@ function createSessionController(deps) {
|
|
|
809
908
|
export {
|
|
810
909
|
AgentChannel,
|
|
811
910
|
createSessionController,
|
|
812
|
-
formatBashPolicyDenial
|
|
911
|
+
formatBashPolicyDenial,
|
|
912
|
+
toWireSessionScope
|
|
813
913
|
};
|