@astrosheep/keiyaku 2.9.2 → 2.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/.tsbuildinfo +1 -1
- package/build/agents/call-terms.js +13 -94
- package/build/agents/harness/activity-values.js +16 -0
- package/build/agents/harness/event-persistence.js +218 -0
- package/build/agents/harness/execution-handle.js +25 -222
- package/build/agents/harness/index.js +3 -1
- package/build/agents/harness/outcome.js +47 -4
- package/build/agents/harness/projection.js +42 -59
- package/build/agents/harness/provider-adapter.js +58 -0
- package/build/agents/harness/router.js +11 -187
- package/build/agents/harness/runtime.js +17 -4
- package/build/agents/harness/session.js +15 -0
- package/build/agents/launch-snapshot/model.js +15 -236
- package/build/agents/launch-snapshot/parse-helpers.js +114 -0
- package/build/agents/launch-snapshot/resolve.js +17 -43
- package/build/agents/opencode-sdk.js +45 -12
- package/build/agents/providers/claude-agent-sdk/adapter.js +6 -17
- package/build/agents/providers/claude-agent-sdk/registration.js +214 -0
- package/build/agents/providers/claude-agent-sdk/session-schema.js +2 -0
- package/build/agents/providers/codex-app-server/adapter.js +50 -53
- package/build/agents/providers/codex-app-server/events.js +67 -11
- package/build/agents/providers/codex-app-server/identity.js +1 -0
- package/build/agents/providers/codex-app-server/policy.js +29 -0
- package/build/agents/providers/codex-app-server/registration.js +248 -0
- package/build/agents/providers/codex-app-server/session-schema.js +6 -0
- package/build/agents/providers/codex-app-server/session.js +23 -17
- package/build/agents/providers/codex-app-server/terms.js +1 -0
- package/build/agents/providers/opencode-sdk/adapter.js +94 -50
- package/build/agents/providers/opencode-sdk/events.js +8 -4
- package/build/agents/providers/opencode-sdk/registration.js +135 -0
- package/build/agents/providers/opencode-sdk/session-schema.js +2 -0
- package/build/agents/providers/opencode-sdk/session.js +21 -14
- package/build/agents/providers/opencode-sdk/terms.js +1 -0
- package/build/agents/providers/pi/adapter.js +36 -30
- package/build/agents/providers/pi/registration.js +145 -0
- package/build/agents/providers/pi/session-schema.js +6 -0
- package/build/agents/providers/pi/terms.js +1 -0
- package/build/agents/providers/registration.js +7 -0
- package/build/agents/providers/registry.js +76 -0
- package/build/agents/selector.js +2 -29
- package/build/agents/types.js +8 -0
- package/build/artifact-directories.js +22 -0
- package/build/cli/commands/akuma/akuma/handler.js +1 -1
- package/build/cli/commands/akuma/view/handler.js +5 -4
- package/build/cli/commands/akuma.js +6 -0
- package/build/cli/commands/contract/amend/handler.js +8 -2
- package/build/cli/commands/contract/arc/handler.js +7 -1
- package/build/cli/commands/contract/bind/handler.js +4 -3
- package/build/cli/commands/contract/bind/meta.js +34 -7
- package/build/cli/commands/contract/forfeit/handler.js +4 -4
- package/build/cli/commands/contract/log/handler.js +3 -3
- package/build/cli/commands/contract/petition/handler.js +4 -6
- package/build/cli/commands/contract/renew/handler.js +20 -6
- package/build/cli/commands/contract/renew/meta.js +5 -4
- package/build/cli/commands/metadata.js +58 -0
- package/build/cli/commands/projection/call/handler.js +6 -5
- package/build/cli/commands/projection/kill/handler.js +16 -32
- package/build/cli/commands/projection/shared.js +28 -0
- package/build/cli/commands/projection/status/handler.js +1 -1
- package/build/cli/commands/projection/tell/handler.js +14 -30
- package/build/cli/commands/projection/wait/handler.js +45 -22
- package/build/cli/commands/projection/wait/meta.js +7 -2
- package/build/cli/commands/registry.js +2 -54
- package/build/cli/commands/shared.js +10 -7
- package/build/cli/commands/skills/install/handler.js +2 -5
- package/build/cli/commands/skills/skills/handler.js +1 -1
- package/build/cli/commands/task/add/handler.js +5 -13
- package/build/cli/commands/task/catalog.js +2 -2
- package/build/cli/commands/task/done/handler.js +4 -8
- package/build/cli/commands/task/drop/handler.js +3 -6
- package/build/cli/commands/task/ls/handler.js +3 -5
- package/build/cli/commands/task/shared.js +14 -4
- package/build/cli/commands/task/{view → show}/handler.js +7 -8
- package/build/cli/commands/task/show/meta.js +8 -0
- package/build/cli/commands/task/start/handler.js +3 -6
- package/build/cli/commands/task/stop/handler.js +4 -8
- package/build/cli/commands/task/task/handler.js +1 -1
- package/build/cli/commands/task/update/handler.js +4 -8
- package/build/cli/completion.js +1 -1
- package/build/cli/flags.js +19 -3
- package/build/cli/help.js +4 -11
- package/build/cli/index.js +57 -83
- package/build/cli/missing-subcommand.js +7 -0
- package/build/cli/parse-flags.js +14 -5
- package/build/cli/parse-metadata.js +3 -3
- package/build/cli/parse-selectors.js +1 -1
- package/build/cli/parse.js +21 -0
- package/build/cli/projection-address.js +7 -12
- package/build/cli/render/address.js +41 -37
- package/build/cli/render/arc.js +24 -12
- package/build/cli/render/call.js +11 -5
- package/build/cli/render/errors.js +36 -1
- package/build/cli/render/format.js +4 -0
- package/build/cli/render/kanshi.js +6 -12
- package/build/cli/render/kill.js +9 -0
- package/build/cli/render/misc.js +55 -12
- package/build/cli/render/petition.js +20 -15
- package/build/cli/render/projection-activity.js +3 -0
- package/build/cli/render/shared.js +60 -21
- package/build/cli/render/skills.js +10 -0
- package/build/cli/render/status.js +37 -14
- package/build/cli/render/success-response.js +77 -0
- package/build/cli/render/task.js +54 -14
- package/build/cli/render/tell.js +5 -0
- package/build/cli/render/terminal-failure.js +58 -0
- package/build/cli/render/types.js +1 -0
- package/build/cli/render/wait.js +38 -36
- package/build/cli/types.js +1 -1
- package/build/config/akuma-loader.js +0 -5
- package/build/config/env-keys.js +1 -1
- package/build/config/provider-policy-ownership.js +3 -32
- package/build/config/settings/disease.js +8 -1
- package/build/config/settings/loader.js +11 -3
- package/build/config/settings/provider-instance-fields.js +51 -0
- package/build/config/settings/schema.js +6 -176
- package/build/core/addressing.js +66 -16
- package/build/core/amend.js +135 -18
- package/build/core/arc.js +19 -67
- package/build/core/bind.js +82 -35
- package/build/core/call/call.js +15 -9
- package/build/core/call/context.js +6 -51
- package/build/core/call/execution.js +21 -22
- package/build/core/call/prompt.js +14 -1
- package/build/core/command-markdown.js +45 -0
- package/build/core/context.js +13 -7
- package/build/core/contract-view.js +20 -3
- package/build/core/draft.js +123 -16
- package/build/core/forfeit.js +5 -2
- package/build/core/hints.js +1 -75
- package/build/core/identifier-slug.js +66 -0
- package/build/core/ids.js +25 -11
- package/build/core/ledger.js +20 -68
- package/build/core/markdown/parser.js +0 -68
- package/build/core/markdown/render.js +68 -0
- package/build/core/markdown/sections.js +2 -1
- package/build/core/outcome-base.js +4 -0
- package/build/core/projection/generation/database.js +2 -38
- package/build/core/projection/generation/model.js +42 -1
- package/build/core/{projection-generation-continuation.js → projection/generation/projection-generation-continuation.js} +3 -3
- package/build/core/{projection-generation-execution.js → projection/generation/projection-generation-execution.js} +19 -49
- package/build/core/{projection-generation-identity.js → projection/generation/projection-generation-identity.js} +2 -2
- package/build/core/{projection-generation-launcher.js → projection/generation/projection-generation-launcher.js} +5 -3
- package/build/core/{projection-generation-process.js → projection/generation/projection-generation-process.js} +2 -1
- package/build/core/{projection-generation-runner.js → projection/generation/projection-generation-runner.js} +18 -3
- package/build/core/projection/generation/store.js +2 -2
- package/build/core/projection/generation/transitions.js +1 -1
- package/build/core/projection/index.js +27 -0
- package/build/core/{projection-activity.js → projection/projection-activity.js} +12 -0
- package/build/core/{projection-alias.js → projection/projection-alias.js} +14 -19
- package/build/core/projection/projection-coordinate.js +61 -0
- package/build/core/{projection-core.js → projection/projection-core.js} +9 -9
- package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js} +2 -57
- package/build/core/{projection-identity.js → projection/projection-identity.js} +1 -1
- package/build/core/{projection-kill.js → projection/projection-kill.js} +1 -1
- package/build/core/{projection-life-observer.js → projection/projection-life-observer.js} +1 -1
- package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
- package/build/core/{projection-status.js → projection/projection-status.js} +98 -25
- package/build/core/projection/projection-terminal-failure.js +104 -0
- package/build/core/projection/projection-wait.js +278 -0
- package/build/core/projection/projection-wake.js +203 -0
- package/build/core/provider-loader-ports.js +4 -0
- package/build/core/ref-log.js +65 -40
- package/build/core/registry.js +63 -10
- package/build/core/renew-session.js +128 -0
- package/build/core/renew.js +426 -99
- package/build/core/scope.js +143 -66
- package/build/core/seal.js +139 -35
- package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +9 -14
- package/build/core/{claim.js → settlement/claim.js} +32 -8
- package/build/core/settlement/index.js +19 -0
- package/build/core/{petition-claim-gates.js → settlement/petition-claim-gates.js} +22 -18
- package/build/core/{petition-forfeit.js → settlement/petition-forfeit.js} +2 -2
- package/build/core/{petition-head-guard.js → settlement/petition-head-guard.js} +2 -2
- package/build/core/settlement/petition-io.js +1 -0
- package/build/core/{petition-preview.js → settlement/petition-preview.js} +1 -1
- package/build/core/{petition.js → settlement/petition.js} +12 -10
- package/build/core/settlement/queue-read-model.js +143 -0
- package/build/core/settlement/queue-seat-allocation.js +156 -0
- package/build/core/settlement/queue.js +6 -0
- package/build/core/settlement/settlement.js +295 -0
- package/build/core/{verdict.js → settlement/verdict.js} +9 -37
- package/build/core/status/board.js +24 -23
- package/build/core/status/ledger-batch.js +158 -0
- package/build/core/status/reconciliation.js +10 -4
- package/build/core/stored-agent-event.js +3 -0
- package/build/core/task/board.js +40 -4
- package/build/core/task/commands.js +30 -21
- package/build/core/task/index.js +12 -0
- package/build/core/task/settlement-git.js +157 -65
- package/build/core/task/settlement-policy.js +54 -24
- package/build/core/task/task-contract.js +370 -0
- package/build/core/{task-doctor.js → task/task-doctor.js} +1 -1
- package/build/core/{task-git-actor.js → task/task-git-actor.js} +5 -10
- package/build/core/{task-git-runtime.js → task/task-git-runtime.js} +3 -3
- package/build/core/{task-git-store.js → task/task-git-store.js} +92 -29
- package/build/core/task/task-repository.js +1 -0
- package/build/core/{task-store-repository.js → task/task-store-repository.js} +5 -4
- package/build/core/task/task-store.js +1 -0
- package/build/core/{task-worktree.js → task/task-worktree.js} +2 -1
- package/build/core/task/task.js +5 -0
- package/build/core/task/tree.js +37 -0
- package/build/core/task/validation.js +5 -2
- package/build/core/transcripts.js +15 -3
- package/build/core/worktree-path.js +43 -28
- package/build/flow-error.js +85 -39
- package/build/fs/durability.js +27 -0
- package/build/fs/path-coordinate.js +16 -0
- package/build/generated/version.js +3 -2
- package/build/git/branches.js +2 -1
- package/build/git/core.js +106 -2
- package/build/git/path-coordinate.js +17 -0
- package/build/git/refs.js +57 -0
- package/build/git/streaming-batch.js +301 -0
- package/build/git/worktree.js +65 -0
- package/build/index.js +3 -3
- package/build/keiyaku.js +2 -36
- package/package.json +4 -10
- package/skills/keiyaku/SKILL.md +3 -2
- package/skills/keiyaku-akuma/SKILL.md +10 -6
- package/skills/keiyaku-task/SKILL.md +1 -1
- package/skills/keiyaku-workflow/SKILL.md +25 -4
- package/build/agents/providers/codex-sdk.js +0 -329
- package/build/cli/commands/task/view/meta.js +0 -8
- package/build/core/command-io.js +0 -174
- package/build/core/path-coordinate.js +0 -27
- package/build/core/petition-claim.js +0 -117
- package/build/core/petition-run.js +0 -83
- package/build/core/projection-coordinate.js +0 -63
- package/build/core/projection-wait.js +0 -165
- package/build/core/projection-wake.js +0 -136
- package/build/core/queue.js +0 -343
- package/build/core/task-contract.js +0 -237
- package/build/core/task.js +0 -4
- /package/build/{core/task-repository.js → agents/launch-snapshot/types.js} +0 -0
- /package/build/{core/task-store.js → agents/providers/claude-agent-sdk/terms.js} +0 -0
- /package/build/core/{projection-generation-runtime.js → projection/generation/projection-generation-runtime.js} +0 -0
- /package/build/core/{projection-life-protocol.js → projection/projection-life-protocol.js} +0 -0
- /package/build/core/{projection-runner-lock.js → projection/projection-runner-lock.js} +0 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { executableSchema, providerCommonFields, providerEnvSchema, } from "../../../config/settings/provider-instance-fields.js";
|
|
3
|
+
import { FlowError } from "../../../flow-error.js";
|
|
4
|
+
import { exactKeys, optionalString, optionalStringRecord, } from "../../launch-snapshot/parse-helpers.js";
|
|
5
|
+
import { SUBAGENT_SESSION_VERSION, subagentSessionEnvelopeSchema, } from "../../session.js";
|
|
6
|
+
import { OPENCODE_SDK_PROVIDER } from "./session.js";
|
|
7
|
+
import { opencodeSessionSchema } from "./session-schema.js";
|
|
8
|
+
const startOpencode = async (prompt, cwd, options) => {
|
|
9
|
+
const { startOpencode: start } = await import("./adapter.js");
|
|
10
|
+
return start(prompt, cwd, options);
|
|
11
|
+
};
|
|
12
|
+
function admitResumeShape(schema, session, resumePath) {
|
|
13
|
+
const envelopeResult = subagentSessionEnvelopeSchema.safeParse(session);
|
|
14
|
+
if (!envelopeResult.success) {
|
|
15
|
+
throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' includes an invalid session envelope.`);
|
|
16
|
+
}
|
|
17
|
+
if (session.provider !== OPENCODE_SDK_PROVIDER) {
|
|
18
|
+
throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' was created with provider '${session.provider}', but the selected subagent resolves to '${OPENCODE_SDK_PROVIDER}'. Cross-provider resume is not supported.`);
|
|
19
|
+
}
|
|
20
|
+
if (session.version !== SUBAGENT_SESSION_VERSION) {
|
|
21
|
+
throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' uses unsupported session version '${session.version}' for provider '${session.provider}'.`);
|
|
22
|
+
}
|
|
23
|
+
const shapeResult = schema.safeParse(session.handle);
|
|
24
|
+
if (!shapeResult.success) {
|
|
25
|
+
throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' includes an invalid session handle for provider '${session.provider}'.`);
|
|
26
|
+
}
|
|
27
|
+
return shapeResult.data;
|
|
28
|
+
}
|
|
29
|
+
export const opencodeSdkRegistration = {
|
|
30
|
+
name: OPENCODE_SDK_PROVIDER,
|
|
31
|
+
start: startOpencode,
|
|
32
|
+
sessionSchema: opencodeSessionSchema,
|
|
33
|
+
effortField: "effort",
|
|
34
|
+
instanceSchema: z
|
|
35
|
+
.object({
|
|
36
|
+
kind: z.literal(OPENCODE_SDK_PROVIDER),
|
|
37
|
+
...providerCommonFields,
|
|
38
|
+
executable: executableSchema.optional(),
|
|
39
|
+
env: providerEnvSchema,
|
|
40
|
+
})
|
|
41
|
+
.strict(),
|
|
42
|
+
builtinInstance: {
|
|
43
|
+
name: OPENCODE_SDK_PROVIDER,
|
|
44
|
+
source: "builtin",
|
|
45
|
+
instance: { kind: OPENCODE_SDK_PROVIDER, executable: "opencode" },
|
|
46
|
+
},
|
|
47
|
+
portablePolicy: {
|
|
48
|
+
access: new Set(),
|
|
49
|
+
network: new Set(),
|
|
50
|
+
webSearch: new Set(),
|
|
51
|
+
},
|
|
52
|
+
maxCaptureChars: (config) => config.opencode.execMaxCaptureChars,
|
|
53
|
+
sessionContinuationPromptPrefix: (body) => `[Akuma system prompt]\n${body}\n\n[Operator prompt]\n`,
|
|
54
|
+
buildCallTerms: ({ snapshot, baseTerms, replayPrompt }) => {
|
|
55
|
+
const provider = snapshot.provider;
|
|
56
|
+
return {
|
|
57
|
+
...baseTerms,
|
|
58
|
+
prompt: replayPrompt,
|
|
59
|
+
provider: OPENCODE_SDK_PROVIDER,
|
|
60
|
+
...(provider.model !== undefined ? { model: provider.model } : {}),
|
|
61
|
+
...(provider.effort !== undefined ? { effort: provider.effort } : {}),
|
|
62
|
+
...(provider.executable !== undefined ? { executable: provider.executable } : {}),
|
|
63
|
+
...(provider.env !== undefined ? { env: provider.env } : {}),
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
resolveLaunchProvider: ({ common, instance, model, effort }) => {
|
|
67
|
+
if (instance.kind !== OPENCODE_SDK_PROVIDER) {
|
|
68
|
+
throw new Error(`resolveLaunchProvider expected ${OPENCODE_SDK_PROVIDER}`);
|
|
69
|
+
}
|
|
70
|
+
const opencodeInstance = instance;
|
|
71
|
+
return Object.freeze({
|
|
72
|
+
...common,
|
|
73
|
+
kind: OPENCODE_SDK_PROVIDER,
|
|
74
|
+
...(opencodeInstance.executable !== undefined ? { executable: opencodeInstance.executable } : {}),
|
|
75
|
+
...(model !== undefined ? { model } : {}),
|
|
76
|
+
...(effort !== undefined ? { effort } : {}),
|
|
77
|
+
...(opencodeInstance.env !== undefined ? { env: opencodeInstance.env } : {}),
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
parseLaunchProvider: (provider, common) => {
|
|
81
|
+
exactKeys(provider, ["name", "source", "kind", "executable", "model", "effort", "env"], "provider");
|
|
82
|
+
const executable = optionalString(provider, "executable", "provider");
|
|
83
|
+
const model = optionalString(provider, "model", "provider");
|
|
84
|
+
const effort = optionalString(provider, "effort", "provider");
|
|
85
|
+
const env = optionalStringRecord(provider, "env");
|
|
86
|
+
return Object.freeze({
|
|
87
|
+
...common,
|
|
88
|
+
kind: OPENCODE_SDK_PROVIDER,
|
|
89
|
+
...(executable !== undefined ? { executable } : {}),
|
|
90
|
+
...(model !== undefined ? { model } : {}),
|
|
91
|
+
...(effort !== undefined ? { effort } : {}),
|
|
92
|
+
...(env !== undefined ? { env } : {}),
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
applyEffort: (provider, effort) => Object.freeze({ ...provider, effort }),
|
|
96
|
+
providerEffortAndModel: (provider) => {
|
|
97
|
+
const resolved = provider;
|
|
98
|
+
return { model: resolved.model, effort: resolved.effort };
|
|
99
|
+
},
|
|
100
|
+
attachLoader: (terms, ports) => {
|
|
101
|
+
if (terms.provider !== OPENCODE_SDK_PROVIDER)
|
|
102
|
+
return terms;
|
|
103
|
+
const loader = ports.opencodeSdk;
|
|
104
|
+
return loader ? { ...terms, loader } : terms;
|
|
105
|
+
},
|
|
106
|
+
nativePolicyOwnership: () => null,
|
|
107
|
+
startLive: async ({ terms, signal, reviveTerms, onSyncCheckpoint, onDeliveryOpportunity, onIngress, }) => {
|
|
108
|
+
if (terms.provider !== OPENCODE_SDK_PROVIDER) {
|
|
109
|
+
throw new Error(`startLive expected ${OPENCODE_SDK_PROVIDER}`);
|
|
110
|
+
}
|
|
111
|
+
const opencodeTerms = terms;
|
|
112
|
+
const options = {
|
|
113
|
+
model: opencodeTerms.model,
|
|
114
|
+
effort: opencodeTerms.effort,
|
|
115
|
+
executable: opencodeTerms.executable,
|
|
116
|
+
env: opencodeTerms.env,
|
|
117
|
+
signal,
|
|
118
|
+
onSyncCheckpoint,
|
|
119
|
+
onDeliveryOpportunity,
|
|
120
|
+
onEvidence: opencodeTerms.onEvidence,
|
|
121
|
+
onIngress,
|
|
122
|
+
initialTurn: opencodeTerms.initialTurn,
|
|
123
|
+
loader: opencodeTerms.loader,
|
|
124
|
+
};
|
|
125
|
+
const { startOpencode: start } = await import("./adapter.js");
|
|
126
|
+
if (reviveTerms) {
|
|
127
|
+
const session = admitResumeShape(opencodeSessionSchema, reviveTerms.session, reviveTerms.resumePath);
|
|
128
|
+
return start(opencodeTerms.prompt, opencodeTerms.workdir, {
|
|
129
|
+
...options,
|
|
130
|
+
sessionId: session.sessionId,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return start(opencodeTerms.prompt, opencodeTerms.workdir, options);
|
|
134
|
+
},
|
|
135
|
+
};
|
|
@@ -18,6 +18,8 @@ export class OpencodeIdleMonitor {
|
|
|
18
18
|
settledIngressEpoch = 0;
|
|
19
19
|
observedIngressEpoch = 0;
|
|
20
20
|
fallbackDelayMs = OPENCODE_SILENT_FALLBACK_INITIAL_MS;
|
|
21
|
+
observedActive = false;
|
|
22
|
+
terminalObserved = false;
|
|
21
23
|
disposed = false;
|
|
22
24
|
constructor(session, sessionId, signal) {
|
|
23
25
|
this.session = session;
|
|
@@ -47,6 +49,9 @@ export class OpencodeIdleMonitor {
|
|
|
47
49
|
if (!this.queryRunning)
|
|
48
50
|
this.scheduleTrailingQuery();
|
|
49
51
|
}
|
|
52
|
+
terminal() {
|
|
53
|
+
this.terminalObserved = true;
|
|
54
|
+
}
|
|
50
55
|
dispose() {
|
|
51
56
|
if (this.disposed)
|
|
52
57
|
return;
|
|
@@ -85,6 +90,8 @@ export class OpencodeIdleMonitor {
|
|
|
85
90
|
this.rejectCycle = undefined;
|
|
86
91
|
this.settledIngressEpoch = this.ingressEpoch;
|
|
87
92
|
this.fallbackDelayMs = OPENCODE_SILENT_FALLBACK_INITIAL_MS;
|
|
93
|
+
this.observedActive = false;
|
|
94
|
+
this.terminalObserved = false;
|
|
88
95
|
resolve?.();
|
|
89
96
|
}
|
|
90
97
|
fail(error) {
|
|
@@ -111,13 +118,20 @@ export class OpencodeIdleMonitor {
|
|
|
111
118
|
this.scheduleTrailingQuery();
|
|
112
119
|
return;
|
|
113
120
|
}
|
|
114
|
-
if (!Object.prototype.hasOwnProperty.call(active, this.sessionId)) {
|
|
115
|
-
this.finish();
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
121
|
if (hadUnobservedIngress) {
|
|
119
122
|
this.scheduleTrailingQuery();
|
|
120
123
|
}
|
|
124
|
+
else if (Object.prototype.hasOwnProperty.call(active, this.sessionId)) {
|
|
125
|
+
this.observedActive = true;
|
|
126
|
+
const delayMs = this.fallbackDelayMs;
|
|
127
|
+
this.fallbackDelayMs = Math.min(delayMs * 2, OPENCODE_SILENT_FALLBACK_MAX_MS);
|
|
128
|
+
this.schedule(delayMs);
|
|
129
|
+
}
|
|
130
|
+
else if (this.observedActive ||
|
|
131
|
+
this.terminalObserved ||
|
|
132
|
+
this.ingressEpoch === this.settledIngressEpoch) {
|
|
133
|
+
this.finish();
|
|
134
|
+
}
|
|
121
135
|
else {
|
|
122
136
|
const delayMs = this.fallbackDelayMs;
|
|
123
137
|
this.fallbackDelayMs = Math.min(delayMs * 2, OPENCODE_SILENT_FALLBACK_MAX_MS);
|
|
@@ -135,7 +149,6 @@ export class OpencodeIdleMonitor {
|
|
|
135
149
|
}
|
|
136
150
|
}
|
|
137
151
|
}
|
|
138
|
-
let opencodeSdkLoader;
|
|
139
152
|
export function sessionIdFrom(info, fallback) {
|
|
140
153
|
return coerceString(info.id) ?? fallback;
|
|
141
154
|
}
|
|
@@ -158,9 +171,9 @@ export async function withAbort(promise, signal, message) {
|
|
|
158
171
|
});
|
|
159
172
|
});
|
|
160
173
|
}
|
|
161
|
-
export async function loadOpencodeSdk(executable, cwd, env, signal) {
|
|
162
|
-
if (
|
|
163
|
-
return
|
|
174
|
+
export async function loadOpencodeSdk(executable, cwd, env, signal, loader) {
|
|
175
|
+
if (loader)
|
|
176
|
+
return loader(cwd);
|
|
164
177
|
const sdk = await createOpencode({
|
|
165
178
|
executable,
|
|
166
179
|
directory: cwd,
|
|
@@ -172,9 +185,3 @@ export async function loadOpencodeSdk(executable, cwd, env, signal) {
|
|
|
172
185
|
close: sdk.server?.close,
|
|
173
186
|
};
|
|
174
187
|
}
|
|
175
|
-
export function setOpencodeSdkLoaderForTests(loader) {
|
|
176
|
-
opencodeSdkLoader = loader;
|
|
177
|
-
}
|
|
178
|
-
export function resetOpencodeSdkLoaderForTests() {
|
|
179
|
-
opencodeSdkLoader = undefined;
|
|
180
|
-
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
1
|
import { FlowError } from "../../../flow-error.js";
|
|
3
2
|
import { appendDebugLog } from "../../../telemetry/debug-log.js";
|
|
4
3
|
import { createProjectionDriver } from "../../harness/execution-handle.js";
|
|
4
|
+
import { createProviderFailure, toProviderTerminalError, } from "../../harness/provider-adapter.js";
|
|
5
5
|
import { createAbortError, emitProviderEvidence, sha256Utf8 } from "../../harness/runtime.js";
|
|
6
|
-
import { SubagentFailure } from "../../types.js";
|
|
7
6
|
import { createPiCheckpointController, PI_PROVIDER, toPiSdkThinkingLevel, } from "./checkpoint.js";
|
|
8
7
|
import { bindPiSessionEvents } from "./events.js";
|
|
9
|
-
|
|
10
|
-
export const piSessionSchema = z.object({
|
|
11
|
-
sessionFile: z.string().trim().min(1),
|
|
12
|
-
sessionId: z.string().trim().min(1).optional(),
|
|
13
|
-
});
|
|
8
|
+
export { piSessionSchema } from "./session-schema.js";
|
|
14
9
|
/** Exact model shape: `<provider>/<id>` (single slash separating non-empty sides). */
|
|
15
10
|
const PI_MODEL_PATTERN = /^[^/]+\/[^/]+$/;
|
|
16
11
|
const importPiSdk = new Function("specifier", "return import(specifier)");
|
|
@@ -18,21 +13,8 @@ async function loadPiSdk(loader) {
|
|
|
18
13
|
if (loader) {
|
|
19
14
|
return loader();
|
|
20
15
|
}
|
|
21
|
-
if (_piSdkLoader) {
|
|
22
|
-
return _piSdkLoader();
|
|
23
|
-
}
|
|
24
16
|
return (await importPiSdk("@earendil-works/pi-coding-agent"));
|
|
25
17
|
}
|
|
26
|
-
/** @deprecated Use PiOptions.loader instead. Kept for pipeline-based tests pending loader channel. */
|
|
27
|
-
let _piSdkLoader;
|
|
28
|
-
/** @deprecated Use PiOptions.loader instead. */
|
|
29
|
-
export function setPiSdkLoaderForTests(loader) {
|
|
30
|
-
_piSdkLoader = loader;
|
|
31
|
-
}
|
|
32
|
-
/** @deprecated Use PiOptions.loader instead. */
|
|
33
|
-
export function resetPiSdkLoaderForTests() {
|
|
34
|
-
_piSdkLoader = undefined;
|
|
35
|
-
}
|
|
36
18
|
export function parsePiModelRef(model) {
|
|
37
19
|
const trimmed = model.trim();
|
|
38
20
|
if (!PI_MODEL_PATTERN.test(trimmed)) {
|
|
@@ -45,6 +27,23 @@ export function parsePiModelRef(model) {
|
|
|
45
27
|
};
|
|
46
28
|
}
|
|
47
29
|
export async function startPi(prompt, cwd, options = {}) {
|
|
30
|
+
// Pre-driver awaits (sdk/session/model/resource/createAgentSession) sit outside
|
|
31
|
+
// createProjectionDriver's run gate; map every startup throw to the typed
|
|
32
|
+
// terminal boundary here. FlowError (settings shape) remains unnormalized.
|
|
33
|
+
try {
|
|
34
|
+
return await openPiProjectionDriver(prompt, cwd, options);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (error instanceof FlowError)
|
|
38
|
+
throw error;
|
|
39
|
+
throw toProviderTerminalError(error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function openPiProjectionDriver(prompt, cwd, options) {
|
|
43
|
+
// Pre-driver cancellation is immediately signal-cancellable — check before any SDK work.
|
|
44
|
+
if (options.signal?.aborted) {
|
|
45
|
+
throw createAbortError(`${PI_PROVIDER} exec cancelled by client`, options.signal.reason);
|
|
46
|
+
}
|
|
48
47
|
const resumeSessionFile = options.sessionFile?.trim();
|
|
49
48
|
appendDebugLog(`startPi: mode=${resumeSessionFile ? "resume" : "fresh"} model=${options.model ?? "default"}`, { cwd, section: PI_PROVIDER });
|
|
50
49
|
const sdk = await loadPiSdk(options.loader);
|
|
@@ -53,22 +52,20 @@ export async function startPi(prompt, cwd, options = {}) {
|
|
|
53
52
|
? sessionManagerApi.open(resumeSessionFile)
|
|
54
53
|
: sessionManagerApi.create(cwd);
|
|
55
54
|
let model;
|
|
56
|
-
let
|
|
57
|
-
let modelRegistry;
|
|
55
|
+
let modelRuntime;
|
|
58
56
|
if (options.model !== undefined && options.model.trim().length > 0) {
|
|
59
57
|
const original = options.model.trim();
|
|
60
58
|
const ref = parsePiModelRef(original);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
model = modelRegistry.find(ref.provider, ref.id);
|
|
59
|
+
modelRuntime = await sdk.ModelRuntime.create();
|
|
60
|
+
model = modelRuntime.getModel(ref.provider, ref.id);
|
|
64
61
|
if (!model) {
|
|
65
|
-
throw
|
|
62
|
+
throw createProviderFailure(`${PI_PROVIDER} model '${original}' is not available`, { code: "SUBAGENT_PROVIDER_UNAVAILABLE" });
|
|
66
63
|
}
|
|
67
64
|
}
|
|
68
65
|
// With an Akuma body, retain the default loader's discovery and override only its append list.
|
|
69
66
|
// The override deliberately suppresses discovered APPEND_SYSTEM.md content.
|
|
70
67
|
if (options.appendSystemPromptOverride && (!sdk.DefaultResourceLoader || !sdk.getAgentDir)) {
|
|
71
|
-
throw
|
|
68
|
+
throw createProviderFailure(`${PI_PROVIDER} SDK does not expose DefaultResourceLoader and getAgentDir`);
|
|
72
69
|
}
|
|
73
70
|
let emittedAppendEvidence = false;
|
|
74
71
|
let pendingEvidenceDiagnostics = 0;
|
|
@@ -94,12 +91,15 @@ export async function startPi(prompt, cwd, options = {}) {
|
|
|
94
91
|
})
|
|
95
92
|
: undefined;
|
|
96
93
|
await resourceLoader?.reload();
|
|
94
|
+
if (options.signal?.aborted) {
|
|
95
|
+
throw createAbortError(`${PI_PROVIDER} exec cancelled by client`, options.signal.reason);
|
|
96
|
+
}
|
|
97
97
|
// Empty bodies retain the SDK's default ResourceLoader path unchanged.
|
|
98
98
|
const created = await sdk.createAgentSession({
|
|
99
99
|
cwd,
|
|
100
100
|
sessionManager,
|
|
101
101
|
...(options.thinkingLevel ? { thinkingLevel: toPiSdkThinkingLevel(options.thinkingLevel) } : {}),
|
|
102
|
-
...(model ? { model,
|
|
102
|
+
...(model ? { model, modelRuntime } : {}),
|
|
103
103
|
...(resourceLoader ? { resourceLoader } : {}),
|
|
104
104
|
});
|
|
105
105
|
const session = created.session;
|
|
@@ -131,6 +131,7 @@ export async function startPi(prompt, cwd, options = {}) {
|
|
|
131
131
|
resolveRunSettled = resolve;
|
|
132
132
|
});
|
|
133
133
|
let activePrompt;
|
|
134
|
+
let activeState;
|
|
134
135
|
let abortRequested;
|
|
135
136
|
const requestAbort = async (state) => {
|
|
136
137
|
state.abortIntent = true;
|
|
@@ -159,13 +160,14 @@ export async function startPi(prompt, cwd, options = {}) {
|
|
|
159
160
|
enqueue: checkpointController.enqueue,
|
|
160
161
|
onIngress: options.onIngress,
|
|
161
162
|
async abort(mode) {
|
|
163
|
+
const state = activeState ?? { abortIntent: true, settled: false };
|
|
162
164
|
if (mode !== "force") {
|
|
163
|
-
await requestAbort(
|
|
165
|
+
await requestAbort(state);
|
|
164
166
|
return;
|
|
165
167
|
}
|
|
166
168
|
let failure;
|
|
167
169
|
try {
|
|
168
|
-
await requestAbort(
|
|
170
|
+
await requestAbort(state);
|
|
169
171
|
}
|
|
170
172
|
catch (error) {
|
|
171
173
|
failure = error;
|
|
@@ -196,6 +198,7 @@ export async function startPi(prompt, cwd, options = {}) {
|
|
|
196
198
|
assistantMessageOrdinal: -1,
|
|
197
199
|
activityCalls: new Map(),
|
|
198
200
|
};
|
|
201
|
+
activeState = state;
|
|
199
202
|
let settleOutcome;
|
|
200
203
|
const outcome = new Promise((resolve, reject) => {
|
|
201
204
|
settleOutcome = {
|
|
@@ -250,6 +253,7 @@ export async function startPi(prompt, cwd, options = {}) {
|
|
|
250
253
|
throw error;
|
|
251
254
|
}
|
|
252
255
|
finally {
|
|
256
|
+
activeState = undefined;
|
|
253
257
|
builder.signal.removeEventListener("abort", onAbort);
|
|
254
258
|
options.signal?.removeEventListener("abort", onAbort);
|
|
255
259
|
await abortRequested?.catch(() => undefined);
|
|
@@ -263,6 +267,8 @@ export async function startPi(prompt, cwd, options = {}) {
|
|
|
263
267
|
},
|
|
264
268
|
});
|
|
265
269
|
}
|
|
270
|
+
// Compiler-level binding to the named ProviderAdapter function contract.
|
|
271
|
+
startPi;
|
|
266
272
|
function readSessionManager(sdk) {
|
|
267
273
|
const store = sdk[`Session${"Man"}${"ager"}`];
|
|
268
274
|
return store;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { providerCommonFields, providerEnvSchema, } from "../../../config/settings/provider-instance-fields.js";
|
|
3
|
+
import { FlowError } from "../../../flow-error.js";
|
|
4
|
+
import { exactKeys, optionalString, optionalStringRecord, } from "../../launch-snapshot/parse-helpers.js";
|
|
5
|
+
import { SUBAGENT_SESSION_VERSION, subagentSessionEnvelopeSchema, } from "../../session.js";
|
|
6
|
+
import { PI_PROVIDER } from "./checkpoint.js";
|
|
7
|
+
import { piSessionSchema } from "./session-schema.js";
|
|
8
|
+
const startPi = async (prompt, cwd, options) => {
|
|
9
|
+
const { startPi: start } = await import("./adapter.js");
|
|
10
|
+
return start(prompt, cwd, options);
|
|
11
|
+
};
|
|
12
|
+
function admitResumeShape(schema, session, resumePath) {
|
|
13
|
+
const envelopeResult = subagentSessionEnvelopeSchema.safeParse(session);
|
|
14
|
+
if (!envelopeResult.success) {
|
|
15
|
+
throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' includes an invalid session envelope.`);
|
|
16
|
+
}
|
|
17
|
+
if (session.provider !== PI_PROVIDER) {
|
|
18
|
+
throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' was created with provider '${session.provider}', but the selected subagent resolves to '${PI_PROVIDER}'. Cross-provider resume is not supported.`);
|
|
19
|
+
}
|
|
20
|
+
if (session.version !== SUBAGENT_SESSION_VERSION) {
|
|
21
|
+
throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' uses unsupported session version '${session.version}' for provider '${session.provider}'.`);
|
|
22
|
+
}
|
|
23
|
+
const shapeResult = schema.safeParse(session.handle);
|
|
24
|
+
if (!shapeResult.success) {
|
|
25
|
+
throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' includes an invalid session handle for provider '${session.provider}'.`);
|
|
26
|
+
}
|
|
27
|
+
return shapeResult.data;
|
|
28
|
+
}
|
|
29
|
+
export const piRegistration = {
|
|
30
|
+
name: PI_PROVIDER,
|
|
31
|
+
start: startPi,
|
|
32
|
+
sessionSchema: piSessionSchema,
|
|
33
|
+
effortField: "thinkingLevel",
|
|
34
|
+
instanceSchema: z
|
|
35
|
+
.object({
|
|
36
|
+
kind: z.literal(PI_PROVIDER),
|
|
37
|
+
...providerCommonFields,
|
|
38
|
+
env: providerEnvSchema,
|
|
39
|
+
})
|
|
40
|
+
.strict()
|
|
41
|
+
.superRefine((data, ctx) => {
|
|
42
|
+
if (data.env === undefined)
|
|
43
|
+
return;
|
|
44
|
+
if (Object.keys(data.env).length === 0)
|
|
45
|
+
return;
|
|
46
|
+
ctx.addIssue({
|
|
47
|
+
code: z.ZodIssueCode.custom,
|
|
48
|
+
path: ["env"],
|
|
49
|
+
message: `env injection not supported for provider ${PI_PROVIDER}`,
|
|
50
|
+
});
|
|
51
|
+
}),
|
|
52
|
+
builtinInstance: {
|
|
53
|
+
name: PI_PROVIDER,
|
|
54
|
+
source: "builtin",
|
|
55
|
+
instance: { kind: PI_PROVIDER },
|
|
56
|
+
},
|
|
57
|
+
portablePolicy: {
|
|
58
|
+
access: new Set(),
|
|
59
|
+
network: new Set(),
|
|
60
|
+
webSearch: new Set(),
|
|
61
|
+
},
|
|
62
|
+
maxCaptureChars: (config) => config.codex.execMaxCaptureChars,
|
|
63
|
+
buildCallTerms: ({ snapshot, baseTerms, body }) => {
|
|
64
|
+
const provider = snapshot.provider;
|
|
65
|
+
return {
|
|
66
|
+
...baseTerms,
|
|
67
|
+
provider: PI_PROVIDER,
|
|
68
|
+
...(provider.model !== undefined ? { model: provider.model } : {}),
|
|
69
|
+
...(provider.thinkingLevel !== undefined ? { thinkingLevel: provider.thinkingLevel } : {}),
|
|
70
|
+
appendSystemPromptOverride: body ? () => [body] : undefined,
|
|
71
|
+
onCheckpoint() { },
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
resolveLaunchProvider: ({ common, instance, model, effort }) => {
|
|
75
|
+
if (instance.kind !== PI_PROVIDER) {
|
|
76
|
+
throw new Error(`resolveLaunchProvider expected ${PI_PROVIDER}`);
|
|
77
|
+
}
|
|
78
|
+
const piInstance = instance;
|
|
79
|
+
return Object.freeze({
|
|
80
|
+
...common,
|
|
81
|
+
kind: PI_PROVIDER,
|
|
82
|
+
...(model !== undefined ? { model } : {}),
|
|
83
|
+
...(effort !== undefined ? { thinkingLevel: effort } : {}),
|
|
84
|
+
...(piInstance.env !== undefined ? { env: piInstance.env } : {}),
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
parseLaunchProvider: (provider, common) => {
|
|
88
|
+
exactKeys(provider, ["name", "source", "kind", "model", "thinkingLevel", "env"], "provider");
|
|
89
|
+
const model = optionalString(provider, "model", "provider");
|
|
90
|
+
const thinkingLevel = optionalString(provider, "thinkingLevel", "provider");
|
|
91
|
+
const env = optionalStringRecord(provider, "env");
|
|
92
|
+
return Object.freeze({
|
|
93
|
+
...common,
|
|
94
|
+
kind: PI_PROVIDER,
|
|
95
|
+
...(model !== undefined ? { model } : {}),
|
|
96
|
+
...(thinkingLevel !== undefined ? { thinkingLevel } : {}),
|
|
97
|
+
...(env !== undefined ? { env } : {}),
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
applyEffort: (provider, effort) => Object.freeze({ ...provider, thinkingLevel: effort }),
|
|
101
|
+
providerEffortAndModel: (provider) => {
|
|
102
|
+
const resolved = provider;
|
|
103
|
+
return { model: resolved.model, effort: resolved.thinkingLevel };
|
|
104
|
+
},
|
|
105
|
+
attachLoader: (terms, ports) => {
|
|
106
|
+
if (terms.provider !== PI_PROVIDER)
|
|
107
|
+
return terms;
|
|
108
|
+
const loader = ports.pi;
|
|
109
|
+
return loader ? { ...terms, loader } : terms;
|
|
110
|
+
},
|
|
111
|
+
nativePolicyOwnership: () => null,
|
|
112
|
+
startLive: async ({ terms, signal, reviveTerms, onSyncCheckpoint, onIngress }) => {
|
|
113
|
+
if (terms.provider !== PI_PROVIDER) {
|
|
114
|
+
throw new Error(`startLive expected ${PI_PROVIDER}`);
|
|
115
|
+
}
|
|
116
|
+
const piTerms = terms;
|
|
117
|
+
const { startPi: start } = await import("./adapter.js");
|
|
118
|
+
if (reviveTerms) {
|
|
119
|
+
const session = admitResumeShape(piSessionSchema, reviveTerms.session, reviveTerms.resumePath);
|
|
120
|
+
return start(piTerms.prompt, piTerms.workdir, {
|
|
121
|
+
model: piTerms.model,
|
|
122
|
+
thinkingLevel: piTerms.thinkingLevel,
|
|
123
|
+
signal,
|
|
124
|
+
sessionFile: session.sessionFile,
|
|
125
|
+
appendSystemPromptOverride: piTerms.appendSystemPromptOverride,
|
|
126
|
+
onSyncCheckpoint,
|
|
127
|
+
onEvidence: piTerms.onEvidence,
|
|
128
|
+
onIngress,
|
|
129
|
+
initialTurn: piTerms.initialTurn,
|
|
130
|
+
loader: piTerms.loader,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return start(piTerms.prompt, piTerms.workdir, {
|
|
134
|
+
model: piTerms.model,
|
|
135
|
+
thinkingLevel: piTerms.thinkingLevel,
|
|
136
|
+
signal,
|
|
137
|
+
appendSystemPromptOverride: piTerms.appendSystemPromptOverride,
|
|
138
|
+
onSyncCheckpoint,
|
|
139
|
+
onEvidence: piTerms.onEvidence,
|
|
140
|
+
onIngress,
|
|
141
|
+
initialTurn: piTerms.initialTurn,
|
|
142
|
+
loader: piTerms.loader,
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity helper that locks `Name` across name / instanceSchema / builtinInstance.
|
|
3
|
+
* `const Name` keeps the literal; a schema whose kind is not exactly that literal fails here.
|
|
4
|
+
*/
|
|
5
|
+
export function defineProviderRegistration(registration) {
|
|
6
|
+
return registration;
|
|
7
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { claudeAgentSdkRegistration } from "./claude-agent-sdk/registration.js";
|
|
3
|
+
import { codexAppServerRegistration } from "./codex-app-server/registration.js";
|
|
4
|
+
import { opencodeSdkRegistration } from "./opencode-sdk/registration.js";
|
|
5
|
+
import { piRegistration } from "./pi/registration.js";
|
|
6
|
+
/**
|
|
7
|
+
* Sole provider-vocabulary registration surface.
|
|
8
|
+
* Add/remove a live provider by editing that provider's directory and this list.
|
|
9
|
+
* Runtime tables, schemas, and builtin Akuma profiles are derived from the list.
|
|
10
|
+
*/
|
|
11
|
+
export const PROVIDER_REGISTRATIONS = [
|
|
12
|
+
codexAppServerRegistration,
|
|
13
|
+
claudeAgentSdkRegistration,
|
|
14
|
+
opencodeSdkRegistration,
|
|
15
|
+
piRegistration,
|
|
16
|
+
];
|
|
17
|
+
function nonEmptyProviderNames(registrations) {
|
|
18
|
+
if (registrations.length === 0) {
|
|
19
|
+
throw new Error("PROVIDER_REGISTRATIONS must not be empty");
|
|
20
|
+
}
|
|
21
|
+
return registrations.map((registration) => registration.name);
|
|
22
|
+
}
|
|
23
|
+
export const SUBAGENT_PROVIDERS = nonEmptyProviderNames(PROVIDER_REGISTRATIONS);
|
|
24
|
+
const providerNameSet = new Set(SUBAGENT_PROVIDERS);
|
|
25
|
+
export function isSubagentProvider(value) {
|
|
26
|
+
return providerNameSet.has(value);
|
|
27
|
+
}
|
|
28
|
+
function indexByProviderName(pick) {
|
|
29
|
+
const out = {};
|
|
30
|
+
for (const registration of PROVIDER_REGISTRATIONS) {
|
|
31
|
+
out[registration.name] = pick(registration);
|
|
32
|
+
}
|
|
33
|
+
return Object.freeze(out);
|
|
34
|
+
}
|
|
35
|
+
const registrationByName = new Map(PROVIDER_REGISTRATIONS.map((registration) => [registration.name, registration]));
|
|
36
|
+
export function getProviderRegistration(name) {
|
|
37
|
+
const registration = registrationByName.get(name);
|
|
38
|
+
if (!registration) {
|
|
39
|
+
throw new Error(`Unknown provider '${name}'`);
|
|
40
|
+
}
|
|
41
|
+
return registration;
|
|
42
|
+
}
|
|
43
|
+
export const PROVIDER_REGISTRATION_BY_NAME = indexByProviderName((registration) => registration);
|
|
44
|
+
export const BUILTIN_PROVIDER_INSTANCE_CANDIDATES = indexByProviderName((registration) => ({
|
|
45
|
+
name: registration.name,
|
|
46
|
+
source: "builtin",
|
|
47
|
+
instance: registration.builtinInstance.instance,
|
|
48
|
+
}));
|
|
49
|
+
export const PROVIDER_PORTABLE_POLICY = indexByProviderName((registration) => registration.portablePolicy);
|
|
50
|
+
/**
|
|
51
|
+
* Closed provider-instance schema derived solely from PROVIDER_REGISTRATIONS.
|
|
52
|
+
* Each contribution's instanceSchema is a kind-literal object schema (possibly
|
|
53
|
+
* refined); Zod's discriminable marker is erased by ProviderInstanceSchema, so
|
|
54
|
+
* the non-empty tuple assertion restores only that structural requirement.
|
|
55
|
+
*/
|
|
56
|
+
export const providerInstanceSchema = z.discriminatedUnion("kind", (() => {
|
|
57
|
+
const schemas = PROVIDER_REGISTRATIONS.map((registration) => registration.instanceSchema);
|
|
58
|
+
if (schemas.length === 0) {
|
|
59
|
+
throw new Error("PROVIDER_REGISTRATIONS must not be empty");
|
|
60
|
+
}
|
|
61
|
+
return schemas;
|
|
62
|
+
})());
|
|
63
|
+
/** Product builtin Akuma profiles contributed by registrations. */
|
|
64
|
+
export const BUILTIN_AGENT_PROFILES = Object.freeze(Object.fromEntries(PROVIDER_REGISTRATIONS.flatMap((registration) => {
|
|
65
|
+
const open = registration;
|
|
66
|
+
const profiles = open.builtinAkumaProfiles ?? [];
|
|
67
|
+
return profiles.map((profile) => [
|
|
68
|
+
profile.name,
|
|
69
|
+
Object.freeze({
|
|
70
|
+
provider: registration.name,
|
|
71
|
+
description: profile.description,
|
|
72
|
+
}),
|
|
73
|
+
]);
|
|
74
|
+
})));
|
|
75
|
+
export const BUILTIN_AGENT_NAMES = Object.freeze(Object.keys(BUILTIN_AGENT_PROFILES));
|
|
76
|
+
export { defineProviderRegistration } from "./registration.js";
|
package/build/agents/selector.js
CHANGED
|
@@ -5,35 +5,8 @@ import { resolveDefaultAgentName } from "../config/settings/knobs.js";
|
|
|
5
5
|
import { loadKeiyakuSettings } from "../config/settings/loader.js";
|
|
6
6
|
import { nativePolicyOwnership } from "../config/provider-policy-ownership.js";
|
|
7
7
|
import { FlowError } from "../flow-error.js";
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const SUPPORTED_EXPLICIT = {
|
|
11
|
-
"codex-sdk": {
|
|
12
|
-
access: new Set(ACCESS_VALUES),
|
|
13
|
-
network: new Set(NETWORK_VALUES),
|
|
14
|
-
webSearch: new Set(["disabled", "cached", "live"]),
|
|
15
|
-
},
|
|
16
|
-
"codex-app-server": {
|
|
17
|
-
access: new Set(["write"]),
|
|
18
|
-
network: new Set(NETWORK_VALUES),
|
|
19
|
-
webSearch: new Set(),
|
|
20
|
-
},
|
|
21
|
-
"claude-agent-sdk": {
|
|
22
|
-
access: new Set(ACCESS_VALUES),
|
|
23
|
-
network: new Set(),
|
|
24
|
-
webSearch: new Set(["disabled"]),
|
|
25
|
-
},
|
|
26
|
-
"opencode-sdk": {
|
|
27
|
-
access: new Set(),
|
|
28
|
-
network: new Set(),
|
|
29
|
-
webSearch: new Set(),
|
|
30
|
-
},
|
|
31
|
-
pi: {
|
|
32
|
-
access: new Set(),
|
|
33
|
-
network: new Set(),
|
|
34
|
-
webSearch: new Set(),
|
|
35
|
-
},
|
|
36
|
-
};
|
|
8
|
+
import { PROVIDER_PORTABLE_POLICY } from "./providers/registry.js";
|
|
9
|
+
const SUPPORTED_EXPLICIT = PROVIDER_PORTABLE_POLICY;
|
|
37
10
|
export function formatAvailableAgentNames(names) {
|
|
38
11
|
if (names.length === 0)
|
|
39
12
|
return "(none configured)";
|
package/build/agents/types.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
export const SUBAGENT_FAILURE_CODES = [
|
|
2
|
+
"SUBAGENT_TIMEOUT",
|
|
3
|
+
"SUBAGENT_NON_ZERO_EXIT",
|
|
4
|
+
"SUBAGENT_SPAWN_ERROR",
|
|
5
|
+
"SUBAGENT_EXEC_ERROR",
|
|
6
|
+
"SUBAGENT_PROVIDER_UNAVAILABLE",
|
|
7
|
+
];
|
|
8
|
+
export const OUTCOME_ERROR_VERSION = 1;
|
|
1
9
|
export class SubagentFailure extends Error {
|
|
2
10
|
code;
|
|
3
11
|
timeoutMs;
|