@ai-sdk/harness-pi 1.0.108 → 1.0.110
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/CHANGELOG.md +24 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.js +65 -18
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/pi-harness.ts +14 -4
- package/src/pi-model-resolver.ts +9 -7
- package/src/pi-session.ts +29 -5
- package/src/pi-subscription.ts +27 -0
- package/src/pi-translate.ts +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @ai-sdk/harness-pi
|
|
2
2
|
|
|
3
|
+
## 1.0.110
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3df6dc6: fix(harness-pi): initialize cold resumed sessions before compaction
|
|
8
|
+
- 3cd6dd8: fix(harness-pi): surface terminal provider errors before successful step boundaries
|
|
9
|
+
- cdc12a1: feat(harness): add support for using adapter-native subscriptions where available
|
|
10
|
+
- c550630: fix(harness-pi): register explicit custom provider models and prefer authenticated providers during model resolution
|
|
11
|
+
- Updated dependencies [4d1bf28]
|
|
12
|
+
- Updated dependencies [cdc12a1]
|
|
13
|
+
- Updated dependencies [d70a334]
|
|
14
|
+
- Updated dependencies [81ba84c]
|
|
15
|
+
- Updated dependencies [813bb36]
|
|
16
|
+
- Updated dependencies [c43e4b7]
|
|
17
|
+
- @ai-sdk/harness@1.0.108
|
|
18
|
+
- @ai-sdk/provider-utils@5.0.40
|
|
19
|
+
|
|
20
|
+
## 1.0.109
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- @ai-sdk/harness@1.0.107
|
|
25
|
+
- @ai-sdk/provider-utils@5.0.39
|
|
26
|
+
|
|
3
27
|
## 1.0.108
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _ai_sdk_harness from '@ai-sdk/harness';
|
|
2
2
|
import { HarnessV1Authentication, HarnessV1, HarnessV1BuiltinTool } from '@ai-sdk/harness';
|
|
3
|
-
import { ExtensionFactory } from '@earendil-works/pi-coding-agent';
|
|
3
|
+
import { ProviderConfig, ExtensionFactory } from '@earendil-works/pi-coding-agent';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Pi auth options. Choose an explicit mode or rely on 'auto' (precedence:
|
|
@@ -17,6 +17,12 @@ type PiThinkingLevel = 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' |
|
|
|
17
17
|
type PiHarnessSettings = {
|
|
18
18
|
/** Where Pi sources API keys / gateway credentials from. */
|
|
19
19
|
readonly auth?: PiAuthenticationMode;
|
|
20
|
+
/**
|
|
21
|
+
* Explicit Pi provider configurations keyed by provider id. Use this to
|
|
22
|
+
* register custom models and their API protocol without coupling model
|
|
23
|
+
* metadata to authentication environment variables.
|
|
24
|
+
*/
|
|
25
|
+
readonly providers?: Readonly<Record<string, ProviderConfig>>;
|
|
20
26
|
/**
|
|
21
27
|
* Pi's extended-thinking budget level. Maps directly to the SDK's
|
|
22
28
|
* `thinkingLevel` option on `createAgentSession`.
|
|
@@ -24,9 +30,9 @@ type PiHarnessSettings = {
|
|
|
24
30
|
readonly thinkingLevel?: PiThinkingLevel;
|
|
25
31
|
/**
|
|
26
32
|
* Directory holding Pi's global agent config (auth.json, models.json,
|
|
27
|
-
* settings.json). When omitted,
|
|
28
|
-
*
|
|
29
|
-
*
|
|
33
|
+
* settings.json). When omitted, native subscription auth is discovered from
|
|
34
|
+
* Pi's default agent directory while model and general settings remain
|
|
35
|
+
* isolated per session.
|
|
30
36
|
*/
|
|
31
37
|
readonly agentDir?: string;
|
|
32
38
|
/**
|
package/dist/index.js
CHANGED
|
@@ -136,7 +136,7 @@ import {
|
|
|
136
136
|
import { access } from "fs/promises";
|
|
137
137
|
|
|
138
138
|
// src/version.ts
|
|
139
|
-
var VERSION = true ? "1.0.
|
|
139
|
+
var VERSION = true ? "1.0.110" : "0.0.0-test";
|
|
140
140
|
|
|
141
141
|
// src/pi-auth.ts
|
|
142
142
|
var DEFAULT_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh";
|
|
@@ -534,6 +534,28 @@ async function registerCustomProviders({
|
|
|
534
534
|
}
|
|
535
535
|
}
|
|
536
536
|
|
|
537
|
+
// src/pi-subscription.ts
|
|
538
|
+
import { homedir } from "os";
|
|
539
|
+
import { resolve } from "path";
|
|
540
|
+
import { isHarnessAuthenticationEnvironment as isHarnessAuthenticationEnvironment2 } from "@ai-sdk/harness/utils";
|
|
541
|
+
function resolvePiSubscriptionAgentDir({
|
|
542
|
+
options,
|
|
543
|
+
env,
|
|
544
|
+
agentDir,
|
|
545
|
+
homeDirectory = homedir()
|
|
546
|
+
}) {
|
|
547
|
+
if (isHarnessAuthenticationEnvironment2(options) || options === "ai-gateway") {
|
|
548
|
+
return void 0;
|
|
549
|
+
}
|
|
550
|
+
const resolvedEnvironment = resolvePiEnv({ options, env });
|
|
551
|
+
if (resolvedEnvironment.AI_GATEWAY_API_KEY != null) {
|
|
552
|
+
return void 0;
|
|
553
|
+
}
|
|
554
|
+
return resolve(
|
|
555
|
+
agentDir ?? env.PI_CODING_AGENT_DIR ?? `${homeDirectory}/.pi/agent`
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
|
|
537
559
|
// src/pi-events.ts
|
|
538
560
|
import { z as z2 } from "zod/v4";
|
|
539
561
|
var piSessionEventSchema = z2.looseObject({
|
|
@@ -662,13 +684,14 @@ function createPiModelResolver({
|
|
|
662
684
|
const gatewayMatch = useGateway ? models.find((m) => m.provider === "vercel-ai-gateway" && matches(m)) : void 0;
|
|
663
685
|
if (gatewayMatch) return gatewayMatch;
|
|
664
686
|
const scopedMatch = findScopedMatch(effectiveId, models);
|
|
665
|
-
if (scopedMatch &&
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
687
|
+
if (scopedMatch && modelRegistry.hasConfiguredAuth(scopedMatch)) {
|
|
688
|
+
return scopedMatch;
|
|
689
|
+
}
|
|
690
|
+
const authenticatedFlatMatches = models.filter(
|
|
691
|
+
(m) => matches(m) && modelRegistry.hasConfiguredAuth(m)
|
|
692
|
+
);
|
|
693
|
+
if (authenticatedFlatMatches.length === 1) {
|
|
694
|
+
return authenticatedFlatMatches[0];
|
|
672
695
|
}
|
|
673
696
|
return scopedMatch ?? models.find(matches);
|
|
674
697
|
};
|
|
@@ -1286,7 +1309,9 @@ function translatePiEvent(event, state) {
|
|
|
1286
1309
|
} else {
|
|
1287
1310
|
state.pendingStepToolCallIds.clear();
|
|
1288
1311
|
state.stepToolCallCount = void 0;
|
|
1289
|
-
|
|
1312
|
+
if (!getPiTerminalError(event)) {
|
|
1313
|
+
parts.push(...finishStep(state));
|
|
1314
|
+
}
|
|
1290
1315
|
}
|
|
1291
1316
|
return parts;
|
|
1292
1317
|
}
|
|
@@ -2168,9 +2193,14 @@ async function createPiSession(input) {
|
|
|
2168
2193
|
readableRoots: [{ sandboxDir: sandboxSkillRootDir }]
|
|
2169
2194
|
});
|
|
2170
2195
|
const agentDir = input.agentDir ?? hostAgentDir;
|
|
2196
|
+
const nativeAgentDir = resolvePiSubscriptionAgentDir({
|
|
2197
|
+
options: input.settings.auth,
|
|
2198
|
+
env: process.env,
|
|
2199
|
+
agentDir: input.agentDir
|
|
2200
|
+
});
|
|
2171
2201
|
const modelRuntime = await createPiModelRuntime({
|
|
2172
2202
|
auth: input.settings.auth,
|
|
2173
|
-
authPath: path6.join(
|
|
2203
|
+
authPath: path6.join(nativeAgentDir ?? hostAgentDir, "auth.json"),
|
|
2174
2204
|
modelsPath: path6.join(agentDir, "models.json")
|
|
2175
2205
|
});
|
|
2176
2206
|
const modelRegistry = new ModelRegistry(modelRuntime);
|
|
@@ -2189,6 +2219,14 @@ async function createPiSession(input) {
|
|
|
2189
2219
|
clientApp: input.clientApp,
|
|
2190
2220
|
headers: input.settings.headers
|
|
2191
2221
|
});
|
|
2222
|
+
for (const [provider, config] of Object.entries(
|
|
2223
|
+
input.settings.providers ?? {}
|
|
2224
|
+
)) {
|
|
2225
|
+
modelRegistry.registerProvider(provider, {
|
|
2226
|
+
...modelRegistry.getRegisteredProviderConfig(provider),
|
|
2227
|
+
...config
|
|
2228
|
+
});
|
|
2229
|
+
}
|
|
2192
2230
|
const resolveModel = createPiModelResolver({
|
|
2193
2231
|
modelRegistry,
|
|
2194
2232
|
env: resolverEnv
|
|
@@ -2405,8 +2443,8 @@ async function createPiSession(input) {
|
|
|
2405
2443
|
deferredRerun?.cancel();
|
|
2406
2444
|
let resolveDone;
|
|
2407
2445
|
let rejectDone;
|
|
2408
|
-
const done = new Promise((
|
|
2409
|
-
resolveDone =
|
|
2446
|
+
const done = new Promise((resolve2, reject) => {
|
|
2447
|
+
resolveDone = resolve2;
|
|
2410
2448
|
rejectDone = reject;
|
|
2411
2449
|
});
|
|
2412
2450
|
let settled = false;
|
|
@@ -2538,8 +2576,8 @@ async function createPiSession(input) {
|
|
|
2538
2576
|
currentEmit?.(part);
|
|
2539
2577
|
}
|
|
2540
2578
|
}
|
|
2541
|
-
return new Promise((
|
|
2542
|
-
pendingToolApprovals.set(args.toolCallId, { resolve });
|
|
2579
|
+
return new Promise((resolve2) => {
|
|
2580
|
+
pendingToolApprovals.set(args.toolCallId, { resolve: resolve2 });
|
|
2543
2581
|
});
|
|
2544
2582
|
}
|
|
2545
2583
|
function buildToolDefinitions(userTools) {
|
|
@@ -2579,7 +2617,7 @@ async function createPiSession(input) {
|
|
|
2579
2617
|
let resourcesReloaded = false;
|
|
2580
2618
|
if (piSession) {
|
|
2581
2619
|
await disposePiSession();
|
|
2582
|
-
await new Promise((
|
|
2620
|
+
await new Promise((resolve2) => setTimeout(resolve2, 25));
|
|
2583
2621
|
if (hasExtensionFactories) {
|
|
2584
2622
|
await resourceLoader.reload();
|
|
2585
2623
|
resourcesReloaded = true;
|
|
@@ -2889,7 +2927,15 @@ async function createPiSession(input) {
|
|
|
2889
2927
|
if (stopped) {
|
|
2890
2928
|
throw new Error("Pi session has been stopped.");
|
|
2891
2929
|
}
|
|
2892
|
-
|
|
2930
|
+
if (piSession == null) {
|
|
2931
|
+
await rebuildPiSession([], true);
|
|
2932
|
+
lastToolsSignature = JSON.stringify([]);
|
|
2933
|
+
}
|
|
2934
|
+
const session = piSession;
|
|
2935
|
+
if (session == null) {
|
|
2936
|
+
throw new Error("Pi session failed to initialize.");
|
|
2937
|
+
}
|
|
2938
|
+
await session.compact(customInstructions);
|
|
2893
2939
|
},
|
|
2894
2940
|
doDestroy: async () => {
|
|
2895
2941
|
if (stopped) return;
|
|
@@ -3207,8 +3253,8 @@ function buildUserToolDefinition(spec, pending) {
|
|
|
3207
3253
|
description: spec.description ?? `User-registered tool ${spec.name}`,
|
|
3208
3254
|
parameters: toolSpecToTypeBoxParameters(schema),
|
|
3209
3255
|
async execute(toolCallId) {
|
|
3210
|
-
return new Promise((
|
|
3211
|
-
pending.set(toolCallId, { resolve });
|
|
3256
|
+
return new Promise((resolve2) => {
|
|
3257
|
+
pending.set(toolCallId, { resolve: resolve2 });
|
|
3212
3258
|
}).then((output) => asPiToolResult(serializeToolOutput(output)));
|
|
3213
3259
|
}
|
|
3214
3260
|
});
|
|
@@ -3309,6 +3355,7 @@ function createPi(settings = {}) {
|
|
|
3309
3355
|
...settings.auth ? { auth: settings.auth } : {},
|
|
3310
3356
|
...settings.thinkingLevel ? { thinkingLevel: settings.thinkingLevel } : {},
|
|
3311
3357
|
...settings.mcpServers ? { mcpServers: settings.mcpServers } : {},
|
|
3358
|
+
...settings.providers ? { providers: settings.providers } : {},
|
|
3312
3359
|
...settings.extensionFactories ? { extensionFactories: settings.extensionFactories } : {},
|
|
3313
3360
|
...startOpts.headers ? { headers: startOpts.headers } : {}
|
|
3314
3361
|
},
|