chore(deps): update dependencies
This commit is contained in:
@@ -222,6 +222,7 @@
|
|||||||
- Agent: add `skipBootstrap` config option. Thanks @onutc for PR #292.
|
- Agent: add `skipBootstrap` config option. Thanks @onutc for PR #292.
|
||||||
- UI: add favicon.ico derived from the macOS app icon. Thanks @jeffersonwarrior for PR #305.
|
- UI: add favicon.ico derived from the macOS app icon. Thanks @jeffersonwarrior for PR #305.
|
||||||
- Tooling: replace tsx with bun for TypeScript execution. Thanks @obviyus for PR #278.
|
- Tooling: replace tsx with bun for TypeScript execution. Thanks @obviyus for PR #278.
|
||||||
|
- Deps: refresh workspace dependencies (pi-* 0.38, carbon 0.13, Vite 7.3.1, TypeBox 0.34.47).
|
||||||
- Deps: bump pi-* stack, Slack SDK, discord-api-types, file-type, zod, and Biome.
|
- Deps: bump pi-* stack, Slack SDK, discord-api-types, file-type, zod, and Biome.
|
||||||
- Skills: add CodexBar model usage helper with macOS requirement metadata.
|
- Skills: add CodexBar model usage helper with macOS requirement metadata.
|
||||||
- Skills: add 1Password CLI skill with op examples.
|
- Skills: add 1Password CLI skill with op examples.
|
||||||
|
|||||||
27
package.json
27
package.json
@@ -85,21 +85,21 @@
|
|||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.23.0",
|
"packageManager": "pnpm@10.23.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@buape/carbon": "0.0.0-beta-20260107085330",
|
"@buape/carbon": "0.13.0",
|
||||||
"@clack/prompts": "^0.11.0",
|
"@clack/prompts": "^0.11.0",
|
||||||
"@grammyjs/runner": "^2.0.3",
|
"@grammyjs/runner": "^2.0.3",
|
||||||
"@grammyjs/transformer-throttler": "^1.2.1",
|
"@grammyjs/transformer-throttler": "^1.2.1",
|
||||||
"@homebridge/ciao": "^1.3.4",
|
"@homebridge/ciao": "^1.3.4",
|
||||||
"@mariozechner/pi-agent-core": "^0.37.2",
|
"@mariozechner/pi-agent-core": "^0.38.0",
|
||||||
"@mariozechner/pi-ai": "^0.37.2",
|
"@mariozechner/pi-ai": "^0.38.0",
|
||||||
"@mariozechner/pi-coding-agent": "^0.37.2",
|
"@mariozechner/pi-coding-agent": "^0.38.0",
|
||||||
"@mariozechner/pi-tui": "^0.37.2",
|
"@mariozechner/pi-tui": "^0.38.0",
|
||||||
"@sinclair/typebox": "0.34.46",
|
"@sinclair/typebox": "0.34.47",
|
||||||
"@slack/bolt": "^4.6.0",
|
"@slack/bolt": "^4.6.0",
|
||||||
"@slack/web-api": "^7.13.0",
|
"@slack/web-api": "^7.13.0",
|
||||||
"@whiskeysockets/baileys": "7.0.0-rc.9",
|
"@whiskeysockets/baileys": "7.0.0-rc.9",
|
||||||
"ajv": "^8.17.1",
|
"ajv": "^8.17.1",
|
||||||
"body-parser": "^2.2.1",
|
"body-parser": "^2.2.2",
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
"chokidar": "^5.0.0",
|
"chokidar": "^5.0.0",
|
||||||
"chromium-bidi": "12.0.1",
|
"chromium-bidi": "12.0.1",
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
"qrcode-terminal": "^0.12.0",
|
"qrcode-terminal": "^0.12.0",
|
||||||
"sharp": "^0.34.5",
|
"sharp": "^0.34.5",
|
||||||
"tslog": "^4.10.2",
|
"tslog": "^4.10.2",
|
||||||
"undici": "^7.18.0",
|
"undici": "^7.18.2",
|
||||||
"ws": "^8.19.0",
|
"ws": "^8.19.0",
|
||||||
"zod": "^4.3.5"
|
"zod": "^4.3.5"
|
||||||
},
|
},
|
||||||
@@ -143,10 +143,10 @@
|
|||||||
"lucide": "^0.562.0",
|
"lucide": "^0.562.0",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"ollama": "^0.6.3",
|
"ollama": "^0.6.3",
|
||||||
"oxlint": "^1.37.0",
|
"oxlint": "^1.38.0",
|
||||||
"oxlint-tsgolint": "^0.10.1",
|
"oxlint-tsgolint": "^0.10.1",
|
||||||
"quicktype-core": "^23.2.6",
|
"quicktype-core": "^23.2.6",
|
||||||
"rolldown": "1.0.0-beta.58",
|
"rolldown": "1.0.0-beta.59",
|
||||||
"signal-utils": "^0.21.1",
|
"signal-utils": "^0.21.1",
|
||||||
"tsx": "^4.21.0",
|
"tsx": "^4.21.0",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
@@ -155,14 +155,11 @@
|
|||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"@sinclair/typebox": "0.34.46"
|
"@sinclair/typebox": "0.34.47"
|
||||||
},
|
},
|
||||||
"patchedDependencies": {
|
"patchedDependencies": {
|
||||||
"@mariozechner/pi-ai": "patches/@mariozechner__pi-ai.patch",
|
"@mariozechner/pi-ai": "patches/@mariozechner__pi-ai.patch",
|
||||||
"@mariozechner/pi-agent-core": "patches/@mariozechner__pi-agent-core.patch",
|
"@mariozechner/pi-agent-core": "patches/@mariozechner__pi-agent-core.patch"
|
||||||
"@mariozechner/pi-coding-agent": "patches/@mariozechner__pi-coding-agent.patch",
|
|
||||||
"qrcode-terminal": "patches/qrcode-terminal.patch",
|
|
||||||
"playwright-core@1.57.0": "patches/playwright-core@1.57.0.patch"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vitest": {
|
"vitest": {
|
||||||
|
|||||||
@@ -1,17 +1,49 @@
|
|||||||
|
diff --git a/dist/agent.d.ts b/dist/agent.d.ts
|
||||||
|
index fcfb19924ef6ce233aa55795e3687ce23938c5a6..a63daea868c5b3b7f7bb9272576c65c6ad95da8a 100644
|
||||||
|
--- a/dist/agent.d.ts
|
||||||
|
+++ b/dist/agent.d.ts
|
||||||
|
@@ -38,6 +38,10 @@ export interface AgentOptions {
|
||||||
|
* Useful for expiring tokens (e.g., GitHub Copilot OAuth).
|
||||||
|
*/
|
||||||
|
getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;
|
||||||
|
+ /**
|
||||||
|
+ * Extra params to pass to the provider API (e.g., Z.AI GLM thinking mode params).
|
||||||
|
+ */
|
||||||
|
+ extraParams?: Record<string, unknown>;
|
||||||
|
/**
|
||||||
|
* Custom token budgets for thinking levels (token-based providers only).
|
||||||
|
*/
|
||||||
|
@@ -56,6 +60,8 @@ export declare class Agent {
|
||||||
|
streamFn: StreamFn;
|
||||||
|
private _sessionId?;
|
||||||
|
getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;
|
||||||
|
+ /** Extra params to pass to the provider API. */
|
||||||
|
+ extraParams?: Record<string, unknown>;
|
||||||
|
private runningPrompt?;
|
||||||
|
private resolveRunningPrompt?;
|
||||||
|
private _thinkingBudgets?;
|
||||||
diff --git a/dist/agent.js b/dist/agent.js
|
diff --git a/dist/agent.js b/dist/agent.js
|
||||||
index 0000000..1111111 100644
|
index 34ceb4ddcbc53d83edd82d774a76d9bf469b42f3..ecd8b7641c71523296890e11ac0cf0855a0dadd5 100644
|
||||||
--- a/dist/agent.js
|
--- a/dist/agent.js
|
||||||
+++ b/dist/agent.js
|
+++ b/dist/agent.js
|
||||||
@@ -42,6 +42,8 @@ export class Agent {
|
@@ -33,6 +33,7 @@ export class Agent {
|
||||||
this.followUpMode = opts.followUpMode || "one-at-a-time";
|
streamFn;
|
||||||
|
_sessionId;
|
||||||
|
getApiKey;
|
||||||
|
+ extraParams;
|
||||||
|
runningPrompt;
|
||||||
|
resolveRunningPrompt;
|
||||||
|
_thinkingBudgets;
|
||||||
|
@@ -45,6 +46,8 @@ export class Agent {
|
||||||
this.streamFn = opts.streamFn || streamSimple;
|
this.streamFn = opts.streamFn || streamSimple;
|
||||||
|
this._sessionId = opts.sessionId;
|
||||||
this.getApiKey = opts.getApiKey;
|
this.getApiKey = opts.getApiKey;
|
||||||
+ // PATCH: Support extraParams for provider-specific features (e.g., GLM-4.7 thinking mode)
|
+ // PATCH: Support extraParams for provider-specific features (e.g., GLM-4.7 thinking mode)
|
||||||
+ this.extraParams = opts.extraParams;
|
+ this.extraParams = opts.extraParams;
|
||||||
|
this._thinkingBudgets = opts.thinkingBudgets;
|
||||||
}
|
}
|
||||||
get state() {
|
/**
|
||||||
return this._state;
|
@@ -225,6 +228,8 @@ export class Agent {
|
||||||
@@ -193,6 +195,8 @@ export class Agent {
|
|
||||||
convertToLlm: this.convertToLlm,
|
convertToLlm: this.convertToLlm,
|
||||||
transformContext: this.transformContext,
|
transformContext: this.transformContext,
|
||||||
getApiKey: this.getApiKey,
|
getApiKey: this.getApiKey,
|
||||||
@@ -20,27 +52,3 @@ index 0000000..1111111 100644
|
|||||||
getSteeringMessages: async () => {
|
getSteeringMessages: async () => {
|
||||||
if (this.steeringMode === "one-at-a-time") {
|
if (this.steeringMode === "one-at-a-time") {
|
||||||
if (this.steeringQueue.length > 0) {
|
if (this.steeringQueue.length > 0) {
|
||||||
diff --git a/dist/agent.d.ts b/dist/agent.d.ts
|
|
||||||
index 0000000..1111111 100644
|
|
||||||
--- a/dist/agent.d.ts
|
|
||||||
+++ b/dist/agent.d.ts
|
|
||||||
@@ -33,6 +33,10 @@ export interface AgentOptions {
|
|
||||||
* Useful for expiring tokens (e.g., GitHub Copilot OAuth).
|
|
||||||
*/
|
|
||||||
getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;
|
|
||||||
+ /**
|
|
||||||
+ * Extra params to pass to the provider API (e.g., Z.AI GLM thinking mode params).
|
|
||||||
+ */
|
|
||||||
+ extraParams?: Record<string, unknown>;
|
|
||||||
}
|
|
||||||
export declare class Agent {
|
|
||||||
private _state;
|
|
||||||
@@ -45,6 +49,8 @@ export declare class Agent {
|
|
||||||
private followUpMode;
|
|
||||||
streamFn: StreamFn;
|
|
||||||
getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;
|
|
||||||
+ /** Extra params to pass to the provider API. */
|
|
||||||
+ extraParams?: Record<string, unknown>;
|
|
||||||
private runningPrompt?;
|
|
||||||
private resolveRunningPrompt?;
|
|
||||||
constructor(opts?: AgentOptions);
|
|
||||||
|
|||||||
@@ -1,28 +1,57 @@
|
|||||||
|
diff --git a/dist/providers/google-gemini-cli.js b/dist/providers/google-gemini-cli.js
|
||||||
|
index b1d6a340e1817b6f5404c2a23efa49139249f754..9dd692688fd73d378802af9600e459abbce6a17e 100644
|
||||||
|
--- a/dist/providers/google-gemini-cli.js
|
||||||
|
+++ b/dist/providers/google-gemini-cli.js
|
||||||
|
@@ -168,7 +168,12 @@ export const streamGoogleGeminiCli = (model, context, options) => {
|
||||||
|
break; // Success, exit retry loop
|
||||||
|
}
|
||||||
|
const errorText = await response.text();
|
||||||
|
- // Check if retryable
|
||||||
|
+ // PATCH: Fail immediately on 429 to let caller rotate accounts
|
||||||
|
+ if (response.status === 429) {
|
||||||
|
+ console.log(`[pi-ai] 429 rate limit - failing fast to rotate account`);
|
||||||
|
+ throw new Error(`Cloud Code Assist API error (${response.status}): ${errorText}`);
|
||||||
|
+ }
|
||||||
|
+ // Check if retryable (non-429 errors)
|
||||||
|
if (attempt < MAX_RETRIES && isRetryableError(response.status, errorText)) {
|
||||||
|
// Use server-provided delay or exponential backoff
|
||||||
|
const serverDelay = extractRetryDelay(errorText);
|
||||||
|
@@ -183,6 +188,10 @@ export const streamGoogleGeminiCli = (model, context, options) => {
|
||||||
|
if (error instanceof Error && error.message === "Request was aborted") {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
+ // PATCH: Don't retry 429 errors - let caller rotate accounts
|
||||||
|
+ if (error instanceof Error && error.message.includes("429")) {
|
||||||
|
+ throw error;
|
||||||
|
+ }
|
||||||
|
lastError = error instanceof Error ? error : new Error(String(error));
|
||||||
|
// Network errors are retryable
|
||||||
|
if (attempt < MAX_RETRIES) {
|
||||||
diff --git a/dist/providers/google-shared.js b/dist/providers/google-shared.js
|
diff --git a/dist/providers/google-shared.js b/dist/providers/google-shared.js
|
||||||
index 7bc0a9f5d6241f191cd607ecb37b3acac8d58267..56866774e47444b5d333961c9b20fce582363124 100644
|
index dbb9c0e263919c9184a5f1c7dfde47d1c3a37ff4..f1866f423f30a4dfbe812d052679abd1f011769f 100644
|
||||||
--- a/dist/providers/google-shared.js
|
--- a/dist/providers/google-shared.js
|
||||||
+++ b/dist/providers/google-shared.js
|
+++ b/dist/providers/google-shared.js
|
||||||
@@ -10,13 +10,27 @@ import { transformMessages } from "./transorm-messages.js";
|
@@ -41,13 +41,27 @@ export function retainThoughtSignature(existing, incoming) {
|
||||||
export function convertMessages(model, context) {
|
export function convertMessages(model, context) {
|
||||||
const contents = [];
|
const contents = [];
|
||||||
const transformedMessages = transformMessages(context.messages, model);
|
const transformedMessages = transformMessages(context.messages, model);
|
||||||
+
|
|
||||||
+ /**
|
+ /**
|
||||||
+ * Helper to add content while merging consecutive messages of the same role.
|
+ * Helper to add content while merging consecutive messages of the same role.
|
||||||
+ * Gemini/Cloud Code Assist requires strict role alternation (user/model/user/model).
|
+ * Gemini/Cloud Code Assist requires strict role alternation (user/model/user/model).
|
||||||
+ * Consecutive messages of the same role cause "function call turn" errors.
|
+ * Consecutive messages of the same role cause "function call turn" errors.
|
||||||
+ */
|
+ */
|
||||||
+ function addContent(role, parts) {
|
+ function addContent(role, parts) {
|
||||||
+ if (parts.length === 0) return;
|
+ if (parts.length === 0)
|
||||||
|
+ return;
|
||||||
+ const lastContent = contents[contents.length - 1];
|
+ const lastContent = contents[contents.length - 1];
|
||||||
+ if (lastContent?.role === role) {
|
+ if (lastContent?.role === role) {
|
||||||
+ // Merge into existing message of same role
|
+ // Merge into existing message of same role
|
||||||
+ lastContent.parts.push(...parts);
|
+ lastContent.parts.push(...parts);
|
||||||
+ } else {
|
+ }
|
||||||
|
+ else {
|
||||||
+ contents.push({ role, parts });
|
+ contents.push({ role, parts });
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
|
||||||
for (const msg of transformedMessages) {
|
for (const msg of transformedMessages) {
|
||||||
if (msg.role === "user") {
|
if (msg.role === "user") {
|
||||||
if (typeof msg.content === "string") {
|
if (typeof msg.content === "string") {
|
||||||
@@ -34,7 +63,7 @@ index 7bc0a9f5d6241f191cd607ecb37b3acac8d58267..56866774e47444b5d333961c9b20fce5
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const parts = msg.content.map((item) => {
|
const parts = msg.content.map((item) => {
|
||||||
@@ -35,10 +49,7 @@ export function convertMessages(model, context) {
|
@@ -66,10 +80,7 @@ export function convertMessages(model, context) {
|
||||||
const filteredParts = !model.input.includes("image") ? parts.filter((p) => p.text !== undefined) : parts;
|
const filteredParts = !model.input.includes("image") ? parts.filter((p) => p.text !== undefined) : parts;
|
||||||
if (filteredParts.length === 0)
|
if (filteredParts.length === 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -46,7 +75,7 @@ index 7bc0a9f5d6241f191cd607ecb37b3acac8d58267..56866774e47444b5d333961c9b20fce5
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (msg.role === "assistant") {
|
else if (msg.role === "assistant") {
|
||||||
@@ -51,9 +62,19 @@ export function convertMessages(model, context) {
|
@@ -82,9 +93,19 @@ export function convertMessages(model, context) {
|
||||||
parts.push({ text: sanitizeSurrogates(block.text) });
|
parts.push({ text: sanitizeSurrogates(block.text) });
|
||||||
}
|
}
|
||||||
else if (block.type === "thinking") {
|
else if (block.type === "thinking") {
|
||||||
@@ -64,12 +93,12 @@ index 7bc0a9f5d6241f191cd607ecb37b3acac8d58267..56866774e47444b5d333961c9b20fce5
|
|||||||
+ // and will mimic <thinking> tags if we convert to text
|
+ // and will mimic <thinking> tags if we convert to text
|
||||||
+ continue;
|
+ continue;
|
||||||
+ }
|
+ }
|
||||||
+ else if (block.thinkingSignature && isClaude) {
|
+ if (block.thinkingSignature && isClaude) {
|
||||||
+ // Claude via Antigravity requires the signature
|
+ // Claude via Antigravity requires the signature
|
||||||
parts.push({
|
parts.push({
|
||||||
thought: true,
|
thought: true,
|
||||||
text: sanitizeSurrogates(block.thinking),
|
text: sanitizeSurrogates(block.thinking),
|
||||||
@@ -61,6 +82,7 @@ export function convertMessages(model, context) {
|
@@ -92,6 +113,7 @@ export function convertMessages(model, context) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -77,7 +106,7 @@ index 7bc0a9f5d6241f191cd607ecb37b3acac8d58267..56866774e47444b5d333961c9b20fce5
|
|||||||
parts.push({
|
parts.push({
|
||||||
text: `<thinking>\n${sanitizeSurrogates(block.thinking)}\n</thinking>`,
|
text: `<thinking>\n${sanitizeSurrogates(block.thinking)}\n</thinking>`,
|
||||||
});
|
});
|
||||||
@@ -85,10 +107,7 @@ export function convertMessages(model, context) {
|
@@ -116,10 +138,7 @@ export function convertMessages(model, context) {
|
||||||
}
|
}
|
||||||
if (parts.length === 0)
|
if (parts.length === 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -89,7 +118,7 @@ index 7bc0a9f5d6241f191cd607ecb37b3acac8d58267..56866774e47444b5d333961c9b20fce5
|
|||||||
}
|
}
|
||||||
else if (msg.role === "toolResult") {
|
else if (msg.role === "toolResult") {
|
||||||
// Extract text and image content
|
// Extract text and image content
|
||||||
@@ -125,27 +144,94 @@ export function convertMessages(model, context) {
|
@@ -156,27 +175,97 @@ export function convertMessages(model, context) {
|
||||||
}
|
}
|
||||||
// Cloud Code Assist API requires all function responses to be in a single user turn.
|
// Cloud Code Assist API requires all function responses to be in a single user turn.
|
||||||
// Check if the last content is already a user turn with function responses and merge.
|
// Check if the last content is already a user turn with function responses and merge.
|
||||||
@@ -124,43 +153,43 @@ index 7bc0a9f5d6241f191cd607ecb37b3acac8d58267..56866774e47444b5d333961c9b20fce5
|
|||||||
+ * and converts to a format compatible with Google's function declarations.
|
+ * and converts to a format compatible with Google's function declarations.
|
||||||
+ */
|
+ */
|
||||||
+function sanitizeSchemaForGoogle(schema) {
|
+function sanitizeSchemaForGoogle(schema) {
|
||||||
+ if (!schema || typeof schema !== 'object') {
|
+ if (!schema || typeof schema !== "object") {
|
||||||
+ return schema;
|
+ return schema;
|
||||||
+ }
|
+ }
|
||||||
+ // If it's an array, sanitize each element
|
+ // If it's an array, sanitize each element
|
||||||
+ if (Array.isArray(schema)) {
|
+ if (Array.isArray(schema)) {
|
||||||
+ return schema.map(item => sanitizeSchemaForGoogle(item));
|
+ return schema.map((item) => sanitizeSchemaForGoogle(item));
|
||||||
+ }
|
+ }
|
||||||
+ const sanitized = {};
|
+ const sanitized = {};
|
||||||
+ // List of unsupported JSON Schema keywords that Google's API doesn't understand
|
+ // List of unsupported JSON Schema keywords that Google's API doesn't understand
|
||||||
+ const unsupportedKeywords = [
|
+ const unsupportedKeywords = [
|
||||||
+ 'patternProperties',
|
+ "patternProperties",
|
||||||
+ 'const',
|
+ "const",
|
||||||
+ 'anyOf',
|
+ "anyOf",
|
||||||
+ 'oneOf',
|
+ "oneOf",
|
||||||
+ 'allOf',
|
+ "allOf",
|
||||||
+ 'not',
|
+ "not",
|
||||||
+ '$schema',
|
+ "$schema",
|
||||||
+ '$id',
|
+ "$id",
|
||||||
+ '$ref',
|
+ "$ref",
|
||||||
+ '$defs',
|
+ "$defs",
|
||||||
+ 'definitions',
|
+ "definitions",
|
||||||
+ 'if',
|
+ "if",
|
||||||
+ 'then',
|
+ "then",
|
||||||
+ 'else',
|
+ "else",
|
||||||
+ 'dependentSchemas',
|
+ "dependentSchemas",
|
||||||
+ 'dependentRequired',
|
+ "dependentRequired",
|
||||||
+ 'unevaluatedProperties',
|
+ "unevaluatedProperties",
|
||||||
+ 'unevaluatedItems',
|
+ "unevaluatedItems",
|
||||||
+ 'contentEncoding',
|
+ "contentEncoding",
|
||||||
+ 'contentMediaType',
|
+ "contentMediaType",
|
||||||
+ 'contentSchema',
|
+ "contentSchema",
|
||||||
+ 'deprecated',
|
+ "deprecated",
|
||||||
+ 'readOnly',
|
+ "readOnly",
|
||||||
+ 'writeOnly',
|
+ "writeOnly",
|
||||||
+ 'examples',
|
+ "examples",
|
||||||
+ '$comment',
|
+ "$comment",
|
||||||
+ 'additionalProperties',
|
+ "additionalProperties",
|
||||||
+ ];
|
+ ];
|
||||||
+ // TODO(steipete): lossy schema scrub; revisit when Google supports these keywords.
|
+ // TODO(steipete): lossy schema scrub; revisit when Google supports these keywords.
|
||||||
+ for (const [key, value] of Object.entries(schema)) {
|
+ for (const [key, value] of Object.entries(schema)) {
|
||||||
@@ -169,30 +198,33 @@ index 7bc0a9f5d6241f191cd607ecb37b3acac8d58267..56866774e47444b5d333961c9b20fce5
|
|||||||
+ continue;
|
+ continue;
|
||||||
+ }
|
+ }
|
||||||
+ // Recursively sanitize nested objects
|
+ // Recursively sanitize nested objects
|
||||||
+ if (key === 'properties' && typeof value === 'object' && value !== null) {
|
+ if (key === "properties" && typeof value === "object" && value !== null) {
|
||||||
+ sanitized[key] = {};
|
+ sanitized[key] = {};
|
||||||
+ for (const [propKey, propValue] of Object.entries(value)) {
|
+ for (const [propKey, propValue] of Object.entries(value)) {
|
||||||
+ sanitized[key][propKey] = sanitizeSchemaForGoogle(propValue);
|
+ sanitized[key][propKey] = sanitizeSchemaForGoogle(propValue);
|
||||||
+ }
|
+ }
|
||||||
+ } else if (key === 'items' && typeof value === 'object') {
|
+ }
|
||||||
|
+ else if (key === "items" && typeof value === "object") {
|
||||||
+ sanitized[key] = sanitizeSchemaForGoogle(value);
|
+ sanitized[key] = sanitizeSchemaForGoogle(value);
|
||||||
+ } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
+ }
|
||||||
|
+ else if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
||||||
+ sanitized[key] = sanitizeSchemaForGoogle(value);
|
+ sanitized[key] = sanitizeSchemaForGoogle(value);
|
||||||
+ } else {
|
+ }
|
||||||
|
+ else {
|
||||||
+ sanitized[key] = value;
|
+ sanitized[key] = value;
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ // Ensure type: "object" is present when properties or required exist
|
+ // Ensure type: "object" is present when properties or required exist
|
||||||
+ // Google API requires type to be set when these fields are present
|
+ // Google API requires type to be set when these fields are present
|
||||||
+ if (('properties' in sanitized || 'required' in sanitized) && !('type' in sanitized)) {
|
+ if (("properties" in sanitized || "required" in sanitized) && !("type" in sanitized)) {
|
||||||
+ sanitized.type = 'object';
|
+ sanitized.type = "object";
|
||||||
+ }
|
+ }
|
||||||
+ return sanitized;
|
+ return sanitized;
|
||||||
+}
|
+}
|
||||||
/**
|
/**
|
||||||
* Convert tools to Gemini function declarations format.
|
* Convert tools to Gemini function declarations format.
|
||||||
*/
|
*/
|
||||||
@@ -157,7 +243,7 @@ export function convertTools(tools) {
|
@@ -188,7 +277,7 @@ export function convertTools(tools) {
|
||||||
functionDeclarations: tools.map((tool) => ({
|
functionDeclarations: tools.map((tool) => ({
|
||||||
name: tool.name,
|
name: tool.name,
|
||||||
description: tool.description,
|
description: tool.description,
|
||||||
@@ -201,8 +233,37 @@ index 7bc0a9f5d6241f191cd607ecb37b3acac8d58267..56866774e47444b5d333961c9b20fce5
|
|||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
diff --git a/dist/providers/openai-completions.d.ts b/dist/providers/openai-completions.d.ts
|
||||||
|
index 723addf341696b5d69c079202e571e9917685ce4..a1d0584a70a7d1fad1332026e301e56ef4f700a8 100644
|
||||||
|
--- a/dist/providers/openai-completions.d.ts
|
||||||
|
+++ b/dist/providers/openai-completions.d.ts
|
||||||
|
@@ -7,6 +7,8 @@ export interface OpenAICompletionsOptions extends StreamOptions {
|
||||||
|
};
|
||||||
|
};
|
||||||
|
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh";
|
||||||
|
+ /** Extra params to pass directly to the API (e.g., Z.AI GLM thinking mode params) */
|
||||||
|
+ extraParams?: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
export declare const streamOpenAICompletions: StreamFunction<"openai-completions">;
|
||||||
|
//# sourceMappingURL=openai-completions.d.ts.map
|
||||||
|
diff --git a/dist/providers/openai-completions.js b/dist/providers/openai-completions.js
|
||||||
|
index 2590381cc5544c4e73c24c1c9a5853202f31361b..b76e1087dd31ccf099e02b1214b9e12d371b9b2d 100644
|
||||||
|
--- a/dist/providers/openai-completions.js
|
||||||
|
+++ b/dist/providers/openai-completions.js
|
||||||
|
@@ -335,6 +335,11 @@ function buildParams(model, context, options) {
|
||||||
|
if (options?.reasoningEffort && model.reasoning && compat.supportsReasoningEffort) {
|
||||||
|
params.reasoning_effort = options.reasoningEffort;
|
||||||
|
}
|
||||||
|
+ // PATCH: Support arbitrary extra params for provider-specific features
|
||||||
|
+ // (e.g., Z.AI GLM-4.7 thinking: { type: "enabled", clear_thinking: boolean })
|
||||||
|
+ if (options?.extraParams && typeof options.extraParams === "object") {
|
||||||
|
+ Object.assign(params, options.extraParams);
|
||||||
|
+ }
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
function convertMessages(model, context, compat) {
|
||||||
diff --git a/dist/providers/openai-responses.js b/dist/providers/openai-responses.js
|
diff --git a/dist/providers/openai-responses.js b/dist/providers/openai-responses.js
|
||||||
index 20fb0a22aaa28f7ff7c2f44a8b628fa1d9d7d936..31bae0aface1319487ce62d35f1f3b6ed334863e 100644
|
index 20fb0a22aaa28f7ff7c2f44a8b628fa1d9d7d936..c2bc63f483f3285b00755901ba97db810221cea6 100644
|
||||||
--- a/dist/providers/openai-responses.js
|
--- a/dist/providers/openai-responses.js
|
||||||
+++ b/dist/providers/openai-responses.js
|
+++ b/dist/providers/openai-responses.js
|
||||||
@@ -486,7 +486,6 @@ function convertTools(tools) {
|
@@ -486,7 +486,6 @@ function convertTools(tools) {
|
||||||
@@ -213,69 +274,16 @@ index 20fb0a22aaa28f7ff7c2f44a8b628fa1d9d7d936..31bae0aface1319487ce62d35f1f3b6e
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
function mapStopReason(status) {
|
function mapStopReason(status) {
|
||||||
diff --git a/dist/providers/google-gemini-cli.js b/dist/providers/google-gemini-cli.js
|
|
||||||
--- a/dist/providers/google-gemini-cli.js
|
|
||||||
+++ b/dist/providers/google-gemini-cli.js
|
|
||||||
@@ -168,7 +168,12 @@ async function* streamCompletion(params, options) {
|
|
||||||
break; // Success, exit retry loop
|
|
||||||
}
|
|
||||||
const errorText = await response.text();
|
|
||||||
- // Check if retryable
|
|
||||||
+ // PATCH: Fail immediately on 429 to let caller rotate accounts
|
|
||||||
+ if (response.status === 429) {
|
|
||||||
+ console.log(`[pi-ai] 429 rate limit - failing fast to rotate account`);
|
|
||||||
+ throw new Error(`Cloud Code Assist API error (${response.status}): ${errorText}`);
|
|
||||||
+ }
|
|
||||||
+ // Check if retryable (non-429 errors)
|
|
||||||
if (attempt < MAX_RETRIES && isRetryableError(response.status, errorText)) {
|
|
||||||
// Use server-provided delay or exponential backoff
|
|
||||||
const serverDelay = extractRetryDelay(errorText);
|
|
||||||
@@ -183,6 +188,10 @@ async function* streamCompletion(params, options) {
|
|
||||||
if (error instanceof Error && error.message === "Request was aborted") {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
+ // PATCH: Don't retry 429 errors - let caller rotate accounts
|
|
||||||
+ if (error instanceof Error && error.message.includes("429")) {
|
|
||||||
+ throw error;
|
|
||||||
+ }
|
|
||||||
lastError = error instanceof Error ? error : new Error(String(error));
|
|
||||||
// Network errors are retryable
|
|
||||||
if (attempt < MAX_RETRIES) {
|
|
||||||
diff --git a/dist/stream.js b/dist/stream.js
|
diff --git a/dist/stream.js b/dist/stream.js
|
||||||
|
index da54f4270e9b8d9e9cf1f902af976cc239601d4c..7ed71597c3369f8e3c1a3da0eb870a68215b714d 100644
|
||||||
--- a/dist/stream.js
|
--- a/dist/stream.js
|
||||||
+++ b/dist/stream.js
|
+++ b/dist/stream.js
|
||||||
@@ -105,6 +105,8 @@ function mapOptionsForApi(model, options, apiKey) {
|
@@ -108,6 +108,8 @@ function mapOptionsForApi(model, options, apiKey) {
|
||||||
maxTokens: options?.maxTokens || Math.min(model.maxTokens, 32000),
|
|
||||||
signal: options?.signal,
|
signal: options?.signal,
|
||||||
apiKey: apiKey || options?.apiKey,
|
apiKey: apiKey || options?.apiKey,
|
||||||
|
sessionId: options?.sessionId,
|
||||||
+ // PATCH: Pass extraParams through to provider-specific API handlers
|
+ // PATCH: Pass extraParams through to provider-specific API handlers
|
||||||
+ extraParams: options?.extraParams,
|
+ extraParams: options?.extraParams,
|
||||||
};
|
};
|
||||||
// Helper to clamp xhigh to high for providers that don't support it
|
// Helper to clamp xhigh to high for providers that don't support it
|
||||||
const clampReasoning = (effort) => (effort === "xhigh" ? "high" : effort);
|
const clampReasoning = (effort) => (effort === "xhigh" ? "high" : effort);
|
||||||
diff --git a/dist/providers/openai-completions.js b/dist/providers/openai-completions.js
|
|
||||||
--- a/dist/providers/openai-completions.js
|
|
||||||
+++ b/dist/providers/openai-completions.js
|
|
||||||
@@ -333,6 +333,11 @@ function buildParams(model, context, options) {
|
|
||||||
if (options?.reasoningEffort && model.reasoning && compat.supportsReasoningEffort) {
|
|
||||||
params.reasoning_effort = options.reasoningEffort;
|
|
||||||
}
|
|
||||||
+ // PATCH: Support arbitrary extra params for provider-specific features
|
|
||||||
+ // (e.g., Z.AI GLM-4.7 thinking: { type: "enabled", clear_thinking: boolean })
|
|
||||||
+ if (options?.extraParams && typeof options.extraParams === 'object') {
|
|
||||||
+ Object.assign(params, options.extraParams);
|
|
||||||
+ }
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
function convertMessages(model, context, compat) {
|
|
||||||
diff --git a/dist/providers/openai-completions.d.ts b/dist/providers/openai-completions.d.ts
|
|
||||||
--- a/dist/providers/openai-completions.d.ts
|
|
||||||
+++ b/dist/providers/openai-completions.d.ts
|
|
||||||
@@ -7,5 +7,7 @@ export interface OpenAICompletionsOptions extends StreamOptions {
|
|
||||||
};
|
|
||||||
};
|
|
||||||
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
||||||
+ /** Extra params to pass directly to the API (e.g., Z.AI GLM thinking mode params) */
|
|
||||||
+ extraParams?: Record<string, unknown>;
|
|
||||||
}
|
|
||||||
export declare const streamOpenAICompletions: StreamFunction<"openai-completions">;
|
|
||||||
|
|||||||
891
pnpm-lock.yaml
generated
891
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,7 @@
|
|||||||
"@vitest/browser-playwright": "4.0.16",
|
"@vitest/browser-playwright": "4.0.16",
|
||||||
"playwright": "^1.57.0",
|
"playwright": "^1.57.0",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"vite": "7.3.0",
|
"vite": "7.3.1",
|
||||||
"vitest": "4.0.16"
|
"vitest": "4.0.16"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user