@ai-sdk/harness-pi 1.0.104 → 1.0.106

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 CHANGED
@@ -1,5 +1,24 @@
1
1
  # @ai-sdk/harness-pi
2
2
 
3
+ ## 1.0.106
4
+
5
+ ### Patch Changes
6
+
7
+ - c04ded8: chore(harness): remove formerly deprecated `model` and `modelId` config on harness adapter settings
8
+ - Updated dependencies [c04ded8]
9
+ - @ai-sdk/harness@1.0.104
10
+
11
+ ## 1.0.105
12
+
13
+ ### Patch Changes
14
+
15
+ - a514695: fix(harness-pi): let extensions read host-backed session workspaces
16
+ - c359fc0: fix(harness-pi): expose tools registered by inline extensions to models
17
+ - Updated dependencies [9e1d1b2]
18
+ - Updated dependencies [a495511]
19
+ - @ai-sdk/provider-utils@5.0.37
20
+ - @ai-sdk/harness@1.0.103
21
+
3
22
  ## 1.0.104
4
23
 
5
24
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -17,14 +17,6 @@ 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
- * Pi model id (or name). Leaving this unset falls back to the AI Gateway
22
- * default when `AI_GATEWAY_API_KEY` / `VERCEL_OIDC_TOKEN` is set, and to
23
- * Pi's own resolution otherwise.
24
- *
25
- * @deprecated Use `model` on `HarnessAgent` instead.
26
- */
27
- readonly model?: string;
28
20
  /**
29
21
  * Pi's extended-thinking budget level. Maps directly to the SDK's
30
22
  * `thinkingLevel` option on `createAgentSession`.
package/dist/index.js CHANGED
@@ -111,7 +111,8 @@ import {
111
111
  SessionManager,
112
112
  SettingsManager
113
113
  } from "@earendil-works/pi-coding-agent";
114
- import { mkdir as mkdir3, rm as rm2 } from "fs/promises";
114
+ import { randomUUID } from "crypto";
115
+ import { mkdir as mkdir3, rm as rm2, writeFile as writeFile3 } from "fs/promises";
115
116
  import { tmpdir } from "os";
116
117
  import path6 from "path";
117
118
  import { Type as Type2 } from "typebox";
@@ -135,7 +136,7 @@ import {
135
136
  import { access } from "fs/promises";
136
137
 
137
138
  // src/version.ts
138
- var VERSION = true ? "1.0.104" : "0.0.0-test";
139
+ var VERSION = true ? "1.0.106" : "0.0.0-test";
139
140
 
140
141
  // src/pi-auth.ts
141
142
  var DEFAULT_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh";
@@ -856,7 +857,7 @@ function createPiRemoteOps(options) {
856
857
  }
857
858
  return Buffer.from(bytes);
858
859
  };
859
- const writeFile3 = async (inputPath, content) => {
860
+ const writeFile4 = async (inputPath, content) => {
860
861
  const remotePath = options.paths.toSandboxPath(inputPath);
861
862
  const resolvedPath = await resolveWritableSandboxPath(
862
863
  remotePath,
@@ -882,7 +883,7 @@ function createPiRemoteOps(options) {
882
883
  const updated = `${current.slice(0, index)}${newText}${current.slice(
883
884
  index + oldText.length
884
885
  )}`;
885
- await writeFile3(inputPath, updated);
886
+ await writeFile4(inputPath, updated);
886
887
  return updated;
887
888
  };
888
889
  const listDirectory = async (inputPath = ".", limit = 500) => {
@@ -972,7 +973,7 @@ function createPiRemoteOps(options) {
972
973
  return {
973
974
  paths: options.paths,
974
975
  readBuffer,
975
- writeFile: writeFile3,
976
+ writeFile: writeFile4,
976
977
  editFile,
977
978
  listDirectory,
978
979
  findFiles,
@@ -2074,6 +2075,26 @@ function resolveActivePiBuiltinNames(toolFiltering) {
2074
2075
  (native) => !toolFiltering.toolNames.includes(NATIVE_TO_COMMON[native] ?? native)
2075
2076
  );
2076
2077
  }
2078
+ async function isWorkspaceAvailableOnHost({
2079
+ sandbox,
2080
+ sessionWorkDir
2081
+ }) {
2082
+ const probePath = path6.join(
2083
+ sessionWorkDir,
2084
+ `.ai-sdk-harness-pi-${randomUUID()}`
2085
+ );
2086
+ const probeContent = randomUUID();
2087
+ try {
2088
+ await writeFile3(probePath, probeContent, { flag: "wx" });
2089
+ const sandboxContent = await sandbox.readBinaryFile({ path: probePath });
2090
+ return sandboxContent != null && Buffer.from(sandboxContent).equals(Buffer.from(probeContent));
2091
+ } catch {
2092
+ return false;
2093
+ } finally {
2094
+ await rm2(probePath, { force: true }).catch(() => {
2095
+ });
2096
+ }
2097
+ }
2077
2098
  async function createPiSession(input) {
2078
2099
  if (input.isResume) {
2079
2100
  const parkedSession = parkedPiSessions.get(input.sessionId);
@@ -2087,16 +2108,20 @@ async function createPiSession(input) {
2087
2108
  }
2088
2109
  const safeSessionId = input.sessionId.replace(/[\\/: ]/g, "-");
2089
2110
  const hostRoot = path6.join(tmpdir(), "ai-sdk-harness", "pi", safeSessionId);
2090
- const hostWorkDir = path6.join(hostRoot, "workspace");
2091
2111
  const hostAgentDir = path6.join(hostRoot, "agent");
2092
2112
  const hostSessionDir = path6.join(hostRoot, "sessions");
2113
+ const toolSafeSandboxSession = getRestrictedSandboxSession(
2114
+ input.sandboxSession
2115
+ );
2093
2116
  const sessionWorkDir = input.sessionWorkDir;
2117
+ const workspaceAvailableOnHost = await isWorkspaceAvailableOnHost({
2118
+ sandbox: toolSafeSandboxSession,
2119
+ sessionWorkDir
2120
+ });
2121
+ const hostWorkDir = workspaceAvailableOnHost ? path6.resolve(sessionWorkDir) : path6.join(hostRoot, "workspace");
2094
2122
  await mkdir3(hostWorkDir, { recursive: true });
2095
2123
  await mkdir3(hostAgentDir, { recursive: true });
2096
2124
  await mkdir3(hostSessionDir, { recursive: true });
2097
- const toolSafeSandboxSession = getRestrictedSandboxSession(
2098
- input.sandboxSession
2099
- );
2100
2125
  const sandboxHomeDir = await resolveSandboxHomeDir({
2101
2126
  sandbox: toolSafeSandboxSession,
2102
2127
  ...input.abortSignal ? { abortSignal: input.abortSignal } : {}
@@ -2126,13 +2151,17 @@ async function createPiSession(input) {
2126
2151
  ...input.abortSignal ? { abortSignal: input.abortSignal } : {}
2127
2152
  });
2128
2153
  }
2129
- await syncHostWorkspaceFromSandbox({
2130
- sandbox: toolSafeSandboxSession,
2131
- sandboxWorkDir: input.sessionWorkDir,
2132
- hostWorkDir
2133
- });
2154
+ if (!workspaceAvailableOnHost) {
2155
+ await syncHostWorkspaceFromSandbox({
2156
+ sandbox: toolSafeSandboxSession,
2157
+ sandboxWorkDir: input.sessionWorkDir,
2158
+ hostWorkDir
2159
+ });
2160
+ }
2134
2161
  const workspaceVfs = new PiWorkspaceVfs();
2135
- workspaceVfs.mount(hostWorkDir, sessionWorkDir);
2162
+ if (!workspaceAvailableOnHost) {
2163
+ workspaceVfs.mount(hostWorkDir, sessionWorkDir);
2164
+ }
2136
2165
  const paths = createPiPathMapper({
2137
2166
  hostWorkDir,
2138
2167
  sandboxWorkDir: sessionWorkDir,
@@ -2164,7 +2193,7 @@ async function createPiSession(input) {
2164
2193
  modelRegistry,
2165
2194
  env: resolverEnv
2166
2195
  });
2167
- let activeResolvedModel = resolveModel(input.settings.model);
2196
+ let activeResolvedModel = resolveModel();
2168
2197
  const mcpServers = resolvePiMcpServers({
2169
2198
  mcpServers: input.settings.mcpServers
2170
2199
  });
@@ -2567,7 +2596,7 @@ async function createPiSession(input) {
2567
2596
  settingsManager,
2568
2597
  resourceLoader,
2569
2598
  customTools,
2570
- ...hasMcpServers ? { noTools: "builtin" } : { tools: toolNames },
2599
+ ...hasExtensionFactories ? { noTools: "builtin" } : { tools: toolNames },
2571
2600
  ...input.settings.thinkingLevel ? { thinkingLevel: input.settings.thinkingLevel } : {},
2572
2601
  ...activeResolvedModel ? { model: activeResolvedModel } : {}
2573
2602
  });
@@ -2656,11 +2685,13 @@ async function createPiSession(input) {
2656
2685
  await reloadResourcesOnly();
2657
2686
  turnAbortController.signal.throwIfAborted();
2658
2687
  }
2659
- await syncHostWorkspaceFromSandbox({
2660
- sandbox: toolSafeSandboxSession,
2661
- sandboxWorkDir: input.sessionWorkDir,
2662
- hostWorkDir
2663
- });
2688
+ if (!workspaceAvailableOnHost) {
2689
+ await syncHostWorkspaceFromSandbox({
2690
+ sandbox: toolSafeSandboxSession,
2691
+ sandboxWorkDir: input.sessionWorkDir,
2692
+ hostWorkDir
2693
+ });
2694
+ }
2664
2695
  turnAbortController.signal.throwIfAborted();
2665
2696
  translatorState = createPiTranslatorState({
2666
2697
  builtinToolNames: [...PI_NATIVE_BUILTIN_NAMES],
@@ -3276,7 +3307,6 @@ function createPi(settings = {}) {
3276
3307
  sessionWorkDir: startOpts.sessionWorkDir,
3277
3308
  settings: {
3278
3309
  ...settings.auth ? { auth: settings.auth } : {},
3279
- ...settings.model == null ? {} : { model: settings.model },
3280
3310
  ...settings.thinkingLevel ? { thinkingLevel: settings.thinkingLevel } : {},
3281
3311
  ...settings.mcpServers ? { mcpServers: settings.mcpServers } : {},
3282
3312
  ...settings.extensionFactories ? { extensionFactories: settings.extensionFactories } : {},