subharness 0.0.4 → 0.0.7
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/README.md +95 -9
- package/dist/adapters/claude-process.d.ts +3 -0
- package/dist/adapters/claude-process.js +19 -2
- package/dist/adapters/claude-process.js.map +1 -1
- package/dist/adapters/claude-result.d.ts +2 -0
- package/dist/adapters/claude-result.js +22 -0
- package/dist/adapters/claude-result.js.map +1 -0
- package/dist/adapters/claude-tools.d.ts +6 -2
- package/dist/adapters/claude-tools.js +14 -12
- package/dist/adapters/claude-tools.js.map +1 -1
- package/dist/adapters/claude-worker-client.d.ts +49 -0
- package/dist/adapters/claude-worker-client.js +359 -0
- package/dist/adapters/claude-worker-client.js.map +1 -0
- package/dist/adapters/claude-worker-process.d.ts +20 -0
- package/dist/adapters/claude-worker-process.js +76 -0
- package/dist/adapters/claude-worker-process.js.map +1 -0
- package/dist/adapters/claude-worker-protocol.d.ts +38 -0
- package/dist/adapters/claude-worker-protocol.js +2 -0
- package/dist/adapters/claude-worker-protocol.js.map +1 -0
- package/dist/adapters/claude-worker.d.ts +1 -0
- package/dist/adapters/claude-worker.js +126 -0
- package/dist/adapters/claude-worker.js.map +1 -0
- package/dist/adapters/claude.d.ts +16 -6
- package/dist/adapters/claude.js +164 -75
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/codex.js +4 -1
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/copilot-permissions.d.ts +26 -0
- package/dist/adapters/copilot-permissions.js +121 -0
- package/dist/adapters/copilot-permissions.js.map +1 -0
- package/dist/adapters/copilot-tools.d.ts +12 -0
- package/dist/adapters/copilot-tools.js +61 -0
- package/dist/adapters/copilot-tools.js.map +1 -0
- package/dist/adapters/copilot.d.ts +108 -0
- package/dist/adapters/copilot.js +819 -0
- package/dist/adapters/copilot.js.map +1 -0
- package/dist/adapters/cursor-cli-approvals.d.ts +2 -0
- package/dist/adapters/cursor-cli-approvals.js +83 -0
- package/dist/adapters/cursor-cli-approvals.js.map +1 -0
- package/dist/adapters/cursor-cli-model.d.ts +4 -0
- package/dist/adapters/cursor-cli-model.js +64 -0
- package/dist/adapters/cursor-cli-model.js.map +1 -0
- package/dist/adapters/cursor-cli-session.d.ts +32 -0
- package/dist/adapters/cursor-cli-session.js +316 -0
- package/dist/adapters/cursor-cli-session.js.map +1 -0
- package/dist/adapters/cursor-cli-tools.d.ts +20 -0
- package/dist/adapters/cursor-cli-tools.js +181 -0
- package/dist/adapters/cursor-cli-tools.js.map +1 -0
- package/dist/adapters/cursor-cli.d.ts +2 -0
- package/dist/adapters/cursor-cli.js +306 -0
- package/dist/adapters/cursor-cli.js.map +1 -0
- package/dist/adapters/cursor-model.d.ts +7 -0
- package/dist/adapters/cursor-model.js +67 -0
- package/dist/adapters/cursor-model.js.map +1 -0
- package/dist/adapters/cursor-rpc.d.ts +42 -0
- package/dist/adapters/cursor-rpc.js +271 -0
- package/dist/adapters/cursor-rpc.js.map +1 -0
- package/dist/adapters/cursor-session.d.ts +4 -0
- package/dist/adapters/cursor-session.js +327 -0
- package/dist/adapters/cursor-session.js.map +1 -0
- package/dist/adapters/cursor-startup.d.ts +16 -0
- package/dist/adapters/cursor-startup.js +74 -0
- package/dist/adapters/cursor-startup.js.map +1 -0
- package/dist/adapters/cursor-tools.d.ts +11 -0
- package/dist/adapters/cursor-tools.js +49 -0
- package/dist/adapters/cursor-tools.js.map +1 -0
- package/dist/adapters/cursor.d.ts +6 -0
- package/dist/adapters/cursor.js +17 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/fx-auth.d.ts +12 -2
- package/dist/adapters/fx-auth.js +51 -61
- package/dist/adapters/fx-auth.js.map +1 -1
- package/dist/adapters/fx-profile.d.ts +8 -0
- package/dist/adapters/fx-profile.js +101 -0
- package/dist/adapters/fx-profile.js.map +1 -0
- package/dist/adapters/fx-rpc.d.ts +2 -0
- package/dist/adapters/fx-rpc.js +30 -4
- package/dist/adapters/fx-rpc.js.map +1 -1
- package/dist/adapters/fx-status.d.ts +2 -0
- package/dist/adapters/fx-status.js +96 -0
- package/dist/adapters/fx-status.js.map +1 -0
- package/dist/adapters/fx.js +28 -12
- package/dist/adapters/fx.js.map +1 -1
- package/dist/adapters/opencode-access.d.ts +13 -0
- package/dist/adapters/opencode-access.js +76 -0
- package/dist/adapters/opencode-access.js.map +1 -0
- package/dist/adapters/opencode-config.d.ts +11 -0
- package/dist/adapters/opencode-config.js +238 -0
- package/dist/adapters/opencode-config.js.map +1 -0
- package/dist/adapters/opencode-http.d.ts +28 -0
- package/dist/adapters/opencode-http.js +297 -0
- package/dist/adapters/opencode-http.js.map +1 -0
- package/dist/adapters/opencode-tools.d.ts +19 -0
- package/dist/adapters/opencode-tools.js +127 -0
- package/dist/adapters/opencode-tools.js.map +1 -0
- package/dist/adapters/opencode.d.ts +2 -0
- package/dist/adapters/opencode.js +569 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/rpc.d.ts +3 -0
- package/dist/adapters/rpc.js +45 -4
- package/dist/adapters/rpc.js.map +1 -1
- package/dist/adapters/types.d.ts +5 -0
- package/dist/adapters/types.js.map +1 -1
- package/dist/approvals/types.d.ts +1 -1
- package/dist/approvals/types.js.map +1 -1
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.js +4 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/catalog-worker.js.map +1 -1
- package/dist/cli/dashboard-client.js +20 -31
- package/dist/cli/dashboard-client.js.map +1 -1
- package/dist/cli/dashboard-controller.d.ts +7 -0
- package/dist/cli/dashboard-controller.js +27 -0
- package/dist/cli/dashboard-controller.js.map +1 -0
- package/dist/cli/dashboard-detail-view.d.ts +1 -1
- package/dist/cli/dashboard-detail-view.js +3 -4
- package/dist/cli/dashboard-detail-view.js.map +1 -1
- package/dist/cli/dashboard-history-view.js.map +1 -1
- package/dist/cli/dashboard-input.d.ts +1 -1
- package/dist/cli/dashboard-input.js +11 -1
- package/dist/cli/dashboard-input.js.map +1 -1
- package/dist/cli/dashboard-layout.js +3 -3
- package/dist/cli/dashboard-layout.js.map +1 -1
- package/dist/cli/dashboard-renderer.js.map +1 -1
- package/dist/cli/dashboard-style.js +2 -2
- package/dist/cli/dashboard-style.js.map +1 -1
- package/dist/cli/dashboard.d.ts +2 -2
- package/dist/cli/dashboard.js +7 -32
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +30 -12
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/main.js +55 -43
- package/dist/cli/main.js.map +1 -1
- package/dist/config/access-provenance.d.ts +10 -0
- package/dist/config/access-provenance.js +31 -0
- package/dist/config/access-provenance.js.map +1 -0
- package/dist/config/access.d.ts +12 -2
- package/dist/config/access.js +125 -27
- package/dist/config/access.js.map +1 -1
- package/dist/config/loader.js +1 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/oidc.js +4 -2
- package/dist/config/oidc.js.map +1 -1
- package/dist/config/project.js +2 -1
- package/dist/config/project.js.map +1 -1
- package/dist/config/resolve-access.js +24 -10
- package/dist/config/resolve-access.js.map +1 -1
- package/dist/errors.d.ts +2 -2
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/process-diagnostics.d.ts +2 -0
- package/dist/process-diagnostics.js +11 -0
- package/dist/process-diagnostics.js.map +1 -0
- package/dist/runtime/access-errors.d.ts +4 -0
- package/dist/runtime/access-errors.js +25 -0
- package/dist/runtime/access-errors.js.map +1 -0
- package/dist/runtime/approval-registry.d.ts +9 -0
- package/dist/runtime/approval-registry.js +144 -5
- package/dist/runtime/approval-registry.js.map +1 -1
- package/dist/runtime/capture.d.ts +22 -0
- package/dist/runtime/capture.js +320 -0
- package/dist/runtime/capture.js.map +1 -0
- package/dist/runtime/catalog.d.ts +39 -0
- package/dist/runtime/catalog.js +84 -0
- package/dist/runtime/catalog.js.map +1 -0
- package/dist/runtime/client.d.ts +2 -1
- package/dist/runtime/client.js +74 -47
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/coordinator.d.ts +44 -7
- package/dist/runtime/coordinator.js +265 -31
- package/dist/runtime/coordinator.js.map +1 -1
- package/dist/runtime/daemon.js +12 -6
- package/dist/runtime/daemon.js.map +1 -1
- package/dist/runtime/dashboard-sanitize.d.ts +2 -0
- package/dist/runtime/dashboard-sanitize.js +7 -0
- package/dist/runtime/dashboard-sanitize.js.map +1 -0
- package/dist/runtime/dashboard-workspace.js +5 -1
- package/dist/runtime/dashboard-workspace.js.map +1 -1
- package/dist/runtime/dashboard.d.ts +1 -1
- package/dist/runtime/dashboard.js +2 -3
- package/dist/runtime/dashboard.js.map +1 -1
- package/dist/runtime/definition.d.ts +6 -1
- package/dist/runtime/definition.js +42 -2
- package/dist/runtime/definition.js.map +1 -1
- package/dist/runtime/native-owner.js +7 -1
- package/dist/runtime/native-owner.js.map +1 -1
- package/dist/runtime/pagination.d.ts +9 -0
- package/dist/runtime/pagination.js +36 -0
- package/dist/runtime/pagination.js.map +1 -0
- package/dist/runtime/sdk-observation.d.ts +8 -0
- package/dist/runtime/sdk-observation.js +75 -0
- package/dist/runtime/sdk-observation.js.map +1 -0
- package/dist/runtime/sdk-projection.d.ts +8 -0
- package/dist/runtime/sdk-projection.js +19 -0
- package/dist/runtime/sdk-projection.js.map +1 -0
- package/dist/runtime/sdk-service.d.ts +11 -0
- package/dist/runtime/sdk-service.js +109 -0
- package/dist/runtime/sdk-service.js.map +1 -0
- package/dist/runtime/select-native.d.ts +4 -1
- package/dist/runtime/select-native.js +28 -13
- package/dist/runtime/select-native.js.map +1 -1
- package/dist/runtime/service.d.ts +11 -1
- package/dist/runtime/service.js +178 -3
- package/dist/runtime/service.js.map +1 -1
- package/dist/runtime/session-launcher.js +1 -1
- package/dist/runtime/session-launcher.js.map +1 -1
- package/dist/runtime/snapshots.d.ts +103 -0
- package/dist/runtime/snapshots.js +124 -0
- package/dist/runtime/snapshots.js.map +1 -0
- package/dist/runtime/state.d.ts +26 -0
- package/dist/runtime/state.js +86 -17
- package/dist/runtime/state.js.map +1 -1
- package/dist/runtime/task-data.d.ts +38 -0
- package/dist/runtime/task-data.js +2 -0
- package/dist/runtime/task-data.js.map +1 -0
- package/dist/runtime/transport.d.ts +13 -0
- package/dist/runtime/transport.js +166 -0
- package/dist/runtime/transport.js.map +1 -0
- package/dist/runtime/types.d.ts +28 -9
- package/dist/runtime/types.js.map +1 -1
- package/dist/runtime/worker-client.js +40 -13
- package/dist/runtime/worker-client.js.map +1 -1
- package/dist/runtime/worker-server.js +105 -24
- package/dist/runtime/worker-server.js.map +1 -1
- package/dist/sdk/connected-types.d.ts +42 -0
- package/dist/sdk/connected-types.js +2 -0
- package/dist/sdk/connected-types.js.map +1 -0
- package/dist/sdk/connected.d.ts +3 -0
- package/dist/sdk/connected.js +232 -0
- package/dist/sdk/connected.js.map +1 -0
- package/dist/sdk/definitions.d.ts +4 -1
- package/dist/sdk/definitions.js +16 -2
- package/dist/sdk/definitions.js.map +1 -1
- package/dist/sdk/execution-definition.d.ts +3 -0
- package/dist/sdk/execution-definition.js +59 -0
- package/dist/sdk/execution-definition.js.map +1 -0
- package/dist/sdk/execution-driver.d.ts +6 -0
- package/dist/sdk/execution-driver.js +86 -0
- package/dist/sdk/execution-driver.js.map +1 -0
- package/dist/sdk/execution-observation.d.ts +3 -0
- package/dist/sdk/execution-observation.js +35 -0
- package/dist/sdk/execution-observation.js.map +1 -0
- package/dist/sdk/execution-options.d.ts +17 -0
- package/dist/sdk/execution-options.js +115 -0
- package/dist/sdk/execution-options.js.map +1 -0
- package/dist/sdk/execution-types.d.ts +72 -0
- package/dist/sdk/execution-types.js +2 -0
- package/dist/sdk/execution-types.js.map +1 -0
- package/dist/sdk/execution.d.ts +3 -0
- package/dist/sdk/execution.js +3 -0
- package/dist/sdk/execution.js.map +1 -0
- package/dist/sdk/hosted-error.d.ts +3 -0
- package/dist/sdk/hosted-error.js +14 -0
- package/dist/sdk/hosted-error.js.map +1 -0
- package/dist/sdk/hosted.d.ts +23 -0
- package/dist/sdk/hosted.js +204 -0
- package/dist/sdk/hosted.js.map +1 -0
- package/dist/sdk/permission-validation.js +10 -1
- package/dist/sdk/permission-validation.js.map +1 -1
- package/dist/sdk/runner.d.ts +5 -0
- package/dist/sdk/runner.js +107 -0
- package/dist/sdk/runner.js.map +1 -0
- package/dist/sdk/tools.js +4 -1
- package/dist/sdk/tools.js.map +1 -1
- package/dist/sdk/types.d.ts +29 -1
- package/dist/sdk/types.js.map +1 -1
- package/package.json +6 -3
- package/sdk/access-config.md +60 -4
- package/sdk/adapter-contract.md +13 -3
- package/sdk/additional-harnesses.md +43 -0
- package/sdk/agent-skill.md +2 -2
- package/sdk/agent.md +6 -4
- package/sdk/approvals.md +5 -1
- package/sdk/authentication.md +1 -1
- package/sdk/cli/dashboard-design.md +6 -0
- package/sdk/cli/index.md +9 -6
- package/sdk/cli/output.md +3 -1
- package/sdk/completion-notifications.md +2 -0
- package/sdk/config.md +1 -1
- package/sdk/copilot.md +53 -0
- package/sdk/cursor.md +68 -0
- package/sdk/diagnostics.md +29 -0
- package/sdk/distribution.md +5 -3
- package/sdk/evals.md +1 -1
- package/sdk/examples/chat-tool.ts +126 -0
- package/sdk/execution.md +743 -0
- package/sdk/fx.md +50 -5
- package/sdk/harnesses.md +13 -13
- package/sdk/index.md +45 -20
- package/sdk/message-delivery.md +2 -0
- package/sdk/opencode.md +57 -0
- package/sdk/permissions.md +6 -2
- package/sdk/plugins/sub-agents.md +4 -2
- package/sdk/project-team.md +25 -1
- package/sdk/sessions.md +2 -0
- package/sdk/tools.md +4 -2
- package/sdk/v1-runtime.md +8 -6
- package/dist/cli/catalog.d.ts +0 -26
- package/dist/cli/catalog.js +0 -41
- package/dist/cli/catalog.js.map +0 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { stat } from "node:fs/promises";
|
|
2
|
+
import { isAbsolute } from "node:path";
|
|
3
|
+
import { parseAccess } from "../config/access.js";
|
|
4
|
+
import { AgentError } from "../errors.js";
|
|
5
|
+
const inheritedExecutionContext = ["AGENT_STATE_DIR", "AGENT_PARENT_TOKEN", "AGENT_CLI_PATH"];
|
|
6
|
+
function record(value) {
|
|
7
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
8
|
+
&& [Object.prototype, null].includes(Object.getPrototypeOf(value));
|
|
9
|
+
}
|
|
10
|
+
function invalid(message) {
|
|
11
|
+
throw new AgentError("INVALID_ARGUMENT", message);
|
|
12
|
+
}
|
|
13
|
+
function exactObject(value, fields, label) {
|
|
14
|
+
if (!record(value))
|
|
15
|
+
invalid(`${label} must be an object.`);
|
|
16
|
+
if (Reflect.ownKeys(value).some(key => typeof key !== "string" || !fields.includes(key))) {
|
|
17
|
+
invalid(`${label} contains an unknown field.`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function runnerConfiguration(options) {
|
|
21
|
+
if (options !== undefined)
|
|
22
|
+
exactObject(options, ["env", "access"], "Runner options");
|
|
23
|
+
const suppliedEnvironment = options?.env;
|
|
24
|
+
if (suppliedEnvironment !== undefined && ((typeof suppliedEnvironment !== "object" || suppliedEnvironment === null
|
|
25
|
+
|| Array.isArray(suppliedEnvironment))
|
|
26
|
+
|| Reflect.ownKeys(suppliedEnvironment).some(key => typeof key !== "string"))) {
|
|
27
|
+
invalid("Runner environment must be an object.");
|
|
28
|
+
}
|
|
29
|
+
const source = (suppliedEnvironment ?? process.env);
|
|
30
|
+
// Runner environments are exact replacements, so framework-required ambient keys cannot be synthesized here.
|
|
31
|
+
const env = {};
|
|
32
|
+
for (const key of Object.keys(source)) {
|
|
33
|
+
const value = source[key];
|
|
34
|
+
if (value !== undefined && typeof value !== "string")
|
|
35
|
+
invalid("Runner environment values must be strings or undefined.");
|
|
36
|
+
env[key] = value;
|
|
37
|
+
}
|
|
38
|
+
for (const key of inheritedExecutionContext)
|
|
39
|
+
delete env[key];
|
|
40
|
+
const selectedAccess = options?.access;
|
|
41
|
+
const access = selectedAccess === undefined
|
|
42
|
+
? {}
|
|
43
|
+
: parseRunnerAccess(selectedAccess);
|
|
44
|
+
return { env, access };
|
|
45
|
+
}
|
|
46
|
+
function parseRunnerAccess(access) {
|
|
47
|
+
try {
|
|
48
|
+
return parseAccess({ access: cloneAccess(access) });
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const prefix = "Personal access settings are invalid at ";
|
|
52
|
+
if (error instanceof AgentError && error.code === "INVALID_CONFIG" && error.message.startsWith(prefix)) {
|
|
53
|
+
throw new AgentError(error.code, `Runner access settings are invalid at ${error.message.slice(prefix.length)}`);
|
|
54
|
+
}
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function cloneAccess(access) {
|
|
59
|
+
if (!record(access)) {
|
|
60
|
+
throw new AgentError("INVALID_CONFIG", "Runner access settings are invalid at access: Value must be an object.");
|
|
61
|
+
}
|
|
62
|
+
return Object.fromEntries(Object.entries(access).map(([kind, connections]) => [
|
|
63
|
+
kind,
|
|
64
|
+
Array.isArray(connections) ? connections.map(connection => record(connection) ? { ...connection } : connection) : connections,
|
|
65
|
+
]));
|
|
66
|
+
}
|
|
67
|
+
export function validatePrompt(prompt) {
|
|
68
|
+
if (typeof prompt !== "string" || !prompt.trim() || Buffer.byteLength(prompt, "utf8") > 1024 * 1024) {
|
|
69
|
+
invalid("Prompt must contain text and cannot exceed 1 MiB.");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export async function validateCwd(cwd) {
|
|
73
|
+
if (typeof cwd !== "string" || !isAbsolute(cwd))
|
|
74
|
+
invalid("Execution cwd must be an existing absolute directory.");
|
|
75
|
+
try {
|
|
76
|
+
if (!(await stat(cwd)).isDirectory())
|
|
77
|
+
throw new Error();
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
invalid("Execution cwd must be an existing absolute directory.");
|
|
81
|
+
}
|
|
82
|
+
return cwd;
|
|
83
|
+
}
|
|
84
|
+
export function runCwd(options) {
|
|
85
|
+
exactObject(options, ["cwd"], "Run options");
|
|
86
|
+
return options.cwd;
|
|
87
|
+
}
|
|
88
|
+
export function delivery(options) {
|
|
89
|
+
if (options === undefined)
|
|
90
|
+
return "queue";
|
|
91
|
+
exactObject(options, ["delivery"], "Send options");
|
|
92
|
+
const selected = options.delivery ?? "queue";
|
|
93
|
+
if (selected !== "queue" && selected !== "steer" && selected !== "interrupt")
|
|
94
|
+
invalid("Unknown delivery mode.");
|
|
95
|
+
return selected;
|
|
96
|
+
}
|
|
97
|
+
export function observeOptions(options) {
|
|
98
|
+
if (options === undefined)
|
|
99
|
+
return {};
|
|
100
|
+
exactObject(options, ["after", "signal"], "Observe options");
|
|
101
|
+
if (options.after !== undefined && typeof options.after !== "string")
|
|
102
|
+
invalid("Observation cursor must be a string.");
|
|
103
|
+
if (options.signal !== undefined && !(options.signal instanceof AbortSignal))
|
|
104
|
+
invalid("Observation signal must be an AbortSignal.");
|
|
105
|
+
return options;
|
|
106
|
+
}
|
|
107
|
+
export function watchOptions(options) {
|
|
108
|
+
if (options === undefined)
|
|
109
|
+
return {};
|
|
110
|
+
exactObject(options, ["signal"], "Watch options");
|
|
111
|
+
if (options.signal !== undefined && !(options.signal instanceof AbortSignal))
|
|
112
|
+
invalid("Watch signal must be an AbortSignal.");
|
|
113
|
+
return options;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=execution-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-options.js","sourceRoot":"","sources":["../../src/sdk/execution-options.ts"],"names":[],"mappings":"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","sourcesContent":["import { stat } from \"node:fs/promises\";\nimport { isAbsolute } from \"node:path\";\nimport { parseAccess, type AccessConfig } from \"../config/access.js\";\nimport { AgentError } from \"../errors.js\";\nimport type { AccessSelection, Delivery, RunnerOptions } from \"./execution-types.js\";\n\nconst inheritedExecutionContext = [\"AGENT_STATE_DIR\", \"AGENT_PARENT_TOKEN\", \"AGENT_CLI_PATH\"] as const;\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n && [Object.prototype, null].includes(Object.getPrototypeOf(value));\n}\n\nfunction invalid(message: string): never {\n throw new AgentError(\"INVALID_ARGUMENT\", message);\n}\n\nfunction exactObject(value: unknown, fields: readonly string[], label: string): asserts value is Record<string, unknown> {\n if (!record(value)) invalid(`${label} must be an object.`);\n if (Reflect.ownKeys(value).some(key => typeof key !== \"string\" || !fields.includes(key))) {\n invalid(`${label} contains an unknown field.`);\n }\n}\n\nexport function runnerConfiguration(options: RunnerOptions | undefined): { env: NodeJS.ProcessEnv; access: AccessConfig } {\n if (options !== undefined) exactObject(options, [\"env\", \"access\"], \"Runner options\");\n const suppliedEnvironment = options?.env;\n if (suppliedEnvironment !== undefined && ((typeof suppliedEnvironment !== \"object\" || suppliedEnvironment === null\n || Array.isArray(suppliedEnvironment))\n || Reflect.ownKeys(suppliedEnvironment).some(key => typeof key !== \"string\"))) {\n invalid(\"Runner environment must be an object.\");\n }\n const source = (suppliedEnvironment ?? process.env) as Readonly<Record<string, string | undefined>>;\n // Runner environments are exact replacements, so framework-required ambient keys cannot be synthesized here.\n const env = {} as NodeJS.ProcessEnv;\n for (const key of Object.keys(source)) {\n const value = source[key];\n if (value !== undefined && typeof value !== \"string\") invalid(\"Runner environment values must be strings or undefined.\");\n env[key] = value;\n }\n for (const key of inheritedExecutionContext) delete env[key];\n const selectedAccess = options?.access;\n const access = selectedAccess === undefined\n ? {}\n : parseRunnerAccess(selectedAccess as AccessSelection);\n return { env, access };\n}\n\nfunction parseRunnerAccess(access: AccessSelection): AccessConfig {\n try {\n return parseAccess({ access: cloneAccess(access) });\n } catch (error) {\n const prefix = \"Personal access settings are invalid at \";\n if (error instanceof AgentError && error.code === \"INVALID_CONFIG\" && error.message.startsWith(prefix)) {\n throw new AgentError(error.code, `Runner access settings are invalid at ${error.message.slice(prefix.length)}`);\n }\n throw error;\n }\n}\n\nfunction cloneAccess(access: AccessSelection): AccessConfig[\"access\"] {\n if (!record(access)) {\n throw new AgentError(\"INVALID_CONFIG\", \"Runner access settings are invalid at access: Value must be an object.\");\n }\n return Object.fromEntries(Object.entries(access).map(([kind, connections]) => [\n kind,\n Array.isArray(connections) ? connections.map(connection => record(connection) ? { ...connection } : connection) : connections,\n ])) as AccessConfig[\"access\"];\n}\n\nexport function validatePrompt(prompt: unknown): asserts prompt is string {\n if (typeof prompt !== \"string\" || !prompt.trim() || Buffer.byteLength(prompt, \"utf8\") > 1024 * 1024) {\n invalid(\"Prompt must contain text and cannot exceed 1 MiB.\");\n }\n}\n\nexport async function validateCwd(cwd: unknown): Promise<string> {\n if (typeof cwd !== \"string\" || !isAbsolute(cwd)) invalid(\"Execution cwd must be an existing absolute directory.\");\n try {\n if (!(await stat(cwd)).isDirectory()) throw new Error();\n } catch {\n invalid(\"Execution cwd must be an existing absolute directory.\");\n }\n return cwd;\n}\n\nexport function runCwd(options: unknown): unknown {\n exactObject(options, [\"cwd\"], \"Run options\");\n return options.cwd;\n}\n\nexport function delivery(options: unknown): Delivery {\n if (options === undefined) return \"queue\";\n exactObject(options, [\"delivery\"], \"Send options\");\n const selected = options.delivery ?? \"queue\";\n if (selected !== \"queue\" && selected !== \"steer\" && selected !== \"interrupt\") invalid(\"Unknown delivery mode.\");\n return selected;\n}\n\nexport function observeOptions(options: unknown): { after?: string; signal?: AbortSignal } {\n if (options === undefined) return {};\n exactObject(options, [\"after\", \"signal\"], \"Observe options\");\n if (options.after !== undefined && typeof options.after !== \"string\") invalid(\"Observation cursor must be a string.\");\n if (options.signal !== undefined && !(options.signal instanceof AbortSignal)) invalid(\"Observation signal must be an AbortSignal.\");\n return options as { after?: string; signal?: AbortSignal };\n}\n\nexport function watchOptions(options: unknown): { signal?: AbortSignal } {\n if (options === undefined) return {};\n exactObject(options, [\"signal\"], \"Watch options\");\n if (options.signal !== undefined && !(options.signal instanceof AbortSignal)) invalid(\"Watch signal must be an AbortSignal.\");\n return options as { signal?: AbortSignal };\n}\n"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { AgentDefinition, HarnessKind } from './types.js';
|
|
2
|
+
import type { CompleteResponse, Page, PageOptions, SdkSessionSnapshot as SessionSnapshot, SdkSessionSummary as SessionSummary, SdkTaskDetails as TaskDetails, SdkTaskSnapshot as TaskSnapshot, SdkTaskSummary as TaskSummary, TaskResult, WorkspaceInfo } from '../runtime/snapshots.js';
|
|
3
|
+
import type { ApprovalAction, ApprovalGrant, ApprovalResponse, ApprovalScope, SdkApprovalRequest as ApprovalRequest, TaskState } from '../runtime/task-data.js';
|
|
4
|
+
export interface RunnerOptions {
|
|
5
|
+
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
6
|
+
readonly access?: AccessSelection;
|
|
7
|
+
}
|
|
8
|
+
export type AccessSelection = Readonly<Partial<Record<HarnessKind, readonly AccessConnection[]>>>;
|
|
9
|
+
export type AccessConnection = {
|
|
10
|
+
readonly type: 'subscription';
|
|
11
|
+
readonly provider?: string;
|
|
12
|
+
} | {
|
|
13
|
+
readonly type: 'api-key';
|
|
14
|
+
readonly provider?: string;
|
|
15
|
+
readonly env?: string;
|
|
16
|
+
readonly envFile?: string;
|
|
17
|
+
readonly baseUrl?: string;
|
|
18
|
+
readonly wireApi?: 'completions' | 'responses';
|
|
19
|
+
readonly apiVersion?: string;
|
|
20
|
+
readonly wireModel?: string;
|
|
21
|
+
} | {
|
|
22
|
+
readonly type: 'vercel-api-key';
|
|
23
|
+
readonly env?: string;
|
|
24
|
+
readonly envFile?: string;
|
|
25
|
+
} | {
|
|
26
|
+
readonly type: 'vercel-oidc';
|
|
27
|
+
readonly env?: string;
|
|
28
|
+
readonly envFile?: string;
|
|
29
|
+
readonly project?: string;
|
|
30
|
+
};
|
|
31
|
+
export type Delivery = 'queue' | 'steer' | 'interrupt';
|
|
32
|
+
export interface Runner {
|
|
33
|
+
createSession(definition: AgentDefinition, options: {
|
|
34
|
+
readonly cwd: string;
|
|
35
|
+
}): Promise<SessionHandle>;
|
|
36
|
+
session(id: string): SessionHandle;
|
|
37
|
+
task(id: string): TaskHandle;
|
|
38
|
+
respond(requestId: string, response: ApprovalResponse): Promise<void>;
|
|
39
|
+
close(): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
export interface SessionHandle {
|
|
42
|
+
readonly id: string;
|
|
43
|
+
prompt(text: string, options?: {
|
|
44
|
+
readonly delivery?: Delivery;
|
|
45
|
+
}): Promise<PromptReceipt>;
|
|
46
|
+
snapshot(): Promise<SessionSnapshot>;
|
|
47
|
+
close(): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
export interface PromptReceipt {
|
|
50
|
+
readonly task: TaskHandle;
|
|
51
|
+
readonly requestedDelivery: Delivery;
|
|
52
|
+
readonly effectiveDelivery: Delivery;
|
|
53
|
+
readonly paused?: true;
|
|
54
|
+
readonly blockedByTaskId?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface TaskHandle {
|
|
57
|
+
readonly id: string;
|
|
58
|
+
readonly sessionId: string;
|
|
59
|
+
readonly result: Promise<TaskResult>;
|
|
60
|
+
snapshot(): Promise<TaskSnapshot>;
|
|
61
|
+
inspect(): Promise<TaskDetails>;
|
|
62
|
+
watch(options?: {
|
|
63
|
+
readonly signal?: AbortSignal;
|
|
64
|
+
}): AsyncIterable<TaskSnapshot>;
|
|
65
|
+
responses(options?: {
|
|
66
|
+
readonly after?: string;
|
|
67
|
+
readonly signal?: AbortSignal;
|
|
68
|
+
}): AsyncIterable<CompleteResponse>;
|
|
69
|
+
cancel(): Promise<TaskSnapshot>;
|
|
70
|
+
}
|
|
71
|
+
export type TerminalState = 'completed' | 'failed' | 'cancelled' | 'interrupted';
|
|
72
|
+
export type { ApprovalAction, ApprovalGrant, ApprovalRequest, ApprovalResponse, ApprovalScope, CompleteResponse, Page, PageOptions, SessionSnapshot, SessionSummary, TaskDetails, TaskResult, TaskSnapshot, TaskState, TaskSummary, WorkspaceInfo };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-types.js","sourceRoot":"","sources":["../../src/sdk/execution-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentDefinition, HarnessKind } from './types.js';\nimport type {\n CompleteResponse, Page, PageOptions, SdkSessionSnapshot as SessionSnapshot,\n SdkSessionSummary as SessionSummary, SdkTaskDetails as TaskDetails,\n SdkTaskSnapshot as TaskSnapshot, SdkTaskSummary as TaskSummary, TaskResult, WorkspaceInfo,\n} from '../runtime/snapshots.js';\nimport type {\n ApprovalAction, ApprovalGrant, ApprovalResponse, ApprovalScope, SdkApprovalRequest as ApprovalRequest, TaskState,\n} from '../runtime/task-data.js';\n\nexport interface RunnerOptions {\n readonly env?: Readonly<Record<string, string | undefined>>;\n readonly access?: AccessSelection;\n}\nexport type AccessSelection = Readonly<Partial<Record<HarnessKind, readonly AccessConnection[]>>>;\nexport type AccessConnection =\n | { readonly type:'subscription'; readonly provider?:string }\n | { readonly type:'api-key'; readonly provider?:string; readonly env?:string; readonly envFile?:string;\n readonly baseUrl?:string; readonly wireApi?:'completions'|'responses'; readonly apiVersion?:string; readonly wireModel?:string }\n | { readonly type:'vercel-api-key'; readonly env?:string; readonly envFile?:string }\n | { readonly type:'vercel-oidc'; readonly env?:string; readonly envFile?:string; readonly project?:string };\n\nexport type Delivery = 'queue' | 'steer' | 'interrupt';\nexport interface Runner {\n createSession(definition: AgentDefinition, options: {readonly cwd:string}): Promise<SessionHandle>;\n session(id:string): SessionHandle;\n task(id:string): TaskHandle;\n respond(requestId:string,response:ApprovalResponse): Promise<void>;\n close(): Promise<void>;\n}\nexport interface SessionHandle {\n readonly id:string;\n prompt(text:string,options?:{readonly delivery?:Delivery}): Promise<PromptReceipt>;\n snapshot(): Promise<SessionSnapshot>;\n close(): Promise<void>;\n}\nexport interface PromptReceipt {\n readonly task:TaskHandle;\n readonly requestedDelivery:Delivery;\n readonly effectiveDelivery:Delivery;\n readonly paused?:true;\n readonly blockedByTaskId?:string;\n}\nexport interface TaskHandle {\n readonly id:string;\n readonly sessionId:string;\n readonly result:Promise<TaskResult>;\n snapshot():Promise<TaskSnapshot>;\n inspect():Promise<TaskDetails>;\n watch(options?:{readonly signal?:AbortSignal}):AsyncIterable<TaskSnapshot>;\n responses(options?:{readonly after?:string;readonly signal?:AbortSignal}):AsyncIterable<CompleteResponse>;\n cancel():Promise<TaskSnapshot>;\n}\n\nexport type TerminalState='completed'|'failed'|'cancelled'|'interrupted';\nexport type { ApprovalAction, ApprovalGrant, ApprovalRequest, ApprovalResponse, ApprovalScope, CompleteResponse, Page, PageOptions,\n SessionSnapshot, SessionSummary, TaskDetails, TaskResult, TaskSnapshot, TaskState, TaskSummary, WorkspaceInfo };\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Runner, RunnerOptions } from './execution-types.js';
|
|
2
|
+
export declare function createRunner(options?: RunnerOptions): Runner;
|
|
3
|
+
export type { AccessConnection, AccessSelection, ApprovalAction, ApprovalGrant, ApprovalRequest, ApprovalResponse, ApprovalScope, CompleteResponse, Delivery, Page, PageOptions, PromptReceipt, Runner, RunnerOptions, SessionHandle, SessionSnapshot, SessionSummary, TaskDetails, TaskHandle, TaskResult, TaskSnapshot, TaskState, TaskSummary, TerminalState, WorkspaceInfo, } from './execution-types.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/sdk/execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAGtE,MAAM,UAAU,YAAY,CAAC,OAAsB,IAAW,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC","sourcesContent":["import { createRunner as createApplicationRunner } from './runner.js';\nimport type { Runner, RunnerOptions } from './execution-types.js';\n\nexport function createRunner(options?:RunnerOptions):Runner { return createApplicationRunner(options); }\nexport type { AccessConnection, AccessSelection, ApprovalAction, ApprovalGrant, ApprovalRequest, ApprovalResponse, ApprovalScope,\n CompleteResponse, Delivery, Page, PageOptions, PromptReceipt, Runner, RunnerOptions, SessionHandle, SessionSnapshot,\n SessionSummary, TaskDetails, TaskHandle, TaskResult, TaskSnapshot, TaskState, TaskSummary, TerminalState,\n WorkspaceInfo,\n} from './execution-types.js';\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AgentError } from "../errors.js";
|
|
2
|
+
const registered = new WeakSet();
|
|
3
|
+
const safeCode = /^[A-Z][A-Z0-9_]*$/u;
|
|
4
|
+
export function markHostedError(error) {
|
|
5
|
+
if (!(error instanceof AgentError) || !safeCode.test(error.code))
|
|
6
|
+
return error;
|
|
7
|
+
const failure = new AgentError(error.code, `Hosted tool failed (${error.code}).`);
|
|
8
|
+
registered.add(failure);
|
|
9
|
+
return failure;
|
|
10
|
+
}
|
|
11
|
+
export function isHostedError(error) {
|
|
12
|
+
return error instanceof AgentError && registered.has(error);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=hosted-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-error.js","sourceRoot":"","sources":["../../src/sdk/hosted-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,UAAU,GAAG,IAAI,OAAO,EAAc,CAAC;AAC7C,MAAM,QAAQ,GAAG,oBAAoB,CAAC;AAEtC,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC,CAAC,KAAK,YAAY,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/E,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,uBAAuB,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;IAClF,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,KAAK,YAAY,UAAU,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import { AgentError } from \"../errors.js\";\n\nconst registered = new WeakSet<AgentError>();\nconst safeCode = /^[A-Z][A-Z0-9_]*$/u;\n\nexport function markHostedError(error: unknown): unknown {\n if (!(error instanceof AgentError) || !safeCode.test(error.code)) return error;\n const failure = new AgentError(error.code, `Hosted tool failed (${error.code}).`);\n registered.add(failure);\n return failure;\n}\n\nexport function isHostedError(error: unknown): error is AgentError {\n return error instanceof AgentError && registered.has(error);\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ExecutionDefinition } from "../adapters/types.js";
|
|
2
|
+
import type { Coordinator } from "../runtime/coordinator.js";
|
|
3
|
+
import type { DriverInput } from "../runtime/types.js";
|
|
4
|
+
import type { AgentDefinition } from "./types.js";
|
|
5
|
+
export declare class HostedDelegation {
|
|
6
|
+
private readonly coordinator;
|
|
7
|
+
private readonly input;
|
|
8
|
+
private readonly definition;
|
|
9
|
+
private turn?;
|
|
10
|
+
constructor(coordinator: Coordinator, input: DriverInput, definition: AgentDefinition);
|
|
11
|
+
prepare(): ExecutionDefinition;
|
|
12
|
+
beginTurn(): void;
|
|
13
|
+
finishTurn(): Promise<void>;
|
|
14
|
+
stopManagedWaits(): void;
|
|
15
|
+
drain(): Promise<void>;
|
|
16
|
+
private nativeDefinition;
|
|
17
|
+
private tools;
|
|
18
|
+
private invoke;
|
|
19
|
+
private current;
|
|
20
|
+
private assertCurrent;
|
|
21
|
+
private stopAdmission;
|
|
22
|
+
private isSelfOrAncestor;
|
|
23
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { AgentError } from "../errors.js";
|
|
3
|
+
import { markHostedError } from "./hosted-error.js";
|
|
4
|
+
import { observeTask } from "./execution-observation.js";
|
|
5
|
+
import { delivery, validateCwd, validatePrompt } from "./execution-options.js";
|
|
6
|
+
const prompt = z.string();
|
|
7
|
+
const deliverySchema = z.enum(["queue", "steer", "interrupt"]);
|
|
8
|
+
const approvalValue = z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]);
|
|
9
|
+
const approvalContent = z.record(z.string(), approvalValue);
|
|
10
|
+
export class HostedDelegation {
|
|
11
|
+
coordinator;
|
|
12
|
+
input;
|
|
13
|
+
definition;
|
|
14
|
+
turn;
|
|
15
|
+
constructor(coordinator, input, definition) {
|
|
16
|
+
this.coordinator = coordinator;
|
|
17
|
+
this.input = input;
|
|
18
|
+
this.definition = definition;
|
|
19
|
+
}
|
|
20
|
+
prepare() {
|
|
21
|
+
if (!Object.keys(this.definition.subagents ?? {}).length)
|
|
22
|
+
return this.nativeDefinition({});
|
|
23
|
+
return this.nativeDefinition(this.tools());
|
|
24
|
+
}
|
|
25
|
+
beginTurn() {
|
|
26
|
+
if (this.turn?.accepting)
|
|
27
|
+
throw new AgentError("SESSION_BUSY", "A hosted turn is already active.");
|
|
28
|
+
const { taskId } = this.coordinator.parentContext(this.input.token);
|
|
29
|
+
this.turn = { taskId, accepting: true, waits: new Set(), callbacks: new Set() };
|
|
30
|
+
}
|
|
31
|
+
async finishTurn() {
|
|
32
|
+
const turn = this.turn;
|
|
33
|
+
if (!turn)
|
|
34
|
+
return;
|
|
35
|
+
this.stopAdmission(turn);
|
|
36
|
+
await Promise.allSettled([...turn.callbacks]);
|
|
37
|
+
if (this.turn === turn)
|
|
38
|
+
this.turn = undefined;
|
|
39
|
+
}
|
|
40
|
+
stopManagedWaits() {
|
|
41
|
+
if (this.turn)
|
|
42
|
+
this.stopAdmission(this.turn);
|
|
43
|
+
}
|
|
44
|
+
async drain() {
|
|
45
|
+
if (this.turn)
|
|
46
|
+
await Promise.allSettled([...this.turn.callbacks]);
|
|
47
|
+
}
|
|
48
|
+
nativeDefinition(hosted) {
|
|
49
|
+
return {
|
|
50
|
+
name: this.definition.name,
|
|
51
|
+
description: this.definition.description,
|
|
52
|
+
instructions: this.definition.instructions,
|
|
53
|
+
harness: this.definition.harness,
|
|
54
|
+
tools: { ...(this.definition.tools ?? {}), ...hosted },
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
tools() {
|
|
58
|
+
const children = this.definition.subagents ?? {};
|
|
59
|
+
const childKeys = Object.keys(children);
|
|
60
|
+
const childCatalog = Object.entries(children).map(([key, child]) => ({
|
|
61
|
+
key,
|
|
62
|
+
name: child.name,
|
|
63
|
+
description: child.description,
|
|
64
|
+
}));
|
|
65
|
+
return {
|
|
66
|
+
agent_run: {
|
|
67
|
+
description: `Start one directly declared child agent and return its admitted task and session. Available direct children: ${JSON.stringify(childCatalog)}`,
|
|
68
|
+
inputSchema: z.object({ agent: z.enum(childKeys), prompt, cwd: z.string().optional() }).strict(),
|
|
69
|
+
execute: input => this.invoke(async (binding) => {
|
|
70
|
+
validatePrompt(input.prompt);
|
|
71
|
+
const children = this.definition.subagents;
|
|
72
|
+
const child = children && Object.hasOwn(children, input.agent) ? children[input.agent] : undefined;
|
|
73
|
+
if (!child)
|
|
74
|
+
throw new AgentError("INVALID_PARENT", "This subagent is not available in the active parent context.");
|
|
75
|
+
const cwd = await validateCwd(input.cwd ?? this.input.cwd);
|
|
76
|
+
this.assertCurrent(binding);
|
|
77
|
+
const receipt = this.coordinator.run({
|
|
78
|
+
reference: { kind: "inline", definition: child },
|
|
79
|
+
cwd,
|
|
80
|
+
env: this.input.env,
|
|
81
|
+
prompt: input.prompt,
|
|
82
|
+
parentToken: this.input.token,
|
|
83
|
+
});
|
|
84
|
+
return { taskId: receipt.taskId, sessionId: receipt.sessionId, state: receipt.state };
|
|
85
|
+
}),
|
|
86
|
+
},
|
|
87
|
+
agent_send: {
|
|
88
|
+
description: "Send a follow-up to an existing hosted child session.",
|
|
89
|
+
inputSchema: z.object({ sessionId: z.string(), prompt, delivery: deliverySchema.optional() }).strict(),
|
|
90
|
+
execute: input => this.invoke(async (binding) => {
|
|
91
|
+
validatePrompt(input.prompt);
|
|
92
|
+
this.assertCurrent(binding);
|
|
93
|
+
const requestedDelivery = delivery(input.delivery === undefined ? undefined : { delivery: input.delivery });
|
|
94
|
+
const receipt = await this.coordinator.send(input.sessionId, input.prompt, requestedDelivery, this.input.token);
|
|
95
|
+
return {
|
|
96
|
+
taskId: receipt.taskId,
|
|
97
|
+
sessionId: receipt.sessionId,
|
|
98
|
+
requestedDelivery,
|
|
99
|
+
effectiveDelivery: receipt.delivery ?? requestedDelivery,
|
|
100
|
+
};
|
|
101
|
+
}),
|
|
102
|
+
},
|
|
103
|
+
agent_wait: {
|
|
104
|
+
description: "Wait for the next complete response, approval request, or terminal outcome of a hosted task.",
|
|
105
|
+
inputSchema: z.object({ taskId: z.string(), after: z.string().optional() }).strict(),
|
|
106
|
+
execute: input => this.invoke(async (binding) => {
|
|
107
|
+
this.assertCurrent(binding);
|
|
108
|
+
if (this.isSelfOrAncestor(input.taskId, binding.taskId)) {
|
|
109
|
+
throw new AgentError("INVALID_PARENT", "A hosted callback cannot wait for its own or an ancestor task.");
|
|
110
|
+
}
|
|
111
|
+
const controller = new AbortController();
|
|
112
|
+
binding.waits.add(controller);
|
|
113
|
+
try {
|
|
114
|
+
return await observeTask(this.coordinator, input.taskId, input.after, this.input.token, controller.signal);
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
binding.waits.delete(controller);
|
|
118
|
+
}
|
|
119
|
+
}),
|
|
120
|
+
},
|
|
121
|
+
agent_status: {
|
|
122
|
+
description: "Read a detached snapshot of a hosted task.",
|
|
123
|
+
inputSchema: z.object({ taskId: z.string() }).strict(),
|
|
124
|
+
execute: input => this.invoke(async (binding) => {
|
|
125
|
+
this.assertCurrent(binding);
|
|
126
|
+
return this.coordinator.snapshot(input.taskId);
|
|
127
|
+
}),
|
|
128
|
+
},
|
|
129
|
+
agent_queue: {
|
|
130
|
+
description: "Read a detached snapshot of a hosted session queue.",
|
|
131
|
+
inputSchema: z.object({ sessionId: z.string() }).strict(),
|
|
132
|
+
execute: input => this.invoke(async (binding) => {
|
|
133
|
+
this.assertCurrent(binding);
|
|
134
|
+
return this.coordinator.sessionSnapshot(input.sessionId);
|
|
135
|
+
}),
|
|
136
|
+
},
|
|
137
|
+
agent_cancel: {
|
|
138
|
+
description: "Cancel a hosted task and its descendants after native stop is confirmed.",
|
|
139
|
+
inputSchema: z.object({ taskId: z.string() }).strict(),
|
|
140
|
+
execute: input => this.invoke(async (binding) => {
|
|
141
|
+
this.assertCurrent(binding);
|
|
142
|
+
if (this.isSelfOrAncestor(input.taskId, binding.taskId)) {
|
|
143
|
+
throw new AgentError("INVALID_PARENT", "A hosted callback cannot cancel its own or an ancestor task.");
|
|
144
|
+
}
|
|
145
|
+
await this.coordinator.cancel(input.taskId);
|
|
146
|
+
return this.coordinator.snapshot(input.taskId);
|
|
147
|
+
}),
|
|
148
|
+
},
|
|
149
|
+
agent_respond: {
|
|
150
|
+
description: "Answer one pending permission request owned by a strict descendant.",
|
|
151
|
+
inputSchema: z.object({ requestId: z.string(), content: approvalContent }).strict(),
|
|
152
|
+
execute: input => this.invoke(async (binding) => {
|
|
153
|
+
this.assertCurrent(binding);
|
|
154
|
+
await this.coordinator.respond(input.requestId, input.content, this.input.token);
|
|
155
|
+
return { requestId: input.requestId, answered: true };
|
|
156
|
+
}),
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
invoke(operation) {
|
|
161
|
+
let binding;
|
|
162
|
+
try {
|
|
163
|
+
binding = this.current();
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
return Promise.reject(markHostedError(error));
|
|
167
|
+
}
|
|
168
|
+
const callback = Promise.resolve().then(() => operation(binding)).catch(error => {
|
|
169
|
+
throw markHostedError(error);
|
|
170
|
+
});
|
|
171
|
+
binding.callbacks.add(callback);
|
|
172
|
+
void callback.finally(() => binding.callbacks.delete(callback)).catch(() => { });
|
|
173
|
+
return callback;
|
|
174
|
+
}
|
|
175
|
+
current() {
|
|
176
|
+
const binding = this.turn;
|
|
177
|
+
if (!binding?.accepting)
|
|
178
|
+
throw new AgentError("INVALID_PARENT", "The hosted tool is not bound to an active task.");
|
|
179
|
+
this.assertCurrent(binding);
|
|
180
|
+
return binding;
|
|
181
|
+
}
|
|
182
|
+
assertCurrent(binding) {
|
|
183
|
+
if (!binding.accepting || this.turn !== binding
|
|
184
|
+
|| this.coordinator.parentContext(this.input.token).taskId !== binding.taskId) {
|
|
185
|
+
throw new AgentError("INVALID_PARENT", "The hosted tool is no longer bound to its invoking task.");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
stopAdmission(binding) {
|
|
189
|
+
binding.accepting = false;
|
|
190
|
+
for (const controller of binding.waits)
|
|
191
|
+
controller.abort();
|
|
192
|
+
}
|
|
193
|
+
isSelfOrAncestor(candidateId, taskId) {
|
|
194
|
+
let current = this.coordinator.snapshot(taskId);
|
|
195
|
+
for (;;) {
|
|
196
|
+
if (current.taskId === candidateId)
|
|
197
|
+
return true;
|
|
198
|
+
if (!current.parentTaskId)
|
|
199
|
+
return false;
|
|
200
|
+
current = this.coordinator.snapshot(current.parentTaskId);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=hosted.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted.js","sourceRoot":"","sources":["../../src/sdk/hosted.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport type { ExecutionDefinition } from \"../adapters/types.js\";\nimport type { ApprovalContent } from \"../approvals/types.js\";\nimport { AgentError } from \"../errors.js\";\nimport type { Coordinator } from \"../runtime/coordinator.js\";\nimport type { DriverInput } from \"../runtime/types.js\";\nimport type { AgentDefinition, ToolDefinition } from \"./types.js\";\nimport { hostedToolNames } from \"./execution-definition.js\";\nimport { markHostedError } from \"./hosted-error.js\";\nimport { observeTask } from \"./execution-observation.js\";\nimport { delivery, validateCwd, validatePrompt } from \"./execution-options.js\";\n\ntype TurnBinding = {\n readonly taskId: string;\n accepting: boolean;\n readonly waits: Set<AbortController>;\n readonly callbacks: Set<Promise<unknown>>;\n};\n\nconst prompt = z.string();\nconst deliverySchema = z.enum([\"queue\", \"steer\", \"interrupt\"]);\nconst approvalValue = z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]);\nconst approvalContent = z.record(z.string(), approvalValue);\n\nexport class HostedDelegation {\n private turn?: TurnBinding;\n\n constructor(\n private readonly coordinator: Coordinator,\n private readonly input: DriverInput,\n private readonly definition: AgentDefinition,\n ) {}\n\n prepare(): ExecutionDefinition {\n if (!Object.keys(this.definition.subagents ?? {}).length) return this.nativeDefinition({});\n return this.nativeDefinition(this.tools());\n }\n\n beginTurn(): void {\n if (this.turn?.accepting) throw new AgentError(\"SESSION_BUSY\", \"A hosted turn is already active.\");\n const { taskId } = this.coordinator.parentContext(this.input.token);\n this.turn = { taskId, accepting: true, waits: new Set(), callbacks: new Set() };\n }\n\n async finishTurn(): Promise<void> {\n const turn = this.turn;\n if (!turn) return;\n this.stopAdmission(turn);\n await Promise.allSettled([...turn.callbacks]);\n if (this.turn === turn) this.turn = undefined;\n }\n\n stopManagedWaits(): void {\n if (this.turn) this.stopAdmission(this.turn);\n }\n\n async drain(): Promise<void> {\n if (this.turn) await Promise.allSettled([...this.turn.callbacks]);\n }\n\n private nativeDefinition(hosted: Readonly<Record<string, ToolDefinition<any>>>): ExecutionDefinition {\n return {\n name: this.definition.name,\n description: this.definition.description,\n instructions: this.definition.instructions,\n harness: this.definition.harness,\n tools: { ...(this.definition.tools ?? {}), ...hosted },\n } as ExecutionDefinition;\n }\n\n private tools(): Record<(typeof hostedToolNames)[number], ToolDefinition<any>> {\n const children = this.definition.subagents ?? {};\n const childKeys = Object.keys(children) as [string, ...string[]];\n const childCatalog = Object.entries(children).map(([key, child]) => ({\n key,\n name: child.name,\n description: child.description,\n }));\n return {\n agent_run: {\n description: `Start one directly declared child agent and return its admitted task and session. Available direct children: ${JSON.stringify(childCatalog)}`,\n inputSchema: z.object({ agent: z.enum(childKeys), prompt, cwd: z.string().optional() }).strict(),\n execute: input => this.invoke(async binding => {\n validatePrompt(input.prompt);\n const children = this.definition.subagents;\n const child = children && Object.hasOwn(children, input.agent) ? children[input.agent] : undefined;\n if (!child) throw new AgentError(\"INVALID_PARENT\", \"This subagent is not available in the active parent context.\");\n const cwd = await validateCwd(input.cwd ?? this.input.cwd);\n this.assertCurrent(binding);\n const receipt = this.coordinator.run({\n reference: { kind: \"inline\", definition: child },\n cwd,\n env: this.input.env,\n prompt: input.prompt,\n parentToken: this.input.token,\n });\n return { taskId: receipt.taskId, sessionId: receipt.sessionId, state: receipt.state! };\n }),\n },\n agent_send: {\n description: \"Send a follow-up to an existing hosted child session.\",\n inputSchema: z.object({ sessionId: z.string(), prompt, delivery: deliverySchema.optional() }).strict(),\n execute: input => this.invoke(async binding => {\n validatePrompt(input.prompt);\n this.assertCurrent(binding);\n const requestedDelivery = delivery(input.delivery === undefined ? undefined : { delivery: input.delivery });\n const receipt = await this.coordinator.send(input.sessionId, input.prompt, requestedDelivery, this.input.token);\n return {\n taskId: receipt.taskId,\n sessionId: receipt.sessionId,\n requestedDelivery,\n effectiveDelivery: receipt.delivery ?? requestedDelivery,\n };\n }),\n },\n agent_wait: {\n description: \"Wait for the next complete response, approval request, or terminal outcome of a hosted task.\",\n inputSchema: z.object({ taskId: z.string(), after: z.string().optional() }).strict(),\n execute: input => this.invoke(async binding => {\n this.assertCurrent(binding);\n if (this.isSelfOrAncestor(input.taskId, binding.taskId)) {\n throw new AgentError(\"INVALID_PARENT\", \"A hosted callback cannot wait for its own or an ancestor task.\");\n }\n const controller = new AbortController();\n binding.waits.add(controller);\n try {\n return await observeTask(this.coordinator, input.taskId, input.after, this.input.token, controller.signal);\n } finally {\n binding.waits.delete(controller);\n }\n }),\n },\n agent_status: {\n description: \"Read a detached snapshot of a hosted task.\",\n inputSchema: z.object({ taskId: z.string() }).strict(),\n execute: input => this.invoke(async binding => {\n this.assertCurrent(binding);\n return this.coordinator.snapshot(input.taskId);\n }),\n },\n agent_queue: {\n description: \"Read a detached snapshot of a hosted session queue.\",\n inputSchema: z.object({ sessionId: z.string() }).strict(),\n execute: input => this.invoke(async binding => {\n this.assertCurrent(binding);\n return this.coordinator.sessionSnapshot(input.sessionId);\n }),\n },\n agent_cancel: {\n description: \"Cancel a hosted task and its descendants after native stop is confirmed.\",\n inputSchema: z.object({ taskId: z.string() }).strict(),\n execute: input => this.invoke(async binding => {\n this.assertCurrent(binding);\n if (this.isSelfOrAncestor(input.taskId, binding.taskId)) {\n throw new AgentError(\"INVALID_PARENT\", \"A hosted callback cannot cancel its own or an ancestor task.\");\n }\n await this.coordinator.cancel(input.taskId);\n return this.coordinator.snapshot(input.taskId);\n }),\n },\n agent_respond: {\n description: \"Answer one pending permission request owned by a strict descendant.\",\n inputSchema: z.object({ requestId: z.string(), content: approvalContent }).strict(),\n execute: input => this.invoke(async binding => {\n this.assertCurrent(binding);\n await this.coordinator.respond(input.requestId, input.content as ApprovalContent, this.input.token);\n return { requestId: input.requestId, answered: true as const };\n }),\n },\n };\n }\n\n private invoke<T>(operation: (binding: TurnBinding) => Promise<T>): Promise<T> {\n let binding: TurnBinding;\n try {\n binding = this.current();\n } catch (error) {\n return Promise.reject(markHostedError(error));\n }\n const callback = Promise.resolve().then(() => operation(binding)).catch(error => {\n throw markHostedError(error);\n });\n binding.callbacks.add(callback);\n void callback.finally(() => binding.callbacks.delete(callback)).catch(() => {});\n return callback;\n }\n\n private current(): TurnBinding {\n const binding = this.turn;\n if (!binding?.accepting) throw new AgentError(\"INVALID_PARENT\", \"The hosted tool is not bound to an active task.\");\n this.assertCurrent(binding);\n return binding;\n }\n\n private assertCurrent(binding: TurnBinding): void {\n if (!binding.accepting || this.turn !== binding\n || this.coordinator.parentContext(this.input.token).taskId !== binding.taskId) {\n throw new AgentError(\"INVALID_PARENT\", \"The hosted tool is no longer bound to its invoking task.\");\n }\n }\n\n private stopAdmission(binding: TurnBinding): void {\n binding.accepting = false;\n for (const controller of binding.waits) controller.abort();\n }\n\n private isSelfOrAncestor(candidateId: string, taskId: string): boolean {\n let current = this.coordinator.snapshot(taskId);\n for (;;) {\n if (current.taskId === candidateId) return true;\n if (!current.parentTaskId) return false;\n current = this.coordinator.snapshot(current.parentTaskId);\n }\n }\n}\n"]}
|
|
@@ -3,6 +3,9 @@ const fields = {
|
|
|
3
3
|
codex: Object.freeze(["approvalPolicy", "sandboxMode", "networkAccessEnabled"]),
|
|
4
4
|
claudeCode: Object.freeze(["permissionMode", "allowedTools", "disallowedTools"]),
|
|
5
5
|
fx: Object.freeze(["permissionMode"]),
|
|
6
|
+
opencode: Object.freeze([]),
|
|
7
|
+
copilot: Object.freeze([]),
|
|
8
|
+
cursor: Object.freeze(["sandboxMode"]),
|
|
6
9
|
};
|
|
7
10
|
const allFields = new Set(Object.values(fields).flat());
|
|
8
11
|
export function permissionOptionFields(kind) {
|
|
@@ -48,7 +51,13 @@ export function validateHarnessPermissions(kind, value) {
|
|
|
48
51
|
}
|
|
49
52
|
return;
|
|
50
53
|
}
|
|
51
|
-
if (
|
|
54
|
+
if (kind === "cursor") {
|
|
55
|
+
if (value.sandboxMode !== undefined && !["enabled", "disabled"].includes(value.sandboxMode)) {
|
|
56
|
+
invalid("Cursor sandboxMode must be enabled or disabled.");
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (kind === "fx" && value.permissionMode !== undefined && !["ask", "auto", "full-access"].includes(value.permissionMode)) {
|
|
52
61
|
invalid("fx permissionMode must be ask, auto, or full-access.");
|
|
53
62
|
}
|
|
54
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-validation.js","sourceRoot":"","sources":["../../src/sdk/permission-validation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,MAAM,GAAG;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,EAAE,aAAa,EAAE,sBAAsB,CAAC,CAAC;IAC/E,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,CAAC,CAAC;IAChF,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"permission-validation.js","sourceRoot":"","sources":["../../src/sdk/permission-validation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { HarnessKind } from \"./types.js\";\nimport { invalid } from \"./validation.js\";\n\nconst fields = {\n codex: Object.freeze([\"approvalPolicy\", \"sandboxMode\", \"networkAccessEnabled\"]),\n claudeCode: Object.freeze([\"permissionMode\", \"allowedTools\", \"disallowedTools\"]),\n fx: Object.freeze([\"permissionMode\"]),\n opencode: Object.freeze([]),\n copilot: Object.freeze([]),\n cursor: Object.freeze([\"sandboxMode\"]),\n} as const satisfies Record<HarnessKind, readonly string[]>;\n\nconst allFields = new Set(Object.values(fields).flat());\n\nexport function permissionOptionFields(kind: HarnessKind): readonly string[] {\n return fields[kind];\n}\n\n/** Validates only native permission fields, ignoring unrelated caller-owned fields. */\nexport function validateHarnessPermissions(kind: HarnessKind, value: Readonly<Record<string, unknown>>): void {\n const supported = new Set<string>(fields[kind]);\n if ([...allFields].some(field => Object.hasOwn(value, field) && !supported.has(field))) {\n invalid(\"Unknown configuration field.\");\n }\n\n if (kind === \"codex\") {\n if (value.approvalPolicy !== undefined && ![\"never\", \"on-request\", \"untrusted\"].includes(value.approvalPolicy as string)) {\n invalid(\"Codex approvalPolicy must be never, on-request, or untrusted.\");\n }\n if (value.sandboxMode !== undefined && ![\"read-only\", \"workspace-write\", \"danger-full-access\"].includes(value.sandboxMode as string)) {\n invalid(\"Codex sandboxMode must be read-only, workspace-write, or danger-full-access.\");\n }\n if (value.networkAccessEnabled !== undefined && typeof value.networkAccessEnabled !== \"boolean\") {\n invalid(\"Codex networkAccessEnabled must be a boolean.\");\n }\n if (value.networkAccessEnabled !== undefined && value.sandboxMode !== \"workspace-write\") {\n invalid(\"Codex networkAccessEnabled requires sandboxMode workspace-write.\");\n }\n return;\n }\n\n if (kind === \"claudeCode\") {\n if (value.permissionMode !== undefined && ![\"default\", \"acceptEdits\", \"bypassPermissions\", \"plan\", \"dontAsk\", \"auto\"].includes(value.permissionMode as string)) {\n invalid(\"Claude permissionMode is unsupported.\");\n }\n for (const field of [\"allowedTools\", \"disallowedTools\"] as const) {\n const rules = value[field];\n if (rules === undefined) continue;\n if (!Array.isArray(rules)) invalid(`Claude ${field} must be an array of nonempty strings.`);\n for (let index = 0; index < rules.length; index++) {\n const rule = rules[index];\n if (typeof rule !== \"string\" || !rule.trim()) {\n invalid(`Claude ${field} must be an array of nonempty strings.`);\n }\n }\n }\n return;\n }\n\n if (kind === \"cursor\") {\n if (value.sandboxMode !== undefined && ![\"enabled\", \"disabled\"].includes(value.sandboxMode as string)) {\n invalid(\"Cursor sandboxMode must be enabled or disabled.\");\n }\n return;\n }\n\n if (kind === \"fx\" && value.permissionMode !== undefined && ![\"ask\", \"auto\", \"full-access\"].includes(value.permissionMode as string)) {\n invalid(\"fx permissionMode must be ask, auto, or full-access.\");\n }\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type NativeOpener } from './execution-driver.js';
|
|
2
|
+
import type { Runner, RunnerOptions } from './execution-types.js';
|
|
3
|
+
export declare function createRunner(options?: RunnerOptions): Runner;
|
|
4
|
+
/** Internal test seam replacing only the external native adapter boundary. */
|
|
5
|
+
export declare function createRunnerWithNativeOpener(options: RunnerOptions | undefined, open: NativeOpener): Runner;
|