mixdog 0.8.1 → 0.9.1
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 +47 -23
- package/package.json +34 -28
- package/scripts/_test-folder-dialog.mjs +30 -0
- package/scripts/agent-parallel-smoke.mjs +388 -0
- package/scripts/agent-tag-reuse-smoke.mjs +183 -0
- package/scripts/background-task-meta-smoke.mjs +38 -0
- package/scripts/boot-smoke.mjs +52 -9
- package/scripts/build-runtime-linux.sh +348 -0
- package/scripts/build-runtime-macos.sh +217 -0
- package/scripts/build-runtime-windows.ps1 +242 -0
- package/scripts/compact-active-turn-test.mjs +68 -0
- package/scripts/compact-smoke.mjs +859 -129
- package/scripts/compact-trigger-migration-smoke.mjs +187 -0
- package/scripts/fix-brief-fn.mjs +35 -0
- package/scripts/fix-format-tool-surface.mjs +24 -0
- package/scripts/fix-tool-exec-visible.mjs +42 -0
- package/scripts/generate-runtime-manifest.mjs +166 -0
- package/scripts/hook-bus-test.mjs +330 -0
- package/scripts/lead-workflow-smoke.mjs +33 -39
- package/scripts/live-worker-smoke.mjs +43 -37
- package/scripts/llm-trace-summary.mjs +315 -0
- package/scripts/memory-meta-concurrency-test.mjs +20 -0
- package/scripts/output-style-smoke.mjs +56 -15
- package/scripts/parent-abort-link-test.mjs +44 -0
- package/scripts/patch-agent-brief.mjs +48 -0
- package/scripts/patch-app.mjs +21 -0
- package/scripts/patch-app2.mjs +18 -0
- package/scripts/patch-dist-brief.mjs +96 -0
- package/scripts/patch-tool-exec.mjs +70 -0
- package/scripts/pretool-ask-runtime-test.mjs +54 -0
- package/scripts/provider-toolcall-test.mjs +376 -0
- package/scripts/reactive-compact-persist-smoke.mjs +124 -0
- package/scripts/sanitize-tool-pairs-test.mjs +260 -0
- package/scripts/session-context-bench.mjs +205 -33
- package/scripts/session-ingest-smoke.mjs +177 -0
- package/scripts/set-effort-config-test.mjs +41 -0
- package/scripts/smoke-runtime-negative.ps1 +106 -0
- package/scripts/smoke-runtime-negative.sh +97 -0
- package/scripts/smoke.mjs +25 -0
- package/scripts/tool-result-hook-test.mjs +48 -0
- package/scripts/tool-smoke.mjs +1222 -90
- package/scripts/toolcall-args-test.mjs +150 -0
- package/scripts/tui-background-failure-smoke.mjs +73 -0
- package/scripts/usage-metrics-epoch-smoke.mjs +114 -0
- package/src/agents/debugger/AGENT.md +8 -0
- package/src/agents/explore/AGENT.md +4 -0
- package/src/agents/heavy-worker/AGENT.md +9 -3
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +8 -0
- package/src/agents/scheduler-task/AGENT.md +12 -0
- package/src/agents/scheduler-task/agent.json +6 -0
- package/src/agents/webhook-handler/AGENT.md +12 -0
- package/src/agents/webhook-handler/agent.json +6 -0
- package/src/agents/worker/AGENT.md +9 -3
- package/src/app.mjs +77 -3
- package/src/defaults/hidden-roles.json +17 -12
- package/src/headless-role.mjs +117 -0
- package/src/help.mjs +30 -0
- package/src/hooks/lib/permission-evaluator.cjs +11 -475
- package/src/lib/keychain-cjs.cjs +9 -1
- package/src/lib/mixdog-debug.cjs +0 -29
- package/src/lib/plugin-paths.cjs +1 -7
- package/src/lib/rules-builder.cjs +242 -98
- package/src/lib/text-utils.cjs +1 -1
- package/src/mixdog-session-runtime.mjs +2211 -446
- package/src/output-styles/default.md +12 -28
- package/src/output-styles/extreme-simple.md +9 -6
- package/src/output-styles/simple.md +22 -9
- package/src/repl.mjs +108 -59
- package/src/rules/agent/00-common.md +15 -0
- package/src/rules/{bridge → agent}/20-skip-protocol.md +1 -2
- package/src/rules/agent/30-explorer.md +22 -0
- package/src/rules/{bridge → agent}/40-cycle1-agent.md +7 -0
- package/src/rules/{bridge → agent}/41-cycle2-agent.md +7 -0
- package/src/rules/{bridge → agent}/42-cycle3-agent.md +7 -0
- package/src/rules/lead/01-general.md +9 -5
- package/src/rules/lead/04-workflow.md +51 -12
- package/src/rules/lead/lead-tool.md +6 -0
- package/src/rules/shared/01-tool.md +12 -1
- package/src/runtime/agent/orchestrator/activity-bus.mjs +7 -18
- package/src/runtime/agent/orchestrator/agent-owner.mjs +11 -0
- package/src/runtime/agent/orchestrator/{smart-bridge/bridge-llm.mjs → agent-runtime/agent-dispatch.mjs} +138 -111
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +94 -0
- package/src/runtime/agent/orchestrator/{smart-bridge → agent-runtime}/cache-strategy.mjs +32 -23
- package/src/runtime/agent/orchestrator/{smart-bridge → agent-runtime}/session-builder.mjs +33 -27
- package/src/runtime/agent/orchestrator/{bridge-trace.mjs → agent-trace.mjs} +132 -81
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +0 -21
- package/src/runtime/agent/orchestrator/config.mjs +174 -55
- package/src/runtime/agent/orchestrator/context/collect.mjs +195 -487
- package/src/runtime/agent/orchestrator/dispatch-persist.mjs +1 -1
- package/src/runtime/agent/orchestrator/internal-roles.mjs +77 -29
- package/src/runtime/agent/orchestrator/internal-tools.mjs +5 -6
- package/src/runtime/agent/orchestrator/mcp/client.mjs +15 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +380 -268
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +131 -93
- package/src/runtime/agent/orchestrator/providers/api-usage.mjs +236 -4
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +49 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +58 -13
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +67 -149
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +132 -2
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +61 -116
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +25 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +79 -255
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +203 -71
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +512 -312
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +343 -518
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +6 -6
- package/src/runtime/agent/orchestrator/providers/registry.mjs +88 -51
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +289 -11
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +41 -8
- package/src/runtime/agent/orchestrator/session/compact.mjs +1173 -267
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +199 -36
- package/src/runtime/agent/orchestrator/session/loop.mjs +840 -612
- package/src/runtime/agent/orchestrator/session/manager.mjs +1574 -459
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +107 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +67 -29
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +31 -16
- package/src/runtime/agent/orchestrator/tool-loop-guard.mjs +3 -219
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +35 -8
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +19 -8
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +10 -53
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +60 -37
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +21 -2
- package/src/runtime/agent/orchestrator/tools/builtin/device-paths.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -7
- package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +1 -3
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +36 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-constants.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +5 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +4 -36
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +2 -40
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +148 -27
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +43 -75
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +90 -20
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +59 -5
- package/src/runtime/agent/orchestrator/tools/code-graph-state.mjs +86 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +11 -11
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4106 -4019
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +33 -4
- package/src/runtime/agent/orchestrator/tools/patch.mjs +90 -6
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +6 -4
- package/src/runtime/agent/orchestrator/tools/result-compression.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +8 -1
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -4
- package/src/runtime/channels/index.mjs +149 -51
- package/src/runtime/channels/lib/cli-worker-host.mjs +1 -8
- package/src/runtime/channels/lib/config.mjs +0 -1
- package/src/runtime/channels/lib/drop-trace.mjs +1 -1
- package/src/runtime/channels/lib/executor.mjs +0 -3
- package/src/runtime/channels/lib/memory-client.mjs +0 -38
- package/src/runtime/channels/lib/output-forwarder.mjs +1 -8
- package/src/runtime/channels/lib/runtime-paths.mjs +0 -6
- package/src/runtime/channels/lib/scheduler.mjs +18 -14
- package/src/runtime/channels/lib/session-discovery.mjs +3 -6
- package/src/runtime/channels/lib/tool-format.mjs +0 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -12
- package/src/runtime/channels/lib/webhook.mjs +1 -1
- package/src/runtime/channels/tool-defs.mjs +29 -29
- package/src/runtime/lib/keychain-cjs.cjs +0 -1
- package/src/runtime/memory/data/runtime-manifest.json +6 -7
- package/src/runtime/memory/index.mjs +519 -118
- package/src/runtime/memory/lib/agent-ipc.mjs +29 -12
- package/src/runtime/memory/lib/core-memory-store.mjs +2 -2
- package/src/runtime/memory/lib/embedding-model-config.mjs +55 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +31 -4
- package/src/runtime/memory/lib/embedding-worker.mjs +19 -10
- package/src/runtime/memory/lib/llm-worker-host.mjs +0 -4
- package/src/runtime/memory/lib/memory-cycle1.mjs +28 -7
- package/src/runtime/memory/lib/memory-cycle2.mjs +4 -5
- package/src/runtime/memory/lib/memory-cycle3.mjs +2 -2
- package/src/runtime/memory/lib/memory-ops-policy.mjs +2 -2
- package/src/runtime/memory/lib/memory-session-merge.mjs +38 -0
- package/src/runtime/memory/lib/memory.mjs +88 -9
- package/src/runtime/memory/lib/model-profile.mjs +1 -1
- package/src/runtime/memory/lib/pg/adapter.mjs +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +12 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +80 -21
- package/src/runtime/memory/lib/session-ingest.mjs +196 -0
- package/src/runtime/memory/lib/trace-store.mjs +96 -51
- package/src/runtime/memory/tool-defs.mjs +46 -37
- package/src/runtime/search/index.mjs +104 -473
- package/src/runtime/search/lib/config.mjs +0 -4
- package/src/runtime/search/lib/state.mjs +1 -15
- package/src/runtime/search/lib/web-tools.mjs +44 -25
- package/src/runtime/search/tool-defs.mjs +16 -23
- package/src/runtime/shared/abort-controller.mjs +1 -1
- package/src/runtime/shared/atomic-file.mjs +4 -3
- package/src/runtime/shared/background-tasks.mjs +122 -11
- package/src/runtime/shared/child-spawn-gate.mjs +139 -0
- package/src/runtime/shared/config.mjs +7 -4
- package/src/runtime/shared/err-text.mjs +131 -4
- package/src/runtime/shared/llm/cost.mjs +2 -2
- package/src/runtime/shared/llm/http-agent.mjs +23 -7
- package/src/runtime/shared/llm/index.mjs +34 -11
- package/src/runtime/shared/llm/usage-log.mjs +4 -4
- package/src/runtime/shared/markdown-frontmatter.mjs +56 -0
- package/src/runtime/shared/singleton-owner.mjs +104 -0
- package/src/runtime/shared/tool-execution-contract.mjs +199 -20
- package/src/runtime/shared/tool-execution-contract.test.mjs +183 -0
- package/src/runtime/shared/tool-surface.mjs +624 -95
- package/src/runtime/shared/user-data-guard.mjs +0 -2
- package/src/standalone/agent-task-status.mjs +203 -0
- package/src/standalone/agent-task-status.test.mjs +76 -0
- package/src/standalone/agent-tool.mjs +1913 -0
- package/src/standalone/channel-worker.mjs +370 -14
- package/src/standalone/explore-tool.mjs +165 -70
- package/src/standalone/folder-dialog.mjs +314 -0
- package/src/standalone/hook-bus.mjs +898 -22
- package/src/standalone/memory-runtime-proxy.mjs +320 -0
- package/src/standalone/projects.mjs +226 -0
- package/src/standalone/provider-admin.mjs +41 -24
- package/src/standalone/seeds.mjs +1 -78
- package/src/standalone/usage-dashboard.mjs +96 -8
- package/src/tui/App.jsx +4800 -2140
- package/src/tui/components/AnsiText.jsx +39 -28
- package/src/tui/components/ContextPanel.jsx +14 -4
- package/src/tui/components/Markdown.jsx +43 -77
- package/src/tui/components/MarkdownTable.jsx +9 -184
- package/src/tui/components/Message.jsx +28 -11
- package/src/tui/components/Picker.jsx +95 -56
- package/src/tui/components/PromptInput.jsx +428 -239
- package/src/tui/components/QueuedCommands.jsx +1 -1
- package/src/tui/components/SlashCommandPalette.jsx +27 -21
- package/src/tui/components/Spinner.jsx +67 -38
- package/src/tui/components/StatusLine.jsx +606 -38
- package/src/tui/components/TextEntryPanel.jsx +128 -9
- package/src/tui/components/ToolExecution.jsx +597 -362
- package/src/tui/components/TurnDone.jsx +3 -3
- package/src/tui/components/UsagePanel.jsx +3 -5
- package/src/tui/components/tool-output-format.mjs +499 -0
- package/src/tui/components/tool-output-format.test.mjs +312 -0
- package/src/tui/dist/index.mjs +9192 -2399
- package/src/tui/engine-runtime-notification.test.mjs +115 -0
- package/src/tui/engine-tool-result-text.test.mjs +75 -0
- package/src/tui/engine.mjs +1455 -279
- package/src/tui/figures.mjs +21 -40
- package/src/tui/index.jsx +75 -31
- package/src/tui/input-editing.mjs +25 -0
- package/src/tui/markdown/format-token.mjs +671 -69
- package/src/tui/markdown/format-token.test.mjs +312 -0
- package/src/tui/markdown/render-ansi.mjs +94 -0
- package/src/tui/markdown/render-ansi.test.mjs +108 -0
- package/src/tui/markdown/stream-fence.mjs +34 -0
- package/src/tui/markdown/stream-fence.test.mjs +26 -0
- package/src/tui/markdown/table-layout.mjs +250 -0
- package/src/tui/paste-attachments.mjs +0 -7
- package/src/tui/spinner-verbs.mjs +1 -2
- package/src/tui/statusline-ansi-bridge.mjs +172 -0
- package/src/tui/statusline-ansi-bridge.test.mjs +159 -0
- package/src/tui/theme.mjs +756 -24
- package/src/tui/time-format.mjs +1 -1
- package/src/tui/transcript-tool-failures.mjs +67 -0
- package/src/tui/transcript-tool-failures.test.mjs +111 -0
- package/src/ui/ansi.mjs +1 -2
- package/src/ui/markdown.mjs +85 -26
- package/src/ui/markdown.test.mjs +70 -0
- package/src/ui/model-display.mjs +121 -0
- package/src/ui/session-stats.mjs +44 -0
- package/src/ui/statusline-context-label.test.mjs +15 -0
- package/src/ui/statusline.mjs +386 -178
- package/src/ui/tool-card.mjs +2 -13
- package/src/vendor/statusline/bin/statusline-lib.mjs +1 -620
- package/src/vendor/statusline/bin/statusline-route.mjs +169 -37
- package/src/vendor/statusline/bin/statusline-route.test.mjs +80 -0
- package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +3 -3
- package/src/vendor/statusline/src/gateway/claude-current.mjs +1 -1
- package/src/vendor/statusline/src/gateway/route-meta.mjs +44 -6
- package/src/vendor/statusline/src/gateway/session-routes.mjs +1 -1
- package/src/workflows/default/WORKFLOW.md +12 -5
- package/src/workflows/default/workflow.json +0 -1
- package/src/workflows/solo/WORKFLOW.md +15 -0
- package/src/workflows/solo/workflow.json +7 -0
- package/vendor/ink/build/ink.js +54 -8
- package/vendor/ink/build/output.js +6 -1
- package/src/agents/scheduler-task.md +0 -3
- package/src/agents/web-researcher/AGENT.md +0 -3
- package/src/agents/web-researcher/agent.json +0 -6
- package/src/agents/webhook-handler.md +0 -3
- package/src/hooks/lib/permission-rules.cjs +0 -170
- package/src/hooks/lib/settings-loader.cjs +0 -112
- package/src/lib/hook-pipe-path.cjs +0 -10
- package/src/rules/bridge/00-common.md +0 -5
- package/src/rules/bridge/30-explorer.md +0 -4
- package/src/rules/lead/00-tool-lead.md +0 -5
- package/src/rules/shared/00-language.md +0 -3
- package/src/runtime/agent/orchestrator/tools/builtin/native-edit-runner.mjs +0 -110
- package/src/runtime/agent/orchestrator/tools/mutation-content-cache.mjs +0 -67
- package/src/runtime/channels/lib/hook-pipe-server.mjs +0 -671
- package/src/runtime/memory/lib/bridge-trace-queries.mjs +0 -120
- package/src/runtime/shared/llm/pid-cleanup.mjs +0 -27
- package/src/standalone/bridge-tool.mjs +0 -1414
- package/src/tui/runtime/shared/process-shutdown.mjs +0 -1
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
closeSync,
|
|
3
2
|
existsSync,
|
|
4
|
-
openSync,
|
|
5
3
|
readFileSync,
|
|
6
|
-
readdirSync,
|
|
7
|
-
readSync,
|
|
8
|
-
statSync,
|
|
9
4
|
} from 'fs';
|
|
10
|
-
import { homedir } from 'os';
|
|
11
5
|
import { join } from 'path';
|
|
12
6
|
import { updateJsonAtomicSync } from '../../../shared/atomic-file.mjs';
|
|
13
7
|
import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
|
|
@@ -16,12 +10,10 @@ import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
|
|
|
16
10
|
const CACHE_FILE = 'gateway-oauth-usage-cache.json';
|
|
17
11
|
const LIVE_CACHE_TTL_MS = 60_000;
|
|
18
12
|
const DISK_CACHE_TTL_MS = 10 * 60_000;
|
|
13
|
+
const STALE_DISK_CACHE_TTL_MS = 7 * 24 * 60 * 60_000;
|
|
19
14
|
const NEGATIVE_CACHE_TTL_MS = 5 * 60_000;
|
|
20
15
|
const FETCH_TIMEOUT_MS = 4500;
|
|
21
16
|
const WARN_TTL_MS = 5 * 60_000;
|
|
22
|
-
const MAX_ROLLOUT_FILES = 8;
|
|
23
|
-
const MAX_ROLLOUT_SCAN_FILES = 2500;
|
|
24
|
-
const MAX_TAIL_BYTES = 2 * 1024 * 1024;
|
|
25
17
|
|
|
26
18
|
const memoryCache = new Map();
|
|
27
19
|
const inflight = new Map();
|
|
@@ -55,6 +47,17 @@ function routeKey(routeInfo = {}) {
|
|
|
55
47
|
return `${providerKey(routeInfo)}\u0001${String(routeInfo?.model || '')}`;
|
|
56
48
|
}
|
|
57
49
|
|
|
50
|
+
function cacheModelId(value) {
|
|
51
|
+
const model = cleanString(value);
|
|
52
|
+
if (!model) return null;
|
|
53
|
+
// Route cache keys are model identifiers, not free-form display/user text.
|
|
54
|
+
// A malformed route once copied a user prompt into the provider-wide OAuth
|
|
55
|
+
// cache; keeping cache keys/display model IDs single-token prevents that
|
|
56
|
+
// poison from persisting or winning provider fallback lookups.
|
|
57
|
+
if (model.length > 160 || /\s/.test(model)) return null;
|
|
58
|
+
return model;
|
|
59
|
+
}
|
|
60
|
+
|
|
58
61
|
function cachePath() {
|
|
59
62
|
return join(resolvePluginData(), CACHE_FILE);
|
|
60
63
|
}
|
|
@@ -134,17 +137,41 @@ function freshSnapshot(snapshot, ttlMs) {
|
|
|
134
137
|
return snapshot;
|
|
135
138
|
}
|
|
136
139
|
|
|
137
|
-
|
|
140
|
+
function newestProviderSnapshot(entries, provider, ttlMs) {
|
|
141
|
+
const providerOnly = String(provider || '').toLowerCase();
|
|
142
|
+
if (!providerOnly) return null;
|
|
143
|
+
const routePrefix = `${providerOnly}\u0001`;
|
|
144
|
+
let best = null;
|
|
145
|
+
let bestAt = 0;
|
|
146
|
+
const iterable = entries instanceof Map ? entries.entries() : Object.entries(entries || {});
|
|
147
|
+
for (const [key, snapshot] of iterable) {
|
|
148
|
+
if (key !== providerOnly && !String(key).startsWith(routePrefix)) continue;
|
|
149
|
+
const fresh = freshSnapshot(snapshot, ttlMs);
|
|
150
|
+
const at = num(fresh?.cachedAt, 0);
|
|
151
|
+
if (fresh && at >= bestAt) {
|
|
152
|
+
best = fresh;
|
|
153
|
+
bestAt = at;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return best;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function readCachedOAuthUsageSnapshot(routeInfo, options = {}) {
|
|
138
160
|
const key = routeKey(routeInfo);
|
|
139
161
|
const providerOnlyKey = providerKey(routeInfo);
|
|
162
|
+
const diskTtlMs = options?.allowStale === true
|
|
163
|
+
? STALE_DISK_CACHE_TTL_MS
|
|
164
|
+
: DISK_CACHE_TTL_MS;
|
|
140
165
|
const mem = freshSnapshot(memoryCache.get(key), LIVE_CACHE_TTL_MS)
|
|
141
|
-
|| freshSnapshot(memoryCache.get(providerOnlyKey), LIVE_CACHE_TTL_MS)
|
|
166
|
+
|| freshSnapshot(memoryCache.get(providerOnlyKey), LIVE_CACHE_TTL_MS)
|
|
167
|
+
|| newestProviderSnapshot(memoryCache, providerOnlyKey, LIVE_CACHE_TTL_MS);
|
|
142
168
|
if (mem) return mem;
|
|
143
169
|
|
|
144
170
|
const raw = readJsonFile(cachePath());
|
|
145
171
|
const routes = raw?.routes && typeof raw.routes === 'object' ? raw.routes : {};
|
|
146
|
-
return freshSnapshot(routes[key],
|
|
147
|
-
|| freshSnapshot(routes[providerOnlyKey],
|
|
172
|
+
return freshSnapshot(routes[key], diskTtlMs)
|
|
173
|
+
|| freshSnapshot(routes[providerOnlyKey], diskTtlMs)
|
|
174
|
+
|| newestProviderSnapshot(routes, providerOnlyKey, diskTtlMs)
|
|
148
175
|
|| null;
|
|
149
176
|
}
|
|
150
177
|
|
|
@@ -366,105 +393,16 @@ function normalizeAnthropicUsage(data, source = 'anthropic-oauth') {
|
|
|
366
393
|
};
|
|
367
394
|
}
|
|
368
395
|
|
|
369
|
-
function parseStatuslineRateLimits(raw, source) {
|
|
370
|
-
if (!raw || typeof raw !== 'object') return null;
|
|
371
|
-
const rateLimits = raw.rate_limits || raw.rateLimits;
|
|
372
|
-
if (!rateLimits || typeof rateLimits !== 'object') return null;
|
|
373
|
-
const windows = [
|
|
374
|
-
windowFromPercent('5H', rateLimits.five_hour || rateLimits.primary, source),
|
|
375
|
-
windowFromPercent('7D', rateLimits.seven_day || rateLimits.secondary, source),
|
|
376
|
-
].filter(Boolean);
|
|
377
|
-
if (!windows.length) return null;
|
|
378
|
-
return { quotaWindows: windows, source };
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
function tailFileText(file, maxBytes = MAX_TAIL_BYTES) {
|
|
382
|
-
let fd = null;
|
|
383
|
-
try {
|
|
384
|
-
const st = statSync(file);
|
|
385
|
-
const size = st.size || 0;
|
|
386
|
-
const start = Math.max(0, size - maxBytes);
|
|
387
|
-
const len = size - start;
|
|
388
|
-
const buf = Buffer.alloc(len);
|
|
389
|
-
fd = openSync(file, 'r');
|
|
390
|
-
readSync(fd, buf, 0, len, start);
|
|
391
|
-
return buf.toString('utf8');
|
|
392
|
-
} catch {
|
|
393
|
-
return '';
|
|
394
|
-
} finally {
|
|
395
|
-
if (fd != null) {
|
|
396
|
-
try { closeSync(fd); } catch {}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
function newestRolloutFiles(root) {
|
|
402
|
-
const out = [];
|
|
403
|
-
const stack = [root];
|
|
404
|
-
let seen = 0;
|
|
405
|
-
while (stack.length && seen < MAX_ROLLOUT_SCAN_FILES) {
|
|
406
|
-
const dir = stack.pop();
|
|
407
|
-
let entries = [];
|
|
408
|
-
try { entries = readdirSync(dir, { withFileTypes: true }); } catch { continue; }
|
|
409
|
-
for (const ent of entries) {
|
|
410
|
-
if (seen++ >= MAX_ROLLOUT_SCAN_FILES) break;
|
|
411
|
-
const full = join(dir, ent.name);
|
|
412
|
-
if (ent.isDirectory()) {
|
|
413
|
-
stack.push(full);
|
|
414
|
-
} else if (ent.isFile() && /^rollout-.*\.jsonl$/i.test(ent.name)) {
|
|
415
|
-
try {
|
|
416
|
-
const st = statSync(full);
|
|
417
|
-
out.push({ file: full, mtimeMs: st.mtimeMs || 0 });
|
|
418
|
-
} catch {}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
return out
|
|
423
|
-
.sort((a, b) => b.mtimeMs - a.mtimeMs)
|
|
424
|
-
.slice(0, MAX_ROLLOUT_FILES)
|
|
425
|
-
.map(x => x.file);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
function latestCodexRateLimitsFromRollout() {
|
|
429
|
-
const root = join(homedir(), '.codex', 'sessions');
|
|
430
|
-
if (!existsSync(root)) return null;
|
|
431
|
-
for (const file of newestRolloutFiles(root)) {
|
|
432
|
-
const lines = tailFileText(file).split(/\r?\n/).filter(Boolean);
|
|
433
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
434
|
-
try {
|
|
435
|
-
const row = JSON.parse(lines[i]);
|
|
436
|
-
const rateLimits = row?.payload?.rate_limits || row?.rate_limits;
|
|
437
|
-
const snap = normalizeCodexRateLimits(rateLimits, 'openai-codex-rollout');
|
|
438
|
-
if (snap && hasFutureWindow(snap)) return snap;
|
|
439
|
-
} catch {}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
return null;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
396
|
function latestClaudeStatuslineUsage() {
|
|
446
|
-
// Standalone CLI must not borrow
|
|
397
|
+
// Standalone CLI must not borrow a host-agent rendered statusline cache.
|
|
447
398
|
// Anthropic quota should come from the OAuth usage endpoint above.
|
|
448
399
|
return null;
|
|
449
400
|
}
|
|
450
401
|
|
|
451
|
-
function grokCliIdentity(accessToken = '') {
|
|
452
|
-
const raw = readJsonFile(join(homedir(), '.grok', 'auth.json'));
|
|
453
|
-
if (!raw || typeof raw !== 'object') return {};
|
|
454
|
-
const entries = Object.values(raw).filter(v => v && typeof v === 'object');
|
|
455
|
-
const exact = accessToken ? entries.find(v => v.key === accessToken || v.access_token === accessToken) : null;
|
|
456
|
-
const entry = exact || entries.find(v => v.key || v.access_token) || null;
|
|
457
|
-
if (!entry) return {};
|
|
458
|
-
return {
|
|
459
|
-
userId: entry.user_id || entry.userId || entry.principal_id || entry.principalId || '',
|
|
460
|
-
token: entry.key || entry.access_token || entry.accessToken || '',
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
|
|
464
402
|
async function fetchOpenAICodexUsage(providerObj) {
|
|
465
403
|
const auth = await providerObj?.ensureAuth?.({ reason: 'usage' });
|
|
466
404
|
const token = auth?.access_token || auth?.accessToken;
|
|
467
|
-
if (!token) return
|
|
405
|
+
if (!token) return null;
|
|
468
406
|
const res = await fetch('https://chatgpt.com/backend-api/wham/usage', fetchOptions({
|
|
469
407
|
Authorization: `Bearer ${token}`,
|
|
470
408
|
originator: 'codex_cli_rs',
|
|
@@ -472,9 +410,9 @@ async function fetchOpenAICodexUsage(providerObj) {
|
|
|
472
410
|
'OpenAI-Beta': 'responses=experimental',
|
|
473
411
|
Accept: 'application/json',
|
|
474
412
|
}));
|
|
475
|
-
if (!res.ok) throw new Error(`
|
|
413
|
+
if (!res.ok) throw new Error(`openai-oauth usage ${res.status}`);
|
|
476
414
|
const data = await res.json();
|
|
477
|
-
return normalizeOpenAIWhamUsage(data)
|
|
415
|
+
return normalizeOpenAIWhamUsage(data);
|
|
478
416
|
}
|
|
479
417
|
|
|
480
418
|
async function fetchAnthropicUsage(providerObj) {
|
|
@@ -497,8 +435,7 @@ async function fetchGrokUsage(providerObj, routeInfo) {
|
|
|
497
435
|
const auth = await providerObj?.ensureAuth?.({ reason: 'usage' });
|
|
498
436
|
const token = auth?.access_token || auth?.accessToken || auth?.key;
|
|
499
437
|
if (!token) return null;
|
|
500
|
-
const
|
|
501
|
-
const userId = auth?.user_id || auth?.userId || auth?.principal_id || auth?.principalId || cliIdentity.userId || '';
|
|
438
|
+
const userId = auth?.user_id || auth?.userId || auth?.principal_id || auth?.principalId || '';
|
|
502
439
|
const cliHeaders = {
|
|
503
440
|
Authorization: `Bearer ${token}`,
|
|
504
441
|
'X-XAI-Token-Auth': 'xai-grok-cli',
|
|
@@ -583,7 +520,6 @@ export async function fetchOAuthUsageSnapshot(routeInfo, providerObj, log = () =
|
|
|
583
520
|
snapshot = await fetchGrokUsage(providerObj, routeInfo);
|
|
584
521
|
}
|
|
585
522
|
} catch (err) {
|
|
586
|
-
if (provider === 'openai-oauth') snapshot = latestCodexRateLimitsFromRollout();
|
|
587
523
|
if (provider === 'anthropic-oauth') snapshot = latestClaudeStatuslineUsage();
|
|
588
524
|
if (!snapshot) {
|
|
589
525
|
warnThrottled(log, `oauth-usage:${provider}`, `gateway ${provider} usage fetch unavailable: ${err?.message || err}`);
|
|
@@ -596,17 +532,26 @@ export async function fetchOAuthUsageSnapshot(routeInfo, providerObj, log = () =
|
|
|
596
532
|
return null;
|
|
597
533
|
}
|
|
598
534
|
|
|
599
|
-
const
|
|
535
|
+
const model = cacheModelId(routeInfo?.model) || cacheModelId(snapshot.model);
|
|
536
|
+
const providerSnapshot = {
|
|
600
537
|
...snapshot,
|
|
601
538
|
provider: routeInfo?.provider || snapshot.provider || provider,
|
|
602
|
-
model: routeInfo?.model || snapshot.model || null,
|
|
603
539
|
cachedAt: Date.now(),
|
|
604
540
|
};
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
541
|
+
delete providerSnapshot.model;
|
|
542
|
+
|
|
543
|
+
const routeSnapshot = model
|
|
544
|
+
? { ...providerSnapshot, model }
|
|
545
|
+
: providerSnapshot;
|
|
546
|
+
|
|
547
|
+
if (model) {
|
|
548
|
+
const normalizedKey = `${provider}\u0001${model}`;
|
|
549
|
+
memoryCache.set(normalizedKey, routeSnapshot);
|
|
550
|
+
writeSnapshotCache(normalizedKey, routeSnapshot);
|
|
551
|
+
}
|
|
552
|
+
memoryCache.set(providerOnly, providerSnapshot);
|
|
553
|
+
writeSnapshotCache(providerOnly, providerSnapshot);
|
|
554
|
+
return routeSnapshot;
|
|
610
555
|
})().finally(() => {
|
|
611
556
|
inflight.delete(key);
|
|
612
557
|
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Lightweight preset table shared by config/registry without importing the
|
|
2
|
+
// OpenAI SDK or compat runtime implementation.
|
|
3
|
+
export const OPENAI_COMPAT_PRESETS = {
|
|
4
|
+
deepseek: {
|
|
5
|
+
baseURL: 'https://api.deepseek.com',
|
|
6
|
+
defaultModel: 'deepseek-v4-pro',
|
|
7
|
+
},
|
|
8
|
+
xai: {
|
|
9
|
+
baseURL: 'https://api.x.ai/v1',
|
|
10
|
+
defaultModel: 'grok-4.3',
|
|
11
|
+
},
|
|
12
|
+
// OpenCode Go - low-cost coding-model subscription gateway.
|
|
13
|
+
'opencode-go': {
|
|
14
|
+
baseURL: 'https://opencode.ai/zen/go/v1',
|
|
15
|
+
defaultModel: 'glm-5.2',
|
|
16
|
+
},
|
|
17
|
+
ollama: {
|
|
18
|
+
baseURL: 'http://localhost:11434/v1',
|
|
19
|
+
defaultModel: 'llama3.3:latest',
|
|
20
|
+
},
|
|
21
|
+
lmstudio: {
|
|
22
|
+
baseURL: 'http://localhost:1234/v1',
|
|
23
|
+
defaultModel: 'default',
|
|
24
|
+
},
|
|
25
|
+
};
|