mixdog 1.1.1 → 1.2.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 +1 -0
- package/package.json +2 -2
- package/scripts/lib/run-node-tests.mjs +9 -0
- package/scripts/prune-desktop-runtime.mjs +3 -0
- package/scripts/release-paths.mjs +39 -2
- package/scripts/test-direct.mjs +4 -2
- package/src/defaults/shipped-history.json +6 -0
- package/src/defaults/skills/setup/references/actions.md +5 -2
- package/src/defaults/skills/visualize/SKILL.md +157 -0
- package/src/defaults/skills/visualize/references/craft.md +88 -0
- package/src/headless-command.mjs +56 -3
- package/src/headless-exec.mjs +17 -1
- package/src/headless-role.mjs +2 -2
- package/src/help.mjs +2 -0
- package/src/lib/rules-builder.cjs +0 -23
- package/src/rules/lead/LEAD.md +2 -2
- package/src/rules/shared/70-delivery.md +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +17 -11
- package/src/runtime/agent/orchestrator/config-storage.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +9 -1
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +47 -7
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +51 -8
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +25 -5
- package/src/runtime/agent/orchestrator/mcp/client.mjs +348 -122
- package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +12 -4
- package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +8 -40
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +51 -12
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +37 -2
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +67 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +521 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +251 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +69 -102
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +15 -1
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +10 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +36 -3
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +12 -11
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +16 -1
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +11 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +11 -8
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +18 -11
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +362 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +253 -0
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +12 -14
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/diagnostic.mjs +1 -7
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/refusal.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +17 -7
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +37 -16
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +90 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +32 -3
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +1 -5
- package/src/runtime/agent/orchestrator/session/message-ids.mjs +123 -0
- package/src/runtime/agent/orchestrator/session/message-ids.test-support.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +29 -19
- package/src/runtime/agent/orchestrator/session/read-dedup.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +23 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +28 -8
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +140 -0
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +52 -2
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +32 -22
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-cache-policy.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +31 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +11 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +9 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +80 -66
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +16 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +137 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +11 -10
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +21 -11
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +56 -13
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +58 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +25 -1
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +78 -5
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +0 -10
- package/src/runtime/attachments/store.mjs +38 -0
- package/src/runtime/channels/index.mjs +1 -5
- package/src/runtime/channels/lib/runtime-paths.mjs +8 -23
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -13
- package/src/runtime/channels/lib/worker-ipc.mjs +2 -2
- package/src/runtime/channels/lib/worker-main.mjs +4 -34
- package/src/runtime/shared/atomic-file.mjs +8 -2
- package/src/runtime/shared/best-effort-stderr.mjs +8 -0
- package/src/runtime/shared/code-graph-state.mjs +12 -0
- package/src/runtime/shared/defaults-separation.mjs +2 -0
- package/src/runtime/shared/git-runner-worker.mjs +3 -2
- package/src/runtime/shared/git-runner.mjs +4 -3
- package/src/runtime/shared/llm/default-context-window.mjs +6 -0
- package/src/runtime/shared/llm/model-catalog-projection.mjs +5 -4
- package/src/runtime/shared/llm/model-catalog.mjs +240 -118
- package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +156 -0
- package/src/runtime/shared/llm/provider-seed-rosters.mjs +130 -0
- package/src/runtime/shared/model-proxy-mode.d.mts +3 -0
- package/src/runtime/shared/model-proxy-mode.mjs +19 -0
- package/src/runtime/shared/provider-accounts.mjs +2 -2
- package/src/runtime/shared/provider-api-key.mjs +21 -1
- package/src/runtime/shared/schedule-model-ref.mjs +11 -2
- package/src/runtime/shared/semver.d.mts +1 -0
- package/src/runtime/shared/semver.mjs +57 -0
- package/src/runtime/shared/session-usage-totals.mjs +19 -0
- package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
- package/src/runtime/shared/singleton-owner.mjs +36 -6
- package/src/runtime/shared/statusline/statusline-segments.mjs +68 -14
- package/src/runtime/shared/tool-surface.mjs +9 -2
- package/src/runtime/shared/tool-work-units.mjs +14 -0
- package/src/runtime/shared/transcript-metadata.mjs +17 -1
- package/src/runtime/shared/turn-changes.mjs +791 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +346 -12
- package/src/runtime/shared/turn-snapshot.mjs +690 -81
- package/src/runtime/shared/turn-worktree-snapshot.mjs +161 -11
- package/src/runtime/shared/update-checker.mjs +2 -31
- package/src/runtime/shared/worktrees/cache-cleanups.mjs +52 -0
- package/src/runtime/shared/worktrees/contract.mjs +551 -0
- package/src/runtime/shared/worktrees/disk.mjs +57 -0
- package/src/runtime/shared/worktrees/git.mjs +247 -0
- package/src/runtime/shared/worktrees/include.mjs +480 -0
- package/src/runtime/shared/worktrees/lock.mjs +46 -0
- package/src/runtime/shared/worktrees/maintenance.mjs +96 -0
- package/src/runtime/shared/worktrees/manager.mjs +1215 -0
- package/src/runtime/shared/worktrees/merge.mjs +182 -0
- package/src/runtime/shared/worktrees/owner.mjs +46 -0
- package/src/runtime/shared/worktrees/paths.mjs +62 -0
- package/src/runtime/shared/worktrees/registry.mjs +110 -0
- package/src/runtime/shared/worktrees/settings.mjs +84 -0
- package/src/runtime/shared/worktrees/slug.mjs +62 -0
- package/src/runtime/shared/worktrees/test-support.mjs +96 -0
- package/src/runtime/visualize-bridge/client.mjs +181 -0
- package/src/runtime/visualize-bridge/tool-defs.mjs +97 -0
- package/src/session-runtime/boot/apis.mjs +35 -0
- package/src/session-runtime/boot/begin.mjs +0 -2
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +20 -0
- package/src/session-runtime/boot/infrastructure.mjs +1 -0
- package/src/session-runtime/boot/session.mjs +1 -0
- package/src/session-runtime/boot/tools.mjs +9 -4
- package/src/session-runtime/config-lifecycle.mjs +10 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +11 -1
- package/src/session-runtime/global-extensions.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +27 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +32 -1
- package/src/session-runtime/internal-tool-executor.mjs +9 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +8 -1
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +5 -0
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +21 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +16 -0
- package/src/session-runtime/mcp-glue/connect.mjs +11 -6
- package/src/session-runtime/mcp-glue/server-catalog.mjs +7 -3
- package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
- package/src/session-runtime/model-route/route-persist.mjs +3 -0
- package/src/session-runtime/model-route/set-route.mjs +15 -2
- package/src/session-runtime/notification-bus.mjs +9 -1
- package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
- package/src/session-runtime/resource-extension-sync.mjs +30 -7
- package/src/session-runtime/resource-mcp-api.mjs +27 -10
- package/src/session-runtime/route-resolution.mjs +10 -1
- package/src/session-runtime/route-state.mjs +16 -2
- package/src/session-runtime/runtime-bootstrap.mjs +0 -4
- package/src/session-runtime/runtime-core.mjs +5 -0
- package/src/session-runtime/runtime-facade.mjs +8 -0
- package/src/session-runtime/runtime-paths.mjs +0 -1
- package/src/session-runtime/runtime-review-api.mjs +9 -0
- package/src/session-runtime/services/agent-tool/helpers.mjs +5 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +3 -0
- package/src/session-runtime/services/agent-tool/job-views/job-lookup.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-views/spawn-meta.mjs +1 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +15 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +1 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -7
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +2 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -0
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +1 -0
- package/src/session-runtime/services/agent-tool.mjs +1 -0
- package/src/session-runtime/services/channel-worker.mjs +1 -1
- package/src/session-runtime/services/daemon-candidate.mjs +3 -2
- package/src/session-runtime/services/daemon-crash-capture/spawn-capture.mjs +55 -0
- package/src/session-runtime/session-create/session-options.mjs +10 -1
- package/src/session-runtime/session-turn-api.mjs +1 -0
- package/src/session-runtime/settings-api.mjs +4 -2
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -2
- package/src/session-runtime/settings-profile-api.mjs +27 -2
- package/src/session-runtime/settings-worktree-api.mjs +17 -0
- package/src/session-runtime/setup-tool/executor.mjs +11 -4
- package/src/session-runtime/setup-tool/settings-contract.mjs +3 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +31 -3
- package/src/session-runtime/starter-guide-state.mjs +62 -0
- package/src/session-runtime/turn/agent-ops.mjs +12 -1
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +13 -3
- package/src/session-runtime/turn/turn-run/snapshot-tracker.mjs +20 -15
- package/src/session-runtime/turn/turn-run/turn-open.mjs +4 -5
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +29 -1
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +6 -1
- package/src/session-runtime/turn/turn-run.mjs +6 -7
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -3
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -2
- package/src/session-runtime/workspace/admission-gate.mjs +197 -0
- package/src/session-runtime/workspace/project-branches.mjs +136 -0
- package/src/session-runtime/workspace/transition-steps.mjs +364 -0
- package/src/session-runtime/workspace/transitions.mjs +651 -0
- package/src/session-runtime/workspace/workspace-state.mjs +112 -0
- package/src/standalone/channel-binding.mjs +1 -2
- package/src/standalone/channel-transport/call-dispatch.mjs +4 -10
- package/src/standalone/channel-transport/http-routes.mjs +17 -0
- package/src/standalone/channel-transport.mjs +13 -1
- package/src/standalone/daemon-channels-loader.mjs +2 -3
- package/src/standalone/daemon-desktop-runtime.mjs +1 -0
- package/src/standalone/daemon-owner.mjs +372 -0
- package/src/standalone/daemon-stored-session-views.mjs +4 -1
- package/src/standalone/daemon.mjs +139 -5
- package/src/standalone/desktop-service-registry.mjs +20 -0
- package/src/standalone/local-session-runtime.mjs +13 -78
- package/src/standalone/session-client/attachment-calls.mjs +3 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +62 -0
- package/src/standalone/session-client/lease-heartbeat.mjs +47 -0
- package/src/standalone/session-client.mjs +104 -13
- package/src/standalone/session-protocol.mjs +17 -0
- package/src/standalone/session-proxy.mjs +3 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-rehydrate.mjs +1 -0
- package/src/standalone/session-service/entries/lifecycle.mjs +6 -0
- package/src/standalone/session-service/projection/revisions.mjs +2 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +149 -19
- package/src/standalone/session-service/projection/workspace.mjs +14 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +11 -3
- package/src/standalone/session-transport/call-route.mjs +13 -0
- package/src/standalone/session-transport/client-registry/client-grace.mjs +45 -3
- package/src/standalone/session-transport/client-registry/registration-replays.mjs +1 -0
- package/src/standalone/session-transport/client-registry.mjs +20 -3
- package/src/standalone/session-transport/routes.mjs +79 -2
- package/src/standalone/session-transport/stack.mjs +2 -0
- package/src/standalone/session-transport.mjs +24 -1
- package/src/tui/app/message-selector.mjs +2 -1
- package/src/tui/app/model-options.mjs +35 -5
- package/src/tui/app/model-picker/provider-models-list.mjs +2 -2
- package/src/tui/app/model-picker.mjs +4 -2
- package/src/tui/dist/index.mjs +332 -36
- package/src/tui/index.jsx +10 -2
- package/src/tui/session/compaction-view.mjs +147 -0
- package/src/tui/session/context-state.mjs +6 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/quota-resume.mjs +2 -1
- package/src/tui/session/session-api/commands.mjs +10 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +12 -8
- package/src/tui/session/session-api/intake/rewind.mjs +2 -1
- package/src/tui/session/session-api/integrations.mjs +18 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +6 -1
- package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -0
- package/src/tui/session/session-api/lifecycle/resume.mjs +3 -0
- package/src/tui/session/session-api/routes.mjs +10 -1
- package/src/tui/session/session-api/settings.mjs +2 -0
- package/src/tui/session/session-api/shared.mjs +10 -6
- package/src/tui/session/session-api/worktree.mjs +60 -0
- package/src/tui/session/session-api.mjs +2 -0
- package/src/tui/session/session-flow/auto-clear.mjs +31 -12
- package/src/tui/session/session-flow/drain.mjs +15 -1
- package/src/tui/session/session-flow/session-reset.mjs +4 -3
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/transcript-intake.mjs +14 -5
- package/src/tui/session/turn-stream.mjs +32 -4
- package/src/tui/session/turn-tool-cards.mjs +10 -2
- package/src/tui/session/turn.mjs +39 -10
- package/src/runtime/channels/tool-defs.mjs +0 -17
|
@@ -8,9 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { createHash, randomBytes } from 'node:crypto';
|
|
10
10
|
import {
|
|
11
|
+
closeSync,
|
|
11
12
|
existsSync,
|
|
13
|
+
fstatSync,
|
|
12
14
|
mkdirSync,
|
|
15
|
+
openSync,
|
|
13
16
|
readFileSync,
|
|
17
|
+
readSync,
|
|
14
18
|
renameSync,
|
|
15
19
|
statSync,
|
|
16
20
|
unlinkSync,
|
|
@@ -303,6 +307,40 @@ function readAttachmentText(value) {
|
|
|
303
307
|
return readAttachmentBuffer(value).toString('utf8');
|
|
304
308
|
}
|
|
305
309
|
|
|
310
|
+
/**
|
|
311
|
+
* A referenced blob's UTF-8 text when the blob on disk holds at most
|
|
312
|
+
* `maxBytes`, else null. The size comes from the opened file, never from the
|
|
313
|
+
* reference's claimed sizeBytes, and at most `maxBytes + 1` bytes are read, so
|
|
314
|
+
* a blob that grows between the check and the read is rejected too. Missing,
|
|
315
|
+
* invalid or tampered blobs throw like readAttachmentBuffer.
|
|
316
|
+
*/
|
|
317
|
+
export function readAttachmentTextWithin(value, maxBytes) {
|
|
318
|
+
const ref = typeof value === 'string' ? value : value?.attachmentRef;
|
|
319
|
+
const fd = openSync(attachmentPath(ref), 'r');
|
|
320
|
+
try {
|
|
321
|
+
const info = fstatSync(fd);
|
|
322
|
+
if (!info.isFile() || info.size <= 0) {
|
|
323
|
+
throw Object.assign(new Error('prompt attachment blob is invalid'), { code: ATTACHMENT_INVALID });
|
|
324
|
+
}
|
|
325
|
+
if (info.size > maxBytes) return null;
|
|
326
|
+
const buffer = Buffer.alloc(info.size + 1);
|
|
327
|
+
let length = 0;
|
|
328
|
+
while (length < buffer.length) {
|
|
329
|
+
const read = readSync(fd, buffer, length, buffer.length - length, length);
|
|
330
|
+
if (read === 0) break;
|
|
331
|
+
length += read;
|
|
332
|
+
}
|
|
333
|
+
if (length > maxBytes) return null;
|
|
334
|
+
const bytes = buffer.subarray(0, length);
|
|
335
|
+
if (attachmentRefForBuffer(bytes) !== ref) {
|
|
336
|
+
throw Object.assign(new Error('prompt attachment integrity check failed'), { code: ATTACHMENT_INTEGRITY });
|
|
337
|
+
}
|
|
338
|
+
return bytes.toString('utf8');
|
|
339
|
+
} finally {
|
|
340
|
+
closeSync(fd);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
306
344
|
export function attachmentTextForPart(part) {
|
|
307
345
|
if (!isAttachmentReference(part)) return typeof part?.text === 'string' ? part.text : '';
|
|
308
346
|
const text = readAttachmentText(part);
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
// Thin facade for the channels worker runtime. The implementation was split
|
|
2
2
|
// out into ./lib/worker-main.mjs plus focused lib/ modules; this file preserves
|
|
3
|
-
// the
|
|
3
|
+
// the current worker API and boot side-effects by re-exporting from worker-main.
|
|
4
4
|
// Kept as the channels worker entrypoint the daemon loads.
|
|
5
5
|
export {
|
|
6
|
-
TOOL_DEFS,
|
|
7
6
|
handleToolCall,
|
|
8
|
-
handleToolCallWithBridgeRetry,
|
|
9
|
-
init,
|
|
10
|
-
instructions,
|
|
11
7
|
isChannelBridgeActive,
|
|
12
8
|
isChannelsDegraded,
|
|
13
9
|
start,
|
|
@@ -114,8 +114,7 @@ function getControlResponsePath(instanceId) {
|
|
|
114
114
|
function getStopFlagPath(instanceId) {
|
|
115
115
|
return join(RUNTIME_ROOT, `stop-${sanitize(instanceId)}.flag`);
|
|
116
116
|
}
|
|
117
|
-
// Pure metadata-advert read
|
|
118
|
-
// advert is never evicted here. A transient read during an atomic rename may
|
|
117
|
+
// Pure metadata-advert read. A transient read during an atomic rename may
|
|
119
118
|
// yield empty/partial content: retry once after 50 ms before reporting the
|
|
120
119
|
// advert as unreadable.
|
|
121
120
|
function readActiveInstance() {
|
|
@@ -141,8 +140,6 @@ function buildActiveInstanceState(instanceId, meta) {
|
|
|
141
140
|
supervisor_started_at: Date.now(),
|
|
142
141
|
server_started_at: Date.now(),
|
|
143
142
|
updatedAt: Date.now(),
|
|
144
|
-
turnEndFile: getTurnEndPath(instanceId),
|
|
145
|
-
statusFile: getStatusPath(instanceId),
|
|
146
143
|
...metaFields(meta),
|
|
147
144
|
};
|
|
148
145
|
}
|
|
@@ -193,26 +190,14 @@ function refreshActiveInstance(instanceId, meta, options) {
|
|
|
193
190
|
(curRaw) => {
|
|
194
191
|
const prevForPreserve = curRaw;
|
|
195
192
|
const prev = activeInstanceStaleReason(curRaw) ? null : curRaw;
|
|
196
|
-
// CAS guard (opt-in via options.onlyIfOwned): heartbeat/refresh ticks
|
|
197
|
-
// check ownership OUTSIDE this lock, so a newer session can claim the
|
|
198
|
-
// seat between that check and this locked update. Without this re-read,
|
|
199
|
-
// the tick would overwrite the newer owner's instanceId (TOCTOU
|
|
200
|
-
// re-steal -> ownership ping-pong / double provider connections).
|
|
201
|
-
// Returning undefined aborts the update with no write. Explicit claims
|
|
202
|
-
// (boot, claimBridgeOwnership) omit the option and stay last-wins.
|
|
203
|
-
if (options?.onlyIfOwned && (!prev?.instanceId || prev.instanceId !== instanceId)) {
|
|
204
|
-
return undefined;
|
|
205
|
-
}
|
|
206
|
-
// CAS guard (opt-in via options.onlyIfVacant): auto-start claim-if-vacant.
|
|
207
|
-
// Abort the write when a live (non-stale) owner OTHER than us already holds
|
|
208
|
-
// the seat — an auto-start must never steal from a live owner. A stale/dead
|
|
209
|
-
// prior owner leaves prev=null above, so it does NOT block the claim; an
|
|
210
|
-
// absent seat (prev=null) is claimable too.
|
|
211
|
-
if (options?.onlyIfVacant && prev?.instanceId && prev.instanceId !== instanceId) {
|
|
212
|
-
return undefined;
|
|
213
|
-
}
|
|
214
193
|
// Drop stale fields (pid/startedAt) written by older server versions.
|
|
215
|
-
const {
|
|
194
|
+
const {
|
|
195
|
+
pid: _legacyPid,
|
|
196
|
+
startedAt: _legacyStartedAt,
|
|
197
|
+
turnEndFile: _turnEndFile,
|
|
198
|
+
statusFile: _statusFile,
|
|
199
|
+
...prevRest
|
|
200
|
+
} = prev ?? {};
|
|
216
201
|
const identity = buildRuntimeIdentity();
|
|
217
202
|
// server_started_at tracks the CURRENT server_pid's start time so the
|
|
218
203
|
// dev-sync barrier can verify the CHILD's freshness (the supervisor's
|
|
@@ -82,12 +82,6 @@ function createToolDispatch({ isChannelsDegraded, lifecycle }) {
|
|
|
82
82
|
};
|
|
83
83
|
break;
|
|
84
84
|
}
|
|
85
|
-
case 'rebind_current_transcript': {
|
|
86
|
-
// Transcript forwarding is retired with channel messaging: accept
|
|
87
|
-
// and no-op so legacy lead-side pushes never surface an error.
|
|
88
|
-
result = { content: [{ type: 'text', text: 'transcript rebind retired' }] };
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
85
|
// memory — handled by memory-service.mjs MCP
|
|
92
86
|
default:
|
|
93
87
|
result = {
|
|
@@ -105,13 +99,7 @@ function createToolDispatch({ isChannelsDegraded, lifecycle }) {
|
|
|
105
99
|
return result;
|
|
106
100
|
}
|
|
107
101
|
|
|
108
|
-
|
|
109
|
-
// pre-flush or tool-log relay — plain dispatch.
|
|
110
|
-
async function handleToolCallWithBridgeRetry(toolName, args, signal) {
|
|
111
|
-
return handleToolCall(toolName, args, signal);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return { handleToolCall, handleToolCallWithBridgeRetry };
|
|
102
|
+
return { handleToolCall };
|
|
115
103
|
}
|
|
116
104
|
|
|
117
105
|
export { createToolDispatch };
|
|
@@ -14,7 +14,7 @@ export function runWorkerIpc({
|
|
|
14
14
|
getProvider: _getProvider,
|
|
15
15
|
getConfig: _getConfig,
|
|
16
16
|
handleMemoryCallResponse,
|
|
17
|
-
|
|
17
|
+
handleToolCall,
|
|
18
18
|
bootProfile,
|
|
19
19
|
}) {
|
|
20
20
|
const sendToParent = (message) =>
|
|
@@ -94,7 +94,7 @@ export function runWorkerIpc({
|
|
|
94
94
|
_inFlightChannelCalls.set(msg.callId, ac);
|
|
95
95
|
let result;
|
|
96
96
|
try {
|
|
97
|
-
result = await
|
|
97
|
+
result = await handleToolCall(msg.name, msg.args || {}, ac.signal);
|
|
98
98
|
} finally {
|
|
99
99
|
_inFlightChannelCalls.delete(msg.callId);
|
|
100
100
|
}
|
|
@@ -4,7 +4,6 @@ import { createRequire } from 'node:module';
|
|
|
4
4
|
import { loadConfig, createProvider, DATA_DIR } from './config.mjs';
|
|
5
5
|
import { resolveVoiceRuntime } from './voice-runtime-fetcher.mjs';
|
|
6
6
|
import { whisperThreadCount } from './voice-transcription.mjs';
|
|
7
|
-
import { TOOL_DEFS } from '../tool-defs.mjs';
|
|
8
7
|
import { ensureReady, stopVoiceWhisperServer } from './whisper-server.mjs';
|
|
9
8
|
import { ensurePrivateRuntimeRoot, resolveRuntimeRoot } from '../../shared/runtime-root.mjs';
|
|
10
9
|
import { Scheduler } from './scheduler.mjs';
|
|
@@ -102,7 +101,6 @@ runWorkerBootstrap({
|
|
|
102
101
|
pruneStalePluginDataLogSiblings,
|
|
103
102
|
DEFAULT_STALE_LOG_SIBLING_MAX,
|
|
104
103
|
});
|
|
105
|
-
const INSTRUCTIONS = '';
|
|
106
104
|
|
|
107
105
|
// ── Parent notification helper ───────────────────────────────────────
|
|
108
106
|
// This worker has no MCP transport of its own. All notifications flow
|
|
@@ -129,10 +127,7 @@ let _reloadDebounce = null;
|
|
|
129
127
|
const STATUS_FILE = getStatusPath(INSTANCE_ID);
|
|
130
128
|
const statusState = new JsonStateFile(STATUS_FILE, {});
|
|
131
129
|
statusState.ensure();
|
|
132
|
-
const scheduler = new Scheduler(
|
|
133
|
-
config.nonInteractive ?? [],
|
|
134
|
-
config.interactive ?? []
|
|
135
|
-
);
|
|
130
|
+
const scheduler = new Scheduler(config.nonInteractive ?? [], config.interactive ?? []);
|
|
136
131
|
// Schedules fire as visible sessions; the session runner belongs to the
|
|
137
132
|
// session-runtime layer, so this worker entry injects it (lazy, like webhooks).
|
|
138
133
|
scheduler.setScheduleRunner(async (schedule, opts) => {
|
|
@@ -250,19 +245,12 @@ function wireEventQueueHandlers(eventQueue) {
|
|
|
250
245
|
// re-read at probe time so a stale-connected flag cannot mask a lost seat.
|
|
251
246
|
eventQueue.setOwnerGetter(() => bridgeRuntimeConnected && currentOwnerState().owned);
|
|
252
247
|
}
|
|
253
|
-
// Inbound messaging, provider interaction handlers, and channel voice-message
|
|
254
|
-
// transcription are DELETED with Discord/Telegram (user decision: PWA replaces
|
|
255
|
-
// channels). The headless provider emits no events, so nothing wires here.
|
|
256
|
-
// Tool dispatch in worker mode goes through the IPC `call` handler at the
|
|
257
|
-
// bottom of this file (parent's `callWorker` → `handleToolCall`). There is no
|
|
258
|
-
// orphan worker-level MCP Server: the parent (server.mjs) owns the single
|
|
259
|
-
// connected transport and routes CallTool through the IPC `call` path.
|
|
260
248
|
// ── Worker/HTTP tool-call dispatch ──────────────────────────────────────────
|
|
261
249
|
// Runtime lifecycle dispatch only (activate_channel_bridge / reload_config):
|
|
262
250
|
// threaded as a lifecycle bag of lazy getters so the module reads live
|
|
263
251
|
// file-level references at call time. Used by the HTTP MCP CallTool path and
|
|
264
252
|
// the worker IPC `call` handler at the bottom of this file.
|
|
265
|
-
const { handleToolCall
|
|
253
|
+
const { handleToolCall } = createToolDispatch({
|
|
266
254
|
isChannelsDegraded,
|
|
267
255
|
lifecycle: {
|
|
268
256
|
getChannelBridgeActive: () => channelBridgeActive,
|
|
@@ -277,14 +265,6 @@ const { handleToolCall, handleToolCallWithBridgeRetry } = createToolDispatch({
|
|
|
277
265
|
reloadRuntimeConfig,
|
|
278
266
|
},
|
|
279
267
|
});
|
|
280
|
-
async function init(_sharedMcp) {
|
|
281
|
-
// _sharedMcp is no longer used. Notifications now flow via IPC to the parent
|
|
282
|
-
// (sendNotifyToParent above). The parameter is retained for backward
|
|
283
|
-
// compatibility with any caller that still passes a Server reference.
|
|
284
|
-
scheduler.setInjectHandler((channelId, name, content, options) => {
|
|
285
|
-
injectAndRecord(channelId, name, content, options);
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
268
|
function ensureConfigWatcher() {
|
|
289
269
|
if (_configWatcher) return;
|
|
290
270
|
try {
|
|
@@ -374,19 +354,9 @@ if (_isWorkerMode && process.send && process.env.MIXDOG_DAEMON_HOST !== '1') {
|
|
|
374
354
|
getProvider: () => provider,
|
|
375
355
|
getConfig: () => config,
|
|
376
356
|
handleMemoryCallResponse,
|
|
377
|
-
|
|
357
|
+
handleToolCall,
|
|
378
358
|
bootProfile,
|
|
379
359
|
});
|
|
380
360
|
}
|
|
381
361
|
|
|
382
|
-
export {
|
|
383
|
-
TOOL_DEFS,
|
|
384
|
-
handleToolCall,
|
|
385
|
-
handleToolCallWithBridgeRetry,
|
|
386
|
-
init,
|
|
387
|
-
INSTRUCTIONS as instructions,
|
|
388
|
-
isChannelBridgeActive,
|
|
389
|
-
isChannelsDegraded,
|
|
390
|
-
start,
|
|
391
|
-
stop,
|
|
392
|
-
};
|
|
362
|
+
export { handleToolCall, isChannelBridgeActive, isChannelsDegraded, start, stop };
|
|
@@ -240,6 +240,12 @@ export function writeJsonAtomicSync(filePath, value, opts = {}) {
|
|
|
240
240
|
return writeFileAtomicSync(filePath, `${JSON.stringify(value, null, opts.compact ? 0 : 2)}\n`, opts);
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
+
// Windows editors and PowerShell 5 save UTF-8 with a leading byte order mark,
|
|
244
|
+
// which JSON.parse rejects; a hand-edited state file must still load.
|
|
245
|
+
export function parseJsonText(text) {
|
|
246
|
+
return JSON.parse(text.charCodeAt(0) === 0xfeff ? text.slice(1) : text);
|
|
247
|
+
}
|
|
248
|
+
|
|
243
249
|
function recoverJsonMutationRead(error) {
|
|
244
250
|
// Missing/malformed JSON retains the existing initializer contract. An I/O
|
|
245
251
|
// or permission failure is not an empty document and must never authorize
|
|
@@ -255,7 +261,7 @@ export function updateJsonAtomicSync(filePath, mutator, opts = {}) {
|
|
|
255
261
|
() => {
|
|
256
262
|
let cur = null;
|
|
257
263
|
try {
|
|
258
|
-
cur =
|
|
264
|
+
cur = parseJsonText(readFileSync(filePath, 'utf8'));
|
|
259
265
|
} catch (error) {
|
|
260
266
|
cur = recoverJsonMutationRead(error);
|
|
261
267
|
}
|
|
@@ -336,7 +342,7 @@ export async function updateJsonAtomic(filePath, mutator, opts = {}) {
|
|
|
336
342
|
async () => {
|
|
337
343
|
let cur = null;
|
|
338
344
|
try {
|
|
339
|
-
cur =
|
|
345
|
+
cur = parseJsonText(await readFileAsync(filePath, 'utf8'));
|
|
340
346
|
} catch (error) {
|
|
341
347
|
cur = recoverJsonMutationRead(error);
|
|
342
348
|
}
|
|
@@ -74,6 +74,18 @@ export function markCodeGraphDirtyPaths(paths) {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
/** Drop the resident graph, pending dirty paths and dirty generation of one
|
|
78
|
+
* root (exact canonical match; nested roots are other roots). Returns the
|
|
79
|
+
* names of the state that was actually dropped. */
|
|
80
|
+
export function forgetCodeGraphStateRoot(root) {
|
|
81
|
+
const key = canonicalGraphCwd(root);
|
|
82
|
+
const removed = [];
|
|
83
|
+
if (codeGraphCache.delete(key)) removed.push('resident-graph');
|
|
84
|
+
if (codeGraphDirtyPaths.delete(key)) removed.push('dirty-paths');
|
|
85
|
+
if (codeGraphDirtyGen.delete(key)) removed.push('dirty-generation');
|
|
86
|
+
return removed;
|
|
87
|
+
}
|
|
88
|
+
|
|
77
89
|
export function registerCodeGraphDrain(fn) {
|
|
78
90
|
drainCodeGraphCacheFn = typeof fn === 'function' ? fn : null;
|
|
79
91
|
}
|
|
@@ -21,6 +21,7 @@ import { DEFAULTS_VERSION, DEFAULTS_VERSION_KEY, configPath, readConfig, updateC
|
|
|
21
21
|
import { DEFAULT_DISABLED_AGENT_ROSTER, disabledAgentDelta, disabledAgentIds } from './agent-route-config.mjs';
|
|
22
22
|
import { withGrandfatheredBuiltins } from './builtin-grandfathering.mjs';
|
|
23
23
|
import { DEFAULT_ORCHESTRATION_MODE, legacyWorkflowOrchestrationMode } from './orchestration.mjs';
|
|
24
|
+
import { WORKTREE_SETTINGS_DEFAULTS } from './worktrees/settings.mjs';
|
|
24
25
|
|
|
25
26
|
export { DEFAULTS_VERSION, DEFAULTS_VERSION_KEY };
|
|
26
27
|
|
|
@@ -33,6 +34,7 @@ const AGENT_SECTION_DEFAULTS = Object.freeze({
|
|
|
33
34
|
update: Object.freeze({ auto: true }),
|
|
34
35
|
recap: Object.freeze({ enabled: true }),
|
|
35
36
|
memoryTools: Object.freeze({ enabled: true }),
|
|
37
|
+
worktree: WORKTREE_SETTINGS_DEFAULTS,
|
|
36
38
|
});
|
|
37
39
|
const MODULE_DEFAULTS = Object.freeze({ enabled: true });
|
|
38
40
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { spawn } from 'node:child_process';
|
|
7
7
|
import { serveWorkerRequests } from './worker-requests.mjs';
|
|
8
8
|
|
|
9
|
-
function runGit({ args, cwd, input, env, timeoutMs, maxBytes }) {
|
|
9
|
+
function runGit({ args, cwd, input, env, timeoutMs, maxBytes, stdoutEncoding = 'utf8' }) {
|
|
10
10
|
return new Promise((resolvePromise, rejectPromise) => {
|
|
11
11
|
const hasInput = (typeof input === 'string' || ArrayBuffer.isView(input)) && input.length > 0;
|
|
12
12
|
const child = spawn('git', args, {
|
|
@@ -55,7 +55,8 @@ function runGit({ args, cwd, input, env, timeoutMs, maxBytes }) {
|
|
|
55
55
|
child.once('close', (code) => {
|
|
56
56
|
const result = {
|
|
57
57
|
code: Number(code ?? 1),
|
|
58
|
-
|
|
58
|
+
// 'base64' keeps non-UTF-8 bytes (a replayable patch) intact across the thread hop.
|
|
59
|
+
stdout: Buffer.concat(stdout).toString(stdoutEncoding === 'base64' ? 'base64' : 'utf8'),
|
|
59
60
|
stderr: Buffer.concat(stderr).toString('utf8'),
|
|
60
61
|
};
|
|
61
62
|
// A failed stdin write only matters when git otherwise reported success.
|
|
@@ -13,8 +13,9 @@ const requestGit = createWorkerRequestClient(new URL('./git-runner-worker.mjs',
|
|
|
13
13
|
/**
|
|
14
14
|
* Resolves to { code, stdout, stderr }. Rejects with code ETIMEDOUT after
|
|
15
15
|
* timeoutMs (the child is killed), EMAXBUFFER once stdout+stderr exceed
|
|
16
|
-
* maxBytes, or the spawn error itself.
|
|
16
|
+
* maxBytes, or the spawn error itself. `stdoutEncoding: 'base64'` returns the
|
|
17
|
+
* exact stdout bytes base64-encoded instead of decoded as UTF-8.
|
|
17
18
|
*/
|
|
18
|
-
export function runGitOffThread(args, { cwd, input = '', env = null, timeoutMs, maxBytes }) {
|
|
19
|
-
return requestGit({ args, cwd, input, env, timeoutMs, maxBytes });
|
|
19
|
+
export function runGitOffThread(args, { cwd, input = '', env = null, timeoutMs, maxBytes, stdoutEncoding = 'utf8' }) {
|
|
20
|
+
return requestGit({ args, cwd, input, env, timeoutMs, maxBytes, stdoutEncoding });
|
|
20
21
|
}
|
|
@@ -24,6 +24,12 @@ function positiveTokens(value) {
|
|
|
24
24
|
return Number.isFinite(tokens) && tokens > 0 ? Math.floor(tokens) : 0;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/** An exact context-window selection in tokens (`contextTokens`); undefined when unset or invalid. */
|
|
28
|
+
export function normalizeContextTokens(value) {
|
|
29
|
+
const tokens = Math.round(Number(value));
|
|
30
|
+
return Number.isFinite(tokens) && tokens > 0 ? tokens : undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
27
33
|
/**
|
|
28
34
|
* The default and the largest selectable window of one model row, in tokens.
|
|
29
35
|
* `defaultWindow` is 0 when the row states no window to start from.
|
|
@@ -69,7 +69,8 @@ function projectModelsDevRow(row) {
|
|
|
69
69
|
if (limit) out.limit = limit;
|
|
70
70
|
const modalities = pickArrays(row.modalities, MODELSDEV_MODALITY_FIELDS);
|
|
71
71
|
if (modalities) out.modalities = modalities;
|
|
72
|
-
|
|
72
|
+
// A declared `reasoning: false` must stay distinct from absent (capabilityFlag).
|
|
73
|
+
if (typeof row.reasoning === 'boolean') out.reasoning = row.reasoning;
|
|
73
74
|
if (Array.isArray(row.reasoning_options) && row.reasoning_options.length > 0) {
|
|
74
75
|
out.reasoning_options = row.reasoning_options;
|
|
75
76
|
}
|
|
@@ -129,8 +130,8 @@ const LITELLM_NUMBER_FIELDS = [
|
|
|
129
130
|
'output_cost_per_video_token',
|
|
130
131
|
'output_cost_per_second',
|
|
131
132
|
];
|
|
132
|
-
// _normalize
|
|
133
|
-
//
|
|
133
|
+
// _normalize keeps each declared boolean (an explicit false outranks a lower
|
|
134
|
+
// layer's true); any other value is indistinguishable from absent.
|
|
134
135
|
const LITELLM_FLAG_FIELDS = [
|
|
135
136
|
'supports_vision',
|
|
136
137
|
'supports_function_calling',
|
|
@@ -164,7 +165,7 @@ function projectLitellmRow(row) {
|
|
|
164
165
|
out[field] = value;
|
|
165
166
|
}
|
|
166
167
|
for (const field of LITELLM_FLAG_FIELDS) {
|
|
167
|
-
if (row[field] ===
|
|
168
|
+
if (typeof row[field] === 'boolean') out[field] = row[field];
|
|
168
169
|
}
|
|
169
170
|
for (const field of LITELLM_STRING_FIELDS) {
|
|
170
171
|
const value = row[field];
|