@rynfar/meridian 1.49.0 → 1.50.0

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 CHANGED
@@ -232,6 +232,7 @@ For large tool sets (>15 tools), non-core tools are automatically deferred via t
232
232
  - **Single tool round-trip per request** — in passthrough mode, the SDK is configured with `maxTurns=2` (or 3 for deferred tools). Multi-step agentic loops where Claude needs several consecutive tool calls require the client to re-send after each round.
233
233
  - **Blocked tools** — 13 built-in SDK tools (Read, Write, Bash, etc.) are blocked to prevent conflicts with the client's own tools. 15 additional Claude Code-only tools (CronCreate, EnterWorktree, Agent, etc.) are blocked because they require capabilities that external clients don't support.
234
234
  - **Subagent extraction** — Meridian parses the client's Task tool description to extract subagent names and build SDK AgentDefinitions. If the client's agent framework uses a non-standard format, subagent routing may not work automatically.
235
+ - **Scratchpad suppression (passthrough)** — the Claude CLI advertises a proxy-host scratchpad directory that clients can't use; OpenCode 1.18+ permission-blocks writes to it. Meridian suppresses it in passthrough mode (`CLAUDE_CODE_SESSION_KIND=bg` on the subprocess). Kill switch: `MERIDIAN_SUPPRESS_SCRATCHPAD=0`.
235
236
  - **Anthropic server tools not supported** — native server-side tools (`web_search_*`, `web_fetch_*`) are a raw Anthropic API feature (billed to an API key) that emits `server_tool_use` / `web_search_tool_result` blocks the Claude Max / Agent SDK path cannot produce. A request carrying one is rejected with a `400` explaining the fix. If a plugin needs server-side web search (e.g. [`opencode-websearch`](https://github.com/emilsvennesson/opencode-websearch)), give it its **own** provider pointed at `https://api.anthropic.com` with your `ANTHROPIC_API_KEY` — don't route that call through Meridian.
236
237
 
237
238
  ## Multi-Profile Support
@@ -83,6 +83,7 @@ function computeSummary(metrics, windowMs) {
83
83
  windowMs,
84
84
  totalRequests: 0,
85
85
  errorCount: 0,
86
+ envelopeViolationCount: 0,
86
87
  requestsPerMinute: 0,
87
88
  queueWait: emptyPhase,
88
89
  proxyOverhead: emptyPhase,
@@ -102,6 +103,7 @@ function computeSummary(metrics, windowMs) {
102
103
  };
103
104
  }
104
105
  const errorCount = metrics.filter((m) => m.error !== null).length;
106
+ const envelopeViolationCount = metrics.reduce((sum, m) => sum + (m.envelopeViolations?.length ?? 0), 0);
105
107
  const oldest = metrics[metrics.length - 1].timestamp;
106
108
  const newest = metrics[0].timestamp;
107
109
  const spanMs = Math.max(newest - oldest, 1);
@@ -148,6 +150,7 @@ function computeSummary(metrics, windowMs) {
148
150
  windowMs,
149
151
  totalRequests: metrics.length,
150
152
  errorCount,
153
+ envelopeViolationCount,
151
154
  requestsPerMinute: Math.round(requestsPerMinute * 100) / 100,
152
155
  queueWait: computePercentiles(queueWaits),
153
156
  proxyOverhead: computePercentiles(overheads),
@@ -8283,7 +8286,7 @@ function noteUserContent(tracker, content) {
8283
8286
  return;
8284
8287
  for (const block of content) {
8285
8288
  const b = block;
8286
- if (b?.type === "tool_result" && typeof b.tool_use_id === "string" && tracker.expected.has(b.tool_use_id)) {
8289
+ if (b?.type === "tool_result" && typeof b.tool_use_id === "string") {
8287
8290
  tracker.resolved.add(b.tool_use_id);
8288
8291
  }
8289
8292
  }
@@ -8301,6 +8304,45 @@ function shouldEarlyStop(tracker) {
8301
8304
  return true;
8302
8305
  }
8303
8306
 
8307
+ // src/proxy/envelopeIntegrity.ts
8308
+ function checkEmptyToolInputs(contentBlocks, tools) {
8309
+ if (!tools || tools.length === 0 || contentBlocks.length === 0)
8310
+ return [];
8311
+ const requiredByName = new Map;
8312
+ for (const t of tools) {
8313
+ const req = t.input_schema?.required;
8314
+ requiredByName.set(t.name, Array.isArray(req) && req.length > 0);
8315
+ }
8316
+ const violations = [];
8317
+ for (const b of contentBlocks) {
8318
+ if (b.type !== "tool_use" || typeof b.name !== "string")
8319
+ continue;
8320
+ if (!requiredByName.get(b.name))
8321
+ continue;
8322
+ const input = b.input;
8323
+ const empty = input == null || typeof input === "object" && Object.keys(input).length === 0;
8324
+ if (empty) {
8325
+ violations.push({
8326
+ type: "empty_tool_input",
8327
+ detail: `tool_use ${b.name} (${String(b.id ?? "?")}) delivered with empty input but schema requires arguments`
8328
+ });
8329
+ }
8330
+ }
8331
+ return violations;
8332
+ }
8333
+ function checkUndeliveredToolUses(captured, deliveredIds) {
8334
+ const violations = [];
8335
+ for (const c of captured) {
8336
+ if (!deliveredIds.has(c.id)) {
8337
+ violations.push({
8338
+ type: "undelivered_tool_use",
8339
+ detail: `captured tool_use ${c.name} (${c.id}) was never delivered to the client`
8340
+ });
8341
+ }
8342
+ }
8343
+ return violations;
8344
+ }
8345
+
8304
8346
  // src/proxy/agentDefs.ts
8305
8347
  var FALLBACK_AGENT_NAME = "general";
8306
8348
  var DEFAULT_AGENT_TYPES = {
@@ -8897,6 +8939,7 @@ function render(s, reqs, logs, quota) {
8897
8939
  html += '<div class="cards">'
8898
8940
  + card('Requests', s.totalRequests, s.requestsPerMinute.toFixed(1) + ' req/min')
8899
8941
  + card('Errors', s.errorCount, s.totalRequests > 0 ? ((s.errorCount/s.totalRequests)*100).toFixed(1) + '% error rate' : '')
8942
+ + '<div class="card"><div class="card-label">Envelope</div><div class="card-value" style="color:' + ((s.envelopeViolationCount || 0) > 0 ? 'var(--red)' : 'var(--green)') + '">' + (s.envelopeViolationCount || 0) + '</div><div class="card-detail">' + ((s.envelopeViolationCount || 0) > 0 ? 'wire-contract violations — check logs' : 'wire contract clean') + '</div></div>'
8900
8943
  + card('Median Total', ms(s.totalDuration.p50), 'p95: ' + ms(s.totalDuration.p95))
8901
8944
  + card('Median TTFB', ms(s.ttfb.p50), 'p95: ' + ms(s.ttfb.p95))
8902
8945
  + card('Proxy Overhead', ms(s.proxyOverhead.p50), 'p95: ' + ms(s.proxyOverhead.p95))
@@ -8974,6 +9017,7 @@ function render(s, reqs, logs, quota) {
8974
9017
  const respW = Math.max((r.upstreamDurationMs - (r.ttfbMs || 0)) * scale, 2);
8975
9018
 
8976
9019
  const lineageBadge = r.lineageType ? '<span style="font-size:10px;padding:1px 5px;border-radius:3px;background:' + ({continuation:'var(--green)',compaction:'var(--yellow)',undo:'var(--purple)',diverged:'var(--red)',new:'var(--muted)'}[r.lineageType] || 'var(--muted)') + ';color:var(--bg)">' + r.lineageType + '</span>' : '';
9020
+ const envBadge = (r.envelopeViolations && r.envelopeViolations.length > 0) ? ' <span style="font-size:10px;padding:1px 5px;border-radius:3px;background:var(--red);color:var(--bg)" title="' + r.envelopeViolations.join(', ') + '">envelope×' + r.envelopeViolations.length + '</span>' : '';
8977
9021
  const sessionShort = r.sdkSessionId ? r.sdkSessionId.slice(0, 8) : '—';
8978
9022
  const msgCount = r.messageCount != null ? r.messageCount : '?';
8979
9023
 
@@ -8984,7 +9028,7 @@ function render(s, reqs, logs, quota) {
8984
9028
  + '<td>' + (r.adapter || '—') + sourceBadge + '</td>'
8985
9029
  + '<td>' + (r.requestModel || r.model) + '<br><span style="font-size:10px;color:var(--muted)">' + r.model + '</span></td>'
8986
9030
  + '<td>' + r.mode + (r.hasDeferredTools ? (function() { var sessDisc = r.sessionDiscoveredCount || 0; var loaded = ((r.toolCount || 0) - (r.deferredToolCount || 0)) + sessDisc; var deferred = Math.max(0, (r.deferredToolCount || 0) - sessDisc); var newDisc = r.discoveredTools || []; return '<br><span style="font-size:10px;color:var(--purple)">loaded=' + loaded + ' deferred=' + deferred + '</span>' + (newDisc.length > 0 ? '<br><span style="font-size:10px;color:var(--green)">+' + newDisc.join(', +') + '</span>' : ''); })() : '') + '</td>'
8987
- + '<td class="mono">' + sessionShort + ' ' + lineageBadge + '<br><span style="font-size:10px;color:var(--muted)">' + msgCount + ' msgs</span></td>'
9031
+ + '<td class="mono">' + sessionShort + ' ' + lineageBadge + envBadge + '<br><span style="font-size:10px;color:var(--muted)">' + msgCount + ' msgs</span></td>'
8988
9032
  + '<td class="' + statusClass + '">' + statusText + '</td>'
8989
9033
  + '<td class="mono">' + ms(r.queueWaitMs) + '</td>'
8990
9034
  + '<td class="mono">' + ms(r.proxyOverheadMs) + '</td>'
@@ -17236,6 +17280,7 @@ function buildQueryOptions(ctx, abortController) {
17236
17280
  ...sharedMemory ? stripConfigDir(cleanEnv) : cleanEnv,
17237
17281
  ENABLE_TOOL_SEARCH: hasDeferredTools ? "true" : "false",
17238
17282
  ...passthrough ? { ENABLE_CLAUDEAI_MCP_SERVERS: "false" } : {},
17283
+ ...passthrough && process.env.MERIDIAN_SUPPRESS_SCRATCHPAD !== "0" ? { CLAUDE_CODE_SESSION_KIND: "bg" } : {},
17239
17284
  ...process.getuid?.() === 0 ? { IS_SANDBOX: "1" } : {},
17240
17285
  ...ctx.envOverrides
17241
17286
  },
@@ -18408,6 +18453,26 @@ function createProxyServer(config = {}) {
18408
18453
  const sessionDiscoveredTools = new Map;
18409
18454
  const sessionToolCache = new Map;
18410
18455
  const sessionMcpCache = new LRUMap(getMaxSessionsLimit());
18456
+ const PENDING_STORE_WAIT_MS = 3000;
18457
+ const PENDING_STORE_AUTO_RESOLVE_MS = 1e4;
18458
+ const pendingSessionStores = new Map;
18459
+ const registerPendingStore = (key) => {
18460
+ let resolveFn = () => {};
18461
+ const promise = new Promise((resolve3) => {
18462
+ const timer = setTimeout(resolve3, PENDING_STORE_AUTO_RESOLVE_MS);
18463
+ resolveFn = () => {
18464
+ clearTimeout(timer);
18465
+ resolve3();
18466
+ };
18467
+ });
18468
+ const entry = { promise, resolve: resolveFn };
18469
+ pendingSessionStores.set(key, entry);
18470
+ return () => {
18471
+ entry.resolve();
18472
+ if (pendingSessionStores.get(key) === entry)
18473
+ pendingSessionStores.delete(key);
18474
+ };
18475
+ };
18411
18476
  const pluginDir = finalConfig.pluginDir ?? join6(homedir5(), ".config", "meridian", "plugins");
18412
18477
  const pluginConfigPath = finalConfig.pluginConfigPath ?? join6(homedir5(), ".config", "meridian", "plugins.json");
18413
18478
  let loadedPlugins = [];
@@ -18594,6 +18659,17 @@ function createProxyServer(config = {}) {
18594
18659
  const lastIsToolResult = Array.isArray(lastMessage?.content) && lastMessage.content.some((b) => b?.type === "tool_result");
18595
18660
  const isClientDrivenLoop = adapterBase !== "claude-code" && !agentSessionId && lastIsToolResult;
18596
18661
  const isIndependentSession = requestSource?.startsWith("fork-") || requestSource?.startsWith("subagent-") || isClientDrivenLoop || false;
18662
+ if (!isIndependentSession && profileSessionId) {
18663
+ const pendingStore = pendingSessionStores.get(profileSessionId);
18664
+ if (pendingStore) {
18665
+ const waitStart = Date.now();
18666
+ await Promise.race([
18667
+ pendingStore.promise,
18668
+ new Promise((resolve3) => setTimeout(resolve3, PENDING_STORE_WAIT_MS))
18669
+ ]);
18670
+ claudeLog("session.pending_store_awaited", { waitedMs: Date.now() - waitStart });
18671
+ }
18672
+ }
18597
18673
  let lineageResult = isIndependentSession ? { type: "diverged" } : lookupSession(profileSessionId, body.messages || [], profileScopedCwd);
18598
18674
  if (lineageResult.type === "undo" && adapterBase === "opencode" && !agentSessionId) {
18599
18675
  lineageResult = { type: "diverged" };
@@ -18713,10 +18789,40 @@ function createProxyServer(config = {}) {
18713
18789
  const capturedToolUses = [];
18714
18790
  const capturedSignatures = new Set;
18715
18791
  const capturedToolNames = new Set;
18792
+ const droppedToolUseIds = new Set;
18716
18793
  let sawDuplicateToolUse = false;
18717
18794
  const earlyStopEnabled = passthrough && process.env.MERIDIAN_PASSTHROUGH_EARLY_STOP !== "0";
18718
18795
  const earlyStop = createEarlyStopTracker();
18719
18796
  let earlyStopFired = false;
18797
+ const envelopeViolations = [];
18798
+ const recordEnvelopeViolations = (violations) => {
18799
+ for (const v of violations) {
18800
+ envelopeViolations.push(v.type);
18801
+ claudeLog("envelope.violation", { type: v.type, detail: v.detail });
18802
+ diagnosticLog2.error(`${requestMeta.requestId} ENVELOPE VIOLATION [${v.type}] ${v.detail}`, requestMeta.requestId);
18803
+ }
18804
+ };
18805
+ const DENY_HOLD_TIMEOUT_MS = 8000;
18806
+ const pendingDenyReleases = [];
18807
+ let turnGenerating = false;
18808
+ const releaseHeldDenies = (reason) => {
18809
+ turnGenerating = false;
18810
+ if (pendingDenyReleases.length === 0)
18811
+ return;
18812
+ claudeLog("passthrough.deny_hold_released", { reason, count: pendingDenyReleases.length });
18813
+ for (const release of pendingDenyReleases.splice(0))
18814
+ release();
18815
+ };
18816
+ const holdDenyUntilTurnEnd = () => new Promise((resolve3) => {
18817
+ const timer = setTimeout(() => {
18818
+ claudeLog("passthrough.deny_hold_timeout", { afterMs: DENY_HOLD_TIMEOUT_MS });
18819
+ resolve3();
18820
+ }, DENY_HOLD_TIMEOUT_MS);
18821
+ pendingDenyReleases.push(() => {
18822
+ clearTimeout(timer);
18823
+ resolve3();
18824
+ });
18825
+ });
18720
18826
  const toolChoice = body.tool_choice;
18721
18827
  const forceSingleToolUse = !!toolChoice && (toolChoice.type === "tool" || toolChoice.disable_parallel_tool_use === true);
18722
18828
  const fileChanges = [];
@@ -18780,11 +18886,13 @@ function createProxyServer(config = {}) {
18780
18886
  }
18781
18887
  const signature = toolUseSignature(toolName, toolInput);
18782
18888
  const isExactDuplicate = capturedSignatures.has(signature);
18783
- const isSameToolRepeat = !isExactDuplicate && capturedToolNames.has(toolName);
18889
+ const isSameToolRepeat = !earlyStopEnabled && !isExactDuplicate && capturedToolNames.has(toolName);
18784
18890
  const exceedsForcedSingle = forceSingleToolUse && capturedToolUses.length >= 1;
18785
18891
  if (isExactDuplicate) {
18892
+ droppedToolUseIds.add(input.tool_use_id);
18786
18893
  claudeLog("passthrough.duplicate_tool_use_dropped", { name: toolName });
18787
18894
  } else if (isSameToolRepeat || exceedsForcedSingle) {
18895
+ droppedToolUseIds.add(input.tool_use_id);
18788
18896
  sawDuplicateToolUse = true;
18789
18897
  claudeLog("passthrough.extra_tool_use_dropped", {
18790
18898
  name: toolName,
@@ -18800,6 +18908,9 @@ function createProxyServer(config = {}) {
18800
18908
  input: toolInput
18801
18909
  });
18802
18910
  }
18911
+ if (stream2 && earlyStopEnabled && turnGenerating && !requestAbort.controller.signal.aborted) {
18912
+ await holdDenyUntilTurnEnd();
18913
+ }
18803
18914
  if (isExactDuplicate) {
18804
18915
  return {
18805
18916
  decision: "block",
@@ -19214,6 +19325,14 @@ Subprocess stderr: ${stderrOutput}`;
19214
19325
  });
19215
19326
  }
19216
19327
  if (passthrough && capturedToolUses.length > 0) {
19328
+ if (droppedToolUseIds.size > 0) {
19329
+ for (let i = contentBlocks.length - 1;i >= 0; i--) {
19330
+ const b = contentBlocks[i];
19331
+ if (b.type === "tool_use" && droppedToolUseIds.has(b.id)) {
19332
+ contentBlocks.splice(i, 1);
19333
+ }
19334
+ }
19335
+ }
19217
19336
  const capturedById = new Map(capturedToolUses.map((tu) => [tu.id, tu]));
19218
19337
  for (const block of contentBlocks) {
19219
19338
  if (block.type === "tool_use" && capturedById.has(block.id)) {
@@ -19299,8 +19418,16 @@ Subprocess stderr: ${stderrOutput}`;
19299
19418
  outputTokens: lastUsage?.output_tokens,
19300
19419
  cacheReadInputTokens: lastUsage?.cache_read_input_tokens,
19301
19420
  cacheCreationInputTokens: lastUsage?.cache_creation_input_tokens,
19302
- cacheHitRate: computeCacheHitRate(lastUsage)
19421
+ cacheHitRate: computeCacheHitRate(lastUsage),
19422
+ ...envelopeViolations.length > 0 ? { envelopeViolations: [...envelopeViolations] } : {}
19303
19423
  });
19424
+ if (passthrough) {
19425
+ const deliveredIds = new Set(contentBlocks.filter((b) => b.type === "tool_use" && typeof b.id === "string").map((b) => b.id));
19426
+ recordEnvelopeViolations([
19427
+ ...checkEmptyToolInputs(contentBlocks, requestTools),
19428
+ ...checkUndeliveredToolUses(capturedToolUses, deliveredIds)
19429
+ ]);
19430
+ }
19304
19431
  if (currentSessionId && !isIndependentSession && !sawDuplicateToolUse) {
19305
19432
  storeSession(profileSessionId, body.messages || [], currentSessionId, profileScopedCwd, sdkUuidMap, lastUsage);
19306
19433
  }
@@ -19367,6 +19494,23 @@ Subprocess stderr: ${stderrOutput}`;
19367
19494
  let structuredOutput;
19368
19495
  const streamedToolUseIds = new Set;
19369
19496
  const openClientBlocks = new Set;
19497
+ const resolvePendingStore = passthrough && earlyStopEnabled && !isIndependentSession && profileSessionId ? registerPendingStore(profileSessionId) : () => {};
19498
+ const flushOpenClientBlocks = (source) => {
19499
+ if (openClientBlocks.size === 0)
19500
+ return;
19501
+ recordEnvelopeViolations([...openClientBlocks].map((idx) => ({
19502
+ type: "dangling_block",
19503
+ detail: `content block ${idx} still open at ${source} close`
19504
+ })));
19505
+ claudeLog("stream.dangling_blocks_closed", { source, count: openClientBlocks.size });
19506
+ for (const idx of openClientBlocks) {
19507
+ safeEnqueue(encoder.encode(`event: content_block_stop
19508
+ data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
19509
+
19510
+ `), `${source}_close_dangling`);
19511
+ }
19512
+ openClientBlocks.clear();
19513
+ };
19370
19514
  try {
19371
19515
  let currentSessionId;
19372
19516
  const MAX_RATE_LIMIT_RETRIES = 2;
@@ -19647,6 +19791,7 @@ Subprocess stderr: ${stderrOutput}`;
19647
19791
  if (shouldEarlyStop(earlyStop) && streamedToolUseIds.size > 0) {
19648
19792
  earlyStopFired = true;
19649
19793
  claudeLog("passthrough.early_stop", { mode: "stream", captured: capturedToolUses.length, drained: awaitingEarlyStopDrain });
19794
+ flushOpenClientBlocks("early_stop");
19650
19795
  safeEnqueue(encoder.encode(`event: message_delta
19651
19796
  data: ${JSON.stringify({ type: "message_delta", delta: { stop_reason: "tool_use", stop_sequence: null }, usage: { output_tokens: lastUsage?.output_tokens ?? 0 } })}
19652
19797
 
@@ -19689,6 +19834,12 @@ data: ${JSON.stringify({ type: "message_stop" })}
19689
19834
  const event = message.event;
19690
19835
  const eventType = event.type;
19691
19836
  const eventIndex = event.index;
19837
+ if (eventType === "message_delta" || eventType === "message_stop" || eventType === "message_start" && messageStartEmitted) {
19838
+ releaseHeldDenies(eventType);
19839
+ }
19840
+ if (eventType === "message_start") {
19841
+ turnGenerating = true;
19842
+ }
19692
19843
  if (outputFormat) {
19693
19844
  if (eventType === "message_start") {
19694
19845
  const startUsage = event.message?.usage;
@@ -19709,6 +19860,7 @@ data: ${JSON.stringify({ type: "message_stop" })}
19709
19860
  lastUsage = { ...lastUsage, ...startUsage };
19710
19861
  if (messageStartEmitted) {
19711
19862
  if (passthrough && streamedToolUseIds.size > 0) {
19863
+ flushOpenClientBlocks("turn2_suppression");
19712
19864
  safeEnqueue(encoder.encode(`event: message_delta
19713
19865
  data: ${JSON.stringify({ type: "message_delta", delta: { stop_reason: "tool_use", stop_sequence: null }, usage: { output_tokens: lastUsage?.output_tokens ?? 0 } })}
19714
19866
 
@@ -19835,6 +19987,7 @@ data: ${JSON.stringify(event)}
19835
19987
  openClientBlocks.delete(idx);
19836
19988
  }
19837
19989
  if (passthrough && eventType === "message_delta" && event.delta?.stop_reason === "tool_use" && streamedToolUseIds.size > 0) {
19990
+ flushOpenClientBlocks("drain_close");
19838
19991
  safeEnqueue(encoder.encode(`event: message_stop
19839
19992
  data: ${JSON.stringify({ type: "message_stop" })}
19840
19993
 
@@ -19857,6 +20010,7 @@ data: ${JSON.stringify({ type: "message_stop" })}
19857
20010
  }
19858
20011
  } finally {
19859
20012
  clearInterval(heartbeat);
20013
+ releaseHeldDenies("stream_loop_exit");
19860
20014
  }
19861
20015
  if (outputFormat) {
19862
20016
  if (!hasStructuredOutput) {
@@ -19912,6 +20066,9 @@ data: ${JSON.stringify({
19912
20066
  eventsForwarded += 5;
19913
20067
  textEventsForwarded += 1;
19914
20068
  }
20069
+ if (passthrough) {
20070
+ recordEnvelopeViolations(checkUndeliveredToolUses(capturedToolUses, streamedToolUseIds));
20071
+ }
19915
20072
  claudeLog("upstream.completed", {
19916
20073
  mode: "stream",
19917
20074
  model,
@@ -19935,12 +20092,14 @@ data: ${JSON.stringify({
19935
20092
  if (currentSessionId && !isIndependentSession && !sawDuplicateToolUse) {
19936
20093
  storeSession(profileSessionId, body.messages || [], currentSessionId, profileScopedCwd, sdkUuidMap, lastUsage);
19937
20094
  }
20095
+ resolvePendingStore();
19938
20096
  if (!streamClosed) {
19939
20097
  const unseenToolUses = capturedToolUses.filter((tu) => !streamedToolUseIds.has(tu.id));
19940
20098
  if (passthrough && unseenToolUses.length > 0 && messageStartEmitted) {
19941
20099
  for (let i = 0;i < unseenToolUses.length; i++) {
19942
20100
  const tu = unseenToolUses[i];
19943
20101
  const blockIndex = eventsForwarded + i;
20102
+ streamedToolUseIds.add(tu.id);
19944
20103
  safeEnqueue(encoder.encode(`event: content_block_start
19945
20104
  data: ${JSON.stringify({
19946
20105
  type: "content_block_start",
@@ -20070,7 +20229,8 @@ data: {"type":"message_stop"}
20070
20229
  outputTokens: lastUsage?.output_tokens,
20071
20230
  cacheReadInputTokens: lastUsage?.cache_read_input_tokens,
20072
20231
  cacheCreationInputTokens: lastUsage?.cache_creation_input_tokens,
20073
- cacheHitRate: computeCacheHitRate(lastUsage)
20232
+ cacheHitRate: computeCacheHitRate(lastUsage),
20233
+ ...envelopeViolations.length > 0 ? { envelopeViolations: [...envelopeViolations] } : {}
20074
20234
  });
20075
20235
  if (textEventsForwarded === 0) {
20076
20236
  claudeLog("response.empty_stream", {
@@ -20093,6 +20253,7 @@ data: {"type":"message_stop"}
20093
20253
  });
20094
20254
  return;
20095
20255
  }
20256
+ resolvePendingStore();
20096
20257
  const stderrOutput = stderrLines.join(`
20097
20258
  `).trim();
20098
20259
  if (stderrOutput && error instanceof Error && !error.message.includes(stderrOutput)) {
@@ -20125,17 +20286,12 @@ Subprocess stderr: ${stderrOutput}`;
20125
20286
  hasDeferredTools,
20126
20287
  sdkSessionId: resumeSessionId
20127
20288
  })} captured=${capturedToolUses.length}`, requestMeta.requestId);
20128
- for (const idx of openClientBlocks) {
20129
- safeEnqueue(encoder.encode(`event: content_block_stop
20130
- data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
20131
-
20132
- `), "recover_close_dangling_block");
20133
- }
20134
- openClientBlocks.clear();
20289
+ flushOpenClientBlocks("recovery");
20135
20290
  const unseenToolUses = capturedToolUses.filter((tu) => !streamedToolUseIds.has(tu.id));
20136
20291
  for (let i = 0;i < unseenToolUses.length; i++) {
20137
20292
  const tu = unseenToolUses[i];
20138
20293
  const blockIndex = eventsForwarded + i;
20294
+ streamedToolUseIds.add(tu.id);
20139
20295
  safeEnqueue(encoder.encode(`event: content_block_start
20140
20296
  data: ${JSON.stringify({
20141
20297
  type: "content_block_start",
@@ -20172,6 +20328,7 @@ data: ${JSON.stringify({
20172
20328
  data: {"type":"message_stop"}
20173
20329
 
20174
20330
  `), "recover_message_stop");
20331
+ recordEnvelopeViolations(checkUndeliveredToolUses(capturedToolUses, streamedToolUseIds));
20175
20332
  const recoverTotalMs = Date.now() - requestStartAt;
20176
20333
  const recoverQueueWaitMs = requestMeta.queueStartedAt - requestMeta.queueEnteredAt;
20177
20334
  telemetryStore2.record({
@@ -20198,7 +20355,8 @@ data: {"type":"message_stop"}
20198
20355
  totalDurationMs: recoverTotalMs,
20199
20356
  contentBlocks: eventsForwarded + unseenToolUses.length,
20200
20357
  textEvents: textEventsForwarded,
20201
- error: null
20358
+ error: null,
20359
+ ...envelopeViolations.length > 0 ? { envelopeViolations: [...envelopeViolations] } : {}
20202
20360
  });
20203
20361
  if (!streamClosed) {
20204
20362
  try {
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startProxyServer
4
- } from "./cli-red47yv3.js";
4
+ } from "./cli-yw8cx02m.js";
5
5
  import"./cli-f0yqy2d2.js";
6
6
  import"./cli-sry5aqdj.js";
7
7
  import"./cli-4rqtm83g.js";
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Envelope integrity checks.
3
+ *
4
+ * Every #552-family bug (red reads, beheaded parallel calls, lost tool
5
+ * inputs) manifested as a wire-contract violation that was visible at
6
+ * response time — but only to the CLIENT, so we learned about each one from
7
+ * user transcripts weeks later. These checks make the proxy assert its own
8
+ * output contract on every response:
9
+ *
10
+ * - dangling_block: a content block left open at stream close
11
+ * (recorded at the flush site in server.ts)
12
+ * - undelivered_tool_use: a hook-captured call that never reached the client
13
+ * - empty_tool_input: a delivered tool_use with no arguments where the
14
+ * tool's schema requires them (the client-visible
15
+ * shape of a beheaded call)
16
+ *
17
+ * Violations are logged (envelope.violation) and counted on /telemetry so
18
+ * the next regression in this family fires a tripwire in OUR logs instead
19
+ * of waiting for a user report.
20
+ *
21
+ * Pure module — no I/O, no imports from server.ts or session/.
22
+ */
23
+ export interface EnvelopeViolation {
24
+ type: "dangling_block" | "undelivered_tool_use" | "empty_tool_input";
25
+ detail: string;
26
+ }
27
+ interface ToolSchema {
28
+ name: string;
29
+ input_schema?: {
30
+ required?: unknown;
31
+ [key: string]: unknown;
32
+ };
33
+ }
34
+ /**
35
+ * Flag delivered tool_use blocks whose input is empty/missing even though
36
+ * the tool's schema declares required fields. A legit no-arg tool (empty
37
+ * `required`) never flags; unknown tools are skipped (nothing to judge by).
38
+ */
39
+ export declare function checkEmptyToolInputs(contentBlocks: Array<Record<string, unknown>>, tools: ToolSchema[] | undefined): EnvelopeViolation[];
40
+ /**
41
+ * Flag hook-captured tool calls that never reached the client — the
42
+ * proxy promised the model "forwarded to the client" for these, so a
43
+ * missing delivery diverges the model's view from reality (#552 family).
44
+ */
45
+ export declare function checkUndeliveredToolUses(captured: Array<{
46
+ id: string;
47
+ name: string;
48
+ }>, deliveredIds: ReadonlySet<string>): EnvelopeViolation[];
49
+ export {};
50
+ //# sourceMappingURL=envelopeIntegrity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelopeIntegrity.d.ts","sourceRoot":"","sources":["../../src/proxy/envelopeIntegrity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,kBAAkB,CAAA;IACpE,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CAC9D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC7C,KAAK,EAAE,UAAU,EAAE,GAAG,SAAS,GAC9B,iBAAiB,EAAE,CAqBrB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7C,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAChC,iBAAiB,EAAE,CAWrB"}
@@ -42,8 +42,14 @@ export declare function isClientForwardedToolUse(block: unknown): boolean;
42
42
  */
43
43
  export declare function noteAssistantContent(tracker: EarlyStopTracker, content: unknown): void;
44
44
  /**
45
- * Record persisted tool_results from a user message's content. Only results
46
- * matching an expected id count — unrelated results are ignored.
45
+ * Record persisted tool_results from a user message's content.
46
+ *
47
+ * Records EVERY tool_result id, not just already-expected ones: the CLI
48
+ * dispatches hooks per-block while later blocks are still streaming, and it
49
+ * emits per-block assistant messages — so a deny's tool_result can reach the
50
+ * iterator BEFORE the assistant message that arms its id in `expected`
51
+ * (observed live, MERIDIAN_TRACE_STREAM). Unmatched ids are harmless:
52
+ * shouldEarlyStop only ever checks ids that are in `expected`.
47
53
  */
48
54
  export declare function noteUserContent(tracker: EarlyStopTracker, content: unknown): void;
49
55
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"passthroughEarlyStop.d.ts","sourceRoot":"","sources":["../../src/proxy/passthroughEarlyStop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAUH,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACrB,6EAA6E;IAC7E,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACrB,0EAA0E;IAC1E,KAAK,EAAE,OAAO,CAAA;CACf;AAED,wBAAgB,sBAAsB,IAAI,gBAAgB,CAEzD;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQhE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAOtF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAQjF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAQlE"}
1
+ {"version":3,"file":"passthroughEarlyStop.d.ts","sourceRoot":"","sources":["../../src/proxy/passthroughEarlyStop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAUH,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACrB,6EAA6E;IAC7E,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACrB,0EAA0E;IAC1E,KAAK,EAAE,OAAO,CAAA;CACf;AAED,wBAAgB,sBAAsB,IAAI,gBAAgB,CAEzD;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQhE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAOtF;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAQjF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAQlE"}
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/proxy/query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/proxy/query.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAsCnG,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EAEpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAA+B,iBAAiB,EAAE,mBAAmB,EAAsC,MAAM,iBAAiB,CAAA;AAGzI,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AA+Q7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CA6rGhF;AAWD,wBAAgB,gCAAgC,IAAI,IAAI,CAavD;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmGhG"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAuCnG,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EAEpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAA+B,iBAAiB,EAAE,mBAAmB,EAAsC,MAAM,iBAAiB,CAAA;AAGzI,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AA+Q7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CAm4GhF;AAWD,wBAAgB,gCAAgC,IAAI,IAAI,CAavD;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmGhG"}
package/dist/server.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  runObserveHook,
12
12
  runTransformHook,
13
13
  startProxyServer
14
- } from "./cli-red47yv3.js";
14
+ } from "./cli-yw8cx02m.js";
15
15
  import"./cli-f0yqy2d2.js";
16
16
  import"./cli-sry5aqdj.js";
17
17
  import"./cli-4rqtm83g.js";
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/telemetry/dashboard.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,eAAO,MAAM,aAAa,QAsdlB,CAAA"}
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/telemetry/dashboard.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,eAAO,MAAM,aAAa,QAwdlB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"percentiles.d.ts","sourceRoot":"","sources":["../../src/telemetry/percentiles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE3E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,CAchE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAuG3F"}
1
+ {"version":3,"file":"percentiles.d.ts","sourceRoot":"","sources":["../../src/telemetry/percentiles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE3E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,CAchE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CA0G3F"}
@@ -26,6 +26,10 @@ export interface RequestMetric {
26
26
  requestModel?: string;
27
27
  /** Streaming or non-streaming */
28
28
  mode: "stream" | "non-stream";
29
+ /** Envelope-integrity violations detected on this response (dangling_block,
30
+ * undelivered_tool_use, empty_tool_input). Absent when the envelope was
31
+ * clean — the overwhelmingly common case. See proxy/envelopeIntegrity.ts. */
32
+ envelopeViolations?: string[];
29
33
  /** Whether the request used session resume */
30
34
  isResume: boolean;
31
35
  /** Whether passthrough mode was active */
@@ -98,6 +102,9 @@ export interface TelemetrySummary {
98
102
  totalRequests: number;
99
103
  /** Requests that returned an error */
100
104
  errorCount: number;
105
+ /** Total envelope-integrity violations across the window (dangling blocks,
106
+ * undelivered tool calls, empty required inputs). 0 = wire contract clean. */
107
+ envelopeViolationCount: number;
101
108
  /** Requests per minute */
102
109
  requestsPerMinute: number;
103
110
  /** Timing breakdowns by phase */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/telemetry/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/telemetry/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rynfar/meridian",
3
- "version": "1.49.0",
3
+ "version": "1.50.0",
4
4
  "description": "Local Anthropic API powered by your Claude Max subscription. One subscription, every agent.",
5
5
  "type": "module",
6
6
  "main": "./dist/server.js",