@ai-sdk/harness-pi 1.0.94 → 1.0.95

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.94",
3
+ "version": "1.0.95",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -26,10 +26,10 @@
26
26
  }
27
27
  },
28
28
  "dependencies": {
29
- "@ai-sdk/harness": "1.0.92",
30
- "@ai-sdk/provider-utils": "5.0.32",
29
+ "@ai-sdk/harness": "1.0.93",
30
+ "@ai-sdk/provider-utils": "5.0.33",
31
31
  "@earendil-works/pi-ai": "0.74.2",
32
- "@earendil-works/pi-coding-agent": "^0.80.10",
32
+ "@earendil-works/pi-coding-agent": "^0.84.3",
33
33
  "pi-mcp-adapter": "2.12.1",
34
34
  "typebox": "^1.1.38"
35
35
  },
@@ -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.92",
40
+ "@ai-sdk/sandbox-just-bash": "1.0.93",
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
@@ -27,6 +27,8 @@ export type PiHarnessSettings = {
27
27
  * Pi model id (or name). Leaving this unset falls back to the AI Gateway
28
28
  * default when `AI_GATEWAY_API_KEY` / `VERCEL_OIDC_TOKEN` is set, and to
29
29
  * Pi's own resolution otherwise.
30
+ *
31
+ * @deprecated Use `model` on `HarnessAgent` instead.
30
32
  */
31
33
  readonly model?: string;
32
34
  /**
@@ -140,6 +142,7 @@ export function createPi(
140
142
  supportsBuiltinToolFiltering: true,
141
143
  lifecycleStateSchema: piResumeStateSchema,
142
144
  doStart: async startOpts => {
145
+ const model = startOpts.model ?? settings.model;
143
146
  const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;
144
147
  const resumeData = lifecycleState?.data as
145
148
  | { sessionFileName?: string }
@@ -149,10 +152,9 @@ export function createPi(
149
152
  sessionId: startOpts.sessionId,
150
153
  sandboxSession: startOpts.sandboxSession,
151
154
  sessionWorkDir: startOpts.sessionWorkDir,
152
- skills: startOpts.skills ?? [],
153
155
  settings: {
154
156
  ...(settings.auth ? { auth: settings.auth } : {}),
155
- ...(settings.model ? { model: settings.model } : {}),
157
+ ...(model == null ? {} : { model }),
156
158
  ...(settings.thinkingLevel
157
159
  ? { thinkingLevel: settings.thinkingLevel }
158
160
  : {}),
package/src/pi-session.ts CHANGED
@@ -212,7 +212,8 @@ export type PiThinkingLevel =
212
212
  | 'low'
213
213
  | 'medium'
214
214
  | 'high'
215
- | 'xhigh';
215
+ | 'xhigh'
216
+ | 'max';
216
217
 
217
218
  export interface PiSessionSettings {
218
219
  readonly auth?: PiAuthenticationMode;
@@ -226,7 +227,6 @@ export interface CreatePiSessionInput {
226
227
  readonly sessionId: string;
227
228
  readonly sandboxSession: HarnessV1NetworkSandboxSession | SandboxSession;
228
229
  readonly sessionWorkDir: string;
229
- readonly skills: ReadonlyArray<HarnessV1Skill>;
230
230
  readonly settings: PiSessionSettings;
231
231
  readonly clientApp: string;
232
232
  readonly isResume: boolean;
@@ -331,24 +331,13 @@ export async function createPiSession(
331
331
  sessionId: input.sessionId,
332
332
  });
333
333
  const permissionMode = input.permissionMode ?? 'allow-all';
334
- let sandboxSkillRootDir: string | undefined;
334
+ const sandboxSkillRootDir = path.posix.join(
335
+ sandboxHomeDir,
336
+ '.agents',
337
+ 'skills',
338
+ );
335
339
  let harnessSkills: Skill[] = [];
336
340
 
337
- // Materialise harness-provided skills into sandbox HOME, not the workspace.
338
- if (input.skills.length > 0) {
339
- sandboxSkillRootDir = path.posix.join(sandboxHomeDir, '.agents', 'skills');
340
- harnessSkills = createHarnessPiSkills({
341
- skills: input.skills,
342
- sandboxSkillRootDir,
343
- });
344
- await writePiSkills({
345
- sandbox: toolSafeSandboxSession,
346
- sandboxHomeDir,
347
- skills: input.skills,
348
- ...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),
349
- });
350
- }
351
-
352
341
  // On resume: pull the Pi session file out of the sandbox into the fresh
353
342
  // host mirror so SessionManager.open can read it.
354
343
  let resumeSessionFilePath: string | undefined;
@@ -384,9 +373,7 @@ export async function createPiSession(
384
373
  const paths = createPiPathMapper({
385
374
  hostWorkDir,
386
375
  sandboxWorkDir: sessionWorkDir,
387
- readableRoots: sandboxSkillRootDir
388
- ? [{ sandboxDir: sandboxSkillRootDir }]
389
- : [],
376
+ readableRoots: [{ sandboxDir: sandboxSkillRootDir }],
390
377
  });
391
378
 
392
379
  // Pi auth + model registry are global to this Pi session. These live on the
@@ -797,6 +784,7 @@ export async function createPiSession(
797
784
  // rebuilding the Pi session from it.
798
785
  const control = await runTurn({
799
786
  text: '',
787
+ skills: continueOpts.skills,
800
788
  tools: continueOpts.tools ?? [],
801
789
  instructions: continueOpts.instructions,
802
790
  emit: continueOpts.emit,
@@ -1073,6 +1061,7 @@ export async function createPiSession(
1073
1061
  */
1074
1062
  async function runTurn(turnOpts: {
1075
1063
  text: string;
1064
+ skills: ReadonlyArray<HarnessV1Skill>;
1076
1065
  tools: ReadonlyArray<HarnessV1ToolSpec>;
1077
1066
  instructions?: string;
1078
1067
  emit: (part: HarnessV1StreamPart) => void;
@@ -1082,6 +1071,20 @@ export async function createPiSession(
1082
1071
  throw new Error('Pi session has been stopped.');
1083
1072
  }
1084
1073
 
1074
+ const skillWriteResult = await writePiSkills({
1075
+ sandbox: toolSafeSandboxSession,
1076
+ sandboxHomeDir,
1077
+ skills: turnOpts.skills,
1078
+ abortSignal: turnOpts.abortSignal,
1079
+ });
1080
+ harnessSkills = createHarnessPiSkills({
1081
+ skills: turnOpts.skills,
1082
+ sandboxSkillRootDir,
1083
+ });
1084
+ if (piSession != null && skillWriteResult.changed) {
1085
+ await reloadResourcesOnly();
1086
+ }
1087
+
1085
1088
  const userTools = turnOpts.tools;
1086
1089
  currentEmit = turnOpts.emit;
1087
1090
  const turnAbortController = new AbortController();
@@ -1334,6 +1337,7 @@ export async function createPiSession(
1334
1337
  }
1335
1338
  return runTurn({
1336
1339
  text: extractUserText(promptOpts.prompt),
1340
+ skills: promptOpts.skills,
1337
1341
  tools: promptOpts.tools ?? [],
1338
1342
  instructions: promptOpts.instructions,
1339
1343
  emit: promptOpts.emit,
@@ -1390,6 +1394,7 @@ export async function createPiSession(
1390
1394
  */
1391
1395
  return runTurn({
1392
1396
  text: '',
1397
+ skills: continueOpts.skills,
1393
1398
  tools: continueOpts.tools ?? [],
1394
1399
  instructions: continueOpts.instructions,
1395
1400
  emit: continueOpts.emit,
package/src/pi-skills.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import path from 'node:path';
2
2
  import type { HarnessV1Skill } from '@ai-sdk/harness';
3
- import { writeSkills } from '@ai-sdk/harness/utils';
3
+ import { writeSkills, type WriteSkillsResult } from '@ai-sdk/harness/utils';
4
4
  import type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';
5
5
 
6
6
  /**
@@ -12,8 +12,8 @@ export async function writePiSkills(args: {
12
12
  readonly sandboxHomeDir: string;
13
13
  readonly skills: ReadonlyArray<HarnessV1Skill>;
14
14
  readonly abortSignal?: AbortSignal;
15
- }): Promise<void> {
16
- await writeSkills({
15
+ }): Promise<WriteSkillsResult> {
16
+ return writeSkills({
17
17
  sandbox: args.sandbox,
18
18
  rootDir: path.posix.join(args.sandboxHomeDir, '.agents', 'skills'),
19
19
  skills: args.skills,