@ai-sdk/harness-pi 1.0.95 → 1.0.97

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/harness-pi",
3
- "version": "1.0.95",
3
+ "version": "1.0.97",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -26,8 +26,8 @@
26
26
  }
27
27
  },
28
28
  "dependencies": {
29
- "@ai-sdk/harness": "1.0.93",
30
- "@ai-sdk/provider-utils": "5.0.33",
29
+ "@ai-sdk/harness": "1.0.95",
30
+ "@ai-sdk/provider-utils": "5.0.34",
31
31
  "@earendil-works/pi-ai": "0.74.2",
32
32
  "@earendil-works/pi-coding-agent": "^0.84.3",
33
33
  "pi-mcp-adapter": "2.12.1",
@@ -37,7 +37,7 @@
37
37
  "zod": "^3.25.76 || ^4.1.8"
38
38
  },
39
39
  "devDependencies": {
40
- "@ai-sdk/sandbox-just-bash": "1.0.93",
40
+ "@ai-sdk/sandbox-just-bash": "1.0.95",
41
41
  "@types/node": "22.19.19",
42
42
  "@vercel/ai-tsconfig": "0.0.0",
43
43
  "tsup": "^8.5.1",
package/src/pi-harness.ts CHANGED
@@ -142,7 +142,6 @@ export function createPi(
142
142
  supportsBuiltinToolFiltering: true,
143
143
  lifecycleStateSchema: piResumeStateSchema,
144
144
  doStart: async startOpts => {
145
- const model = startOpts.model ?? settings.model;
146
145
  const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;
147
146
  const resumeData = lifecycleState?.data as
148
147
  | { sessionFileName?: string }
@@ -154,7 +153,7 @@ export function createPi(
154
153
  sessionWorkDir: startOpts.sessionWorkDir,
155
154
  settings: {
156
155
  ...(settings.auth ? { auth: settings.auth } : {}),
157
- ...(model == null ? {} : { model }),
156
+ ...(settings.model == null ? {} : { model: settings.model }),
158
157
  ...(settings.thinkingLevel
159
158
  ? { thinkingLevel: settings.thinkingLevel }
160
159
  : {}),
package/src/pi-session.ts CHANGED
@@ -415,9 +415,7 @@ export async function createPiSession(
415
415
  modelRegistry,
416
416
  env: resolverEnv,
417
417
  });
418
- // Resolve once: deterministic given the configured model. This is the Pi
419
- // `Model` object handed to `createAgentSession`.
420
- const resolvedModel = resolveModel(input.settings.model);
418
+ let activeResolvedModel = resolveModel(input.settings.model);
421
419
  const mcpServers = resolvePiMcpServers({
422
420
  mcpServers: input.settings.mcpServers,
423
421
  });
@@ -784,6 +782,7 @@ export async function createPiSession(
784
782
  // rebuilding the Pi session from it.
785
783
  const control = await runTurn({
786
784
  text: '',
785
+ ...(continueOpts.model ? { model: continueOpts.model } : {}),
787
786
  skills: continueOpts.skills,
788
787
  tools: continueOpts.tools ?? [],
789
788
  instructions: continueOpts.instructions,
@@ -1015,7 +1014,7 @@ export async function createPiSession(
1015
1014
  ...(input.settings.thinkingLevel
1016
1015
  ? { thinkingLevel: input.settings.thinkingLevel }
1017
1016
  : {}),
1018
- ...(resolvedModel ? { model: resolvedModel } : {}),
1017
+ ...(activeResolvedModel ? { model: activeResolvedModel } : {}),
1019
1018
  });
1020
1019
  piSession = session;
1021
1020
  if (hasMcpServers) {
@@ -1061,6 +1060,7 @@ export async function createPiSession(
1061
1060
  */
1062
1061
  async function runTurn(turnOpts: {
1063
1062
  text: string;
1063
+ model?: string;
1064
1064
  skills: ReadonlyArray<HarnessV1Skill>;
1065
1065
  tools: ReadonlyArray<HarnessV1ToolSpec>;
1066
1066
  instructions?: string;
@@ -1111,6 +1111,10 @@ export async function createPiSession(
1111
1111
  const didAppendDeliveredHostToolResults =
1112
1112
  appendDeliveredHostToolResults();
1113
1113
 
1114
+ const nextModel =
1115
+ turnOpts.model == null ? undefined : resolveModel(turnOpts.model);
1116
+ if (nextModel != null) activeResolvedModel = nextModel;
1117
+
1114
1118
  const signature = JSON.stringify(userTools.map(t => t.name).sort());
1115
1119
  const needsRebuild =
1116
1120
  piSession == null || signature !== lastToolsSignature;
@@ -1122,6 +1126,14 @@ export async function createPiSession(
1122
1126
  );
1123
1127
  turnAbortController.signal.throwIfAborted();
1124
1128
  lastToolsSignature = signature;
1129
+ } else if (
1130
+ nextModel != null &&
1131
+ piSession != null &&
1132
+ (piSession.model?.provider !== nextModel.provider ||
1133
+ piSession.model.id !== nextModel.id)
1134
+ ) {
1135
+ await piSession.setModel(nextModel);
1136
+ turnAbortController.signal.throwIfAborted();
1125
1137
  }
1126
1138
 
1127
1139
  if (!resourcesReloaded) {
@@ -1143,7 +1155,10 @@ export async function createPiSession(
1143
1155
  nativeToCommon: NATIVE_TO_COMMON,
1144
1156
  });
1145
1157
 
1146
- currentEmit?.({ type: 'stream-start' });
1158
+ currentEmit?.({
1159
+ type: 'stream-start',
1160
+ ...(piSession?.model?.id ? { modelId: piSession.model.id } : {}),
1161
+ });
1147
1162
 
1148
1163
  /*
1149
1164
  * A live continuation reports the completed tool execution before the
@@ -1318,10 +1333,6 @@ export async function createPiSession(
1318
1333
  const sessionImpl: HarnessV1Session = {
1319
1334
  sessionId: input.sessionId,
1320
1335
  isResume: input.isResume,
1321
- // The model Pi actually resolves to (the configured id, or its default when
1322
- // unset) — `gen_ai.request.model`.
1323
- ...(resolvedModel?.id ? { modelId: resolvedModel.id } : {}),
1324
-
1325
1336
  // Pi has no bridge to attach to and no on-disk event log to replay; its
1326
1337
  // only resume path is restoring the session file on a fresh/snapshotted
1327
1338
  // sandbox, i.e. `rerun`.
@@ -1337,6 +1348,7 @@ export async function createPiSession(
1337
1348
  }
1338
1349
  return runTurn({
1339
1350
  text: extractUserText(promptOpts.prompt),
1351
+ ...(promptOpts.model ? { model: promptOpts.model } : {}),
1340
1352
  skills: promptOpts.skills,
1341
1353
  tools: promptOpts.tools ?? [],
1342
1354
  instructions: promptOpts.instructions,
@@ -1394,6 +1406,7 @@ export async function createPiSession(
1394
1406
  */
1395
1407
  return runTurn({
1396
1408
  text: '',
1409
+ ...(continueOpts.model ? { model: continueOpts.model } : {}),
1397
1410
  skills: continueOpts.skills,
1398
1411
  tools: continueOpts.tools ?? [],
1399
1412
  instructions: continueOpts.instructions,