github-router 0.3.319 → 0.3.320

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.
@@ -2291,7 +2291,7 @@ function collectToolFieldKeys(body) {
2291
2291
  //#endregion
2292
2292
  //#region package.json
2293
2293
  var name = "github-router";
2294
- var version = "0.3.319";
2294
+ var version = "0.3.320";
2295
2295
  //#endregion
2296
2296
  //#region src/lib/approval.ts
2297
2297
  const awaitApproval = async () => {
@@ -4200,6 +4200,72 @@ function parseOutputConfigEffort(body, model) {
4200
4200
  return clampEffort(known ? effort : UNKNOWN_EFFORT_ANCHOR, supported);
4201
4201
  }
4202
4202
  /**
4203
+ * True for a `user` message carrying ONLY image parts.
4204
+ *
4205
+ * These are the synthetic follow-ups `anthropicMessageToNeutral` emits for
4206
+ * images found inside `tool_result` blocks (a `function_call_output` / chat
4207
+ * `tool` item cannot carry pixels). A genuine image-only user turn also
4208
+ * matches, but such a turn never appears mid-tool-run from Claude Code — and
4209
+ * even if it did, deferring it past the tool block is still the valid shape.
4210
+ */
4211
+ function isImageOnlyUserMessage(m) {
4212
+ return m.role === "user" && Array.isArray(m.content) && m.content.length > 0 && m.content.every((c) => c.type === "image");
4213
+ }
4214
+ /**
4215
+ * Hoist `tool_result`-extracted images to the END of each contiguous run of
4216
+ * tool results.
4217
+ *
4218
+ * A tool-output wire item cannot carry an image on any endpoint, so images
4219
+ * have to ride in a separate user message. Fanning each `toolResult` out to
4220
+ * `[tool, user]` independently is WRONG for parallel tool calls: it yields
4221
+ * `tool A, user A, tool B, user B`, and providers require the tool messages
4222
+ * answering one assistant turn to be CONTIGUOUS — the interjected user message
4223
+ * orphans the following tool message and the request is rejected outright
4224
+ * (verified live on `gemini-3.8-flash` `/chat/completions`: interleaved →
4225
+ * `400 invalid_request_body`, batched → `200`; see also
4226
+ * `github/copilot-sdk#1922`). Mirrors `translateMessages` in
4227
+ * `src/lib/worker-agent/stream-fn.ts`, which implements the same invariant
4228
+ * for the worker path.
4229
+ *
4230
+ * So images accumulate across the run and flush once, after the last tool
4231
+ * message of that run: `tool A, tool B, user(imgA, imgB)`. Any other message
4232
+ * ends the run and the pending images flush before it. Runs at parse time
4233
+ * over the FULL neutral sequence (a run routinely spans several Anthropic
4234
+ * messages — one `tool_result` per message), never written back to state.
4235
+ * Single-image and image-free inputs are returned unchanged in shape.
4236
+ */
4237
+ function groupToolResultImages(messages) {
4238
+ const out = [];
4239
+ let pending = [];
4240
+ let inToolRun = false;
4241
+ const flushImages = () => {
4242
+ if (pending.length === 0) return;
4243
+ out.push({
4244
+ role: "user",
4245
+ content: pending
4246
+ });
4247
+ pending = [];
4248
+ };
4249
+ for (const m of messages) {
4250
+ if (m.role === "toolResult") {
4251
+ out.push(m);
4252
+ inToolRun = true;
4253
+ continue;
4254
+ }
4255
+ if (inToolRun && isImageOnlyUserMessage(m)) {
4256
+ pending.push(...m.content);
4257
+ continue;
4258
+ }
4259
+ if (inToolRun) {
4260
+ flushImages();
4261
+ inToolRun = false;
4262
+ }
4263
+ out.push(m);
4264
+ }
4265
+ flushImages();
4266
+ return out;
4267
+ }
4268
+ /**
4203
4269
  * Parse an already-JSON-parsed Anthropic Messages body into the neutral shape.
4204
4270
  * `resolvedModel` is the catalog id the request will run on; `model` its
4205
4271
  * catalog entry (for the reasoning-effort allowlist).
@@ -4218,7 +4284,7 @@ function parseAnthropicRequest(body, resolvedModel, model) {
4218
4284
  model: resolvedModel,
4219
4285
  instructions: system.stable,
4220
4286
  dynamicInstructions: system.dynamic,
4221
- messages,
4287
+ messages: groupToolResultImages(messages),
4222
4288
  tools,
4223
4289
  toolChoice: parseToolChoice(body.tool_choice),
4224
4290
  parallelToolCalls: parseDisableParallelToolUse(body.tool_choice),
@@ -7786,4 +7852,4 @@ function getCodexEnvVars(serverUrl) {
7786
7852
  //#endregion
7787
7853
  export { validateCheapProfilePrerequisites as A, formatCheap1mPrerequisiteFailure as C, profileDescriptor as D, formatFastPrerequisiteFailure as E, checkClaudeVersion as F, updateClaude as I, validateFastProfilePrerequisites as M, validateMaxProfileLaunch as N, resolveLaunchProfile as O, runSelfUpdate as P, LUNA_SCOUT_ALIAS_ID as S, formatCheapestPrerequisiteFailure as T, CHEAP_EXPLORE_ALIAS_ID as _, sharedServerArgs as a, CHEAP_PLAN_ALIAS_ID as b, stopKeepAwake as c, enableFileLogging as d, CHEAPEST_EXPLORE_ALIAS_ID as f, CHEAPEST_REVIEWER_ALIAS_ID as g, CHEAPEST_PLAN_ALIAS_ID as h, setupAndServe as i, validateCheapestProfilePrerequisites as j, validateCheap1mProfilePrerequisites as k, injectModelPickerSettingsFile as l, CHEAPEST_IMPLEMENTER_ALIAS_ID as m, getCodexEnvVars as n, LAUNCH_SECRET_HEADER as o, CHEAPEST_GENERAL_PURPOSE_ALIAS_ID as p, parseSharedArgs as r, startKeepAwake as s, getClaudeCodeEnvVars as t, listModelsForEndpoint as u, CHEAP_GENERAL_PURPOSE_ALIAS_ID as v, formatCheapPrerequisiteFailure as w, CHEAP_REVIEWER_ALIAS_ID as x, CHEAP_IMPLEMENTER_ALIAS_ID as y };
7788
7854
 
7789
- //# sourceMappingURL=server-setup-DPay_uYp.js.map
7855
+ //# sourceMappingURL=server-setup-ByyVi5SS.js.map