mixdog 1.2.6 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/simple-icons-CC0-1.0.txt +30 -0
- package/NOTICE.md +19 -0
- 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 +7 -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 +11 -4
- package/src/defaults/skills/setup-guide/SKILL.md +175 -0
- package/src/defaults/skills/setup-guide/model-recommendations.json +333 -0
- package/src/lib/rules-builder.cjs +55 -6
- 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 +21 -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 +182 -13
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +4 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +215 -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-login.mjs +10 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- 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/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 +12 -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 +10 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +50 -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 +162 -0
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +641 -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 +165 -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/pre-dispatch-deny.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +16 -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 +7 -0
- 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/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 +27 -5
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +55 -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/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 +24 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +32 -5
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +70 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +277 -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 +44 -1
- 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/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/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-route-config.d.mts +3 -0
- package/src/runtime/shared/agent-route-config.mjs +16 -0
- package/src/runtime/shared/atomic-file.mjs +14 -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 +52 -0
- package/src/runtime/shared/connector-catalog.mjs +230 -0
- package/src/runtime/shared/connector-triggers.d.mts +3 -0
- package/src/runtime/shared/connector-triggers.mjs +43 -0
- package/src/runtime/shared/google-oauth-client.mjs +24 -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/plain-preview.d.mts +1 -0
- package/src/runtime/shared/plain-preview.mjs +28 -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/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 +56 -0
- package/src/runtime/shared/user-data-guard.mjs +114 -36
- package/src/session-runtime/agent-home-delivery.mjs +459 -0
- package/src/session-runtime/agent-profile-changes.mjs +21 -0
- package/src/session-runtime/agent-room-delivery.mjs +92 -0
- package/src/session-runtime/agent-task-sessions.mjs +200 -0
- package/src/session-runtime/boot/apis.mjs +50 -18
- package/src/session-runtime/boot/facade.mjs +5 -8
- package/src/session-runtime/boot/infrastructure.mjs +28 -17
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/channel-config-api.mjs +53 -5
- 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/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 +31 -2
- 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/set-route.mjs +14 -3
- 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/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 +10 -0
- 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/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 +68 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +72 -14
- package/src/session-runtime/setup-tool/settings-contract.mjs +8 -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 +238 -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 +3 -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 +556 -22
- 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 +11 -2
- package/src/standalone/daemon.mjs +18 -4
- package/src/standalone/session-protocol.mjs +27 -0
- package/src/standalone/session-service/session-calls/session-turns.mjs +9 -0
- package/src/standalone/session-service.mjs +19 -0
- package/src/tui/app/slash-commands.mjs +20 -0
- package/src/tui/dist/index.mjs +164 -86
- package/src/tui/session/context-state.mjs +6 -1
- package/src/tui/session/notice-surface.mjs +35 -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 +48 -3
- 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 +6 -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 +56 -0
- package/src/tui/session/turn.mjs +22 -6
- package/src/session-runtime/automation-agents.mjs +0 -94
- package/src/session-runtime/automation-workflow.mjs +0 -59
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Refresh the empty Lead session's model-facing tool surface and BP1/BP3
|
|
2
2
|
// layers after workflow or search/memory settings change. Conversation
|
|
3
3
|
// sessions keep their frozen schema; the next new session picks up the
|
|
4
|
-
// updated policy.
|
|
4
|
+
// updated policy. The one exception is a workflow switch made in the session
|
|
5
|
+
// itself (switchSessionWorkflow), which rebuilds that conversation's policy.
|
|
5
6
|
import { sessionHasConversationMessages } from '../runtime/agent/orchestrator/runtime-core/session-text.mjs';
|
|
6
7
|
import { toSessionWorkflowMeta } from '../runtime/agent/orchestrator/runtime-core/workflow.mjs';
|
|
7
8
|
import {
|
|
@@ -21,7 +22,25 @@ import {
|
|
|
21
22
|
} from '../runtime/agent/orchestrator/session/manager/session-tool-surface.mjs';
|
|
22
23
|
import { finalizeSessionToolList } from '../runtime/agent/orchestrator/session/manager/tool-resolution.mjs';
|
|
23
24
|
import { isAgentOwner } from '../runtime/agent/orchestrator/agent-owner.mjs';
|
|
25
|
+
import {
|
|
26
|
+
AGENT_MODE,
|
|
27
|
+
isRoutineSource,
|
|
28
|
+
resolveSessionMode,
|
|
29
|
+
sessionModeOf,
|
|
30
|
+
} from '../runtime/agent/orchestrator/session/agent-mode.mjs';
|
|
24
31
|
import { unusedModelEditToolName } from '../runtime/shared/edit-tool-dialect.mjs';
|
|
32
|
+
import { MIXY_AGENT_ID } from '../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
33
|
+
import {
|
|
34
|
+
refreshSessionBp3Environment,
|
|
35
|
+
withPresentedWorkspaceSlices,
|
|
36
|
+
} from '../runtime/agent/orchestrator/session/manager/prompt-utils.mjs';
|
|
37
|
+
import { stageWorkflowSwitchNotice } from '../runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs';
|
|
38
|
+
import { markToolSurfaceMigrated } from '../runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs';
|
|
39
|
+
import { agentProfileRevision, leadRosterRevision } from '../runtime/agent/orchestrator/context/role-instructions.mjs';
|
|
40
|
+
import { recordTranscriptBoundary } from './model-route/set-route.mjs';
|
|
41
|
+
|
|
42
|
+
const WORKFLOW_SWITCH_BUSY = 'The session is running a turn; wait for it to finish.';
|
|
43
|
+
const AGENT_PROFILE_INTENT = 'agent_profile';
|
|
25
44
|
|
|
26
45
|
function toolNames(list) {
|
|
27
46
|
return (Array.isArray(list) ? list : [])
|
|
@@ -46,16 +65,28 @@ function rewriteSystemHeading(session, heading, nextContent) {
|
|
|
46
65
|
if (target) replaceMessageContent(messages, target, nextContent);
|
|
47
66
|
}
|
|
48
67
|
|
|
49
|
-
function
|
|
68
|
+
function bp3Message(session) {
|
|
50
69
|
const messages = Array.isArray(session.messages) ? session.messages : [];
|
|
51
|
-
|
|
70
|
+
return (
|
|
52
71
|
messages.find((message) => message?.role === 'system' && message.cacheTier === 'tier3') ||
|
|
53
72
|
messages.find(
|
|
54
73
|
(message) =>
|
|
55
74
|
message?.role === 'system' &&
|
|
56
75
|
typeof message.content === 'string' &&
|
|
57
76
|
message.content.startsWith('# Active Workflow:')
|
|
58
|
-
)
|
|
77
|
+
)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// The BP3 core the session's prompt carries now (split layout: the whole
|
|
82
|
+
// tier3 block; combined: the stored core beside the environment).
|
|
83
|
+
function presentedBp3Core(session) {
|
|
84
|
+
return session.bp3EnvSplit === true ? bp3Message(session)?.content : session.bp3CoreContext;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function rewriteBp3Core(session, nextCore) {
|
|
88
|
+
const messages = Array.isArray(session.messages) ? session.messages : [];
|
|
89
|
+
const bp3 = bp3Message(session);
|
|
59
90
|
if (!bp3 || typeof bp3.content !== 'string') return;
|
|
60
91
|
if (session.bp3EnvSplit === true) {
|
|
61
92
|
// Split layout: the environment lives in its own cacheTier:'env' system
|
|
@@ -69,6 +100,27 @@ function rewriteBp3Core(session, nextCore) {
|
|
|
69
100
|
session.bp3CoreContext = nextCore || '';
|
|
70
101
|
}
|
|
71
102
|
|
|
103
|
+
// A Lead's workflow slices (orchestration, agent and contact catalogs) for its
|
|
104
|
+
// mode, Mixy's with the contacts.
|
|
105
|
+
function leadPartsFor(session, leadPromptParts) {
|
|
106
|
+
return leadPromptParts({
|
|
107
|
+
agentMode: sessionModeOf(session) === AGENT_MODE,
|
|
108
|
+
mixy: resolveSessionMode({ session }).agentId === MIXY_AGENT_ID,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// A conversation keeps its `# Session` block: the legacy combined layout
|
|
113
|
+
// rebuilds the tier3 block from the new core (rooted where it was).
|
|
114
|
+
function rewriteConversationBp3Core(session, nextCore) {
|
|
115
|
+
if (session.bp3EnvSplit !== true && typeof session.bp3CoreContext === 'string') {
|
|
116
|
+
const previous = session.bp3CoreContext;
|
|
117
|
+
session.bp3CoreContext = nextCore;
|
|
118
|
+
if (refreshSessionBp3Environment(session, session.cwd)) return;
|
|
119
|
+
session.bp3CoreContext = previous;
|
|
120
|
+
}
|
|
121
|
+
rewriteBp3Core(session, nextCore);
|
|
122
|
+
}
|
|
123
|
+
|
|
72
124
|
export function createToolPolicyRefresh({
|
|
73
125
|
getSession,
|
|
74
126
|
getRoute,
|
|
@@ -137,15 +189,11 @@ export function createToolPolicyRefresh({
|
|
|
137
189
|
);
|
|
138
190
|
}
|
|
139
191
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
// Older records contain only compiled prompt text; rebuilding would guess
|
|
146
|
-
// away custom instructions. Keep that immutable material for every owner.
|
|
147
|
-
const identity = session.promptIdentity;
|
|
148
|
-
if (!identity) return { appliedToCurrentSession: false, reason: 'missing-prompt-identity' };
|
|
192
|
+
// The policy `config` gives `session`, computed without touching the
|
|
193
|
+
// session, so a turn that starts during the async rebuild cannot lose tools
|
|
194
|
+
// to it. `conversation`: the rebuilt BP3 core keeps the instruction files
|
|
195
|
+
// and core memory the prompt presents now (withPresentedWorkspaceSlices).
|
|
196
|
+
async function stagePolicy(session, identity, config, { conversation = false } = {}) {
|
|
149
197
|
const ownerIsAgent = isAgentOwner(session);
|
|
150
198
|
const schemaAllowedTools = honoredSchemaAllowlist(session.schemaAllowedTools, {
|
|
151
199
|
ownerIsAgent,
|
|
@@ -155,11 +203,13 @@ export function createToolPolicyRefresh({
|
|
|
155
203
|
|
|
156
204
|
const {
|
|
157
205
|
summary: workflow,
|
|
158
|
-
|
|
159
|
-
packContext,
|
|
206
|
+
leadPromptParts,
|
|
207
|
+
packContext: workflowContext,
|
|
160
208
|
orchestrationMode,
|
|
161
|
-
} = activeWorkflowContext(
|
|
162
|
-
const
|
|
209
|
+
} = activeWorkflowContext(config, getDataDir());
|
|
210
|
+
const sessionMode = sessionModeOf(session);
|
|
211
|
+
const agentMode = sessionMode === AGENT_MODE;
|
|
212
|
+
const leadWorkflowParts = ownerIsAgent ? {} : leadPartsFor(session, leadPromptParts);
|
|
163
213
|
const denied = [
|
|
164
214
|
...session.callerDisallowedTools,
|
|
165
215
|
...featureDisallowedTools(),
|
|
@@ -168,8 +218,6 @@ export function createToolPolicyRefresh({
|
|
|
168
218
|
.map((name) => String(name || ''))
|
|
169
219
|
.filter(Boolean);
|
|
170
220
|
|
|
171
|
-
// Stage: everything below is computed without touching the session, so a
|
|
172
|
-
// turn that starts during the async rebuild cannot lose tools to it.
|
|
173
221
|
const baseRules =
|
|
174
222
|
identity.skipAgentRules || toolFreeRole
|
|
175
223
|
? ''
|
|
@@ -179,29 +227,190 @@ export function createToolPolicyRefresh({
|
|
|
179
227
|
provider: getRoute()?.provider,
|
|
180
228
|
model: getRoute()?.model,
|
|
181
229
|
});
|
|
182
|
-
const coreMemoryContext = await leadCoreMemoryContext();
|
|
230
|
+
const coreMemoryContext = conversation ? '' : await leadCoreMemoryContext();
|
|
183
231
|
const { sessionMarkerCore } = composeSystemPrompt({
|
|
184
232
|
...sessionRolePromptFields(identity, {
|
|
185
233
|
ownerIsAgent,
|
|
186
234
|
toolFreeRole,
|
|
187
235
|
delegationFree: delegationDisabled(session, ownerIsAgent),
|
|
236
|
+
sessionMode,
|
|
237
|
+
routine: isRoutineSource(session.sourceType),
|
|
188
238
|
}),
|
|
189
239
|
provider: getRoute()?.provider,
|
|
190
240
|
workflowContext,
|
|
241
|
+
...leadWorkflowParts,
|
|
191
242
|
coreMemoryContext,
|
|
192
|
-
// The rebuilt core keeps (or newly applies) the instruction-files
|
|
193
|
-
|
|
243
|
+
// The rebuilt core keeps (or newly applies) the instruction-files
|
|
244
|
+
// setting; agent mode carries none.
|
|
245
|
+
instructionFilesContext:
|
|
246
|
+
conversation || toolFreeRole || agentMode ? null : loadInstructionFilesContext?.(session) || null,
|
|
194
247
|
});
|
|
248
|
+
return {
|
|
249
|
+
workflow,
|
|
250
|
+
orchestrationMode,
|
|
251
|
+
sessionMode,
|
|
252
|
+
denied,
|
|
253
|
+
schemaAllowedTools,
|
|
254
|
+
ownerIsAgent,
|
|
255
|
+
baseRules,
|
|
256
|
+
core: conversation ? withPresentedWorkspaceSlices(session, sessionMarkerCore) : sessionMarkerCore,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Apply a staged policy synchronously; the BP3 core is the caller's.
|
|
261
|
+
function applyPolicy(session, staged) {
|
|
262
|
+
session.workflow = toSessionWorkflowMeta(staged.workflow);
|
|
263
|
+
session.orchestrationMode = staged.orchestrationMode;
|
|
264
|
+
session.sessionMode = staged.sessionMode;
|
|
265
|
+
applyToolDenials(session, staged.denied, staged.schemaAllowedTools, staged.ownerIsAgent);
|
|
266
|
+
rewriteSystemHeading(session, '# Tool Use', staged.baseRules);
|
|
267
|
+
session.updatedAt = Date.now();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async function refreshEmptySessionToolPolicy() {
|
|
271
|
+
invalidatePreSessionToolSurface?.();
|
|
272
|
+
const session = getSession?.();
|
|
273
|
+
if (!session?.id) return { appliedToCurrentSession: true };
|
|
274
|
+
if (!admitsRefresh(session)) return { appliedToCurrentSession: false };
|
|
275
|
+
// Older records contain only compiled prompt text; rebuilding would guess
|
|
276
|
+
// away custom instructions. Keep that immutable material for every owner.
|
|
277
|
+
const identity = session.promptIdentity;
|
|
278
|
+
if (!identity) return { appliedToCurrentSession: false, reason: 'missing-prompt-identity' };
|
|
279
|
+
const staged = await stagePolicy(session, identity, getConfig());
|
|
195
280
|
// Apply: re-check admission after the await, then mutate synchronously.
|
|
196
281
|
if (!admitsRefresh(session)) return { appliedToCurrentSession: false };
|
|
197
|
-
session
|
|
198
|
-
session.
|
|
199
|
-
applyToolDenials(session, denied, schemaAllowedTools, ownerIsAgent);
|
|
200
|
-
rewriteSystemHeading(session, '# Tool Use', baseRules);
|
|
201
|
-
rewriteBp3Core(session, sessionMarkerCore);
|
|
202
|
-
session.updatedAt = Date.now();
|
|
282
|
+
applyPolicy(session, staged);
|
|
283
|
+
rewriteBp3Core(session, staged.core);
|
|
203
284
|
return { appliedToCurrentSession: true };
|
|
204
285
|
}
|
|
205
286
|
|
|
206
|
-
|
|
287
|
+
/**
|
|
288
|
+
* Switch the current coding session's workflow mid-conversation (the
|
|
289
|
+
* composer's workflow selector): its prompt (BP3 core and `# Tool Use`) and
|
|
290
|
+
* tool/delegation surface are rebuilt now for `workflowId` with the current
|
|
291
|
+
* orchestration mode and agents, so its next turn runs on them, and that
|
|
292
|
+
* turn carries a one-time notice (manager/workflow-switch-notice.mjs). The
|
|
293
|
+
* provider prompt cache is rebuilt once. Refused while a turn runs, like a
|
|
294
|
+
* working-folder change. The configured workflow (the default for new
|
|
295
|
+
* sessions) is the caller's and stays as it is.
|
|
296
|
+
*
|
|
297
|
+
* Running work is untouched: agents and workers the session started under
|
|
298
|
+
* the old workflow are separate sessions with their own prompts and tools,
|
|
299
|
+
* so they keep running as they are (unlike a working-folder change, running
|
|
300
|
+
* agents never refuse this); only delegation made from the next turn on
|
|
301
|
+
* uses the new surface.
|
|
302
|
+
*
|
|
303
|
+
* Returns null when the session has no conversation (the caller applies the
|
|
304
|
+
* configured workflow to an empty session as before), else
|
|
305
|
+
* `{ appliedToCurrentSession: true, workflow, workflowSwitch }` where
|
|
306
|
+
* `workflowSwitch` is the transcript boundary (null when unchanged).
|
|
307
|
+
*/
|
|
308
|
+
async function switchSessionWorkflow(workflowId) {
|
|
309
|
+
const session = getSession?.();
|
|
310
|
+
if (!session?.id) return null;
|
|
311
|
+
const conversation = () =>
|
|
312
|
+
sessionHasConversationMessages(session) || sessionHasConversationMessages({ messages: session.liveTurnMessages });
|
|
313
|
+
if (!conversation()) return null;
|
|
314
|
+
if (isAgentOwner(session) || sessionModeOf(session) === AGENT_MODE) {
|
|
315
|
+
throw new Error('Only a coding session has a workflow.');
|
|
316
|
+
}
|
|
317
|
+
const identity = session.promptIdentity;
|
|
318
|
+
if (!identity) throw new Error('This session is too old to switch its workflow; start a new task.');
|
|
319
|
+
const busy = () => getSession?.() !== session || turnInFlight(session);
|
|
320
|
+
if (busy()) throw new Error(WORKFLOW_SWITCH_BUSY);
|
|
321
|
+
const config = getConfig();
|
|
322
|
+
const staged = await stagePolicy(
|
|
323
|
+
session,
|
|
324
|
+
identity,
|
|
325
|
+
{ ...config, workflow: { ...(config?.workflow || {}), active: workflowId } },
|
|
326
|
+
{ conversation: true }
|
|
327
|
+
);
|
|
328
|
+
if (busy()) throw new Error(WORKFLOW_SWITCH_BUSY);
|
|
329
|
+
const before = session.workflow;
|
|
330
|
+
const from = before?.id ? before : null;
|
|
331
|
+
applyPolicy(session, staged);
|
|
332
|
+
rewriteConversationBp3Core(session, staged.core);
|
|
333
|
+
// The request prefix changed: drop provider replay state and the context
|
|
334
|
+
// baseline, and tag the next send's expected cache break.
|
|
335
|
+
markToolSurfaceMigrated(session, 'workflow_switch');
|
|
336
|
+
stageWorkflowSwitchNotice(session, from, session.workflow);
|
|
337
|
+
let workflowSwitch = null;
|
|
338
|
+
if (from?.id !== session.workflow.id) {
|
|
339
|
+
workflowSwitch = {
|
|
340
|
+
fromId: from?.id || '',
|
|
341
|
+
from: from?.name || from?.id || '',
|
|
342
|
+
toId: session.workflow.id,
|
|
343
|
+
to: session.workflow.name,
|
|
344
|
+
at: Date.now(),
|
|
345
|
+
};
|
|
346
|
+
recordTranscriptBoundary(session, 'workflowSwitches', workflowSwitch, (entry) => entry?.at === workflowSwitch.at);
|
|
347
|
+
}
|
|
348
|
+
return { appliedToCurrentSession: true, workflow: session.workflow, workflowSwitch };
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// An agent profile edit that met a running turn: the next turn applies it.
|
|
352
|
+
let agentProfilePending = false;
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Bring a Lead session's prompt to the saved bots — its own agent's
|
|
356
|
+
* persona, AGENT.md and name, and the bot roster its catalogs list — after
|
|
357
|
+
* a bot was saved, created, renamed, archived or restored
|
|
358
|
+
* (agent-profile-changes.mjs), on resume, or at the start of the turn after
|
|
359
|
+
* one that ran through the change (`trigger`: 'save' | 'resume' | 'turn').
|
|
360
|
+
* Two stamps (agentProfileRevision, agentRosterRevision) tell whether
|
|
361
|
+
* anything it embeds changed; a delegated worker keeps its prompt. The core
|
|
362
|
+
* is rebuilt like a workflow switch's (the session's own workflow, the
|
|
363
|
+
* workspace slices the model was told) and replaces the stored one, so the
|
|
364
|
+
* next turn sends it with one provider cache break; nothing is re-read per
|
|
365
|
+
* turn. Tools are untouched. Returns true when the prompt changed.
|
|
366
|
+
*/
|
|
367
|
+
async function refreshAgentProfile({ trigger = 'save' } = {}) {
|
|
368
|
+
const session = getSession?.();
|
|
369
|
+
const identity = session?.promptIdentity;
|
|
370
|
+
const agent = identity?.agent;
|
|
371
|
+
if (!session?.id || !agent || isAgentOwner(session)) return false;
|
|
372
|
+
const revision = agentProfileRevision(agent);
|
|
373
|
+
const config = getConfig();
|
|
374
|
+
const workflowId = session.workflow?.id;
|
|
375
|
+
const workflowConfig = workflowId
|
|
376
|
+
? { ...config, workflow: { ...(config?.workflow || {}), active: workflowId } }
|
|
377
|
+
: config;
|
|
378
|
+
const roster = leadRosterRevision(
|
|
379
|
+
leadPartsFor(session, activeWorkflowContext(workflowConfig, getDataDir()).leadPromptParts)
|
|
380
|
+
);
|
|
381
|
+
if (session.agentProfileRevision === revision && session.agentRosterRevision === roster) return false;
|
|
382
|
+
// A coding session from before profile stamps keeps its prompt when it
|
|
383
|
+
// is reopened; a saved edit still reaches it.
|
|
384
|
+
if (session.agentProfileRevision === undefined && trigger === 'resume' && sessionModeOf(session) !== AGENT_MODE) {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
// At a turn's start its own turn is the one counted; nothing runs yet.
|
|
388
|
+
const busy = () => getSession?.() !== session || (trigger !== 'turn' && turnInFlight(session));
|
|
389
|
+
if (busy()) {
|
|
390
|
+
agentProfilePending = true;
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
const staged = await stagePolicy(session, identity, workflowConfig, { conversation: true });
|
|
394
|
+
if (busy()) {
|
|
395
|
+
agentProfilePending = true;
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
session.agentProfileRevision = revision;
|
|
399
|
+
session.agentRosterRevision = roster;
|
|
400
|
+
session.updatedAt = Date.now();
|
|
401
|
+
if (staged.core === presentedBp3Core(session)) return false;
|
|
402
|
+
rewriteConversationBp3Core(session, staged.core);
|
|
403
|
+
// The request prefix changed: one cache break, tagged on the next send.
|
|
404
|
+
markToolSurfaceMigrated(session, AGENT_PROFILE_INTENT);
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/** Turn start: apply an edit that arrived while the previous turn ran. */
|
|
409
|
+
async function applyPendingAgentProfile() {
|
|
410
|
+
if (!agentProfilePending) return false;
|
|
411
|
+
agentProfilePending = false;
|
|
412
|
+
return refreshAgentProfile({ trigger: 'turn' });
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
return { refreshEmptySessionToolPolicy, switchSessionWorkflow, refreshAgentProfile, applyPendingAgentProfile };
|
|
207
416
|
}
|
|
@@ -29,15 +29,22 @@ export function createSessionOps(deps) {
|
|
|
29
29
|
} catch {}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// `rebuildPrompt` (an agent chat's "대화 초기화"): refused while a turn
|
|
33
|
+
// runs, and the emptied session's prompt and tool surface are then rebuilt
|
|
34
|
+
// from the current rules, as a new session's are (refreshEmptySessionToolPolicy).
|
|
32
35
|
async function clear(options = {}) {
|
|
33
36
|
const session = getSession();
|
|
34
37
|
if (!session?.id) return false;
|
|
38
|
+
const rebuild = options.rebuildPrompt === true;
|
|
39
|
+
if (rebuild && getActiveTurnCount() > 0) throw new Error('The session is running a turn; wait for it to finish.');
|
|
35
40
|
const cleared = await mgr.clearSessionMessages(session.id, options);
|
|
36
41
|
if (!cleared) return false;
|
|
37
42
|
setSession(typeof cleared === 'object' ? cleared : mgr.getSession(session.id) || session);
|
|
38
43
|
if (options.recoverAgent === true) recoverAgentWorkers();
|
|
44
|
+
let promptRebuilt = false;
|
|
45
|
+
if (rebuild) promptRebuilt = (await refreshEmptySessionToolPolicy?.())?.appliedToCurrentSession === true;
|
|
39
46
|
invalidateContextStatusCache();
|
|
40
|
-
return true;
|
|
47
|
+
return rebuild ? { promptRebuilt } : true;
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
// Message-selector rewind: drop the chosen user prompt and everything
|
|
@@ -61,11 +61,17 @@ export function createAskCallbacks({ transcript, notifyFnForSession, scheduleSea
|
|
|
61
61
|
|
|
62
62
|
// The turn's change-record key rides the caller's transcript metadata (in
|
|
63
63
|
// place: the stream stamps assistantAt on this same object), so the
|
|
64
|
-
// persisted user row and completion carry it across restore.
|
|
64
|
+
// persisted user row and completion carry it across restore. A merged
|
|
65
|
+
// batch also names every submission it delivers, so a queued-input restore
|
|
66
|
+
// can tell each one delivered.
|
|
65
67
|
function stampCheckpoint(options) {
|
|
66
68
|
const meta = options.transcriptMeta;
|
|
69
|
+
if (!meta || typeof meta !== 'object') return meta;
|
|
67
70
|
const checkpointId = String(options.id || '').trim();
|
|
68
|
-
if (checkpointId
|
|
71
|
+
if (checkpointId) meta.checkpointId = checkpointId;
|
|
72
|
+
if (Array.isArray(options.submissionIds) && options.submissionIds.length > 1) {
|
|
73
|
+
meta.submissionIds = options.submissionIds.map(String);
|
|
74
|
+
}
|
|
69
75
|
return meta;
|
|
70
76
|
}
|
|
71
77
|
|
|
@@ -74,6 +80,8 @@ export function createAskCallbacks({ transcript, notifyFnForSession, scheduleSea
|
|
|
74
80
|
beforeToolExecution: () => turn.snapshot.promise || Promise.resolve(),
|
|
75
81
|
transcriptMeta: stampCheckpoint(options),
|
|
76
82
|
promptSource: options.promptSource,
|
|
83
|
+
// A routine turn's trusted selection text (its instructions only).
|
|
84
|
+
...(typeof options.skillSelection === 'string' ? { skillSelection: options.skillSelection } : {}),
|
|
77
85
|
retryFailedTurn: options.retryFailedTurn === true,
|
|
78
86
|
retryTurnId: options.retryTurnId,
|
|
79
87
|
retryAttemptId: options.retryAttemptId,
|
|
@@ -24,6 +24,7 @@ export function createTurnPreparation({
|
|
|
24
24
|
prepareTurnWorkspace,
|
|
25
25
|
admitTurnWorkspace,
|
|
26
26
|
applyPendingRoute,
|
|
27
|
+
applyPendingAgentProfile,
|
|
27
28
|
}) {
|
|
28
29
|
const scopedMcpTools = (session) => scopedMcpToolsFor(session, getConfig());
|
|
29
30
|
|
|
@@ -131,6 +132,8 @@ export function createTurnPreparation({
|
|
|
131
132
|
assertSessionAdmission?.();
|
|
132
133
|
}
|
|
133
134
|
const modelSwitch = applyPendingRoute?.();
|
|
135
|
+
// An agent profile saved while the previous turn ran applies from this one.
|
|
136
|
+
await applyPendingAgentProfile?.();
|
|
134
137
|
options.onRouteApplied?.(getSession());
|
|
135
138
|
if (modelSwitch) options.onModelSwitch?.(modelSwitch);
|
|
136
139
|
ensureSessionTranscriptWriter?.();
|
|
@@ -1,83 +1,65 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Run an inbound webhook
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* name). Invoked from the channels worker's webhook dispatch.
|
|
2
|
+
* Run an inbound webhook: the endpoint's instructions and the fenced event
|
|
3
|
+
* payload become one turn in its owner bot's home thread
|
|
4
|
+
* (routine-home-turn.mjs). Invoked from the channels worker's webhook
|
|
5
|
+
* dispatch and the app's "Run now".
|
|
7
6
|
*/
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { modelRouteFields, parseScheduleModelRef } from '../runtime/shared/schedule-model-ref.mjs';
|
|
12
|
-
import { migrateCodexRoute } from '../runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs';
|
|
13
|
-
import { automationWorkflowOpts } from './automation-workflow.mjs';
|
|
14
|
-
import { runAutomationTurns } from './automation-agents.mjs';
|
|
15
|
-
import { automationPromptContent } from '../runtime/shared/automation-attachments.mjs';
|
|
7
|
+
import { markEndpointRun } from '../runtime/channels/lib/webhooks-db.mjs';
|
|
8
|
+
import { runOwnedAutomation } from './owned-automation-run.mjs';
|
|
9
|
+
import { runRoutineTurn } from './routine-home-turn.mjs';
|
|
16
10
|
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
/**
|
|
12
|
+
* One run of the endpoint in its owner's thread (Mixy when absent): a run
|
|
13
|
+
* while the previous one of the same endpoint is still going is skipped (and
|
|
14
|
+
* stamped), and every outcome is stamped on the endpoint. `prompt` carries the
|
|
15
|
+
* fenced payload; `skillSelection` only the endpoint's instructions.
|
|
16
|
+
*/
|
|
17
|
+
export async function runWebhookSession({ ownerAgentId = null, ...options }, deps = {}) {
|
|
18
|
+
const name = String(options.name || '').trim();
|
|
19
|
+
const { markRun = markEndpointRun, run = runWebhookTurn, ...ownedDeps } = deps;
|
|
20
|
+
const stamp = (outcome) =>
|
|
21
|
+
markRun(name, outcome, new Date()).catch((error) =>
|
|
22
|
+
process.stderr.write(`mixdog webhook: ${name} ${outcome} stamp failed: ${error?.message || error}\n`)
|
|
23
|
+
);
|
|
24
|
+
let outcome;
|
|
25
|
+
try {
|
|
26
|
+
// The dispatch's cancellation reaches the run as `signal`.
|
|
27
|
+
outcome = await runOwnedAutomation(
|
|
28
|
+
'webhook',
|
|
29
|
+
{ name, ownerAgentId },
|
|
30
|
+
({ signal }) => run({ ...options, ownerAgentId, signal }),
|
|
31
|
+
{ recordSkip: () => stamp('skipped'), signal: options.signal || null, ...ownedDeps }
|
|
32
|
+
);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
await stamp('failed');
|
|
35
|
+
throw error;
|
|
23
36
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (maintenance?.provider && maintenance?.model) return modelRouteFields(maintenance);
|
|
27
|
-
throw new Error('webhook run has no model: set one on the endpoint or configure maintenance.webhook');
|
|
37
|
+
if (!outcome.skipped) await stamp('success');
|
|
38
|
+
return outcome;
|
|
28
39
|
}
|
|
29
40
|
|
|
30
|
-
|
|
41
|
+
/** One turn in the owner's thread; `skillSelection` absent selects nothing. */
|
|
42
|
+
function runWebhookTurn({
|
|
31
43
|
name,
|
|
32
|
-
model = null,
|
|
33
44
|
prompt,
|
|
45
|
+
ownerAgentId = null,
|
|
34
46
|
cwd = null,
|
|
35
|
-
workflow = null,
|
|
36
47
|
attachments = null,
|
|
37
|
-
|
|
38
|
-
// Endpoint-authored instructions: the run's ONLY skill-selection input.
|
|
39
|
-
// `prompt` also carries the fenced external payload, which must never
|
|
40
|
-
// select a skill; absent means nothing selects.
|
|
48
|
+
event = '',
|
|
41
49
|
skillSelection = '',
|
|
50
|
+
signal = null,
|
|
42
51
|
}) {
|
|
43
52
|
const endpoint = String(name || '').trim();
|
|
44
|
-
const body = String(prompt || '').trim();
|
|
45
53
|
if (!endpoint) throw new Error('runWebhookSession: endpoint name required');
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
sourceName: endpoint,
|
|
57
|
-
...(projectCwd ? { cwd: projectCwd } : {}),
|
|
58
|
-
desktopSession: projectCwd
|
|
59
|
-
? { classification: 'project', projectPath: projectCwd }
|
|
60
|
-
: { classification: 'task', projectPath: null },
|
|
61
|
-
...automationWorkflowOpts(workflow),
|
|
54
|
+
return runRoutineTurn({
|
|
55
|
+
kind: 'webhook',
|
|
56
|
+
name: endpoint,
|
|
57
|
+
ownerAgentId,
|
|
58
|
+
prompt,
|
|
59
|
+
skillSelection: String(skillSelection ?? ''),
|
|
60
|
+
attachments,
|
|
61
|
+
cwd,
|
|
62
|
+
event,
|
|
63
|
+
signal,
|
|
62
64
|
});
|
|
63
|
-
// The user message leads with the endpoint's instructions, so Recent titles
|
|
64
|
-
// read as the user-authored intent rather than payload noise.
|
|
65
|
-
// Stored attachments ride along as composer-style content parts.
|
|
66
|
-
const content = automationPromptContent(body, attachments);
|
|
67
|
-
// askOpts.signal is the parent-abort link: it is cascaded onto the turn
|
|
68
|
-
// controller, so aborting it stops the in-flight provider/tool work instead
|
|
69
|
-
// of leaving a timed-out delivery's session running with live side effects.
|
|
70
|
-
const ask = (turnContent, askOpts) =>
|
|
71
|
-
askSession(session.id, turnContent, null, null, projectCwd || undefined, undefined, {
|
|
72
|
-
...askOpts,
|
|
73
|
-
...(signal ? { signal } : {}),
|
|
74
|
-
});
|
|
75
|
-
// Agents the run delegates to report back; each result is the next turn
|
|
76
|
-
// (runAutomationTurns marks those turns as task notifications).
|
|
77
|
-
const result = await runAutomationTurns(
|
|
78
|
-
session.id,
|
|
79
|
-
() => ask(content, { skillSelection: String(skillSelection ?? '') }),
|
|
80
|
-
ask
|
|
81
|
-
);
|
|
82
|
-
return { sessionId: session.id, result: String(result?.content || '') };
|
|
83
65
|
}
|