instar 1.3.342 → 1.3.344
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/dist/commands/init.d.ts +4 -4
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +47 -0
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/setup.d.ts +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js.map +1 -1
- package/dist/core/Config.d.ts +12 -3
- package/dist/core/Config.d.ts.map +1 -1
- package/dist/core/Config.js +40 -6
- package/dist/core/Config.js.map +1 -1
- package/dist/core/FrameworkSessionStore.d.ts +1 -1
- package/dist/core/FrameworkSessionStore.d.ts.map +1 -1
- package/dist/core/PiCliIntelligenceProvider.d.ts +52 -0
- package/dist/core/PiCliIntelligenceProvider.d.ts.map +1 -0
- package/dist/core/PiCliIntelligenceProvider.js +71 -0
- package/dist/core/PiCliIntelligenceProvider.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +14 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/PreCompactionFlush.d.ts +1 -1
- package/dist/core/PreCompactionFlush.d.ts.map +1 -1
- package/dist/core/ResumeValidator.d.ts +1 -1
- package/dist/core/ResumeValidator.d.ts.map +1 -1
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +35 -1
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/TopicFrameworksStore.d.ts.map +1 -1
- package/dist/core/TopicFrameworksStore.js +3 -0
- package/dist/core/TopicFrameworksStore.js.map +1 -1
- package/dist/core/frameworkInjectionProcesses.d.ts.map +1 -1
- package/dist/core/frameworkInjectionProcesses.js +4 -0
- package/dist/core/frameworkInjectionProcesses.js.map +1 -1
- package/dist/core/frameworkSessionLaunch.d.ts +8 -0
- package/dist/core/frameworkSessionLaunch.d.ts.map +1 -1
- package/dist/core/frameworkSessionLaunch.js +73 -0
- package/dist/core/frameworkSessionLaunch.js.map +1 -1
- package/dist/core/intelligenceProviderFactory.d.ts +15 -1
- package/dist/core/intelligenceProviderFactory.d.ts.map +1 -1
- package/dist/core/intelligenceProviderFactory.js +39 -1
- package/dist/core/intelligenceProviderFactory.js.map +1 -1
- package/dist/core/types.d.ts +18 -7
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/messaging/shared/telegramRelayPrompt.d.ts +1 -1
- package/dist/messaging/shared/telegramRelayPrompt.d.ts.map +1 -1
- package/dist/monitoring/SessionReaper.d.ts +1 -1
- package/dist/monitoring/SessionReaper.d.ts.map +1 -1
- package/dist/monitoring/SessionReaper.js.map +1 -1
- package/dist/monitoring/frameworkActivitySignals.d.ts.map +1 -1
- package/dist/monitoring/frameworkActivitySignals.js +21 -0
- package/dist/monitoring/frameworkActivitySignals.js.map +1 -1
- package/dist/monitoring/frameworkProcessSignals.d.ts.map +1 -1
- package/dist/monitoring/frameworkProcessSignals.js +22 -0
- package/dist/monitoring/frameworkProcessSignals.js.map +1 -1
- package/dist/providers/adapters/pi-cli/capabilities.d.ts +31 -0
- package/dist/providers/adapters/pi-cli/capabilities.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/capabilities.js +40 -0
- package/dist/providers/adapters/pi-cli/capabilities.js.map +1 -0
- package/dist/providers/adapters/pi-cli/config.d.ts +65 -0
- package/dist/providers/adapters/pi-cli/config.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/config.js +43 -0
- package/dist/providers/adapters/pi-cli/config.js.map +1 -0
- package/dist/providers/adapters/pi-cli/control/piHardKill.d.ts +19 -0
- package/dist/providers/adapters/pi-cli/control/piHardKill.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/control/piHardKill.js +67 -0
- package/dist/providers/adapters/pi-cli/control/piHardKill.js.map +1 -0
- package/dist/providers/adapters/pi-cli/errors.d.ts +43 -0
- package/dist/providers/adapters/pi-cli/errors.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/errors.js +71 -0
- package/dist/providers/adapters/pi-cli/errors.js.map +1 -0
- package/dist/providers/adapters/pi-cli/index.d.ts +39 -0
- package/dist/providers/adapters/pi-cli/index.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/index.js +69 -0
- package/dist/providers/adapters/pi-cli/index.js.map +1 -0
- package/dist/providers/adapters/pi-cli/observability/sessionId.d.ts +27 -0
- package/dist/providers/adapters/pi-cli/observability/sessionId.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/observability/sessionId.js +53 -0
- package/dist/providers/adapters/pi-cli/observability/sessionId.js.map +1 -0
- package/dist/providers/adapters/pi-cli/policy.d.ts +44 -0
- package/dist/providers/adapters/pi-cli/policy.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/policy.js +74 -0
- package/dist/providers/adapters/pi-cli/policy.js.map +1 -0
- package/dist/providers/adapters/pi-cli/transport/agenticSessionRpc.d.ts +34 -0
- package/dist/providers/adapters/pi-cli/transport/agenticSessionRpc.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/transport/agenticSessionRpc.js +194 -0
- package/dist/providers/adapters/pi-cli/transport/agenticSessionRpc.js.map +1 -0
- package/dist/providers/adapters/pi-cli/transport/oneShotCompletion.d.ts +33 -0
- package/dist/providers/adapters/pi-cli/transport/oneShotCompletion.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/transport/oneShotCompletion.js +166 -0
- package/dist/providers/adapters/pi-cli/transport/oneShotCompletion.js.map +1 -0
- package/dist/providers/adapters/pi-cli/transport/piSpawn.d.ts +87 -0
- package/dist/providers/adapters/pi-cli/transport/piSpawn.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/transport/piSpawn.js +242 -0
- package/dist/providers/adapters/pi-cli/transport/piSpawn.js.map +1 -0
- package/dist/providers/adapters/pi-cli/transport/rpcClient.d.ts +103 -0
- package/dist/providers/adapters/pi-cli/transport/rpcClient.d.ts.map +1 -0
- package/dist/providers/adapters/pi-cli/transport/rpcClient.js +238 -0
- package/dist/providers/adapters/pi-cli/transport/rpcClient.js.map +1 -0
- package/dist/providers/bootRegistration.d.ts +38 -0
- package/dist/providers/bootRegistration.d.ts.map +1 -1
- package/dist/providers/bootRegistration.js +52 -0
- package/dist/providers/bootRegistration.js.map +1 -1
- package/dist/providers/parity/rules/skillParityRule.d.ts.map +1 -1
- package/dist/providers/parity/rules/skillParityRule.js +6 -0
- package/dist/providers/parity/rules/skillParityRule.js.map +1 -1
- package/dist/redteam/ScenarioPack.d.ts +161 -0
- package/dist/redteam/ScenarioPack.d.ts.map +1 -0
- package/dist/redteam/ScenarioPack.js +200 -0
- package/dist/redteam/ScenarioPack.js.map +1 -0
- package/dist/scaffold/templates.js +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +20 -20
- package/src/scaffold/templates.ts +1 -1
- package/upgrades/1.3.343.md +49 -0
- package/upgrades/1.3.344.md +46 -0
- package/upgrades/side-effects/pi-harness-integration.md +82 -0
- package/upgrades/side-effects/redteam-harness-phase1-core.md +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionId.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/pi-cli/observability/sessionId.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,eAAe,GAAG,IAAI,GAAG,EAAyB,CAAC;AACzD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAyB,CAAC;AAEzD,MAAM,cAAc;IACT,UAAU,GAAG,cAAc,CAAC,SAAS,CAAC;IAE/C,KAAK,CAAC,aAAa,CAAC,OAAsB,EAAE,QAA8B;QACxE,OAAO,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,iBAAyB,EAAE,QAA8B;QACvE,OAAO,eAAe,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC;IACxD,CAAC;CACF;AAED,wDAAwD;AACxD,MAAM,UAAU,eAAe,CAAC,MAAqB,EAAE,SAAiB;IACtE,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACvC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,OAAO,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;AAChD,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,2BAA2B,CAAC,SAAiB;IAC3D,OAAO,aAAa,CAAC,GAAG,SAAS,YAAY,SAAS,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,OAAO,aAAa,CAAC,GAAG,SAAS,QAAQ,GAAG,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,cAAc,EAAE,CAAC;AAC9B,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,qBAAqB;IACnC,eAAe,CAAC,KAAK,EAAE,CAAC;IACxB,eAAe,CAAC,KAAK,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-cli routing policy — the STRUCTURAL subscription guard
|
|
3
|
+
* (PI-HARNESS-INTEGRATION-SPEC §4.3; Justin's additive-only constraint,
|
|
4
|
+
* topic 20390, 2026-06-06).
|
|
5
|
+
*
|
|
6
|
+
* THE RULE: Claude work stays on Claude Code. Anthropic counts only Claude
|
|
7
|
+
* Code itself against plan limits — a third-party harness like pi bills
|
|
8
|
+
* Claude Pro/Max usage as per-token EXTRA USAGE. Routing an instar component
|
|
9
|
+
* through pi onto an Anthropic provider would therefore silently convert
|
|
10
|
+
* subscription-covered work into billed work. That must be structurally
|
|
11
|
+
* impossible by default, not a configuration accident.
|
|
12
|
+
*
|
|
13
|
+
* Enforcement point: every pi call-construction path (one-shot transport,
|
|
14
|
+
* RPC session start, intelligence provider) calls `assertPiProviderAllowed`
|
|
15
|
+
* BEFORE spawning. The check is deliberately conservative: it denies any
|
|
16
|
+
* model pattern that names Anthropic or Claude in ANY segment — including
|
|
17
|
+
* pass-through aggregators (`openrouter/anthropic/claude-*`), which would
|
|
18
|
+
* bill an API key and violate the no-API-keys rule from the other side.
|
|
19
|
+
*
|
|
20
|
+
* Override: `piCli.allowAnthropicProviders: true` in config — explicit,
|
|
21
|
+
* file-based, never via env var or per-call parameter. Even when allowed,
|
|
22
|
+
* the call is audit-logged with a cost warning so the spend is visible.
|
|
23
|
+
* A false positive costs one explicit config line; a false negative costs
|
|
24
|
+
* silent real money. Deny wins ties.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Decide whether a pi `--model` pattern (a `provider/id` string, a bare
|
|
28
|
+
* model id, or pi's pattern syntax with an optional `:<thinking>` suffix)
|
|
29
|
+
* routes to an Anthropic/Claude target.
|
|
30
|
+
*
|
|
31
|
+
* Exported for tests; production callers use `assertPiProviderAllowed`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isAnthropicRoutedModelPattern(modelPattern: string | undefined): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Throw `PiAnthropicRouteError` when the model pattern routes to Anthropic
|
|
36
|
+
* and the explicit override is not set. On an allowed-by-override call, the
|
|
37
|
+
* audit logger is invoked so the extra-usage spend stays visible.
|
|
38
|
+
*/
|
|
39
|
+
export declare function assertPiProviderAllowed(modelPattern: string | undefined, options?: {
|
|
40
|
+
allowAnthropicProviders?: boolean;
|
|
41
|
+
/** Audit sink for override-allowed calls. Defaults to console.warn. */
|
|
42
|
+
auditLog?: (line: string) => void;
|
|
43
|
+
}): void;
|
|
44
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../../src/providers/adapters/pi-cli/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAYH;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAcvF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,OAAO,GAAE;IACP,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B,GACL,IAAI,CAcN"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-cli routing policy — the STRUCTURAL subscription guard
|
|
3
|
+
* (PI-HARNESS-INTEGRATION-SPEC §4.3; Justin's additive-only constraint,
|
|
4
|
+
* topic 20390, 2026-06-06).
|
|
5
|
+
*
|
|
6
|
+
* THE RULE: Claude work stays on Claude Code. Anthropic counts only Claude
|
|
7
|
+
* Code itself against plan limits — a third-party harness like pi bills
|
|
8
|
+
* Claude Pro/Max usage as per-token EXTRA USAGE. Routing an instar component
|
|
9
|
+
* through pi onto an Anthropic provider would therefore silently convert
|
|
10
|
+
* subscription-covered work into billed work. That must be structurally
|
|
11
|
+
* impossible by default, not a configuration accident.
|
|
12
|
+
*
|
|
13
|
+
* Enforcement point: every pi call-construction path (one-shot transport,
|
|
14
|
+
* RPC session start, intelligence provider) calls `assertPiProviderAllowed`
|
|
15
|
+
* BEFORE spawning. The check is deliberately conservative: it denies any
|
|
16
|
+
* model pattern that names Anthropic or Claude in ANY segment — including
|
|
17
|
+
* pass-through aggregators (`openrouter/anthropic/claude-*`), which would
|
|
18
|
+
* bill an API key and violate the no-API-keys rule from the other side.
|
|
19
|
+
*
|
|
20
|
+
* Override: `piCli.allowAnthropicProviders: true` in config — explicit,
|
|
21
|
+
* file-based, never via env var or per-call parameter. Even when allowed,
|
|
22
|
+
* the call is audit-logged with a cost warning so the spend is visible.
|
|
23
|
+
* A false positive costs one explicit config line; a false negative costs
|
|
24
|
+
* silent real money. Deny wins ties.
|
|
25
|
+
*/
|
|
26
|
+
import { PiAnthropicRouteError } from './errors.js';
|
|
27
|
+
/**
|
|
28
|
+
* Segments that mark a model pattern as routing to Anthropic/Claude.
|
|
29
|
+
* Matched case-insensitively against `/`-, `:`- and whitespace-delimited
|
|
30
|
+
* segments of the pattern, AND as a substring of the model id segment
|
|
31
|
+
* (Claude model ids embed the name, e.g. `claude-sonnet-4-6`).
|
|
32
|
+
*/
|
|
33
|
+
const DENIED_NEEDLES = ['anthropic', 'claude'];
|
|
34
|
+
/**
|
|
35
|
+
* Decide whether a pi `--model` pattern (a `provider/id` string, a bare
|
|
36
|
+
* model id, or pi's pattern syntax with an optional `:<thinking>` suffix)
|
|
37
|
+
* routes to an Anthropic/Claude target.
|
|
38
|
+
*
|
|
39
|
+
* Exported for tests; production callers use `assertPiProviderAllowed`.
|
|
40
|
+
*/
|
|
41
|
+
export function isAnthropicRoutedModelPattern(modelPattern) {
|
|
42
|
+
if (!modelPattern) {
|
|
43
|
+
// No explicit model → pi falls back to ITS OWN configured default
|
|
44
|
+
// provider/model, which we cannot see from here. The conservative floor
|
|
45
|
+
// is enforced at the config layer instead: adapter configs must pin a
|
|
46
|
+
// model; the intelligence provider refuses to run without one. Treating
|
|
47
|
+
// undefined as allowed here would let pi's ambient default (potentially
|
|
48
|
+
// an Anthropic login from interactive use) leak through — so undefined
|
|
49
|
+
// is DENIED at this gate too. Callers that legitimately want pi's
|
|
50
|
+
// default must resolve it to an explicit pattern first.
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
const lower = modelPattern.toLowerCase();
|
|
54
|
+
return DENIED_NEEDLES.some((needle) => lower.includes(needle));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Throw `PiAnthropicRouteError` when the model pattern routes to Anthropic
|
|
58
|
+
* and the explicit override is not set. On an allowed-by-override call, the
|
|
59
|
+
* audit logger is invoked so the extra-usage spend stays visible.
|
|
60
|
+
*/
|
|
61
|
+
export function assertPiProviderAllowed(modelPattern, options = {}) {
|
|
62
|
+
if (!isAnthropicRoutedModelPattern(modelPattern)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (options.allowAnthropicProviders === true) {
|
|
66
|
+
const audit = options.auditLog ?? ((line) => console.warn(line));
|
|
67
|
+
audit(`[pi-cli policy] ALLOWED Anthropic-routed pi call by explicit override ` +
|
|
68
|
+
`(piCli.allowAnthropicProviders=true): model=${modelPattern ?? '<pi-default>'} — ` +
|
|
69
|
+
`NOTE: this bills as Anthropic extra usage (per-token), NOT plan limits.`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
throw new PiAnthropicRouteError(modelPattern);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../../src/providers/adapters/pi-cli/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAU,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAAC,YAAgC;IAC5E,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,kEAAkE;QAClE,wEAAwE;QACxE,sEAAsE;QACtE,wEAAwE;QACxE,wEAAwE;QACxE,uEAAuE;QACvE,kEAAkE;QAClE,wDAAwD;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;IACzC,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACrC,YAAgC,EAChC,UAII,EAAE;IAEN,IAAI,CAAC,6BAA6B,CAAC,YAAY,CAAC,EAAE,CAAC;QACjD,OAAO;IACT,CAAC;IACD,IAAI,OAAO,CAAC,uBAAuB,KAAK,IAAI,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzE,KAAK,CACH,wEAAwE;YACxE,+CAA+C,YAAY,IAAI,cAAc,KAAK;YAClF,yEAAyE,CAC1E,CAAC;QACF,OAAO;IACT,CAAC;IACD,MAAM,IAAI,qBAAqB,CAAC,YAAY,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-cli AgenticSessionRpc — the "data cable" primitive
|
|
3
|
+
* (PI-HARNESS-INTEGRATION-SPEC §4.1-4.2).
|
|
4
|
+
*
|
|
5
|
+
* pi's RPC mode is a NATIVE structured-control channel (stdio JSONL with
|
|
6
|
+
* prompt / mid-stream steer / abort), so this is a direct mapping rather
|
|
7
|
+
* than a facade: start() spawns `pi --mode rpc`, startTurn() sends `prompt`,
|
|
8
|
+
* steerTurn() sends `steer`, interruptTurn() sends `abort`, close() ends
|
|
9
|
+
* the process. pi events normalize to the canonical vocabulary:
|
|
10
|
+
*
|
|
11
|
+
* message_update(text_delta) → message-delta
|
|
12
|
+
* tool_execution_start → tool-call
|
|
13
|
+
* tool_execution_end → tool-result
|
|
14
|
+
* turn_end → turn-end (usage from message.usage)
|
|
15
|
+
* agent_start / agent_end / rest → provider-raw (pi run boundaries)
|
|
16
|
+
*
|
|
17
|
+
* The subscription guard (policy.ts) runs at start(): an Anthropic-routed
|
|
18
|
+
* model pattern throws PiAnthropicRouteError before any process spawns.
|
|
19
|
+
*
|
|
20
|
+
* Protocol facts verified hands-on in the P0.1 eval (pi 0.78.1):
|
|
21
|
+
* docs/specs/_drafts/pi-eval-report.md.
|
|
22
|
+
*/
|
|
23
|
+
import type { CanonicalEvent } from '../../../events.js';
|
|
24
|
+
import { type SessionHandle } from '../../../types.js';
|
|
25
|
+
import type { AgenticSessionRpc } from '../../../primitives/transport/agenticSessionRpc.js';
|
|
26
|
+
import type { PiCliConfig } from '../config.js';
|
|
27
|
+
import { type PiRpcEvent } from './rpcClient.js';
|
|
28
|
+
/** Normalize one pi event line to a CanonicalEvent (always returns one). */
|
|
29
|
+
export declare function normalizePiEvent(event: PiRpcEvent, session: SessionHandle): CanonicalEvent;
|
|
30
|
+
/**
|
|
31
|
+
* Build the AgenticSessionRpc primitive for the pi adapter.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createPiAgenticSessionRpc(config: PiCliConfig): AgenticSessionRpc;
|
|
34
|
+
//# sourceMappingURL=agenticSessionRpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agenticSessionRpc.d.ts","sourceRoot":"","sources":["../../../../../src/providers/adapters/pi-cli/transport/agenticSessionRpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EACV,iBAAiB,EAIlB,MAAM,oDAAoD,CAAC;AAI5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAW9D,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,GAAG,cAAc,CA8D1F;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAoHhF"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-cli AgenticSessionRpc — the "data cable" primitive
|
|
3
|
+
* (PI-HARNESS-INTEGRATION-SPEC §4.1-4.2).
|
|
4
|
+
*
|
|
5
|
+
* pi's RPC mode is a NATIVE structured-control channel (stdio JSONL with
|
|
6
|
+
* prompt / mid-stream steer / abort), so this is a direct mapping rather
|
|
7
|
+
* than a facade: start() spawns `pi --mode rpc`, startTurn() sends `prompt`,
|
|
8
|
+
* steerTurn() sends `steer`, interruptTurn() sends `abort`, close() ends
|
|
9
|
+
* the process. pi events normalize to the canonical vocabulary:
|
|
10
|
+
*
|
|
11
|
+
* message_update(text_delta) → message-delta
|
|
12
|
+
* tool_execution_start → tool-call
|
|
13
|
+
* tool_execution_end → tool-result
|
|
14
|
+
* turn_end → turn-end (usage from message.usage)
|
|
15
|
+
* agent_start / agent_end / rest → provider-raw (pi run boundaries)
|
|
16
|
+
*
|
|
17
|
+
* The subscription guard (policy.ts) runs at start(): an Anthropic-routed
|
|
18
|
+
* model pattern throws PiAnthropicRouteError before any process spawns.
|
|
19
|
+
*
|
|
20
|
+
* Protocol facts verified hands-on in the P0.1 eval (pi 0.78.1):
|
|
21
|
+
* docs/specs/_drafts/pi-eval-report.md.
|
|
22
|
+
*/
|
|
23
|
+
import { randomUUID } from 'node:crypto';
|
|
24
|
+
import { CapabilityFlag } from '../../../capabilities.js';
|
|
25
|
+
import { sessionHandle } from '../../../types.js';
|
|
26
|
+
import { PI_CLI_ID } from '../errors.js';
|
|
27
|
+
import { UnexpectedError } from '../../../errors.js';
|
|
28
|
+
import { assertPiProviderAllowed } from '../policy.js';
|
|
29
|
+
import { PiRpcClient } from './rpcClient.js';
|
|
30
|
+
function nowIso() {
|
|
31
|
+
return new Date().toISOString();
|
|
32
|
+
}
|
|
33
|
+
/** Normalize one pi event line to a CanonicalEvent (always returns one). */
|
|
34
|
+
export function normalizePiEvent(event, session) {
|
|
35
|
+
const base = { timestamp: nowIso(), providerId: PI_CLI_ID, session };
|
|
36
|
+
switch (event.type) {
|
|
37
|
+
case 'message_update': {
|
|
38
|
+
const inner = event.assistantMessageEvent;
|
|
39
|
+
if (inner?.type === 'text_delta' && typeof inner.delta === 'string') {
|
|
40
|
+
return { ...base, type: 'message-delta', delta: inner.delta };
|
|
41
|
+
}
|
|
42
|
+
return { ...base, type: 'provider-raw', nativeName: `message_update.${inner?.type ?? 'unknown'}`, payload: event };
|
|
43
|
+
}
|
|
44
|
+
case 'tool_execution_start': {
|
|
45
|
+
const e = event;
|
|
46
|
+
return {
|
|
47
|
+
...base,
|
|
48
|
+
type: 'tool-call',
|
|
49
|
+
toolCallId: String(e.toolCallId ?? e.id ?? 'unknown'),
|
|
50
|
+
toolName: String(e.toolName ?? 'unknown'),
|
|
51
|
+
arguments: e.args ?? e.arguments ?? null,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
case 'tool_execution_end': {
|
|
55
|
+
const e = event;
|
|
56
|
+
return {
|
|
57
|
+
...base,
|
|
58
|
+
type: 'tool-result',
|
|
59
|
+
toolCallId: String(e.toolCallId ?? e.id ?? 'unknown'),
|
|
60
|
+
result: e.result ?? null,
|
|
61
|
+
isError: e.isError === true,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
case 'turn_end': {
|
|
65
|
+
const message = event.message;
|
|
66
|
+
const stop = message?.stopReason;
|
|
67
|
+
const stopReason = stop === 'stop' ? 'end-of-turn'
|
|
68
|
+
: stop === 'toolUse' || stop === 'tool_calls' || stop === 'tool_use' ? 'tool-use'
|
|
69
|
+
: stop === 'maxTokens' || stop === 'max_tokens' ? 'max-tokens'
|
|
70
|
+
: stop === 'aborted' || stop === 'interrupted' ? 'interrupted'
|
|
71
|
+
: 'unknown';
|
|
72
|
+
const usage = message?.usage
|
|
73
|
+
? {
|
|
74
|
+
inputTokens: message.usage.input ?? 0,
|
|
75
|
+
outputTokens: message.usage.output ?? 0,
|
|
76
|
+
...(message.usage.cacheRead !== undefined ? { cachedTokens: message.usage.cacheRead } : {}),
|
|
77
|
+
...(message.usage.cost?.total !== undefined ? { estimatedCostUsd: message.usage.cost.total } : {}),
|
|
78
|
+
}
|
|
79
|
+
: null;
|
|
80
|
+
return { ...base, type: 'turn-end', stopReason, usage };
|
|
81
|
+
}
|
|
82
|
+
case 'error': {
|
|
83
|
+
const e = event;
|
|
84
|
+
return {
|
|
85
|
+
...base,
|
|
86
|
+
type: 'error',
|
|
87
|
+
message: String(e.message ?? e.error ?? 'pi error event'),
|
|
88
|
+
recoverable: true,
|
|
89
|
+
errorKind: 'unknown',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
default:
|
|
93
|
+
return { ...base, type: 'provider-raw', nativeName: String(event.type), payload: event };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Build the AgenticSessionRpc primitive for the pi adapter.
|
|
98
|
+
*/
|
|
99
|
+
export function createPiAgenticSessionRpc(config) {
|
|
100
|
+
const sessions = new Map();
|
|
101
|
+
function requireSession(handle) {
|
|
102
|
+
const live = sessions.get(String(handle));
|
|
103
|
+
if (!live) {
|
|
104
|
+
throw new UnexpectedError(`Unknown pi RPC session handle: ${String(handle)}`, PI_CLI_ID);
|
|
105
|
+
}
|
|
106
|
+
return live;
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
capability: CapabilityFlag.AgenticSessionRpc,
|
|
110
|
+
async start(options) {
|
|
111
|
+
if (options.transport !== 'stdio') {
|
|
112
|
+
throw new UnexpectedError(`pi RPC supports only stdio transport (got "${options.transport}")`, PI_CLI_ID);
|
|
113
|
+
}
|
|
114
|
+
// STRUCTURAL SUBSCRIPTION GUARD (spec §4.3): refuse Anthropic-routed
|
|
115
|
+
// models BEFORE any process exists. ModelTier values resolve to the
|
|
116
|
+
// adapter's configured pattern — the pattern is what gets judged.
|
|
117
|
+
const model = config.model;
|
|
118
|
+
assertPiProviderAllowed(model, {
|
|
119
|
+
...(config.allowAnthropicProviders !== undefined
|
|
120
|
+
? { allowAnthropicProviders: config.allowAnthropicProviders }
|
|
121
|
+
: {}),
|
|
122
|
+
});
|
|
123
|
+
const id = randomUUID();
|
|
124
|
+
const client = PiRpcClient.spawn({
|
|
125
|
+
binaryPath: config.piPath,
|
|
126
|
+
...(model ? { model } : {}),
|
|
127
|
+
...(config.sessionDir ? { sessionDir: config.sessionDir } : { noSession: true }),
|
|
128
|
+
...(options.workingDirectory ? { cwd: options.workingDirectory } : {}),
|
|
129
|
+
});
|
|
130
|
+
client.assertSpawned();
|
|
131
|
+
const handle = sessionHandle(`pi-rpc:${id}`);
|
|
132
|
+
const live = { client, turnCounter: 0 };
|
|
133
|
+
sessions.set(String(handle), live);
|
|
134
|
+
const events = (async function* () {
|
|
135
|
+
yield {
|
|
136
|
+
type: 'session-lifecycle',
|
|
137
|
+
lifecycleKind: 'started',
|
|
138
|
+
timestamp: nowIso(),
|
|
139
|
+
providerId: PI_CLI_ID,
|
|
140
|
+
session: handle,
|
|
141
|
+
};
|
|
142
|
+
for await (const event of client.events()) {
|
|
143
|
+
yield normalizePiEvent(event, handle);
|
|
144
|
+
}
|
|
145
|
+
yield {
|
|
146
|
+
type: 'session-lifecycle',
|
|
147
|
+
lifecycleKind: 'ended',
|
|
148
|
+
timestamp: nowIso(),
|
|
149
|
+
providerId: PI_CLI_ID,
|
|
150
|
+
session: handle,
|
|
151
|
+
};
|
|
152
|
+
})();
|
|
153
|
+
return {
|
|
154
|
+
handle,
|
|
155
|
+
events,
|
|
156
|
+
// pi's RPC is a narrow agent-control channel; there is no codex-style
|
|
157
|
+
// fs/command/plugin control plane behind it.
|
|
158
|
+
hasControlPlane: false,
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
async startTurn(handle, turn, _options) {
|
|
162
|
+
const live = requireSession(handle);
|
|
163
|
+
live.turnCounter += 1;
|
|
164
|
+
const turnId = `turn-${live.turnCounter}`;
|
|
165
|
+
const response = await live.client.prompt(turn.prompt);
|
|
166
|
+
if (!response.success) {
|
|
167
|
+
throw new UnexpectedError(`pi prompt rejected: ${response.error ?? 'unknown error'}`, PI_CLI_ID);
|
|
168
|
+
}
|
|
169
|
+
return { turnId };
|
|
170
|
+
},
|
|
171
|
+
async steerTurn(handle, _turnId, input, _options) {
|
|
172
|
+
const live = requireSession(handle);
|
|
173
|
+
const response = await live.client.steer(input);
|
|
174
|
+
if (!response.success) {
|
|
175
|
+
throw new UnexpectedError(`pi steer rejected: ${response.error ?? 'unknown error'}`, PI_CLI_ID);
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
async interruptTurn(handle, _turnId, _options) {
|
|
179
|
+
const live = requireSession(handle);
|
|
180
|
+
const response = await live.client.abort();
|
|
181
|
+
if (!response.success) {
|
|
182
|
+
throw new UnexpectedError(`pi abort rejected: ${response.error ?? 'unknown error'}`, PI_CLI_ID);
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
async close(handle, _options) {
|
|
186
|
+
const live = sessions.get(String(handle));
|
|
187
|
+
if (!live)
|
|
188
|
+
return; // idempotent close
|
|
189
|
+
sessions.delete(String(handle));
|
|
190
|
+
await live.client.close();
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=agenticSessionRpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agenticSessionRpc.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/pi-cli/transport/agenticSessionRpc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OneShotCompletion implementation for the pi-cli adapter.
|
|
3
|
+
*
|
|
4
|
+
* Spawns the CANONICAL one-shot argv (buildPiOneShotArgv):
|
|
5
|
+
* pi -p --mode json --no-session --offline [--model <pattern>] <prompt>
|
|
6
|
+
* and parses pi's typed JSONL event stream from stdout, extracting the
|
|
7
|
+
* completion text + usage from the assistant's `message_end` event.
|
|
8
|
+
*
|
|
9
|
+
* The argv and the event-stream shape (`message_end` with
|
|
10
|
+
* `message.role==='assistant'`, `message.content[]` text entries,
|
|
11
|
+
* `message.usage`) were verified HANDS-ON in the P0.1 eval (pi 0.78.1,
|
|
12
|
+
* docs/specs/_drafts/pi-eval-report.md) — ground truth, not inferred.
|
|
13
|
+
*
|
|
14
|
+
* SAFETY (pinned at the call site):
|
|
15
|
+
* - `--no-session` / `--offline` are part of the canonical argv; this
|
|
16
|
+
* primitive never writes a session file or fetches binaries.
|
|
17
|
+
* - The env unconditionally hard-deletes every billing-capable provider var
|
|
18
|
+
* (buildPiChildEnv) — the no-API-keys rule.
|
|
19
|
+
* - Output is byte-capped (spawnPiAndWait).
|
|
20
|
+
*
|
|
21
|
+
* Model/tier resolution is PASS-THROUGH for pi: a pi `provider/id` pattern
|
|
22
|
+
* comes from `config.model` (or the per-call `options.model`). The abstract
|
|
23
|
+
* ModelTier vocabulary (`fast`/`balanced`/`capable`) does NOT map to fixed pi
|
|
24
|
+
* model names — tier vocabulary lives INSIDE the configured provider for pi.
|
|
25
|
+
* So a ModelTier resolves to `config.model ?? undefined`, and when undefined
|
|
26
|
+
* pi's own default model applies. (The §4.3 subscription guard — policy.ts —
|
|
27
|
+
* is the gate that refuses Anthropic-routed patterns; it is not invoked from
|
|
28
|
+
* this file.)
|
|
29
|
+
*/
|
|
30
|
+
import type { OneShotCompletion } from '../../../primitives/transport/oneShotCompletion.js';
|
|
31
|
+
import type { PiCliConfig } from '../config.js';
|
|
32
|
+
export declare function createOneShotCompletion(config: PiCliConfig): OneShotCompletion;
|
|
33
|
+
//# sourceMappingURL=oneShotCompletion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oneShotCompletion.d.ts","sourceRoot":"","sources":["../../../../../src/providers/adapters/pi-cli/transport/oneShotCompletion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,oDAAoD,CAAC;AAI5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAyLhD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAE9E"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OneShotCompletion implementation for the pi-cli adapter.
|
|
3
|
+
*
|
|
4
|
+
* Spawns the CANONICAL one-shot argv (buildPiOneShotArgv):
|
|
5
|
+
* pi -p --mode json --no-session --offline [--model <pattern>] <prompt>
|
|
6
|
+
* and parses pi's typed JSONL event stream from stdout, extracting the
|
|
7
|
+
* completion text + usage from the assistant's `message_end` event.
|
|
8
|
+
*
|
|
9
|
+
* The argv and the event-stream shape (`message_end` with
|
|
10
|
+
* `message.role==='assistant'`, `message.content[]` text entries,
|
|
11
|
+
* `message.usage`) were verified HANDS-ON in the P0.1 eval (pi 0.78.1,
|
|
12
|
+
* docs/specs/_drafts/pi-eval-report.md) — ground truth, not inferred.
|
|
13
|
+
*
|
|
14
|
+
* SAFETY (pinned at the call site):
|
|
15
|
+
* - `--no-session` / `--offline` are part of the canonical argv; this
|
|
16
|
+
* primitive never writes a session file or fetches binaries.
|
|
17
|
+
* - The env unconditionally hard-deletes every billing-capable provider var
|
|
18
|
+
* (buildPiChildEnv) — the no-API-keys rule.
|
|
19
|
+
* - Output is byte-capped (spawnPiAndWait).
|
|
20
|
+
*
|
|
21
|
+
* Model/tier resolution is PASS-THROUGH for pi: a pi `provider/id` pattern
|
|
22
|
+
* comes from `config.model` (or the per-call `options.model`). The abstract
|
|
23
|
+
* ModelTier vocabulary (`fast`/`balanced`/`capable`) does NOT map to fixed pi
|
|
24
|
+
* model names — tier vocabulary lives INSIDE the configured provider for pi.
|
|
25
|
+
* So a ModelTier resolves to `config.model ?? undefined`, and when undefined
|
|
26
|
+
* pi's own default model applies. (The §4.3 subscription guard — policy.ts —
|
|
27
|
+
* is the gate that refuses Anthropic-routed patterns; it is not invoked from
|
|
28
|
+
* this file.)
|
|
29
|
+
*/
|
|
30
|
+
import { CapabilityFlag } from '../../../capabilities.js';
|
|
31
|
+
import { AbortError, UnexpectedError } from '../../../errors.js';
|
|
32
|
+
import { PI_CLI_ID, mapExecError } from '../errors.js';
|
|
33
|
+
import { assertPiProviderAllowed } from '../policy.js';
|
|
34
|
+
import { buildPiChildEnv, buildPiOneShotArgv, spawnPiAndWait, } from './piSpawn.js';
|
|
35
|
+
/** The abstract tiers — pass-through for pi (tier lives in the provider). */
|
|
36
|
+
const MODEL_TIERS = new Set(['fast', 'balanced', 'capable']);
|
|
37
|
+
/**
|
|
38
|
+
* Resolve a per-call model selector to a concrete pi `--model` pattern.
|
|
39
|
+
*
|
|
40
|
+
* - A concrete pattern (a `provider/id` string or bare id) passes through.
|
|
41
|
+
* - An abstract ModelTier resolves to `config.model` (pi tiers live in the
|
|
42
|
+
* configured provider, not in a fixed name map) — and to `undefined` when no
|
|
43
|
+
* config.model is set, in which case pi's own default model applies.
|
|
44
|
+
*/
|
|
45
|
+
function resolvePiModel(selector, configModel) {
|
|
46
|
+
if (selector && !MODEL_TIERS.has(selector)) {
|
|
47
|
+
return selector;
|
|
48
|
+
}
|
|
49
|
+
return configModel;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Parse pi's JSONL event stream and return the LAST assistant `message_end`
|
|
53
|
+
* event, or null if none is present. Non-JSON / malformed lines are skipped
|
|
54
|
+
* (pi may interleave a benign non-JSON banner line on stdout).
|
|
55
|
+
*/
|
|
56
|
+
function lastAssistantMessageEnd(stdout) {
|
|
57
|
+
let found = null;
|
|
58
|
+
for (const line of stdout.split('\n')) {
|
|
59
|
+
const trimmed = line.trim();
|
|
60
|
+
if (!trimmed)
|
|
61
|
+
continue;
|
|
62
|
+
let event;
|
|
63
|
+
try {
|
|
64
|
+
event = JSON.parse(trimmed);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (event.type === 'message_end' && event.message?.role === 'assistant') {
|
|
70
|
+
found = event.message;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return found;
|
|
74
|
+
}
|
|
75
|
+
/** Concatenate the `text` of every `type==='text'` content entry. */
|
|
76
|
+
function textFromContent(content) {
|
|
77
|
+
if (!content)
|
|
78
|
+
return '';
|
|
79
|
+
return content
|
|
80
|
+
.filter((c) => c.type === 'text' && typeof c.text === 'string')
|
|
81
|
+
.map((c) => c.text)
|
|
82
|
+
.join('');
|
|
83
|
+
}
|
|
84
|
+
/** Map pi's `message.usage` onto the canonical UsageReport, or null. */
|
|
85
|
+
function usageFromMessage(usage) {
|
|
86
|
+
if (!usage)
|
|
87
|
+
return null;
|
|
88
|
+
const report = {
|
|
89
|
+
inputTokens: usage.input ?? 0,
|
|
90
|
+
outputTokens: usage.output ?? 0,
|
|
91
|
+
};
|
|
92
|
+
if (usage.cacheRead !== undefined)
|
|
93
|
+
report.cachedTokens = usage.cacheRead;
|
|
94
|
+
if (usage.cost?.total !== undefined)
|
|
95
|
+
report.estimatedCostUsd = usage.cost.total;
|
|
96
|
+
return report;
|
|
97
|
+
}
|
|
98
|
+
class PiCliOneShotCompletion {
|
|
99
|
+
config;
|
|
100
|
+
capability = CapabilityFlag.OneShotCompletion;
|
|
101
|
+
constructor(config) {
|
|
102
|
+
this.config = config;
|
|
103
|
+
}
|
|
104
|
+
async evaluate(prompt, options) {
|
|
105
|
+
const timeoutMs = options?.timeoutMs ?? this.config.timeoutMs ?? 60_000;
|
|
106
|
+
const model = resolvePiModel(options?.model, this.config.model);
|
|
107
|
+
// STRUCTURAL SUBSCRIPTION GUARD (PI-HARNESS-INTEGRATION-SPEC §4.3):
|
|
108
|
+
// refuse Anthropic-routed model patterns BEFORE any process spawns —
|
|
109
|
+
// every pi call-construction path enforces this, not just the RPC face.
|
|
110
|
+
assertPiProviderAllowed(model, {
|
|
111
|
+
...(this.config.allowAnthropicProviders !== undefined
|
|
112
|
+
? { allowAnthropicProviders: this.config.allowAnthropicProviders }
|
|
113
|
+
: {}),
|
|
114
|
+
});
|
|
115
|
+
// System prompt is prepended to the user prompt (pi's one-shot `-p` takes a
|
|
116
|
+
// single prompt; there's no separate system flag on this path).
|
|
117
|
+
const effectivePrompt = options?.system
|
|
118
|
+
? `${options.system}\n\n${prompt}`
|
|
119
|
+
: prompt;
|
|
120
|
+
const childEnv = buildPiChildEnv();
|
|
121
|
+
const abortSignal = options?.signal;
|
|
122
|
+
if (abortSignal?.aborted) {
|
|
123
|
+
throw new AbortError('Aborted before start', PI_CLI_ID);
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const args = buildPiOneShotArgv(model, effectivePrompt);
|
|
127
|
+
const result = await spawnPiAndWait(this.config.piPath, args, {
|
|
128
|
+
timeoutMs,
|
|
129
|
+
env: childEnv,
|
|
130
|
+
...(abortSignal ? { signal: abortSignal } : {}),
|
|
131
|
+
...(this.config.maxOutputBytes !== undefined
|
|
132
|
+
? { maxOutputBytes: this.config.maxOutputBytes }
|
|
133
|
+
: {}),
|
|
134
|
+
});
|
|
135
|
+
if (result.exitCode !== 0) {
|
|
136
|
+
throw mapExecError(new Error(`Pi exited ${result.exitCode}`), result.stderr);
|
|
137
|
+
}
|
|
138
|
+
const message = lastAssistantMessageEnd(result.stdout);
|
|
139
|
+
if (!message) {
|
|
140
|
+
throw new UnexpectedError(`pi produced no assistant message_end event` +
|
|
141
|
+
(result.stderr ? `: ${result.stderr.slice(0, 500)}` : ''), PI_CLI_ID);
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
text: textFromContent(message.content).trim(),
|
|
145
|
+
usage: usageFromMessage(message.usage),
|
|
146
|
+
providerSpecific: {
|
|
147
|
+
[PI_CLI_ID]: { model: model ?? null, truncated: result.truncated },
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
if (err instanceof UnexpectedError)
|
|
153
|
+
throw err;
|
|
154
|
+
const error = err;
|
|
155
|
+
if (error.name === 'AbortError' || abortSignal?.aborted) {
|
|
156
|
+
throw new AbortError('Aborted during execution', PI_CLI_ID, err);
|
|
157
|
+
}
|
|
158
|
+
const stderr = String(error.stderr ?? '');
|
|
159
|
+
throw mapExecError(error, stderr);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
export function createOneShotCompletion(config) {
|
|
164
|
+
return new PiCliOneShotCompletion(config);
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=oneShotCompletion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oneShotCompletion.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/pi-cli/transport/oneShotCompletion.ts"],"names":[],"mappings":"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"}
|