@usine/agents 0.3.0 → 0.4.0
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 +92 -30
- package/dist/child-host/child-host.d.ts +60 -0
- package/dist/child-host/child-host.d.ts.map +1 -0
- package/dist/child-host/child-host.js +84 -0
- package/dist/child-host/child-host.js.map +1 -0
- package/dist/child-host/command.d.ts +11 -0
- package/dist/child-host/command.d.ts.map +1 -0
- package/dist/child-host/command.js +26 -0
- package/dist/child-host/command.js.map +1 -0
- package/dist/pi/authentication.d.ts +11 -2
- package/dist/pi/authentication.d.ts.map +1 -1
- package/dist/pi/authentication.js +15 -2
- package/dist/pi/authentication.js.map +1 -1
- package/dist/pi/children.d.ts +1 -4
- package/dist/pi/children.d.ts.map +1 -1
- package/dist/pi/children.js +1 -4
- package/dist/pi/children.js.map +1 -1
- package/dist/pi/claude.d.ts +8 -9
- package/dist/pi/claude.d.ts.map +1 -1
- package/dist/pi/claude.js +366 -50
- package/dist/pi/claude.js.map +1 -1
- package/dist/pi/codex/account.d.ts +3 -3
- package/dist/pi/codex/account.d.ts.map +1 -1
- package/dist/pi/codex/account.js +5 -5
- package/dist/pi/codex/account.js.map +1 -1
- package/dist/pi/codex/app-server.d.ts +19 -7
- package/dist/pi/codex/app-server.d.ts.map +1 -1
- package/dist/pi/codex/app-server.js +41 -36
- package/dist/pi/codex/app-server.js.map +1 -1
- package/dist/pi/codex/codec.d.ts +35 -13
- package/dist/pi/codex/codec.d.ts.map +1 -1
- package/dist/pi/codex/codec.js +42 -15
- package/dist/pi/codex/codec.js.map +1 -1
- package/dist/pi/codex/codex.d.ts +0 -1
- package/dist/pi/codex/codex.d.ts.map +1 -1
- package/dist/pi/codex/codex.js +75 -14
- package/dist/pi/codex/codex.js.map +1 -1
- package/dist/pi/conversation.d.ts +29 -12
- package/dist/pi/conversation.d.ts.map +1 -1
- package/dist/pi/conversation.js +54 -18
- package/dist/pi/conversation.js.map +1 -1
- package/dist/pi/pi.d.ts +1 -4
- package/dist/pi/pi.d.ts.map +1 -1
- package/dist/pi/pi.js +24 -175
- package/dist/pi/pi.js.map +1 -1
- package/dist/pi/sdk.d.ts +11 -15
- package/dist/pi/sdk.d.ts.map +1 -1
- package/dist/pi/sdk.js +35 -53
- package/dist/pi/sdk.js.map +1 -1
- package/dist/pi/session.d.ts +13 -14
- package/dist/pi/session.d.ts.map +1 -1
- package/dist/pi/session.js +63 -24
- package/dist/pi/session.js.map +1 -1
- package/dist/pi/turns.d.ts +7 -7
- package/dist/pi/turns.d.ts.map +1 -1
- package/dist/pi/turns.js +22 -9
- package/dist/pi/turns.js.map +1 -1
- package/dist/pi/usage.d.ts +29 -15
- package/dist/pi/usage.d.ts.map +1 -1
- package/dist/pi/usage.js +48 -24
- package/dist/pi/usage.js.map +1 -1
- package/dist/preflight/command.d.ts +16 -3
- package/dist/preflight/command.d.ts.map +1 -1
- package/dist/preflight/command.js +30 -17
- package/dist/preflight/command.js.map +1 -1
- package/dist/preflight/preflight.d.ts +10 -5
- package/dist/preflight/preflight.d.ts.map +1 -1
- package/dist/preflight/preflight.js +52 -25
- package/dist/preflight/preflight.js.map +1 -1
- package/dist/prompt.d.ts +12 -9
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +33 -4
- package/dist/prompt.js.map +1 -1
- package/dist/protocol/codex.d.ts +4 -7
- package/dist/protocol/codex.d.ts.map +1 -1
- package/dist/protocol/codex.js +1 -1
- package/dist/protocol/codex.js.map +1 -1
- package/dist/runtime.d.ts +100 -55
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +108 -27
- package/dist/runtime.js.map +1 -1
- package/package.json +22 -10
- package/dist/pi/live.d.ts +0 -4
- package/dist/pi/live.d.ts.map +0 -1
- package/dist/pi/live.js +0 -11
- package/dist/pi/live.js.map +0 -1
- package/dist/pi/subagents.d.ts +0 -29
- package/dist/pi/subagents.d.ts.map +0 -1
- package/dist/pi/subagents.js +0 -120
- package/dist/pi/subagents.js.map +0 -1
- package/dist/pi/thinking.d.ts +0 -8
- package/dist/pi/thinking.d.ts.map +0 -1
- package/dist/pi/thinking.js +0 -15
- package/dist/pi/thinking.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,57 +1,119 @@
|
|
|
1
1
|
# @usine/agents
|
|
2
2
|
|
|
3
|
-
The agent
|
|
3
|
+
The agent layer for [usine](https://github.com/basaltbytes/usine): the Claude Code, Codex, and Pi child backends that an attempt's Pi parent delegates to, their prompts, and harness preflight. The parent runs in the orchestrator as a durable task (`@usine/durable`); its `subagent` tool starts the child that the agent's brain spec selects. [Attempt execution](https://docs.usine.dev/architecture/execution/) describes each harness.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
0.x APIs can change between minor releases. Supply `effect` at the workspace's pinned version. Harness SDKs and protocols are exact-pinned.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
import { layer as agentLayer } from "@usine/agents/pi/live";
|
|
9
|
-
```
|
|
7
|
+
## Compose the child backends
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
`/prompt` and `/runtime` are platform-free: prompt assembly, typed runtime errors, and the `ChildBackend` contracts. `childDispatcherLayer` (`/children`) picks a backend from the agent's `harness`. Provide its three backends from `/claude`, `/codex`, and `/pi`, which also export their SDK contracts and production SDK layers. `@usine/durable/live` composes them:
|
|
12
10
|
|
|
13
11
|
```ts
|
|
14
12
|
import { Layer } from "effect";
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
import { childDispatcherLayer } from "@usine/agents/children";
|
|
14
|
+
import { claudeChildBackendLayer, claudeSdkLive } from "@usine/agents/claude";
|
|
15
|
+
import { codexAppServerLive, codexChildBackendLayer } from "@usine/agents/codex";
|
|
16
|
+
import { piChildBackendLayer, piSdkLive } from "@usine/agents/pi";
|
|
17
|
+
|
|
18
|
+
const childBackendLayer = childDispatcherLayer.pipe(
|
|
19
|
+
Layer.provide(
|
|
20
|
+
Layer.mergeAll(
|
|
21
|
+
claudeChildBackendLayer.pipe(Layer.provide(claudeSdkLive)),
|
|
22
|
+
codexChildBackendLayer.pipe(Layer.provide(codexAppServerLive)),
|
|
23
|
+
piChildBackendLayer.pipe(Layer.provide(piSdkLive)),
|
|
24
|
+
),
|
|
25
|
+
),
|
|
21
26
|
);
|
|
22
27
|
```
|
|
23
28
|
|
|
24
|
-
|
|
29
|
+
The Claude backend also needs `ClaudeLoginLock` (`/runtime`), one per worker, which every Claude command that can refresh the worker's login takes. Give the same instance (`claudeLoginLockLayer` from `@usine/executor`) to the backends and the executor running preflight.
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
## Harnesses and credentials
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
- **Parent:** a Pi model with an API key, or an `openai-codex` ChatGPT model through Plus or Pro OAuth. The start log records `apiKeys` or `chatgptPlan`. A child past the run spec's child-session budget stops the parent with `ChildSessionBudgetExceededError`.
|
|
34
|
+
- **Claude Code:** the worker's `claude` through the Agent SDK, with `bypassPermissions`, worker-user settings only, and the CLI login.
|
|
35
|
+
- **Codex:** app-server JSON-RPC over stdio, with `approvalPolicy: never` and the CLI login. It checks the login with `account/read` before creating a thread, and records plan rate windows as `PoolRateLimitsUpdated`. An API-key login, no login, or an unsupported account fails with `PoolUnavailableError`, which needs the operator. A login change ends the session before more rate windows are recorded.
|
|
36
|
+
- **Pi children:** API keys only.
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
Logs record the verified authentication method and pool. On completion or interrupt, usine closes the input of the child's Codex app server and waits for it to exit before publishing, releasing background commands. Scope cleanup does the same, bounded, and logs before force-stopping a stalled process.
|
|
31
39
|
|
|
32
|
-
|
|
40
|
+
`/pi/authentication` exports the parent's rules for other runtimes: `splitPiModel` (parses `provider/model`), `piAuthentication` (a provider's credential check), `requiredPiPool` (a provider's pool), and `resolvePiPool` (its credential's pool).
|
|
33
41
|
|
|
34
|
-
|
|
42
|
+
## Child hosts
|
|
35
43
|
|
|
36
|
-
|
|
44
|
+
`ChildRequest.host` (`/child-host`) sets where a child runs, and `ChildRequest.worker` names that machine's worker:
|
|
37
45
|
|
|
38
|
-
|
|
46
|
+
- `LocalProcess`: on this machine, with `ChildRequest.environment` as the whole environment.
|
|
47
|
+
- `RemoteShell`: one `ssh <args> <destination> -- <remote command>`, which enters the worktree, exports the request's environment over the machine's own, writes its pid to `<worktree>.child-<n>.pid`, and runs the harness. The SSH client gets only `RemoteShell.sshEnvironment`.
|
|
39
48
|
|
|
40
|
-
|
|
49
|
+
Executors run `CHILD_KILL_SCRIPT` remotely to stop every child in those pid files before keeping or removing a worktree. Claude Code runs remotely through `spawnClaudeCodeProcess`, Codex over the same SSH command. Pi children run tools in this process and fail on `RemoteShell` with `AgentResultError`.
|
|
41
50
|
|
|
42
|
-
|
|
51
|
+
The worktree is repo-controlled input: Pi ignores the project's `.pi/` settings, extensions, prompt templates, skills, and themes; Claude omits project setting sources; Codex marks the worktree untrusted. AGENTS instructions still apply. The executor isolates the worker.
|
|
43
52
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
## Session events and operator actions
|
|
54
|
+
|
|
55
|
+
Child output becomes typed events: `SessionStarted`, `TextOutput` for completed assistant text (streaming deltas stay out of the transcript), tool calls, pool observations, and `SessionFinished`. Each child session has one parent session; recursive child events can't enter the public model.
|
|
56
|
+
|
|
57
|
+
`RunningSession.intervene(action, onDelivery)` applies steer, interrupt, and holds. A message to an idle or paused child starts a turn and emits `SessionResumed`. A message to a working child joins the turn and returns `InterventionState.queued`; `onDelivery` runs once, with the child's state when the harness reads it, or with none if the child stops first. Pi reads it when the queued steering message starts, Codex when it records a `userMessage` item, and Claude Code with a result whose `queued_turn_count` no longer counts it. A finished turn has read all its queued messages.
|
|
58
|
+
|
|
59
|
+
## Claude login lock
|
|
60
|
+
|
|
61
|
+
A Claude child holds the worker's `ClaudeLoginLock` from process start until its first messages prove the login (a rate-limit or thinking update, an API retry, a model answer, or the turn result), for one minute at most. `launch` returns then.
|
|
62
|
+
|
|
63
|
+
If the first turn ends with `Failed to refresh OAuth token: another Claude Code process ...` and no tokens spent, another process had the refresh lock. The backend stops the process and relaunches after 15, 30, then 60 seconds, logging each retry at info. Only the running launch is transcribed. If the last launch fails the same way, the parent gets Claude's error as the child's report.
|
|
64
|
+
|
|
65
|
+
## Background work
|
|
66
|
+
|
|
67
|
+
Claude children use the CLI's background-task snapshots and session-idle signal to wait for background work and its follow-up answer, without an operator hold. Queued user turns delay completion; ambient watchers don't. An output stream that closes without a completed answer fails with `SessionOperationError`.
|
|
68
|
+
|
|
69
|
+
The prompts tell parents and children, before returning, to run gates, tests, and CI watches in the foreground, wait for background results and pending checks, finish dependent steps, record real blockers on the issue or pull request, and push commits, since cleanup removes the worktree. This also covers older CLIs without background-task or session-state messages.
|
|
70
|
+
|
|
71
|
+
## Outcome markers
|
|
72
|
+
|
|
73
|
+
An unresolved blocker starts the final answer with `[usine:blocked]`, then details and incomplete work on that line or the next:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
[usine:blocked]
|
|
77
|
+
Repository permission denied; publishing remains incomplete.
|
|
47
78
|
```
|
|
48
79
|
|
|
49
|
-
|
|
80
|
+
An operator-only decision starts it with `[usine:question]` and the question, which the prompt tells the agent to post on the item first:
|
|
50
81
|
|
|
51
|
-
|
|
82
|
+
```text
|
|
83
|
+
[usine:question]
|
|
84
|
+
Should egress use HTTP CONNECT or a SOCKS proxy? Both fit the gateway.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`reportedOutcome` reads markers as `AgentBlockedError` and `AgentQuestionError`, and `reportText` writes them. A parent's blocker becomes a non-retryable `BlockedFailure` and its question a non-retryable `QuestionFailure`: the run fails, its loop suppresses the item, and the run waits for the operator. A child's harness failure (`AgentResultError`) goes to the parent as a `[usine:failed]` report that `reportedOutcome` reads back, so the attempt ends with `AgentFailure` and suppresses nothing: the harness posted nothing.
|
|
88
|
+
|
|
89
|
+
A child's report returns to the parent's `subagent` call as text opening with its marker, to return verbatim. The parent keeps the first: a later ordinary answer fails with it, and the paraphrase stays in the transcript. Successful siblings don't clear it. Held children can take guidance and replace their answer before release. A marker without details still fails.
|
|
90
|
+
|
|
91
|
+
Model ids stay opaque until the harness checks its registry. Harness failures use `AgentResultError`. `toAttemptFailure` maps only `SessionOperationError` (SDK, process, and protocol failures) to a retryable infrastructure failure; `ChildSessionBudgetExceededError` becomes a non-retryable `ChildSessionBudgetFailure`.
|
|
92
|
+
|
|
93
|
+
## GitHub identity and reviews
|
|
94
|
+
|
|
95
|
+
Agents share the installation's GitHub App identity. The instructions require comment reviews at the reviewed head and the loop's outcome labels. A success label doesn't satisfy GitHub's required review: an independent reviewer approves and the operator merges. See [Write review and fix loops](https://docs.usine.dev/guides/review-fix-loops/).
|
|
96
|
+
|
|
97
|
+
## Resume a harness session
|
|
98
|
+
|
|
99
|
+
Claude children save sessions, and Codex threads aren't ephemeral. `SessionStarted.harnessSession` and launch logs (`harnessSessionId`, `sessionId`, `cwd`) give the id and directory. While the worktree and session files exist, run `claude --resume <id>` or `codex resume <id>` there, on the same worker and account.
|
|
100
|
+
|
|
101
|
+
## Preflight
|
|
52
102
|
|
|
53
|
-
|
|
103
|
+
`preflight(brain, host, environment)` (`/preflight`, Node) checks a worker without a prompt, using a `ChildProcessSpawner` layer. Each check sees `environment` as a child does. On a `RemoteShell` host, checks run over SSH, an SSH failure (exit 255) is an incomplete check rather than a missing harness, and a Pi brain is unavailable.
|
|
54
104
|
|
|
55
|
-
|
|
105
|
+
It accepts Codex CLI **0.144.0 or 0.153.4** with a verified ChatGPT account, a Claude subscription in `claude auth status --json`, and Pi's model and API key through the SDK. `HarnessUnavailableError` reports a missing binary, version, or login; `SessionOperationError` an incomplete check, such as a timeout or failed SDK connection. Install and log in as the worker user before starting usine.
|
|
106
|
+
|
|
107
|
+
## Live contract tests
|
|
108
|
+
|
|
109
|
+
The opt-in live contracts, in disposable directories, steer a child during a waiting command, checking the response and event framing, and interrupt another; Codex also needs a real rate-window snapshot. Claude and Codex cases also run through `test/fixtures/ssh-shim.sh`, an SSH stand-in that runs the remote command locally, to check it, its environment, and its pid file with the real CLIs.
|
|
110
|
+
|
|
111
|
+
They need a supported Codex CLI with a ChatGPT login, a Claude CLI with a subscription login, an API key for the Pi provider, and explicit models:
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
USINE_CLAUDE_INTEGRATION_MODEL=claude-sonnet-5-5 pnpm --filter @usine/agents test:integration:claude
|
|
115
|
+
USINE_CODEX_INTEGRATION_MODEL=gpt-5.6-terra pnpm --filter @usine/agents test:integration:codex
|
|
116
|
+
USINE_PI_INTEGRATION_MODEL=anthropic/claude-sonnet-4-6 pnpm --filter @usine/agents test:integration:pi
|
|
117
|
+
```
|
|
56
118
|
|
|
57
|
-
|
|
119
|
+
The protocol conformance baseline is 0.144.0. Codex 0.153.4 also passed its generated protocol types and the real steering and interruption contracts, including Astra. Other CLI builds need verification first.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { AgentSessionId } from "@usine/core/agent/session";
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
declare const LocalProcess_base: Schema.Class<LocalProcess, Schema.TaggedStruct<"LocalProcess", {}>, {}>;
|
|
4
|
+
/** A host that runs children as local processes. */
|
|
5
|
+
export declare class LocalProcess extends LocalProcess_base {
|
|
6
|
+
}
|
|
7
|
+
/** The local SSH executable and the options before the destination. */
|
|
8
|
+
export declare const SshCommand: Schema.Struct<{
|
|
9
|
+
readonly command: Schema.NonEmptyString;
|
|
10
|
+
readonly args: Schema.$Array<Schema.String>;
|
|
11
|
+
}>;
|
|
12
|
+
export type SshCommand = typeof SshCommand.Type;
|
|
13
|
+
declare const RemoteShell_base: Schema.Class<RemoteShell, Schema.TaggedStruct<"RemoteShell", {
|
|
14
|
+
readonly ssh: Schema.Struct<{
|
|
15
|
+
readonly command: Schema.NonEmptyString;
|
|
16
|
+
readonly args: Schema.$Array<Schema.String>;
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* The SSH client's process environment: what SSH needs to connect, never the orchestrator's
|
|
20
|
+
* secrets (ADR 0011), plus the variables that `-o SendEnv=` options in `ssh` forward to the
|
|
21
|
+
* child. Use it for values that must not appear on the command line, such as a Gateway caller
|
|
22
|
+
* token. Never log this field.
|
|
23
|
+
*/
|
|
24
|
+
readonly sshEnvironment: Schema.$Record<Schema.String, Schema.String>;
|
|
25
|
+
/** The SSH destination, passed as one argument. */
|
|
26
|
+
readonly destination: Schema.NonEmptyString;
|
|
27
|
+
}>, {}>;
|
|
28
|
+
/** A host that runs each child on another machine as one SSH command, through its standard streams. */
|
|
29
|
+
export declare class RemoteShell extends RemoteShell_base {
|
|
30
|
+
}
|
|
31
|
+
/** The host that runs an Attempt's children, chosen by the Worker that prepared its checkout. */
|
|
32
|
+
export declare const ChildHost: Schema.Union<readonly [typeof LocalProcess, typeof RemoteShell]>;
|
|
33
|
+
export type ChildHost = typeof ChildHost.Type;
|
|
34
|
+
/** A command for a host to run. */
|
|
35
|
+
export interface HostInvocation {
|
|
36
|
+
/** The working directory; defaults to the host user's home directory. */
|
|
37
|
+
readonly cwd?: string | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* The command's complete environment on a local host, or the variables exported on top of a remote
|
|
40
|
+
* shell's environment; `undefined` values are skipped.
|
|
41
|
+
*/
|
|
42
|
+
readonly environment?: Readonly<Record<string, string | undefined>> | undefined;
|
|
43
|
+
/** On a remote shell, the file that contains the command's PID while it runs, so cleanup can stop it after the SSH client exits. */
|
|
44
|
+
readonly pidFile?: string | undefined;
|
|
45
|
+
readonly command: string;
|
|
46
|
+
readonly args: ReadonlyArray<string>;
|
|
47
|
+
}
|
|
48
|
+
/** Returns the SSH client arguments that run `invocation`: the options, the destination, and one remote command line. */
|
|
49
|
+
export declare const sshArguments: (host: RemoteShell, invocation: HostInvocation) => Array<string>;
|
|
50
|
+
/** Returns the PID file path of a remote child: next to its worktree, named by the child number in its session ID. */
|
|
51
|
+
export declare const childPidFile: (worktree: string, session: AgentSessionId) => string;
|
|
52
|
+
/**
|
|
53
|
+
* A shell script that stops an Attempt's remaining remote children before its worktree is kept or
|
|
54
|
+
* removed: for each `<worktree>.child-*.pid`, it sends TERM, waits, then sends KILL. Run it with
|
|
55
|
+
* `sh -c` and the worktree as `$1`; it prints one outcome per PID file. An exited SSH client does
|
|
56
|
+
* not mean that its remote command stopped.
|
|
57
|
+
*/
|
|
58
|
+
export declare const CHILD_KILL_SCRIPT: string;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=child-host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"child-host.d.ts","sourceRoot":"","sources":["../../src/child-host/child-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;;AAEhC,oDAAoD;AACpD,qBAAa,YAAa,SAAQ,iBAGjC;CAAG;AAEJ,uEAAuE;AACvE,eAAO,MAAM,UAAU;;;EAGrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;;;;;;IAO5C;;;;;OAKG;;IAEH,mDAAmD;;;AAZvD,uGAAuG;AACvG,qBAAa,WAAY,SAAQ,gBAchC;CAAG;AAEJ,iGAAiG;AACjG,eAAO,MAAM,SAAS,kEAA4C,CAAC;AACnE,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAC;AAE9C,mCAAmC;AACnC,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC;IAChF,oIAAoI;IACpI,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACtC;AA8BD,yHAAyH;AACzH,eAAO,MAAM,YAAY,SAAU,WAAW,cAAc,cAAc,KAAG,KAAK,CAAC,MAAM,CAKxF,CAAC;AAEF,sHAAsH;AACtH,eAAO,MAAM,YAAY,aAAc,MAAM,WAAW,cAAc,KAAG,MACD,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAgBtB,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
/** A host that runs children as local processes. */
|
|
3
|
+
export class LocalProcess extends Schema.TaggedClass("@usine/agents/LocalProcess")("LocalProcess", {}) {
|
|
4
|
+
}
|
|
5
|
+
/** The local SSH executable and the options before the destination. */
|
|
6
|
+
export const SshCommand = Schema.Struct({
|
|
7
|
+
command: Schema.NonEmptyString,
|
|
8
|
+
args: Schema.Array(Schema.String),
|
|
9
|
+
});
|
|
10
|
+
/** A host that runs each child on another machine as one SSH command, through its standard streams. */
|
|
11
|
+
export class RemoteShell extends Schema.TaggedClass("@usine/agents/RemoteShell")("RemoteShell", {
|
|
12
|
+
ssh: SshCommand,
|
|
13
|
+
/**
|
|
14
|
+
* The SSH client's process environment: what SSH needs to connect, never the orchestrator's
|
|
15
|
+
* secrets (ADR 0011), plus the variables that `-o SendEnv=` options in `ssh` forward to the
|
|
16
|
+
* child. Use it for values that must not appear on the command line, such as a Gateway caller
|
|
17
|
+
* token. Never log this field.
|
|
18
|
+
*/
|
|
19
|
+
sshEnvironment: Schema.Record(Schema.String, Schema.String),
|
|
20
|
+
/** The SSH destination, passed as one argument. */
|
|
21
|
+
destination: Schema.NonEmptyString,
|
|
22
|
+
}) {
|
|
23
|
+
}
|
|
24
|
+
/** The host that runs an Attempt's children, chosen by the Worker that prepared its checkout. */
|
|
25
|
+
export const ChildHost = Schema.Union([LocalProcess, RemoteShell]);
|
|
26
|
+
const VARIABLE_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
27
|
+
const quote = (value) => `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
28
|
+
const quoted = (words) => words.map(quote).join(" ");
|
|
29
|
+
/**
|
|
30
|
+
* Returns the remote POSIX shell command line for `invocation`, with every word quoted so it passes
|
|
31
|
+
* through OpenSSH unchanged. Throws if a variable name is not a shell identifier.
|
|
32
|
+
*/
|
|
33
|
+
const remoteShellCommand = (invocation) => {
|
|
34
|
+
const exports = Object.entries(invocation.environment ?? {}).flatMap(([name, value]) => {
|
|
35
|
+
if (!VARIABLE_NAME.test(name))
|
|
36
|
+
throw new Error(`Cannot export ${name} in a remote shell`);
|
|
37
|
+
return value === undefined ? [] : [`${name}=${quote(value)}`];
|
|
38
|
+
});
|
|
39
|
+
const setup = [
|
|
40
|
+
...(invocation.cwd === undefined ? [] : [`cd ${quote(invocation.cwd)}`]),
|
|
41
|
+
...(exports.length === 0 ? [] : [`export ${exports.join(" ")}`]),
|
|
42
|
+
];
|
|
43
|
+
const command = [invocation.command, ...invocation.args];
|
|
44
|
+
if (invocation.pidFile === undefined)
|
|
45
|
+
return [...setup, `exec ${quoted(command)}`].join(" && ");
|
|
46
|
+
// The inner shell writes its PID, then execs the command. The file exists only while the command
|
|
47
|
+
// runs, so cleanup never signals a reused PID.
|
|
48
|
+
const pidFile = quote(invocation.pidFile);
|
|
49
|
+
const run = `sh -c 'printf %s "$$" > "$0" && exec "$@"' ${pidFile} ${quoted(command)}`;
|
|
50
|
+
return `${[...setup, run].join(" && ")}; code=$?; rm -f ${pidFile}; exit "$code"`;
|
|
51
|
+
};
|
|
52
|
+
/** Returns the SSH client arguments that run `invocation`: the options, the destination, and one remote command line. */
|
|
53
|
+
export const sshArguments = (host, invocation) => [
|
|
54
|
+
...host.ssh.args,
|
|
55
|
+
host.destination,
|
|
56
|
+
"--",
|
|
57
|
+
remoteShellCommand(invocation),
|
|
58
|
+
];
|
|
59
|
+
/** Returns the PID file path of a remote child: next to its worktree, named by the child number in its session ID. */
|
|
60
|
+
export const childPidFile = (worktree, session) => `${worktree}.child-${session.slice(session.lastIndexOf(":") + 1)}.pid`;
|
|
61
|
+
/**
|
|
62
|
+
* A shell script that stops an Attempt's remaining remote children before its worktree is kept or
|
|
63
|
+
* removed: for each `<worktree>.child-*.pid`, it sends TERM, waits, then sends KILL. Run it with
|
|
64
|
+
* `sh -c` and the worktree as `$1`; it prints one outcome per PID file. An exited SSH client does
|
|
65
|
+
* not mean that its remote command stopped.
|
|
66
|
+
*/
|
|
67
|
+
export const CHILD_KILL_SCRIPT = `
|
|
68
|
+
found=0
|
|
69
|
+
for pidfile in "$1".child-*.pid; do
|
|
70
|
+
test -f "$pidfile" || continue
|
|
71
|
+
found=1
|
|
72
|
+
pid=$(cat "$pidfile" 2>/dev/null)
|
|
73
|
+
if [ -n "$pid" ] && kill -TERM "$pid" 2>/dev/null; then
|
|
74
|
+
n=0
|
|
75
|
+
while kill -0 "$pid" 2>/dev/null && [ "$n" -lt 10 ]; do sleep 0.5; n=$((n+1)); done
|
|
76
|
+
if kill -0 "$pid" 2>/dev/null; then kill -KILL "$pid" 2>/dev/null; echo "$pidfile killed"; else echo "$pidfile stopped"; fi
|
|
77
|
+
else
|
|
78
|
+
echo "$pidfile absent"
|
|
79
|
+
fi
|
|
80
|
+
rm -f "$pidfile"
|
|
81
|
+
done
|
|
82
|
+
test "$found" = 1 || echo no-children
|
|
83
|
+
`.trim();
|
|
84
|
+
//# sourceMappingURL=child-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"child-host.js","sourceRoot":"","sources":["../../src/child-host/child-host.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ChildProcess } from "effect/unstable/process";
|
|
2
|
+
import { type ChildHost, type HostInvocation } from "./child-host.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Returns the local process command that runs `invocation` on `host`: the command itself with
|
|
5
|
+
* exactly `environment` on a local host, or one SSH command whose client gets only `sshEnvironment`
|
|
6
|
+
* on a remote host.
|
|
7
|
+
*/
|
|
8
|
+
export declare const hostCommand: (host: ChildHost, invocation: HostInvocation & {
|
|
9
|
+
readonly environment: Readonly<Record<string, string>>;
|
|
10
|
+
}, options: ChildProcess.CommandOptions) => ChildProcess.Command;
|
|
11
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/child-host/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,cAAc,EAAgB,MAAM,iBAAiB,CAAC;AAEpF;;;;GAIG;AACH,eAAO,MAAM,WAAW,SAChB,SAAS,cACH,cAAc,GAAG;IAAE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,WAC9E,YAAY,CAAC,cAAc,KACnC,YAAY,CAAC,OAgBf,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ChildProcess } from "effect/unstable/process";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { sshArguments } from "./child-host.js";
|
|
4
|
+
/**
|
|
5
|
+
* Returns the local process command that runs `invocation` on `host`: the command itself with
|
|
6
|
+
* exactly `environment` on a local host, or one SSH command whose client gets only `sshEnvironment`
|
|
7
|
+
* on a remote host.
|
|
8
|
+
*/
|
|
9
|
+
export const hostCommand = (host, invocation, options) => {
|
|
10
|
+
switch (host._tag) {
|
|
11
|
+
case "LocalProcess":
|
|
12
|
+
return ChildProcess.make(invocation.command, invocation.args, {
|
|
13
|
+
...options,
|
|
14
|
+
cwd: invocation.cwd ?? homedir(),
|
|
15
|
+
env: { ...invocation.environment },
|
|
16
|
+
extendEnv: false,
|
|
17
|
+
});
|
|
18
|
+
case "RemoteShell":
|
|
19
|
+
return ChildProcess.make(host.ssh.command, sshArguments(host, invocation), {
|
|
20
|
+
...options,
|
|
21
|
+
env: { ...host.sshEnvironment },
|
|
22
|
+
extendEnv: false,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/child-host/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAuC,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,IAAe,EACf,UAAuF,EACvF,OAAoC,EACd,EAAE;IACxB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,cAAc;YACjB,OAAO,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,EAAE;gBAC5D,GAAG,OAAO;gBACV,GAAG,EAAE,UAAU,CAAC,GAAG,IAAI,OAAO,EAAE;gBAChC,GAAG,EAAE,EAAE,GAAG,UAAU,CAAC,WAAW,EAAE;gBAClC,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;QACL,KAAK,aAAa;YAChB,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE;gBACzE,GAAG,OAAO;gBACV,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE;gBAC/B,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;IACP,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -6,8 +6,17 @@ export type PiAuthentication = {
|
|
|
6
6
|
readonly subscription: boolean;
|
|
7
7
|
};
|
|
8
8
|
export type PiPool = Extract<BillingPool, "apiKeys" | "chatgptPlan">;
|
|
9
|
-
/**
|
|
9
|
+
/** Splits `provider/model` into provider and model ID; `undefined` unless both parts are present. */
|
|
10
|
+
export declare const splitPiModel: (model: string) => {
|
|
11
|
+
readonly provider: string;
|
|
12
|
+
readonly modelId: string;
|
|
13
|
+
} | undefined;
|
|
14
|
+
/** Converts Pi's credential check, with `subscription` set if the OAuth login is a subscription; returns `undefined` if Pi found no credential. */
|
|
15
|
+
export declare const piAuthentication: (check: {
|
|
16
|
+
readonly type: "api_key" | "oauth";
|
|
17
|
+
} | undefined, subscription: boolean) => PiAuthentication | undefined;
|
|
18
|
+
/** Returns the billing pool that a Pi provider requires; checked before launch. */
|
|
10
19
|
export declare const requiredPiPool: (provider: string) => PiPool;
|
|
11
|
-
/** Returns the billing pool of the credential
|
|
20
|
+
/** Returns the billing pool of the credential used for the model request, or `undefined` if it is neither an API key nor a subscription login to `openai-codex`. */
|
|
12
21
|
export declare const resolvePiPool: (provider: string, authentication: PiAuthentication | undefined) => PiPool | undefined;
|
|
13
22
|
//# sourceMappingURL=authentication.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authentication.d.ts","sourceRoot":"","sources":["../../src/pi/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC;AAC/D,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,SAAS,GAAG,aAAa,CAAC,CAAC;AAErE,
|
|
1
|
+
{"version":3,"file":"authentication.d.ts","sourceRoot":"","sources":["../../src/pi/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC;AAC/D,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,SAAS,GAAG,aAAa,CAAC,CAAC;AAErE,qGAAqG;AACrG,eAAO,MAAM,YAAY,UAChB,MAAM,KACZ;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAK5D,CAAC;AAEF,mJAAmJ;AACnJ,eAAO,MAAM,gBAAgB,UACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;CAAE,GAAG,SAAS,gBAC3C,OAAO,KACpB,gBAAgB,GAAG,SAKL,CAAC;AAElB,mFAAmF;AACnF,eAAO,MAAM,cAAc,aAAc,MAAM,KAAG,MACO,CAAC;AAE1D,oKAAoK;AACpK,eAAO,MAAM,aAAa,aACd,MAAM,kBACA,gBAAgB,GAAG,SAAS,KAC3C,MAAM,GAAG,SAUX,CAAC"}
|
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Splits `provider/model` into provider and model ID; `undefined` unless both parts are present. */
|
|
2
|
+
export const splitPiModel = (model) => {
|
|
3
|
+
const separator = model.indexOf("/");
|
|
4
|
+
return separator <= 0 || separator === model.length - 1
|
|
5
|
+
? undefined
|
|
6
|
+
: { provider: model.slice(0, separator), modelId: model.slice(separator + 1) };
|
|
7
|
+
};
|
|
8
|
+
/** Converts Pi's credential check, with `subscription` set if the OAuth login is a subscription; returns `undefined` if Pi found no credential. */
|
|
9
|
+
export const piAuthentication = (check, subscription) => check?.type === "api_key"
|
|
10
|
+
? { _tag: "ApiKey" }
|
|
11
|
+
: check?.type === "oauth"
|
|
12
|
+
? { _tag: "OAuth", subscription }
|
|
13
|
+
: undefined;
|
|
14
|
+
/** Returns the billing pool that a Pi provider requires; checked before launch. */
|
|
2
15
|
export const requiredPiPool = (provider) => provider === "openai-codex" ? "chatgptPlan" : "apiKeys";
|
|
3
|
-
/** Returns the billing pool of the credential
|
|
16
|
+
/** Returns the billing pool of the credential used for the model request, or `undefined` if it is neither an API key nor a subscription login to `openai-codex`. */
|
|
4
17
|
export const resolvePiPool = (provider, authentication) => {
|
|
5
18
|
if (authentication?._tag === "ApiKey")
|
|
6
19
|
return "apiKeys";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../src/pi/authentication.ts"],"names":[],"mappings":"AAOA,
|
|
1
|
+
{"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../src/pi/authentication.ts"],"names":[],"mappings":"AAOA,qGAAqG;AACrG,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,KAAa,EACwD,EAAE;IACvE,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,SAAS,IAAI,CAAC,IAAI,SAAS,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC;QACrD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC;AACnF,CAAC,CAAC;AAEF,mJAAmJ;AACnJ,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,KAAyD,EACzD,YAAqB,EACS,EAAE,CAChC,KAAK,EAAE,IAAI,KAAK,SAAS;IACvB,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE;IACpB,CAAC,CAAC,KAAK,EAAE,IAAI,KAAK,OAAO;QACvB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE;QACjC,CAAC,CAAC,SAAS,CAAC;AAElB,mFAAmF;AACnF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAgB,EAAU,EAAE,CACzD,QAAQ,KAAK,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;AAE1D,oKAAoK;AACpK,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,QAAgB,EAChB,cAA4C,EACxB,EAAE;IACtB,IAAI,cAAc,EAAE,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACxD,IACE,cAAc,EAAE,IAAI,KAAK,OAAO;QAChC,cAAc,CAAC,YAAY;QAC3B,QAAQ,KAAK,cAAc,EAC3B,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC"}
|
package/dist/pi/children.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { Layer } from "effect";
|
|
2
2
|
import { ChildBackend, ClaudeChildBackend, CodexChildBackend, PiChildBackend } from "../runtime.ts";
|
|
3
|
-
/**
|
|
4
|
-
* Selects Claude Code, Codex, or Pi for each delegated task from the Agent's harness.
|
|
5
|
-
* Supply the three backend layers here, or use a concrete backend directly.
|
|
6
|
-
*/
|
|
3
|
+
/** Dispatches each delegated task to the Claude Code, Codex, or Pi backend according to the Agent's harness; requires all three backend layers. */
|
|
7
4
|
export declare const childDispatcherLayer: Layer.Layer<ChildBackend, never, ClaudeChildBackend | CodexChildBackend | PiChildBackend>;
|
|
8
5
|
//# sourceMappingURL=children.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"children.d.ts","sourceRoot":"","sources":["../../src/pi/children.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAyBpG
|
|
1
|
+
{"version":3,"file":"children.d.ts","sourceRoot":"","sources":["../../src/pi/children.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAyBpG,mJAAmJ;AACnJ,eAAO,MAAM,oBAAoB,2FAAkD,CAAC"}
|
package/dist/pi/children.js
CHANGED
|
@@ -21,9 +21,6 @@ const makeChildDispatcher = Effect.gen(function* () {
|
|
|
21
21
|
}),
|
|
22
22
|
});
|
|
23
23
|
});
|
|
24
|
-
/**
|
|
25
|
-
* Selects Claude Code, Codex, or Pi for each delegated task from the Agent's harness.
|
|
26
|
-
* Supply the three backend layers here, or use a concrete backend directly.
|
|
27
|
-
*/
|
|
24
|
+
/** Dispatches each delegated task to the Claude Code, Codex, or Pi backend according to the Agent's harness; requires all three backend layers. */
|
|
28
25
|
export const childDispatcherLayer = Layer.effect(ChildBackend, makeChildDispatcher);
|
|
29
26
|
//# sourceMappingURL=children.js.map
|
package/dist/pi/children.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"children.js","sourceRoot":"","sources":["../../src/pi/children.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpG,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,kBAAkB,CAAC;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC;IACvC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;IAEjC,OAAO,YAAY,CAAC,EAAE,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO;YACzD,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,2BAA2B,EAAE;gBAClD,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;gBACtC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;aAC9B,CAAC,CAAC;YACH,QAAQ,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBACtC,KAAK,QAAQ;oBACX,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACvC,KAAK,OAAO;oBACV,OAAO,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACtC,KAAK,IAAI;oBACP,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACrC,CAAC;QACH,CAAC,CAAC;KACH,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"children.js","sourceRoot":"","sources":["../../src/pi/children.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpG,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,kBAAkB,CAAC;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC;IACvC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;IAEjC,OAAO,YAAY,CAAC,EAAE,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO;YACzD,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,2BAA2B,EAAE;gBAClD,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;gBACtC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;aAC9B,CAAC,CAAC;YACH,QAAQ,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBACtC,KAAK,QAAQ;oBACX,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACvC,KAAK,OAAO;oBACV,OAAO,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACtC,KAAK,IAAI;oBACP,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACrC,CAAC;QACH,CAAC,CAAC;KACH,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,mJAAmJ;AACnJ,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC"}
|
package/dist/pi/claude.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Options } from "@anthropic-ai/claude-agent-sdk";
|
|
2
2
|
import { Context, Layer, Schema } from "effect";
|
|
3
|
-
import { ClaudeChildBackend, ChildBackend } from "../runtime.ts";
|
|
3
|
+
import { ClaudeChildBackend, ClaudeLoginLock, ChildBackend } from "../runtime.ts";
|
|
4
4
|
export interface ClaudeUserMessage {
|
|
5
5
|
readonly type: "user";
|
|
6
6
|
readonly message: {
|
|
@@ -9,12 +9,12 @@ export interface ClaudeUserMessage {
|
|
|
9
9
|
};
|
|
10
10
|
readonly parent_tool_use_id: null;
|
|
11
11
|
}
|
|
12
|
-
export type ClaudeQueryOptions = Pick<Options, "allowDangerouslySkipPermissions" | "cwd" | "effort" | "model" | "pathToClaudeCodeExecutable" | "permissionMode" | "persistSession" | "settingSources" | "thinking" | "hooks">;
|
|
12
|
+
export type ClaudeQueryOptions = Pick<Options, "allowDangerouslySkipPermissions" | "cwd" | "effort" | "env" | "model" | "pathToClaudeCodeExecutable" | "permissionMode" | "persistSession" | "settingSources" | "spawnClaudeCodeProcess" | "thinking" | "hooks">;
|
|
13
13
|
export interface ClaudeModelInfo {
|
|
14
14
|
readonly value: string;
|
|
15
15
|
readonly resolvedModel?: string;
|
|
16
16
|
}
|
|
17
|
-
/** A
|
|
17
|
+
/** A running Claude Code session: its message stream, model list, and stop controls. */
|
|
18
18
|
export interface ClaudeQuery extends AsyncIterable<Schema.Json> {
|
|
19
19
|
readonly close: () => void;
|
|
20
20
|
readonly interrupt: () => Promise<void>;
|
|
@@ -23,14 +23,13 @@ export interface ClaudeQuery extends AsyncIterable<Schema.Json> {
|
|
|
23
23
|
declare const ClaudeSdk_base: Context.ServiceClass<ClaudeSdk, "@usine/agents/pi/ClaudeSdk", {
|
|
24
24
|
readonly open: (input: AsyncIterable<ClaudeUserMessage>, options: ClaudeQueryOptions) => ClaudeQuery;
|
|
25
25
|
}>;
|
|
26
|
-
/**
|
|
26
|
+
/** The service that opens Claude Code sessions. */
|
|
27
27
|
export declare class ClaudeSdk extends ClaudeSdk_base {
|
|
28
28
|
}
|
|
29
|
-
/** Provides Claude Code's session creation and model discovery. */
|
|
30
29
|
export declare const claudeSdkLive: Layer.Layer<ClaudeSdk, never, never>;
|
|
31
|
-
/**
|
|
32
|
-
export declare const claudeChildLayer: Layer.Layer<ChildBackend, never, ClaudeSdk>;
|
|
33
|
-
/** Provides
|
|
34
|
-
export declare const claudeChildBackendLayer: Layer.Layer<ClaudeChildBackend, never, ClaudeSdk>;
|
|
30
|
+
/** Provides `ChildBackend` with Claude Code for every delegated task. */
|
|
31
|
+
export declare const claudeChildLayer: Layer.Layer<ChildBackend, never, ClaudeLoginLock | ClaudeSdk>;
|
|
32
|
+
/** Provides `ClaudeChildBackend` for direct use or harness-based dispatch. */
|
|
33
|
+
export declare const claudeChildBackendLayer: Layer.Layer<ClaudeChildBackend, never, ClaudeLoginLock | ClaudeSdk>;
|
|
35
34
|
export {};
|
|
36
35
|
//# sourceMappingURL=claude.d.ts.map
|
package/dist/pi/claude.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/pi/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/pi/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,OAAO,EAMb,MAAM,gCAAgC,CAAC;AAiBxC,OAAO,EAEL,OAAO,EAMP,KAAK,EAKL,MAAM,EAGP,MAAM,QAAQ,CAAC;AAChB,OAAO,EAEL,kBAAkB,EAClB,eAAe,EACf,YAAY,EAKb,MAAM,eAAe,CAAC;AAMvB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,QAAQ,CAAC,kBAAkB,EAAE,IAAI,CAAC;CACnC;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,OAAO,EACL,iCAAiC,GACjC,KAAK,GACL,QAAQ,GACR,KAAK,GACL,OAAO,GACP,4BAA4B,GAC5B,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,wBAAwB,GACxB,UAAU,GACV,OAAO,CACV,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,wFAAwF;AACxF,MAAM,WAAW,WAAY,SAAQ,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC;IAC7D,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;CACzE;;mBAMkB,CACb,KAAK,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACvC,OAAO,EAAE,kBAAkB,KACxB,WAAW;;AAPpB,mDAAmD;AACnD,qBAAa,SAAU,SAAQ,cAQE;CAAG;AAOpC,eAAO,MAAM,aAAa,sCAexB,CAAC;AAsvBH,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,+DAA8C,CAAC;AAC5E,8EAA8E;AAC9E,eAAO,MAAM,uBAAuB,qEAAoD,CAAC"}
|