mixdog 0.9.52 → 0.9.53

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 (111) hide show
  1. package/package.json +1 -1
  2. package/scripts/bench-run.mjs +2 -2
  3. package/scripts/compact-pressure-test.mjs +104 -0
  4. package/scripts/desktop-session-bridge-test.mjs +704 -0
  5. package/scripts/freevar-smoke.mjs +7 -4
  6. package/scripts/lifecycle-api-test.mjs +65 -4
  7. package/scripts/max-output-recovery-test.mjs +31 -0
  8. package/scripts/memory-core-input-test.mjs +10 -0
  9. package/scripts/openai-oauth-ws-1006-retry-test.mjs +63 -3
  10. package/scripts/openai-ws-early-settle-test.mjs +40 -0
  11. package/scripts/parent-abort-link-test.mjs +24 -0
  12. package/scripts/process-lifecycle-test.mjs +80 -22
  13. package/scripts/provider-contract-test.mjs +257 -0
  14. package/scripts/provider-toolcall-test.mjs +172 -10
  15. package/scripts/session-orphan-sweep-test.mjs +27 -1
  16. package/src/lib/keychain-cjs.cjs +36 -23
  17. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +1 -13
  18. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +7 -8
  19. package/src/runtime/agent/orchestrator/agent-trace.mjs +33 -9
  20. package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +7 -2
  21. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +14 -300
  22. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -4
  23. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +18 -266
  24. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +18 -1
  25. package/src/runtime/agent/orchestrator/providers/gemini.mjs +15 -130
  26. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +5 -115
  27. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +224 -0
  28. package/src/runtime/agent/orchestrator/providers/lib/env-utils.mjs +6 -0
  29. package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +119 -0
  30. package/src/runtime/agent/orchestrator/providers/lib/grok-tool-schema.mjs +109 -0
  31. package/src/runtime/agent/orchestrator/providers/lib/openai-tool-args.mjs +70 -0
  32. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +14 -71
  33. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +47 -3
  34. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +1 -7
  35. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +72 -77
  36. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +15 -20
  37. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +10 -10
  38. package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +30 -3
  39. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +37 -28
  40. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +5 -7
  41. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +8 -0
  42. package/src/runtime/agent/orchestrator/session/context-compaction-policy.mjs +170 -0
  43. package/src/runtime/agent/orchestrator/session/context-utils.mjs +20 -223
  44. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +11 -17
  45. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +12 -5
  46. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +21 -5
  47. package/src/runtime/agent/orchestrator/session/manager/prefetch-bridge.mjs +3 -58
  48. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +24 -0
  49. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +57 -16
  50. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +2 -2
  51. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +7 -1
  52. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +52 -0
  53. package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +62 -0
  54. package/src/runtime/agent/orchestrator/session/store.mjs +305 -127
  55. package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +46 -0
  56. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-grep-chunks.mjs +173 -0
  57. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +117 -0
  58. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-insights.mjs +199 -0
  59. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-spawn-helpers.mjs +107 -0
  60. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +1 -40
  61. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +19 -277
  62. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +22 -298
  63. package/src/runtime/agent/orchestrator/tools/lib/shell-spawn-retry.mjs +67 -0
  64. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +1 -71
  65. package/src/runtime/channels/backends/discord-gateway.mjs +1 -1
  66. package/src/runtime/channels/backends/discord.mjs +6 -6
  67. package/src/runtime/channels/lib/config.mjs +15 -2
  68. package/src/runtime/channels/lib/memory-client.mjs +20 -3
  69. package/src/runtime/channels/lib/owned-runtime.mjs +19 -12
  70. package/src/runtime/channels/lib/status-snapshot.mjs +9 -0
  71. package/src/runtime/channels/lib/tool-dispatch.mjs +9 -5
  72. package/src/runtime/channels/lib/worker-main.mjs +16 -5
  73. package/src/runtime/memory/index.mjs +24 -198
  74. package/src/runtime/memory/lib/memory-action-handlers.mjs +2 -53
  75. package/src/runtime/memory/lib/memory-daemon-lifecycle.mjs +115 -0
  76. package/src/runtime/memory/lib/memory-port-advertiser.mjs +105 -0
  77. package/src/runtime/memory/lib/pg/supervisor.mjs +0 -4
  78. package/src/runtime/memory/lib/query-handlers.mjs +2 -122
  79. package/src/runtime/memory/lib/query-maintenance-handlers.mjs +126 -0
  80. package/src/runtime/memory/lib/tool-call-handler.mjs +57 -0
  81. package/src/runtime/search/lib/http-fetch.mjs +1 -1
  82. package/src/runtime/shared/config.mjs +58 -13
  83. package/src/runtime/shared/llm/cost.mjs +14 -4
  84. package/src/runtime/shared/memory-snapshot.mjs +236 -0
  85. package/src/runtime/shared/process-lifecycle.mjs +92 -19
  86. package/src/runtime/shared/process-shutdown.mjs +6 -0
  87. package/src/runtime/shared/resource-admission.mjs +7 -2
  88. package/src/session-runtime/channel-config-api.mjs +7 -7
  89. package/src/session-runtime/config-lifecycle.mjs +20 -17
  90. package/src/session-runtime/cwd-plugins.mjs +9 -7
  91. package/src/session-runtime/env.mjs +1 -2
  92. package/src/session-runtime/hitch-profile.mjs +45 -0
  93. package/src/session-runtime/lifecycle-api.mjs +36 -9
  94. package/src/session-runtime/mcp-glue.mjs +6 -11
  95. package/src/session-runtime/provider-init-key.mjs +17 -0
  96. package/src/session-runtime/runtime-core.mjs +44 -103
  97. package/src/session-runtime/runtime-paths.mjs +20 -0
  98. package/src/session-runtime/runtime-tool-routing.mjs +55 -0
  99. package/src/session-runtime/tool-catalog-data.mjs +51 -0
  100. package/src/session-runtime/tool-catalog.mjs +15 -89
  101. package/src/standalone/agent-tool/spawn-preset.mjs +73 -0
  102. package/src/standalone/agent-tool/worker-rows.mjs +93 -0
  103. package/src/standalone/agent-tool.mjs +12 -162
  104. package/src/standalone/channel-admin.mjs +29 -0
  105. package/src/tui/App.jsx +11 -5
  106. package/src/tui/dist/index.mjs +202 -65
  107. package/src/tui/engine/session-api-ext.mjs +37 -4
  108. package/src/tui/index.jsx +1 -0
  109. package/src/tui/lib/voice-setup.mjs +5 -5
  110. package/scripts/_devtools-stub.mjs +0 -1
  111. package/src/runtime/lib/keychain-cjs.cjs +0 -288
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixdog",
3
- "version": "0.9.52",
3
+ "version": "0.9.53",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Standalone mixdog coding-agent CLI/TUI workspace.",
@@ -336,7 +336,7 @@ function averageCards(cards) {
336
336
  // ---- main ----
337
337
  const tasksPath = argValue('--tasks', null);
338
338
  if (!tasksPath) {
339
- console.error('usage: --tasks <tasks.json> [--round N] [--runner mixdog] [--provider P] [--model M] [--effort E] [--fast] [--save round.json] [--json]');
339
+ console.error('usage: --tasks <tasks.json> [--round N] [--runner mixdog|codex|lead] [--provider P] [--model M] [--effort E] [--fast] [--save round.json] [--json]');
340
340
  process.exit(1);
341
341
  }
342
342
  if (!existsSync(resolve(tasksPath))) { console.error(`tasks file not found: ${tasksPath}`); process.exit(1); }
@@ -345,7 +345,7 @@ if (!Array.isArray(tasks) || !tasks.length) { console.error('tasks.json must be
345
345
 
346
346
  const runnerName = argValue('--runner', 'mixdog');
347
347
  const runner = RUNNERS[runnerName];
348
- if (!runner) { console.error(`unknown runner "${runnerName}" (mixdog|codex|claude)`); process.exit(1); }
348
+ if (!runner) { console.error(`unknown runner "${runnerName}" (mixdog|codex|lead)`); process.exit(1); }
349
349
  const round = argValue('--round', '1');
350
350
  const savePath = argValue('--save', null);
351
351
  const jsonMode = hasFlag('--json');
@@ -22,6 +22,8 @@ import { initialCompactionConfig } from '../src/runtime/agent/orchestrator/sessi
22
22
  import { resolveSessionCompactionPolicy } from '../src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs';
23
23
  import { sendWithRecovery } from '../src/runtime/agent/orchestrator/session/send-with-recovery.mjs';
24
24
  import { recallFastTrackCompactMessages } from '../src/runtime/agent/orchestrator/session/compact/engine.mjs';
25
+ import { _combineUsageWithWarmup } from '../src/runtime/agent/orchestrator/providers/openai-ws-events.mjs';
26
+ import { applyAskTerminalUsageTotals } from '../src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs';
25
27
 
26
28
  function policyFor(session) {
27
29
  return resolveWorkerCompactPolicy(session, []);
@@ -626,6 +628,108 @@ test('thinking-only continuation without assistant replay excludes provider outp
626
628
  }), false, 'unreplayed thinking output must not cause an early compact');
627
629
  });
628
630
 
631
+ test('OpenAI OAuth WS warmup remains billed but does not double the main context footprint', async () => {
632
+ const main = {
633
+ inputTokens: 167_635,
634
+ outputTokens: 611,
635
+ cachedTokens: 160_000,
636
+ promptTokens: 167_635,
637
+ raw: {},
638
+ };
639
+ const usage = _combineUsageWithWarmup(main, main, { separateMainContext: true });
640
+ assert.equal(usage.inputTokens, 335_270, 'billing usage must retain warmup plus main input');
641
+ const { initProviders, getProvider } = await import('../src/runtime/agent/orchestrator/providers/registry.mjs');
642
+ const { createSession, askSession, getSession } = await import('../src/runtime/agent/orchestrator/session/manager.mjs');
643
+ await initProviders({ 'openai-oauth': { enabled: true } });
644
+ const provider = getProvider('openai-oauth');
645
+ const originalSend = provider.send;
646
+ const compactEvents = [];
647
+ provider.send = async () => ({ content: 'done', usage });
648
+ try {
649
+ const session = createSession({
650
+ provider: 'openai-oauth',
651
+ model: 'warmup-context-regression',
652
+ tools: [],
653
+ cwd: process.cwd(),
654
+ skipAgentRules: true,
655
+ skipSkills: true,
656
+ compaction: { auto: true },
657
+ });
658
+ session.contextWindow = 272_000;
659
+ session.rawContextWindow = 272_000;
660
+ await askSession(session.id, 'large OAuth WebSocket request', null, null, process.cwd(), null, {
661
+ onCompactEvent: event => compactEvents.push(event),
662
+ });
663
+
664
+ const persisted = getSession(session.id);
665
+ const policy = { ...policyFor(persisted), reserveTokens: 0 };
666
+ const messageTokens = estimateMessagesTokens(persisted.messages);
667
+ const pressure = resolveCompactionPressureTokens(messageTokens, policy, {
668
+ messages: persisted.messages,
669
+ sessionRef: persisted,
670
+ });
671
+ assert.equal(persisted.totalInputTokens, 335_270, 'incremental lifetime totals must retain warmup billing');
672
+ assert.equal(persisted.lastContextTokens, 167_635, 'incremental context snapshot must exclude warmup');
673
+ assert.equal(persisted.contextPressureBaselineTokens, 168_246, 'stored baseline must use main request usage');
674
+ assert.equal(pressure, 168_246, 'resolved pressure must use the stored baseline without transcript growth');
675
+ assert.equal(policy.triggerTokens, 258_400, 'fixture trigger must match the reported premature-compaction threshold');
676
+ assert.equal(shouldCompactForSession(messageTokens, policy, {
677
+ messages: persisted.messages,
678
+ sessionRef: persisted,
679
+ pressureTokens: pressure,
680
+ }), false, 'main-request pressure must not trigger compaction');
681
+ assert.equal(compactEvents.length, 0, 'warmup must not cause an auto-compaction');
682
+ } finally {
683
+ provider.send = originalSend;
684
+ }
685
+ });
686
+
687
+ test('warmup-only OpenAI OAuth WS usage stays billable but invalidates context usage', () => {
688
+ const warmup = { inputTokens: 167_635, outputTokens: 611, cachedTokens: 160_000, promptTokens: 167_635 };
689
+ const usage = _combineUsageWithWarmup(null, warmup, { separateMainContext: true });
690
+ const session = { provider: 'openai-oauth', contextPressureBaselineTokens: 99_000 };
691
+ assert.equal(usage.mainUsageAvailable, false);
692
+ assert.equal(recordProviderContextBaseline(session, [], usage), false);
693
+ assert.equal(session.contextPressureBaselineTokens, null, 'warmup-only usage must not remain a provider baseline');
694
+ applyAskTerminalUsageTotals(session, { usage, lastTurnUsage: usage });
695
+ assert.equal(session.totalInputTokens, 167_635, 'warmup-only usage remains billable');
696
+ assert.equal(session.lastContextTokens, null, 'warmup-only usage has no main-request context snapshot');
697
+ });
698
+
699
+ test('xAI warmup remains billable while main usage alone drives context pressure', () => {
700
+ const actual = { inputTokens: 20, outputTokens: 2, cachedTokens: 5, promptTokens: 20, raw: { provider: 'xai', cost_in_usd_ticks: 200 } };
701
+ const warmup = { inputTokens: 10, outputTokens: 1, cachedTokens: 3, promptTokens: 10, raw: { phase: 'warmup', cost_in_usd_ticks: 100 } };
702
+ const usage = _combineUsageWithWarmup(actual, warmup, { separateMainContext: true });
703
+ assert.deepEqual(usage, {
704
+ ...actual,
705
+ inputTokens: 30,
706
+ outputTokens: 3,
707
+ cachedTokens: 8,
708
+ promptTokens: 30,
709
+ warmupInputTokens: 10,
710
+ warmupCachedTokens: 3,
711
+ warmupOutputTokens: 1,
712
+ warmupPromptTokens: 10,
713
+ warmupCacheWriteTokens: 0,
714
+ raw: {
715
+ provider: 'xai',
716
+ cost_in_usd_ticks: 300,
717
+ warmup_usage: { phase: 'warmup', cost_in_usd_ticks: 100 },
718
+ },
719
+ mainInputTokens: 20,
720
+ mainOutputTokens: 2,
721
+ mainCachedTokens: 5,
722
+ mainPromptTokens: 20,
723
+ mainCacheWriteTokens: 0,
724
+ mainUsageAvailable: true,
725
+ });
726
+ const session = { provider: 'xai', contextPressureBaselineTokens: null };
727
+ assert.equal(recordProviderContextBaseline(session, [], usage), true);
728
+ applyAskTerminalUsageTotals(session, { usage, lastTurnUsage: usage });
729
+ assert.equal(session.totalInputTokens, 30, 'lifetime total includes xAI warmup');
730
+ assert.equal(session.lastContextTokens, 20, 'context snapshot excludes xAI warmup');
731
+ });
732
+
629
733
  test('successful compact invalidates stale usage and cannot immediately compact again', () => {
630
734
  const session = { provider: 'openai', contextWindow: 100_000, compaction: {} };
631
735
  const policy = { ...policyFor(session), reserveTokens: 0 };