@gajae-code/coding-agent 0.11.6 → 0.11.8
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 +92 -0
- package/dist/types/capability/index.d.ts +10 -20
- package/dist/types/capability/types.d.ts +3 -0
- package/dist/types/cli/args.d.ts +0 -2
- package/dist/types/commands/daemon.d.ts +2 -2
- package/dist/types/commands/sdk.d.ts +20 -2
- package/dist/types/config/keybindings.d.ts +34 -4
- package/dist/types/config/model-profile-activation.d.ts +4 -3
- package/dist/types/config/model-profile-contract.d.ts +38 -0
- package/dist/types/config/settings-schema.d.ts +70 -7
- package/dist/types/edit/modes/patch.d.ts +13 -0
- package/dist/types/edit/path-mutation-lock.d.ts +15 -0
- package/dist/types/eval/py/executor.d.ts +1 -1
- package/dist/types/eval/py/runner-artifact.d.ts +8 -0
- package/dist/types/eval/py/tool-bridge.d.ts +1 -2
- package/dist/types/gjc-runtime/repository-binding.d.ts +63 -0
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +6 -5
- package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +20 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +43 -5
- package/dist/types/main.d.ts +32 -1
- package/dist/types/modes/components/btw-panel.d.ts +1 -0
- package/dist/types/modes/components/model-selector.d.ts +2 -0
- package/dist/types/modes/components/runtime-mcp-add-wizard.d.ts +2 -1
- package/dist/types/modes/components/tool-status-header.d.ts +4 -2
- package/dist/types/modes/components/welcome.d.ts +2 -0
- package/dist/types/modes/controllers/btw-controller.d.ts +5 -0
- package/dist/types/modes/controllers/command-controller.d.ts +2 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -1
- package/dist/types/modes/interactive-mode.d.ts +7 -2
- package/dist/types/modes/prompt-action-autocomplete.d.ts +6 -1
- package/dist/types/modes/prompt-suggestion-controller.d.ts +35 -0
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +2 -2
- package/dist/types/modes/types.d.ts +4 -0
- package/dist/types/modes/utils/hotkeys-markdown.d.ts +2 -1
- package/dist/types/runtime-mcp/content-limits.d.ts +7 -0
- package/dist/types/runtime-mcp/manager.d.ts +1 -1
- package/dist/types/runtime-mcp/oauth-flow.d.ts +0 -5
- package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +14 -0
- package/dist/types/sdk/broker/broker.d.ts +2 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +6 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +6 -1
- package/dist/types/sdk/bus/config-commands.d.ts +2 -2
- package/dist/types/sdk/bus/config.d.ts +2 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +1 -0
- package/dist/types/sdk/bus/index.d.ts +26 -1
- package/dist/types/sdk/bus/lifecycle-commands.d.ts +5 -4
- package/dist/types/sdk/bus/notification-orchestration.d.ts +1 -0
- package/dist/types/sdk/bus/notification-service.d.ts +34 -0
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +105 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +18 -3
- package/dist/types/sdk/bus/telegram-daemon-control.d.ts +5 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +189 -4
- package/dist/types/sdk/bus/telegram-reference.d.ts +2 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +88 -2
- package/dist/types/sdk/client/discovery.d.ts +2 -0
- package/dist/types/sdk/client/liveness.d.ts +7 -0
- package/dist/types/sdk/host/control/operations.d.ts +1 -1
- package/dist/types/sdk/host/host.d.ts +1 -1
- package/dist/types/sdk/host/query/handlers.d.ts +9 -0
- package/dist/types/sdk/index.d.ts +2 -0
- package/dist/types/sdk/prompt-status.d.ts +88 -0
- package/dist/types/sdk/session-directory.d.ts +1 -1
- package/dist/types/sdk/startup-capability.d.ts +3 -0
- package/dist/types/sdk/transport/auth-preface.d.ts +9 -0
- package/dist/types/sdk/transport/index.d.ts +12 -0
- package/dist/types/sdk/transport/relay.d.ts +43 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +4 -0
- package/dist/types/sdk/transport/socket.d.ts +7 -0
- package/dist/types/sdk/transport/stdio.d.ts +3 -0
- package/dist/types/session/agent-session.d.ts +30 -5
- package/dist/types/session/btw-contract.d.ts +16 -0
- package/dist/types/session/internal/managed-session-scope.d.ts +32 -9
- package/dist/types/session/internal/managed-session-storage.d.ts +27 -10
- package/dist/types/session/internal/native-publish-outcome.d.ts +48 -0
- package/dist/types/session/session-manager.d.ts +25 -4
- package/dist/types/session/session-storage.d.ts +18 -0
- package/dist/types/setup/credential-import.d.ts +5 -1
- package/dist/types/setup/provider-onboarding.d.ts +2 -0
- package/dist/types/ssh/utils.d.ts +1 -0
- package/dist/types/task/discovery.d.ts +3 -1
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/task/receipt.d.ts +2 -0
- package/dist/types/task/types.d.ts +94 -0
- package/dist/types/tools/ask.d.ts +454 -174
- package/dist/types/tools/fetch.d.ts +5 -8
- package/dist/types/tools/image-gen.d.ts +63 -1
- package/dist/types/tools/index.d.ts +4 -0
- package/dist/types/tools/skill-discovery.d.ts +7 -0
- package/dist/types/tools/sqlite-reader.d.ts +7 -0
- package/dist/types/utils/prompt-suggestion.d.ts +33 -0
- package/dist/types/utils/shell-snapshot.d.ts +12 -0
- package/dist/types/web/insane/bridge.d.ts +1 -0
- package/dist/types/web/insane/url-guard.d.ts +17 -0
- package/package.json +8 -8
- package/scripts/capture-platform-shortcut-labels-showcase.ts +342 -0
- package/scripts/dogfood-repository-binding.ts +209 -0
- package/scripts/generate-sdk-operation-inventory.ts +4 -0
- package/scripts/run-test-manifest.ts +4 -4
- package/src/capability/index.ts +50 -42
- package/src/capability/types.ts +3 -0
- package/src/cli/args.ts +2 -92
- package/src/cli/notify-cli.ts +5 -38
- package/src/cli/setup-cli.ts +10 -4
- package/src/cli.ts +52 -9
- package/src/commands/daemon.ts +22 -5
- package/src/commands/sdk.ts +44 -11
- package/src/config/keybindings.ts +158 -25
- package/src/config/model-profile-activation.ts +7 -18
- package/src/config/model-profile-contract.ts +161 -0
- package/src/config/model-profiles.ts +18 -0
- package/src/config/model-registry.ts +11 -1
- package/src/config/settings-schema.ts +73 -7
- package/src/coordinator-mcp/model-preset.ts +21 -74
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +2 -2
- package/src/defaults/gjc/skills/ralplan/SKILL.md +3 -1
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +42 -1
- package/src/discovery/ssh.ts +12 -1
- package/src/edit/index.ts +3 -6
- package/src/edit/modes/patch.ts +38 -1
- package/src/edit/modes/replace.ts +42 -0
- package/src/edit/path-mutation-lock.ts +112 -0
- package/src/eval/py/executor.ts +30 -11
- package/src/eval/py/kernel.ts +1 -21
- package/src/eval/py/prelude.py +2 -2
- package/src/eval/py/runner-artifact.ts +84 -0
- package/src/eval/py/tool-bridge.ts +34 -18
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +2 -1
- package/src/extensibility/plugins/marketplace/fetcher.ts +191 -7
- package/src/gjc-runtime/launch-tmux.ts +1 -1
- package/src/gjc-runtime/managed-owner-supervisor.ts +83 -4
- package/src/gjc-runtime/ralplan-runtime.ts +75 -3
- package/src/gjc-runtime/repository-binding.ts +267 -0
- package/src/gjc-runtime/session-state-sidecar.ts +25 -9
- package/src/gjc-runtime/tmux-owner-isolation.ts +2 -1
- package/src/gjc-runtime/tmux-sessions.ts +45 -6
- package/src/gjc-runtime/ultragoal-guard.ts +93 -15
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +103 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +456 -31
- package/src/gjc-runtime/workflow-manifest.generated.json +58 -0
- package/src/gjc-runtime/workflow-manifest.ts +23 -0
- package/src/internal-urls/docs-index.generated.ts +12 -10
- package/src/internal-urls/local-protocol.ts +64 -21
- package/src/internal-urls/mcp-protocol.ts +73 -11
- package/src/main.ts +111 -37
- package/src/modes/DESIGN.md +5 -0
- package/src/modes/acp/acp-agent.ts +50 -16
- package/src/modes/action-registry.ts +1 -1
- package/src/modes/components/btw-panel.ts +82 -16
- package/src/modes/components/model-selector.ts +73 -11
- package/src/modes/components/plan-preview-overlay.ts +1 -1
- package/src/modes/components/runtime-mcp-add-wizard.ts +5 -0
- package/src/modes/components/tool-status-header.ts +25 -4
- package/src/modes/components/welcome.ts +22 -18
- package/src/modes/controllers/btw-controller.ts +119 -36
- package/src/modes/controllers/command-controller.ts +97 -54
- package/src/modes/controllers/event-controller.ts +10 -0
- package/src/modes/controllers/input-controller.ts +38 -2
- package/src/modes/controllers/runtime-mcp-command-controller.ts +29 -6
- package/src/modes/controllers/selector-controller.ts +149 -63
- package/src/modes/interactive-mode.ts +57 -34
- package/src/modes/prompt-action-autocomplete.ts +32 -13
- package/src/modes/prompt-suggestion-controller.ts +96 -0
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +2 -2
- package/src/modes/types.ts +4 -0
- package/src/modes/utils/hotkeys-markdown.ts +64 -36
- package/src/modes/utils/ui-helpers.ts +5 -3
- package/src/prompts/agents/architect.md +0 -1
- package/src/prompts/agents/critic.md +0 -1
- package/src/prompts/system/btw-user.md +3 -8
- package/src/prompts/system/prompt-suggestion-system.md +32 -0
- package/src/prompts/system/system-prompt.md +6 -4
- package/src/prompts/tools/cron.md +3 -1
- package/src/prompts/tools/skill-discovery.md +1 -0
- package/src/runtime-mcp/client.ts +41 -55
- package/src/runtime-mcp/content-limits.ts +71 -0
- package/src/runtime-mcp/json-rpc.ts +23 -9
- package/src/runtime-mcp/manager.ts +51 -53
- package/src/runtime-mcp/oauth-flow.ts +0 -72
- package/src/runtime-mcp/plugin-network-boundary.ts +101 -0
- package/src/runtime-mcp/transports/http.ts +63 -22
- package/src/sdk/broker/broker.ts +34 -20
- package/src/sdk/broker/lifecycle.ts +185 -36
- package/src/sdk/bus/chat-daemon-control.ts +19 -5
- package/src/sdk/bus/config-commands.ts +2 -2
- package/src/sdk/bus/config.ts +9 -1
- package/src/sdk/bus/conversation-store.ts +40 -6
- package/src/sdk/bus/index.ts +244 -70
- package/src/sdk/bus/lifecycle-commands.ts +63 -10
- package/src/sdk/bus/lifecycle-control-runtime.ts +11 -2
- package/src/sdk/bus/lifecycle-orchestrator.ts +32 -1
- package/src/sdk/bus/notification-orchestration.ts +12 -0
- package/src/sdk/bus/notification-service.ts +68 -20
- package/src/sdk/bus/prompt-reconciliation.ts +239 -0
- package/src/sdk/bus/recent-activity.ts +90 -26
- package/src/sdk/bus/telegram-daemon-contract.ts +18 -3
- package/src/sdk/bus/telegram-daemon-control.ts +147 -35
- package/src/sdk/bus/telegram-daemon.ts +2463 -450
- package/src/sdk/bus/telegram-reference.ts +20 -2
- package/src/sdk/bus/topic-registry.ts +451 -12
- package/src/sdk/cli/session-cli.ts +15 -2
- package/src/sdk/client/discovery.ts +19 -3
- package/src/sdk/client/liveness.ts +49 -0
- package/src/sdk/host/control/dispatch.ts +1 -1
- package/src/sdk/host/control/operations.ts +1 -1
- package/src/sdk/host/host.ts +2 -6
- package/src/sdk/host/query/handlers.ts +70 -5
- package/src/sdk/index.ts +12 -0
- package/src/sdk/prompt-status.ts +97 -0
- package/src/sdk/protocol/operation-inventory.generated.json +58 -0
- package/src/sdk/protocol/operation-registry.ts +18 -4
- package/src/sdk/session-directory.ts +5 -1
- package/src/sdk/session.ts +31 -5
- package/src/sdk/startup-capability.ts +9 -1
- package/src/sdk/transport/auth-preface.ts +82 -0
- package/src/sdk/transport/index.ts +18 -0
- package/src/sdk/transport/relay.ts +252 -0
- package/src/sdk/transport/serve-cli.ts +105 -0
- package/src/sdk/transport/socket.ts +197 -0
- package/src/sdk/transport/stdio.ts +17 -0
- package/src/session/agent-session.ts +292 -154
- package/src/session/blob-store.ts +25 -7
- package/src/session/btw-contract.ts +59 -0
- package/src/session/internal/managed-session-scope.ts +1163 -137
- package/src/session/internal/managed-session-storage.ts +397 -234
- package/src/session/internal/native-publish-outcome.ts +266 -0
- package/src/session/session-manager.ts +620 -403
- package/src/session/session-storage.ts +128 -11
- package/src/setup/credential-import.ts +28 -3
- package/src/setup/provider-onboarding.ts +30 -1
- package/src/setup/provider-presets.json +2 -1
- package/src/slash-commands/builtin-registry.ts +1 -1
- package/src/ssh/utils.ts +14 -0
- package/src/task/discovery.ts +8 -2
- package/src/task/gjc-command.ts +2 -2
- package/src/task/index.ts +121 -15
- package/src/task/receipt.ts +3 -0
- package/src/task/types.ts +34 -3
- package/src/tools/ask.ts +199 -89
- package/src/tools/ast-edit.ts +2 -2
- package/src/tools/bash-pty-selection.ts +2 -2
- package/src/tools/browser/screenshot-format.ts +6 -1
- package/src/tools/cron.ts +1 -1
- package/src/tools/fetch.ts +13 -131
- package/src/tools/image-gen.ts +476 -23
- package/src/tools/index.ts +4 -0
- package/src/tools/read.ts +2 -0
- package/src/tools/render-utils.ts +7 -1
- package/src/tools/skill-discovery.ts +39 -3
- package/src/tools/sqlite-reader.ts +63 -5
- package/src/utils/edit-mode.ts +2 -2
- package/src/utils/pasted-image-path.ts +15 -6
- package/src/utils/prompt-suggestion.ts +265 -0
- package/src/utils/shell-snapshot.ts +173 -63
- package/src/utils/sixel.ts +3 -3
- package/src/web/insane/bridge.ts +5 -1
- package/src/web/insane/url-guard.ts +140 -27
- package/src/web/scrapers/docs-rs.ts +30 -5
- package/src/web/scrapers/types.ts +19 -49
- package/src/web/scrapers/utils.ts +12 -26
|
@@ -6,6 +6,8 @@ export interface SdkSessionEndpoint {
|
|
|
6
6
|
sessionId: string;
|
|
7
7
|
url: string;
|
|
8
8
|
token: string;
|
|
9
|
+
pid?: number;
|
|
10
|
+
stale?: boolean;
|
|
9
11
|
path: string;
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -38,12 +40,26 @@ function endpointDirectory(repo: string): string {
|
|
|
38
40
|
function parseEndpoint(sessionId: string, file: string, value: unknown): SdkSessionEndpoint {
|
|
39
41
|
if (!value || typeof value !== "object")
|
|
40
42
|
throw new SdkDiscoveryError(file, "SDK endpoint discovery record must be an object.");
|
|
41
|
-
const endpoint = value as { version?: unknown; url?: unknown; token?: unknown };
|
|
43
|
+
const endpoint = value as { version?: unknown; url?: unknown; token?: unknown; pid?: unknown; stale?: unknown };
|
|
42
44
|
if (typeof endpoint.version === "number" && endpoint.version > 1)
|
|
43
45
|
throw new SdkDiscoveryError(file, "Unsupported SDK endpoint discovery state version.");
|
|
44
|
-
if (typeof endpoint.url !== "string" ||
|
|
46
|
+
if (typeof endpoint.url !== "string" || !endpoint.url)
|
|
45
47
|
throw new SdkDiscoveryError(file, "SDK endpoint discovery record is invalid.");
|
|
46
|
-
|
|
48
|
+
const stale = typeof endpoint.stale === "boolean" ? endpoint.stale : undefined;
|
|
49
|
+
const pid =
|
|
50
|
+
typeof endpoint.pid === "number" && Number.isInteger(endpoint.pid) && endpoint.pid > 0 ? endpoint.pid : undefined;
|
|
51
|
+
if (endpoint.token !== undefined && typeof endpoint.token !== "string")
|
|
52
|
+
throw new SdkDiscoveryError(file, "SDK endpoint discovery record is invalid.");
|
|
53
|
+
const token = endpoint.token ?? "";
|
|
54
|
+
if (!token && stale !== true) throw new SdkDiscoveryError(file, "SDK endpoint discovery record is invalid.");
|
|
55
|
+
return {
|
|
56
|
+
sessionId,
|
|
57
|
+
url: endpoint.url,
|
|
58
|
+
token,
|
|
59
|
+
...(pid === undefined ? {} : { pid }),
|
|
60
|
+
...(stale === undefined ? {} : { stale }),
|
|
61
|
+
path: file,
|
|
62
|
+
};
|
|
47
63
|
}
|
|
48
64
|
|
|
49
65
|
function discoveryError(file: string, error: unknown): SdkDiscoveryError {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { SdkSessionEndpoint } from "./discovery";
|
|
2
|
+
|
|
3
|
+
export type SdkEndpointLiveness = "live" | "stale" | "dead" | "unknown";
|
|
4
|
+
|
|
5
|
+
export interface SdkEndpointSelectionError {
|
|
6
|
+
code:
|
|
7
|
+
| "endpoint_stale"
|
|
8
|
+
| "endpoint_dead"
|
|
9
|
+
| "endpoint_unknown"
|
|
10
|
+
| "no_live_endpoint"
|
|
11
|
+
| "multiple_live_endpoints"
|
|
12
|
+
| "not_found";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function classifyEndpoint(endpoint: SdkSessionEndpoint): SdkEndpointLiveness {
|
|
16
|
+
if (endpoint.stale === true) return "stale";
|
|
17
|
+
if (!Number.isInteger(endpoint.pid) || endpoint.pid === undefined || endpoint.pid <= 0) return "unknown";
|
|
18
|
+
try {
|
|
19
|
+
process.kill(endpoint.pid, 0);
|
|
20
|
+
return "live";
|
|
21
|
+
} catch (error) {
|
|
22
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
23
|
+
if (code === "ESRCH") return "dead";
|
|
24
|
+
return code === "EPERM" ? "live" : "unknown";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function selectLiveEndpoint(
|
|
29
|
+
records: readonly SdkSessionEndpoint[],
|
|
30
|
+
explicitSessionId?: string,
|
|
31
|
+
): SdkSessionEndpoint | SdkEndpointSelectionError {
|
|
32
|
+
if (explicitSessionId !== undefined) {
|
|
33
|
+
const endpoint = records.find(record => record.sessionId === explicitSessionId);
|
|
34
|
+
if (!endpoint) return { code: "not_found" };
|
|
35
|
+
switch (classifyEndpoint(endpoint)) {
|
|
36
|
+
case "live":
|
|
37
|
+
return endpoint;
|
|
38
|
+
case "stale":
|
|
39
|
+
return { code: "endpoint_stale" };
|
|
40
|
+
case "dead":
|
|
41
|
+
return { code: "endpoint_dead" };
|
|
42
|
+
case "unknown":
|
|
43
|
+
return { code: "endpoint_unknown" };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const live = records.filter(record => classifyEndpoint(record) === "live");
|
|
47
|
+
if (live.length === 1) return live[0]!;
|
|
48
|
+
return { code: live.length === 0 ? "no_live_endpoint" : "multiple_live_endpoints" };
|
|
49
|
+
}
|
|
@@ -137,7 +137,7 @@ function invoke(
|
|
|
137
137
|
): Promise<ControlValue> | ControlValue {
|
|
138
138
|
switch (operation) {
|
|
139
139
|
case "turn.prompt":
|
|
140
|
-
return surface.prompt(text(input), input.images);
|
|
140
|
+
return surface.prompt(text(input), input.images, input.clientRef as string | undefined);
|
|
141
141
|
case "turn.steer":
|
|
142
142
|
return surface.steer(text(input));
|
|
143
143
|
case "turn.follow_up":
|
|
@@ -6,7 +6,7 @@ export type ControlInput = Record<string, unknown>;
|
|
|
6
6
|
* AgentSession and its controllers without exposing those concrete types here.
|
|
7
7
|
*/
|
|
8
8
|
export interface ControlSurface {
|
|
9
|
-
prompt(text: string, images?: ControlValue): Promise<ControlValue> | ControlValue;
|
|
9
|
+
prompt(text: string, images?: ControlValue, clientRef?: string): Promise<ControlValue> | ControlValue;
|
|
10
10
|
steer(text: string): Promise<ControlValue> | ControlValue;
|
|
11
11
|
followUp(text: string): Promise<ControlValue> | ControlValue;
|
|
12
12
|
abort(): Promise<ControlValue> | ControlValue;
|
package/src/sdk/host/host.ts
CHANGED
|
@@ -15,7 +15,7 @@ export interface SessionSdkHostOptions extends HostEndpointAdapters {
|
|
|
15
15
|
onProviderDefinitionsRemoved?: (capability: string) => void;
|
|
16
16
|
onReverseCancel?: (requestId: string, reason: "provider_disconnected" | "lease_released") => void;
|
|
17
17
|
/** Best-effort capabilities mirrored from the native transport for out-of-band consumers. */
|
|
18
|
-
connectionCapabilities?: (connectionId: string) => ReadonlySet<string
|
|
18
|
+
connectionCapabilities?: (connectionId: string) => ReadonlySet<string> | undefined;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
const TOOL_ACTIVITY_V1 = "tool_activity_v1";
|
|
@@ -231,11 +231,7 @@ export class SessionSdkHost {
|
|
|
231
231
|
const sinceGeneration = rawGeneration;
|
|
232
232
|
const sinceSeq = rawSeq;
|
|
233
233
|
const replay = this.events.replay(sinceSeq, sinceGeneration);
|
|
234
|
-
const capabilities =
|
|
235
|
-
? new Set(
|
|
236
|
-
frame.capabilities.filter((capability): capability is string => typeof capability === "string"),
|
|
237
|
-
)
|
|
238
|
-
: (this.#options.connectionCapabilities?.(connectionId) ?? EMPTY_CAPABILITIES);
|
|
234
|
+
const capabilities = this.#options.connectionCapabilities?.(connectionId) ?? EMPTY_CAPABILITIES;
|
|
239
235
|
const events = replay.events.filter(
|
|
240
236
|
event => !CAP_GATED_FRAME_KINDS.has(String(event.kind)) || capabilities.has(TOOL_ACTIVITY_V1),
|
|
241
237
|
);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PROMPT_CLIENT_REF_MAX_LENGTH } from "../../prompt-status.js";
|
|
1
2
|
import {
|
|
2
3
|
assertCursorSelector,
|
|
3
4
|
type CursorEnvelope,
|
|
@@ -43,6 +44,10 @@ export interface SessionSurface {
|
|
|
43
44
|
| Promise<{ bytes: Uint8Array; totalBytes: number } | undefined>;
|
|
44
45
|
|
|
45
46
|
getJobs(): unknown | Promise<unknown>;
|
|
47
|
+
/** Q26 keyed lookup of a submitted prompt's authoritative reconciliation status. */
|
|
48
|
+
getPromptStatus?(selector: { commandId?: string; turnId?: string; clientRef?: string }): unknown | Promise<unknown>;
|
|
49
|
+
/** Q27 effective model-profile catalog from the live session registry. */
|
|
50
|
+
getModelProfiles?(): unknown[] | Promise<unknown[]>;
|
|
46
51
|
/** Query rows backed by the session's installed binding map. */
|
|
47
52
|
installedQueries?: ReadonlySet<string>;
|
|
48
53
|
}
|
|
@@ -66,7 +71,7 @@ export interface QueryResponse {
|
|
|
66
71
|
ok: boolean;
|
|
67
72
|
page?: QueryPage;
|
|
68
73
|
result?: unknown;
|
|
69
|
-
error?: { code: string; message: string; restartQuery?: boolean };
|
|
74
|
+
error?: { code: string; message: string; restartQuery?: boolean; details?: unknown };
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
const sources: Record<string, { resource: string; method: keyof SessionSurface; mvcc: boolean }> = {
|
|
@@ -92,6 +97,7 @@ const sources: Record<string, { resource: string; method: keyof SessionSurface;
|
|
|
92
97
|
Q21: { resource: "queue", method: "getQueueMessages", mvcc: true },
|
|
93
98
|
Q22: { resource: "extensions", method: "getExtensions", mvcc: true },
|
|
94
99
|
Q25: { resource: "jobs", method: "getJobs", mvcc: false },
|
|
100
|
+
Q27: { resource: "modelProfiles", method: "getModelProfiles", mvcc: true },
|
|
95
101
|
};
|
|
96
102
|
const names = [
|
|
97
103
|
"transcript.list",
|
|
@@ -119,6 +125,8 @@ const names = [
|
|
|
119
125
|
"resource.body",
|
|
120
126
|
"artifact.read",
|
|
121
127
|
"runtime.jobs.list",
|
|
128
|
+
"turn.prompt_status",
|
|
129
|
+
"models.profiles.list",
|
|
122
130
|
];
|
|
123
131
|
|
|
124
132
|
export class QueryHandlers {
|
|
@@ -147,13 +155,18 @@ export class QueryHandlers {
|
|
|
147
155
|
);
|
|
148
156
|
if (query === "Q02") return await this.#transcriptBody(request);
|
|
149
157
|
if (query === "Q23") return await this.#resourceBody(request);
|
|
158
|
+
if (query === "Q26") return await this.#promptStatus(request);
|
|
150
159
|
if (query === "Q24") return await this.#artifact(request);
|
|
160
|
+
if (query === "Q27" && request.input && Object.keys(request.input).length > 0)
|
|
161
|
+
return this.#error(request, "invalid_request", false, "models.profiles.list does not accept input fields.");
|
|
162
|
+
if (query === "Q27" && typeof this.surface.getModelProfiles !== "function")
|
|
163
|
+
return this.#error(request, "unavailable", false, "models.profiles.list is unavailable for this session.");
|
|
151
164
|
const source = sources[query];
|
|
152
165
|
if (!source) return this.#error(request, "invalid_request");
|
|
153
166
|
return await this.#pageSource(request, query, source);
|
|
154
167
|
} catch (error) {
|
|
155
168
|
if (error instanceof CursorError) return this.#error(request, error.code, error.restartQuery, error.message);
|
|
156
|
-
if (isTypedError(error)) return this.#error(request, error.code, false, error.message);
|
|
169
|
+
if (isTypedError(error)) return this.#error(request, error.code, false, error.message, error.details);
|
|
157
170
|
return this.#error(request, "internal", false, error instanceof Error ? error.message : String(error));
|
|
158
171
|
}
|
|
159
172
|
}
|
|
@@ -504,8 +517,60 @@ export class QueryHandlers {
|
|
|
504
517
|
return { id: request.id, ok: true, page };
|
|
505
518
|
}
|
|
506
519
|
|
|
507
|
-
#
|
|
508
|
-
|
|
520
|
+
async #promptStatus(request: QueryRequest): Promise<QueryResponse> {
|
|
521
|
+
if (request.cursor)
|
|
522
|
+
return this.#error(request, "invalid_request", false, "turn.prompt_status does not support cursors.");
|
|
523
|
+
const input = request.input ?? {};
|
|
524
|
+
for (const key of Object.keys(input))
|
|
525
|
+
if (key !== "commandId" && key !== "turnId" && key !== "clientRef")
|
|
526
|
+
return this.#error(
|
|
527
|
+
request,
|
|
528
|
+
"invalid_request",
|
|
529
|
+
false,
|
|
530
|
+
`turn.prompt_status does not accept selector field "${key}".`,
|
|
531
|
+
);
|
|
532
|
+
const commandId = typeof input.commandId === "string" && input.commandId ? input.commandId : undefined;
|
|
533
|
+
const turnId = typeof input.turnId === "string" && input.turnId ? input.turnId : undefined;
|
|
534
|
+
const rawClientRef = typeof input.clientRef === "string" ? input.clientRef : undefined;
|
|
535
|
+
const trimmedClientRef = rawClientRef?.trim();
|
|
536
|
+
if (rawClientRef !== undefined && (!trimmedClientRef || trimmedClientRef.length > PROMPT_CLIENT_REF_MAX_LENGTH))
|
|
537
|
+
return this.#error(
|
|
538
|
+
request,
|
|
539
|
+
"invalid_request",
|
|
540
|
+
false,
|
|
541
|
+
"clientRef must be a non-empty string of at most 128 characters.",
|
|
542
|
+
);
|
|
543
|
+
const clientRef = trimmedClientRef || undefined;
|
|
544
|
+
if ((commandId === undefined) !== (turnId === undefined))
|
|
545
|
+
return this.#error(request, "invalid_request", false, "commandId and turnId must be provided together.");
|
|
546
|
+
if (commandId !== undefined && clientRef !== undefined)
|
|
547
|
+
return this.#error(
|
|
548
|
+
request,
|
|
549
|
+
"invalid_request",
|
|
550
|
+
false,
|
|
551
|
+
"Provide exactly one selector: a commandId/turnId pair or a clientRef.",
|
|
552
|
+
);
|
|
553
|
+
if (commandId === undefined && clientRef === undefined)
|
|
554
|
+
return this.#error(
|
|
555
|
+
request,
|
|
556
|
+
"invalid_request",
|
|
557
|
+
false,
|
|
558
|
+
"turn.prompt_status requires a commandId/turnId pair or a clientRef.",
|
|
559
|
+
);
|
|
560
|
+
if (typeof this.surface.getPromptStatus !== "function")
|
|
561
|
+
return this.#error(request, "unavailable", false, "turn.prompt_status is unavailable for this session.");
|
|
562
|
+
const result = await this.surface.getPromptStatus(
|
|
563
|
+
clientRef !== undefined ? { clientRef } : { commandId: commandId!, turnId: turnId! },
|
|
564
|
+
);
|
|
565
|
+
return { id: request.id, ok: true, result };
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
#error(request: QueryRequest, code: string, restartQuery = false, message = code, details?: unknown): QueryResponse {
|
|
569
|
+
return {
|
|
570
|
+
id: request.id,
|
|
571
|
+
ok: false,
|
|
572
|
+
error: { code, message, ...(restartQuery ? { restartQuery: true } : {}), ...(details ? { details } : {}) },
|
|
573
|
+
};
|
|
509
574
|
}
|
|
510
575
|
}
|
|
511
576
|
function selectorFor(queryId: string, input: Record<string, unknown> | undefined): CursorSelector {
|
|
@@ -521,7 +586,7 @@ function idOf(value: unknown): string | undefined {
|
|
|
521
586
|
function lastId(value: unknown): string | undefined {
|
|
522
587
|
return Array.isArray(value) ? idOf(value.at(-1)) : undefined;
|
|
523
588
|
}
|
|
524
|
-
function isTypedError(error: unknown): error is { code: string; message: string } {
|
|
589
|
+
function isTypedError(error: unknown): error is { code: string; message: string; details?: unknown } {
|
|
525
590
|
return Boolean(
|
|
526
591
|
error &&
|
|
527
592
|
typeof error === "object" &&
|
package/src/sdk/index.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
export {
|
|
2
|
+
MODEL_PROFILE_DISCOVERY_QUERY,
|
|
3
|
+
MODEL_PROFILE_ERROR_DETAIL_MAX_BYTES,
|
|
4
|
+
type ModelProfileCatalogItem,
|
|
5
|
+
type ModelProfileErrorCode,
|
|
6
|
+
type ModelProfileErrorDetails,
|
|
7
|
+
ModelProfileRegistryError,
|
|
8
|
+
type ModelProfileRegistryErrorDetails,
|
|
9
|
+
type UnknownModelProfileDetails,
|
|
10
|
+
UnknownModelProfileError,
|
|
11
|
+
} from "../config/model-profile-contract";
|
|
1
12
|
export * as bus from "./bus";
|
|
2
13
|
export * from "./client";
|
|
3
14
|
export * as host from "./host";
|
|
@@ -10,5 +21,6 @@ export type {
|
|
|
10
21
|
Q10ThinkingEffort,
|
|
11
22
|
Q10ThinkingMode,
|
|
12
23
|
} from "./models";
|
|
24
|
+
export * from "./prompt-status";
|
|
13
25
|
export * from "./session";
|
|
14
26
|
export * from "./session-directory";
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public DTO contract for Q26 `turn.prompt_status` and the `clientRef`
|
|
3
|
+
* correlation field on `turn.prompt`.
|
|
4
|
+
*
|
|
5
|
+
* Semantics:
|
|
6
|
+
* - `turn.prompt` remains ordered and non-idempotent. An envelope
|
|
7
|
+
* `idempotencyKey` is ignored for replay/conflict purposes on ordered
|
|
8
|
+
* operations (no replay cache, no `idempotency_conflict`).
|
|
9
|
+
* - `clientRef` is a caller-chosen correlation key (trimmed, non-empty,
|
|
10
|
+
* 1..PROMPT_CLIENT_REF_MAX_LENGTH chars; one fresh value per logical prompt)
|
|
11
|
+
* mapped to the generated commandId/turnId at preflight acceptance so a
|
|
12
|
+
* caller can reconcile after a lost acknowledgement frame.
|
|
13
|
+
* - The clientRef index is scoped to one live session runtime: identical refs
|
|
14
|
+
* may coexist in different sessions, lookups never cross sessions, a ref
|
|
15
|
+
* conflicts only while its record is retained (`client_ref_conflict`), and
|
|
16
|
+
* after terminal TTL/capacity eviction a ref may be admitted again with the
|
|
17
|
+
* prior outcome unknown — callers MUST NOT reuse a clientRef as a retry
|
|
18
|
+
* mechanism and MUST treat `unknown` as uncertainty, not proof of
|
|
19
|
+
* non-execution.
|
|
20
|
+
* - The durability floor is the live session process: after restart or
|
|
21
|
+
* retained-record eviction, a lookup honestly reports `unknown`.
|
|
22
|
+
* - Q26 tracks prompts accepted through the SDK control surface (which always
|
|
23
|
+
* carries a requesting connection); submissions without a delivery owner are
|
|
24
|
+
* outside the reconciliation contract and hold no reservation.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
export const PROMPT_CLIENT_REF_MAX_LENGTH = 128;
|
|
28
|
+
|
|
29
|
+
export interface TurnPromptImageInput {
|
|
30
|
+
data: string;
|
|
31
|
+
mimeType?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Public input contract for ordered `turn.prompt`. */
|
|
35
|
+
export interface TurnPromptInput {
|
|
36
|
+
text: string;
|
|
37
|
+
images?: TurnPromptImageInput[];
|
|
38
|
+
clientRef?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Terminal outcome is preserved exactly; active records never age into terminal. */
|
|
42
|
+
export type PromptReconciliationStatus = "accepted" | "in_flight" | "terminal_ok" | "failed";
|
|
43
|
+
|
|
44
|
+
/** Exactly one selector per lookup. */
|
|
45
|
+
export type TurnPromptStatusSelector = { clientRef: string } | { commandId: string; turnId: string };
|
|
46
|
+
|
|
47
|
+
interface TurnPromptReconciliationIdentity {
|
|
48
|
+
commandId: string;
|
|
49
|
+
turnId: string;
|
|
50
|
+
clientRef?: string;
|
|
51
|
+
/** Epoch milliseconds of preflight acceptance. */
|
|
52
|
+
acceptedAt: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface TurnPromptReconciliationAccepted extends TurnPromptReconciliationIdentity {
|
|
56
|
+
status: "accepted";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface TurnPromptReconciliationInFlight extends TurnPromptReconciliationIdentity {
|
|
60
|
+
status: "in_flight";
|
|
61
|
+
/** Epoch milliseconds of the agent_start transition. */
|
|
62
|
+
startedAt: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface TurnPromptReconciliationTerminalOk extends TurnPromptReconciliationIdentity {
|
|
66
|
+
status: "terminal_ok";
|
|
67
|
+
startedAt?: number;
|
|
68
|
+
/** Epoch milliseconds of the terminal transition. */
|
|
69
|
+
terminalAt: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface TurnPromptReconciliationFailed extends TurnPromptReconciliationIdentity {
|
|
73
|
+
status: "failed";
|
|
74
|
+
startedAt?: number;
|
|
75
|
+
terminalAt: number;
|
|
76
|
+
/** Bounded, sanitized failure detail (code safe-token ≤64, message ≤512). */
|
|
77
|
+
error: { code: string; message: string };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface TurnPromptReconciliationUnknown {
|
|
81
|
+
status: "unknown";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export type TurnPromptReconciliation =
|
|
85
|
+
| TurnPromptReconciliationAccepted
|
|
86
|
+
| TurnPromptReconciliationInFlight
|
|
87
|
+
| TurnPromptReconciliationTerminalOk
|
|
88
|
+
| TurnPromptReconciliationFailed
|
|
89
|
+
| TurnPromptReconciliationUnknown;
|
|
90
|
+
|
|
91
|
+
/** Result of a successful `turn.prompt` preflight acknowledgement. */
|
|
92
|
+
export interface TurnPromptAcceptedResult {
|
|
93
|
+
commandId: string;
|
|
94
|
+
turnId: string;
|
|
95
|
+
accepted: true;
|
|
96
|
+
clientRef?: string;
|
|
97
|
+
}
|
|
@@ -1511,6 +1511,42 @@
|
|
|
1511
1511
|
"packages/coding-agent/test/sdk-operation-inventory.test.ts"
|
|
1512
1512
|
]
|
|
1513
1513
|
},
|
|
1514
|
+
{
|
|
1515
|
+
"sourceId": "registry:Q26",
|
|
1516
|
+
"sourceFile": "packages/coding-agent/src/sdk/protocol/operation-registry.ts",
|
|
1517
|
+
"sourceKind": "registry",
|
|
1518
|
+
"decision": "include",
|
|
1519
|
+
"sdkId": "turn.prompt_status",
|
|
1520
|
+
"adapterMappings": {
|
|
1521
|
+
"telegram": "prohibited",
|
|
1522
|
+
"discord": "prohibited",
|
|
1523
|
+
"slack": "prohibited",
|
|
1524
|
+
"mcp": "generic_safe",
|
|
1525
|
+
"acp": "generic_safe",
|
|
1526
|
+
"daemonCli": "generic_safe"
|
|
1527
|
+
},
|
|
1528
|
+
"testIds": [
|
|
1529
|
+
"packages/coding-agent/test/sdk-operation-inventory.test.ts"
|
|
1530
|
+
]
|
|
1531
|
+
},
|
|
1532
|
+
{
|
|
1533
|
+
"sourceId": "registry:Q27",
|
|
1534
|
+
"sourceFile": "packages/coding-agent/src/sdk/protocol/operation-registry.ts",
|
|
1535
|
+
"sourceKind": "registry",
|
|
1536
|
+
"decision": "include",
|
|
1537
|
+
"sdkId": "models.profiles.list",
|
|
1538
|
+
"adapterMappings": {
|
|
1539
|
+
"telegram": "prohibited",
|
|
1540
|
+
"discord": "prohibited",
|
|
1541
|
+
"slack": "prohibited",
|
|
1542
|
+
"mcp": "generic_safe",
|
|
1543
|
+
"acp": "generic_safe",
|
|
1544
|
+
"daemonCli": "generic_safe"
|
|
1545
|
+
},
|
|
1546
|
+
"testIds": [
|
|
1547
|
+
"packages/coding-agent/test/sdk-operation-inventory.test.ts"
|
|
1548
|
+
]
|
|
1549
|
+
},
|
|
1514
1550
|
{
|
|
1515
1551
|
"sourceId": "registry:R01",
|
|
1516
1552
|
"sourceFile": "packages/coding-agent/src/sdk/protocol/operation-registry.ts",
|
|
@@ -2294,6 +2330,17 @@
|
|
|
2294
2330
|
"testIds": "not_applicable"
|
|
2295
2331
|
}
|
|
2296
2332
|
},
|
|
2333
|
+
{
|
|
2334
|
+
"sourceId": "agent_session:getDeepInterviewAskStage",
|
|
2335
|
+
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
2336
|
+
"sourceKind": "agent_session",
|
|
2337
|
+
"decision": "exclude",
|
|
2338
|
+
"rationale": "internal AskTool schema-selection accessor, not a user-facing SDK control seam",
|
|
2339
|
+
"exclusionMetadata": {
|
|
2340
|
+
"adapterMappings": "not_applicable",
|
|
2341
|
+
"testIds": "not_applicable"
|
|
2342
|
+
}
|
|
2343
|
+
},
|
|
2297
2344
|
{
|
|
2298
2345
|
"sourceId": "agent_session:peekQueueInvoker",
|
|
2299
2346
|
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
@@ -4430,6 +4477,17 @@
|
|
|
4430
4477
|
"testIds": "not_applicable"
|
|
4431
4478
|
}
|
|
4432
4479
|
},
|
|
4480
|
+
{
|
|
4481
|
+
"sourceId": "agent_session:createBtwConversationScope",
|
|
4482
|
+
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
4483
|
+
"sourceKind": "agent_session",
|
|
4484
|
+
"decision": "exclude",
|
|
4485
|
+
"rationale": "internal privacy-scoped side-chat snapshot factory, not a user-facing SDK control seam",
|
|
4486
|
+
"exclusionMetadata": {
|
|
4487
|
+
"adapterMappings": "not_applicable",
|
|
4488
|
+
"testIds": "not_applicable"
|
|
4489
|
+
}
|
|
4490
|
+
},
|
|
4433
4491
|
{
|
|
4434
4492
|
"sourceId": "agent_session:runEphemeralTurn",
|
|
4435
4493
|
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
@@ -154,6 +154,11 @@ const queries = [
|
|
|
154
154
|
["resource.body", "Read a bounded resource continuation."],
|
|
155
155
|
["artifact.read", "Read a bounded artifact range."],
|
|
156
156
|
["runtime.jobs.list", "List managed jobs."],
|
|
157
|
+
[
|
|
158
|
+
"turn.prompt_status",
|
|
159
|
+
"Read the authoritative reconciliation status of a submitted prompt by command/turn IDs or clientRef.",
|
|
160
|
+
],
|
|
161
|
+
["models.profiles.list", "List the effective built-in and configured model profiles for this session."],
|
|
157
162
|
] as const;
|
|
158
163
|
|
|
159
164
|
const reverse = [
|
|
@@ -191,6 +196,7 @@ function controlDisposition(id: string): Record<Adapter, AdapterDisposition> {
|
|
|
191
196
|
|
|
192
197
|
function controlErrors(id: string): string[] {
|
|
193
198
|
const errors: Record<string, string[]> = {
|
|
199
|
+
C01: ["client_ref_conflict", "reconciliation_capacity"],
|
|
194
200
|
C06: ["action_claimed"],
|
|
195
201
|
C07: ["action_claimed", "terminal_uncertain"],
|
|
196
202
|
C08: ["action_claimed", "terminal_uncertain"],
|
|
@@ -224,14 +230,14 @@ function revision(id: string): string | undefined {
|
|
|
224
230
|
}
|
|
225
231
|
function queryContinuityClass(id: string): QueryContinuityClass {
|
|
226
232
|
if (["Q01", "Q02"].includes(id)) return "stable_prefix";
|
|
227
|
-
if (["Q04", "Q05", "Q06", "Q07", "Q08", "Q11", "Q12", "Q13", "Q20", "Q21", "Q22", "Q23"].includes(id))
|
|
233
|
+
if (["Q04", "Q05", "Q06", "Q07", "Q08", "Q11", "Q12", "Q13", "Q20", "Q21", "Q22", "Q23", "Q27"].includes(id))
|
|
228
234
|
return "retained_revision";
|
|
229
235
|
if (id === "Q24") return "content_addressed";
|
|
230
236
|
return "scalar_snapshot";
|
|
231
237
|
}
|
|
232
238
|
|
|
233
239
|
function queryDisposition(id: string): Record<Adapter, AdapterDisposition> {
|
|
234
|
-
if (["Q23", "Q24", "Q25"].includes(id))
|
|
240
|
+
if (["Q23", "Q24", "Q25", "Q26", "Q27"].includes(id))
|
|
235
241
|
return dispositions({ telegram: "prohibited", discord: "prohibited", slack: "prohibited" });
|
|
236
242
|
return dispositions();
|
|
237
243
|
}
|
|
@@ -263,7 +269,12 @@ export const OPERATIONS: readonly Operation[] = [
|
|
|
263
269
|
kind: "global" as const,
|
|
264
270
|
description,
|
|
265
271
|
idempotency: "idempotent" as const,
|
|
266
|
-
errorCodes:
|
|
272
|
+
errorCodes:
|
|
273
|
+
id === "G02"
|
|
274
|
+
? ["endpoint_credential_forbidden"]
|
|
275
|
+
: ["G03", "G04", "G05"].includes(id)
|
|
276
|
+
? ["invalid_request", "unknown_model_profile", "model_profile_registry_error"]
|
|
277
|
+
: ["invalid_request"],
|
|
267
278
|
adapterDispositions:
|
|
268
279
|
id === "G02"
|
|
269
280
|
? dispositions({
|
|
@@ -286,7 +297,10 @@ export const OPERATIONS: readonly Operation[] = [
|
|
|
286
297
|
kind: "query" as const,
|
|
287
298
|
description,
|
|
288
299
|
idempotency: "idempotent" as const,
|
|
289
|
-
errorCodes:
|
|
300
|
+
errorCodes:
|
|
301
|
+
id === "Q27"
|
|
302
|
+
? ["invalid_request", "resource_gone", "model_profile_registry_error"]
|
|
303
|
+
: ["invalid_request", "resource_gone"],
|
|
290
304
|
continuityClass: queryContinuityClass(id),
|
|
291
305
|
adapterDispositions: queryDisposition(id),
|
|
292
306
|
testIds: ["packages/coding-agent/test/sdk-operation-inventory.test.ts"],
|
|
@@ -38,7 +38,11 @@ export type ResolveManagedSessionScopeResult =
|
|
|
38
38
|
| "network_unsupported"
|
|
39
39
|
| "sessions_root_unavailable"
|
|
40
40
|
| "binding_conflict"
|
|
41
|
-
| "binding_invalid"
|
|
41
|
+
| "binding_invalid"
|
|
42
|
+
| "atomic_unavailable"
|
|
43
|
+
| "durability_not_provable"
|
|
44
|
+
| "durability_failed"
|
|
45
|
+
| "invalid_request";
|
|
42
46
|
message: string;
|
|
43
47
|
};
|
|
44
48
|
|
package/src/sdk/session.ts
CHANGED
|
@@ -92,6 +92,7 @@ import type { FileSlashCommand } from "../extensibility/slash-commands";
|
|
|
92
92
|
import type { HindsightSessionState } from "../hindsight/state";
|
|
93
93
|
import { initializeLocalRoot, LocalProtocolHandler, type LocalProtocolOptions } from "../internal-urls";
|
|
94
94
|
import { resolveMemoryBackend } from "../memory-backend";
|
|
95
|
+
import btwUserPrompt from "../prompts/system/btw-user.md" with { type: "text" };
|
|
95
96
|
import asyncResultTemplate from "../prompts/tools/async-result.md" with { type: "text" };
|
|
96
97
|
import { AgentRegistry, MAIN_AGENT_ID } from "../registry/agent-registry";
|
|
97
98
|
import { MCPManager } from "../runtime-mcp";
|
|
@@ -149,6 +150,7 @@ import {
|
|
|
149
150
|
ReadTool,
|
|
150
151
|
ResolveTool,
|
|
151
152
|
SearchTool,
|
|
153
|
+
setConfiguredImageModel,
|
|
152
154
|
setPreferredImageProvider,
|
|
153
155
|
setPreferredSearchProvider,
|
|
154
156
|
setSearchFallbackProviders,
|
|
@@ -1158,14 +1160,27 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1158
1160
|
applyConfiguredSearchTimeout(settings);
|
|
1159
1161
|
|
|
1160
1162
|
const imageProvider = settings.get("providers.image");
|
|
1163
|
+
const imageModel = settings.get("providers.imageModel");
|
|
1164
|
+
const imageCustomUrl = settings.get("providers.imageCustomUrl");
|
|
1165
|
+
const imageCustomKey = settings.get("providers.imageCustomKey");
|
|
1166
|
+
const imageCustomKeyEnv = settings.get("providers.imageCustomKeyEnv");
|
|
1161
1167
|
if (
|
|
1162
1168
|
imageProvider === "auto" ||
|
|
1163
1169
|
imageProvider === "openai" ||
|
|
1164
1170
|
imageProvider === "gemini" ||
|
|
1165
1171
|
imageProvider === "openrouter" ||
|
|
1166
|
-
imageProvider === "antigravity"
|
|
1172
|
+
imageProvider === "antigravity" ||
|
|
1173
|
+
imageProvider === "alibaba" ||
|
|
1174
|
+
imageProvider === "custom"
|
|
1167
1175
|
) {
|
|
1168
|
-
setPreferredImageProvider(imageProvider);
|
|
1176
|
+
setPreferredImageProvider(imageProvider === "custom" ? "auto" : imageProvider);
|
|
1177
|
+
setConfiguredImageModel({
|
|
1178
|
+
provider: imageProvider,
|
|
1179
|
+
model: imageModel ?? null,
|
|
1180
|
+
customUrl: imageCustomUrl,
|
|
1181
|
+
customKey: imageCustomKey,
|
|
1182
|
+
customKeyEnv: imageCustomKeyEnv,
|
|
1183
|
+
});
|
|
1169
1184
|
}
|
|
1170
1185
|
|
|
1171
1186
|
const sessionManager =
|
|
@@ -1509,6 +1524,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1509
1524
|
isManagedSessionDestination: () => sessionManager.isManagedDestination(),
|
|
1510
1525
|
getActiveSkillState: () => session?.getActiveSkillState(),
|
|
1511
1526
|
getActiveSkillPhase: () => session?.getActiveSkillPhase(),
|
|
1527
|
+
getDeepInterviewAskStage: () => session?.getDeepInterviewAskStage(),
|
|
1512
1528
|
getHindsightSessionState: () => session?.getHindsightSessionState(),
|
|
1513
1529
|
get model() {
|
|
1514
1530
|
return agent?.state.model ?? model;
|
|
@@ -1590,13 +1606,19 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1590
1606
|
// which collapses to the parent's dir for subagents (they adopt the
|
|
1591
1607
|
// parent's ArtifactManager) so one lookup hits everything.
|
|
1592
1608
|
const getArtifactsDir = () => sessionManager.getArtifactsDir();
|
|
1609
|
+
const localProtocolOptions = options.localProtocolOptions ?? {
|
|
1610
|
+
getArtifactsDir,
|
|
1611
|
+
isManagedDestination: () => sessionManager.isManagedDestination(),
|
|
1612
|
+
getManagedLegacyLocalMigrationSource: () => sessionManager.getManagedLegacyLocalMigrationSource(),
|
|
1613
|
+
getSessionId: () => sessionManager.getSessionId(),
|
|
1614
|
+
};
|
|
1593
1615
|
if (!options.parentTaskPrefix) {
|
|
1594
1616
|
setActiveSkills(skills);
|
|
1595
1617
|
setActiveRules([...rulebookRules, ...alwaysApplyRules]);
|
|
1596
1618
|
if (asyncJobManager) AsyncJobManager.setInstance(asyncJobManager);
|
|
1597
1619
|
}
|
|
1620
|
+
await initializeLocalRoot(localProtocolOptions);
|
|
1598
1621
|
if (options.localProtocolOptions) {
|
|
1599
|
-
await initializeLocalRoot(options.localProtocolOptions);
|
|
1600
1622
|
disposeLocalProtocolOverride = LocalProtocolHandler.installOverride(options.localProtocolOptions);
|
|
1601
1623
|
}
|
|
1602
1624
|
toolSession.getArtifactsDir = getArtifactsDir;
|
|
@@ -1849,9 +1871,13 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1849
1871
|
spawnedByGjc,
|
|
1850
1872
|
sdkHostModeSupported: options.sdkHostModeSupported,
|
|
1851
1873
|
ensureProviderDaemon: options.ensureNotificationProviderDaemon,
|
|
1852
|
-
|
|
1874
|
+
runBtwTurn: async (question, signal) => {
|
|
1853
1875
|
if (!session) throw new Error("Ephemeral turns are unavailable.");
|
|
1854
|
-
const { replyText } = await session.runEphemeralTurn({
|
|
1876
|
+
const { replyText } = await session.runEphemeralTurn({
|
|
1877
|
+
purpose: "btw",
|
|
1878
|
+
turn: { question, scope: session.createBtwConversationScope(btwUserPrompt) },
|
|
1879
|
+
signal,
|
|
1880
|
+
});
|
|
1855
1881
|
return { replyText };
|
|
1856
1882
|
},
|
|
1857
1883
|
});
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isModelProfileError,
|
|
3
|
+
type ModelProfileErrorCode,
|
|
4
|
+
type ModelProfileErrorDetails,
|
|
5
|
+
} from "../config/model-profile-contract";
|
|
1
6
|
export type SdkStartupPhase = "registration" | "startup";
|
|
2
7
|
|
|
3
8
|
export type SdkStartupReason = "disabled" | "ineligible" | "factory_absent" | "runner_absent" | "pending" | "failed";
|
|
@@ -6,6 +11,8 @@ export interface SdkStartupFailure {
|
|
|
6
11
|
phase: SdkStartupPhase;
|
|
7
12
|
reason: SdkStartupReason;
|
|
8
13
|
message: string;
|
|
14
|
+
code?: ModelProfileErrorCode;
|
|
15
|
+
details?: ModelProfileErrorDetails;
|
|
9
16
|
}
|
|
10
17
|
|
|
11
18
|
export type SdkStartupResult = { status: "started" } | { status: "failed"; failure: SdkStartupFailure };
|
|
@@ -134,7 +141,8 @@ export function normalizeSdkStartupFailure(
|
|
|
134
141
|
? "SDK startup did not complete before readiness cutoff."
|
|
135
142
|
: FALLBACK_MESSAGE;
|
|
136
143
|
const message = sanitizeSdkStartupMessage(error, knownSecrets);
|
|
137
|
-
|
|
144
|
+
const profileError = isModelProfileError(error) ? { code: error.code, details: error.details } : {};
|
|
145
|
+
return { phase, reason, message: message === FALLBACK_MESSAGE ? fallback : message, ...profileError };
|
|
138
146
|
}
|
|
139
147
|
|
|
140
148
|
/** Collect process-scoped credentials without exposing a raw-secret API. */
|