maka-agent 0.2.0-dev.52.20260926 → 0.2.0-dev.53.20260927

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.
Files changed (71) hide show
  1. package/dist/activation-command.js +11 -3
  2. package/dist/pi-tui-mcp-status.js +73 -5
  3. package/dist/pi-tui-runner.js +1 -1
  4. package/dist/runtime-host-run-command.js +39 -6
  5. package/dist/runtime-host-run-mcp.js +161 -0
  6. package/dist/runtime-host-session-driver.js +22 -2
  7. package/dist/tui-copy-catalog.js +6 -0
  8. package/dist/tui-mcp-control.js +11 -2
  9. package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
  10. package/node_modules/@maka/core/dist/attachments.js +7 -0
  11. package/node_modules/@maka/core/dist/events.js +11 -0
  12. package/node_modules/@maka/core/dist/provider-registry.js +11 -2
  13. package/node_modules/@maka/core/dist/turn-origin.js +6 -0
  14. package/node_modules/@maka/runtime/dist/ai-sdk-compaction.js +1 -5
  15. package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +80 -24
  16. package/node_modules/@maka/runtime/dist/bots/proxied-fetch.js +5 -4
  17. package/node_modules/@maka/runtime/dist/computer-use-tools.js +136 -100
  18. package/node_modules/@maka/runtime/dist/context-budget-helpers.js +4 -0
  19. package/node_modules/@maka/runtime/dist/conversation-copy.js +51 -205
  20. package/node_modules/@maka/runtime/dist/edit-replace.js +7 -7
  21. package/node_modules/@maka/runtime/dist/filesystem-executor.js +4 -20
  22. package/node_modules/@maka/runtime/dist/filesystem-worker/operations.js +17 -28
  23. package/node_modules/@maka/runtime/dist/format-json.js +39 -0
  24. package/node_modules/@maka/runtime/dist/history-compact-checkpoint.js +1 -6
  25. package/node_modules/@maka/runtime/dist/image-file.js +22 -14
  26. package/node_modules/@maka/runtime/dist/model-adapter.js +18 -2
  27. package/node_modules/@maka/runtime/dist/model-history.js +201 -3
  28. package/node_modules/@maka/runtime/dist/network/abortable-connector.js +55 -0
  29. package/node_modules/@maka/runtime/dist/network/proxy-dispatcher.js +72 -37
  30. package/node_modules/@maka/runtime/dist/network/proxy-test.js +1 -1
  31. package/node_modules/@maka/runtime/dist/network/scoped-fetch-transport.js +7 -2
  32. package/node_modules/@maka/runtime/dist/openai-codex-history-compactor.js +1 -3
  33. package/node_modules/@maka/runtime/dist/provider-error-classification.js +36 -8
  34. package/node_modules/@maka/runtime/dist/recovery-resolver.js +1 -91
  35. package/node_modules/@maka/runtime/dist/runtime-kernel.js +44 -0
  36. package/node_modules/@maka/runtime/dist/session-manager.js +54 -58
  37. package/node_modules/@maka/runtime/dist/subscription-model-fetch.js +84 -2
  38. package/node_modules/@maka/runtime/dist/workers/filesystem-worker.js +63 -51
  39. package/node_modules/@maka/runtime/dist/workspace-executor.js +5 -6
  40. package/node_modules/@maka/runtime-host/dist/adapter/session-projector.js +27 -6
  41. package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +4 -1
  42. package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +9 -9
  43. package/node_modules/@maka/runtime-host/dist/client/session-catalog-summary.js +9 -1
  44. package/node_modules/@maka/runtime-host/dist/protocol/index.js +12 -1
  45. package/node_modules/@maka/runtime-host/dist/protocol/session-catalog.js +28 -6
  46. package/node_modules/@maka/runtime-host/dist/protocol/turn.js +12 -2
  47. package/node_modules/@maka/runtime-host/dist/server/client-capability-coordinator.js +10 -7
  48. package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +10 -2
  49. package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +2 -0
  50. package/node_modules/@maka/runtime-host/dist/server/interactive-turn-coordinator.js +4 -1
  51. package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +4 -2
  52. package/node_modules/@maka/runtime-host/dist/server/operation-dispatcher.js +4 -0
  53. package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +6 -5
  54. package/node_modules/@maka/runtime-host/dist/server/safe-boundary-resume-policy.js +27 -0
  55. package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +5 -3
  56. package/node_modules/@maka/runtime-host/dist/server/session-continuity-coordinator.js +7 -2
  57. package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +11 -141
  58. package/node_modules/@maka/runtime-host/dist/server/session-revision-graph-references.js +46 -75
  59. package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +18 -2
  60. package/node_modules/@maka/runtime-host/dist/server/workhub-result-coordinator.js +33 -3
  61. package/node_modules/@maka/runtime-host/dist/transport/framed-byte-stream-transport.js +39 -5
  62. package/node_modules/@maka/storage/dist/agent-run-store-contract.js +7 -1
  63. package/node_modules/@maka/storage/dist/artifact-store.js +1 -5
  64. package/node_modules/@maka/storage/dist/artifact-stores.js +0 -3
  65. package/node_modules/@maka/storage/dist/atomic-file-write.js +1 -0
  66. package/node_modules/@maka/storage/dist/claude-code-session-adapter.js +107 -57
  67. package/node_modules/@maka/storage/dist/codex-session-adapter.js +227 -19
  68. package/node_modules/@maka/storage/dist/external-session-importer.js +1 -1
  69. package/node_modules/@maka/storage/dist/mcp-config-store.js +22 -3
  70. package/node_modules/@maka/storage/dist/settings-store.js +281 -13
  71. package/package.json +1 -1
@@ -56,6 +56,13 @@ export function isDirectoryReference(value) {
56
56
  value.path.length <= 4096 &&
57
57
  isCanonicalAbsolutePath(value.path));
58
58
  }
59
+ /**
60
+ * Cap for {@link QuoteRef.comment}. A note about a quote carries intent, not
61
+ * content: long prose belongs in the message text, which has its own limit.
62
+ * The single authority for the IPC normalizer, the Runtime Host protocol and
63
+ * the composer's staging cap.
64
+ */
65
+ export const QUOTE_COMMENT_MAX_LENGTH = 1000;
59
66
  const MESSAGE_CONTENT_SHAPE = defineObjectShape()(['text'], ['displayText', 'attachments', 'directoryReferences', 'quotes', 'inlineReferences']);
60
67
  /**
61
68
  * A Turn message is meaningful when at least one of its four content carriers
@@ -81,6 +88,7 @@ export function hasMeaningfulMessageContent(content) {
81
88
  const ATTACHMENT_REF_SHAPE = defineObjectShape()(['kind', 'name', 'mimeType', 'bytes', 'ref'], []);
82
89
  const QUOTE_REF_SHAPE = defineObjectShape()(['text'], [
83
90
  'label',
91
+ 'comment',
84
92
  'sourceTurnId',
85
93
  'sourceSessionId',
86
94
  'sourceSessionName',
@@ -121,6 +129,7 @@ export function normalizeMessageContent(content) {
121
129
  quotes: content.quotes.map((quote) => ({
122
130
  text: quote.text,
123
131
  ...(quote.label !== undefined ? { label: quote.label } : {}),
132
+ ...(quote.comment !== undefined ? { comment: quote.comment } : {}),
124
133
  ...(quote.sourceTurnId !== undefined ? { sourceTurnId: quote.sourceTurnId } : {}),
125
134
  ...(quote.sourceSessionId !== undefined
126
135
  ? { sourceSessionId: quote.sourceSessionId }
@@ -244,6 +253,7 @@ export function isQuoteRef(value) {
244
253
  hasExactShape(record, QUOTE_REF_SHAPE) &&
245
254
  typeof record.text === 'string' &&
246
255
  (record.label === undefined || typeof record.label === 'string') &&
256
+ (record.comment === undefined || typeof record.comment === 'string') &&
247
257
  (record.sourceTurnId === undefined || typeof record.sourceTurnId === 'string') &&
248
258
  (!hasSourceMetadata ||
249
259
  (typeof record.sourceSessionId === 'string' &&
@@ -386,6 +396,7 @@ function inlineReferencesEqual(left, right) {
386
396
  function quoteRefsEqual(left, right) {
387
397
  return (left.text === right.text &&
388
398
  left.label === right.label &&
399
+ left.comment === right.comment &&
389
400
  left.sourceTurnId === right.sourceTurnId &&
390
401
  left.sourceSessionId === right.sourceSessionId &&
391
402
  left.sourceSessionName === right.sourceSessionName &&
@@ -671,7 +671,7 @@ const providerRegistry = {
671
671
  label: 'MiniMax',
672
672
  baseUrl: 'https://api.minimax.io/anthropic/v1',
673
673
  authKind: 'api_key',
674
- fallbackModels: ['MiniMax-M3'],
674
+ fallbackModels: ['MiniMax-M3', 'MiniMax-M2.7'],
675
675
  status: 'ready',
676
676
  runtimeAdapter: { kind: 'anthropic', auth: 'bearer', normalizeBaseUrl: false },
677
677
  modelDiscovery: { kind: 'protocol' },
@@ -684,7 +684,7 @@ const providerRegistry = {
684
684
  label: 'MiniMax 中国站',
685
685
  baseUrl: 'https://api.minimaxi.com/anthropic/v1',
686
686
  authKind: 'api_key',
687
- fallbackModels: ['MiniMax-M3'],
687
+ fallbackModels: ['MiniMax-M3', 'MiniMax-M2.7'],
688
688
  status: 'ready',
689
689
  runtimeAdapter: { kind: 'anthropic', auth: 'bearer', normalizeBaseUrl: false },
690
690
  modelDiscovery: { kind: 'protocol' },
@@ -1438,5 +1438,14 @@ export function providerMenuLabel(providerType) {
1438
1438
  export function isRetiredProvider(providerType) {
1439
1439
  return providerDefaultsOf(providerType)?.retired === true;
1440
1440
  }
1441
+ /**
1442
+ * Whether a request on this provider may carry an output-token limit. The
1443
+ * ChatGPT Codex backend answers `max_output_tokens` with HTTP 400
1444
+ * "Unsupported parameter", so no limit can be honoured there: Runtime must not
1445
+ * send one, and settings must not offer one.
1446
+ */
1447
+ export function providerAcceptsOutputTokenLimit(providerType) {
1448
+ return providerDefaultsOf(providerType)?.runtimeAdapter.kind !== 'openai-codex';
1449
+ }
1441
1450
  export const CATALOG_PROVIDER_TYPES = providerTypesByOrder('catalogOrder');
1442
1451
  export const RECOMMENDED_PROVIDER_TYPES = providerTypesByOrder('recommendedOrder');
@@ -18,6 +18,7 @@
18
18
  */
19
19
  import { defineObjectShape, hasExactShape, isRecord } from './record-schema.js';
20
20
  const SCHEDULED_TASK_ORIGIN_SHAPE = defineObjectShape()(['kind', 'scheduledTaskId'], []);
21
+ const CLOUD_ACTIVATION_ORIGIN_SHAPE = defineObjectShape()(['kind', 'activationId'], []);
21
22
  const LEGACY_AUTOMATION_ORIGIN_SHAPE = defineObjectShape()(['kind', 'automationId'], []);
22
23
  const GOAL_ORIGIN_SHAPE = defineObjectShape()(['kind', 'goalId'], []);
23
24
  const AGENT_GRAPH_ORIGIN_SHAPE = defineObjectShape()(['kind', 'graphId', 'wakeId', 'attemptId'], []);
@@ -44,6 +45,11 @@ export function decodeTurnOrigin(value) {
44
45
  typeof value.scheduledTaskId === 'string') {
45
46
  return { kind: 'scheduled_task', scheduledTaskId: value.scheduledTaskId };
46
47
  }
48
+ if (hasExactShape(value, CLOUD_ACTIVATION_ORIGIN_SHAPE) &&
49
+ value.kind === 'cloud_activation' &&
50
+ typeof value.activationId === 'string') {
51
+ return { kind: 'cloud_activation', activationId: value.activationId };
52
+ }
47
53
  if (hasExactShape(value, LEGACY_AUTOMATION_ORIGIN_SHAPE) &&
48
54
  (value.kind === 'automation' || value.kind === 'legacy_automation') &&
49
55
  typeof value.automationId === 'string') {
@@ -21,9 +21,8 @@ import { buildContextBudgetDiagnosticShell, mergeContextBudgetDiagnostic, mergeC
21
21
  import { isHistoryCompactContentEvent } from './history-compaction.js';
22
22
  import { canContinueHistoryCompactCheckpointForModel, canReplayHistoryCompactCheckpointForModel, historyCompactSourceDigest, matchHistoryCompactCheckpointPrefix, projectHistoryCompactCheckpointReplay, } from './history-compact-checkpoint.js';
23
23
  import { HistoryCompactSummarizerError, isMalformedHistoryCompactSummaryReason, } from './history-compact-error.js';
24
- import { createHash } from 'node:crypto';
25
24
  import { archiveToolResultAsTransition, collectToolResultArchiveCandidates, serializedToolResultProjection, } from './tool-result-archive-transition.js';
26
- import { estimateTokens } from './context-budget-helpers.js';
25
+ import { estimateTokens, sha256 } from './context-budget-helpers.js';
27
26
  import { reduceEffectiveModelProjections, } from './model-projection-transition-ledger.js';
28
27
  import { buildRuntimeEventModelReplayPlan, collectToolActivityTurnIds, compatibleProviderReasoningReplayEventIds, } from './model-history.js';
29
28
  import { planHistoryCompaction } from './history-compaction.js';
@@ -969,9 +968,6 @@ function projectAcceptedMidTurnCompactionMessages(incomingMessages, acceptedProj
969
968
  ...incomingMessages.slice(acceptedProjection.sourceSignatures.length),
970
969
  ];
971
970
  }
972
- function sha256(text) {
973
- return createHash('sha256').update(text).digest('hex');
974
- }
975
971
  function modelMessageSignature(message) {
976
972
  return sha256(stableStringifyForSignature(message));
977
973
  }
@@ -38,7 +38,7 @@ import { hasBlockingReplayDiagnostics } from './ai-sdk-compaction.js';
38
38
  import { portableApplyPatchTool } from './apply-patch-profile.js';
39
39
  import { RunTrace } from './run-trace.js';
40
40
  import { REQUEST_SANDBOX_BOUNDARY_TOOL_NAME, SANDBOX_BOUNDARY_DENIED_FOR_TURN, SANDBOX_BOUNDARY_FINALIZATION_PROMPT, } from './sandbox-boundary-tool.js';
41
- import { buildRuntimeEventModelReplayPlan, buildSteeringEnvelope, collectToolActivityTurnIds, compatibleProviderReasoningReplayEventIds, formatTextWithInlineRefs, steeringMessagesMissingFromBase, steeringModelMessage, } from './model-history.js';
41
+ import { buildRuntimeEventModelReplayPlan, appendPriorUnknownToolResponses, buildSteeringEnvelope, collectToolActivityTurnIds, compatibleProviderReasoningReplayEventIds, formatTextWithInlineRefs, inspectPriorUnknownToolOutcomes, steeringMessagesMissingFromBase, steeringModelMessage, } from './model-history.js';
42
42
  import { toolSchemaCharsForDiagnostics, requestCompositionToolSchemas, stableHash, toolCatalogHash, } from './request-shape.js';
43
43
  import { toolAvailabilityHash } from './tool-availability.js';
44
44
  import { hasFinalizedReasoning } from './ai-sdk-message-projection.js';
@@ -584,7 +584,24 @@ export class AiSdkTurn {
584
584
  const maxSteps = input.maxSteps === null ? undefined : (input.maxSteps ?? this.deps.maxSteps);
585
585
  const toolRuntime = this.toolRuntime;
586
586
  const turnAbortController = this.abortController;
587
- const midTurnState = this.deps.compaction.buildMidTurnCapacityCompactState(input);
587
+ const priorEvents = (input.runtimeContext ?? []).filter((event) => input.continuation !== undefined || event.turnId !== input.turnId);
588
+ const observedPriorUnknownProjection = !input.continuation
589
+ ? inspectPriorUnknownToolOutcomes(priorEvents, input.runtimeContextInvocations)
590
+ : { kind: 'none' };
591
+ if (observedPriorUnknownProjection.kind === 'blocked') {
592
+ throw new Error(`Cannot use prior tool history: ${observedPriorUnknownProjection.reason}`);
593
+ }
594
+ if (observedPriorUnknownProjection.kind === 'projected' &&
595
+ !input.allowPriorUnknownToolOutcomes) {
596
+ throw new Error('Cannot continue an automated turn while a prior tool outcome is unknown; an explicit user message is required');
597
+ }
598
+ const priorUnknownProjection = input.allowPriorUnknownToolOutcomes
599
+ ? observedPriorUnknownProjection
600
+ : { kind: 'none' };
601
+ const preservingUnknownHistory = priorUnknownProjection.kind === 'projected';
602
+ const midTurnState = preservingUnknownHistory
603
+ ? undefined
604
+ : this.deps.compaction.buildMidTurnCapacityCompactState(input);
588
605
  const queue = new AsyncEventQueue();
589
606
  const codeModeExecTool = this.createCodeModeExecTool(queue);
590
607
  // One AssistantMessage is flushed per provider step (not per turn), so the
@@ -844,7 +861,7 @@ export class AiSdkTurn {
844
861
  let resolvedSystemPrompt = { sourceRevisions: [] };
845
862
  let systemPrompt;
846
863
  // --- Build messages from RuntimeEvent history and its compatibility projection. ---
847
- const priorReplayResult = await this.buildPriorMessages(input);
864
+ const priorReplayResult = await this.buildPriorMessages(input, priorUnknownProjection);
848
865
  if (this.aborted) {
849
866
  queue.push({
850
867
  type: 'abort',
@@ -975,6 +992,10 @@ export class AiSdkTurn {
975
992
  };
976
993
  const loadDurableTurnProjection = async () => {
977
994
  const turnEvents = await loadDurableTurnEvents();
995
+ // Prior unknown call/result pairs are outside this current-turn event
996
+ // set and are preserved separately in priorReplay. Continue pruning
997
+ // new tool results from this turn so one unknown predecessor does not
998
+ // make an unrelated large result permanently unprunable.
978
999
  const pruned = await this.deps.compaction.pruneToolResults(turnEvents, turnId);
979
1000
  if (pruned.stats) {
980
1001
  contextBudgetForTelemetry = addToolResultPruneStats(contextBudgetForTelemetry ?? minimalContextBudgetDiagnostic(), pruned.stats);
@@ -1106,6 +1127,9 @@ export class AiSdkTurn {
1106
1127
  }
1107
1128
  const requestSystemPromptBase = joinPromptFragments([
1108
1129
  systemPrompt,
1130
+ priorUnknownProjection.kind === 'projected'
1131
+ ? priorUnknownProjection.systemNotice
1132
+ : undefined,
1109
1133
  finalChildSummaryStep ? CHILD_STEP_BUDGET_FINALIZATION_PROMPT : undefined,
1110
1134
  toolRuntime.hasSandboxBoundaryDenial() ? SANDBOX_BOUNDARY_DENIED_FOR_TURN : undefined,
1111
1135
  sandboxBoundaryFinalizationStep ? SANDBOX_BOUNDARY_FINALIZATION_PROMPT : undefined,
@@ -1542,7 +1566,8 @@ export class AiSdkTurn {
1542
1566
  // more step; with the send-level budget already spent there is
1543
1567
  // nothing left to grant it, so the error is terminal.
1544
1568
  const stepBudgetRemains = maxSteps === undefined || runtimeSteps < maxSteps;
1545
- const recovered = stepBudgetRemains &&
1569
+ const recovered = !preservingUnknownHistory &&
1570
+ stepBudgetRemains &&
1546
1571
  failure.kind === 'context_overflow' &&
1547
1572
  providerAttempt < MAX_PROVIDER_ATTEMPTS_PER_STEP &&
1548
1573
  attemptHasNoObservableOutput()
@@ -2218,7 +2243,7 @@ export class AiSdkTurn {
2218
2243
  return this.deps.modelAdapter.makeErrorEvent(turnId, err, reasonOverride);
2219
2244
  }
2220
2245
  /** Materialize canonical RuntimeEvent history into ai-sdk's message format. */
2221
- async buildPriorMessages(input) {
2246
+ async buildPriorMessages(input, priorUnknownProjection) {
2222
2247
  if (!input.runtimeContext) {
2223
2248
  return {
2224
2249
  status: 'ready',
@@ -2236,26 +2261,57 @@ export class AiSdkTurn {
2236
2261
  // the durable projection-transition reducer (#4283). Replay, budgeting and
2237
2262
  // compaction share one input, so no RuntimeEvent replay path can resurrect
2238
2263
  // content a committed transition removed.
2239
- const preparedContextBudget = await this.deps.compaction.prepareContextBudgetPolicy(rawPriorRuntimeContext, input.turnId);
2240
- const priorRuntimeContext = preparedContextBudget.events;
2241
- const providerReasoningReplayEventIds = compatibleProviderReasoningReplayEventIds(priorRuntimeContext, input.runtimeContextInvocations, this.deps.backend.providerStateIdentity, this.deps.backend.modelId);
2242
- let contextBudget = preparedContextBudget.policy;
2243
- // Match the durable checkpoint against the RAW ledger prefix: every
2244
- // creation path (standalone compactHistory and the mid-turn state) pins
2245
- // its coverage digest on raw events, so matching the folded view here
2246
- // lets any durable projection transition inside the covered prefix orphan
2247
- // the checkpoint and silently fail open into a full-history replay
2248
- // (#4842). The projected [block, tail] is then folded through the
2249
- // transition reducer before it becomes messages, so a committed
2250
- // transition still cannot resurrect content for the model (#4283).
2251
- const budgeted = applyRuntimeEventContextBudget(rawPriorRuntimeContext, contextBudget);
2252
- let runtimeContext = await this.deps.compaction.foldEffectiveModelHistory(budgeted?.events ?? rawPriorRuntimeContext, preparedContextBudget.projectionSnapshot);
2253
- let contextBudgetDiagnostic = budgeted?.diagnostic;
2254
- let projectedHistoryCompactCheckpoint = budgeted?.historyCompactCheckpoint;
2255
- if (preparedContextBudget.diagnosticPatch) {
2256
- contextBudgetDiagnostic = mergeContextBudgetDiagnostic(contextBudgetDiagnostic ??
2257
- buildContextBudgetDiagnosticShell(priorRuntimeContext, runtimeContext, contextBudget), preparedContextBudget.diagnosticPatch);
2264
+ const preservingUnknownHistory = priorUnknownProjection.kind === 'projected';
2265
+ let priorRuntimeContext;
2266
+ let runtimeContext;
2267
+ let contextBudget;
2268
+ let contextBudgetDiagnostic;
2269
+ let projectedHistoryCompactCheckpoint;
2270
+ if (priorUnknownProjection.kind === 'projected') {
2271
+ const preparedContextBudget = await this.deps.compaction.prepareContextBudgetPolicy(rawPriorRuntimeContext, input.turnId);
2272
+ priorRuntimeContext = preparedContextBudget.events;
2273
+ contextBudget = preparedContextBudget.policy;
2274
+ const budgeted = applyRuntimeEventContextBudget(rawPriorRuntimeContext, contextBudget);
2275
+ const budgetedEvents = budgeted?.events ?? rawPriorRuntimeContext;
2276
+ const preservesUnknownCalls = priorUnknownProjection.outcomes.every((outcome) => budgetedEvents.some((event) => event.id === outcome.callEventId));
2277
+ // Existing checkpoints and durable result pruning are safe when they
2278
+ // leave every unknown call available to pair with its temporary result.
2279
+ // Otherwise replay the full effective ledger: a summary that erases T1
2280
+ // would make the request-local T2 orphaned or hide the uncertainty.
2281
+ const selectedEvents = preservesUnknownCalls ? budgetedEvents : rawPriorRuntimeContext;
2282
+ const effectiveEvents = await this.deps.compaction.foldEffectiveModelHistory(selectedEvents, preparedContextBudget.projectionSnapshot);
2283
+ runtimeContext = appendPriorUnknownToolResponses(effectiveEvents, priorUnknownProjection);
2284
+ if (preservesUnknownCalls) {
2285
+ contextBudgetDiagnostic = budgeted?.diagnostic;
2286
+ projectedHistoryCompactCheckpoint = budgeted?.historyCompactCheckpoint;
2287
+ }
2288
+ if (preparedContextBudget.diagnosticPatch) {
2289
+ contextBudgetDiagnostic = mergeContextBudgetDiagnostic(contextBudgetDiagnostic ??
2290
+ buildContextBudgetDiagnosticShell(priorRuntimeContext, effectiveEvents, contextBudget), preparedContextBudget.diagnosticPatch);
2291
+ }
2292
+ }
2293
+ else {
2294
+ const preparedContextBudget = await this.deps.compaction.prepareContextBudgetPolicy(rawPriorRuntimeContext, input.turnId);
2295
+ priorRuntimeContext = preparedContextBudget.events;
2296
+ contextBudget = preparedContextBudget.policy;
2297
+ // Match the durable checkpoint against the RAW ledger prefix: every
2298
+ // creation path (standalone compactHistory and the mid-turn state) pins
2299
+ // its coverage digest on raw events, so matching the folded view here
2300
+ // lets any durable projection transition inside the covered prefix orphan
2301
+ // the checkpoint and silently fail open into a full-history replay
2302
+ // (#4842). The projected [block, tail] is then folded through the
2303
+ // transition reducer before it becomes messages, so a committed
2304
+ // transition still cannot resurrect content for the model (#4283).
2305
+ const budgeted = applyRuntimeEventContextBudget(rawPriorRuntimeContext, contextBudget);
2306
+ runtimeContext = await this.deps.compaction.foldEffectiveModelHistory(budgeted?.events ?? rawPriorRuntimeContext, preparedContextBudget.projectionSnapshot);
2307
+ contextBudgetDiagnostic = budgeted?.diagnostic;
2308
+ projectedHistoryCompactCheckpoint = budgeted?.historyCompactCheckpoint;
2309
+ if (preparedContextBudget.diagnosticPatch) {
2310
+ contextBudgetDiagnostic = mergeContextBudgetDiagnostic(contextBudgetDiagnostic ??
2311
+ buildContextBudgetDiagnosticShell(priorRuntimeContext, runtimeContext, contextBudget), preparedContextBudget.diagnosticPatch);
2312
+ }
2258
2313
  }
2314
+ const providerReasoningReplayEventIds = compatibleProviderReasoningReplayEventIds(priorRuntimeContext, input.runtimeContextInvocations, this.deps.backend.providerStateIdentity, this.deps.backend.modelId);
2259
2315
  // No pre-turn estimate gate: the turn's first request is judged by the
2260
2316
  // request-projection hook from the previous request's real usage, and by
2261
2317
  // the provider when it goes out (#4559).
@@ -25,14 +25,14 @@ const DEFAULT_TIMEOUT_MS = 15_000;
25
25
  export async function proxiedFetch(input, init = {}) {
26
26
  const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
27
27
  const proxy = resolveActiveProxy();
28
+ const { timeoutMs = DEFAULT_TIMEOUT_MS, signal, ...fetchInit } = init;
29
+ const controller = new AbortController();
30
+ const requestSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;
28
31
  let dispatcher;
29
32
  if (proxy && !matchesBypassList(new URL(url).hostname, proxy.bypassList)) {
30
- dispatcher = buildProxyDispatcher(proxy);
33
+ dispatcher = buildProxyDispatcher(proxy, requestSignal);
31
34
  }
32
- const { timeoutMs = DEFAULT_TIMEOUT_MS, signal, ...fetchInit } = init;
33
35
  const timeoutEnabled = timeoutMs > 0;
34
- const controller = new AbortController();
35
- const requestSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;
36
36
  let timedOut = false;
37
37
  const disposeDispatcher = async (force = false) => {
38
38
  const disposable = dispatcher;
@@ -70,6 +70,7 @@ export async function proxiedFetch(input, init = {}) {
70
70
  catch (error) {
71
71
  if (timer)
72
72
  clearTimeout(timer);
73
+ controller.abort(error);
73
74
  await disposeDispatcher(timedOut);
74
75
  throw error;
75
76
  }