mixdog 1.2.6 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/simple-icons-CC0-1.0.txt +30 -0
- package/NOTICE.md +71 -9
- package/package.json +4 -1
- package/scripts/check-model-recommendations.mjs +89 -0
- package/scripts/gate-local.mjs +7 -0
- package/scripts/lib/isolated-test-env.mjs +16 -0
- package/src/agents/reviewer/AGENT.md +4 -2
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +10 -0
- package/src/defaults/skills/browser-use/SKILL.md +5 -0
- package/src/defaults/skills/memory-management/SKILL.md +4 -1
- package/src/defaults/skills/setup/references/actions.md +14 -4
- package/src/defaults/skills/setup-guide/SKILL.md +178 -0
- package/src/defaults/skills/setup-guide/model-recommendations.json +333 -0
- package/src/lib/rules-builder.cjs +55 -6
- package/src/output-styles/common.md +13 -8
- package/src/rules/agent/AGENT.md +4 -0
- package/src/rules/agent-mode/AGENT_MODE.md +24 -0
- package/src/rules/agent-mode/MIXY.md +28 -0
- package/src/rules/agent-mode/ROUTINE.md +6 -0
- package/src/rules/lead/LEAD.md +7 -3
- package/src/rules/shared/70-delivery.md +3 -0
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +86 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +77 -14
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +241 -14
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +4 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +216 -0
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -4
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +10 -1
- package/src/runtime/agent/orchestrator/mcp/client.mjs +115 -11
- package/src/runtime/agent/orchestrator/mcp/oauth-account.mjs +97 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +49 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +59 -9
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +32 -7
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +45 -6
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +195 -6
- package/src/runtime/agent/orchestrator/mcp/server-connectors.mjs +17 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +10 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +7 -8
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/lib/tool-call-wire-ids.mjs +65 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +17 -12
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +14 -2
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +17 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +96 -1
- package/src/runtime/agent/orchestrator/runtime-core/context-status-shape.mjs +4 -0
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +6 -4
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +14 -0
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +12 -6
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +32 -5
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +21 -5
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +40 -7
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +52 -20
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/agent-home.d.mts +4 -0
- package/src/runtime/agent/orchestrator/session/agent-home.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +62 -0
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +31 -0
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +241 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +166 -0
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +650 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +192 -0
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +221 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +195 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +167 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +108 -6
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +74 -15
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +13 -3
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +49 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-lifecycle-epoch.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +44 -16
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +50 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -5
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +39 -4
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +33 -24
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +58 -8
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +32 -5
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +86 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +329 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +28 -9
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -12
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +46 -0
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +58 -10
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +92 -15
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +12 -0
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +113 -5
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +4 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +25 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +6 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +3 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +75 -57
- package/src/runtime/attachments/store.mjs +6 -0
- package/src/runtime/browser-bridge/client.mjs +24 -0
- package/src/runtime/channels/lib/scheduler.mjs +40 -12
- package/src/runtime/channels/lib/schedules-db.mjs +71 -12
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +36 -16
- package/src/runtime/channels/lib/webhook.mjs +0 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +100 -10
- package/src/runtime/channels/lib/worker-main.mjs +17 -20
- package/src/runtime/computer-bridge/client.mjs +28 -1
- package/src/runtime/connectors/gmail-app-password.mjs +690 -0
- package/src/runtime/connectors/google-mcp.mjs +446 -0
- package/src/runtime/effort-judge/judge-client.mjs +1 -1
- package/src/runtime/effort-judge/model-manifest.json +7 -7
- package/src/runtime/memory/lib/core-memory-access.mjs +69 -0
- package/src/runtime/memory/lib/core-memory-file.mjs +16 -8
- package/src/runtime/memory/lib/core-memory-index.mjs +15 -9
- package/src/runtime/memory/lib/core-memory-management.mjs +10 -4
- package/src/runtime/memory/lib/core-memory-store.mjs +53 -30
- package/src/runtime/memory/lib/core-memory-uniqueness.mjs +10 -6
- package/src/runtime/memory/lib/http-router/session-routes.mjs +3 -2
- package/src/runtime/memory/lib/memory-action-handlers/core-actions.mjs +44 -14
- package/src/runtime/memory/lib/memory-schema/core-and-meta.mjs +11 -0
- package/src/runtime/memory/lib/memory.mjs +7 -1
- package/src/runtime/memory/lib/query-core-recall.mjs +9 -1
- package/src/runtime/memory/lib/query-hybrid-search.mjs +2 -0
- package/src/runtime/memory/lib/tool-call-handler.mjs +2 -0
- package/src/runtime/memory/tool-defs.mjs +5 -0
- package/src/runtime/shared/agent-avatar-sprites.mjs +445 -0
- package/src/runtime/shared/agent-avatar.d.mts +64 -0
- package/src/runtime/shared/agent-avatar.mjs +320 -0
- package/src/runtime/shared/agent-kind.mjs +152 -0
- package/src/runtime/shared/agent-route-config.d.mts +4 -0
- package/src/runtime/shared/agent-route-config.mjs +30 -0
- package/src/runtime/shared/agent-store.mjs +132 -0
- package/src/runtime/shared/atomic-file.mjs +14 -1
- package/src/runtime/shared/bot-split-migration.mjs +457 -0
- package/src/runtime/shared/config-patch.mjs +20 -1
- package/src/runtime/shared/config.mjs +8 -1
- package/src/runtime/shared/connector-accounts.mjs +15 -0
- package/src/runtime/shared/connector-catalog.d.mts +51 -0
- package/src/runtime/shared/connector-catalog.mjs +228 -0
- package/src/runtime/shared/connector-triggers.d.mts +3 -0
- package/src/runtime/shared/connector-triggers.mjs +45 -0
- package/src/runtime/shared/err-text.mjs +3 -1
- package/src/runtime/shared/error-presentation.mjs +91 -6
- package/src/runtime/shared/google-oauth-client.mjs +24 -0
- package/src/runtime/shared/handoff-artifacts.d.mts +20 -0
- package/src/runtime/shared/handoff-artifacts.mjs +61 -0
- package/src/runtime/shared/held-request-host.d.mts +12 -0
- package/src/runtime/shared/held-request-host.mjs +71 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +6 -1
- package/src/runtime/shared/llm/usage-accounting.mjs +7 -1
- package/src/runtime/shared/model-route-fallback.mjs +79 -7
- package/src/runtime/shared/plain-preview.d.mts +1 -0
- package/src/runtime/shared/plain-preview.mjs +33 -0
- package/src/runtime/shared/routine-limits.d.mts +11 -0
- package/src/runtime/shared/routine-limits.mjs +21 -0
- package/src/runtime/shared/routine-trigger.d.mts +10 -0
- package/src/runtime/shared/routine-trigger.mjs +44 -0
- package/src/runtime/shared/schedule-model-ref.mjs +9 -10
- package/src/runtime/shared/sensitive-path-rules.d.mts +15 -0
- package/src/runtime/shared/sensitive-path-rules.mjs +256 -0
- package/src/runtime/shared/slow-span.mjs +4 -12
- package/src/runtime/shared/statusline/statusline-segments.mjs +13 -1
- package/src/runtime/shared/transcript-metadata.mjs +10 -0
- package/src/runtime/shared/turn-changes.mjs +0 -8
- package/src/runtime/shared/usage-readout-totals.mjs +58 -0
- package/src/runtime/shared/user-data-guard.mjs +119 -38
- package/src/session-runtime/agent-home-delivery.mjs +826 -0
- package/src/session-runtime/agent-profile-changes.mjs +21 -0
- package/src/session-runtime/agent-room-delivery.mjs +133 -0
- package/src/session-runtime/agent-task-sessions.mjs +460 -0
- package/src/session-runtime/boot/apis.mjs +63 -18
- package/src/session-runtime/boot/facade.mjs +5 -8
- package/src/session-runtime/boot/infrastructure.mjs +28 -17
- package/src/session-runtime/boot/providers.mjs +14 -4
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/channel-config-api.mjs +53 -5
- package/src/session-runtime/config-lifecycle.mjs +43 -2
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +36 -20
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +6 -1
- package/src/session-runtime/handoff-attachments.mjs +593 -0
- package/src/session-runtime/held-requests.mjs +228 -0
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +121 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +56 -3
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -0
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +4 -0
- package/src/session-runtime/lifecycle/shared.mjs +6 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +8 -0
- package/src/session-runtime/mcp-glue/server-input.mjs +3 -0
- package/src/session-runtime/mcp-oauth-login.mjs +112 -15
- package/src/session-runtime/model-route/route-persist.mjs +2 -2
- package/src/session-runtime/model-route/route-tuning.mjs +7 -1
- package/src/session-runtime/model-route/set-route.mjs +35 -4
- package/src/session-runtime/native-web-search.mjs +2 -2
- package/src/session-runtime/new-session-config.mjs +6 -1
- package/src/session-runtime/owned-automation-run.mjs +229 -0
- package/src/session-runtime/resource-api.mjs +5 -0
- package/src/session-runtime/resource-mcp-api.mjs +107 -13
- package/src/session-runtime/resource-skills-api.mjs +12 -0
- package/src/session-runtime/room-member-gate.mjs +48 -0
- package/src/session-runtime/route-resolution.mjs +5 -11
- package/src/session-runtime/routine-home-turn.mjs +156 -0
- package/src/session-runtime/routine-owner.mjs +48 -0
- package/src/session-runtime/schedule-session-run.mjs +30 -64
- package/src/session-runtime/services/agent-tool/helpers.mjs +30 -1
- package/src/session-runtime/services/agent-tool/send-flow.mjs +11 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +19 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +2 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +4 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +5 -8
- package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
- package/src/session-runtime/services/channel-admin.mjs +93 -24
- package/src/session-runtime/services/memory-access.mjs +37 -0
- package/src/session-runtime/services/provider-admin.mjs +74 -39
- package/src/session-runtime/services/schedule-access.mjs +91 -0
- package/src/session-runtime/session-create/session-options.mjs +34 -7
- package/src/session-runtime/session-hooks.mjs +16 -8
- package/src/session-runtime/setup-tool/executor.mjs +79 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +90 -20
- package/src/session-runtime/setup-tool/settings-contract.mjs +14 -6
- package/src/session-runtime/setup-tool/tool-defs.mjs +8 -0
- package/src/session-runtime/skills-api.mjs +16 -1
- package/src/session-runtime/tool-policy-refresh.mjs +249 -29
- package/src/session-runtime/turn/session-ops.mjs +8 -1
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +10 -2
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +14 -0
- package/src/session-runtime/webhook-session-run.mjs +49 -67
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +239 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +650 -25
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +67 -7
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +11 -4
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +11 -1
- package/src/session-runtime/workflow-agents-api.mjs +4 -1
- package/src/standalone/daemon-agent-control.mjs +1 -8
- package/src/standalone/daemon-session-control.mjs +21 -4
- package/src/standalone/daemon.mjs +31 -5
- package/src/standalone/session-protocol.mjs +27 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +46 -3
- package/src/standalone/session-service/agent-tree.mjs +4 -3
- package/src/standalone/session-service/session-calls/session-turns.mjs +28 -0
- package/src/standalone/session-service.mjs +19 -0
- package/src/tui/app/slash-commands.mjs +20 -0
- package/src/tui/dist/index.mjs +234 -95
- package/src/tui/session/context-state.mjs +6 -1
- package/src/tui/session/notice-surface.mjs +34 -4
- package/src/tui/session/queue-helpers.mjs +2 -1
- package/src/tui/session/session-api/extensions.mjs +4 -0
- package/src/tui/session/session-api/intake/submission.mjs +5 -0
- package/src/tui/session/session-api/integrations.mjs +8 -0
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +13 -3
- package/src/tui/session/session-api/lifecycle.mjs +17 -1
- package/src/tui/session/session-api/routes.mjs +61 -5
- package/src/tui/session/session-flow/drain.mjs +12 -3
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -1
- package/src/tui/session/session-flow/queue/take-entries.mjs +3 -2
- package/src/tui/session/session-flow/steering.mjs +58 -24
- package/src/tui/session/tool-approval.mjs +26 -5
- package/src/tui/session/transcript-intake.mjs +8 -2
- package/src/tui/session/transcript-spill.mjs +5 -1
- package/src/tui/session/tui-steering-persist.mjs +65 -42
- package/src/tui/session/turn-live-call.mjs +64 -0
- package/src/tui/session/turn.mjs +34 -8
- package/src/session-runtime/automation-agents.mjs +0 -94
- package/src/session-runtime/automation-workflow.mjs +0 -59
|
@@ -4,8 +4,22 @@ import { isHiddenAgent } from '../../runtime/agent/orchestrator/internal-agents.
|
|
|
4
4
|
import { normalizeWorkflowRoute } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
|
|
5
5
|
import { ensureProviderEnabled } from '../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
6
6
|
import { resolveRouteContextState, selectionFastCapable } from '../route-state.mjs';
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import {
|
|
8
|
+
canonicalizeAgentRouteStorage,
|
|
9
|
+
isAgentDisabled,
|
|
10
|
+
withAgentDisabled,
|
|
11
|
+
} from '../../runtime/shared/agent-route-config.mjs';
|
|
12
|
+
import { agentEditorId, resolveDataDir } from './shared.mjs';
|
|
13
|
+
import {
|
|
14
|
+
isStoreBot,
|
|
15
|
+
readBotRoute,
|
|
16
|
+
readMixyRoute,
|
|
17
|
+
writeBotRoute,
|
|
18
|
+
writeMixyRoute,
|
|
19
|
+
} from '../../runtime/shared/agent-store.mjs';
|
|
20
|
+
|
|
21
|
+
/** Mixy's runtime id (agent-home.mjs MIXY_AGENT_ID). */
|
|
22
|
+
const MIXY_RUNTIME_ID = 'lead';
|
|
9
23
|
import { routeChain, validateRouteChainProviders } from '../../runtime/shared/model-route-chain.mjs';
|
|
10
24
|
|
|
11
25
|
// Agent route persistence. Route-scope isolation: an agent route owns its
|
|
@@ -23,8 +37,35 @@ export function createAgentRouteApi(deps) {
|
|
|
23
37
|
saveConfigAndAdopt(canonicalizeAgentRouteStorage(withAgentDisabled(getConfig(), id, disabled)));
|
|
24
38
|
}
|
|
25
39
|
|
|
40
|
+
// A bot of the store keeps its route in its own folder (agent-store.mjs);
|
|
41
|
+
// Mixy (`lead` here, its runtime id) keeps its own in bots/mixy — never the
|
|
42
|
+
// Lead's route, which the Main route setter owns.
|
|
43
|
+
const dataDir = () => (deps.cfgMod || deps.STANDALONE_DATA_DIR ? resolveDataDir(deps) : '');
|
|
44
|
+
const isMixy = (id) => id === MIXY_RUNTIME_ID && Boolean(dataDir());
|
|
45
|
+
const storeBot = (id) => isStoreBot(dataDir(), id);
|
|
46
|
+
function saveRoute(id, route, keepOff) {
|
|
47
|
+
if (isMixy(id)) {
|
|
48
|
+
writeMixyRoute(dataDir(), route);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (storeBot(id)) {
|
|
52
|
+
writeBotRoute(dataDir(), id, route);
|
|
53
|
+
saveDisabled(id, keepOff);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const nextConfig = withAgentDisabled(getConfig(), id, keepOff);
|
|
57
|
+
nextConfig.agents = { ...(nextConfig.agents || {}), [id]: route };
|
|
58
|
+
saveConfigAndAdopt(canonicalizeAgentRouteStorage(nextConfig));
|
|
59
|
+
}
|
|
60
|
+
|
|
26
61
|
// Only an explicitly empty provider removes an override: the agent inherits Main.
|
|
27
62
|
function clearOverride(id) {
|
|
63
|
+
if (isMixy(id) || storeBot(id)) {
|
|
64
|
+
if (isMixy(id)) writeMixyRoute(dataDir(), null);
|
|
65
|
+
else writeBotRoute(dataDir(), id, null);
|
|
66
|
+
const inherited = normalizeWorkflowRoute(resolveRoute(getConfig(), {}));
|
|
67
|
+
return { ...(inherited || {}), inherited: true };
|
|
68
|
+
}
|
|
28
69
|
const nextConfig = { ...getConfig() };
|
|
29
70
|
const agents = { ...(nextConfig.agents || {}) };
|
|
30
71
|
const hadOverride = Object.hasOwn(agents, id);
|
|
@@ -83,7 +124,20 @@ export function createAgentRouteApi(deps) {
|
|
|
83
124
|
if (!id) throw new Error(`unknown agent "${agentId}"`);
|
|
84
125
|
if (isHiddenAgent(id)) throw new Error(`agent "${id}" is internal and has no configurable route`);
|
|
85
126
|
const requested = { ...(next || {}) };
|
|
86
|
-
|
|
127
|
+
// Compare-and-set: fill the route only while the agent has none. A route
|
|
128
|
+
// picked while the model resolved below stays (answered with `skipped`).
|
|
129
|
+
const onlyIfEmpty = requested.onlyIfEmpty === true;
|
|
130
|
+
delete requested.onlyIfEmpty;
|
|
131
|
+
const readStored = () => {
|
|
132
|
+
if (isMixy(id)) return readMixyRoute(dataDir()) || {};
|
|
133
|
+
if (storeBot(id)) return readBotRoute(dataDir(), id) || {};
|
|
134
|
+
return agentRouteFromConfig(getConfig(), id) || {};
|
|
135
|
+
};
|
|
136
|
+
const kept = () => ({ ...readStored(), id, skipped: true });
|
|
137
|
+
const stored = readStored();
|
|
138
|
+
if (onlyIfEmpty && clean(stored.provider)) return kept();
|
|
139
|
+
// Mixy is never off: its route request is a model pick alone.
|
|
140
|
+
if (isMixy(id)) delete requested.disabled;
|
|
87
141
|
// Off is an explicit state, stored apart from the route so the model the
|
|
88
142
|
// user picked survives and comes back when the agent is switched on. An
|
|
89
143
|
// off request that also carries a model saves that model and stays off.
|
|
@@ -126,11 +180,17 @@ export function createAgentRouteApi(deps) {
|
|
|
126
180
|
const [primary, ...fallbacks] = resolved;
|
|
127
181
|
const routeToSave = normalizeWorkflowRoute({ ...primary, fallbacks });
|
|
128
182
|
if (!routeToSave) throw new Error('agent route requires provider and model');
|
|
183
|
+
// No await from here to the write: the emptiness checked is the emptiness
|
|
184
|
+
// written over. An off agent stays off when it was only back-filled.
|
|
185
|
+
// A store bot's or Mixy's route is read from its folder on disk right here.
|
|
186
|
+
// An agent routed in the config file may have been written by another
|
|
187
|
+
// process whose change notification is still pending: re-read it first.
|
|
188
|
+
if (onlyIfEmpty && !isMixy(id) && !storeBot(id)) deps.reloadFullConfig?.();
|
|
189
|
+
if (onlyIfEmpty && clean(readStored().provider)) return kept();
|
|
190
|
+
const stayOff = onlyIfEmpty ? isAgentDisabled(getConfig(), id) : keepOff;
|
|
129
191
|
// Picking a model is also the "on" switch unless the request keeps it off.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
saveConfigAndAdopt(canonicalizeAgentRouteStorage(nextConfig));
|
|
133
|
-
return keepOff ? { ...routeToSave, id, disabled: true } : routeToSave;
|
|
192
|
+
saveRoute(id, routeToSave, stayOff);
|
|
193
|
+
return stayOff ? { ...routeToSave, id, disabled: true } : routeToSave;
|
|
134
194
|
}
|
|
135
195
|
|
|
136
196
|
return { setAgentRoute };
|
|
@@ -25,6 +25,7 @@ function applyWorkflowSlots(workflowInput, draft) {
|
|
|
25
25
|
if (!normalized) continue;
|
|
26
26
|
draft.presets = upsertWorkflowPreset(draft.presets, 'lead', normalized);
|
|
27
27
|
draft.defaultPreset = workflowPresetId('lead');
|
|
28
|
+
draft.leadRoute = normalized;
|
|
28
29
|
} else if (slot === 'agent') {
|
|
29
30
|
if (normalized) draft.agentRoutes.worker = normalized;
|
|
30
31
|
else delete draft.agentRoutes.worker;
|
|
@@ -72,10 +73,13 @@ export function createOnboardingApi(deps) {
|
|
|
72
73
|
presets: Array.isArray(nextConfig.presets) ? nextConfig.presets.slice() : [],
|
|
73
74
|
defaultPreset: nextConfig.default,
|
|
74
75
|
agentRoutes: { ...(nextConfig.agents || {}) },
|
|
76
|
+
// The Lead route this save writes, from `defaultRoute` or `workflowRoutes.lead`.
|
|
77
|
+
leadRoute: null,
|
|
75
78
|
};
|
|
76
79
|
if (defaultRoute) {
|
|
77
80
|
draft.presets = upsertWorkflowPreset(draft.presets, 'lead', defaultRoute);
|
|
78
81
|
draft.defaultPreset = workflowPresetId('lead');
|
|
82
|
+
draft.leadRoute = defaultRoute;
|
|
79
83
|
}
|
|
80
84
|
const workflowInput =
|
|
81
85
|
payload.workflowRoutes && typeof payload.workflowRoutes === 'object' ? payload.workflowRoutes : {};
|
|
@@ -104,12 +108,15 @@ export function createOnboardingApi(deps) {
|
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
saveConfigAndAdopt(canonicalizeAgentRouteStorage(nextConfig));
|
|
107
|
-
|
|
111
|
+
// Whatever wrote the Lead route also moves the runtime Main route, in the
|
|
112
|
+
// same synchronous step as the save: a pending conditional backfill then
|
|
113
|
+
// finds a route that is not empty instead of overwriting this choice.
|
|
114
|
+
if (draft.leadRoute) {
|
|
108
115
|
setRouteState(
|
|
109
116
|
resolveRoute(getConfig(), {
|
|
110
|
-
provider:
|
|
111
|
-
model:
|
|
112
|
-
effort:
|
|
117
|
+
provider: draft.leadRoute.provider,
|
|
118
|
+
model: draft.leadRoute.model,
|
|
119
|
+
effort: draft.leadRoute.effort,
|
|
113
120
|
})
|
|
114
121
|
);
|
|
115
122
|
deps.invalidatePreSessionToolSurface?.();
|
|
@@ -48,11 +48,21 @@ export function createWorkflowPacksApi(deps) {
|
|
|
48
48
|
}));
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
// `{ scope: 'session' }` (the composer's selector in a session): a session
|
|
52
|
+
// with a conversation switches alone from its next turn
|
|
53
|
+
// (switchSessionWorkflow) and the configured workflow — the default for new
|
|
54
|
+
// sessions — stays as it is. Without a conversation, and without the
|
|
55
|
+
// scope, the choice becomes the configured workflow and an empty session
|
|
56
|
+
// picks it up in place, as before.
|
|
57
|
+
async function setWorkflow(workflowId, options = {}) {
|
|
52
58
|
const requested = normalizeWorkflowId(workflowId, DEFAULT_WORKFLOW_ID);
|
|
53
59
|
const id = requested === 'solo' ? DEFAULT_WORKFLOW_ID : requested;
|
|
54
60
|
const pack = loadWorkflowPack(resolveDataDir(deps), id);
|
|
55
61
|
if (!pack || pack.id !== id) throw new Error(`workflow "${workflowId}" not found`);
|
|
62
|
+
if (options?.scope === 'session') {
|
|
63
|
+
const switched = await deps.switchSessionWorkflow?.(id);
|
|
64
|
+
if (switched) return { ...switched.workflow, ...switched };
|
|
65
|
+
}
|
|
56
66
|
saveActiveWorkflow(id);
|
|
57
67
|
const applied = await deps.refreshEmptySessionToolPolicy?.();
|
|
58
68
|
deps.invalidatePreSessionToolSurface?.();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createOnboardingApi } from './workflow-agents-api/onboarding.mjs';
|
|
2
2
|
import { createAgentEditorApi } from './workflow-agents-api/agent-editor.mjs';
|
|
3
|
+
import { createAgentConnectorsApi } from './workflow-agents-api/agent-connectors.mjs';
|
|
3
4
|
import { createAgentRouteApi } from './workflow-agents-api/agent-route.mjs';
|
|
4
5
|
import { createWorkflowPacksApi } from './workflow-agents-api/workflow-packs.mjs';
|
|
5
6
|
import { createStyleAndModeApi } from './workflow-agents-api/style-and-mode.mjs';
|
|
@@ -11,9 +12,11 @@ import { createStyleAndModeApi } from './workflow-agents-api/style-and-mode.mjs'
|
|
|
11
12
|
// getOnboardingStatus from the composed runtime API through `this`.
|
|
12
13
|
export function createWorkflowAgentsApi(deps) {
|
|
13
14
|
const routeApi = createAgentRouteApi(deps);
|
|
15
|
+
const editorApi = createAgentEditorApi({ ...deps, setAgentRoute: routeApi.setAgentRoute });
|
|
14
16
|
return {
|
|
15
17
|
...createOnboardingApi(deps),
|
|
16
|
-
...
|
|
18
|
+
...editorApi,
|
|
19
|
+
...createAgentConnectorsApi(deps, editorApi),
|
|
17
20
|
...routeApi,
|
|
18
21
|
...createWorkflowPacksApi(deps),
|
|
19
22
|
...createStyleAndModeApi(deps),
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
// this control exists — the host takes `execute` as a constructor option), and
|
|
9
9
|
// `cwd`. Output: { canonicalAgentTool, execute }.
|
|
10
10
|
|
|
11
|
-
import { deliverAutomationCompletion } from '../session-runtime/automation-agents.mjs';
|
|
12
|
-
|
|
13
11
|
export function createCanonicalAgentControl({ getSessionService, getSessionRuntimeHost, cwd }) {
|
|
14
12
|
let canonicalAgentToolPromise = null;
|
|
15
13
|
|
|
@@ -34,12 +32,7 @@ export function createCanonicalAgentControl({ getSessionService, getSessionRunti
|
|
|
34
32
|
isKeychainPrewarmReady: () => true,
|
|
35
33
|
sessionSurface: sessionService.agentSurface,
|
|
36
34
|
notifySessionCompletion(ownerSessionId, text, meta = {}) {
|
|
37
|
-
|
|
38
|
-
// agent-result waiter takes the completions it is owed.
|
|
39
|
-
return (
|
|
40
|
-
getSessionRuntimeHost()?.notifySessionCompletion?.(ownerSessionId, text, meta) === true ||
|
|
41
|
-
deliverAutomationCompletion(ownerSessionId, text, meta)
|
|
42
|
-
);
|
|
35
|
+
return getSessionRuntimeHost()?.notifySessionCompletion?.(ownerSessionId, text, meta) === true;
|
|
43
36
|
},
|
|
44
37
|
});
|
|
45
38
|
})
|
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
import { SESSION_ID_PATTERN } from '../runtime/agent/orchestrator/runtime-core/session-id.mjs';
|
|
2
2
|
import { sessionListOutput, sessionReadOutput, SESSION_TOOL_OUTPUT_BYTES } from './session-tool-output.mjs';
|
|
3
|
+
import { createAgentTaskSessions } from '../session-runtime/agent-task-sessions.mjs';
|
|
4
|
+
import { handoffContent } from '../session-runtime/handoff-attachments.mjs';
|
|
3
5
|
|
|
4
6
|
const TARGET_ACTIONS = new Set(['status', 'read', 'send', 'cancel', 'delete']);
|
|
5
7
|
const MUTATING_ACTIONS = new Set(['send', 'cancel', 'delete']);
|
|
6
8
|
|
|
7
9
|
/** Model-facing session operations over the same service used by desktop and TUI. */
|
|
8
|
-
export function createSessionControl({
|
|
10
|
+
export function createSessionControl({
|
|
11
|
+
getSessionService,
|
|
12
|
+
agentTasks = createAgentTaskSessions({ getSessionService }),
|
|
13
|
+
}) {
|
|
9
14
|
return async function executeSessionControl(args = {}, context = {}) {
|
|
10
15
|
const action = args.action;
|
|
11
|
-
if (action !== 'list' && !TARGET_ACTIONS.has(action)) {
|
|
16
|
+
if (action !== 'list' && action !== 'create' && !TARGET_ACTIONS.has(action)) {
|
|
12
17
|
throw new Error(`session: unsupported remote action "${action}"`);
|
|
13
18
|
}
|
|
14
19
|
const caller = context.callerSessionId;
|
|
15
20
|
if (typeof caller !== 'string' || !SESSION_ID_PATTERN.test(caller)) {
|
|
16
21
|
throw new Error('session: caller session is required');
|
|
17
22
|
}
|
|
23
|
+
// `callerAgentId`: set only for an attended agent conversation (workspace-tools.mjs).
|
|
24
|
+
if (action === 'create') return agentTasks.create(args, context);
|
|
18
25
|
const sessionId = typeof args.session_id === 'string' ? args.session_id.trim() : '';
|
|
19
26
|
if (TARGET_ACTIONS.has(action) && (typeof sessionId !== 'string' || !SESSION_ID_PATTERN.test(sessionId))) {
|
|
20
27
|
throw new Error(`session: session_id is required for action=${action}`);
|
|
@@ -45,12 +52,22 @@ export function createSessionControl({ getSessionService }) {
|
|
|
45
52
|
if (typeof args.prompt !== 'string' || !args.prompt.trim()) {
|
|
46
53
|
throw new Error('session: prompt is required for action=send');
|
|
47
54
|
}
|
|
55
|
+
// An agent conversation's send reports its turn back to the agent's
|
|
56
|
+
// home: a task session it created by its stored origin, any other
|
|
57
|
+
// session by an origin for this send only.
|
|
58
|
+
// Forwarded files ride along as stored attachment parts (workspace-tools.mjs).
|
|
59
|
+
const prompt = handoffContent(args.prompt, context.attachmentParts);
|
|
60
|
+
const origin = await agentTasks.reportOrigin(sessionId, context.callerAgentId, caller);
|
|
61
|
+
if (origin) {
|
|
62
|
+
const { accepted, reportsBack } = await agentTasks.send(sessionId, prompt, origin);
|
|
63
|
+
return { sessionId, accepted, reportsBack };
|
|
64
|
+
}
|
|
48
65
|
const result = await service.submitSession({
|
|
49
66
|
sessionId,
|
|
50
|
-
prompt
|
|
67
|
+
prompt,
|
|
51
68
|
options: { mode: 'prompt', transcriptMeta: { sender: 'lead' } },
|
|
52
69
|
});
|
|
53
|
-
return { sessionId, accepted: result.accepted === true };
|
|
70
|
+
return { sessionId, accepted: result.accepted === true, reportsBack: false };
|
|
54
71
|
}
|
|
55
72
|
if (action === 'cancel') {
|
|
56
73
|
const result = await service.abortSession({ sessionId });
|
|
@@ -77,6 +77,8 @@ import { createStoredSessionViews } from './daemon-stored-session-views.mjs';
|
|
|
77
77
|
import * as quotaResumeStore from '../runtime/shared/quota-resume-store.mjs';
|
|
78
78
|
import { registerWorktreeCacheCleanups } from '../runtime/shared/worktrees/cache-cleanups.mjs';
|
|
79
79
|
import { createInlineSessionRuntimeHost } from './session-runtime-inline-host.mjs';
|
|
80
|
+
import { recoverScheduleResults, setAgentHomeLiveSurface } from '../session-runtime/agent-home-delivery.mjs';
|
|
81
|
+
import { recoverRoutineDeliveries } from '../session-runtime/owned-automation-run.mjs';
|
|
80
82
|
import { getStandaloneMemoryRuntime } from '../session-runtime/services/memory-runtime-proxy.mjs';
|
|
81
83
|
import { registerTranscriptPurgeHook } from '../session-runtime/session-transcript-purge.mjs';
|
|
82
84
|
import { createBootPhaseProfiler } from './boot-phase-profiler.mjs';
|
|
@@ -94,8 +96,8 @@ import { createChannelsRuntimeLoader } from './daemon-channels-loader.mjs';
|
|
|
94
96
|
import { createDesktopRuntime } from './daemon-desktop-runtime.mjs';
|
|
95
97
|
import { createCanonicalAgentControl } from './daemon-agent-control.mjs';
|
|
96
98
|
import { createSessionControl } from './daemon-session-control.mjs';
|
|
99
|
+
import { createAgentTaskSessions } from '../session-runtime/agent-task-sessions.mjs';
|
|
97
100
|
import { flushAllIndexWrites } from '../session-runtime/services/agent-tool/index-write-queue.mjs';
|
|
98
|
-
import { registerAutomationAgentTool } from '../session-runtime/automation-agents.mjs';
|
|
99
101
|
import {
|
|
100
102
|
compareRuntimeVersions,
|
|
101
103
|
SESSION_CAPABILITY_FINGERPRINT,
|
|
@@ -925,9 +927,8 @@ async function main() {
|
|
|
925
927
|
cwd: CWD,
|
|
926
928
|
});
|
|
927
929
|
canonicalAgentControl = agentControl;
|
|
928
|
-
//
|
|
929
|
-
|
|
930
|
-
registerAutomationAgentTool(agentControl.execute);
|
|
930
|
+
// Agents' cross-session sends and task sessions, and their report watches.
|
|
931
|
+
const agentTasks = createAgentTaskSessions({ getSessionService: () => sessionService });
|
|
931
932
|
const requestedRuntimeMode = String(process.env.MIXDOG_SESSION_RUNTIME_MODE || '')
|
|
932
933
|
.trim()
|
|
933
934
|
.toLowerCase();
|
|
@@ -941,7 +942,7 @@ async function main() {
|
|
|
941
942
|
log,
|
|
942
943
|
measureBootPhase: bootPhases.measure,
|
|
943
944
|
executeAgentControl: agentControl.execute,
|
|
944
|
-
executeSessionControl: createSessionControl({ getSessionService: () => sessionService }),
|
|
945
|
+
executeSessionControl: createSessionControl({ getSessionService: () => sessionService, agentTasks }),
|
|
945
946
|
});
|
|
946
947
|
// Codex-style runtime: daemon routing and independent async session actors
|
|
947
948
|
// share one V8 isolate and module graph. CPU-heavy work stays in bounded
|
|
@@ -984,6 +985,31 @@ async function main() {
|
|
|
984
985
|
},
|
|
985
986
|
log,
|
|
986
987
|
});
|
|
988
|
+
// Schedule results reach an open home thread at once (and wait out its turn).
|
|
989
|
+
setAgentHomeLiveSurface({
|
|
990
|
+
busy: (sessionId) => sessionService.liveSessionBusy(sessionId),
|
|
991
|
+
notice: (sessionId, notice) => sessionService.pushLiveSessionNotice(sessionId, notice),
|
|
992
|
+
// A task session's result (session create): the agent relays it in one
|
|
993
|
+
// turn. Resolves whether the turn was taken.
|
|
994
|
+
wake: async (sessionId, prompt, { id } = {}) =>
|
|
995
|
+
(
|
|
996
|
+
await sessionService.submitSession({
|
|
997
|
+
sessionId,
|
|
998
|
+
prompt,
|
|
999
|
+
options: { mode: 'prompt', kickoff: true, ...(id ? { id } : {}) },
|
|
1000
|
+
})
|
|
1001
|
+
)?.accepted === true,
|
|
1002
|
+
// A routine fire: one queued turn in its bot's thread (routine-home-turn.mjs).
|
|
1003
|
+
submit: async (sessionId, prompt, options) =>
|
|
1004
|
+
(await sessionService.submitSession({ sessionId, prompt, options }))?.accepted === true,
|
|
1005
|
+
abort: (sessionId) => sessionService.abortSession({ sessionId }),
|
|
1006
|
+
});
|
|
1007
|
+
// Results queued before a restart are posted now; results a finished run
|
|
1008
|
+
// could not queue (kept on its routine's record) are queued again.
|
|
1009
|
+
recoverScheduleResults().catch((error) => log(`routine results recovery failed: ${error?.message || error}`));
|
|
1010
|
+
// Agents' sends whose report an earlier process had not queued yet.
|
|
1011
|
+
agentTasks.recover().catch((error) => log(`agent task report recovery failed: ${error?.message || error}`));
|
|
1012
|
+
recoverRoutineDeliveries().catch((error) => log(`routine delivery recovery failed: ${error?.message || error}`));
|
|
987
1013
|
sessionTransport = createSessionTransport({
|
|
988
1014
|
// ctx carries the CLIENT token: the session service refcounts views across
|
|
989
1015
|
// processes with it, so a terminal exiting cannot destroy the session a
|
|
@@ -9,7 +9,18 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
9
9
|
'inspectProjectBranch',
|
|
10
10
|
'isSessionTerminal',
|
|
11
11
|
'contextStatus',
|
|
12
|
+
'agentDefinitionPresence',
|
|
13
|
+
'archivedAgentIdentities',
|
|
12
14
|
'getAgentDefinition',
|
|
15
|
+
'getAgentAvatarImage',
|
|
16
|
+
'getAgentConnectors',
|
|
17
|
+
'getProjectConnectors',
|
|
18
|
+
'getAgentPermissions',
|
|
19
|
+
'listConnectors',
|
|
20
|
+
'listConnectorTools',
|
|
21
|
+
'getLeadPersona',
|
|
22
|
+
'getLeadAgentBody',
|
|
23
|
+
'getLeadStatus',
|
|
13
24
|
'getAutoClear',
|
|
14
25
|
'getChannelSettings',
|
|
15
26
|
'getChannelSetup',
|
|
@@ -91,6 +102,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
91
102
|
'addPlugin',
|
|
92
103
|
'addSkill',
|
|
93
104
|
'agentControl',
|
|
105
|
+
'appendRoomRows',
|
|
94
106
|
'askSide',
|
|
95
107
|
'authenticateProvider',
|
|
96
108
|
'beginOAuthProviderLogin',
|
|
@@ -111,6 +123,8 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
111
123
|
'consumeCodexRateLimitResetCredit',
|
|
112
124
|
'createWorkflow',
|
|
113
125
|
'deleteAgentDefinition',
|
|
126
|
+
'restoreAgentDefinition',
|
|
127
|
+
'purgeAgentDefinition',
|
|
114
128
|
'deleteHookRule',
|
|
115
129
|
'deleteMediaAsset',
|
|
116
130
|
'deleteMediaAssets',
|
|
@@ -142,7 +156,9 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
142
156
|
'reloadSkills',
|
|
143
157
|
'rememberPromptHistory',
|
|
144
158
|
'removeMcpServer',
|
|
159
|
+
'removeSkill',
|
|
145
160
|
'continueSessionInModel',
|
|
161
|
+
'decideRoomTurn',
|
|
146
162
|
'scheduleQuotaResume',
|
|
147
163
|
'cancelQuotaResume',
|
|
148
164
|
'retryFailedTurn',
|
|
@@ -164,7 +180,18 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
164
180
|
'runDoctor',
|
|
165
181
|
'runScheduleNow',
|
|
166
182
|
'runUpdateNow',
|
|
183
|
+
'runWebhookNow',
|
|
184
|
+
'retryRoutineDelivery',
|
|
167
185
|
'saveAgentDefinition',
|
|
186
|
+
'setAgentConnectors',
|
|
187
|
+
'setAgentConnectorEnabled',
|
|
188
|
+
'setAgentConnectorToolPermission',
|
|
189
|
+
'setProjectConnectorEnabled',
|
|
190
|
+
'setAgentPermission',
|
|
191
|
+
'saveLeadPersona',
|
|
192
|
+
'saveLeadAgentBody',
|
|
193
|
+
'setLeadCreated',
|
|
194
|
+
'saveLeadIdentity',
|
|
168
195
|
'saveMcpServer',
|
|
169
196
|
'saveOpenAIUsageSessionKey',
|
|
170
197
|
'saveProviderApiKey',
|
|
@@ -4,6 +4,43 @@
|
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
import { createAgentChildFactory } from './agent-child.mjs';
|
|
6
6
|
import { partialHandoffTextFromSession } from '../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
|
|
7
|
+
import { attachmentsForIntake } from '../../../runtime/attachments/store.mjs';
|
|
8
|
+
import { artifactLines } from '../../../runtime/shared/handoff-artifacts.mjs';
|
|
9
|
+
import { collectTurnArtifacts, handoffContent, sessionRoots } from '../../../session-runtime/handoff-attachments.mjs';
|
|
10
|
+
|
|
11
|
+
/** An agent turn's prompt: text, or text with forwarded attachment parts
|
|
12
|
+
* (handoff-attachments.mjs), never any other shape. */
|
|
13
|
+
export function agentTurnContent(prompt) {
|
|
14
|
+
if (!Array.isArray(prompt)) return String(prompt || '');
|
|
15
|
+
const text = prompt
|
|
16
|
+
.filter((part) => part?.type === 'text' && !part.attachmentRef)
|
|
17
|
+
.map((part) => String(part.text || ''))
|
|
18
|
+
.join('\n');
|
|
19
|
+
return handoffContent(text, prompt);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** The prompt row's metadata: a Lead's message, with the files it carries. */
|
|
23
|
+
export function agentTurnTranscriptMeta(content) {
|
|
24
|
+
const attachments = Array.isArray(content) ? attachmentsForIntake(content) : [];
|
|
25
|
+
return { sender: 'lead', ...(attachments.length ? { attachments } : {}) };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The artifact lines of the turn that began at `messageStart`; [] on any
|
|
29
|
+
* failure to read it (the handoff still goes out). */
|
|
30
|
+
async function turnArtifactLines(runtime, messageStart, descriptor) {
|
|
31
|
+
try {
|
|
32
|
+
const { messages } = await runtime.readModelMessages(messageStart);
|
|
33
|
+
const session = runtime.session || descriptor;
|
|
34
|
+
const { files, omitted } = collectTurnArtifacts(messages, {
|
|
35
|
+
cwd: descriptor.cwd,
|
|
36
|
+
roots: sessionRoots(session, descriptor.cwd),
|
|
37
|
+
});
|
|
38
|
+
// Text only: the caller forwards these by path (an id in text is never trusted).
|
|
39
|
+
return artifactLines(files, omitted, { ids: false });
|
|
40
|
+
} catch {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
7
44
|
|
|
8
45
|
export function createAgentTurns({
|
|
9
46
|
registry,
|
|
@@ -67,15 +104,16 @@ export function createAgentTurns({
|
|
|
67
104
|
descriptor.stage = 'running';
|
|
68
105
|
descriptor.updatedAt = Date.now();
|
|
69
106
|
try {
|
|
107
|
+
const content = agentTurnContent(prompt);
|
|
70
108
|
const options = {
|
|
71
109
|
id: `agent-turn-${randomUUID()}`,
|
|
72
110
|
mode: 'prompt',
|
|
73
111
|
priority: 'next',
|
|
74
112
|
context,
|
|
75
|
-
transcriptMeta:
|
|
113
|
+
transcriptMeta: agentTurnTranscriptMeta(content),
|
|
76
114
|
...(entry.runtime.isWireSafe === true || typeof onToolResult !== 'function' ? {} : { onToolResult }),
|
|
77
115
|
};
|
|
78
|
-
const detail = await target.call(entry.runtime,
|
|
116
|
+
const detail = await target.call(entry.runtime, content, options);
|
|
79
117
|
if (detail?.status === 'failed') {
|
|
80
118
|
throw new Error(String(detail.error || 'agent session turn failed'));
|
|
81
119
|
}
|
|
@@ -91,7 +129,12 @@ export function createAgentTurns({
|
|
|
91
129
|
const reason = String(detail?.reason || detail?.error || '').trim();
|
|
92
130
|
throw new Error(`agent turn ${status}${reason ? `: ${reason}` : ''}`);
|
|
93
131
|
}
|
|
94
|
-
|
|
132
|
+
let result = detail?.result || { content: '' };
|
|
133
|
+
// The files the turn produced reach the owner with its handoff.
|
|
134
|
+
const files = await turnArtifactLines(entry.runtime, messageStart, descriptor);
|
|
135
|
+
if (files.length) {
|
|
136
|
+
result = { ...result, content: [String(result.content || ''), files.join('\n')].join('\n\n') };
|
|
137
|
+
}
|
|
95
138
|
descriptor.status = 'idle';
|
|
96
139
|
descriptor.stage = 'idle';
|
|
97
140
|
descriptor.lastHandoff = typeof result?.content === 'string' ? result.content : '';
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { createAgentCancellation } from './agent-tree/agent-cancel.mjs';
|
|
11
11
|
import { createAgentRegistry } from './agent-tree/agent-registry.mjs';
|
|
12
12
|
import { createAgentRehydration, lastStoredAgentHandoff } from './agent-tree/agent-rehydrate.mjs';
|
|
13
|
-
import { createAgentTurns } from './agent-tree/agent-turns.mjs';
|
|
13
|
+
import { agentTurnContent, agentTurnTranscriptMeta, createAgentTurns } from './agent-tree/agent-turns.mjs';
|
|
14
14
|
import { randomUUID } from 'node:crypto';
|
|
15
15
|
|
|
16
16
|
export { SESSION_ID_PATTERN } from './agent-tree/agent-registry.mjs';
|
|
@@ -139,12 +139,13 @@ export function createAgentTree({
|
|
|
139
139
|
const cancelEpoch = registry.assertAdmission(descriptor.id);
|
|
140
140
|
const runtime = sessionOwner(descriptor.id)?.runtime;
|
|
141
141
|
if (!runtime || !stateBusy(runtime.getState())) return null;
|
|
142
|
-
const
|
|
142
|
+
const content = agentTurnContent(prompt);
|
|
143
|
+
const accepted = await runtime.submitAsync(content, {
|
|
143
144
|
id: `agent-message-${randomUUID()}`,
|
|
144
145
|
mode: 'prompt',
|
|
145
146
|
priority: 'next',
|
|
146
147
|
context,
|
|
147
|
-
transcriptMeta:
|
|
148
|
+
transcriptMeta: agentTurnTranscriptMeta(content),
|
|
148
149
|
});
|
|
149
150
|
if (accepted === false) throw new Error('agent follow-up was not accepted');
|
|
150
151
|
registry.assertAdmission(descriptor.id, cancelEpoch);
|
|
@@ -11,6 +11,10 @@ import {
|
|
|
11
11
|
} from '../../../runtime/attachments/store.mjs';
|
|
12
12
|
import { providerNativePdf } from '../../../runtime/agent/orchestrator/providers/registry.mjs';
|
|
13
13
|
import { cancelBackgroundTasks } from '../../../runtime/shared/background-tasks.mjs';
|
|
14
|
+
import { isAgentModeSession } from '../../../runtime/agent/orchestrator/session/agent-mode.mjs';
|
|
15
|
+
import { isAgentHomeSessionId } from '../../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
16
|
+
import { recognisedAgentRoomSlash } from '../../../tui/app/slash-commands.mjs';
|
|
17
|
+
import { promptContentText } from '../../../tui/session/queue-helpers.mjs';
|
|
14
18
|
|
|
15
19
|
/** Whether an abort on this session is an Agent cancelling its own turn: the
|
|
16
20
|
* catalog knows it, the runtime declares agent-only visibility, or it is a
|
|
@@ -35,6 +39,17 @@ function abortsAgentTurn(id, state, hasAgentSession) {
|
|
|
35
39
|
);
|
|
36
40
|
}
|
|
37
41
|
|
|
42
|
+
/** A prompt the user typed: not an agent's send (`sender: 'lead'`), a hidden
|
|
43
|
+
* wake, a routine fire or any other runtime-made turn. */
|
|
44
|
+
export function isUserTurn(options = {}) {
|
|
45
|
+
return (
|
|
46
|
+
(options.mode || 'prompt') === 'prompt' &&
|
|
47
|
+
options.kickoff !== true &&
|
|
48
|
+
options.isMeta !== true &&
|
|
49
|
+
options.transcriptMeta?.sender !== 'lead'
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
38
53
|
export function createSessionTurnCalls(ctx) {
|
|
39
54
|
const { log, readStoredGoal, listStoredActiveGoalSessionIds, hasAgentSession, sessionResult, advanceForCaller } = ctx;
|
|
40
55
|
const { retainUnwatched } = ctx.retention;
|
|
@@ -76,9 +91,22 @@ export function createSessionTurnCalls(ctx) {
|
|
|
76
91
|
},
|
|
77
92
|
};
|
|
78
93
|
}
|
|
94
|
+
// A bot's conversation room runs only its own /compact and /clear (the
|
|
95
|
+
// composer's rule): every other leading `/` is message text for the model.
|
|
96
|
+
if (isAgentModeSession(entry.runtime.session ?? { id })) {
|
|
97
|
+
const text = typeof intake.prompt === 'string' ? intake.prompt : promptContentText(intake.prompt);
|
|
98
|
+
if (!recognisedAgentRoomSlash(text)) submissionOptions = { ...submissionOptions, skipSlashCommands: true };
|
|
99
|
+
}
|
|
79
100
|
const accepted = await Promise.resolve(target.call(entry.runtime, intake.prompt, submissionOptions));
|
|
80
101
|
if (accepted === true) {
|
|
81
102
|
entry.reservedOnly = false;
|
|
103
|
+
if (isAgentHomeSessionId(id) && isUserTurn(submissionOptions)) {
|
|
104
|
+
// The user spoke in this agent's home: its round trips with other
|
|
105
|
+
// sessions count from zero again, so a capped thread wakes again.
|
|
106
|
+
void import('../../../session-runtime/agent-home-delivery.mjs')
|
|
107
|
+
.then(({ resetAgentTaskRounds }) => resetAgentTaskRounds(id))
|
|
108
|
+
.catch((error) => log(`round reset of ${id} failed: ${error?.message || error}`));
|
|
109
|
+
}
|
|
82
110
|
}
|
|
83
111
|
const step = settleAction(entry, 'headless session submit');
|
|
84
112
|
log(`session submit session=${id} accepted=${accepted === true}`);
|
|
@@ -237,6 +237,23 @@ export function createSessionService({
|
|
|
237
237
|
return stopPromise;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
+
/** Whether the runtime hosting `sessionId` is mid-turn or holds queued input. */
|
|
241
|
+
function liveSessionBusy(sessionId) {
|
|
242
|
+
const owner = projection.sessionOwner(sessionId);
|
|
243
|
+
return Boolean(owner) && retention.stateBusy(owner.runtime?.getState?.());
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** Show a transcript notice in the hosted runtime of `sessionId` (no turn)
|
|
247
|
+
* and publish it to its views; false when no runtime hosts it. */
|
|
248
|
+
function pushLiveSessionNotice(sessionId, { text, tone = 'info', ...options } = {}) {
|
|
249
|
+
const owner = projection.sessionOwner(sessionId);
|
|
250
|
+
if (typeof owner?.runtime?.pushNotice !== 'function') return false;
|
|
251
|
+
owner.runtime.pushNotice(text, tone, { ...options, transcript: true });
|
|
252
|
+
const step = projection.advance(owner);
|
|
253
|
+
if (step.changed) projection.publishStep(owner, step);
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
|
|
240
257
|
function getStatus() {
|
|
241
258
|
const busy = retention.liveBusyCount();
|
|
242
259
|
let watched = 0;
|
|
@@ -282,6 +299,8 @@ export function createSessionService({
|
|
|
282
299
|
},
|
|
283
300
|
methods: {
|
|
284
301
|
...calls,
|
|
302
|
+
liveSessionBusy,
|
|
303
|
+
pushLiveSessionNotice,
|
|
285
304
|
stop,
|
|
286
305
|
startQuotaResume: () => quotaResume?.start(),
|
|
287
306
|
runDueQuotaResumes: () => quotaResume?.tick() ?? Promise.resolve(),
|
|
@@ -142,6 +142,26 @@ for (const command of SLASH_COMMANDS) {
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
/**
|
|
146
|
+
* The registered command a prompt runs, by the renderer's rule
|
|
147
|
+
* (apps/desktop renderer/slash-commands.ts recognisedSlashSpan): the text,
|
|
148
|
+
* trimmed, begins with `/` and its first whitespace-delimited token names a
|
|
149
|
+
* command or alias. Returns that token lowercased, else null: any other
|
|
150
|
+
* leading `/` (an absolute path, a stray word) is ordinary message text.
|
|
151
|
+
*/
|
|
152
|
+
export function recognisedSlashToken(text) {
|
|
153
|
+
const token = /^\s*\/(\S+)/.exec(String(text ?? ''))?.[1].toLowerCase();
|
|
154
|
+
return token && SLASH_COMMAND_BY_TOKEN.has(token) ? token : null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** The only commands a bot's conversation room runs, by their literal name
|
|
158
|
+
* (`/new` stays text); mirrors the renderer's recognisedAgentRoomSlash. */
|
|
159
|
+
const AGENT_ROOM_SLASH_TOKENS = new Set(['compact', 'clear']);
|
|
160
|
+
|
|
161
|
+
export function recognisedAgentRoomSlash(text) {
|
|
162
|
+
return AGENT_ROOM_SLASH_TOKENS.has(recognisedSlashToken(text));
|
|
163
|
+
}
|
|
164
|
+
|
|
145
165
|
export function normalizeSlashCommandName(cmd) {
|
|
146
166
|
const name = String(cmd || '').toLowerCase();
|
|
147
167
|
return SLASH_COMMAND_BY_TOKEN.get(name)?.name || name;
|