@ai-sdk/harness-pi 1.0.36 → 1.0.38

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.38
4
+
5
+ ### Patch Changes
6
+
7
+ - f5cdb2d: chore(harness): update primary SDK dependencies
8
+ - Updated dependencies [02ffdcb]
9
+ - Updated dependencies [76cb673]
10
+ - @ai-sdk/provider-utils@5.0.12
11
+ - @ai-sdk/harness@1.0.38
12
+
13
+ ## 1.0.37
14
+
15
+ ### Patch Changes
16
+
17
+ - 81c3aa5: feat(harness-pi): add `agentDir` option to `createPi` for reusing CLI config
18
+ - Updated dependencies [b460541]
19
+ - Updated dependencies [079591e]
20
+ - @ai-sdk/harness@1.0.37
21
+
3
22
  ## 1.0.36
4
23
 
5
24
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -45,6 +45,13 @@ type PiHarnessSettings = {
45
45
  * `thinkingLevel` option on `createAgentSession`.
46
46
  */
47
47
  readonly thinkingLevel?: PiThinkingLevel;
48
+ /**
49
+ * Directory holding Pi's global agent config (auth.json, models.json,
50
+ * settings.json). When omitted, a per-session temp dir is used. Pass the
51
+ * user's agent dir (e.g. `~/.pi/agent/`) to reuse their CLI auth and
52
+ * model settings.
53
+ */
54
+ readonly agentDir?: string;
48
55
  };
49
56
  declare const PI_BUILTIN_TOOLS: {
50
57
  readonly read: HarnessV1BuiltinTool<{
package/dist/index.js CHANGED
@@ -90,11 +90,11 @@ async function pullSessionFileFromSandbox(args) {
90
90
 
91
91
  // src/pi-session.ts
92
92
  import {
93
- AuthStorage,
94
93
  createAgentSession,
95
94
  DefaultResourceLoader,
96
95
  defineTool,
97
96
  ModelRegistry,
97
+ ModelRuntime,
98
98
  SessionManager,
99
99
  SettingsManager
100
100
  } from "@earendil-works/pi-coding-agent";
@@ -108,7 +108,7 @@ import { resolveSandboxHomeDir } from "@ai-sdk/harness/utils";
108
108
  import { getAiGatewayAuthFromEnv } from "@ai-sdk/harness/utils";
109
109
 
110
110
  // src/version.ts
111
- var VERSION = true ? "1.0.36" : "0.0.0-test";
111
+ var VERSION = true ? "1.0.38" : "0.0.0-test";
112
112
 
113
113
  // src/pi-auth.ts
114
114
  var DEFAULT_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh";
@@ -130,9 +130,14 @@ function createGatewayProviderConfig({
130
130
  }
131
131
  };
132
132
  }
133
- function register(registries, provider, apiKey, config) {
134
- registries.authStorage.setRuntimeApiKey(provider, apiKey);
133
+ async function register({
134
+ registries,
135
+ provider,
136
+ apiKey,
137
+ config
138
+ }) {
135
139
  registries.modelRegistry.registerProvider(provider, config);
140
+ await registries.modelRuntime.setRuntimeApiKey(provider, apiKey);
136
141
  }
137
142
  function hasConfiguredValue(value) {
138
143
  if (value == null) return false;
@@ -142,17 +147,11 @@ function hasConfiguredValue(value) {
142
147
  }
143
148
  function resolvePiEnv({
144
149
  options,
145
- env,
146
- registries,
147
- clientApp = HARNESS_CLIENT_APP
150
+ env
148
151
  }) {
149
152
  const customEnvConfigured = hasConfiguredValue(options?.customEnv);
150
153
  if (customEnvConfigured) {
151
- return applyCustomEnv({
152
- customEnv: options.customEnv ?? {},
153
- registries,
154
- clientApp
155
- });
154
+ return resolveCustomEnv({ customEnv: options.customEnv ?? {} });
156
155
  }
157
156
  const gatewayConfigured = hasConfiguredValue(options?.gateway);
158
157
  const gatewayAuthFromEnv = getAiGatewayAuthFromEnv({ env });
@@ -160,31 +159,11 @@ function resolvePiEnv({
160
159
  const apiKey = options.gateway?.apiKey ?? gatewayAuthFromEnv.apiKey;
161
160
  const baseUrl = options.gateway?.baseUrl ?? gatewayAuthFromEnv.baseUrl;
162
161
  if (apiKey) {
163
- register(
164
- registries,
165
- "vercel-ai-gateway",
166
- apiKey,
167
- createGatewayProviderConfig({
168
- apiKey,
169
- baseUrl,
170
- clientApp
171
- })
172
- );
173
162
  return { AI_GATEWAY_API_KEY: apiKey, AI_GATEWAY_BASE_URL: baseUrl };
174
163
  }
175
164
  return {};
176
165
  }
177
166
  if (gatewayAuthFromEnv.apiKey) {
178
- register(
179
- registries,
180
- "vercel-ai-gateway",
181
- gatewayAuthFromEnv.apiKey,
182
- createGatewayProviderConfig({
183
- apiKey: gatewayAuthFromEnv.apiKey,
184
- baseUrl: gatewayAuthFromEnv.baseUrl,
185
- clientApp
186
- })
187
- );
188
167
  return {
189
168
  AI_GATEWAY_API_KEY: gatewayAuthFromEnv.apiKey,
190
169
  AI_GATEWAY_BASE_URL: gatewayAuthFromEnv.baseUrl
@@ -192,46 +171,87 @@ function resolvePiEnv({
192
171
  }
193
172
  return {};
194
173
  }
195
- function applyCustomEnv({
174
+ async function registerPiProviders({
175
+ options,
176
+ resolvedEnv,
177
+ registries,
178
+ clientApp = HARNESS_CLIENT_APP
179
+ }) {
180
+ if (hasConfiguredValue(options?.customEnv)) {
181
+ await registerCustomProviders({
182
+ customEnv: options.customEnv ?? {},
183
+ registries,
184
+ clientApp
185
+ });
186
+ return;
187
+ }
188
+ const apiKey = resolvedEnv.AI_GATEWAY_API_KEY;
189
+ const baseUrl = resolvedEnv.AI_GATEWAY_BASE_URL;
190
+ if (!apiKey || !baseUrl) return;
191
+ await register({
192
+ registries,
193
+ provider: "vercel-ai-gateway",
194
+ apiKey,
195
+ config: createGatewayProviderConfig({ apiKey, baseUrl, clientApp })
196
+ });
197
+ }
198
+ function resolveCustomEnv({
199
+ customEnv
200
+ }) {
201
+ const apiKey = customEnv.AI_GATEWAY_API_KEY;
202
+ if (!apiKey) return {};
203
+ return {
204
+ AI_GATEWAY_API_KEY: apiKey,
205
+ AI_GATEWAY_BASE_URL: customEnv.AI_GATEWAY_BASE_URL ?? DEFAULT_GATEWAY_BASE_URL
206
+ };
207
+ }
208
+ async function registerCustomProviders({
196
209
  customEnv,
197
210
  registries,
198
211
  clientApp
199
212
  }) {
200
- const out = {};
201
213
  const gatewayKey = customEnv.AI_GATEWAY_API_KEY;
202
214
  if (gatewayKey) {
203
215
  const baseUrl = customEnv.AI_GATEWAY_BASE_URL ?? DEFAULT_GATEWAY_BASE_URL;
204
- register(
216
+ await register({
205
217
  registries,
206
- "vercel-ai-gateway",
207
- gatewayKey,
208
- createGatewayProviderConfig({
218
+ provider: "vercel-ai-gateway",
219
+ apiKey: gatewayKey,
220
+ config: createGatewayProviderConfig({
209
221
  apiKey: gatewayKey,
210
222
  baseUrl,
211
223
  clientApp
212
224
  })
213
- );
214
- out.AI_GATEWAY_API_KEY = gatewayKey;
215
- out.AI_GATEWAY_BASE_URL = baseUrl;
225
+ });
216
226
  }
217
227
  if (customEnv.OPENAI_API_KEY) {
218
228
  const baseUrl = customEnv.OPENAI_BASE_URL ?? DEFAULT_OPENAI_BASE_URL;
219
- register(registries, "openai", customEnv.OPENAI_API_KEY, {
229
+ await register({
230
+ registries,
231
+ provider: "openai",
220
232
  apiKey: customEnv.OPENAI_API_KEY,
221
- baseUrl,
222
- authHeader: true
233
+ config: {
234
+ apiKey: customEnv.OPENAI_API_KEY,
235
+ baseUrl,
236
+ authHeader: true
237
+ }
223
238
  });
224
239
  }
225
240
  if (customEnv.ANTHROPIC_API_KEY) {
226
241
  const baseUrl = customEnv.ANTHROPIC_BASE_URL ?? DEFAULT_ANTHROPIC_BASE_URL;
227
- register(registries, "anthropic", customEnv.ANTHROPIC_API_KEY, {
242
+ await register({
243
+ registries,
244
+ provider: "anthropic",
228
245
  apiKey: customEnv.ANTHROPIC_API_KEY,
229
- baseUrl,
230
- ...customEnv.ANTHROPIC_AUTH_TOKEN ? {
231
- headers: {
232
- authorization: `Bearer ${customEnv.ANTHROPIC_AUTH_TOKEN}`
233
- }
234
- } : {}
246
+ config: {
247
+ apiKey: customEnv.ANTHROPIC_API_KEY,
248
+ baseUrl,
249
+ ...customEnv.ANTHROPIC_AUTH_TOKEN ? {
250
+ headers: {
251
+ authorization: `Bearer ${customEnv.ANTHROPIC_AUTH_TOKEN}`
252
+ }
253
+ } : {}
254
+ }
235
255
  });
236
256
  }
237
257
  for (const [name, apiKey] of Object.entries(customEnv)) {
@@ -247,13 +267,17 @@ function applyCustomEnv({
247
267
  if (!baseUrl) {
248
268
  continue;
249
269
  }
250
- register(registries, provider, apiKey, {
270
+ await register({
271
+ registries,
272
+ provider,
251
273
  apiKey,
252
- baseUrl,
253
- authHeader: true
274
+ config: {
275
+ apiKey,
276
+ baseUrl,
277
+ authHeader: true
278
+ }
254
279
  });
255
280
  }
256
- return out;
257
281
  }
258
282
 
259
283
  // src/pi-events.ts
@@ -344,7 +368,10 @@ function extractAssistantText(message) {
344
368
  // src/pi-model-resolver.ts
345
369
  import { getAiGatewayAuthFromEnv as getAiGatewayAuthFromEnv2 } from "@ai-sdk/harness/utils";
346
370
  var DEFAULT_PI_GATEWAY_MODEL_ID = "anthropic/claude-sonnet-4.6";
347
- function createPiModelResolver(modelRegistry, env = process.env) {
371
+ function createPiModelResolver({
372
+ modelRegistry,
373
+ env = process.env
374
+ }) {
348
375
  let cachedModels;
349
376
  const loadModels = () => {
350
377
  if (cachedModels) {
@@ -1617,22 +1644,31 @@ async function createPiSession(input) {
1617
1644
  sandboxWorkDir: sessionWorkDir,
1618
1645
  readableRoots: sandboxSkillRootDir ? [{ sandboxDir: sandboxSkillRootDir }] : []
1619
1646
  });
1620
- const authStorage = AuthStorage.create(path7.join(hostAgentDir, "auth.json"));
1621
- const modelRegistry = ModelRegistry.create(
1622
- authStorage,
1623
- path7.join(hostAgentDir, "models.json")
1624
- );
1625
- const settingsManager = SettingsManager.inMemory();
1647
+ const agentDir = input.agentDir ?? hostAgentDir;
1648
+ const modelRuntime = await ModelRuntime.create({
1649
+ authPath: path7.join(agentDir, "auth.json"),
1650
+ modelsPath: path7.join(agentDir, "models.json"),
1651
+ allowModelNetwork: false
1652
+ });
1653
+ const modelRegistry = new ModelRegistry(modelRuntime);
1654
+ const settingsManager = input.agentDir != null ? SettingsManager.create(hostWorkDir, agentDir) : SettingsManager.inMemory();
1626
1655
  const resolverEnv = resolvePiEnv({
1627
1656
  options: input.settings.auth,
1628
- env: process.env,
1657
+ env: process.env
1658
+ });
1659
+ await registerPiProviders({
1660
+ options: input.settings.auth,
1661
+ resolvedEnv: resolverEnv,
1629
1662
  registries: {
1630
- authStorage,
1631
- modelRegistry
1663
+ modelRegistry,
1664
+ modelRuntime
1632
1665
  },
1633
1666
  clientApp: input.clientApp
1634
1667
  });
1635
- const resolveModel = createPiModelResolver(modelRegistry, resolverEnv);
1668
+ const resolveModel = createPiModelResolver({
1669
+ modelRegistry,
1670
+ env: resolverEnv
1671
+ });
1636
1672
  const resolvedModel = resolveModel(input.settings.model);
1637
1673
  const resourceLoader = new DefaultResourceLoader({
1638
1674
  cwd: sessionWorkDir,
@@ -1806,8 +1842,7 @@ async function createPiSession(input) {
1806
1842
  const { session } = await createAgentSession({
1807
1843
  cwd: sessionWorkDir,
1808
1844
  agentDir: hostAgentDir,
1809
- authStorage,
1810
- modelRegistry,
1845
+ modelRuntime,
1811
1846
  sessionManager,
1812
1847
  settingsManager,
1813
1848
  resourceLoader,
@@ -2400,7 +2435,8 @@ function createPi(settings = {}) {
2400
2435
  permissionMode: startOpts.permissionMode,
2401
2436
  builtinToolFiltering: startOpts.builtinToolFiltering,
2402
2437
  ...resumeData?.sessionFileName ? { resumeSessionFileName: resumeData.sessionFileName } : {},
2403
- ...startOpts.abortSignal ? { abortSignal: startOpts.abortSignal } : {}
2438
+ ...startOpts.abortSignal ? { abortSignal: startOpts.abortSignal } : {},
2439
+ ...settings.agentDir ? { agentDir: settings.agentDir } : {}
2404
2440
  });
2405
2441
  }
2406
2442
  };