@koda-sl/baker-bridge 0.147.0-dev.ad499429a → 0.148.0-dev.a87640a51
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/README.md +12 -1
- package/dist/hono/bridge-job.d.ts +2 -1
- package/dist/hono/bridge-job.d.ts.map +1 -1
- package/dist/hono/bridge-job.js +69 -7
- package/dist/hono/bridge-job.js.map +1 -1
- package/dist/hono/bridge-job.test.js +79 -2
- package/dist/hono/bridge-job.test.js.map +1 -1
- package/dist/hono/turn-events.d.ts +1 -1
- package/dist/hono/turn-events.d.ts.map +1 -1
- package/dist/hono/turn-events.js.map +1 -1
- package/package.json +1 -1
|
@@ -260,6 +260,24 @@ function memoryInFlightTurns(initial) {
|
|
|
260
260
|
},
|
|
261
261
|
};
|
|
262
262
|
}
|
|
263
|
+
// The CLI's own report of a failed model request, written as an assistant
|
|
264
|
+
// message — the shape production stores (`model: "<synthetic>"`, `error`).
|
|
265
|
+
function apiErrorMessage(uuid, text, error) {
|
|
266
|
+
return {
|
|
267
|
+
type: "assistant",
|
|
268
|
+
uuid,
|
|
269
|
+
session_id: "session_api_error",
|
|
270
|
+
parent_tool_use_id: null,
|
|
271
|
+
error,
|
|
272
|
+
is_api_error_message: true,
|
|
273
|
+
message: {
|
|
274
|
+
role: "assistant",
|
|
275
|
+
model: "<synthetic>",
|
|
276
|
+
content: [{ type: "text", text }],
|
|
277
|
+
stop_reason: "stop_sequence",
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
}
|
|
263
281
|
function resultMessage(costUsd, sessionId, modelUsage) {
|
|
264
282
|
return {
|
|
265
283
|
type: "result",
|
|
@@ -2061,7 +2079,7 @@ describe("BridgeJobExecutor", () => {
|
|
|
2061
2079
|
expect(savedBoundaries).toEqual([]);
|
|
2062
2080
|
expect(clearCalls).toContainEqual({ threadId: "thread_result_error", reason: "result_error" });
|
|
2063
2081
|
});
|
|
2064
|
-
it("
|
|
2082
|
+
it("reports a provider's server error in product language, not its status line", async () => {
|
|
2065
2083
|
const clearCalls = [];
|
|
2066
2084
|
const executor = createExecutor({
|
|
2067
2085
|
clearCalls,
|
|
@@ -2087,10 +2105,69 @@ describe("BridgeJobExecutor", () => {
|
|
|
2087
2105
|
kind: "errored",
|
|
2088
2106
|
costUsd: 0.17,
|
|
2089
2107
|
model: "claude-test",
|
|
2090
|
-
errors: ["
|
|
2108
|
+
errors: [expect.stringContaining("on our side")],
|
|
2091
2109
|
});
|
|
2092
2110
|
expect(clearCalls).toContainEqual({ threadId: "thread_provider_result_error", reason: "result_error" });
|
|
2093
2111
|
});
|
|
2112
|
+
it("never shows the marketer a model provider's billing error, as a reply or as the turn's error", async () => {
|
|
2113
|
+
const providerError = "API Error: 402 Insufficient credits. Add more using https://openrouter.ai/settings/credits";
|
|
2114
|
+
const relay = recordingRelay();
|
|
2115
|
+
const executor = createExecutor({
|
|
2116
|
+
relay,
|
|
2117
|
+
queryResults: [
|
|
2118
|
+
scriptedMessages(apiErrorMessage("assistant_402", providerError, "unknown"), {
|
|
2119
|
+
type: "result",
|
|
2120
|
+
subtype: "success",
|
|
2121
|
+
is_error: true,
|
|
2122
|
+
result: providerError,
|
|
2123
|
+
api_error_status: 402,
|
|
2124
|
+
total_cost_usd: 0,
|
|
2125
|
+
session_id: "session_402",
|
|
2126
|
+
}),
|
|
2127
|
+
],
|
|
2128
|
+
});
|
|
2129
|
+
const outcome = await executor.execute({ threadId: "thread_402", turnId: "turn_402", prompt: "Build the creatives", history: history([]) }, activeControls());
|
|
2130
|
+
const shown = JSON.stringify([relay.assistantEvents, outcome.kind === "errored" ? outcome.errors : []]);
|
|
2131
|
+
expect(outcome.kind).toBe("errored");
|
|
2132
|
+
expect(shown).not.toMatch(/API Error|openrouter|402/i);
|
|
2133
|
+
});
|
|
2134
|
+
it("tells the marketer how to fix an image the provider could not read, not to send the same message again", async () => {
|
|
2135
|
+
const imageError = 'API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"Could not process image"}}';
|
|
2136
|
+
const executor = createExecutor({
|
|
2137
|
+
queryResults: [
|
|
2138
|
+
scriptedMessages({
|
|
2139
|
+
type: "result",
|
|
2140
|
+
subtype: "success",
|
|
2141
|
+
is_error: true,
|
|
2142
|
+
result: imageError,
|
|
2143
|
+
api_error_status: 400,
|
|
2144
|
+
total_cost_usd: 0,
|
|
2145
|
+
session_id: "session_bad_image",
|
|
2146
|
+
}),
|
|
2147
|
+
],
|
|
2148
|
+
});
|
|
2149
|
+
const outcome = await executor.execute({ threadId: "thread_bad_image", turnId: "turn_bad_image", prompt: "Use this photo", history: history([]) }, activeControls());
|
|
2150
|
+
expect(outcome.kind === "errored" ? outcome.errors : []).toEqual([
|
|
2151
|
+
expect.stringContaining("extension lies about its format"),
|
|
2152
|
+
]);
|
|
2153
|
+
});
|
|
2154
|
+
it("keeps a server error the turn recovered from out of the chat, and in the turn events", async () => {
|
|
2155
|
+
const providerError = "API Error: Server error mid-response. The response above may be incomplete.";
|
|
2156
|
+
const relay = recordingRelay();
|
|
2157
|
+
const turnEvents = [];
|
|
2158
|
+
const executor = createExecutor({
|
|
2159
|
+
relay,
|
|
2160
|
+
turnEvents,
|
|
2161
|
+
queryResults: [
|
|
2162
|
+
scriptedMessages(apiErrorMessage("assistant_server_error", providerError, "server_error"), assistantMessage("assistant_recovered", "Your three headlines are ready.", "session_recovered"), resultMessage(0.3, "session_recovered")),
|
|
2163
|
+
],
|
|
2164
|
+
});
|
|
2165
|
+
const outcome = await executor.execute({ threadId: "thread_recovered", turnId: "turn_recovered", prompt: "Write headlines", history: history([]) }, activeControls());
|
|
2166
|
+
expect(outcome.kind).toBe("completed");
|
|
2167
|
+
expect(JSON.stringify(relay.assistantEvents)).not.toContain("API Error");
|
|
2168
|
+
expect(JSON.stringify(relay.assistantEvents)).toContain("Your three headlines are ready.");
|
|
2169
|
+
expect(turnEvents).toContainEqual(expect.objectContaining({ event: "api_error", detail: { error: "server_error", text: providerError } }));
|
|
2170
|
+
});
|
|
2094
2171
|
it("closes SDK queries on error and inactive exits but not on natural clean completion", async () => {
|
|
2095
2172
|
const naturalCloseCalls = [];
|
|
2096
2173
|
const naturalExecutor = createExecutor({
|