@bastani/atomic 0.8.21-0 → 0.8.22-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/CHANGELOG.md +46 -9
- package/dist/builtin/intercom/broker/broker.ts +3 -3
- package/dist/builtin/intercom/config.ts +3 -3
- package/dist/builtin/intercom/index.ts +1 -1
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/ui/compose.ts +2 -2
- package/dist/builtin/mcp/host-html-template.ts +0 -3
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +13 -4
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +9 -9
- package/dist/builtin/subagents/agents/debugger.md +6 -6
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/prompts/parallel-handoff-plan.md +1 -1
- package/dist/builtin/subagents/skills/browser-use/SKILL.md +234 -0
- package/dist/builtin/subagents/skills/browser-use/references/cdp-python.md +76 -0
- package/dist/builtin/subagents/skills/browser-use/references/multi-session.md +92 -0
- package/dist/builtin/subagents/skills/subagent/SKILL.md +4 -4
- package/dist/builtin/subagents/src/agents/skills.ts +19 -1
- package/dist/builtin/subagents/src/extension/index.ts +24 -22
- package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +7 -1
- package/dist/builtin/subagents/src/runs/background/async-execution.ts +23 -7
- package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +98 -3
- package/dist/builtin/subagents/src/runs/background/async-status.ts +3 -1
- package/dist/builtin/subagents/src/runs/background/run-status.ts +1 -1
- package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +3 -0
- package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +37 -12
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +15 -15
- package/dist/builtin/subagents/src/runs/foreground/execution.ts +26 -2
- package/dist/builtin/subagents/src/runs/shared/nested-render.ts +1 -1
- package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +7 -0
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +28 -1
- package/dist/builtin/subagents/src/shared/fast-mode.ts +80 -0
- package/dist/builtin/subagents/src/shared/formatters.ts +4 -2
- package/dist/builtin/subagents/src/shared/types.ts +4 -2
- package/dist/builtin/subagents/src/shared/utils.ts +3 -61
- package/dist/builtin/subagents/src/tui/render.ts +303 -157
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +101 -35
- package/dist/builtin/workflows/README.md +228 -41
- package/dist/builtin/workflows/builtin/deep-research-codebase.ts +535 -541
- package/dist/builtin/workflows/builtin/goal.ts +39 -25
- package/dist/builtin/workflows/builtin/open-claude-design.ts +66 -69
- package/dist/builtin/workflows/builtin/ralph.ts +21 -21
- package/dist/builtin/workflows/package.json +6 -5
- package/dist/builtin/workflows/skills/research-codebase/SKILL.md +1 -1
- package/dist/builtin/workflows/src/extension/background-ui-adapter.ts +2 -2
- package/dist/builtin/workflows/src/extension/discovery.ts +25 -146
- package/dist/builtin/workflows/src/extension/dispatcher.ts +72 -24
- package/dist/builtin/workflows/src/extension/hil-answer-notifications.ts +363 -0
- package/dist/builtin/workflows/src/extension/index.ts +690 -352
- package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +99 -62
- package/dist/builtin/workflows/src/extension/render-call.ts +2 -1
- package/dist/builtin/workflows/src/extension/render-result.ts +9 -3
- package/dist/builtin/workflows/src/extension/renderers.ts +5 -3
- package/dist/builtin/workflows/src/extension/runtime.ts +68 -33
- package/dist/builtin/workflows/src/extension/status-writer.ts +1 -1
- package/dist/builtin/workflows/src/extension/wiring.ts +34 -13
- package/dist/builtin/workflows/src/extension/workflow-module-loader.ts +142 -0
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +4 -4
- package/dist/builtin/workflows/src/index.ts +2 -0
- package/dist/builtin/workflows/src/intercom/result-intercom.ts +1 -1
- package/dist/builtin/workflows/src/runs/background/runner.ts +6 -4
- package/dist/builtin/workflows/src/runs/background/status.ts +45 -21
- package/dist/builtin/workflows/src/runs/foreground/executor.ts +624 -52
- package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +80 -24
- package/dist/builtin/workflows/src/runs/shared/validate-inputs.ts +61 -24
- package/dist/builtin/workflows/src/runs/shared/workflow-runner.ts +32 -10
- package/dist/builtin/workflows/src/sdk-surface.ts +6 -0
- package/dist/builtin/workflows/src/shared/expanded-workflow-graph.ts +178 -0
- package/dist/builtin/workflows/src/shared/persistence-restore.ts +92 -12
- package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +21 -3
- package/dist/builtin/workflows/src/shared/render-inputs-schema.ts +1 -2
- package/dist/builtin/workflows/src/shared/run-visibility.ts +9 -0
- package/dist/builtin/workflows/src/shared/schema-introspection.ts +121 -0
- package/dist/builtin/workflows/src/shared/serializable.ts +132 -0
- package/dist/builtin/workflows/src/shared/stage-ui-broker.ts +91 -9
- package/dist/builtin/workflows/src/shared/store-types.ts +31 -3
- package/dist/builtin/workflows/src/shared/store.ts +58 -14
- package/dist/builtin/workflows/src/shared/types.ts +105 -40
- package/dist/builtin/workflows/src/tui/chat-surface-message.ts +129 -13
- package/dist/builtin/workflows/src/tui/chat-surface.ts +6 -1
- package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +3 -2
- package/dist/builtin/workflows/src/tui/graph-canvas.ts +1 -1
- package/dist/builtin/workflows/src/tui/graph-view.ts +91 -65
- package/dist/builtin/workflows/src/tui/inline-form-card.ts +1 -1
- package/dist/builtin/workflows/src/tui/inline-form-overlay.ts +3 -2
- package/dist/builtin/workflows/src/tui/inputs-overlay.ts +3 -2
- package/dist/builtin/workflows/src/tui/inputs-picker.ts +8 -7
- package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +2 -0
- package/dist/builtin/workflows/src/tui/node-card.ts +34 -8
- package/dist/builtin/workflows/src/tui/overlay-adapter.ts +4 -11
- package/dist/builtin/workflows/src/tui/prompt-card.ts +98 -50
- package/dist/builtin/workflows/src/tui/session-list.ts +7 -2
- package/dist/builtin/workflows/src/tui/session-picker.ts +2 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +226 -55
- package/dist/builtin/workflows/src/tui/status-helpers.ts +2 -0
- package/dist/builtin/workflows/src/tui/store-widget-installer.ts +37 -158
- package/dist/builtin/workflows/src/tui/toast.ts +2 -2
- package/dist/builtin/workflows/src/tui/widget.ts +53 -12
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +270 -19
- package/dist/builtin/workflows/src/tui/workflow-notice-card.ts +184 -0
- package/dist/builtin/workflows/src/workflows/define-workflow.ts +138 -43
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +45 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +27 -9
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +196 -17
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/atomic-guide-command.d.ts.map +1 -1
- package/dist/core/atomic-guide-command.js +2 -2
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/codex-fast-mode.d.ts +36 -0
- package/dist/core/codex-fast-mode.d.ts.map +1 -0
- package/dist/core/codex-fast-mode.js +117 -0
- package/dist/core/codex-fast-mode.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +1 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/index.d.ts +4 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -0
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +7 -2
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +23 -8
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/reactive-widget.d.ts +58 -0
- package/dist/core/extensions/reactive-widget.d.ts.map +1 -0
- package/dist/core/extensions/reactive-widget.js +182 -0
- package/dist/core/extensions/reactive-widget.js.map +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +26 -12
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/messages.d.ts +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +8 -2
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry.d.ts +4 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +11 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/resource-loader.d.ts +9 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +49 -21
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +22 -13
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +7 -5
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +5 -3
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +16 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +64 -5
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +7 -4
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/ask-user-question/ask-user-question.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/ask-user-question.js +2 -2
- package/dist/core/tools/ask-user-question/ask-user-question.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +12 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/chat-input-actions.d.ts.map +1 -1
- package/dist/modes/interactive/chat-input-actions.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js +0 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/fast-mode-selector.d.ts +27 -0
- package/dist/modes/interactive/components/fast-mode-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/fast-mode-selector.js +105 -0
- package/dist/modes/interactive/components/fast-mode-selector.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +7 -12
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +132 -30
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +53 -6
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +3 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/docs/compaction.md +1 -1
- package/docs/custom-provider.md +2 -2
- package/docs/development.md +2 -2
- package/docs/docs.json +2 -2
- package/docs/extensions.md +18 -13
- package/docs/providers.md +5 -1
- package/docs/quickstart.md +5 -3
- package/docs/rpc.md +5 -5
- package/docs/sdk.md +12 -12
- package/docs/settings.md +18 -0
- package/docs/themes.md +6 -6
- package/docs/tui.md +20 -18
- package/docs/usage.md +2 -0
- package/docs/workflows.md +403 -39
- package/examples/extensions/qna.ts +2 -2
- package/package.json +4 -4
- package/dist/builtin/subagents/skills/playwright-cli/SKILL.md +0 -392
- package/dist/builtin/subagents/skills/playwright-cli/references/element-attributes.md +0 -23
- package/dist/builtin/subagents/skills/playwright-cli/references/playwright-tests.md +0 -39
- package/dist/builtin/subagents/skills/playwright-cli/references/request-mocking.md +0 -87
- package/dist/builtin/subagents/skills/playwright-cli/references/running-code.md +0 -241
- package/dist/builtin/subagents/skills/playwright-cli/references/session-management.md +0 -225
- package/dist/builtin/subagents/skills/playwright-cli/references/spec-driven-testing.md +0 -305
- package/dist/builtin/subagents/skills/playwright-cli/references/storage-state.md +0 -275
- package/dist/builtin/subagents/skills/playwright-cli/references/test-generation.md +0 -134
- package/dist/builtin/subagents/skills/playwright-cli/references/tracing.md +0 -139
- package/dist/builtin/subagents/skills/playwright-cli/references/video-recording.md +0 -143
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ExtensionAPI,
|
|
3
|
+
PiMessageRenderComponent,
|
|
4
|
+
PiMessageRenderer,
|
|
5
|
+
} from "./index.js";
|
|
6
|
+
import type { Store } from "../shared/store.js";
|
|
7
|
+
import type {
|
|
8
|
+
PendingPrompt,
|
|
9
|
+
PromptKind,
|
|
10
|
+
RunSnapshot,
|
|
11
|
+
StageInputKind,
|
|
12
|
+
StageInputRequest,
|
|
13
|
+
StageSnapshot,
|
|
14
|
+
StoreSnapshot,
|
|
15
|
+
} from "../shared/store-types.js";
|
|
16
|
+
import type { StageUiBroker } from "../shared/stage-ui-broker.js";
|
|
17
|
+
import { deriveGraphThemeFromPiTheme, type GraphTheme } from "../tui/graph-theme.js";
|
|
18
|
+
import { renderWorkflowNoticeCard } from "../tui/workflow-notice-card.js";
|
|
19
|
+
|
|
20
|
+
export const HIL_ANSWER_NOTICE_CUSTOM_TYPE = "workflows:hil-answer-notice";
|
|
21
|
+
const HIL_ANSWER_SNIPPET_LIMIT = 1000;
|
|
22
|
+
|
|
23
|
+
export type WorkflowHilAnswerPromptKind = PromptKind | StageInputKind;
|
|
24
|
+
|
|
25
|
+
export interface WorkflowHilAnswerNoticeDetails {
|
|
26
|
+
readonly kind: "hil_answered";
|
|
27
|
+
readonly scope: "stage";
|
|
28
|
+
readonly runId: string;
|
|
29
|
+
readonly workflowName: string;
|
|
30
|
+
readonly stageId: string;
|
|
31
|
+
readonly stageName?: string;
|
|
32
|
+
readonly promptId?: string;
|
|
33
|
+
readonly promptKind?: WorkflowHilAnswerPromptKind;
|
|
34
|
+
readonly promptMessage?: string;
|
|
35
|
+
readonly answeredAt: number;
|
|
36
|
+
readonly answerAvailable: true;
|
|
37
|
+
readonly answerIncluded: true;
|
|
38
|
+
readonly answerSummary: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface WorkflowHilAnswerNotificationState {
|
|
42
|
+
readonly deliveredAnswerPrompts: Set<string>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface WorkflowHilAnswerNotificationOptions {
|
|
46
|
+
readonly store: Store;
|
|
47
|
+
readonly stageUiBroker?: Pick<StageUiBroker, "onStagePromptResolved">;
|
|
48
|
+
readonly sendMessage?: ExtensionAPI["sendMessage"];
|
|
49
|
+
readonly registerMessageRenderer?: ExtensionAPI["registerMessageRenderer"];
|
|
50
|
+
readonly rendererHost?: object;
|
|
51
|
+
readonly state?: WorkflowHilAnswerNotificationState;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type RawRenderer = PiMessageRenderer;
|
|
55
|
+
|
|
56
|
+
const rendererRegisteredHosts = new WeakSet<object>();
|
|
57
|
+
|
|
58
|
+
export function createWorkflowHilAnswerNotificationState(): WorkflowHilAnswerNotificationState {
|
|
59
|
+
return {
|
|
60
|
+
deliveredAnswerPrompts: new Set<string>(),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function resetWorkflowHilAnswerNotificationState(
|
|
65
|
+
state: WorkflowHilAnswerNotificationState,
|
|
66
|
+
): void {
|
|
67
|
+
state.deliveredAnswerPrompts.clear();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function installWorkflowHilAnswerNotifications(
|
|
71
|
+
options: WorkflowHilAnswerNotificationOptions,
|
|
72
|
+
): () => void {
|
|
73
|
+
registerHilAnswerNoticeRenderer(options);
|
|
74
|
+
|
|
75
|
+
const send = options.sendMessage;
|
|
76
|
+
if (typeof send !== "function") return () => undefined;
|
|
77
|
+
|
|
78
|
+
const state = options.state ?? createWorkflowHilAnswerNotificationState();
|
|
79
|
+
let previousSnapshot = options.store.snapshot();
|
|
80
|
+
|
|
81
|
+
const emitOnce = (details: WorkflowHilAnswerNoticeDetails): void => {
|
|
82
|
+
const key = answerNoticeKey(details.runId, details.stageId, details.promptId, details.promptKind);
|
|
83
|
+
if (state.deliveredAnswerPrompts.has(key)) return;
|
|
84
|
+
|
|
85
|
+
state.deliveredAnswerPrompts.add(key);
|
|
86
|
+
sendHilAnswerNotice(send, details);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const inspectSimplePromptAnswers = (snapshot: StoreSnapshot): void => {
|
|
90
|
+
for (const previousRun of previousSnapshot.runs) {
|
|
91
|
+
const currentRun = snapshot.runs.find((run) => run.id === previousRun.id);
|
|
92
|
+
if (currentRun === undefined) continue;
|
|
93
|
+
|
|
94
|
+
for (const previousStage of previousRun.stages) {
|
|
95
|
+
const answeredPrompt = simplePromptAnswer(previousStage, currentRun);
|
|
96
|
+
if (answeredPrompt === undefined) continue;
|
|
97
|
+
const answerRecord = options.store.getStagePromptAnswer(currentRun.id, answeredPrompt.stage.id);
|
|
98
|
+
if (answerRecord?.answerSource === "workflow_tool") continue;
|
|
99
|
+
emitOnce(makeSimplePromptAnswerNotice(currentRun, answeredPrompt.stage, answeredPrompt.prompt, answerRecord?.value));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
previousSnapshot = snapshot;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const unsubscribeStore = options.store.subscribe(inspectSimplePromptAnswers);
|
|
106
|
+
const unsubscribeBroker = options.stageUiBroker?.onStagePromptResolved((event) => {
|
|
107
|
+
if (event.answerSource === "workflow_tool") return;
|
|
108
|
+
const answeredStage = findStageSnapshot(options.store.snapshot(), event.runId, event.stageId);
|
|
109
|
+
if (answeredStage === undefined) return;
|
|
110
|
+
|
|
111
|
+
emitOnce(makeBrokerPromptAnswerNotice(answeredStage.run, answeredStage.stage, event.prompt, event.answer, event.answeredAt));
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return () => {
|
|
115
|
+
unsubscribeStore();
|
|
116
|
+
unsubscribeBroker?.();
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function registerHilAnswerNoticeRenderer(
|
|
121
|
+
options: Pick<WorkflowHilAnswerNotificationOptions, "registerMessageRenderer" | "rendererHost">,
|
|
122
|
+
): void {
|
|
123
|
+
const register = options.registerMessageRenderer;
|
|
124
|
+
if (typeof register !== "function") return;
|
|
125
|
+
|
|
126
|
+
const host = options.rendererHost ?? register;
|
|
127
|
+
if (rendererRegisteredHosts.has(host)) return;
|
|
128
|
+
|
|
129
|
+
const renderer: RawRenderer = (raw, _options, piTheme) => {
|
|
130
|
+
const details = readHilAnswerNoticeDetails(raw);
|
|
131
|
+
if (details === undefined) return undefined;
|
|
132
|
+
return makeNoticeComponent(details, themeFromRenderer(piTheme));
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
register(HIL_ANSWER_NOTICE_CUSTOM_TYPE, renderer);
|
|
136
|
+
rendererRegisteredHosts.add(host);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function formatWorkflowHilAnswerNoticeText(details: WorkflowHilAnswerNoticeDetails): string {
|
|
140
|
+
const workflowName = escapeQuotedText(details.workflowName);
|
|
141
|
+
const stage = details.stageName ?? details.stageId;
|
|
142
|
+
const prompt = details.promptId ? `, prompt ${details.promptId}` : "";
|
|
143
|
+
const question = details.promptMessage ? ` Question: ${details.promptMessage}` : "";
|
|
144
|
+
const subject = `Workflow "${workflowName}" received the user's response for its pending human-in-the-loop prompt`;
|
|
145
|
+
const location = `(run ${details.runId}, stage ${stage}${prompt})`;
|
|
146
|
+
const instruction =
|
|
147
|
+
"Do not ask the same question again. No main-chat action is needed; do not answer any other workflow human-in-the-loop prompt unless the user explicitly provides that answer.";
|
|
148
|
+
return `✓ ${subject} ${location}.${question} User responded with: ${details.answerSummary}. ${instruction}`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function formatWorkflowHilAnswerInterruptAbortText(details: WorkflowHilAnswerNoticeDetails): string {
|
|
152
|
+
const workflowName = escapeQuotedText(details.workflowName);
|
|
153
|
+
const stage = details.stageName ?? details.stageId;
|
|
154
|
+
const prompt = details.promptId ? `, prompt ${details.promptId}` : "";
|
|
155
|
+
return `The main-chat question was dismissed because the user responded in the workflow chat for workflow "${workflowName}" (run ${details.runId}, stage ${stage}${prompt}). User responded with: ${details.answerSummary}. Do not ask the same question again.`;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function sendHilAnswerNotice(
|
|
159
|
+
send: NonNullable<ExtensionAPI["sendMessage"]>,
|
|
160
|
+
details: WorkflowHilAnswerNoticeDetails,
|
|
161
|
+
): void {
|
|
162
|
+
const content = formatWorkflowHilAnswerNoticeText(details);
|
|
163
|
+
try {
|
|
164
|
+
void Promise.resolve(
|
|
165
|
+
send(
|
|
166
|
+
{
|
|
167
|
+
customType: HIL_ANSWER_NOTICE_CUSTOM_TYPE,
|
|
168
|
+
content,
|
|
169
|
+
display: true,
|
|
170
|
+
details,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
triggerTurn: false,
|
|
174
|
+
excludeFromContext: true,
|
|
175
|
+
},
|
|
176
|
+
),
|
|
177
|
+
).catch((error: unknown) => warnHilAnswerSendFailure(error));
|
|
178
|
+
} catch (error) {
|
|
179
|
+
warnHilAnswerSendFailure(error);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function simplePromptAnswer(
|
|
184
|
+
previousStage: StageSnapshot,
|
|
185
|
+
currentRun: RunSnapshot,
|
|
186
|
+
): { stage: StageSnapshot; prompt: PendingPrompt } | undefined {
|
|
187
|
+
const prompt = previousStage.pendingPrompt;
|
|
188
|
+
if (prompt === undefined) return undefined;
|
|
189
|
+
const currentStage = currentRun.stages.find((stage) => stage.id === previousStage.id);
|
|
190
|
+
if (currentStage === undefined) return undefined;
|
|
191
|
+
if (currentStage.pendingPrompt !== undefined) return undefined;
|
|
192
|
+
if (currentStage.promptAnswerState !== "available") return undefined;
|
|
193
|
+
return { stage: currentStage, prompt };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function findStageSnapshot(
|
|
197
|
+
snapshot: StoreSnapshot,
|
|
198
|
+
runId: string,
|
|
199
|
+
stageId: string,
|
|
200
|
+
): { run: RunSnapshot; stage: StageSnapshot } | undefined {
|
|
201
|
+
const run = snapshot.runs.find((candidate) => candidate.id === runId);
|
|
202
|
+
const stage = run?.stages.find((candidate) => candidate.id === stageId);
|
|
203
|
+
if (run === undefined || stage === undefined) return undefined;
|
|
204
|
+
return { run, stage };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function readHilAnswerNoticeDetails(raw: unknown): WorkflowHilAnswerNoticeDetails | undefined {
|
|
208
|
+
if (typeof raw !== "object" || raw === null || !("details" in raw)) return undefined;
|
|
209
|
+
const message = raw as { details?: WorkflowHilAnswerNoticeDetails };
|
|
210
|
+
return message.details;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function makeSimplePromptAnswerNotice(
|
|
214
|
+
run: RunSnapshot,
|
|
215
|
+
stage: StageSnapshot,
|
|
216
|
+
prompt: PendingPrompt,
|
|
217
|
+
answer: unknown,
|
|
218
|
+
): WorkflowHilAnswerNoticeDetails {
|
|
219
|
+
return {
|
|
220
|
+
kind: "hil_answered",
|
|
221
|
+
scope: "stage",
|
|
222
|
+
runId: run.id,
|
|
223
|
+
workflowName: run.name,
|
|
224
|
+
stageId: stage.id,
|
|
225
|
+
stageName: stage.name,
|
|
226
|
+
promptId: prompt.id,
|
|
227
|
+
promptKind: prompt.kind,
|
|
228
|
+
promptMessage: truncateAnswerSnippet(prompt.message),
|
|
229
|
+
answeredAt: Date.now(),
|
|
230
|
+
answerAvailable: true,
|
|
231
|
+
answerIncluded: true,
|
|
232
|
+
answerSummary: formatAnswerSummary(answer),
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function makeBrokerPromptAnswerNotice(
|
|
237
|
+
run: RunSnapshot,
|
|
238
|
+
stage: StageSnapshot,
|
|
239
|
+
prompt: StageInputRequest,
|
|
240
|
+
answer: unknown,
|
|
241
|
+
answeredAt: number,
|
|
242
|
+
): WorkflowHilAnswerNoticeDetails {
|
|
243
|
+
return {
|
|
244
|
+
kind: "hil_answered",
|
|
245
|
+
scope: "stage",
|
|
246
|
+
runId: run.id,
|
|
247
|
+
workflowName: run.name,
|
|
248
|
+
stageId: stage.id,
|
|
249
|
+
stageName: stage.name,
|
|
250
|
+
promptId: prompt.id,
|
|
251
|
+
promptKind: prompt.kind,
|
|
252
|
+
promptMessage: truncateAnswerSnippet(prompt.questions.map((question) => question.question).join(" | ")),
|
|
253
|
+
answeredAt,
|
|
254
|
+
answerAvailable: true,
|
|
255
|
+
answerIncluded: true,
|
|
256
|
+
answerSummary: formatAnswerSummary(answer),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function formatAnswerSummary(answer: unknown): string {
|
|
261
|
+
const questionnaire = formatQuestionnaireAnswer(answer);
|
|
262
|
+
if (questionnaire !== undefined) return questionnaire;
|
|
263
|
+
if (typeof answer === "string") return truncateAnswerSnippet(answer);
|
|
264
|
+
if (typeof answer === "number" || typeof answer === "boolean" || typeof answer === "bigint") {
|
|
265
|
+
return String(answer);
|
|
266
|
+
}
|
|
267
|
+
if (answer === null) return "null";
|
|
268
|
+
if (answer === undefined) return "(answer unavailable)";
|
|
269
|
+
try {
|
|
270
|
+
return truncateAnswerSnippet(JSON.stringify(answer));
|
|
271
|
+
} catch {
|
|
272
|
+
return truncateAnswerSnippet(String(answer));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function formatQuestionnaireAnswer(answer: unknown): string | undefined {
|
|
277
|
+
if (typeof answer !== "object" || answer === null || !("answers" in answer)) return undefined;
|
|
278
|
+
const answers = (answer as { answers?: unknown }).answers;
|
|
279
|
+
if (!Array.isArray(answers)) return undefined;
|
|
280
|
+
const parts = answers.map(formatQuestionnaireAnswerPart).filter((part) => part.length > 0);
|
|
281
|
+
if (parts.length > 0) return truncateAnswerSnippet(parts.join("; "));
|
|
282
|
+
const cancelled = (answer as { cancelled?: unknown }).cancelled === true;
|
|
283
|
+
return cancelled ? "(cancelled)" : "(no answer)";
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function formatQuestionnaireAnswerPart(value: unknown): string {
|
|
287
|
+
if (typeof value !== "object" || value === null) return "";
|
|
288
|
+
const record = value as { question?: unknown; answer?: unknown; selected?: unknown; kind?: unknown };
|
|
289
|
+
const question = typeof record.question === "string" && record.question.trim().length > 0
|
|
290
|
+
? record.question.trim()
|
|
291
|
+
: "Question";
|
|
292
|
+
const selected = Array.isArray(record.selected)
|
|
293
|
+
? record.selected.filter((item): item is string => typeof item === "string" && item.length > 0).join(", ")
|
|
294
|
+
: "";
|
|
295
|
+
const answer = typeof record.answer === "string" && record.answer.length > 0
|
|
296
|
+
? record.answer
|
|
297
|
+
: selected.length > 0
|
|
298
|
+
? selected
|
|
299
|
+
: typeof record.kind === "string"
|
|
300
|
+
? `(${record.kind})`
|
|
301
|
+
: "(no answer)";
|
|
302
|
+
return `${question} → ${answer}`;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function truncateAnswerSnippet(value: string): string {
|
|
306
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
307
|
+
if (normalized.length <= HIL_ANSWER_SNIPPET_LIMIT) return normalized;
|
|
308
|
+
return `${normalized.slice(0, HIL_ANSWER_SNIPPET_LIMIT - 1)}…`;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function answerNoticeKey(
|
|
312
|
+
runId: string,
|
|
313
|
+
stageId: string,
|
|
314
|
+
promptId: string | undefined,
|
|
315
|
+
promptKind: WorkflowHilAnswerPromptKind | undefined,
|
|
316
|
+
): string {
|
|
317
|
+
return `hil_answered:${runId}:stage:${stageId}:${promptKind ?? "unknown"}:${promptId ?? "unknown"}`;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function warnHilAnswerSendFailure(error: unknown): void {
|
|
321
|
+
if (process.env.ATOMIC_WORKFLOW_DEBUG !== "1") return;
|
|
322
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
323
|
+
console.warn("[workflows] workflow HiL answer notice send failed", message);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function escapeQuotedText(value: string): string {
|
|
327
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function makeNoticeComponent(
|
|
331
|
+
details: WorkflowHilAnswerNoticeDetails,
|
|
332
|
+
theme: GraphTheme | undefined,
|
|
333
|
+
): PiMessageRenderComponent {
|
|
334
|
+
const text = formatWorkflowHilAnswerNoticeText(details);
|
|
335
|
+
return {
|
|
336
|
+
render(width: number): string[] {
|
|
337
|
+
return renderWorkflowNoticeCard({
|
|
338
|
+
title: "HIL ANSWERED",
|
|
339
|
+
glyph: "✓",
|
|
340
|
+
headline: `Workflow "${details.workflowName}" received the user's response`,
|
|
341
|
+
tone: "success",
|
|
342
|
+
fields: [
|
|
343
|
+
{ label: "workflow", value: details.workflowName },
|
|
344
|
+
{ label: "run", value: details.runId },
|
|
345
|
+
{ label: "stage", value: details.stageName ?? details.stageId },
|
|
346
|
+
{ label: "prompt", value: details.promptMessage, tone: "muted" },
|
|
347
|
+
{ label: "answer", value: details.answerSummary },
|
|
348
|
+
],
|
|
349
|
+
footer: "No main-chat action is needed; do not answer other workflow prompts unless the user explicitly provides that answer.",
|
|
350
|
+
fallbackText: text,
|
|
351
|
+
width,
|
|
352
|
+
...(theme ? { theme } : {}),
|
|
353
|
+
});
|
|
354
|
+
},
|
|
355
|
+
invalidate() {
|
|
356
|
+
/* stored HiL-answer notices are immutable */
|
|
357
|
+
},
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function themeFromRenderer(piTheme: unknown): GraphTheme | undefined {
|
|
362
|
+
return piTheme === undefined ? undefined : deriveGraphThemeFromPiTheme(piTheme);
|
|
363
|
+
}
|