diff --git a/package.json b/package.json index a4f63f30a..43b7b2636 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,8 @@ "minimatch@9.0.9": "patches/minimatch@9.0.9.patch", "minimatch@10.2.6": "patches/minimatch@10.2.6.patch", "glob@11.1.0": "patches/glob@11.1.0.patch", - "glob@13.0.6": "patches/glob@13.0.6.patch" + "glob@13.0.6": "patches/glob@13.0.6.patch", + "@earendil-works/pi-coding-agent@1.4.0": "patches/@earendil-works__pi-coding-agent@1.4.0.patch" } } } diff --git a/packages/runner-pi/package.json b/packages/runner-pi/package.json index 95afde6de..1eb31f7d1 100644 --- a/packages/runner-pi/package.json +++ b/packages/runner-pi/package.json @@ -6,16 +6,16 @@ "types": "./dist/index.d.ts", "scripts": { "build:ci": "tsc -p tsconfig.json", - "typecheck:ci": "tsc -p tsconfig.json --noEmit", - "test:ci": "node --test test/*.test.mjs", + "typecheck:ci": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json", + "test:ci": "node --test test/*.test.mjs test/*.test.ts", "build": "corepack pnpm --filter @ling-stack/plugin-sdk build && tsc -p tsconfig.json", - "typecheck": "corepack pnpm --filter @ling-stack/plugin-sdk build && tsc -p tsconfig.json --noEmit", + "typecheck": "corepack pnpm --filter @ling-stack/plugin-sdk build && corepack pnpm typecheck:ci", "lint": "echo \"lint not configured yet\"", - "test": "corepack pnpm --filter @ling-stack/plugin-sdk build && tsc -p tsconfig.json && node --test test/*.test.mjs" + "test": "corepack pnpm --filter @ling-stack/plugin-sdk build && tsc -p tsconfig.json && corepack pnpm test:ci" }, "dependencies": { - "@earendil-works/pi-ai": "1.1.0", - "@earendil-works/pi-coding-agent": "1.1.0", + "@earendil-works/pi-ai": "1.4.0", + "@earendil-works/pi-coding-agent": "1.4.0", "@ling-stack/plugin-sdk": "workspace:*", "undici": "7.30.1", "zod": "4.6.7" diff --git a/packages/runner-pi/src/adapter.ts b/packages/runner-pi/src/adapter.ts index 5a25a2e8b..c8d113faa 100644 --- a/packages/runner-pi/src/adapter.ts +++ b/packages/runner-pi/src/adapter.ts @@ -145,6 +145,12 @@ export class PiRunnerAdapter { if (event.type === "agent_settled") sdkSettlement = { aborted: event.aborted }; if ((event.type === "message_start" || event.type === "message_end" || event.type === "message_update") && isPiHostResumeControl(event.message)) return; + if (event.type === "message_end" && event.message.role === "system" && session && frozenAuthority) { + // Pi reduces the system patch into state before notifying subscribers. + // Omit SDK bookkeeping only after proving prompt and tools are unchanged. + frozenPiConversation(session.state.messages, frozenAuthority); + return; + } const translatedEvents = translatePiEvents(event); // Buffer only Pi's exact reflection of this boundary's private control // error and its identity-paired empty turn_end. Nothing is discarded until diff --git a/packages/runner-pi/test/session-authority.test.ts b/packages/runner-pi/test/session-authority.test.ts new file mode 100644 index 000000000..0749932ed --- /dev/null +++ b/packages/runner-pi/test/session-authority.test.ts @@ -0,0 +1,109 @@ +import assert from "node:assert/strict"; +import { mkdtemp, rm } from "node:fs/promises"; +import { createServer } from "node:http"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import test, { type TestContext } from "node:test"; +import type { SystemMessage } from "@earendil-works/pi-ai"; +import { AgentSession } from "@earendil-works/pi-coding-agent"; +import { PiRunnerAdapter } from "../dist/adapter.js"; +import { frozenPiConversation } from "../dist/session-transcript.js"; +import type { PiRunnerEvent, PiRunnerRunOptions } from "../dist/types.js"; + +async function fixture(t: TestContext) { + const cwd = await mkdtemp(join(tmpdir(), "ling-pi-authority-")); + t.after(() => rm(cwd, { recursive: true, force: true })); + const requests: unknown[] = []; + const events: PiRunnerEvent[] = []; + let effects = 0; + const server = createServer(async (request, response) => { + const chunks: Buffer[] = []; + for await (const chunk of request) chunks.push(Buffer.from(chunk)); + requests.push(JSON.parse(Buffer.concat(chunks).toString("utf8"))); + response.writeHead(200, { "content-type": "text/event-stream" }); + response.end('data: {"choices":[{"index":0,"delta":{"content":"Recovered."},"finish_reason":null}]}\n\n' + + 'data: {"choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}\n\ndata: [DONE]\n\n'); + }); + t.after(() => new Promise((resolve, reject) => { + server.close(error => error ? reject(error) : resolve()); + server.closeAllConnections(); + })); + await new Promise((resolve, reject) => { + server.once("error", reject); + server.listen(0, "127.0.0.1", resolve); + }); + const address = server.address(); + assert.ok(address && typeof address !== "string"); + const runner = new PiRunnerAdapter(); + const options: PiRunnerRunOptions = { + cwd, agentDir: join(cwd, "agent"), runId: "saved-run", runnerAttemptId: "restored-attempt", + task: { id: "saved-task", title: "Recover", prompt: "Report the saved read without repeating it." }, + provider: { provider: "authority-fixture", model: "fixture", api: "openai-completions", + baseUrl: `http://127.0.0.1:${address.port}/v1`, apiKey: "fixture-no-network", reasoning: false }, + tools: ["read"], onEvent: event => { events.push(event); }, + onToolBefore: () => { effects += 1; return { allowed: true }; }, + onTaskContinuationBoundary: async () => {}, + }; + const preparedInput = await runner.prepareTaskInput(options); + const modelView = [ + { role: "user", content: [{ type: "text", text: preparedInput.userPrompt }], timestamp: 0 }, + { role: "assistant", content: [{ type: "toolCall", id: "saved-read", name: "read", arguments: { path: "saved.txt" } }], + api: "openai-completions", provider: options.provider.provider, model: options.provider.model, stopReason: "toolUse", + usage: { input: 10, output: 5, cacheRead: 0, cacheWrite: 0, totalTokens: 15, + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } }, timestamp: 1 }, + { role: "toolResult", toolCallId: "saved-read", toolName: "read", isError: false, + content: [{ type: "text", text: "The original durable result." }], timestamp: 2 }, + ]; + return { runner, options: { ...options, preparedInput, + ordinaryProgressRecovery: { schemaVersion: 1 as const, modelView } }, modelView, events, requests, effects: () => effects }; +} + +test("a restored SDK system patch preserves frozen authority without adding Host recovery effects", { timeout: 15_000 }, async t => { + const f = await fixture(t); + let admissions = 0; + const result = await f.runner.runTask({ ...f.options, onTaskContinuationBoundary: async point => { + if (point !== "before_provider_request") return; + admissions += 1; + assert.deepEqual(f.events.map(event => event.type), ["run_start", "turn_start"], + "only canonical recovery bookkeeping may precede the first provider request"); + } }); + assert.equal(admissions, 1); + assert.equal(f.requests.length, 1); + assert.equal(f.effects(), 0); + assert.ok(result.messages.filter(message => (message as { role: string }).role === "system").length >= 2, + "the SDK transcript retains its system patch"); + const conversation = frozenPiConversation(result.messages, f.options.preparedInput); + assert.deepEqual(conversation.slice(0, -1), f.modelView); + assert.equal((conversation.at(-1) as { role: string }).role, "assistant"); + assert.equal(f.events.some(event => event.type === "message_end" && event.role === "system"), false); + assert.equal(f.events.some(event => event.type === "run_end"), true); +}); + +const drifts: { name: string; patch: Partial }[] = [ + { name: "prompt", patch: { content: "Unsealed replacement instructions." } }, + { name: "tool declaration", patch: { toolsAdded: [{ name: "read", description: "Changed read authority", parameters: { type: "object" } }] } }, + { name: "tool removal", patch: { toolsRemoved: [{ name: "read" }] } }, +]; + +for (const { name, patch } of drifts) { + test(`a restored ${name} change cannot be omitted as bookkeeping or reach a provider`, { timeout: 15_000 }, async t => { + const subscribe = AgentSession.prototype.subscribe; + let injected = false; + t.mock.method(AgentSession.prototype, "subscribe", function (this: AgentSession, listener: Parameters[0]) { + return subscribe.call(this, event => { + if (event.type === "message_end" && event.message.role === "system") { + const message = { ...event.message, ...patch }; + this.agent.state.messages = this.agent.state.messages.map(value => value === event.message ? message : value); + injected = true; + listener({ ...event, message }); + } else listener(event); + }); + }); + const f = await fixture(t); + await assert.rejects(f.runner.runTask(f.options)); + assert.equal(injected, true); + assert.equal(f.requests.length, 0); + assert.equal(f.effects(), 0); + assert.equal(f.events.some(event => event.type === "run_end"), false); + }); +} diff --git a/packages/runner-pi/test/summary-budget.test.ts b/packages/runner-pi/test/summary-budget.test.ts new file mode 100644 index 000000000..36f27bda9 --- /dev/null +++ b/packages/runner-pi/test/summary-budget.test.ts @@ -0,0 +1,134 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { InMemoryCredentialStore, InMemoryModelsStore, type Model } from "@earendil-works/pi-ai"; +import { stream } from "@earendil-works/pi-ai/api/openai-completions"; +import { compact, generateBranchSummary, generateSummaryWithUsage, ModelRuntime, type SessionEntry } from "@earendil-works/pi-coding-agent"; +import { createPiTaskBoundary } from "../dist/task-boundary.js"; +import type { PiRunnerRunOptions } from "../dist/types.js"; + +const messages = [{ role: "user" as const, content: "Preserve the completed work.", timestamp: 0 }]; + +async function fixture({ outputLimit = 1_024, quota = 204, finishReason = "stop", finishAt = 1 } = {}) { + const model: Model<"openai-completions"> = { + provider: "summary-budget-fixture", id: "fixture", name: "fixture", api: "openai-completions", + baseUrl: "https://fixture.invalid/v1", reasoning: false, input: ["text"], contextWindow: 32_768, + maxTokens: outputLimit, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + }; + const reservations: { maxOutputTokens: number; payload: unknown }[] = []; + const requests: { max_tokens?: number; max_completion_tokens?: number }[] = []; + let settlements = 0; + const options: PiRunnerRunOptions = { + cwd: process.cwd(), task: { id: "summary-budget", title: "Summary", prompt: "Preserve the completed work." }, + runId: "summary-run", runnerAttemptId: "summary-attempt", + provider: { provider: model.provider, model: model.id, api: model.api, baseUrl: model.baseUrl, + contextWindow: model.contextWindow, maxTokens: model.maxTokens, apiKey: "fixture-no-network" }, + providerBudget: { + requiresTokenUpperBound: true, requiresCostUpperBound: false, + reserve(request) { + reservations.push(request); + if (request.maxOutputTokens > quota) throw new Error("summary quota exhausted"); + return { reservationId: `summary-${reservations.length}`, reservedTokens: 32_768 + quota }; + }, + settle() { settlements += 1; }, + settleUnknown() { assert.fail("the fixture supplies measured usage"); }, + }, + }; + const runtime = await ModelRuntime.create({ credentials: new InMemoryCredentialStore(), modelsStore: new InMemoryModelsStore(), + modelsPath: null, allowModelNetwork: false, refreshOnCreate: false }); + runtime.registerProvider(model.provider, { + api: model.api, apiKey: options.provider.apiKey, + streamSimple: (requestModel, context, requestOptions) => stream(requestModel as Model<"openai-completions">, context, { + ...requestOptions, + fetch: async (_url, init) => { + requests.push(JSON.parse(String(init?.body))); + const records = [ + { choices: [{ index: 0, delta: { content: "Completed work retained." }, finish_reason: null }] }, + { choices: [{ index: 0, delta: {}, finish_reason: requests.length === finishAt ? finishReason : "stop" }] }, + { choices: [], usage: { prompt_tokens: 20, completion_tokens: 16, total_tokens: 36 } }, + ]; + return new Response(records.map(record => `data: ${JSON.stringify(record)}\n\n`).join("") + "data: [DONE]\n\n", { + headers: { "content-type": "text/event-stream" }, + }); + }, + }), + }); + const boundary = createPiTaskBoundary(options); + boundary.bindModelRuntime(runtime); + const signal = boundary.options.signal; + assert.ok(signal); + async function admitted(operation: Promise): Promise { + const result = await operation; + boundary.assertOpen(); + return result; + } + return { model, runtime, boundary, reservations, requests, settlements: () => settlements, + summary: (reserveTokens = 256, previousSummary?: string) => admitted(generateSummaryWithUsage(messages, model, reserveTokens, + options.provider.apiKey, undefined, signal, undefined, previousSummary, "off", runtime.streamSimple)), + compact: (split = false) => admitted(compact({ firstKeptEntryId: "retained-entry", messagesToSummarize: messages, + turnPrefixMessages: split ? messages : [], isSplitTurn: split, tokensBefore: 500, + fileOps: { read: new Set(), written: new Set(), edited: new Set() }, + settings: { enabled: true, reserveTokens: 256, keepRecentTokens: 64 } }, model, options.provider.apiKey, + undefined, undefined, signal, "off", runtime.streamSimple)), + branch: () => admitted(generateBranchSummary([{ type: "message", id: "abandoned-entry", parentId: null, + timestamp: new Date(0).toISOString(), message: messages[0] } satisfies SessionEntry], { + model, apiKey: options.provider.apiKey, reserveTokens: 256, signal, streamFn: runtime.streamSimple, + })), + }; +} + +for (const mode of ["summary", "update", "compact", "split", "branch"] as const) { + test(`${mode} summary reserves and sends the configured output cap`, { timeout: 15_000 }, async () => { + const f = await fixture(); + const result = mode === "summary" ? await f.summary() + : mode === "update" ? await f.summary(256, "Earlier completed work.") + : mode === "branch" ? await f.branch() : await f.compact(mode === "split"); + assert.match(("text" in result ? result.text : result.summary) ?? "", /Completed work retained\./); + assert.equal(f.requests.length, mode === "split" ? 2 : 1); + assert.equal(f.reservations.length, f.requests.length); + assert.equal(f.settlements(), f.requests.length); + for (const [index, request] of f.requests.entries()) { + assert.equal(request.max_tokens ?? request.max_completion_tokens, 204); + assert.equal(f.reservations[index].maxOutputTokens, 204); + assert.deepEqual(f.reservations[index].payload, request); + } + f.boundary.assertOpen(); + }); +} + +test("the summary cap never exceeds the model output limit", async () => { + const f = await fixture({ outputLimit: 128, quota: 128 }); + await f.summary(); + assert.equal(f.reservations[0].maxOutputTokens, 128); + assert.equal(f.requests[0].max_tokens ?? f.requests[0].max_completion_tokens, 128); +}); + +test("an insufficient summary quota still rejects before transport", async () => { + const f = await fixture({ quota: 203 }); + await assert.rejects(f.summary(), /summary quota exhausted/); + assert.equal(f.reservations.length, 1); + assert.equal(f.reservations[0].maxOutputTokens, 204); + assert.equal(f.requests.length, 0); + assert.throws(() => f.boundary.assertOpen(), /summary quota exhausted/); +}); + +for (const mode of ["summary", "update", "compact", "split", "branch"] as const) { + test(`${mode} output at the token cap cannot become a checkpoint`, async () => { + const requestCount = mode === "split" ? 2 : 1; + const f = await fixture({ finishReason: "length", finishAt: requestCount }); + const operation = mode === "summary" ? f.summary() + : mode === "update" ? f.summary(256, "Earlier completed work.") + : mode === "branch" ? f.branch() : f.compact(mode === "split"); + if (mode === "branch") { + assert.deepEqual(await operation, { + error: "Branch summarization failed: generation hit the token cap and the summary is incomplete", + }); + } else { + await assert.rejects(operation, /summary is incomplete/); + } + assert.equal(f.requests.length, requestCount); + assert.equal(f.settlements(), requestCount); + for (const request of f.requests) { + assert.equal(request.max_tokens ?? request.max_completion_tokens, 204); + } + }); +} diff --git a/packages/runner-pi/tsconfig.test.json b/packages/runner-pi/tsconfig.test.json new file mode 100644 index 000000000..c9e4ef726 --- /dev/null +++ b/packages/runner-pi/tsconfig.test.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "module": "NodeNext", + "moduleResolution": "NodeNext", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2022", + "types": ["node"] + }, + "include": ["test/**/*.ts"] +} diff --git a/patches/@earendil-works__pi-coding-agent@1.4.0.patch b/patches/@earendil-works__pi-coding-agent@1.4.0.patch new file mode 100644 index 000000000..6381a4a80 --- /dev/null +++ b/patches/@earendil-works__pi-coding-agent@1.4.0.patch @@ -0,0 +1,112 @@ +diff --git a/dist/core/compaction/branch-summarization.js b/dist/core/compaction/branch-summarization.js +index dba3462974d41ae6201ccf12a775c75ec6c7de5e..7292cadd2e390b27edc22f3bfff2a798aea5fc1b 100644 +--- a/dist/core/compaction/branch-summarization.js ++++ b/dist/core/compaction/branch-summarization.js +@@ -221,7 +221,8 @@ export async function generateBranchSummary(entries, options) { + // without running through agent state/events. Retried via completeSummarization + // so transient stream drops reuse the configured retry policy. + const context = normalizeContext({ systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages }); +- const requestOptions = { apiKey, headers, env, signal }; ++ const maxTokens = Math.min(Math.floor(0.8 * reserveTokens), model.maxTokens); ++ const requestOptions = { apiKey, headers, env, signal, maxTokens }; + const response = await completeSummarization(model, context, requestOptions, streamFn, retry, callbacks); + // Check if aborted or errored + if (response.stopReason === "aborted") { +diff --git a/dist/core/compaction/compaction.js b/dist/core/compaction/compaction.js +index 9b1a409d96b39413d8598c79f14fee72f4cd533c..528b87e11eaa1d318f0261603b4b62608c301408 100644 +--- a/dist/core/compaction/compaction.js ++++ b/dist/core/compaction/compaction.js +@@ -460,8 +460,10 @@ export function getSummarizationFailure(response, label) { + } + return undefined; + } +-function createSummarizationOptions(model, apiKey, headers, env, signal, thinkingLevel, sessionId) { +- const options = { signal, apiKey, headers, env, sessionId }; ++function createSummarizationOptions(model, apiKey, headers, env, signal, thinkingLevel, sessionId, reserveTokens = 16384) { ++ // Summary output must fit the reserve admitted by the host's provider budget. ++ const maxTokens = Math.min(Math.floor(0.8 * reserveTokens), model.maxTokens); ++ const options = { signal, apiKey, headers, env, sessionId, maxTokens }; + if (model.reasoning && thinkingLevel && thinkingLevel !== "off") { + options.reasoning = thinkingLevel; + } +@@ -491,10 +493,8 @@ export async function completeSummarization(model, context, options, streamFn, r + * Generate a summary of the conversation using the LLM. + * If previousSummary is provided, uses the update prompt to merge. + */ +-export async function generateSummary(currentMessages, model, +-// Unused. Kept for existing callers; summaries use the model's output limit (#9512). +-_reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env, retry, callbacks, sessionId) { +- return (await generateSummaryWithUsage(currentMessages, model, _reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env, retry, callbacks, sessionId)).text; ++export async function generateSummary(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env, retry, callbacks, sessionId) { ++ return (await generateSummaryWithUsage(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env, retry, callbacks, sessionId)).text; + } + /** Build the provider context for a standalone summary request. */ + function buildSummarizationContext(promptText) { +@@ -510,9 +510,7 @@ function buildSummarizationContext(promptText) { + }); + } + /** Generate or update a conversation summary and return its provider usage. */ +-export async function generateSummaryWithUsage(currentMessages, model, +-// Unused. Kept for existing callers; summaries use the model's output limit (#9512). +-_reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env, retry, callbacks, sessionId) { ++export async function generateSummaryWithUsage(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env, retry, callbacks, sessionId) { + // Use update prompt if we have a previous summary, otherwise initial prompt + let basePrompt = previousSummary ? UPDATE_SUMMARIZATION_PROMPT : SUMMARIZATION_PROMPT; + if (customInstructions) { +@@ -528,7 +526,7 @@ _reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, th + promptText += `\n${previousSummary}\n\n\n`; + } + promptText += basePrompt; +- const completionOptions = createSummarizationOptions(model, apiKey, headers, env, signal, thinkingLevel, sessionId); ++ const completionOptions = createSummarizationOptions(model, apiKey, headers, env, signal, thinkingLevel, sessionId, reserveTokens); + const response = await completeSummarization(model, buildSummarizationContext(promptText), completionOptions, streamFn, retry, callbacks); + const failure = getSummarizationFailure(response, "Summarization"); + if (failure) { +@@ -686,7 +684,7 @@ Only summarize information explicitly present above. Do not infer or recreate la + * @param sessionId - Optional routing session ID forwarded without enabling prompt caching + */ + export async function compact(preparation, model, apiKey, headers, customInstructions, signal, thinkingLevel, streamFn, env, retry, callbacks, sessionId) { +- const { firstKeptEntryId, messagesToSummarize, turnPrefixMessages, isSplitTurn, tokensBefore, previousSummary, fileOps, } = preparation; ++ const { firstKeptEntryId, messagesToSummarize, turnPrefixMessages, isSplitTurn, tokensBefore, previousSummary, fileOps, settings, } = preparation; + // Generate summaries and merge into one + let summary; + let summaryUsage; +@@ -694,18 +692,18 @@ export async function compact(preparation, model, apiKey, headers, customInstruc + let historyText = previousSummary ?? "No prior history."; + let historyUsage; + if (messagesToSummarize.length > 0) { +- const historyResult = await generateSummaryWithUsage(messagesToSummarize, model, undefined, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env, retry, callbacks, sessionId); ++ const historyResult = await generateSummaryWithUsage(messagesToSummarize, model, settings.reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env, retry, callbacks, sessionId); + historyText = historyResult.text; + historyUsage = historyResult.usage; + } +- const turnPrefixResult = await generateTurnPrefixSummary(turnPrefixMessages, model, apiKey, headers, env, signal, thinkingLevel, streamFn, retry, callbacks, sessionId, customInstructions); ++ const turnPrefixResult = await generateTurnPrefixSummary(turnPrefixMessages, model, apiKey, headers, env, signal, thinkingLevel, streamFn, retry, callbacks, sessionId, customInstructions, settings.reserveTokens); + // Merge into single summary + summary = `${historyText}\n\n---\n\n**Turn Context (split turn):**\n\n${turnPrefixResult.text}`; + summaryUsage = historyUsage ? combineUsage(historyUsage, turnPrefixResult.usage) : turnPrefixResult.usage; + } + else { + // Just generate history summary +- const result = await generateSummaryWithUsage(messagesToSummarize, model, undefined, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env, retry, callbacks, sessionId); ++ const result = await generateSummaryWithUsage(messagesToSummarize, model, settings.reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env, retry, callbacks, sessionId); + summary = result.text; + summaryUsage = result.usage; + } +@@ -726,14 +724,14 @@ export async function compact(preparation, model, apiKey, headers, customInstruc + /** + * Generate a summary for a turn prefix (when splitting a turn). + */ +-async function generateTurnPrefixSummary(messages, model, apiKey, headers, env, signal, thinkingLevel, streamFn, retry, callbacks, sessionId, customInstructions) { ++async function generateTurnPrefixSummary(messages, model, apiKey, headers, env, signal, thinkingLevel, streamFn, retry, callbacks, sessionId, customInstructions, reserveTokens) { + const llmMessages = convertToLlm(messages); + const conversationText = serializeConversation(llmMessages); + let promptText = `# Conversation\n${conversationText}\n\n# Instructions\n${TURN_PREFIX_SUMMARIZATION_PROMPT}`; + if (customInstructions) { + promptText = `${promptText}\n\nAdditional focus: ${customInstructions}`; + } +- const response = await completeSummarization(model, buildSummarizationContext(promptText), createSummarizationOptions(model, apiKey, headers, env, signal, thinkingLevel, sessionId), streamFn, retry, callbacks); ++ const response = await completeSummarization(model, buildSummarizationContext(promptText), createSummarizationOptions(model, apiKey, headers, env, signal, thinkingLevel, sessionId, reserveTokens), streamFn, retry, callbacks); + const failure = getSummarizationFailure(response, "Turn prefix summarization"); + if (failure) { + throw new Error(failure); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02bfdeb19..28b36def8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ overrides: exceljs>unzipper: 0.11.2 patchedDependencies: + '@earendil-works/pi-coding-agent@1.4.0': + hash: 0109641cd7ceb1a42210da2d94dc5b96cb397d4497a63266354e21fe1fdf1ef0 + path: patches/@earendil-works__pi-coding-agent@1.4.0.patch braces@3.0.3: hash: ad74a34b0200bbe14ba95e31e8f296205ce32a374eca2cef25cc8940aa0c76c1 path: patches/braces@3.0.3.patch @@ -550,11 +553,11 @@ importers: packages/runner-pi: dependencies: '@earendil-works/pi-ai': - specifier: 1.1.0 - version: 1.1.0(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.4)(undici@7.30.1)(ws@8.22.1)(zod@4.6.7) + specifier: 1.4.0 + version: 1.4.0(@aws-sdk/credential-provider-node@3.972.92)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.5)(undici@7.30.1)(ws@8.22.1)(zod@4.6.7) '@earendil-works/pi-coding-agent': - specifier: 1.1.0 - version: 1.1.0(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.4)(ws@8.22.1)(zod@4.6.7) + specifier: 1.4.0 + version: 1.4.0(patch_hash=0109641cd7ceb1a42210da2d94dc5b96cb397d4497a63266354e21fe1fdf1ef0)(@aws-sdk/credential-provider-node@3.972.92)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.5)(ws@8.22.1)(zod@4.6.7) '@ling-stack/plugin-sdk': specifier: workspace:* version: link:../plugin-sdk @@ -662,76 +665,76 @@ packages: resolution: {integrity: sha512-IDl/lrPb90aH+pZFHGNDmgH9nAUQj5PlZH1sJ3w7RikctyjHSnY3oNjZhrLoaBoQn/rNK0zsP6OHEqEhj2tdLA==} engines: {node: '>=20.0.0'} - '@aws-sdk/core@3.978.1': - resolution: {integrity: sha512-LbY9aGsEiznDWmUc30Nwv3aIX/+dbwTx8KfS0yOC3NPYMO+O91e6jkT1azf34FwjOndq8/Q+RcVVZz5xnerwdg==} + '@aws-sdk/core@3.979.1': + resolution: {integrity: sha512-ayOlV1VhLNMiq8PW9ZkVobG4gkldnUoHjG69yy2b8j+VYFlhz/uAL7ZdYQAoQ+eShtGUdNDnnG5rxDg6yUJrOg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.72': - resolution: {integrity: sha512-xTKO/FWJPozTIXbozVnVGoNBhaGba8TBcx+KyUjRVeOlXE+dUc7GTR1cLvu0uTdIdmemzaFbqqCshXeZA1fZew==} + '@aws-sdk/credential-provider-env@3.972.80': + resolution: {integrity: sha512-uO5TiSvb6j1w9RTe5z28OaOmsrOxVQUPaC5+wZl50RfOXcrYD/KgnS8I9lfyGXc7sGbkCopK6VnhNIAoLqfewQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.74': - resolution: {integrity: sha512-u91E/hT8f4d1xy0Jl7VG4nVKJ3lxbrZkoBTeSVoJdWBiSEUMwMS/9+e0H/aJVQV//Lt5wuzP+E69v4aRSsNTmw==} + '@aws-sdk/credential-provider-http@3.972.82': + resolution: {integrity: sha512-vQzlDHlC24Yz42p+rT4NBoP/5VdetkBoujbOLq9h6QYWC8THuZSPYnXIR9OP3XcOrdMgPBBipOrdssfxnIiWUg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.973.17': - resolution: {integrity: sha512-ged4KXdBkvIC81bLvNHHuQKdKak/VXhQTR1NWYTTqW0474nlmsxy9O/vlgTIohDDWH3xpBdtVMZRyjb+DnocDA==} + '@aws-sdk/credential-provider-ini@3.973.25': + resolution: {integrity: sha512-b5xl71uCRdWsu7P1VeGpiGuCf6zfYETsSNOv8AmYVTrsgbvTJRXdmmOPVfxkvGGVNsiKkGctClQW3jAn0SZLug==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.79': - resolution: {integrity: sha512-L+Z85anONJd8MaiuraO4wRxATCdEejBZ3K3eymzWI5JPXa9sOS9CkIm72PBKqXKX+Z9p9NGMX5AIMXm0LEflgw==} + '@aws-sdk/credential-provider-login@3.972.87': + resolution: {integrity: sha512-C4ZFmcwM+Zj14Z8huVUk54Gv4uzT1ZdzG9cY3Gdh8FePakq7Bss1OFsgZjAhWFOkFOGpBvFBeu0OWjWf8HNKRQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.84': - resolution: {integrity: sha512-oHt854odINVwzwsh+c5x69j0ajm4DbqqqVJ+O1ECsCIZeMDAbzFpXItaqP7UZstJj/ATdTk/KFSH0LaNAgV+kA==} + '@aws-sdk/credential-provider-node@3.972.92': + resolution: {integrity: sha512-jC3zmOo7Qxlk+oBivvSsS1Ph7sFGm0QfuhqDGbqgRXi4cxUYMG+dWtBwS2XYYXgc8TIVXJiwgQ65sbNpbYupTA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.72': - resolution: {integrity: sha512-rLIp2xbMjX/k9/od7APpqq1ZgXXnV0pOL1Th3ZsL8Wu0TRtBsDTVS8iPqcfRFcHakFxPvR04OSTv2ka2qOb/2A==} + '@aws-sdk/credential-provider-process@3.972.80': + resolution: {integrity: sha512-xqfixO5aclje7tbQJDias+iNND5wp/3QZixCdZcVQpgWPTZ0V5DfTW9A804A5Z7ezu7sH3WRO+vzUjtiJBA8yg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.973.16': - resolution: {integrity: sha512-IGihaJfFZYacJJr/odqILCoK7W/mvrZ7cuK7ECn3sAu4vLC6u0V8bS7mCGbdugJ8Aum2tnvqmx0F2MRFp2rn9g==} + '@aws-sdk/credential-provider-sso@3.973.24': + resolution: {integrity: sha512-nlg3BKG03Cgzvv/dMnhxvDJPhAhQSpaN0RUdwgU7ziwkasoev7iI8el8Xy4Rd5sqzgaDUbV269fOXck5SargqA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.78': - resolution: {integrity: sha512-/y9WvNtlcPBGLR0qc1a+9J/xtYZfVczvLUOuXaVWylzttH7ewsxwHtjmiJSolNrVSDorIxHGHMU61CbonRkmwA==} + '@aws-sdk/credential-provider-web-identity@3.972.86': + resolution: {integrity: sha512-zKTyLJBEyfQBVlYqT6Jt+mYV4r8kGbWM7dn6v4Y4MRARizhYafjDXP/iMu76UMRhToSPNmIKX1XAb24gtpBFIA==} engines: {node: '>=20.0.0'} - '@aws-sdk/eventstream-handler-node@3.972.35': - resolution: {integrity: sha512-a8xilRoRaalvSPZdfrs0VY3/BPc0uYhXW56Z/k6nmZ5Vk430LHeowf9APIPq8utM3tMJSNGSSuJMlB9YrPsN+A==} + '@aws-sdk/eventstream-handler-node@3.972.40': + resolution: {integrity: sha512-LR2mRKFb9EMlGHmJNXMtuMPvVQqN1b9/v68A1UQaE72pb8pHqiHxTtS++vaab8844YesGVzBVrloAis7+EXq/w==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-eventstream@3.972.30': - resolution: {integrity: sha512-B6gvZlcnRBNWraKgyEjKsbhv+VjtbyHmpU7hmtTHzXpDSxHPpCJnYLpglEOOsF+SFne20DbZC5IVC1aNr2Pb4A==} + '@aws-sdk/middleware-eventstream@3.972.36': + resolution: {integrity: sha512-OkV+alDzmJ3DOs2mRPLSM9FUVSul7G1wkpKrbO+tyxxGOT7qLMPZHOlj4Ipjw9OayRmU7nMVPSFo7hvUqOSeJg==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-websocket@3.972.54': - resolution: {integrity: sha512-bhESdru8u8KosziH8jcVta/NM/dNreeRz2+2aU86si5bfBYOiJ6IiqD+9U4URUcU5WJO3Yw+jO3GLDIHlscXMQ==} + '@aws-sdk/middleware-websocket@3.972.62': + resolution: {integrity: sha512-pNkKv8TlxEBpL26J8zpeHLzW//As72QapCPfciTs7k7H+ppFZxE/zVteAH9zdFI83Xx7Ki5rE0hJjVh+TmOH7g==} engines: {node: '>= 14.0.0'} - '@aws-sdk/nested-clients@3.997.46': - resolution: {integrity: sha512-oRxtBcka/JGHGs9l9p9IVajGoTP8vTPmoAzdHGy4Qcy9P5vPnDf6nhIeM/COQNY9k/OahImTRaLkHftoXvfcmQ==} + '@aws-sdk/nested-clients@3.997.54': + resolution: {integrity: sha512-/OczlavsS7U5sOodRO10Ug4R/AKFVZiXTstKipWe68EfjPkmdDFNXNl9FCJyXWkg1DG6RBm3qAuVB8FNW9O8KQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.47': - resolution: {integrity: sha512-Zk08macMvQTHzQJCLJVkOlviVoqwYMrpXv4lmLN7b7sAbiMoOK7Go0NYdR5UeF+MW8LIbRmwrNy9u/5VvX1U5g==} + '@aws-sdk/signature-v4-multi-region@3.996.51': + resolution: {integrity: sha512-+aHvUugVBuMPXxgkPfWnTMyGdE/yWS8GHi5+qQ37HowS0YqzrbuaDLznj+Dtmtu5jgCdqz36gXmujOToUhNNWw==} engines: {node: '>=20.0.0'} '@aws-sdk/token-providers@3.1127.0': resolution: {integrity: sha512-Dv2TMWBshJ+tF6ahs2Sy5bh4Iabsd4GAQqVvE9XZmYmnoaVbpS2QKIKE/HRacc7bTtbjEEvP+laGzHvHlf1CiQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.1138.0': - resolution: {integrity: sha512-GpyAr0DD63YOEmYFM6Df+gJuIgC92MMTiBK4FTKfxii5MJ9ge20epR7LyroulscYlG89J+ZB2ivFDPjvfQhzdw==} + '@aws-sdk/token-providers@3.1161.0': + resolution: {integrity: sha512-ypbXSofNcSHwf/KA40bFCXJb0MLaAKrfT7sot4dFaA+2lsuXNah4zLRJIAU7Qmvs9PFJ6rnY0bZFEC+mE7attA==} engines: {node: '>=20.0.0'} - '@aws-sdk/types@3.974.6': - resolution: {integrity: sha512-v/clNZzZnDxGyvpHMOGpJKVXFAExJzUNAAjaWGdcx8QAcXLGwTaOkw33p5SHAi0YAioK32xB3hWwOekRVfmfKg==} + '@aws-sdk/types@3.975.0': + resolution: {integrity: sha512-WQlhs6juByzWOzj5fwxOx0mPJaEqMcG/sDpl3Id61B3XhKE63xY+0QWcnG+sWR/sCfprmreyUo1lM7IKZmHMzw==} engines: {node: '>=20.0.0'} - '@aws-sdk/xml-builder@3.972.41': - resolution: {integrity: sha512-ctjVSyCMegrWfXlx6VqzSBFI6UqmQ5ZlnfMhdLIiWmhoH8UAQxSCP5N3OpG7X3k4LnS7ou74C4mt20+bfTW2aQ==} + '@aws-sdk/xml-builder@3.972.42': + resolution: {integrity: sha512-smX8/gNP8Kjq+CWTBMZQLQ912vOQjiWExzwzvMO+eujPB5RY8IbtF0AGdUUXHKN7KoDWK9dIcuW0WG269kiP6w==} engines: {node: '>=20.0.0'} '@aws/lambda-invoke-store@0.3.0': @@ -1134,38 +1137,34 @@ packages: '@chevrotain/types@11.1.2': resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} - '@earendil-works/chord@1.1.0': - resolution: {integrity: sha512-gsHzKfyQ3t0ZIQ3cLBjJ5Vqy1TYnFyruHIV3g3BwmulCDYe5BW4yT9vaJk9QzN6YANILIO75uzuq+Gdxtzz1og==} - engines: {node: '>=22.19.0'} - - '@earendil-works/pi-agent-core@1.1.0': - resolution: {integrity: sha512-aX1KZomNCPmwYnXa3OivF3VYLJ+WPUkIJlEIZTgwdOZdY/+oToWTQ334WYpQeOz9POpiYFNMJLPwIhXQ4e48kg==} + '@earendil-works/pi-agent-core@1.4.0': + resolution: {integrity: sha512-PoKY84SKUwnt7S5QBZaGUqfNO1kjP3KHpHUA9QpFTj4cOjaVWMYIcBPJ6FDRCdE8Zen9OSECQUd0uUfVgtSmgA==} engines: {node: '>=22.19.0'} - '@earendil-works/pi-ai@1.1.0': - resolution: {integrity: sha512-1T7LAkc/5Bvc0v6w4vAGVdCrli0o/E0pEmYKTnixu95vSFArBjvbhS/G4ZwI0RUePgf0Imcu0VyqlM4EcXxqfw==} + '@earendil-works/pi-ai@1.4.0': + resolution: {integrity: sha512-hQM/C4+1w8rHYACzDDf+0vQMnEnpzIop1tptIERVgR3ZeT/hHSzBNG8PaWPgxWQjqSeKCyBZSyp8uTT6eKK1pQ==} engines: {node: '>=22.19.0'} hasBin: true - '@earendil-works/pi-codemode@1.1.0': - resolution: {integrity: sha512-8Asc2AzhoNaXS1snmRFa96OhcWIlFM5k1Kuiz6p2DvIYgi5QHQccRAmDVY9oO92TzWrizpvQpconZGQ7JhlI7Q==} + '@earendil-works/pi-codemode@1.4.0': + resolution: {integrity: sha512-23CNAXpS9DuLzPMyYuvrXVVio46x4YhffCgCqaWmF7F5H8PooqjrQvX4ucF6M0BhUd+x2tV6r1J0dv8cCME4Cg==} engines: {node: '>=22.19.0'} - '@earendil-works/pi-coding-agent@1.1.0': - resolution: {integrity: sha512-SeEi/4hdcHNgA9UWlefZl7ZZpm3dzi2OoxNjDHsBJ9o298LNOtbL4DGKgitlEj6uCTccvtw6f2hlCkTPVJ2RXg==} + '@earendil-works/pi-coding-agent@1.4.0': + resolution: {integrity: sha512-Z41LpZ3yYHSC/UUps6Mr39UMFPwH8elhJBG9DY1P7kuzsE5qSK/6eMj2EHzO5evJRQWLbKSqUMw+4nCNtIyiQg==} engines: {node: '>=22.19.0'} hasBin: true - '@earendil-works/pi-mcp@1.1.0': - resolution: {integrity: sha512-xGKwvu3SvVTeoIx8Z7UGoJprB4VK20wKORMhufcWGx61fIauhu3J+UqfB5eeoF1oE/geYBA598K6nh1SdABQkg==} + '@earendil-works/pi-mcp@1.4.0': + resolution: {integrity: sha512-92aZmmGsUpHHknYuKXZHRINQfahntw5hU9If0I0ZM49GojOaFHpkl5/GF3/aatqpt7v7GjZbBfpfSygGKW+pnw==} engines: {node: '>=22.19.0'} - '@earendil-works/pi-telemetry@1.1.0': - resolution: {integrity: sha512-8gAK05/2pPozZZz6hCLOi8x2vsqzvsmO9gG92kbvuvTPm0qMHaFlaXX98ndXsrOi5pmzha7vNLguuG4+0Rgxjw==} + '@earendil-works/pi-telemetry@1.4.0': + resolution: {integrity: sha512-MLIfowwUYIY65jSjMX82paZOrX/NTvLk6D08h+3Jq42a99RzUOewzuCR0zOlPul3D6UBfddat76VT6LvsHEs1w==} engines: {node: '>=22.19.0'} - '@earendil-works/pi-tui@1.1.0': - resolution: {integrity: sha512-v7wkS0y2ErZvZkSfemqd9RrBZJ5x6p8Ujsv7NdJj01IXJyFM0kNL6rMdcKcvTe7EVTd6ugvDB9VPZSoaBF9QxQ==} + '@earendil-works/pi-tui@1.4.0': + resolution: {integrity: sha512-4obPOjgOD7g4mGSlngIvxyujC1UPdmyI9zdVthbr8GufacFEX+Ce0+scPgHg++k2xj5+QjESM2d5TxvIuzCVmg==} engines: {node: '>=22.19.0'} '@electron-internal/extract-zip@1.0.5': @@ -2636,10 +2635,9 @@ packages: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} - '@smithy/core@3.35.1': - resolution: {integrity: sha512-i4YPS4B6ts7bjn7UwLnGjiZdprOvHvgGobFZsYK3GIY3E5hIqtj0rReU69BcTpGp+fvtraSNXeG1l+jtJvF55w==} + '@smithy/core@3.38.1': + resolution: {integrity: sha512-U/mB2XiwTLaf+NSgLSWwJfptsMT/H8aBi0aTAA/E5e2/TagFeGCqAyhKGG0w0A9IWTkm4qYEmLoD/HB6aYfnRA==} engines: {node: '>=18.0.0'} - deprecated: Deprecated due to a bug in custom logger data redaction. See https://github.com/aws/aws-sdk-js-v3/issues/8393. '@smithy/credential-provider-imds@4.5.2': resolution: {integrity: sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg==} @@ -2653,8 +2651,12 @@ packages: resolution: {integrity: sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw==} engines: {node: '>=18.0.0'} - '@smithy/signature-v4@5.7.4': - resolution: {integrity: sha512-tHy0K0VtqNd5Y7Y41h0a0Lhh0L1GzC08dTWg0F7vRJWFtTENg7IZikf3wQkanYIRdb7ngoIPMTmqgUi401fEeQ==} + '@smithy/node-http-handler@4.14.1': + resolution: {integrity: sha512-/T6E1jzCL0fErS9uq8JqES/5yYQQ4ppVmmYHwXw2nlov8KFzLb+3QqHR5iAun1BsuAB50IPxZliV8YMgghLwhA==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.7.5': + resolution: {integrity: sha512-WPjdr5oWOk1LArpI4pavu+fSo+/evi0Re1olxGvqwuZopd4gYR1UGCi+Soyn/IjmafqbWs+ZC+3AKxJS3ZpwUg==} engines: {node: '>=18.0.0'} '@smithy/types@4.19.0': @@ -3264,8 +3266,8 @@ packages: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - bowser@2.14.1: - resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + bowser@2.15.0: + resolution: {integrity: sha512-xic6KSZglg/I4ymp45fdM4GWfYpBK79Fxd/TOvJktlaPgQqqDxvmGwOPZl2V0dyeS3Lj5c180bLhXF43iyAjZQ==} bplist-creator@0.1.0: resolution: {integrity: sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==} @@ -4956,6 +4958,12 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + marked-cjk-friendly@0.1.2: + resolution: {integrity: sha512-GUj8HjiEbur9yhgUo52FBgKizggF1QtT6gVdrYdWW6ZB4lVVjgS3EyyXPyfyRD0V4ghGRPlO7MO80rgSWbm0eA==} + engines: {node: '>=18'} + peerDependencies: + marked: '>=15.0.0' + marked@16.4.2: resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} engines: {node: '>= 20'} @@ -6338,6 +6346,9 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tslib@2.9.1: + resolution: {integrity: sha512-a4Ux9VKuIMHsOS7ENbEq6hK2ZGYIT27Rtl0E4eD9KqwxhKiQeMZE/9xb3IdYwWaSOyIBQLExhQgXDTYoiCxnWA==} + type-fest@0.13.1: resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} engines: {node: '>=10'} @@ -6824,183 +6835,183 @@ snapshots: '@aws-sdk/client-bedrock-runtime@3.1127.0': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/credential-provider-node': 3.972.84 - '@aws-sdk/eventstream-handler-node': 3.972.35 - '@aws-sdk/middleware-eventstream': 3.972.30 - '@aws-sdk/middleware-websocket': 3.972.54 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/credential-provider-node': 3.972.92 + '@aws-sdk/eventstream-handler-node': 3.972.40 + '@aws-sdk/middleware-eventstream': 3.972.36 + '@aws-sdk/middleware-websocket': 3.972.62 '@aws-sdk/token-providers': 3.1127.0 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/fetch-http-handler': 5.8.0 - '@smithy/node-http-handler': 4.12.1 + '@smithy/node-http-handler': 4.14.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/core@3.978.1': + '@aws-sdk/core@3.979.1': dependencies: - '@aws-sdk/types': 3.974.6 - '@aws-sdk/xml-builder': 3.972.41 + '@aws-sdk/types': 3.975.0 + '@aws-sdk/xml-builder': 3.972.42 '@aws/lambda-invoke-store': 0.3.0 - '@smithy/core': 3.35.1 - '@smithy/signature-v4': 5.7.4 + '@smithy/core': 3.38.1 + '@smithy/signature-v4': 5.7.5 '@smithy/types': 4.19.0 - bowser: 2.14.1 - tslib: 2.8.1 + bowser: 2.15.0 + tslib: 2.9.1 - '@aws-sdk/credential-provider-env@3.972.72': + '@aws-sdk/credential-provider-env@3.972.80': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/credential-provider-http@3.972.74': + '@aws-sdk/credential-provider-http@3.972.82': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/fetch-http-handler': 5.8.0 - '@smithy/node-http-handler': 4.12.1 + '@smithy/node-http-handler': 4.14.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-ini@3.973.17': - dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/credential-provider-env': 3.972.72 - '@aws-sdk/credential-provider-http': 3.972.74 - '@aws-sdk/credential-provider-login': 3.972.79 - '@aws-sdk/credential-provider-process': 3.972.72 - '@aws-sdk/credential-provider-sso': 3.973.16 - '@aws-sdk/credential-provider-web-identity': 3.972.78 - '@aws-sdk/nested-clients': 3.997.46 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + tslib: 2.9.1 + + '@aws-sdk/credential-provider-ini@3.973.25': + dependencies: + '@aws-sdk/core': 3.979.1 + '@aws-sdk/credential-provider-env': 3.972.80 + '@aws-sdk/credential-provider-http': 3.972.82 + '@aws-sdk/credential-provider-login': 3.972.87 + '@aws-sdk/credential-provider-process': 3.972.80 + '@aws-sdk/credential-provider-sso': 3.973.24 + '@aws-sdk/credential-provider-web-identity': 3.972.86 + '@aws-sdk/nested-clients': 3.997.54 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/credential-provider-imds': 4.5.2 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/credential-provider-login@3.972.79': + '@aws-sdk/credential-provider-login@3.972.87': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/nested-clients': 3.997.46 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/nested-clients': 3.997.54 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-node@3.972.84': - dependencies: - '@aws-sdk/credential-provider-env': 3.972.72 - '@aws-sdk/credential-provider-http': 3.972.74 - '@aws-sdk/credential-provider-ini': 3.973.17 - '@aws-sdk/credential-provider-process': 3.972.72 - '@aws-sdk/credential-provider-sso': 3.973.16 - '@aws-sdk/credential-provider-web-identity': 3.972.78 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + tslib: 2.9.1 + + '@aws-sdk/credential-provider-node@3.972.92': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.80 + '@aws-sdk/credential-provider-http': 3.972.82 + '@aws-sdk/credential-provider-ini': 3.973.25 + '@aws-sdk/credential-provider-process': 3.972.80 + '@aws-sdk/credential-provider-sso': 3.973.24 + '@aws-sdk/credential-provider-web-identity': 3.972.86 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/credential-provider-imds': 4.5.2 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/credential-provider-process@3.972.72': + '@aws-sdk/credential-provider-process@3.972.80': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/credential-provider-sso@3.973.16': + '@aws-sdk/credential-provider-sso@3.973.24': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/nested-clients': 3.997.46 - '@aws-sdk/token-providers': 3.1138.0 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/nested-clients': 3.997.54 + '@aws-sdk/token-providers': 3.1161.0 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/credential-provider-web-identity@3.972.78': + '@aws-sdk/credential-provider-web-identity@3.972.86': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/nested-clients': 3.997.46 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/nested-clients': 3.997.54 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/eventstream-handler-node@3.972.35': + '@aws-sdk/eventstream-handler-node@3.972.40': dependencies: - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/middleware-eventstream@3.972.30': + '@aws-sdk/middleware-eventstream@3.972.36': dependencies: - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/middleware-websocket@3.972.54': + '@aws-sdk/middleware-websocket@3.972.62': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/fetch-http-handler': 5.8.0 - '@smithy/signature-v4': 5.7.4 + '@smithy/signature-v4': 5.7.5 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/nested-clients@3.997.46': + '@aws-sdk/nested-clients@3.997.54': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/signature-v4-multi-region': 3.996.47 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/signature-v4-multi-region': 3.996.51 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/fetch-http-handler': 5.8.0 - '@smithy/node-http-handler': 4.12.1 + '@smithy/node-http-handler': 4.14.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/signature-v4-multi-region@3.996.47': + '@aws-sdk/signature-v4-multi-region@3.996.51': dependencies: - '@aws-sdk/types': 3.974.6 - '@smithy/signature-v4': 5.7.4 + '@aws-sdk/types': 3.975.0 + '@smithy/signature-v4': 5.7.5 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 '@aws-sdk/token-providers@3.1127.0': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/nested-clients': 3.997.46 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/nested-clients': 3.997.54 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/token-providers@3.1138.0': + '@aws-sdk/token-providers@3.1161.0': dependencies: - '@aws-sdk/core': 3.978.1 - '@aws-sdk/nested-clients': 3.997.46 - '@aws-sdk/types': 3.974.6 - '@smithy/core': 3.35.1 + '@aws-sdk/core': 3.979.1 + '@aws-sdk/nested-clients': 3.997.54 + '@aws-sdk/types': 3.975.0 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/types@3.974.6': + '@aws-sdk/types@3.975.0': dependencies: '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@aws-sdk/xml-builder@3.972.41': + '@aws-sdk/xml-builder@3.972.42': dependencies: '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 '@aws/lambda-invoke-store@0.3.0': {} @@ -7508,13 +7519,9 @@ snapshots: '@chevrotain/types@11.1.2': {} - '@earendil-works/chord@1.1.0': + '@earendil-works/pi-agent-core@1.4.0(@aws-sdk/credential-provider-node@3.972.92)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.5)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7)': dependencies: - esbuild: 0.28.2 - - '@earendil-works/pi-agent-core@1.1.0(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.4)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7)': - dependencies: - '@earendil-works/pi-ai': 1.1.0(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.4)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7) + '@earendil-works/pi-ai': 1.4.0(@aws-sdk/credential-provider-node@3.972.92)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.5)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7) typebox: 1.3.27 transitivePeerDependencies: - '@aws-sdk/credential-provider-node' @@ -7529,16 +7536,16 @@ snapshots: - ws - zod - '@earendil-works/pi-ai@1.1.0(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.4)(undici@7.30.1)(ws@8.22.1)(zod@4.6.7)': + '@earendil-works/pi-ai@1.4.0(@aws-sdk/credential-provider-node@3.972.92)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.5)(undici@7.30.1)(ws@8.22.1)(zod@4.6.7)': dependencies: '@anthropic-ai/sdk': 0.129.0(zod@4.6.7) '@aws-sdk/client-bedrock-runtime': 3.1127.0 - '@earendil-works/pi-telemetry': 1.1.0 + '@earendil-works/pi-telemetry': 1.4.0 '@google/genai': 2.21.0(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7)) '@smithy/node-http-handler': 4.12.1 http-proxy-agent: 9.1.0 https-proxy-agent: 9.1.0 - openai: 7.19.0(@aws-sdk/credential-provider-node@3.972.84)(@smithy/signature-v4@5.7.4)(undici@7.30.1)(ws@8.22.1)(zod@4.6.7) + openai: 7.19.0(@aws-sdk/credential-provider-node@3.972.92)(@smithy/signature-v4@5.7.5)(undici@7.30.1)(ws@8.22.1)(zod@4.6.7) partial-json: 0.1.7 typebox: 1.3.27 transitivePeerDependencies: @@ -7554,16 +7561,16 @@ snapshots: - ws - zod - '@earendil-works/pi-ai@1.1.0(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.4)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7)': + '@earendil-works/pi-ai@1.4.0(@aws-sdk/credential-provider-node@3.972.92)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.5)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7)': dependencies: '@anthropic-ai/sdk': 0.129.0(zod@4.6.7) '@aws-sdk/client-bedrock-runtime': 3.1127.0 - '@earendil-works/pi-telemetry': 1.1.0 + '@earendil-works/pi-telemetry': 1.4.0 '@google/genai': 2.21.0(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7)) '@smithy/node-http-handler': 4.12.1 http-proxy-agent: 9.1.0 https-proxy-agent: 9.1.0 - openai: 7.19.0(@aws-sdk/credential-provider-node@3.972.84)(@smithy/signature-v4@5.7.4)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7) + openai: 7.19.0(@aws-sdk/credential-provider-node@3.972.92)(@smithy/signature-v4@5.7.5)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7) partial-json: 0.1.7 typebox: 1.3.27 transitivePeerDependencies: @@ -7579,18 +7586,17 @@ snapshots: - ws - zod - '@earendil-works/pi-codemode@1.1.0': + '@earendil-works/pi-codemode@1.4.0': dependencies: quickjs-wasi: 3.6.2 - '@earendil-works/pi-coding-agent@1.1.0(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.4)(ws@8.22.1)(zod@4.6.7)': + '@earendil-works/pi-coding-agent@1.4.0(patch_hash=0109641cd7ceb1a42210da2d94dc5b96cb397d4497a63266354e21fe1fdf1ef0)(@aws-sdk/credential-provider-node@3.972.92)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.5)(ws@8.22.1)(zod@4.6.7)': dependencies: - '@earendil-works/chord': 1.1.0 - '@earendil-works/pi-agent-core': 1.1.0(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.4)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7) - '@earendil-works/pi-ai': 1.1.0(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.4)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7) - '@earendil-works/pi-codemode': 1.1.0 - '@earendil-works/pi-mcp': 1.1.0 - '@earendil-works/pi-tui': 1.1.0 + '@earendil-works/pi-agent-core': 1.4.0(@aws-sdk/credential-provider-node@3.972.92)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.5)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7) + '@earendil-works/pi-ai': 1.4.0(@aws-sdk/credential-provider-node@3.972.92)(@modelcontextprotocol/sdk@1.32.2(zod@4.6.7))(@smithy/signature-v4@5.7.5)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7) + '@earendil-works/pi-codemode': 1.4.0 + '@earendil-works/pi-mcp': 1.4.0 + '@earendil-works/pi-tui': 1.4.0 '@silvia-odwyer/photon-node': 0.3.4 brace-expansion: 5.0.12 chalk: 6.0.0 @@ -7620,16 +7626,17 @@ snapshots: - ws - zod - '@earendil-works/pi-mcp@1.1.0': + '@earendil-works/pi-mcp@1.4.0': dependencies: cross-spawn: 7.0.6 - '@earendil-works/pi-telemetry@1.1.0': {} + '@earendil-works/pi-telemetry@1.4.0': {} - '@earendil-works/pi-tui@1.1.0': + '@earendil-works/pi-tui@1.4.0': dependencies: get-east-asian-width: 1.6.0 marked: 18.0.11 + marked-cjk-friendly: 0.1.2(marked@18.0.11) '@electron-internal/extract-zip@1.0.5': {} @@ -8252,7 +8259,7 @@ snapshots: google-auth-library: 10.9.1 p-retry: 4.6.2 protobufjs: 7.6.5 - ws: 8.22.0 + ws: 8.22.1 optionalDependencies: '@modelcontextprotocol/sdk': 1.32.2(zod@4.6.7) transitivePeerDependencies: @@ -8557,15 +8564,15 @@ snapshots: dependencies: '@peculiar/utils': 2.0.3 asn1js: 3.0.10 - tslib: 2.8.1 + tslib: 2.9.1 '@peculiar/json-schema@1.1.12': dependencies: - tslib: 2.8.1 + tslib: 2.9.1 '@peculiar/utils@2.0.3': dependencies: - tslib: 2.8.1 + tslib: 2.9.1 '@peculiar/webcrypto@1.7.1': dependencies: @@ -9235,38 +9242,44 @@ snapshots: '@sindresorhus/is@4.6.0': {} - '@smithy/core@3.35.1': + '@smithy/core@3.38.1': dependencies: '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 '@smithy/credential-provider-imds@4.5.2': dependencies: - '@smithy/core': 3.35.1 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 '@smithy/fetch-http-handler@5.8.0': dependencies: - '@smithy/core': 3.35.1 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 '@smithy/node-http-handler@4.12.1': dependencies: - '@smithy/core': 3.35.1 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 - '@smithy/signature-v4@5.7.4': + '@smithy/node-http-handler@4.14.1': dependencies: - '@smithy/core': 3.35.1 + '@smithy/core': 3.38.1 '@smithy/types': 4.19.0 - tslib: 2.8.1 + tslib: 2.9.1 + + '@smithy/signature-v4@5.7.5': + dependencies: + '@smithy/core': 3.38.1 + '@smithy/types': 4.19.0 + tslib: 2.9.1 '@smithy/types@4.19.0': dependencies: - tslib: 2.8.1 + tslib: 2.9.1 '@stablelib/base64@1.0.1': {} @@ -9932,7 +9945,7 @@ snapshots: boolean@3.2.0: optional: true - bowser@2.14.1: {} + bowser@2.15.0: {} bplist-creator@0.1.0: dependencies: @@ -11762,6 +11775,10 @@ snapshots: markdown-table@3.0.4: {} + marked-cjk-friendly@0.1.2(marked@18.0.11): + dependencies: + marked: 18.0.11 + marked@16.4.2: {} marked@18.0.11: {} @@ -12680,18 +12697,18 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - openai@7.19.0(@aws-sdk/credential-provider-node@3.972.84)(@smithy/signature-v4@5.7.4)(undici@7.30.1)(ws@8.22.1)(zod@4.6.7): + openai@7.19.0(@aws-sdk/credential-provider-node@3.972.92)(@smithy/signature-v4@5.7.5)(undici@7.30.1)(ws@8.22.1)(zod@4.6.7): optionalDependencies: - '@aws-sdk/credential-provider-node': 3.972.84 - '@smithy/signature-v4': 5.7.4 + '@aws-sdk/credential-provider-node': 3.972.92 + '@smithy/signature-v4': 5.7.5 undici: 7.30.1 ws: 8.22.1 zod: 4.6.7 - openai@7.19.0(@aws-sdk/credential-provider-node@3.972.84)(@smithy/signature-v4@5.7.4)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7): + openai@7.19.0(@aws-sdk/credential-provider-node@3.972.92)(@smithy/signature-v4@5.7.5)(undici@8.12.2)(ws@8.22.1)(zod@4.6.7): optionalDependencies: - '@aws-sdk/credential-provider-node': 3.972.84 - '@smithy/signature-v4': 5.7.4 + '@aws-sdk/credential-provider-node': 3.972.92 + '@smithy/signature-v4': 5.7.5 undici: 8.12.2 ws: 8.22.1 zod: 4.6.7 @@ -12914,7 +12931,7 @@ snapshots: pvtsutils@1.3.6: dependencies: - tslib: 2.8.1 + tslib: 2.9.1 pvutils@1.1.5: {} @@ -13029,7 +13046,7 @@ snapshots: dependencies: react: 19.3.0 react-style-singleton: 2.2.3(@types/react@19.3.0)(react@19.3.0) - tslib: 2.8.1 + tslib: 2.9.1 optionalDependencies: '@types/react': 19.3.0 @@ -13048,7 +13065,7 @@ snapshots: dependencies: get-nonce: 1.0.1 react: 19.3.0 - tslib: 2.8.1 + tslib: 2.9.1 optionalDependencies: '@types/react': 19.3.0 @@ -13621,6 +13638,8 @@ snapshots: tslib@2.8.1: {} + tslib@2.9.1: {} + type-fest@0.13.1: optional: true @@ -13767,7 +13786,7 @@ snapshots: use-callback-ref@1.3.3(@types/react@19.3.0)(react@19.3.0): dependencies: react: 19.3.0 - tslib: 2.8.1 + tslib: 2.9.1 optionalDependencies: '@types/react': 19.3.0 @@ -13779,7 +13798,7 @@ snapshots: dependencies: detect-node-es: 1.1.0 react: 19.3.0 - tslib: 2.8.1 + tslib: 2.9.1 optionalDependencies: '@types/react': 19.3.0 @@ -13848,7 +13867,7 @@ snapshots: '@peculiar/json-schema': 1.1.12 '@peculiar/utils': 2.0.3 asn1js: 3.0.10 - tslib: 2.8.1 + tslib: 2.9.1 webidl-conversions@3.0.1: {}