@astrosheep/keiyaku 4.6.7 → 4.6.9
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 +46 -16
- package/build/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/build/plugins/claude/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/claude/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/claude/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/build/plugins/codex/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/codex/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/opencode/index.js +1 -1
- package/build/plugins/opencode/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/opencode/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/pi/keiyaku.ts +0 -5
- package/build/skills/keiyaku/SKILL.md +5 -6
- package/build/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/src/akuma/akuma-call.d.ts +2 -0
- package/build/src/akuma/akuma-call.js +8 -2
- package/build/src/akuma/akuma-instance.d.ts +14 -1
- package/build/src/akuma/akuma-instance.js +37 -7
- package/build/src/akuma/akuma-observe.d.ts +33 -8
- package/build/src/akuma/akuma-observe.js +89 -63
- package/build/src/akuma/akuma-owner.d.ts +14 -2
- package/build/src/akuma/akuma-owner.js +49 -35
- package/build/src/akuma/akuma-selection-execution.js +9 -1
- package/build/src/akuma/akuma-stream.d.ts +22 -0
- package/build/src/akuma/akuma-stream.js +116 -0
- package/build/src/akuma/akuma-wait.d.ts +1 -40
- package/build/src/akuma/akuma-wait.js +23 -84
- package/build/src/akuma/akuma.d.ts +52 -16
- package/build/src/akuma/akuma.js +10 -10
- package/build/src/akuma/allowed.d.ts +7 -12
- package/build/src/akuma/allowed.js +13 -4
- package/build/src/akuma/archetype.d.ts +7 -15
- package/build/src/akuma/archetype.js +36 -35
- package/build/src/akuma/body-supervisor.d.ts +5 -5
- package/build/src/akuma/body-supervisor.js +22 -20
- package/build/src/akuma/body.d.ts +5 -3
- package/build/src/akuma/body.js +57 -8
- package/build/src/akuma/call-request.d.ts +30 -32
- package/build/src/akuma/call-request.js +10 -3
- package/build/src/akuma/caller.d.ts +39 -0
- package/build/src/akuma/caller.js +36 -0
- package/build/src/akuma/dispatch-association.d.ts +0 -1
- package/build/src/akuma/dispatch-association.js +0 -3
- package/build/src/akuma/heart/activity-schema.d.ts +12 -0
- package/build/src/akuma/heart/activity-schema.js +6 -0
- package/build/src/akuma/heart/facts.d.ts +16 -12
- package/build/src/akuma/heart/facts.js +8 -0
- package/build/src/akuma/heart/index.d.ts +61 -9
- package/build/src/akuma/heart/index.js +89 -24
- package/build/src/akuma/heart/rows.d.ts +3 -3
- package/build/src/akuma/heart/rows.js +5 -3
- package/build/src/akuma/heart/soul.d.ts +10 -1
- package/build/src/akuma/heart/soul.js +34 -24
- package/build/src/akuma/heart/storage.d.ts +20 -0
- package/build/src/akuma/heart/storage.js +62 -3
- package/build/src/akuma/heart/timeline.d.ts +7 -0
- package/build/src/akuma/heart/timeline.js +10 -0
- package/build/src/akuma/identity.d.ts +0 -1
- package/build/src/akuma/identity.js +2 -5
- package/build/src/akuma/index.d.ts +6 -2
- package/build/src/akuma/index.js +1 -0
- package/build/src/akuma/nuke.js +6 -28
- package/build/src/akuma/projection.d.ts +25 -11
- package/build/src/akuma/projection.js +24 -7
- package/build/src/akuma/provider-recipe.d.ts +18 -6
- package/build/src/akuma/provider-recipe.js +24 -1
- package/build/src/akuma/provider.d.ts +31 -10
- package/build/src/akuma/provider.js +105 -14
- package/build/src/akuma/providers/acp/events.js +29 -19
- package/build/src/akuma/providers/acp/index.js +2 -3
- package/build/src/akuma/providers/claude/events.js +110 -69
- package/build/src/akuma/providers/claude/index.d.ts +2 -2
- package/build/src/akuma/providers/claude/index.js +4 -8
- package/build/src/akuma/providers/codex-app-server/events.js +17 -2
- package/build/src/akuma/providers/codex-app-server/index.js +17 -11
- package/build/src/akuma/providers/decode.d.ts +33 -0
- package/build/src/akuma/providers/decode.js +65 -0
- package/build/src/akuma/providers/execution-environment.d.ts +2 -1
- package/build/src/akuma/providers/execution-environment.js +3 -0
- package/build/src/akuma/providers/grok-build/index.js +16 -48
- package/build/src/akuma/providers/index.js +2 -0
- package/build/src/akuma/providers/lifecycle.d.ts +9 -0
- package/build/src/akuma/providers/lifecycle.js +10 -0
- package/build/src/akuma/providers/opencode-sdk/event-stream.d.ts +3 -3
- package/build/src/akuma/providers/opencode-sdk/event-stream.js +2 -25
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +7 -43
- package/build/src/akuma/providers/opencode-sdk/events.js +146 -296
- package/build/src/akuma/providers/opencode-sdk/index.js +270 -431
- package/build/src/akuma/providers/opencode-sdk/native-http.d.ts +9 -0
- package/build/src/akuma/providers/opencode-sdk/native-http.js +69 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +42 -36
- package/build/src/akuma/providers/opencode-sdk/session.js +75 -84
- package/build/src/akuma/providers/paseo/events.d.ts +33 -0
- package/build/src/akuma/providers/paseo/events.js +204 -0
- package/build/src/akuma/providers/paseo/index.d.ts +9 -0
- package/build/src/akuma/providers/paseo/index.js +357 -0
- package/build/src/akuma/providers/pi/events.d.ts +2 -0
- package/build/src/akuma/providers/pi/events.js +36 -38
- package/build/src/akuma/providers/pi/index.js +21 -35
- package/build/src/akuma/publication.d.ts +2 -0
- package/build/src/akuma/publication.js +5 -0
- package/build/src/akuma/request-lifecycle.d.ts +4 -2
- package/build/src/akuma/request-lifecycle.js +27 -12
- package/build/src/akuma/request-rendezvous.js +38 -55
- package/build/src/akuma/request-serve.d.ts +1 -1
- package/build/src/akuma/request-serve.js +77 -113
- package/build/src/akuma/requests.d.ts +3 -1
- package/build/src/akuma/requests.js +32 -0
- package/build/src/akuma/selection-observation.d.ts +129 -53
- package/build/src/akuma/selection-observation.js +3 -9
- package/build/src/akuma/turn-drive.d.ts +3 -0
- package/build/src/akuma/turn-drive.js +28 -10
- package/build/src/akuma-body.js +12 -22
- package/build/src/cli/akuma-caller.d.ts +3 -0
- package/build/src/cli/akuma-caller.js +31 -0
- package/build/src/cli/commands/akuma-grammar.js +10 -16
- package/build/src/cli/commands/akuma.js +25 -55
- package/build/src/cli/commands/contract-grammar.d.ts +9 -7
- package/build/src/cli/commands/contract-grammar.js +40 -47
- package/build/src/cli/commands/contract-help.d.ts +17 -7
- package/build/src/cli/commands/contract-help.js +50 -11
- package/build/src/cli/commands/contract.js +34 -63
- package/build/src/cli/commands/debt-grammar.d.ts +19 -0
- package/build/src/cli/commands/debt-grammar.js +323 -0
- package/build/src/cli/commands/debt-query.d.ts +5 -0
- package/build/src/cli/commands/{task-query.js → debt-query.js} +9 -9
- package/build/src/cli/commands/{task.d.ts → debt.d.ts} +2 -2
- package/build/src/cli/commands/{task.js → debt.js} +87 -164
- package/build/src/cli/coordinates.d.ts +1 -1
- package/build/src/cli/coordinates.js +1 -1
- package/build/src/cli/parse.d.ts +5 -5
- package/build/src/cli/parse.js +17 -16
- package/build/src/cli/render/akuma-activity.d.ts +11 -83
- package/build/src/cli/render/akuma-activity.js +20 -382
- package/build/src/cli/render/catalog.d.ts +4 -7
- package/build/src/cli/render/catalog.js +5 -5
- package/build/src/cli/render/contract-history.js +3 -6
- package/build/src/cli/render/contract.js +17 -52
- package/build/src/cli/render/debt.d.ts +28 -0
- package/build/src/cli/render/{task.js → debt.js} +55 -133
- package/build/src/cli/render/kanshi.js +28 -28
- package/build/src/cli/render/marks.d.ts +5 -5
- package/build/src/cli/render/marks.js +4 -10
- package/build/src/cli/render/nuke.js +1 -1
- package/build/src/cli/render/receipt.js +3 -10
- package/build/src/cli/runtime.d.ts +1 -1
- package/build/src/cli/runtime.js +14 -20
- package/build/src/cli/scan.d.ts +1 -1
- package/build/src/cli/selectors.d.ts +3 -6
- package/build/src/cli/selectors.js +22 -53
- package/build/src/cli/usage.d.ts +1 -1
- package/build/src/cli/usage.js +4 -4
- package/build/src/contract-worktree.js +3 -3
- package/build/src/debt/board.d.ts +160 -0
- package/build/src/{task → debt}/board.js +89 -89
- package/build/src/debt/catalog.d.ts +11 -0
- package/build/src/debt/catalog.js +59 -0
- package/build/src/{task → debt}/context.d.ts +1 -1
- package/build/src/{task → debt}/context.js +1 -1
- package/build/src/{task → debt}/created-observation.d.ts +6 -10
- package/build/src/{task → debt}/created-observation.js +7 -7
- package/build/src/debt/document.d.ts +37 -0
- package/build/src/{task → debt}/document.js +37 -37
- package/build/src/debt/identity.d.ts +21 -0
- package/build/src/{task → debt}/identity.js +35 -35
- package/build/src/debt/index.d.ts +111 -0
- package/build/src/debt/index.js +203 -0
- package/build/src/{task → debt}/input.d.ts +8 -8
- package/build/src/{task → debt}/input.js +21 -21
- package/build/src/debt/lifecycle-operations.d.ts +6 -0
- package/build/src/{task → debt}/lifecycle-operations.js +27 -31
- package/build/src/debt/mutation-result.d.ts +981 -0
- package/build/src/debt/mutation-result.js +109 -0
- package/build/src/debt/mutation.d.ts +424 -0
- package/build/src/debt/mutation.js +223 -0
- package/build/src/debt/operation-types.d.ts +71 -0
- package/build/src/debt/operations.d.ts +28 -0
- package/build/src/{task → debt}/operations.js +59 -60
- package/build/src/debt/query.d.ts +76 -0
- package/build/src/{task → debt}/query.js +55 -55
- package/build/src/{task → debt}/store.d.ts +13 -13
- package/build/src/{task → debt}/store.js +58 -49
- package/build/src/debt/view.d.ts +4 -0
- package/build/src/debt/view.js +7 -0
- package/build/src/dispatch/index.d.ts +3 -3
- package/build/src/dispatch/index.js +1 -2
- package/build/src/git/observe.d.ts +6 -2
- package/build/src/git/observe.js +6 -2
- package/build/src/identity/coordinates.d.ts +1 -1
- package/build/src/index.d.ts +17 -17
- package/build/src/index.js +11 -11
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/read.js +54 -39
- package/build/src/kanshi/report.d.ts +7 -7
- package/build/src/kanshi/select.js +4 -4
- package/build/src/library/address.js +2 -4
- package/build/src/library/akuma-creation.d.ts +5 -1
- package/build/src/library/akuma-creation.js +27 -47
- package/build/src/library/akumas.d.ts +7 -7
- package/build/src/library/akumas.js +13 -9
- package/build/src/library/bind.d.ts +17 -17
- package/build/src/library/bind.js +16 -12
- package/build/src/library/contract-address.d.ts +9 -0
- package/build/src/library/contract-address.js +71 -0
- package/build/src/library/contract-composition.d.ts +4 -7
- package/build/src/library/contract-composition.js +6 -18
- package/build/src/library/contract-creation.d.ts +3 -5
- package/build/src/library/contract-creation.js +24 -22
- package/build/src/library/contract-execution.js +21 -26
- package/build/src/library/contract-outcomes.d.ts +2 -14
- package/build/src/library/contract-outcomes.js +2 -13
- package/build/src/library/contract-types.d.ts +38 -4
- package/build/src/library/delivery.d.ts +0 -2
- package/build/src/library/delivery.js +2 -5
- package/build/src/library/input.d.ts +2 -2
- package/build/src/library/input.js +5 -5
- package/build/src/library/invocation.js +2 -2
- package/build/src/library/keiyaku.d.ts +0 -5
- package/build/src/library/keiyaku.js +6 -12
- package/build/src/library/nuke.js +3 -3
- package/build/src/library/outcome.d.ts +626 -625
- package/build/src/library/outcome.js +13 -3
- package/build/src/library/reconcile.js +8 -16
- package/build/src/library/refusal.d.ts +2 -2
- package/build/src/library/repo.d.ts +3 -2
- package/build/src/library/repo.js +10 -5
- package/build/src/library/selection.d.ts +5 -8
- package/build/src/library/selection.js +22 -73
- package/build/src/plugin/akuma-signals.d.ts +2 -0
- package/build/src/plugin/akuma-signals.js +4 -0
- package/build/src/plugin/public.d.ts +32 -2
- package/build/src/plugin/runtime.js +5 -3
- package/build/src/protocol/amend.js +3 -2
- package/build/src/protocol/attempt.js +3 -8
- package/build/src/protocol/bind.d.ts +2 -2
- package/build/src/protocol/bind.js +1 -1
- package/build/src/protocol/deliver.js +3 -3
- package/build/src/protocol/operations.d.ts +1 -3
- package/build/src/protocol/operations.js +0 -8
- package/build/src/protocol/outcome.d.ts +1 -2
- package/build/src/protocol/outcome.js +1 -13
- package/build/src/protocol/placement.js +3 -10
- package/build/src/protocol/read/status.js +31 -70
- package/build/src/protocol/reintegrate.js +3 -10
- package/build/src/protocol/review.js +3 -3
- package/build/src/protocol/run.d.ts +5 -1
- package/build/src/protocol/run.js +3 -3
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/fence.d.ts +3 -3
- package/build/src/settlement/fence.js +4 -4
- package/build/src/settlement/holder.d.ts +16 -16
- package/build/src/settlement/holder.js +69 -63
- package/build/src/settlement/settle.d.ts +5 -5
- package/build/src/settlement/settle.js +53 -53
- package/package.json +19 -9
- package/plugins/paseo/plugin/index.server.ts +17 -0
- package/plugins/paseo/plugin/paseo-plugin.json +4 -0
- package/plugins/paseo/plugin/server/attach.ts +52 -0
- package/plugins/paseo/plugin/server/keiyaku.ts +44 -0
- package/plugins/paseo/plugin/server/message.ts +60 -0
- package/plugins/paseo/plugin/server/mirror.ts +193 -0
- package/plugins/paseo/plugin/server/model.ts +14 -0
- package/plugins/paseo/plugin/server/provider.ts +276 -0
- package/plugins/paseo/plugin/server/sdk-worker.ts +237 -0
- package/plugins/paseo/plugin/server/sdk.ts +289 -0
- package/plugins/paseo/plugin/server/stop.ts +26 -0
- package/plugins/paseo/plugin/server/transport.ts +35 -0
- package/plugins/paseo/plugin/shared/attach-rpc.ts +10 -0
- package/plugins/paseo/plugin/shared/refresh-rpc.ts +6 -0
- package/plugins/paseo/plugin/tsconfig.json +6 -0
- package/plugins/pi/keiyaku.ts +57 -0
- package/skills/keiyaku/SKILL.md +43 -0
- package/skills/keiyaku-akuma/SKILL.md +130 -0
- package/skills/keiyaku-akuma/references/automation.md +269 -0
- package/skills/keiyaku-babysit/SKILL.md +65 -0
- package/skills/keiyaku-bind/SKILL.md +216 -0
- package/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/skills/keiyaku-debt/SKILL.md +91 -0
- package/skills/keiyaku-workflow/SKILL.md +129 -0
- package/build/plugins/claude/skills/keiyaku-task/SKILL.md +0 -104
- package/build/plugins/codex/skills/keiyaku-task/SKILL.md +0 -104
- package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +0 -104
- package/build/skills/keiyaku-task/SKILL.md +0 -104
- package/build/src/cli/commands/amend.d.ts +0 -12
- package/build/src/cli/commands/amend.js +0 -10
- package/build/src/cli/commands/bind.d.ts +0 -11
- package/build/src/cli/commands/bind.js +0 -23
- package/build/src/cli/commands/task-grammar.d.ts +0 -19
- package/build/src/cli/commands/task-grammar.js +0 -384
- package/build/src/cli/commands/task-query.d.ts +0 -5
- package/build/src/cli/render/task.d.ts +0 -41
- package/build/src/dispatch/association.d.ts +0 -1
- package/build/src/dispatch/association.js +0 -1
- package/build/src/task/board.d.ts +0 -168
- package/build/src/task/catalog.d.ts +0 -11
- package/build/src/task/catalog.js +0 -59
- package/build/src/task/compose-language.d.ts +0 -57
- package/build/src/task/compose-language.js +0 -364
- package/build/src/task/compose-parser.d.ts +0 -32
- package/build/src/task/compose-parser.js +0 -180
- package/build/src/task/compose.d.ts +0 -16
- package/build/src/task/compose.js +0 -189
- package/build/src/task/document.d.ts +0 -39
- package/build/src/task/identity.d.ts +0 -21
- package/build/src/task/index.d.ts +0 -138
- package/build/src/task/index.js +0 -269
- package/build/src/task/lifecycle-operations.d.ts +0 -6
- package/build/src/task/mutation-result.d.ts +0 -1726
- package/build/src/task/mutation-result.js +0 -198
- package/build/src/task/mutation.d.ts +0 -590
- package/build/src/task/mutation.js +0 -262
- package/build/src/task/operation-types.d.ts +0 -71
- package/build/src/task/operations.d.ts +0 -28
- package/build/src/task/query.d.ts +0 -76
- package/build/src/task/view.d.ts +0 -4
- package/build/src/task/view.js +0 -7
- /package/build/src/{task → debt}/operation-types.js +0 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { isAbsolute, resolve } from "node:path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
// Pinned vendor CLI entry: the public SDK does not expose cancellation or selectors.
|
|
5
|
+
import { DaemonClient } from "@getpaseo/client/internal/daemon-client";
|
|
6
|
+
import { bindWsHandler, createWebSocketTransportFactory, defaultWebSocketFactory, } from "@getpaseo/client/internal/daemon-client-websocket-transport";
|
|
7
|
+
import { abortable } from "../../abort.js";
|
|
8
|
+
import { launchPrompt, modelEvent, } from "../../provider.js";
|
|
9
|
+
import { AKUMA_REQUESTS_ENTRY_ENV, akumaExecutionEnvironment } from "../execution-environment.js";
|
|
10
|
+
import { PaseoTurn, paseoRuntimeModel } from "./events.js";
|
|
11
|
+
import { providerLifecycle } from "../lifecycle.js";
|
|
12
|
+
const configSchema = z
|
|
13
|
+
.object({
|
|
14
|
+
url: z.string().default("ws://127.0.0.1:6767/ws"),
|
|
15
|
+
provider: z.string().trim().min(1).default("claude"),
|
|
16
|
+
})
|
|
17
|
+
.strict();
|
|
18
|
+
function failures(errors, message) {
|
|
19
|
+
if (errors.length === 1)
|
|
20
|
+
throw errors[0];
|
|
21
|
+
if (errors.length > 1)
|
|
22
|
+
throw new AggregateError(errors, message);
|
|
23
|
+
}
|
|
24
|
+
/** Native disposal forgets sockets before their close event and swallows close errors. */
|
|
25
|
+
class PaseoSockets {
|
|
26
|
+
retiring = false;
|
|
27
|
+
errors = [];
|
|
28
|
+
sockets = [];
|
|
29
|
+
factory = (options) => {
|
|
30
|
+
if (this.retiring)
|
|
31
|
+
throw new Error("Paseo socket custody retired");
|
|
32
|
+
const native = createWebSocketTransportFactory((url, settings) => {
|
|
33
|
+
if (this.retiring)
|
|
34
|
+
throw new Error("Paseo socket custody retired");
|
|
35
|
+
const socket = defaultWebSocketFactory(url, settings);
|
|
36
|
+
let proveClosed;
|
|
37
|
+
const closed = new Promise((resolve) => {
|
|
38
|
+
proveClosed = resolve;
|
|
39
|
+
});
|
|
40
|
+
const owned = { socket, closed, observed: false };
|
|
41
|
+
const remove = bindWsHandler(socket, "close", () => {
|
|
42
|
+
owned.observed = true;
|
|
43
|
+
remove();
|
|
44
|
+
proveClosed();
|
|
45
|
+
});
|
|
46
|
+
this.sockets.push(owned);
|
|
47
|
+
return socket;
|
|
48
|
+
})(options);
|
|
49
|
+
return {
|
|
50
|
+
...native,
|
|
51
|
+
close: (code, reason) => {
|
|
52
|
+
try {
|
|
53
|
+
native.close(code, reason);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.errors.push(error);
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
async retire(client) {
|
|
63
|
+
this.retiring = true;
|
|
64
|
+
// Begin logical retirement, but independently close saved sockets even if
|
|
65
|
+
// native disposal already forgot one after a rejected close code (1001).
|
|
66
|
+
const logical = (async () => {
|
|
67
|
+
try {
|
|
68
|
+
await client.close();
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
this.errors.push(error);
|
|
72
|
+
}
|
|
73
|
+
})();
|
|
74
|
+
const physical = [];
|
|
75
|
+
for (const owned of this.sockets) {
|
|
76
|
+
try {
|
|
77
|
+
if (!owned.observed)
|
|
78
|
+
owned.socket.close(1000, "Paseo adapter retired");
|
|
79
|
+
physical.push(owned.closed);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
this.errors.push(error);
|
|
83
|
+
// No success proof for this socket; the Body's existing custody policy
|
|
84
|
+
// receives unsuccessful closure rather than a fabricated close event.
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
await Promise.all([logical, ...physical]);
|
|
88
|
+
failures(this.errors, "Paseo client/socket retirement failed");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** Check before invoking native work, not only after creating its promise. */
|
|
92
|
+
async function setup(signal, operation) {
|
|
93
|
+
signal.throwIfAborted();
|
|
94
|
+
const result = await abortable(operation(), signal);
|
|
95
|
+
signal.throwIfAborted();
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
function configuration(execution) {
|
|
99
|
+
if (execution.executable !== undefined)
|
|
100
|
+
throw new TypeError("Paseo connects to a local daemon, not an executable");
|
|
101
|
+
const parsed = configSchema.safeParse(execution.config ?? {});
|
|
102
|
+
if (!parsed.success)
|
|
103
|
+
throw new TypeError(`Paseo configuration: ${parsed.error.issues[0]?.message}`, { cause: parsed.error });
|
|
104
|
+
const config = parsed.data;
|
|
105
|
+
const url = new URL(config.url);
|
|
106
|
+
if (!["ws:", "wss:"].includes(url.protocol) ||
|
|
107
|
+
!["127.0.0.1", "localhost", "[::1]"].includes(url.hostname) ||
|
|
108
|
+
url.pathname !== "/ws" ||
|
|
109
|
+
url.username !== "" ||
|
|
110
|
+
url.password !== "" ||
|
|
111
|
+
url.search !== "" ||
|
|
112
|
+
url.hash !== "") {
|
|
113
|
+
throw new TypeError("Paseo url must be a loopback WebSocket endpoint ending in /ws");
|
|
114
|
+
}
|
|
115
|
+
if (config.provider.includes("/"))
|
|
116
|
+
throw new TypeError("Paseo provider must be a bare native provider id; use the model option separately");
|
|
117
|
+
return config;
|
|
118
|
+
}
|
|
119
|
+
function optionAdmission(options) {
|
|
120
|
+
if (options.network !== undefined)
|
|
121
|
+
return { kind: "refused", diagnostic: "Paseo does not support the network option" };
|
|
122
|
+
if (options.systemPromptMode === "replace")
|
|
123
|
+
return { kind: "refused", diagnostic: "Paseo does not support systemPrompt replacement" };
|
|
124
|
+
return { kind: "admitted", options };
|
|
125
|
+
}
|
|
126
|
+
function usable(agent, input, config) {
|
|
127
|
+
if (agent.archivedAt != null || agent.providerUnavailable || agent.status === "closed")
|
|
128
|
+
throw new Error(`Paseo agent ${agent.id} is unavailable`);
|
|
129
|
+
if (agent.cwd !== input.cwd || agent.provider !== config.provider)
|
|
130
|
+
throw new Error(`Paseo agent ${agent.id} no longer matches its execution recipe`);
|
|
131
|
+
if (agent.activeTurn != null || agent.status === "running" || agent.status === "initializing")
|
|
132
|
+
throw new Error(`Paseo agent ${agent.id} is busy; refusing to submit into another native execution`);
|
|
133
|
+
}
|
|
134
|
+
async function offeredModel(client, agent, input, config) {
|
|
135
|
+
const { model, effort } = input.options;
|
|
136
|
+
if (model === undefined && effort === undefined)
|
|
137
|
+
return undefined;
|
|
138
|
+
const catalog = await setup(input.signal, () => client.listProviderModels(config.provider, { cwd: input.cwd }));
|
|
139
|
+
if (catalog.error != null)
|
|
140
|
+
throw new Error(`Paseo selector catalog unavailable: ${catalog.error}`);
|
|
141
|
+
const requested = model ?? agent.runtimeInfo?.model ?? agent.model;
|
|
142
|
+
const selected = catalog.models?.find((choice) => choice.isSelectable !== false &&
|
|
143
|
+
(requested == null ? choice.isDefault : choice.id === requested || choice.aliases?.includes(requested)));
|
|
144
|
+
if (selected === undefined)
|
|
145
|
+
throw new Error(`Paseo model is not available: ${requested ?? "native default"}`);
|
|
146
|
+
if (effort !== undefined && !selected.thinkingOptions?.some((choice) => choice.id === effort)) {
|
|
147
|
+
throw new Error(`Paseo effort is not available for ${selected.id}: ${effort}`);
|
|
148
|
+
}
|
|
149
|
+
return model === undefined ? undefined : selected.id;
|
|
150
|
+
}
|
|
151
|
+
async function applyOptions(client, agent, input, config) {
|
|
152
|
+
usable(agent, input, config);
|
|
153
|
+
const model = await offeredModel(client, agent, input, config);
|
|
154
|
+
const { effort } = input.options;
|
|
155
|
+
if (model !== undefined)
|
|
156
|
+
await setup(input.signal, () => client.setAgentModel(agent.id, model));
|
|
157
|
+
if (effort !== undefined) {
|
|
158
|
+
const notice = await setup(input.signal, () => client.setAgentThinkingOption(agent.id, effort));
|
|
159
|
+
if (notice?.type === "error")
|
|
160
|
+
throw new Error(`Paseo effort refused: ${notice.message}`);
|
|
161
|
+
}
|
|
162
|
+
const observed = await setup(input.signal, () => client.fetchAgent(agent.id));
|
|
163
|
+
if (observed === null)
|
|
164
|
+
throw new Error(`Paseo agent ${agent.id} is unavailable`);
|
|
165
|
+
usable(observed.agent, input, config);
|
|
166
|
+
if (model !== undefined && (observed.agent.runtimeInfo?.model ?? observed.agent.model) !== model) {
|
|
167
|
+
throw new Error(`Paseo model selection was not confirmed: ${model}`);
|
|
168
|
+
}
|
|
169
|
+
if (effort !== undefined &&
|
|
170
|
+
(observed.agent.effectiveThinkingOptionId ?? observed.agent.runtimeInfo?.thinkingOptionId) !== effort) {
|
|
171
|
+
throw new Error(`Paseo effort selection was not confirmed: ${effort}`);
|
|
172
|
+
}
|
|
173
|
+
// The runtime's own answer names the model this agent will run, whether or
|
|
174
|
+
// not the caller requested one. The snapshot's top-level model may be a
|
|
175
|
+
// configured fallback rather than what the runtime loaded, so it is never
|
|
176
|
+
// runtime evidence; an unnamed runtime stays unknown and clears nothing.
|
|
177
|
+
return paseoRuntimeModel(observed.agent.runtimeInfo);
|
|
178
|
+
}
|
|
179
|
+
class PaseoDrive {
|
|
180
|
+
client;
|
|
181
|
+
environment;
|
|
182
|
+
sockets;
|
|
183
|
+
closed;
|
|
184
|
+
turn = new PaseoTurn(randomUUID());
|
|
185
|
+
proveClosed;
|
|
186
|
+
failClosed;
|
|
187
|
+
closure;
|
|
188
|
+
removeConnectionListener = () => undefined;
|
|
189
|
+
agentId;
|
|
190
|
+
submitted = false;
|
|
191
|
+
sequence;
|
|
192
|
+
epoch;
|
|
193
|
+
constructor(client, custody, environment, sockets) {
|
|
194
|
+
this.client = client;
|
|
195
|
+
this.environment = environment;
|
|
196
|
+
this.sockets = sockets;
|
|
197
|
+
this.closed = new Promise((resolve, reject) => {
|
|
198
|
+
this.proveClosed = resolve;
|
|
199
|
+
this.failClosed = reject;
|
|
200
|
+
});
|
|
201
|
+
custody.own({ closed: this.closed, abort: () => this.retire(true), forceDispose: () => this.retire(true) });
|
|
202
|
+
this.removeConnectionListener = client.subscribeConnectionStatus((state) => {
|
|
203
|
+
if (this.closure !== undefined)
|
|
204
|
+
return;
|
|
205
|
+
if (state.status === "disconnected" || state.status === "disposed")
|
|
206
|
+
this.turn.fail(new Error("Paseo connection lost before own turn completion"));
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
async establish(input, config, coordinate) {
|
|
210
|
+
const entry = input.requests.entry;
|
|
211
|
+
if (entry === undefined || !isAbsolute(entry) || resolve(entry) !== entry)
|
|
212
|
+
throw new Error("Paseo requires the Body's stable request entry");
|
|
213
|
+
input.signal.throwIfAborted();
|
|
214
|
+
await setup(input.signal, () => this.client.connect());
|
|
215
|
+
const agent = coordinate === undefined
|
|
216
|
+
? await setup(input.signal, () => this.client.createAgent({
|
|
217
|
+
provider: config.provider,
|
|
218
|
+
cwd: input.cwd,
|
|
219
|
+
...(input.options.systemPrompt === undefined ? {} : { systemPrompt: input.options.systemPrompt }),
|
|
220
|
+
env: { ...akumaExecutionEnvironment(process.env, this.environment), [AKUMA_REQUESTS_ENTRY_ENV]: entry },
|
|
221
|
+
autoArchive: false,
|
|
222
|
+
}))
|
|
223
|
+
: await this.existingAgent(coordinate, input.signal);
|
|
224
|
+
this.agentId = agent.id;
|
|
225
|
+
const startupModel = await applyOptions(this.client, agent, input, config);
|
|
226
|
+
input.signal.throwIfAborted();
|
|
227
|
+
const subscription = this.client.subscribeAgentTimeline(agent.id, (message) => this.receive(message));
|
|
228
|
+
await abortable(subscription.ready, input.signal);
|
|
229
|
+
this.turn.events.emit({ type: "session", coordinate: { sessionId: agent.id } });
|
|
230
|
+
if (startupModel !== undefined)
|
|
231
|
+
this.turn.events.emit(modelEvent(startupModel));
|
|
232
|
+
// Native steer may still replace work if a human wins the check/send race.
|
|
233
|
+
input.signal.throwIfAborted();
|
|
234
|
+
const prompt = launchPrompt(input.body, input.launchTells, input.schemaJson);
|
|
235
|
+
await setup(input.signal, () => {
|
|
236
|
+
this.submitted = true;
|
|
237
|
+
return this.client.sendMessage(agent.id, prompt, { messageId: this.turn.messageId, activeTurnBehavior: "steer" });
|
|
238
|
+
});
|
|
239
|
+
const admissionSignal = AbortSignal.any([input.signal, AbortSignal.timeout(15_000)]);
|
|
240
|
+
const fence = await abortable(this.turn.admission, admissionSignal).catch((error) => {
|
|
241
|
+
if (input.signal.aborted)
|
|
242
|
+
throw error;
|
|
243
|
+
throw new Error("Paseo canonical native admission was not observed", { cause: error });
|
|
244
|
+
});
|
|
245
|
+
const completion = this.finish();
|
|
246
|
+
void completion.catch(() => undefined);
|
|
247
|
+
return {
|
|
248
|
+
admission: { fence },
|
|
249
|
+
events: this.turn.events,
|
|
250
|
+
completion,
|
|
251
|
+
abort: () => this.retire(true),
|
|
252
|
+
forceDispose: () => this.retire(true),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
async existingAgent(coordinate, signal) {
|
|
256
|
+
if (!("sessionId" in coordinate) || coordinate.sessionId === undefined || "sessionFile" in coordinate)
|
|
257
|
+
throw new Error("Paseo resume requires an agent id");
|
|
258
|
+
const found = await setup(signal, () => this.client.fetchAgent(coordinate.sessionId));
|
|
259
|
+
if (found === null)
|
|
260
|
+
throw new Error(`Paseo agent ${coordinate.sessionId} is unavailable`);
|
|
261
|
+
return found.agent;
|
|
262
|
+
}
|
|
263
|
+
receive(message) {
|
|
264
|
+
if (this.closure !== undefined || message.payload.agentId !== this.agentId)
|
|
265
|
+
return;
|
|
266
|
+
if (message.type === "agent_stream") {
|
|
267
|
+
const { seq, epoch, event } = message.payload;
|
|
268
|
+
if (this.epoch !== undefined && epoch !== undefined && epoch !== this.epoch)
|
|
269
|
+
return this.turn.fail(new Error("Paseo timeline epoch changed before own turn completion"));
|
|
270
|
+
if (epoch !== undefined)
|
|
271
|
+
this.epoch = epoch;
|
|
272
|
+
if (seq !== undefined) {
|
|
273
|
+
if (this.sequence !== undefined && seq > this.sequence + 1)
|
|
274
|
+
return this.turn.fail(new Error("Paseo timeline delivery gap before own turn completion"));
|
|
275
|
+
if (this.sequence !== undefined && seq <= this.sequence)
|
|
276
|
+
return;
|
|
277
|
+
this.sequence = seq;
|
|
278
|
+
}
|
|
279
|
+
this.turn.receive(event);
|
|
280
|
+
}
|
|
281
|
+
else
|
|
282
|
+
this.turn.fail(new Error(message.type === "agent.timeline.error"
|
|
283
|
+
? `Paseo timeline failed: ${message.payload.error}`
|
|
284
|
+
: "Paseo timeline was invalidated before own turn completion"));
|
|
285
|
+
}
|
|
286
|
+
async finish() {
|
|
287
|
+
try {
|
|
288
|
+
const result = await this.turn.completion;
|
|
289
|
+
await this.retire(false);
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
try {
|
|
294
|
+
await this.retire(true);
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
// Attempt closure retains the control or client-retirement failure independently.
|
|
298
|
+
}
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
retire(cancel) {
|
|
303
|
+
return (this.closure ??= this.close(cancel));
|
|
304
|
+
}
|
|
305
|
+
async close(cancel) {
|
|
306
|
+
this.removeConnectionListener();
|
|
307
|
+
try {
|
|
308
|
+
const errors = [];
|
|
309
|
+
try {
|
|
310
|
+
if (cancel && this.submitted && !this.turn.terminal && this.agentId !== undefined)
|
|
311
|
+
await this.client.cancelAgent(this.agentId);
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
errors.push(error);
|
|
315
|
+
}
|
|
316
|
+
try {
|
|
317
|
+
await this.sockets.retire(this.client);
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
errors.push(error);
|
|
321
|
+
}
|
|
322
|
+
failures(errors, "Paseo native control and retirement failed");
|
|
323
|
+
this.proveClosed();
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
this.failClosed(error);
|
|
327
|
+
throw error;
|
|
328
|
+
}
|
|
329
|
+
finally {
|
|
330
|
+
this.turn.fail(new Error("Paseo client retired"));
|
|
331
|
+
this.turn.events.end();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
export function createPaseoProvider(execution, dependencies = {}) {
|
|
336
|
+
const config = configuration(execution);
|
|
337
|
+
return {
|
|
338
|
+
admitOptions: optionAdmission,
|
|
339
|
+
...providerLifecycle(async (input, custody) => {
|
|
340
|
+
custody.signal.throwIfAborted();
|
|
341
|
+
const environment = akumaExecutionEnvironment(process.env, execution.env);
|
|
342
|
+
const sockets = new PaseoSockets();
|
|
343
|
+
const client = (dependencies.createClient ?? ((value) => new DaemonClient(value)))({
|
|
344
|
+
url: config.url,
|
|
345
|
+
clientId: randomUUID(),
|
|
346
|
+
clientType: "cli",
|
|
347
|
+
reconnect: { enabled: false },
|
|
348
|
+
transportFactory: sockets.factory,
|
|
349
|
+
connectTimeoutMs: 15_000,
|
|
350
|
+
...(environment.PASEO_PASSWORD === undefined ? {} : { password: environment.PASEO_PASSWORD }),
|
|
351
|
+
});
|
|
352
|
+
const drive = new PaseoDrive(client, custody, execution.env ?? {}, sockets);
|
|
353
|
+
const signal = AbortSignal.any([custody.signal, AbortSignal.timeout(15_000)]);
|
|
354
|
+
return await drive.establish({ ...input, signal }, config, input.session.kind === "resume" ? input.session.coordinate : undefined);
|
|
355
|
+
}),
|
|
356
|
+
};
|
|
357
|
+
}
|
|
@@ -25,6 +25,8 @@ export declare const PI_EVENT_DISPOSITIONS: {
|
|
|
25
25
|
readonly turn_end: "drop";
|
|
26
26
|
readonly turn_start: "drop";
|
|
27
27
|
};
|
|
28
|
+
/** The model this native session will run, from its own selection. */
|
|
29
|
+
export declare function piSessionModel(selected: unknown): string | undefined;
|
|
28
30
|
export type PiEventState = {
|
|
29
31
|
answer: string;
|
|
30
32
|
assistantSeen: boolean;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { noteEvent, otherToolCall, unknownEvent } from "../../provider.js";
|
|
1
|
+
import { modelEvent, noteEvent, otherToolCall, unknownEvent } from "../../provider.js";
|
|
2
|
+
import { nonblank, observedTextContent, positiveLine, searchToolCall } from "../decode.js";
|
|
2
3
|
import { diffstatFromUnifiedPatch } from "../unified-patch.js";
|
|
3
4
|
export const PI_EVENT_DISPOSITIONS = {
|
|
4
5
|
agent_end: "drop",
|
|
@@ -31,31 +32,25 @@ function record(value) {
|
|
|
31
32
|
: null;
|
|
32
33
|
}
|
|
33
34
|
function textContent(content) {
|
|
34
|
-
|
|
35
|
-
return content;
|
|
36
|
-
if (!Array.isArray(content))
|
|
37
|
-
return "";
|
|
38
|
-
return content
|
|
39
|
-
.map((block) => {
|
|
40
|
-
const value = record(block);
|
|
41
|
-
return value?.type === "text" && typeof value.text === "string" ? value.text : "";
|
|
42
|
-
})
|
|
43
|
-
.join("");
|
|
35
|
+
return observedTextContent(content) ?? "";
|
|
44
36
|
}
|
|
45
37
|
function hasTextContent(content) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
38
|
+
return observedTextContent(content) !== undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Pi identifies a model as `<provider>/<id>`, the same convention its model
|
|
42
|
+
* option uses. The selected model and every recorded response carry both
|
|
43
|
+
* halves; a response without them names no model and stays unknown.
|
|
44
|
+
*/
|
|
45
|
+
function piModel(provider, id) {
|
|
46
|
+
const owner = nonblank(provider);
|
|
47
|
+
const name = nonblank(id);
|
|
48
|
+
return owner === undefined || name === undefined ? undefined : `${owner}/${name}`;
|
|
49
|
+
}
|
|
50
|
+
/** The model this native session will run, from its own selection. */
|
|
51
|
+
export function piSessionModel(selected) {
|
|
52
|
+
const value = record(selected);
|
|
53
|
+
return piModel(value?.provider, value?.id);
|
|
59
54
|
}
|
|
60
55
|
function runCall(name, value) {
|
|
61
56
|
return name === "bash" && typeof value.command === "string" ? { kind: "run", command: value.command } : undefined;
|
|
@@ -78,15 +73,10 @@ function searchCall(name, value) {
|
|
|
78
73
|
const query = value.pattern ?? value.query;
|
|
79
74
|
if (typeof query !== "string")
|
|
80
75
|
return undefined;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
query,
|
|
86
|
-
scope: name === "find" ? "files" : "content",
|
|
87
|
-
...(path === undefined ? {} : { path }),
|
|
88
|
-
...(name === "grep" && glob !== undefined ? { glob } : {}),
|
|
89
|
-
};
|
|
76
|
+
return searchToolCall(query, name === "find" ? "files" : "content", {
|
|
77
|
+
path: nonblank(value.path),
|
|
78
|
+
glob: name === "grep" ? nonblank(value.glob) : undefined,
|
|
79
|
+
});
|
|
90
80
|
}
|
|
91
81
|
function fileChangeCall(name, value) {
|
|
92
82
|
// Native write cannot prove creation versus overwrite and reports no patch, so
|
|
@@ -99,13 +89,14 @@ function refineEditCall(call, result) {
|
|
|
99
89
|
if (call.kind !== "fileChange")
|
|
100
90
|
return call;
|
|
101
91
|
const details = record(record(result)?.details);
|
|
102
|
-
|
|
92
|
+
const patch = typeof details?.patch === "string" ? details.patch : undefined;
|
|
93
|
+
if (patch === undefined)
|
|
103
94
|
return call;
|
|
104
|
-
const diffstat = diffstatFromUnifiedPatch(
|
|
95
|
+
const diffstat = diffstatFromUnifiedPatch(patch);
|
|
105
96
|
const change = call.changes[0];
|
|
106
|
-
if (
|
|
97
|
+
if (change === undefined)
|
|
107
98
|
return call;
|
|
108
|
-
return { kind: "fileChange", changes: [{ ...change, diffstat }] };
|
|
99
|
+
return { kind: "fileChange", changes: [{ ...change, ...(diffstat === undefined ? {} : { diffstat }), patch }] };
|
|
109
100
|
}
|
|
110
101
|
function toolCall(name, args) {
|
|
111
102
|
const value = record(args) ?? {};
|
|
@@ -131,6 +122,7 @@ function translateToolEnd(event, state) {
|
|
|
131
122
|
state.tools.delete(event.toolCallId);
|
|
132
123
|
const name = started?.name ?? event.toolName;
|
|
133
124
|
const call = started?.call ?? otherToolCall(name);
|
|
125
|
+
const output = observedTextContent(record(event.result)?.content);
|
|
134
126
|
return [
|
|
135
127
|
{
|
|
136
128
|
type: "tool",
|
|
@@ -138,7 +130,10 @@ function translateToolEnd(event, state) {
|
|
|
138
130
|
id: event.toolCallId,
|
|
139
131
|
name,
|
|
140
132
|
call: event.isError ? call : refineEditCall(call, event.result),
|
|
141
|
-
result: {
|
|
133
|
+
result: {
|
|
134
|
+
status: event.isError ? "error" : "ok",
|
|
135
|
+
...(output === undefined ? {} : { output }),
|
|
136
|
+
},
|
|
142
137
|
},
|
|
143
138
|
];
|
|
144
139
|
}
|
|
@@ -147,6 +142,9 @@ function translateMessage(event, state) {
|
|
|
147
142
|
if (message?.role !== "assistant")
|
|
148
143
|
return [];
|
|
149
144
|
const translated = [];
|
|
145
|
+
const model = piModel(message.provider, message.model);
|
|
146
|
+
if (model !== undefined)
|
|
147
|
+
translated.push(modelEvent(model));
|
|
150
148
|
if (Array.isArray(message.content)) {
|
|
151
149
|
for (const block of message.content) {
|
|
152
150
|
const value = record(block);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { abortable } from "../../abort.js";
|
|
2
2
|
import { akumaExecutionEnvironment } from "../execution-environment.js";
|
|
3
|
-
import { AgentEventChannel, createProviderAttempt, } from "../../provider.js";
|
|
4
|
-
import { piTerminalFailure, translatePiEvent } from "./events.js";
|
|
3
|
+
import { AgentEventChannel, createProviderAttempt, launchPrompt, modelEvent, tellRegistry, } from "../../provider.js";
|
|
4
|
+
import { piSessionModel, piTerminalFailure, translatePiEvent } from "./events.js";
|
|
5
5
|
const PI_THINKING_LEVELS = new Set(["minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
6
6
|
const MODEL_PATTERN = /^[^/\s]+\/[^\s]+$/u;
|
|
7
7
|
function diagnostic(error) {
|
|
@@ -83,15 +83,7 @@ async function createPiSession(sdk, execution, input) {
|
|
|
83
83
|
}
|
|
84
84
|
async function runPiPrompt(native, input, events, state, settle) {
|
|
85
85
|
try {
|
|
86
|
-
|
|
87
|
-
.filter((part) => part.length > 0)
|
|
88
|
-
.join("\n\n");
|
|
89
|
-
const schemaPrompt = input.schemaJson === undefined
|
|
90
|
-
? prompt
|
|
91
|
-
: [prompt, "Respond with JSON matching this JSON Schema and no other text:", input.schemaJson]
|
|
92
|
-
.filter((part) => part.length > 0)
|
|
93
|
-
.join("\n\n");
|
|
94
|
-
await native.prompt(schemaPrompt);
|
|
86
|
+
await native.prompt(launchPrompt(input.body, input.launchTells, input.schemaJson));
|
|
95
87
|
let result;
|
|
96
88
|
if (state.aborting)
|
|
97
89
|
result = { kind: "failed", diagnostic: "Pi session aborted" };
|
|
@@ -162,17 +154,15 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
162
154
|
aborting: false,
|
|
163
155
|
settled: false,
|
|
164
156
|
};
|
|
165
|
-
const
|
|
166
|
-
const endPendingTells = () => {
|
|
167
|
-
for (const waiter of pendingTells.values())
|
|
168
|
-
waiter.resolve({ kind: "turn-ended" });
|
|
169
|
-
pendingTells.clear();
|
|
170
|
-
};
|
|
157
|
+
const tells = tellRegistry((id) => `${native.sessionId}:${id}`);
|
|
171
158
|
let settleCompletion;
|
|
172
159
|
const completion = new Promise((resolve) => {
|
|
173
160
|
settleCompletion = resolve;
|
|
174
161
|
});
|
|
175
162
|
const agent = native.agent;
|
|
163
|
+
// Tells are harness input, not interactive typing: deliver every queued one at
|
|
164
|
+
// the next boundary regardless of the user's interactive Pi setting.
|
|
165
|
+
agent.steeringMode = "all";
|
|
176
166
|
let unsubscribeAgent;
|
|
177
167
|
let unsubscribe;
|
|
178
168
|
let binding;
|
|
@@ -180,7 +170,7 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
180
170
|
if (state.settled)
|
|
181
171
|
return closed;
|
|
182
172
|
state.settled = true;
|
|
183
|
-
|
|
173
|
+
tells.end();
|
|
184
174
|
let failure;
|
|
185
175
|
try {
|
|
186
176
|
unsubscribe?.();
|
|
@@ -219,13 +209,8 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
219
209
|
custody?.own({ closed, abort: forceDispose, forceDispose });
|
|
220
210
|
try {
|
|
221
211
|
unsubscribeAgent = agent.subscribe((event) => {
|
|
222
|
-
if (event.type === "message_end")
|
|
223
|
-
|
|
224
|
-
if (waiter !== undefined) {
|
|
225
|
-
pendingTells.delete(event.message);
|
|
226
|
-
waiter.resolve({ kind: "accepted", fence: `${native.sessionId}:${waiter.id}` });
|
|
227
|
-
}
|
|
228
|
-
}
|
|
212
|
+
if (event.type === "message_end")
|
|
213
|
+
tells.accept(event.message);
|
|
229
214
|
});
|
|
230
215
|
unsubscribe = native.subscribe((event) => {
|
|
231
216
|
if (event.type === "agent_end" && !event.willRetry) {
|
|
@@ -251,6 +236,9 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
251
236
|
await abortable(binding, signal);
|
|
252
237
|
signal.throwIfAborted();
|
|
253
238
|
events.emit({ type: "session", coordinate: { sessionFile: native.sessionFile, sessionId: native.sessionId } });
|
|
239
|
+
const sessionModel = piSessionModel(native.model);
|
|
240
|
+
if (sessionModel !== undefined)
|
|
241
|
+
events.emit(modelEvent(sessionModel));
|
|
254
242
|
void runPiPrompt(native, input, eventState, state, (result) => {
|
|
255
243
|
void settle(result).catch(() => undefined);
|
|
256
244
|
});
|
|
@@ -266,16 +254,14 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
266
254
|
content: [{ type: "text", text: tell.text }],
|
|
267
255
|
timestamp: new Date().getTime(),
|
|
268
256
|
};
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
});
|
|
257
|
+
const submission = tells.register(message, tell.id);
|
|
258
|
+
try {
|
|
259
|
+
agent.steer(message);
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
tells.fail(message, error);
|
|
263
|
+
}
|
|
264
|
+
return submission;
|
|
279
265
|
},
|
|
280
266
|
abort: () => {
|
|
281
267
|
state.abortRequest ??= (async () => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AkumaCaller } from "./caller.js";
|
|
1
2
|
import { type Soul } from "./heart/index.js";
|
|
2
3
|
import { type AllocatedAkuma, type AkumaPaths, type AkuId } from "./identity.js";
|
|
3
4
|
import type { OwnedProcess } from "../runtime/proc/run.js";
|
|
@@ -81,6 +82,7 @@ type PreparedCallResult = Readonly<{
|
|
|
81
82
|
type PreparedCallInput = Readonly<{
|
|
82
83
|
archetype: string;
|
|
83
84
|
cwd: string;
|
|
85
|
+
caller?: AkumaCaller;
|
|
84
86
|
initialTell?: CallInitialTell;
|
|
85
87
|
signal?: AbortSignal;
|
|
86
88
|
custody: PreparedCallCustody;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { decodeAkumaCaller } from "./caller.js";
|
|
1
2
|
import { HeldAkumaLeash, initializeHeart, readHeart, readSeal, readSoul } from "./heart/index.js";
|
|
2
3
|
import { acquireLeash } from "./control.js";
|
|
3
4
|
import { allocateAkumaDirectory } from "./identity.js";
|
|
@@ -337,6 +338,9 @@ async function durablyBorn(allocated) {
|
|
|
337
338
|
*/
|
|
338
339
|
export async function executePreparedCall(input) {
|
|
339
340
|
const { custody } = input;
|
|
341
|
+
const caller = custody.kind === "request"
|
|
342
|
+
? { kind: "akuma", world: custody.world, akuId: custody.parent.id }
|
|
343
|
+
: decodeAkumaCaller(input.caller);
|
|
340
344
|
let world;
|
|
341
345
|
if (custody.kind === "local") {
|
|
342
346
|
world = custody.world;
|
|
@@ -383,6 +387,7 @@ export async function executePreparedCall(input) {
|
|
|
383
387
|
allowed: recipe.allowed,
|
|
384
388
|
cwd: input.cwd,
|
|
385
389
|
origin,
|
|
390
|
+
...(caller === undefined ? {} : { caller }),
|
|
386
391
|
},
|
|
387
392
|
});
|
|
388
393
|
},
|
|
@@ -14,22 +14,24 @@ type ServeClaim = (input: PumpInput & Readonly<{
|
|
|
14
14
|
claim: RequestEnvelope;
|
|
15
15
|
signal: AbortSignal;
|
|
16
16
|
admissionOpen(): boolean;
|
|
17
|
-
}>) => Promise<
|
|
17
|
+
}>) => Promise<void>;
|
|
18
18
|
export declare class BodyRequestPump {
|
|
19
19
|
private readonly input;
|
|
20
20
|
private readonly serveClaim;
|
|
21
21
|
readonly directory: string;
|
|
22
|
+
readonly entry: string;
|
|
22
23
|
readonly failure: Promise<never>;
|
|
23
24
|
private readonly closeSignal;
|
|
24
25
|
private readonly executionSignal;
|
|
25
|
-
private readonly handled;
|
|
26
26
|
private readonly running;
|
|
27
27
|
private readonly cancelBody;
|
|
28
28
|
private admissionClosed;
|
|
29
|
+
private closure;
|
|
29
30
|
protected constructor(input: PumpInput, serveClaim: ServeClaim);
|
|
30
31
|
static openWithService(input: PumpInput, serveClaim: ServeClaim): Promise<BodyRequestPump>;
|
|
31
32
|
private run;
|
|
32
33
|
close(): Promise<void>;
|
|
34
|
+
private closeTransport;
|
|
33
35
|
stopAdmission(): void;
|
|
34
36
|
}
|
|
35
37
|
export declare function clearBodyRequestTransport(paths: AkumaPaths): Promise<void>;
|