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
|
@@ -4,7 +4,15 @@ import { createAgentTaskSessions } from '../session-runtime/agent-task-sessions.
|
|
|
4
4
|
import { assertWorktreeMutationAllowed } from '../session-runtime/services/worktree-access.mjs';
|
|
5
5
|
import { createBotStatus, scanCatalog, scopedBot, sessionBotOf } from '../session-runtime/bot-status.mjs';
|
|
6
6
|
import { handoffContent } from '../session-runtime/handoff-attachments.mjs';
|
|
7
|
-
import {
|
|
7
|
+
import { checkEffort, readModelCatalog } from '../session-runtime/task-session-route.mjs';
|
|
8
|
+
import {
|
|
9
|
+
BOT_HOP_LIMIT_ERROR,
|
|
10
|
+
MAX_BOT_HOPS,
|
|
11
|
+
assertBotChainTarget,
|
|
12
|
+
botChainOf,
|
|
13
|
+
rememberSubmissionBotChain,
|
|
14
|
+
} from '../runtime/shared/bot-hops.mjs';
|
|
15
|
+
import { agentIdOfHomeSession } from '../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
8
16
|
import { rebindDelegation } from '../runtime/agent/orchestrator/session/human-gate/delegation.mjs';
|
|
9
17
|
import { isAgentOnlySession } from '../runtime/agent/orchestrator/session/store-summary-visibility.mjs';
|
|
10
18
|
import { readSessionSidebarState } from '../runtime/shared/session-sidebar-host.mjs';
|
|
@@ -19,7 +27,13 @@ const TARGET_ACTIONS = new Set(['status', 'read', 'send', 'cancel', 'delete']);
|
|
|
19
27
|
const MUTATING_ACTIONS = new Set(['send', 'cancel', 'delete']);
|
|
20
28
|
// The workspace methods `worktree` reaches on another session (all on the
|
|
21
29
|
// session protocol's read/configure allowlists).
|
|
22
|
-
const WORKTREE_METHODS = new Set([
|
|
30
|
+
const WORKTREE_METHODS = new Set([
|
|
31
|
+
'getBranchMenu',
|
|
32
|
+
'requestWorktree',
|
|
33
|
+
'selectBranch',
|
|
34
|
+
'mergeWorkspace',
|
|
35
|
+
'removeWorktree',
|
|
36
|
+
]);
|
|
23
37
|
// Why a send from a conversation that is no bot's reports nothing back.
|
|
24
38
|
const NOT_BOT_REASON = 'only a bot conversation gets session results reported back; check that session for the result';
|
|
25
39
|
|
|
@@ -120,22 +134,25 @@ export function createSessionControl({
|
|
|
120
134
|
}
|
|
121
135
|
}
|
|
122
136
|
// Scoped like bots (`callerScope`, bot-status.mjs): the human's sessions
|
|
123
|
-
// list everything, a bot (or its unattended run)
|
|
124
|
-
//
|
|
137
|
+
// list everything with previews, a bot (or its unattended run) lists the
|
|
138
|
+
// same rows (so it can find a session to send to) but only its own carry
|
|
139
|
+
// the bot, activity, preview and working state, anything else the plain
|
|
140
|
+
// rows without previews. Sub-agent sessions (a
|
|
125
141
|
// parent finds its own through the agent tool) and archived ones (the
|
|
126
142
|
// desktop's flag) only on request; the scan pages past the rows left
|
|
127
143
|
// out, so a page is never short while more rows match.
|
|
128
144
|
const own = scopedBot(context.callerScope);
|
|
129
145
|
const archived = (await readSessionSidebarState())?.archived ?? {};
|
|
130
146
|
const keep = (row) =>
|
|
131
|
-
(!own || sessionBotOf(row) === own) &&
|
|
132
147
|
(args.include_agents === true || !isAgentOnlySession(row)) &&
|
|
133
148
|
(args.include_archived === true || !Object.hasOwn(archived, row.id));
|
|
134
149
|
// Bounded: past 10000 rows scanned with fewer than `limit` matching, the
|
|
135
150
|
// page ends (possibly empty) with a nextCursor to continue from.
|
|
136
151
|
const scan = await scanCatalog(service, keep, { cursor: args.cursor || null, want: limit, maxRows: 10_000 });
|
|
137
152
|
const sessions = scan.rows.map((row) => (Object.hasOwn(archived, row.id) ? { ...row, archived: true } : row));
|
|
138
|
-
return sessionListOutput({ sessions, nextCursor: scan.nextCursor }, limit, {
|
|
153
|
+
return sessionListOutput({ sessions, nextCursor: scan.nextCursor }, limit, {
|
|
154
|
+
rich: own ? (row) => sessionBotOf(row) === own : own !== null,
|
|
155
|
+
});
|
|
139
156
|
}
|
|
140
157
|
if (action === 'send') {
|
|
141
158
|
if (typeof args.prompt !== 'string' || !args.prompt.trim()) {
|
|
@@ -153,6 +170,15 @@ export function createSessionControl({
|
|
|
153
170
|
// its member session is the turn that answers and reports.
|
|
154
171
|
const room = roomIdOfSession(sessionId) ? await roomAddressee(sessionId, args) : null;
|
|
155
172
|
if (room?.sessionId === caller) throw new Error('session: send must target another session');
|
|
173
|
+
// Work goes on to a bot (a room seat's, or a bot's home) only outside
|
|
174
|
+
// the caller's bot chain (`callerBotChain`, bot-chain.mjs), never back
|
|
175
|
+
// to the caller's own bot; the turn it starts carries that chain on.
|
|
176
|
+
const botChain = botChainOf(context.callerBotChain);
|
|
177
|
+
assertBotChainTarget(
|
|
178
|
+
room ? room.agentId : agentIdOfHomeSession(sessionId),
|
|
179
|
+
{ chain: botChain, self: context.callerBotId || context.callerAgentId || '' },
|
|
180
|
+
'session'
|
|
181
|
+
);
|
|
156
182
|
// An agent conversation's send reports its turn back to the agent's
|
|
157
183
|
// home: a task session it created by its stored origin, any other
|
|
158
184
|
// session by an origin for this send only.
|
|
@@ -161,23 +187,58 @@ export function createSessionControl({
|
|
|
161
187
|
const turnSessionId = room ? room.sessionId : sessionId;
|
|
162
188
|
const from = { sessionId: caller, ...(context.callerAgentId ? { agentId: context.callerAgentId } : {}) };
|
|
163
189
|
// The member's turn carries the send's hop (`transcriptMeta.hop`), so a
|
|
164
|
-
// chain through the room counts on toward MAX_BOT_HOPS
|
|
190
|
+
// chain through the room counts on toward MAX_BOT_HOPS; its bot chain is
|
|
191
|
+
// recorded under every submission id that turn may take.
|
|
165
192
|
const submit = room
|
|
166
|
-
? async ({ id, onSettled, follow, transcriptMeta } = {}) =>
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
193
|
+
? async ({ id, onSettled, follow, transcriptMeta } = {}) => {
|
|
194
|
+
rememberSubmissionBotChain(id, transcriptMeta?.botChain);
|
|
195
|
+
const followed = follow
|
|
196
|
+
? (submissionId) => {
|
|
197
|
+
rememberSubmissionBotChain(submissionId, transcriptMeta?.botChain);
|
|
198
|
+
return follow(submissionId);
|
|
199
|
+
}
|
|
200
|
+
: null;
|
|
201
|
+
return {
|
|
202
|
+
accepted:
|
|
203
|
+
(await room.host.ask(sessionId, {
|
|
204
|
+
agentId: room.agentId,
|
|
205
|
+
prompt,
|
|
206
|
+
from,
|
|
207
|
+
...(id ? { id } : {}),
|
|
208
|
+
...(transcriptMeta?.hop > 0 ? { hop: transcriptMeta.hop } : {}),
|
|
209
|
+
...(onSettled ? { onSettled } : {}),
|
|
210
|
+
...(followed ? { follow: followed } : {}),
|
|
211
|
+
})) === true,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
178
214
|
: null;
|
|
179
215
|
const addressed = room ? { to: room.agentId } : {};
|
|
180
216
|
let origin = await agentTasks.reportOrigin(turnSessionId, context.callerAgentId, caller);
|
|
217
|
+
// `effort` is the menu's effort pick on the target: checked now against the
|
|
218
|
+
// levels of its model, applied just before the prompt is queued.
|
|
219
|
+
let applyEffort = async () => {};
|
|
220
|
+
if (args.effort !== undefined) {
|
|
221
|
+
if (room) throw new Error('session: effort applies to a session, not a group room');
|
|
222
|
+
// Any bot, attended or not (`callerBotId`), changes only the task
|
|
223
|
+
// sessions it created; reports go only to a bot conversation.
|
|
224
|
+
const botId = context.callerBotId || context.callerAgentId || '';
|
|
225
|
+
if (botId && (await agentTasks.reportOrigin(sessionId, botId, caller))?.target === 'session') {
|
|
226
|
+
throw new Error('session: a bot may set the effort only of the task sessions it created');
|
|
227
|
+
}
|
|
228
|
+
const target = (await service.readSession({ sessionId, transcriptItemLimit: 1 })).full;
|
|
229
|
+
if (!target) throw new Error(`session: ${sessionId} is unavailable`);
|
|
230
|
+
const level = checkEffort(args.effort, target, await readModelCatalog(service, caller));
|
|
231
|
+
// sessionOnly: the session's route changes, never the user's saved model settings.
|
|
232
|
+
applyEffort = async () => {
|
|
233
|
+
const applied = await service.configureSession(
|
|
234
|
+
{ sessionId, action: 'setEffort', args: [level, { sessionOnly: true }] },
|
|
235
|
+
{ revision: 1 }
|
|
236
|
+
);
|
|
237
|
+
if (applied?.value === false) {
|
|
238
|
+
throw new Error(`session: ${sessionId} is busy with another command; effort not changed`);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
181
242
|
// A send made in a bot-descended turn (`callerHop` > 0), or by a bot to
|
|
182
243
|
// another session, extends the chain by one; a bot's own task session
|
|
183
244
|
// only continues it. Refused past the limit, whatever the target.
|
|
@@ -189,13 +250,17 @@ export function createSessionControl({
|
|
|
189
250
|
if (origin) {
|
|
190
251
|
const hop = chained(origin.target === 'session' ? turnHop + 1 : turnHop);
|
|
191
252
|
if (hop > 0) origin = { ...origin, hop };
|
|
253
|
+
if (botChain.length) origin = { ...origin, botChain };
|
|
192
254
|
// The task session a bot created acts as the sending conversation does
|
|
193
255
|
// from now on (attended chat or run); another's session keeps its own.
|
|
194
256
|
if (origin.target !== 'session') await rebindDelegation(sessionId, caller);
|
|
257
|
+
await applyEffort();
|
|
195
258
|
const sent = await agentTasks.send(turnSessionId, prompt, origin, submit);
|
|
196
259
|
return { sessionId, ...addressed, ...sent, ...(hop > 0 ? { hop } : {}) };
|
|
197
260
|
}
|
|
198
261
|
const hop = turnHop > 0 ? chained(turnHop + 1) : 0;
|
|
262
|
+
await applyEffort();
|
|
263
|
+
const chainMeta = { ...(hop > 0 ? { hop } : {}), ...(botChain.length ? { botChain } : {}) };
|
|
199
264
|
let accepted;
|
|
200
265
|
if (submit) accepted = (await submit(hop > 0 ? { transcriptMeta: { hop } } : {})).accepted;
|
|
201
266
|
else {
|
|
@@ -204,7 +269,7 @@ export function createSessionControl({
|
|
|
204
269
|
const result = await service.submitSession({
|
|
205
270
|
sessionId,
|
|
206
271
|
prompt,
|
|
207
|
-
options: { mode: 'prompt', transcriptMeta: { sender: 'lead', ...
|
|
272
|
+
options: { mode: 'prompt', transcriptMeta: { sender: 'lead', ...chainMeta } },
|
|
208
273
|
});
|
|
209
274
|
accepted = result.accepted === true;
|
|
210
275
|
}
|
|
@@ -256,6 +321,9 @@ export function createSessionControl({
|
|
|
256
321
|
cwd: snapshot.cwd ?? null,
|
|
257
322
|
provider: snapshot.provider ?? null,
|
|
258
323
|
model: snapshot.model ?? null,
|
|
324
|
+
effort: snapshot.effort ?? null,
|
|
325
|
+
autoEffort: snapshot.autoEffort ?? null,
|
|
326
|
+
fast: snapshot.fast ?? null,
|
|
259
327
|
busy: snapshot.busy === true,
|
|
260
328
|
quotaResume: snapshot.quotaResume ?? null,
|
|
261
329
|
};
|
|
@@ -1001,6 +1001,8 @@ async function main() {
|
|
|
1001
1001
|
setAgentHomeLiveSurface({
|
|
1002
1002
|
busy: (sessionId) => sessionService.liveSessionBusy(sessionId),
|
|
1003
1003
|
notice: (sessionId, notice) => sessionService.pushLiveSessionNotice(sessionId, notice),
|
|
1004
|
+
// A bot's emoji reaction on a user message (message-reactions.mjs).
|
|
1005
|
+
react: (sessionId, messageId, reactions) => sessionService.setLiveMessageReactions(sessionId, messageId, reactions),
|
|
1004
1006
|
// A task session's result (session create): the agent relays it in one
|
|
1005
1007
|
// turn. Resolves false when the turn was refused, else `{ settled }`, the
|
|
1006
1008
|
// turn's end status ('done' when it finished).
|
|
@@ -1027,6 +1029,12 @@ async function main() {
|
|
|
1027
1029
|
(await sessionService.submitSession({ sessionId, prompt, options }))?.accepted === true,
|
|
1028
1030
|
abort: (sessionId) => sessionService.abortSession({ sessionId }),
|
|
1029
1031
|
});
|
|
1032
|
+
// Mixy's 30-minute heartbeat check (mixy-heartbeat.mjs), on an unref'd timer.
|
|
1033
|
+
import('../session-runtime/mixy-heartbeat.mjs')
|
|
1034
|
+
.then(({ startMixyHeartbeat }) =>
|
|
1035
|
+
startMixyHeartbeat({ getSessionService: () => sessionService, log: (line) => log(`heartbeat: ${line}`) })
|
|
1036
|
+
)
|
|
1037
|
+
.catch((error) => log(`heartbeat start failed: ${error?.message || error}`));
|
|
1030
1038
|
// Results queued before a restart are posted now; results a finished run
|
|
1031
1039
|
// could not queue (kept on its routine's record) are queued again.
|
|
1032
1040
|
recoverScheduleResults().catch((error) => log(`routine results recovery failed: ${error?.message || error}`));
|
|
@@ -47,6 +47,8 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
47
47
|
'getQuotaHistory',
|
|
48
48
|
'getRecapSettings',
|
|
49
49
|
'getSessionTitleSettings',
|
|
50
|
+
'getHeartbeatSettings',
|
|
51
|
+
'getReactionSettings',
|
|
50
52
|
'getLeadAppearance',
|
|
51
53
|
'getBotOrder',
|
|
52
54
|
'getWebSearchRoute',
|
|
@@ -134,6 +136,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
134
136
|
'deleteMediaAssets',
|
|
135
137
|
'deleteSchedule',
|
|
136
138
|
'saveCustomProvider',
|
|
139
|
+
'saveCustomProviderKey',
|
|
137
140
|
'removeCustomProvider',
|
|
138
141
|
'updateCustomProviderModel',
|
|
139
142
|
'setModelPreferences',
|
|
@@ -238,6 +241,8 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
238
241
|
'setProgressHint',
|
|
239
242
|
'setRecapEnabled',
|
|
240
243
|
'setAiSessionTitles',
|
|
244
|
+
'setHeartbeatEnabled',
|
|
245
|
+
'setReactionsEnabled',
|
|
241
246
|
'setLeadAppearance',
|
|
242
247
|
'setBotOrder',
|
|
243
248
|
'setRoute',
|
|
@@ -64,9 +64,10 @@ export function createAgentCancellation({
|
|
|
64
64
|
if (typeof closeCanonical !== 'function') {
|
|
65
65
|
throw new TypeError('session runtime must implement closeCanonicalSession');
|
|
66
66
|
}
|
|
67
|
+
const wasRunning = descriptor.status === 'running';
|
|
67
68
|
// The close clears the transcript: capture a running turn's transcript
|
|
68
69
|
// first so the cancelled turn still hands off its partial output.
|
|
69
|
-
if (
|
|
70
|
+
if (wasRunning) {
|
|
70
71
|
try {
|
|
71
72
|
const { messages } = await entry.runtime.readModelMessages(0);
|
|
72
73
|
rememberCancelTranscript(id, messages);
|
|
@@ -77,7 +78,10 @@ export function createAgentCancellation({
|
|
|
77
78
|
const closed = await closeCanonical.call(entry.runtime, reason, { tombstone: options.tombstone === true });
|
|
78
79
|
if (closed !== true) throw new Error(`agent session ${id} could not be durably closed`);
|
|
79
80
|
descriptor.closed = options.tombstone === true;
|
|
80
|
-
|
|
81
|
+
// Only a close that stopped a running turn is a cancellation; closing a
|
|
82
|
+
// finished agent (cleanup after its handoff) keeps its last status.
|
|
83
|
+
if (descriptor.closed) descriptor.status = 'closed';
|
|
84
|
+
else if (wasRunning) descriptor.status = 'cancelled';
|
|
81
85
|
descriptor.stage = descriptor.status;
|
|
82
86
|
descriptor.updatedAt = Date.now();
|
|
83
87
|
return true;
|
|
@@ -128,6 +128,12 @@ export function createSessionTurnCalls(ctx) {
|
|
|
128
128
|
const accepted = await Promise.resolve(target.call(entry.runtime, intake.prompt, submissionOptions));
|
|
129
129
|
if (accepted === true) {
|
|
130
130
|
entry.reservedOnly = false;
|
|
131
|
+
if (isUserTurn(submissionOptions)) {
|
|
132
|
+
// The user is active: Mixy's due heartbeat check waits for quiet.
|
|
133
|
+
void import('../../../session-runtime/mixy-heartbeat.mjs')
|
|
134
|
+
.then(({ noteUserTurn }) => noteUserTurn())
|
|
135
|
+
.catch((error) => log(`heartbeat activity note failed: ${error?.message || error}`));
|
|
136
|
+
}
|
|
131
137
|
if (isAgentHomeSessionId(id) && isUserTurn(submissionOptions)) {
|
|
132
138
|
// The user spoke in this agent's home: its round trips with other
|
|
133
139
|
// sessions count from zero again, so a capped thread wakes again.
|
|
@@ -274,6 +274,18 @@ export function createSessionService({
|
|
|
274
274
|
return true;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
/** Show the reactions now on message `messageId` in the hosted runtime of
|
|
278
|
+
* `sessionId` and publish them to its views; false when no runtime hosts
|
|
279
|
+
* it or its live rows do not hold that message. */
|
|
280
|
+
function setLiveMessageReactions(sessionId, messageId, reactions) {
|
|
281
|
+
const owner = projection.sessionOwner(sessionId);
|
|
282
|
+
if (typeof owner?.runtime?.setMessageReactions !== 'function') return false;
|
|
283
|
+
if (!owner.runtime.setMessageReactions(messageId, reactions)) return false;
|
|
284
|
+
const step = projection.advance(owner);
|
|
285
|
+
if (step.changed) projection.publishStep(owner, step);
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
|
|
277
289
|
function getStatus() {
|
|
278
290
|
const busy = retention.liveBusyCount();
|
|
279
291
|
let watched = 0;
|
|
@@ -322,6 +334,7 @@ export function createSessionService({
|
|
|
322
334
|
liveSessionBusy,
|
|
323
335
|
liveSessionAwaitingApproval,
|
|
324
336
|
pushLiveSessionNotice,
|
|
337
|
+
setLiveMessageReactions,
|
|
325
338
|
stop,
|
|
326
339
|
startQuotaResume: () => quotaResume?.start(),
|
|
327
340
|
runDueQuotaResumes: () => quotaResume?.tick() ?? Promise.resolve(),
|
|
@@ -13,20 +13,23 @@ const outputBytes = (value) => Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
|
13
13
|
|
|
14
14
|
/** Keep catalog paging authoritative even when the output budget shortens a page.
|
|
15
15
|
* `rich` adds the owning bot, last activity, latest line and working state
|
|
16
|
-
* (never for a background caller: bot-status.mjs scopedBot).
|
|
16
|
+
* (never for a background caller: bot-status.mjs scopedBot). `rich` may be a
|
|
17
|
+
* per-row predicate: a bot gets them only for its own sessions. */
|
|
17
18
|
export function sessionListOutput(page, limit, { rich = true } = {}) {
|
|
18
19
|
const raw = page.sessions;
|
|
19
20
|
const sessions = raw.slice(0, limit).map((row) => {
|
|
21
|
+
// Decided first: a session that is not the caller's carries its real
|
|
22
|
+
// title only, never a preview standing in for it.
|
|
23
|
+
const own = typeof rich === 'function' ? rich(row) : rich;
|
|
24
|
+
const title = own ? row.title || row.preview : row.title;
|
|
20
25
|
const base = {
|
|
21
26
|
id: row.id,
|
|
22
|
-
...(
|
|
23
|
-
? { title: escapeHarnessTags(truncateToolText(row.title || row.preview, 160)) }
|
|
24
|
-
: {}),
|
|
27
|
+
...(title ? { title: escapeHarnessTags(truncateToolText(title, 160)) } : {}),
|
|
25
28
|
...(row.status ? { status: row.status } : {}),
|
|
26
29
|
...(row.cwd ? { cwd: row.cwd } : {}),
|
|
27
30
|
...(row.archived === true ? { archived: true } : {}),
|
|
28
31
|
};
|
|
29
|
-
if (!
|
|
32
|
+
if (!own) return base;
|
|
30
33
|
// The bot it belongs to: its chat, room seat or the task's creator.
|
|
31
34
|
const bot = sessionBotOf(row);
|
|
32
35
|
const lastUsedAt = Number(row.lastUsedAt) || 0;
|
|
@@ -173,6 +173,7 @@ const PROVIDER_DISPLAY_NAMES = new Map([
|
|
|
173
173
|
['command-code-oauth', 'Command Code'],
|
|
174
174
|
['mimo-oauth', 'MiMo'],
|
|
175
175
|
['cursor-oauth', 'Cursor OAuth'],
|
|
176
|
+
['devin-oauth', 'Devin'],
|
|
176
177
|
['antigravity-oauth', 'Antigravity OAuth'],
|
|
177
178
|
['openai', 'OpenAI API'],
|
|
178
179
|
['openai-api', 'OpenAI API'],
|
|
@@ -279,6 +280,7 @@ const PROVIDER_DISPLAY_RANKS = {
|
|
|
279
280
|
'mimo-oauth': 34,
|
|
280
281
|
'antigravity-oauth': 31,
|
|
281
282
|
'cursor-oauth': 32,
|
|
283
|
+
'devin-oauth': 32.5,
|
|
282
284
|
'opencode-go-oauth': 34.5,
|
|
283
285
|
openai: 40,
|
|
284
286
|
'openai-api': 40,
|