@ai-sdk/harness-pi 1.0.104 → 1.0.105

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,16 @@
1
1
  # @ai-sdk/harness-pi
2
2
 
3
+ ## 1.0.105
4
+
5
+ ### Patch Changes
6
+
7
+ - a514695: fix(harness-pi): let extensions read host-backed session workspaces
8
+ - c359fc0: fix(harness-pi): expose tools registered by inline extensions to models
9
+ - Updated dependencies [9e1d1b2]
10
+ - Updated dependencies [a495511]
11
+ - @ai-sdk/provider-utils@5.0.37
12
+ - @ai-sdk/harness@1.0.103
13
+
3
14
  ## 1.0.104
4
15
 
5
16
  ### Patch Changes
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.105" : "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,
@@ -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],