@victor-software-house/pi-openai-proxy 4.9.1 → 4.9.3

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/dist/index.mjs CHANGED
@@ -72,6 +72,16 @@ function getAvailableModels() {
72
72
  return getRegistry().getAvailable();
73
73
  }
74
74
  /**
75
+ * Resolve request auth for a specific model at request time.
76
+ *
77
+ * This uses Pi's current request-auth contract, which may return both an API
78
+ * key and model-specific headers. That covers API-key providers, OAuth-backed
79
+ * providers, authHeader handling, and dynamic models.json header resolution.
80
+ */
81
+ async function getRequestAuth(model) {
82
+ return getRegistry().getApiKeyAndHeaders(model);
83
+ }
84
+ /**
75
85
  * Get the `enabledModels` patterns from pi's global settings.
76
86
  *
77
87
  * These are the canonical model IDs (e.g. "anthropic/claude-sonnet-4-6")
@@ -324,6 +334,8 @@ const toolArgsSchema = z.record(z.string().trim(), z.unknown());
324
334
  function convertMessages(messages) {
325
335
  const systemParts = [];
326
336
  const piMessages = [];
337
+ const toolCallNames = /* @__PURE__ */ new Map();
338
+ for (const msg of messages) if (msg !== void 0 && msg.role === "assistant" && "tool_calls" in msg) for (const tc of msg.tool_calls ?? []) toolCallNames.set(tc.id, tc.function.name);
327
339
  for (let i = 0; i < messages.length; i++) {
328
340
  const msg = messages[i];
329
341
  if (msg === void 0) continue;
@@ -337,7 +349,8 @@ function convertMessages(messages) {
337
349
  const assistantMsg = convertAssistantMessage(msg.content ?? null, msg.tool_calls);
338
350
  piMessages.push(assistantMsg);
339
351
  } else if (msg.role === "tool") {
340
- const toolMsg = convertToolMessage(msg.content, msg.tool_call_id);
352
+ const toolName = toolCallNames.get(msg.tool_call_id) ?? "";
353
+ const toolMsg = convertToolMessage(msg.content, msg.tool_call_id, toolName);
341
354
  piMessages.push(toolMsg);
342
355
  }
343
356
  }
@@ -442,11 +455,11 @@ function convertAssistantMessage(textContent, toolCalls) {
442
455
  timestamp: Date.now()
443
456
  };
444
457
  }
445
- function convertToolMessage(content, toolCallId) {
458
+ function convertToolMessage(content, toolCallId, toolName) {
446
459
  return {
447
460
  role: "toolResult",
448
461
  toolCallId,
449
- toolName: "",
462
+ toolName,
450
463
  content: [{
451
464
  type: "text",
452
465
  text: content
@@ -1586,8 +1599,10 @@ async function buildStreamOptions(model, request, options) {
1586
1599
  if (combinedSignal !== void 0) opts.signal = combinedSignal;
1587
1600
  if (options.upstreamApiKey !== void 0) opts.apiKey = options.upstreamApiKey;
1588
1601
  else {
1589
- const apiKey = await getRegistry().getApiKey(model);
1590
- if (apiKey !== void 0) opts.apiKey = apiKey;
1602
+ const auth = await getRequestAuth(model);
1603
+ if (!auth.ok) throw new Error(auth.error);
1604
+ if (auth.apiKey !== void 0) opts.apiKey = auth.apiKey;
1605
+ if (auth.headers !== void 0) opts.headers = auth.headers;
1591
1606
  }
1592
1607
  const payloadFields = collectPayloadFields(request, model.api);
1593
1608
  const strictFlags = collectToolStrictFlags(request.tools);
@@ -1686,7 +1701,8 @@ function createRoutes(config, configReader = fileConfigReader) {
1686
1701
  context.tools = toolConversion.tools;
1687
1702
  }
1688
1703
  if (upstreamApiKey === void 0) {
1689
- if (await getRegistry().getApiKey(model) === void 0) return c.json(authenticationError(`No API key configured for provider '${model.provider}'. Configure credentials via 'pi /login' or pass X-Pi-Upstream-Api-Key header.`), 401);
1704
+ const requestAuth = await getRequestAuth(model);
1705
+ if (!requestAuth.ok) return c.json(authenticationError(`Could not resolve request auth for provider '${model.provider}'. ${requestAuth.error}. Configure credentials via 'pi /login' or pass X-Pi-Upstream-Api-Key header.`), 401);
1690
1706
  }
1691
1707
  const completionOptions = {
1692
1708
  upstreamApiKey,
@@ -723,7 +723,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
723
723
 
724
724
  // HACK: SettingsList has no public API for jumping to an index.
725
725
  // Accesses private fields via bracket notation for provider jumping.
726
- // Pinned to pi-tui behavior as of @mariozechner/pi-coding-agent ^0.62.0.
726
+ // Pinned to pi-tui behavior as of @mariozechner/pi-coding-agent ^0.63.1.
727
727
  // Remove when SettingsList exposes a jumpTo/setSelectedIndex method.
728
728
 
729
729
  // Isolated unsafe accessor for SettingsList private fields.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@victor-software-house/pi-openai-proxy",
3
- "version": "4.9.1",
3
+ "version": "4.9.3",
4
4
  "description": "OpenAI-compatible HTTP proxy for pi's multi-provider model registry",
5
5
  "license": "MIT",
6
6
  "author": "Victor Software House",
@@ -72,8 +72,8 @@
72
72
  "prepublishOnly": "bun test && bun run build"
73
73
  },
74
74
  "dependencies": {
75
- "@mariozechner/pi-ai": "^0.62.0",
76
- "@mariozechner/pi-coding-agent": "^0.62.0",
75
+ "@mariozechner/pi-ai": "^0.63.1",
76
+ "@mariozechner/pi-coding-agent": "^0.63.1",
77
77
  "@sinclair/typebox": "^0.34.0",
78
78
  "citty": "^0.1.6",
79
79
  "hono": "^4.12.8",