mixdog 1.3.3 → 1.3.5
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/LICENSES/oh-my-pi-MIT.txt +23 -0
- package/NOTICE.md +15 -0
- package/README.md +11 -0
- package/package.json +3 -2
- package/scripts/embed-google-oauth-client.mjs +49 -0
- package/scripts/lib/test-spawn-ledger.mjs +46 -1
- package/scripts/test.mjs +5 -0
- package/src/defaults/shipped-history.json +8 -0
- package/src/defaults/skills/browser-use/SKILL.md +21 -9
- package/src/defaults/skills/setup/SKILL.md +7 -2
- package/src/defaults/skills/setup/references/actions.md +82 -27
- package/src/defaults/skills/setup/references/surfaces.md +67 -34
- package/src/defaults/skills/setup-guide/SKILL.md +3 -3
- package/src/lib/keychain-cjs.cjs +359 -29
- package/src/rules/agent-mode/AGENT_MODE.md +10 -2
- package/src/rules/agent-mode/MIXY.md +12 -0
- package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +193 -0
- package/src/runtime/agent/orchestrator/config.mjs +18 -0
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +2 -2
- package/src/runtime/agent/orchestrator/mcp/client.mjs +6 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +31 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +16 -3
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +42 -7
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +21 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +23 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +11 -1
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +68 -23
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +22 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +18 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +52 -8
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +22 -6
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +15 -4
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +17 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +19 -2
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +10 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +10 -217
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +409 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-families.mjs +187 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-identity.mjs +342 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-models.mjs +541 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-protobuf.mjs +305 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-request.mjs +558 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-schema.mjs +880 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-session.mjs +190 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-tool-args.mjs +351 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +560 -0
- package/src/runtime/agent/orchestrator/providers/devin.mjs +491 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/gemini-output-limit.mjs +46 -0
- package/src/runtime/agent/orchestrator/providers/gemini-reasoning-relay.mjs +30 -0
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +7 -11
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +61 -22
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -4
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +25 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +96 -5
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +23 -5
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +17 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +39 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/provider-availability.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/wire-protobuf-codec.mjs +368 -0
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs +133 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +23 -5
- package/src/runtime/agent/orchestrator/runtime-core/tool-profile.mjs +35 -10
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +57 -10
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +9 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +0 -3
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +10 -4
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +50 -2
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/message-ids.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/message-reactions.mjs +89 -0
- package/src/runtime/agent/orchestrator/session/message-reactions.test-support.mjs +75 -0
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +0 -2
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +20 -2
- package/src/runtime/agent/orchestrator/session/store-agent-worker-header-cache.mjs +85 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +125 -12
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +7 -1
- package/src/runtime/channels/lib/schedule-errors.mjs +51 -0
- package/src/runtime/channels/lib/scheduler.mjs +109 -14
- package/src/runtime/channels/lib/schedules-db.mjs +49 -0
- package/src/runtime/channels/lib/tool-dispatch.mjs +13 -0
- package/src/runtime/channels/lib/worker-main.mjs +9 -0
- package/src/runtime/office/com/com-adapter.mjs +17 -1
- package/src/runtime/office/com/office-com-host.ps1 +51 -1
- package/src/runtime/office/pdf/cfb-fixture.mjs +328 -0
- package/src/runtime/office/pdf/cfb-protection.mjs +311 -0
- package/src/runtime/office/pdf/document-preview.mjs +326 -8
- package/src/runtime/office/pdf/ooxml-crypto.mjs +469 -0
- package/src/runtime/office/pdf/ooxml-key-worker.mjs +14 -0
- package/src/runtime/office/portable/portable-soffice.mjs +45 -5
- package/src/runtime/shared/agent-room-host.mjs +1 -1
- package/src/runtime/shared/bot-hops.mjs +62 -2
- package/src/runtime/shared/config.mjs +49 -22
- package/src/runtime/shared/connector-catalog.d.mts +4 -2
- package/src/runtime/shared/connector-catalog.mjs +16 -8
- package/src/runtime/shared/developer-options.mjs +32 -1
- package/src/runtime/shared/google-oauth-client.generated.json +4 -0
- package/src/runtime/shared/google-oauth-client.mjs +34 -9
- package/src/runtime/shared/llm/anthropic-betas.mjs +7 -0
- package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +12 -0
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +1 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +4 -383
- package/src/runtime/shared/llm/well-formed.mjs +66 -0
- package/src/runtime/shared/provider-accounts.mjs +224 -58
- package/src/runtime/shared/provider-api-key.mjs +19 -8
- package/src/runtime/shared/routine-trigger.mjs +42 -0
- package/src/runtime/shared/tool-execution-contract.mjs +2 -0
- package/src/runtime/shared/transcript-metadata.mjs +38 -0
- package/src/runtime/shared/user-data-guard.mjs +30 -2
- package/src/runtime/shared/worktrees/activity-gate.mjs +12 -5
- package/src/session-runtime/agent-home-delivery.mjs +57 -13
- package/src/session-runtime/agent-room-delivery.mjs +28 -1
- package/src/session-runtime/agent-task-sessions.mjs +292 -79
- package/src/session-runtime/agent-tool-routing.mjs +49 -4
- package/src/session-runtime/boot/begin.mjs +3 -2
- package/src/session-runtime/boot/tools.mjs +4 -0
- package/src/session-runtime/bot-chain.mjs +32 -0
- package/src/session-runtime/bot-status.mjs +7 -4
- package/src/session-runtime/channel-config-api.mjs +63 -17
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +45 -0
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +72 -5
- package/src/session-runtime/internal-tool-executor.mjs +4 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +7 -1
- package/src/session-runtime/mixy-heartbeat.mjs +807 -0
- package/src/session-runtime/model-route/route-tuning.mjs +10 -6
- package/src/session-runtime/owned-automation-run.mjs +33 -12
- package/src/session-runtime/provider-auth/login.mjs +7 -0
- package/src/session-runtime/provider-models/row-hydration.mjs +13 -2
- package/src/session-runtime/routine-home-turn.mjs +33 -6
- package/src/session-runtime/schedule-session-run.mjs +7 -3
- package/src/session-runtime/services/agent-tool/close-flow.mjs +14 -2
- package/src/session-runtime/services/agent-tool/execute.mjs +6 -1
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +11 -2
- package/src/session-runtime/services/agent-tool/render.mjs +3 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +8 -12
- package/src/session-runtime/services/agent-tool/tool-def.mjs +1 -1
- package/src/session-runtime/services/channel-admin.mjs +66 -18
- package/src/session-runtime/services/channel-worker.mjs +1 -1
- package/src/session-runtime/services/provider-admin.mjs +128 -25
- package/src/session-runtime/services/schedule-access.mjs +14 -0
- package/src/session-runtime/services/usage-dashboard-model.mjs +1 -0
- package/src/session-runtime/session-create/session-options.mjs +7 -4
- package/src/session-runtime/settings-system-api.mjs +16 -1
- package/src/session-runtime/setup-tool/executor.mjs +49 -14
- package/src/session-runtime/setup-tool/extended-actions.mjs +29 -3
- package/src/session-runtime/setup-tool/settings-contract.mjs +65 -4
- package/src/session-runtime/setup-tool/tool-defs.mjs +30 -3
- package/src/session-runtime/task-session-route.mjs +99 -0
- package/src/session-runtime/tool-policy/policy-stage.mjs +5 -2
- package/src/session-runtime/tool-policy/surface-helpers.mjs +2 -3
- package/src/session-runtime/tool-surface.mjs +4 -0
- package/src/session-runtime/usage-stats-api.mjs +1 -1
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +98 -21
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -1
- package/src/session-runtime/workspace/transitions.mjs +10 -2
- package/src/standalone/daemon-session-control.mjs +88 -20
- package/src/standalone/daemon.mjs +8 -0
- package/src/standalone/session-protocol.mjs +5 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +6 -2
- package/src/standalone/session-service/session-calls/session-turns.mjs +6 -0
- package/src/standalone/session-service.mjs +13 -0
- package/src/standalone/session-tool-output.mjs +8 -5
- package/src/tui/app/model-options.mjs +2 -0
- package/src/tui/dist/index.mjs +335 -172
- package/src/tui/session/notice-surface.mjs +17 -1
- package/src/tui/session/session-api/integrations.mjs +1 -0
- package/src/tui/session/session-api/lifecycle.mjs +8 -0
- package/src/tui/session/session-api/settings.mjs +14 -2
- package/src/tui/session/turn-stream.mjs +17 -1
- package/src/tui/session/turn.mjs +22 -2
- package/src/vendor/statusline/src/gateway/claude-current.mjs +0 -58
- package/src/vendor/statusline/src/gateway/route-meta.mjs +1 -361
- package/src/vendor/statusline/src/gateway/session-routes.mjs +0 -55
- package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +0 -285
|
@@ -35,10 +35,26 @@ export function createNoticeSurface({ getState, set, isDisposed, pushItem, repla
|
|
|
35
35
|
// A routine result is a finished sentence, never a raw error to polish;
|
|
36
36
|
// a group-room row is someone's words, kept verbatim (a pass has none).
|
|
37
37
|
const value =
|
|
38
|
-
options.routine || options.room || options.heldRequest
|
|
38
|
+
options.routine || options.room || options.heldRequest || options.assistant
|
|
39
|
+
? String(text ?? '').trim()
|
|
40
|
+
: polishNoticeText(text);
|
|
39
41
|
if (!value && !options.room) return null;
|
|
40
42
|
const forceTranscript = options.transcript === true;
|
|
41
43
|
if (!forceTranscript) return pushToast(value, tone, options.ttlMs, options);
|
|
44
|
+
// The agent's own message posted outside a turn (agent-home-delivery.mjs):
|
|
45
|
+
// its reply row, as the stored message restores.
|
|
46
|
+
if (options.assistant) {
|
|
47
|
+
const id = options.messageId || nextId();
|
|
48
|
+
pushItem({
|
|
49
|
+
kind: 'assistant',
|
|
50
|
+
id,
|
|
51
|
+
text: value,
|
|
52
|
+
streaming: false,
|
|
53
|
+
at: Date.now(),
|
|
54
|
+
...(options.messageId ? { messageId: options.messageId } : {}),
|
|
55
|
+
});
|
|
56
|
+
return id;
|
|
57
|
+
}
|
|
42
58
|
const userRow = options.room?.kind === 'user';
|
|
43
59
|
// A room user row keeps its message id (the sender's submission id), as a
|
|
44
60
|
// turn's own prompt row keeps its submission id.
|
|
@@ -138,6 +138,7 @@ export function createSessionIntegrationsApi(bag, { oauthFlows }) {
|
|
|
138
138
|
(input) => runtime.saveCustomProvider(input),
|
|
139
139
|
(result) => `custom provider saved: ${result.id}`
|
|
140
140
|
),
|
|
141
|
+
saveCustomProviderKey: (id, secret) => runtime.saveCustomProviderKey(id, secret),
|
|
141
142
|
updateCustomProviderModel: (id, modelId, patch) => runtime.updateCustomProviderModel(id, modelId, patch),
|
|
142
143
|
setModelPreferences: (provider, changes) => runtime.setModelPreferences(provider, changes),
|
|
143
144
|
removeCustomProvider: async (id) => {
|
|
@@ -81,6 +81,14 @@ export function createSessionLifecycleApi(bag, { restoreTranscriptItems, oauthFl
|
|
|
81
81
|
pushNotice,
|
|
82
82
|
removeNotice,
|
|
83
83
|
setProgressHint,
|
|
84
|
+
// A bot's emoji reactions on a user message (message-reactions.mjs): its
|
|
85
|
+
// live row shows them at once; false when the live rows do not hold it.
|
|
86
|
+
setMessageReactions: (messageId, reactions) => {
|
|
87
|
+
const row = bag
|
|
88
|
+
.getState()
|
|
89
|
+
.items.findLast((item) => item?.kind === 'user' && messageId && item.messageId === messageId);
|
|
90
|
+
return row ? bag.patchItem(row.id, { reactions: Array.isArray(reactions) ? reactions : [] }) : false;
|
|
91
|
+
},
|
|
84
92
|
...createSessionResetActions(bag),
|
|
85
93
|
listSessions: (options) => {
|
|
86
94
|
return runtime.listSessions(options);
|
|
@@ -34,8 +34,8 @@ export function createSessionSettingsApi(bag) {
|
|
|
34
34
|
// refused: another command's lock does not block a selection.
|
|
35
35
|
setModel: async (m) => (await bag.setSessionRoute({ model: m })) !== false,
|
|
36
36
|
setEffort: withCommandLock(
|
|
37
|
-
async (value) => {
|
|
38
|
-
await runtime.setEffort(value);
|
|
37
|
+
async (value, options) => {
|
|
38
|
+
await runtime.setEffort(value, options);
|
|
39
39
|
set({ ...routeState() });
|
|
40
40
|
return runtime.effort || 'auto';
|
|
41
41
|
},
|
|
@@ -112,6 +112,18 @@ export function createSessionSettingsApi(bag) {
|
|
|
112
112
|
setAiSessionTitles: withCommandLock(async (enabled) => {
|
|
113
113
|
return await runtime.setAiSessionTitles?.(enabled);
|
|
114
114
|
}),
|
|
115
|
+
getHeartbeatSettings: () => {
|
|
116
|
+
return runtime.getHeartbeatSettings?.() || { heartbeat: true };
|
|
117
|
+
},
|
|
118
|
+
setHeartbeatEnabled: withCommandLock(async (enabled) => {
|
|
119
|
+
return await runtime.setHeartbeatEnabled?.(enabled);
|
|
120
|
+
}),
|
|
121
|
+
getReactionSettings: () => {
|
|
122
|
+
return runtime.getReactionSettings?.() || { reactions: true };
|
|
123
|
+
},
|
|
124
|
+
setReactionsEnabled: withCommandLock(async (enabled) => {
|
|
125
|
+
return await runtime.setReactionsEnabled?.(enabled);
|
|
126
|
+
}),
|
|
115
127
|
getLeadAppearance: () => {
|
|
116
128
|
return runtime.getLeadAppearance?.() || { avatar: null };
|
|
117
129
|
},
|
|
@@ -40,6 +40,9 @@ export function createTurnStream(deps) {
|
|
|
40
40
|
// (`commentary` / `final_answer`), or null; the desktop row carries it.
|
|
41
41
|
phase: null,
|
|
42
42
|
thinkingText: '',
|
|
43
|
+
// Length of thinkingText when the current provider send began: a
|
|
44
|
+
// `reasoning` retraction drops only what that send added.
|
|
45
|
+
thinkingSendMark: 0,
|
|
43
46
|
thinkingStartedAt: 0,
|
|
44
47
|
thinkingSegmentStartedAt: 0,
|
|
45
48
|
accumulatedThinkingMs: 0,
|
|
@@ -492,9 +495,20 @@ export function appendReasoningDelta(stream, chunk) {
|
|
|
492
495
|
scheduleStreamFlush(stream);
|
|
493
496
|
}
|
|
494
497
|
|
|
498
|
+
// A provider send (one model request of the turn) begins: the thinking so far
|
|
499
|
+
// belongs to earlier sends and survives a retraction of this one.
|
|
500
|
+
export function markThinkingSendStart(stream) {
|
|
501
|
+
stream.thinkingSendMark = stream.thinkingText.length;
|
|
502
|
+
}
|
|
503
|
+
|
|
495
504
|
export function resetStreamedText(stream, { chars, reasoning } = {}) {
|
|
496
505
|
const count = Math.max(0, Number(chars) || 0);
|
|
497
|
-
if (reasoning)
|
|
506
|
+
if (reasoning) {
|
|
507
|
+
endThinkingForText(stream);
|
|
508
|
+
// The discarded attempt's thinking must not prefix the next attempt's;
|
|
509
|
+
// earlier sends' thinking stays.
|
|
510
|
+
stream.thinkingText = stream.thinkingText.slice(0, stream.thinkingSendMark);
|
|
511
|
+
}
|
|
498
512
|
if (!count) return reasoning === true;
|
|
499
513
|
flushStreamBatch(stream);
|
|
500
514
|
stream.assistantText = stream.assistantText.slice(0, Math.max(0, stream.assistantText.length - count));
|
|
@@ -529,6 +543,8 @@ export function resetStreamedText(stream, { chars, reasoning } = {}) {
|
|
|
529
543
|
// tool phase (`spinnerMode`: 'task-wait' or 'tool-use').
|
|
530
544
|
export function closeThinkingForToolBatch(stream, spinnerMode) {
|
|
531
545
|
const { getState, set } = stream;
|
|
546
|
+
// The send that produced this batch is complete; its thinking is kept.
|
|
547
|
+
markThinkingSendStart(stream);
|
|
532
548
|
if (stream.thinkingText && getState().thinking) {
|
|
533
549
|
const thinkingLastEndedAt = closeThinkingSegment(stream);
|
|
534
550
|
set({
|
package/src/tui/session/turn.mjs
CHANGED
|
@@ -23,6 +23,10 @@ import { isRejected429 } from '../../runtime/shared/error-presentation.mjs';
|
|
|
23
23
|
import { QUOTA_KINDS, providerErrorKind } from '../../runtime/agent/orchestrator/providers/provider-error-kind.mjs';
|
|
24
24
|
import { turnFailureRecord } from '../../runtime/agent/orchestrator/session/turn-failure.mjs';
|
|
25
25
|
import { registerTaskWaitSteeringCheck } from '../../runtime/agent/orchestrator/session/task-wait-control.mjs';
|
|
26
|
+
import {
|
|
27
|
+
isReactionSuccess,
|
|
28
|
+
reactionCallIds,
|
|
29
|
+
} from '../../runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs';
|
|
26
30
|
import { promptDisplayText, STEERING_SUPPRESSED_DISPLAY } from './queue-helpers.mjs';
|
|
27
31
|
import { yieldToRenderer } from './render-timing.mjs';
|
|
28
32
|
import { archiveItemsForCompaction, compactionArchivedRows } from './compaction-view.mjs';
|
|
@@ -35,6 +39,7 @@ import {
|
|
|
35
39
|
appendTextDelta,
|
|
36
40
|
appendAssistantText,
|
|
37
41
|
appendReasoningDelta,
|
|
42
|
+
markThinkingSendStart,
|
|
38
43
|
noteAssistantPhase,
|
|
39
44
|
resetStreamedText,
|
|
40
45
|
applyStageChange,
|
|
@@ -152,6 +157,9 @@ function beginTurn({ flags, getState, transcriptRouteMetadata }, options) {
|
|
|
152
157
|
askResult: null,
|
|
153
158
|
finishedNormally: false,
|
|
154
159
|
transcriptCompacted: false,
|
|
160
|
+
// Ids of this turn's react calls; `reacted` is set once one succeeds.
|
|
161
|
+
reactionCallIds: new Set(),
|
|
162
|
+
reacted: false,
|
|
155
163
|
};
|
|
156
164
|
}
|
|
157
165
|
|
|
@@ -403,10 +411,15 @@ export function toolHandlers(ctx) {
|
|
|
403
411
|
if (isCurrentTurn()) settleSegmentBeforeToolCall(ctx);
|
|
404
412
|
},
|
|
405
413
|
onToolCall: async (_iter, calls) => {
|
|
406
|
-
if (isCurrentTurn())
|
|
414
|
+
if (!isCurrentTurn()) return;
|
|
415
|
+
for (const id of reactionCallIds(calls)) ctx.turn.reactionCallIds.add(id);
|
|
416
|
+
await openToolCalls(ctx, calls);
|
|
407
417
|
},
|
|
408
418
|
onToolResult: (message) => {
|
|
409
419
|
if (!isCurrentTurn()) return;
|
|
420
|
+
// A reaction that landed on the user's message is this turn's output
|
|
421
|
+
// even with no reply text; a rejected or failed react call is not.
|
|
422
|
+
if (isReactionSuccess(message, ctx.turn.reactionCallIds)) ctx.turn.reacted = true;
|
|
410
423
|
try {
|
|
411
424
|
options.onToolResult?.(message);
|
|
412
425
|
} catch {}
|
|
@@ -440,7 +453,9 @@ export function streamHandlers(ctx) {
|
|
|
440
453
|
const { isCurrentTurn, stream } = ctx;
|
|
441
454
|
return {
|
|
442
455
|
onProviderSendStarted: () => {
|
|
443
|
-
if (isCurrentTurn())
|
|
456
|
+
if (!isCurrentTurn()) return;
|
|
457
|
+
markThinkingSendStart(stream);
|
|
458
|
+
markLiveCallRequestStart(stream);
|
|
444
459
|
},
|
|
445
460
|
onStageChange: async (stage, detail = null) => {
|
|
446
461
|
if (!isCurrentTurn()) return;
|
|
@@ -554,6 +569,9 @@ export function turnDoneItem({ turn, stream, cards, getState, nextId }) {
|
|
|
554
569
|
outputTokens: finalOutputTokens(stream, getState().spinner?.outputTokens),
|
|
555
570
|
thinkingElapsedMs: stream.thinkingStartedAt ? stream.accumulatedThinkingMs : 0,
|
|
556
571
|
toolCount: cards.toolCards.length,
|
|
572
|
+
// Its answer may be a reaction alone: readers of the turn's final answer
|
|
573
|
+
// take it as done with nothing to say (session-final-answer.ts).
|
|
574
|
+
...(turn.reacted ? { reacted: true } : {}),
|
|
557
575
|
verb: turn.completionVerb,
|
|
558
576
|
at: Date.now(),
|
|
559
577
|
...(turn.failureDetail ? { detail: turn.failureDetail } : {}),
|
|
@@ -577,9 +595,11 @@ function publishTurnClose(ctx, closingItems) {
|
|
|
577
595
|
const assistantOutput = (stream.currentAssistantText || stream.assistantText || '').trim();
|
|
578
596
|
// Suppress only true pending-resume no-ops: no transcript items added and
|
|
579
597
|
// no model output; cancelled/error turns and any visible turn stay marked.
|
|
598
|
+
// A turn whose only output was a reaction ends with its turndone row too.
|
|
580
599
|
const isNoOpTurn =
|
|
581
600
|
turn.finishedNormally &&
|
|
582
601
|
!turn.cancelled &&
|
|
602
|
+
!turn.reacted &&
|
|
583
603
|
cards.toolCards.length === 0 &&
|
|
584
604
|
!resultContent &&
|
|
585
605
|
!assistantOutput &&
|
|
@@ -5,7 +5,6 @@ import { getModelMetadataSync } from '../../../../runtime/shared/llm/model-catal
|
|
|
5
5
|
import { providerCachedModelsSync } from '../../../../runtime/shared/llm/provider-catalog-cache.mjs';
|
|
6
6
|
|
|
7
7
|
export const CLAUDE_CURRENT_MODE = 'claude-current';
|
|
8
|
-
export const CLAUDE_CURRENT_CHOICE_ID = 'claude-current';
|
|
9
8
|
|
|
10
9
|
const DEFAULT_FAMILY_MODEL = Object.freeze({
|
|
11
10
|
opus: 'claude-opus-4-8',
|
|
@@ -20,7 +19,6 @@ const EFFORT_BUDGET = Object.freeze({
|
|
|
20
19
|
xhigh: 32768,
|
|
21
20
|
max: 32768,
|
|
22
21
|
});
|
|
23
|
-
const SNAPSHOT_REFRESH_MS = 30_000;
|
|
24
22
|
|
|
25
23
|
function cleanString(v) {
|
|
26
24
|
return typeof v === 'string' && v.trim() ? v.trim() : '';
|
|
@@ -33,15 +31,6 @@ export function isMixdogModelSelection(value) {
|
|
|
33
31
|
return cleanString(raw).toLowerCase().startsWith('mixdog/');
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
export function isClaudeNativeModelSelection(route) {
|
|
37
|
-
return !!(
|
|
38
|
-
route &&
|
|
39
|
-
route.provider === 'anthropic-oauth' &&
|
|
40
|
-
cleanString(route.model) &&
|
|
41
|
-
!isMixdogModelSelection(route)
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
34
|
function num(v, fallback = null) {
|
|
46
35
|
if (v === null || v === undefined || v === '') return fallback;
|
|
47
36
|
const n = Number(v);
|
|
@@ -80,23 +69,6 @@ function readFreshJsonFile(file, maxAgeMs) {
|
|
|
80
69
|
}
|
|
81
70
|
}
|
|
82
71
|
|
|
83
|
-
function snapshotEquivalent(a, b) {
|
|
84
|
-
if (!a || !b) return false;
|
|
85
|
-
const keys = [
|
|
86
|
-
'mode',
|
|
87
|
-
'source',
|
|
88
|
-
'provider',
|
|
89
|
-
'model',
|
|
90
|
-
'requestedModel',
|
|
91
|
-
'modelDisplay',
|
|
92
|
-
'effort',
|
|
93
|
-
'fast',
|
|
94
|
-
'thinkingBudgetTokens',
|
|
95
|
-
'contextWindow',
|
|
96
|
-
];
|
|
97
|
-
return keys.every(k => (a[k] ?? null) === (b[k] ?? null));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
72
|
// The newest roster model of a family, by the roster's own release stamps.
|
|
101
73
|
function newestRosterModel(family) {
|
|
102
74
|
const stamp = (row) => Date.parse(row.releaseDate) || (Number(row.created) > 0 ? Number(row.created) : 0);
|
|
@@ -298,33 +270,3 @@ export function readClaudeCodeCurrentRoute({ request = null, maxAgeMs = 10 * 60
|
|
|
298
270
|
if (route.fast === null || route.fast === undefined) route.fast = false;
|
|
299
271
|
return route;
|
|
300
272
|
}
|
|
301
|
-
|
|
302
|
-
export function writeClaudeCodeCurrentSnapshot(ccJsonInput) {
|
|
303
|
-
if (!ccJsonInput) return null;
|
|
304
|
-
let payload = null;
|
|
305
|
-
try { payload = JSON.parse(String(ccJsonInput)); } catch { return null; }
|
|
306
|
-
const route = routeFromPayload(payload, 'statusline');
|
|
307
|
-
if (!route || (!route.model && !route.requestedModel)) return null;
|
|
308
|
-
const file = path.join(pluginDataDir(), 'claude-current-model.json');
|
|
309
|
-
try {
|
|
310
|
-
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
311
|
-
const st = fs.existsSync(file) ? fs.statSync(file) : null;
|
|
312
|
-
const current = st ? readJsonFile(file) : null;
|
|
313
|
-
if (
|
|
314
|
-
st &&
|
|
315
|
-
Date.now() - st.mtimeMs < SNAPSHOT_REFRESH_MS &&
|
|
316
|
-
snapshotEquivalent(current, route)
|
|
317
|
-
) {
|
|
318
|
-
return route;
|
|
319
|
-
}
|
|
320
|
-
fs.writeFileSync(file, JSON.stringify(route, null, 2) + '\n');
|
|
321
|
-
} catch { /* best-effort statusline cache */ }
|
|
322
|
-
return route;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
export function formatClaudeCurrentChoiceLabel(route = readClaudeCodeCurrentRoute()) {
|
|
326
|
-
const parts = [`Current selection: ${route.modelDisplay || route.model || 'current model'}`];
|
|
327
|
-
if (route.effort) parts.push(String(route.effort).toUpperCase());
|
|
328
|
-
if (route.fast === true) parts.push('fast');
|
|
329
|
-
return parts.join(' · ');
|
|
330
|
-
}
|