@osolmaz/pi-workflows 0.16.0 → 0.16.2

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.
Files changed (175) hide show
  1. package/README.md +18 -2
  2. package/dist/channels/adapter-entry.d.ts +3 -0
  3. package/dist/channels/adapter-entry.js +203 -0
  4. package/dist/channels/adapter-entry.js.map +1 -0
  5. package/dist/channels/config.d.ts +43 -0
  6. package/dist/channels/config.js +234 -0
  7. package/dist/channels/config.js.map +1 -0
  8. package/dist/channels/protocol.d.ts +94 -0
  9. package/dist/channels/protocol.js +219 -0
  10. package/dist/channels/protocol.js.map +1 -0
  11. package/dist/channels/telegram.d.ts +46 -0
  12. package/dist/channels/telegram.js +285 -0
  13. package/dist/channels/telegram.js.map +1 -0
  14. package/dist/client/client.d.ts +1 -0
  15. package/dist/client/client.js +5 -1
  16. package/dist/client/client.js.map +1 -1
  17. package/dist/client/index.d.ts +1 -1
  18. package/dist/client/protocol.d.ts +1 -1
  19. package/dist/client/protocol.js +11 -5
  20. package/dist/client/protocol.js.map +1 -1
  21. package/dist/client/view.d.ts +48 -16
  22. package/dist/client/view.js +1 -0
  23. package/dist/client/view.js.map +1 -1
  24. package/dist/controllers/index.d.ts +1 -1
  25. package/dist/controllers/index.js.map +1 -1
  26. package/dist/controllers/sqlite.d.ts +20 -165
  27. package/dist/controllers/sqlite.js +178 -436
  28. package/dist/controllers/sqlite.js.map +1 -1
  29. package/dist/extension/index.d.ts +23 -2
  30. package/dist/extension/index.js +637 -534
  31. package/dist/extension/index.js.map +1 -1
  32. package/dist/extension/recorder.d.ts +95 -0
  33. package/dist/extension/recorder.js +530 -0
  34. package/dist/extension/recorder.js.map +1 -0
  35. package/dist/extension/remote-recorder-store.d.ts +25 -0
  36. package/dist/extension/remote-recorder-store.js +81 -0
  37. package/dist/extension/remote-recorder-store.js.map +1 -0
  38. package/dist/extension/session-events.d.ts +134 -0
  39. package/dist/extension/session-events.js +60 -0
  40. package/dist/extension/session-events.js.map +1 -0
  41. package/dist/extension/session-view.d.ts +2 -0
  42. package/dist/extension/session-view.js +60 -2
  43. package/dist/extension/session-view.js.map +1 -1
  44. package/dist/extension/step-message.d.ts +6 -4
  45. package/dist/extension/step-message.js +12 -6
  46. package/dist/extension/step-message.js.map +1 -1
  47. package/dist/extension/widget.d.ts +2 -2
  48. package/dist/extension/widget.js +28 -18
  49. package/dist/extension/widget.js.map +1 -1
  50. package/dist/extension/workflow-message-coordinator.d.ts +28 -0
  51. package/dist/extension/workflow-message-coordinator.js +346 -0
  52. package/dist/extension/workflow-message-coordinator.js.map +1 -0
  53. package/dist/host/channel-effects.d.ts +72 -0
  54. package/dist/host/channel-effects.js +271 -0
  55. package/dist/host/channel-effects.js.map +1 -0
  56. package/dist/host/channel-supervisor.d.ts +21 -0
  57. package/dist/host/channel-supervisor.js +54 -0
  58. package/dist/host/channel-supervisor.js.map +1 -0
  59. package/dist/host/runner.d.ts +50 -8
  60. package/dist/host/runner.js +1632 -341
  61. package/dist/host/runner.js.map +1 -1
  62. package/dist/host/state.d.ts +19 -16
  63. package/dist/host/state.js +251 -63
  64. package/dist/host/state.js.map +1 -1
  65. package/dist/host/view.d.ts +19 -9
  66. package/dist/host/view.js +227 -119
  67. package/dist/host/view.js.map +1 -1
  68. package/dist/host/worker-entry.d.ts +4 -1
  69. package/dist/host/worker-entry.js +23 -24
  70. package/dist/host/worker-entry.js.map +1 -1
  71. package/dist/host/worker-protocol.d.ts +15 -0
  72. package/dist/host/worker-protocol.js.map +1 -1
  73. package/dist/state/prune.js +3 -25
  74. package/dist/state/prune.js.map +1 -1
  75. package/dist/state/schema.js +76 -97
  76. package/dist/state/schema.js.map +1 -1
  77. package/dist/state/workflow-messages.d.ts +98 -0
  78. package/dist/state/workflow-messages.js +366 -0
  79. package/dist/state/workflow-messages.js.map +1 -0
  80. package/dist/viewer/render.js +1 -1
  81. package/dist/viewer/render.js.map +1 -1
  82. package/dist/viewer/tui.d.ts +1 -1
  83. package/dist/viewer/tui.js +65 -8
  84. package/dist/viewer/tui.js.map +1 -1
  85. package/dist/workflows/composition.js +0 -4
  86. package/dist/workflows/composition.js.map +1 -1
  87. package/dist/workflows/definition.js +0 -8
  88. package/dist/workflows/definition.js.map +1 -1
  89. package/dist/workflows/engine.js +4 -5
  90. package/dist/workflows/engine.js.map +1 -1
  91. package/dist/workflows/human-decision.d.ts +2 -0
  92. package/dist/workflows/human-decision.js +8 -2
  93. package/dist/workflows/human-decision.js.map +1 -1
  94. package/dist/workflows/index.d.ts +1 -1
  95. package/dist/workflows/index.js.map +1 -1
  96. package/dist/workflows/schema.js +0 -4
  97. package/dist/workflows/schema.js.map +1 -1
  98. package/dist/workflows/settings.d.ts +1 -8
  99. package/dist/workflows/settings.js.map +1 -1
  100. package/dist/workflows/store.d.ts +20 -19
  101. package/dist/workflows/store.js +163 -354
  102. package/dist/workflows/store.js.map +1 -1
  103. package/dist/workflows/tool-input.d.ts +21 -0
  104. package/dist/workflows/tool-input.js +23 -1
  105. package/dist/workflows/tool-input.js.map +1 -1
  106. package/dist/workflows/types.d.ts +6 -8
  107. package/dist/workflows/workflow-message-content.d.ts +38 -0
  108. package/dist/workflows/workflow-message-content.js +157 -0
  109. package/dist/workflows/workflow-message-content.js.map +1 -0
  110. package/docs/2026-08-18-herdr-piw-plan.md +2 -1
  111. package/docs/2026-08-20-durable-workflow-launch-plan.md +1 -1
  112. package/docs/2026-08-25-workflow-follow-ups.md +26 -50
  113. package/docs/2026-08-30-out-of-process-workflow-host-plan.md +3 -3
  114. package/docs/2026-09-01-restore-session-delivery-controls-plan.md +4 -0
  115. package/docs/2026-09-01-unified-workflow-client-plan.md +5 -1
  116. package/docs/2026-09-02-installed-live-e2e-plan.md +15 -1
  117. package/docs/2026-09-02-unify-workflow-messages-plan.md +562 -0
  118. package/docs/2026-09-04-workflow-run-state-plan.md +363 -0
  119. package/docs/DEFERRED_TURNS.md +66 -294
  120. package/docs/HUMAN_DECISIONS.md +29 -30
  121. package/docs/HUMAN_DECISION_PRESENTATIONS.md +4 -11
  122. package/docs/SQLITE_STATE.md +25 -17
  123. package/docs/WORKFLOW_HOST.md +105 -31
  124. package/docs/WORKFLOW_STEP_MESSAGES.md +166 -75
  125. package/docs/live-replay-protocol.md +8 -4
  126. package/docs/tui-viewer.md +3 -1
  127. package/docs/workflows.md +44 -28
  128. package/herdr-plugin.toml +1 -1
  129. package/package.json +1 -1
  130. package/plugins/herdr/viewer.mjs +14 -5
  131. package/src/channels/adapter-entry.ts +220 -0
  132. package/src/channels/config.ts +296 -0
  133. package/src/channels/protocol.ts +333 -0
  134. package/src/channels/telegram.ts +335 -0
  135. package/src/client/client.ts +6 -2
  136. package/src/client/index.ts +2 -1
  137. package/src/client/protocol.ts +11 -5
  138. package/src/client/view.ts +51 -18
  139. package/src/controllers/index.ts +0 -1
  140. package/src/controllers/sqlite.ts +247 -845
  141. package/src/extension/index.ts +712 -647
  142. package/src/extension/recorder.ts +687 -0
  143. package/src/extension/remote-recorder-store.ts +126 -0
  144. package/src/extension/session-events.ts +119 -0
  145. package/src/extension/session-view.ts +86 -3
  146. package/src/extension/step-message.ts +19 -9
  147. package/src/extension/widget.ts +37 -17
  148. package/src/extension/workflow-message-coordinator.ts +398 -0
  149. package/src/host/channel-effects.ts +465 -0
  150. package/src/host/channel-supervisor.ts +73 -0
  151. package/src/host/runner.ts +2163 -525
  152. package/src/host/state.ts +333 -94
  153. package/src/host/view.ts +254 -122
  154. package/src/host/worker-entry.ts +38 -30
  155. package/src/host/worker-protocol.ts +11 -0
  156. package/src/state/prune.ts +3 -31
  157. package/src/state/schema.ts +76 -97
  158. package/src/state/workflow-messages.ts +599 -0
  159. package/src/viewer/render.ts +1 -5
  160. package/src/viewer/tui.ts +71 -6
  161. package/src/workflows/composition.ts +0 -5
  162. package/src/workflows/definition.ts +0 -8
  163. package/src/workflows/engine.ts +4 -6
  164. package/src/workflows/human-decision.ts +18 -2
  165. package/src/workflows/index.ts +0 -1
  166. package/src/workflows/schema.ts +0 -6
  167. package/src/workflows/settings.ts +1 -20
  168. package/src/workflows/store.ts +237 -489
  169. package/src/workflows/tool-input.ts +36 -1
  170. package/src/workflows/types.ts +6 -8
  171. package/src/workflows/workflow-message-content.ts +197 -0
  172. package/dist/extension/decision-channels.d.ts +0 -134
  173. package/dist/extension/decision-channels.js +0 -1307
  174. package/dist/extension/decision-channels.js.map +0 -1
  175. package/src/extension/decision-channels.ts +0 -1826
@@ -12,7 +12,8 @@ const inputSchema = Type.Unknown({
12
12
  "Ordinary checkpoint answer for answer; protected human decisions require a human channel; optional structured workflow input for start",
13
13
  });
14
14
  const runIdSchema = Type.String({
15
- description: "Run id; optional for status, cancel, and answer",
15
+ description:
16
+ "Run id; required for restart and optional for status, cancel, answer, settings, and follow-ups",
16
17
  });
17
18
  const stepSchema = Type.String({
18
19
  description: "Workflow step id; required when action is update or submit",
@@ -44,6 +45,33 @@ export const WorkflowActionSchemas = {
44
45
  },
45
46
  noExtraProperties,
46
47
  ),
48
+ restart: Type.Object({ action: Type.Literal("restart"), runId: runIdSchema }, noExtraProperties),
49
+ "change-settings": Type.Object(
50
+ {
51
+ action: Type.Literal("change-settings"),
52
+ runId: Type.Optional(runIdSchema),
53
+ scopeId: Type.Optional(Type.String()),
54
+ expectedChangeNumber: Type.Optional(Type.Integer({ minimum: 0 })),
55
+ patch: Type.Unknown(),
56
+ },
57
+ noExtraProperties,
58
+ ),
59
+ "queue-follow-up": Type.Object(
60
+ {
61
+ action: Type.Literal("queue-follow-up"),
62
+ runId: Type.Optional(runIdSchema),
63
+ prompt: Type.String({ minLength: 1 }),
64
+ },
65
+ noExtraProperties,
66
+ ),
67
+ "remove-follow-up": Type.Object(
68
+ {
69
+ action: Type.Literal("remove-follow-up"),
70
+ runId: Type.Optional(runIdSchema),
71
+ followUpId: Type.String(),
72
+ },
73
+ noExtraProperties,
74
+ ),
47
75
  status: Type.Object(
48
76
  { action: Type.Literal("status"), runId: Type.Optional(runIdSchema) },
49
77
  noExtraProperties,
@@ -102,6 +130,13 @@ type ToolInputParser<Output> = (value: unknown) => Output;
102
130
  const workflowInputParsers = {
103
131
  list: (value) => parseToolInput(WorkflowActionSchemas.list, value, "workflow"),
104
132
  start: (value) => parseToolInput(WorkflowActionSchemas.start, value, "workflow"),
133
+ restart: (value) => parseToolInput(WorkflowActionSchemas.restart, value, "workflow"),
134
+ "change-settings": (value) =>
135
+ parseToolInput(WorkflowActionSchemas["change-settings"], value, "workflow"),
136
+ "queue-follow-up": (value) =>
137
+ parseToolInput(WorkflowActionSchemas["queue-follow-up"], value, "workflow"),
138
+ "remove-follow-up": (value) =>
139
+ parseToolInput(WorkflowActionSchemas["remove-follow-up"], value, "workflow"),
105
140
  status: (value) => parseToolInput(WorkflowActionSchemas.status, value, "workflow"),
106
141
  pause: (value) => parseToolInput(WorkflowActionSchemas.pause, value, "workflow"),
107
142
  resume: (value) => parseToolInput(WorkflowActionSchemas.resume, value, "workflow"),
@@ -53,9 +53,7 @@ export type WorkflowEffectRecovery = "idempotent" | "manual";
53
53
  export type WorkflowManagedEffect = {
54
54
  /** Stable external effect category, for example `github.comment`. */
55
55
  type: string;
56
- /** Stable key. Idempotent adapters must pass this key to the external system. */
57
- idempotencyKey: string | ((context: WorkflowNodeContext) => MaybePromise<string>);
58
- /** Canonical request data used to reject key reuse with another operation. */
56
+ /** Canonical request data used to reject engine-owned key reuse with another operation. */
59
57
  request: unknown | ((context: WorkflowNodeContext) => MaybePromise<unknown>);
60
58
  /** `manual` never retries after an uncertain child exit. */
61
59
  recovery: WorkflowEffectRecovery;
@@ -97,9 +95,9 @@ export type WorkflowProgressData = {
97
95
 
98
96
  export type WorkflowNodeCommon = {
99
97
  /**
100
- * Per-node timeout or a callback that derives it from the run context.
101
- * Null disables the wall-clock deadline. Omission falls back to the engine
102
- * default (15 minutes).
98
+ * Per-node active-execution timeout or a callback that derives it from the run context.
99
+ * Waiting, paused, disconnected, and host-down origin-session time does not count.
100
+ * Null disables the deadline. Omission falls back to the engine default (15 minutes).
103
101
  */
104
102
  timeoutMs?: number | null | ((context: WorkflowNodeContext) => MaybePromise<number | null>);
105
103
  /** Short human-readable label shown in the viewer while the node runs. */
@@ -436,7 +434,7 @@ export type HumanDecisionSettlementRecord = {
436
434
  decisionId: string;
437
435
  requestDigest: string;
438
436
  channel: string;
439
- state: "confirmed" | "failed";
437
+ state: "confirmed" | "failed" | "unknown";
440
438
  createdAt: string;
441
439
  finishedAt: string;
442
440
  errorCode?: string;
@@ -719,7 +717,7 @@ export type WorkflowRunState = {
719
717
  currentNode?: string;
720
718
  currentAttemptId?: string;
721
719
  currentNodeStartedAt?: string;
722
- /** Durable wall-clock deadline for the current attempt. Null disables the deadline. */
720
+ /** Durable active-execution deadline for the current attempt. Null disables the deadline. */
723
721
  currentNodeDeadlineAt?: string | null;
724
722
  currentSettingsScopeId?: string;
725
723
  currentSettingsChangeNumber?: number;
@@ -0,0 +1,197 @@
1
+ import type { JsonValue } from "../state/json.js";
2
+ import {
3
+ WORKFLOW_MESSAGE_CONTENT_SCHEMA,
4
+ type WorkflowMessageContent,
5
+ type WorkflowStepReason,
6
+ } from "../state/workflow-messages.js";
7
+ import type { AgentStepContract } from "./types.js";
8
+
9
+ export const WORKFLOW_STEP_MESSAGE_TYPE = "pi-workflows-step";
10
+ export const WORKFLOW_DECISION_MESSAGE_TYPE = "pi-workflows-interaction";
11
+ export const WORKFLOW_NOTIFICATION_MESSAGE_TYPE = "pi-workflows-notification";
12
+ export const WORKFLOW_TERMINAL_MESSAGE_TYPE = "pi-workflows-presentation";
13
+ export const WORKFLOW_FOLLOW_UP_MESSAGE_TYPE = "pi-workflows-follow-up";
14
+
15
+ export function stepWorkflowMessageContent(options: {
16
+ workflowMessageId: string;
17
+ requestId: string;
18
+ contract: JsonValue;
19
+ reason: WorkflowStepReason;
20
+ }): WorkflowMessageContent {
21
+ const outer = requireRecord(options.contract, "Stored workflow step contract");
22
+ const agent = requireAgentContract(outer.contract);
23
+ const details: Record<string, JsonValue> = {
24
+ schema: "pi-workflows.agent-step-message.v1",
25
+ kind: "step",
26
+ contract: agent as unknown as JsonValue,
27
+ requestId: options.requestId,
28
+ workflowMessageId: options.workflowMessageId,
29
+ reason: options.reason,
30
+ };
31
+ if (isRecord(outer.presentation)) details.presentation = outer.presentation as JsonValue;
32
+ return {
33
+ schema: WORKFLOW_MESSAGE_CONTENT_SCHEMA,
34
+ customType: WORKFLOW_STEP_MESSAGE_TYPE,
35
+ content: typeof outer.prompt === "string" ? outer.prompt : "Continue the workflow step.",
36
+ display: true,
37
+ details,
38
+ triggerTurn: true,
39
+ };
40
+ }
41
+
42
+ export function decisionWorkflowMessageContent(options: {
43
+ workflowMessageId: string;
44
+ requestId: string;
45
+ runId: string;
46
+ contract: JsonValue;
47
+ }): WorkflowMessageContent {
48
+ const contract = requireRecord(options.contract, "Stored workflow decision contract");
49
+ return {
50
+ schema: WORKFLOW_MESSAGE_CONTENT_SCHEMA,
51
+ customType: WORKFLOW_DECISION_MESSAGE_TYPE,
52
+ content: decisionPrompt(contract),
53
+ display: true,
54
+ details: {
55
+ workflowMessageId: options.workflowMessageId,
56
+ requestId: options.requestId,
57
+ runId: options.runId,
58
+ kind: "decision",
59
+ },
60
+ triggerTurn: false,
61
+ };
62
+ }
63
+
64
+ export function notificationWorkflowMessageContent(options: {
65
+ workflowMessageId: string;
66
+ notificationId: string;
67
+ runId: string;
68
+ kind: "progress" | "final";
69
+ content: string;
70
+ }): WorkflowMessageContent {
71
+ return {
72
+ schema: WORKFLOW_MESSAGE_CONTENT_SCHEMA,
73
+ customType: WORKFLOW_NOTIFICATION_MESSAGE_TYPE,
74
+ content: options.content,
75
+ display: true,
76
+ details: {
77
+ workflowMessageId: options.workflowMessageId,
78
+ notificationId: options.notificationId,
79
+ runId: options.runId,
80
+ kind: options.kind,
81
+ },
82
+ triggerTurn: false,
83
+ };
84
+ }
85
+
86
+ export function terminalWorkflowMessageContent(options: {
87
+ workflowMessageId: string;
88
+ runId: string;
89
+ content: string;
90
+ details: JsonValue;
91
+ }): WorkflowMessageContent {
92
+ return {
93
+ schema: WORKFLOW_MESSAGE_CONTENT_SCHEMA,
94
+ customType: WORKFLOW_TERMINAL_MESSAGE_TYPE,
95
+ content: options.content,
96
+ display: false,
97
+ details: {
98
+ workflowMessageId: options.workflowMessageId,
99
+ runId: options.runId,
100
+ kind: "terminal",
101
+ terminal: options.details,
102
+ },
103
+ triggerTurn: true,
104
+ };
105
+ }
106
+
107
+ export function followUpWorkflowMessageContent(options: {
108
+ workflowMessageId: string;
109
+ followUpId: string;
110
+ runId: string;
111
+ prompt: string;
112
+ }): WorkflowMessageContent {
113
+ return {
114
+ schema: WORKFLOW_MESSAGE_CONTENT_SCHEMA,
115
+ customType: WORKFLOW_FOLLOW_UP_MESSAGE_TYPE,
116
+ content: options.prompt,
117
+ display: true,
118
+ details: {
119
+ workflowMessageId: options.workflowMessageId,
120
+ followUpId: options.followUpId,
121
+ runId: options.runId,
122
+ kind: "followUp",
123
+ },
124
+ triggerTurn: true,
125
+ };
126
+ }
127
+
128
+ function requireAgentContract(value: unknown): AgentStepContract {
129
+ if (
130
+ !isRecord(value) ||
131
+ typeof value.runId !== "string" ||
132
+ typeof value.workflowName !== "string" ||
133
+ typeof value.nodeId !== "string" ||
134
+ typeof value.attemptId !== "string" ||
135
+ (value.completion !== "submit" && value.completion !== "assistant")
136
+ ) {
137
+ throw new Error("Stored workflow agent contract is invalid");
138
+ }
139
+ return value as unknown as AgentStepContract;
140
+ }
141
+
142
+ function decisionPrompt(contract: Record<string, unknown>): string {
143
+ const title = typeof contract.title === "string" ? contract.title : "Workflow decision";
144
+ const presentation = isRecord(contract.presentation) ? contract.presentation : {};
145
+ const blocks = Array.isArray(presentation.blocks)
146
+ ? presentation.blocks.flatMap((block) => decisionBlockText(block))
147
+ : [];
148
+ const choices = isRecord(contract.choices)
149
+ ? Object.entries(contract.choices).map(([key, value]) => {
150
+ const choice = isRecord(value) ? value : {};
151
+ const label = typeof choice.label === "string" ? choice.label : key;
152
+ const input = isRecord(choice.input) ? choice.input : undefined;
153
+ const prompt = input === undefined ? "" : `; input: ${String(input.prompt ?? "text")}`;
154
+ return `- ${key}: ${label}${prompt}`;
155
+ })
156
+ : [];
157
+ return [
158
+ title,
159
+ typeof presentation.summary === "string" ? presentation.summary : "",
160
+ ...blocks,
161
+ choices.length === 0 ? "" : `Choices:\n${choices.join("\n")}`,
162
+ "A human must answer this protected decision with `/workflow answer`.",
163
+ ]
164
+ .filter(Boolean)
165
+ .join("\n\n");
166
+ }
167
+
168
+ function decisionBlockText(value: unknown): string[] {
169
+ if (!isRecord(value)) return [];
170
+ if (value.kind === "paragraph" && typeof value.text === "string") return [value.text];
171
+ if (value.kind === "section" && typeof value.title === "string") return [value.title];
172
+ if (value.kind === "preformatted" && typeof value.text === "string") return [value.text];
173
+ if (value.kind === "bullets" && Array.isArray(value.items)) {
174
+ return [value.items.map((item) => `- ${String(item)}`).join("\n")];
175
+ }
176
+ if (value.kind === "fields" && Array.isArray(value.items)) {
177
+ return [
178
+ value.items
179
+ .flatMap((item) =>
180
+ isRecord(item) && typeof item.label === "string" && typeof item.value === "string"
181
+ ? [`${item.label}: ${item.value}`]
182
+ : [],
183
+ )
184
+ .join("\n"),
185
+ ];
186
+ }
187
+ return [];
188
+ }
189
+
190
+ function requireRecord(value: unknown, label: string): Record<string, unknown> {
191
+ if (!isRecord(value)) throw new Error(`${label} is invalid`);
192
+ return value;
193
+ }
194
+
195
+ function isRecord(value: unknown): value is Record<string, unknown> {
196
+ return typeof value === "object" && value !== null && !Array.isArray(value);
197
+ }
@@ -1,134 +0,0 @@
1
- import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
- import { HumanDecisionStore } from "../workflows/human-decision.js";
3
- import type { ResolvedHumanDecision, HumanDecisionAnswerSource, HumanDecisionCancellationRecord, HumanDecisionChannelRequest, HumanDecisionResponse } from "../workflows/types.js";
4
- export type HumanDecisionChannelAnswer = {
5
- request: HumanDecisionChannelRequest;
6
- response: HumanDecisionResponse;
7
- source: HumanDecisionAnswerSource;
8
- idempotencyKey: string;
9
- };
10
- export type HumanDecisionDeliveryResult = {
11
- status: "confirmed" | "failed" | "unknown";
12
- channel: string;
13
- attemptId: string;
14
- errorCode?: string;
15
- };
16
- export type SettledHumanDecision = ResolvedHumanDecision | HumanDecisionCancellationRecord;
17
- export interface HumanDecisionChannel {
18
- readonly id: string;
19
- start(): Promise<void>;
20
- deliver(request: HumanDecisionChannelRequest): Promise<HumanDecisionDeliveryResult>;
21
- settle(decision: SettledHumanDecision): Promise<void>;
22
- stop(): Promise<void>;
23
- }
24
- export type DecisionChannelConfig = {
25
- schema: "pi-workflows.channels.v1";
26
- audiences: Record<string, {
27
- channels: string[];
28
- accept: "first-valid-answer";
29
- }>;
30
- telegramProfiles?: Record<string, {
31
- credential: string;
32
- allowedUserIds: string[];
33
- allowedChatIds: string[];
34
- }>;
35
- };
36
- export type DecisionCredentialConfig = {
37
- schema: "pi-workflows.credentials.v1";
38
- telegram: Record<string, {
39
- tokenFile: string;
40
- }>;
41
- };
42
- type ResolvedDecisionCredentials = Record<string, string>;
43
- export type LoadedDecisionChannelConfig = {
44
- channels: DecisionChannelConfig;
45
- credentials: ResolvedDecisionCredentials;
46
- configDir: string;
47
- };
48
- export type TelegramFetch = (input: string, init?: RequestInit) => Promise<{
49
- ok: boolean;
50
- status: number;
51
- json(): Promise<unknown>;
52
- }>;
53
- export type PiDecisionUi = Pick<ExtensionContext["ui"], "custom" | "input">;
54
- export declare function decisionConfigDir(env?: NodeJS.ProcessEnv): string;
55
- export declare function loadDecisionChannelConfig(configDir?: string): Promise<LoadedDecisionChannelConfig | null>;
56
- export declare function audienceChannels(config: DecisionChannelConfig | null, audience: string): string[];
57
- export declare class PiDecisionChannel implements HumanDecisionChannel {
58
- private readonly options;
59
- readonly id = "pi";
60
- private promptAbort;
61
- private settlementTask;
62
- constructor(options: {
63
- actorId: string;
64
- ui: PiDecisionUi;
65
- store: HumanDecisionStore;
66
- onAnswer: (answer: HumanDecisionChannelAnswer) => Promise<void>;
67
- });
68
- start(): Promise<void>;
69
- stop(): Promise<void>;
70
- deliver(request: HumanDecisionChannelRequest): Promise<HumanDecisionDeliveryResult>;
71
- private alreadyDecided;
72
- settle(decision: SettledHumanDecision): Promise<void>;
73
- private settleOnce;
74
- }
75
- export declare class TelegramDecisionChannel implements HumanDecisionChannel {
76
- readonly id: string;
77
- private readonly profile;
78
- private readonly store;
79
- private readonly fetchFn;
80
- private readonly apiBase;
81
- private readonly onAnswer;
82
- private readonly projection;
83
- private running;
84
- private pollAbort;
85
- private pollTask;
86
- private readonly settlementTasks;
87
- constructor(options: {
88
- profileName: string;
89
- token: string;
90
- allowedUserIds: string[];
91
- allowedChatIds: string[];
92
- store: HumanDecisionStore;
93
- configDir?: string;
94
- onAnswer: (answer: HumanDecisionChannelAnswer) => Promise<void>;
95
- fetchFn?: TelegramFetch;
96
- apiBase?: string;
97
- ownerId?: string;
98
- });
99
- start(): Promise<void>;
100
- stop(): Promise<void>;
101
- deliver(request: HumanDecisionChannelRequest): Promise<HumanDecisionDeliveryResult>;
102
- settle(decision: SettledHumanDecision): Promise<void>;
103
- private settleOnce;
104
- handleUpdate(value: unknown): Promise<void>;
105
- private registerCallbacks;
106
- private channelPath;
107
- private allowed;
108
- private isStale;
109
- private poll;
110
- private deliverPendingRequests;
111
- private call;
112
- }
113
- export declare function createTelegramChannels(options: {
114
- config: DecisionChannelConfig;
115
- credentials: ResolvedDecisionCredentials;
116
- store: HumanDecisionStore;
117
- configDir?: string;
118
- onAnswer: (answer: HumanDecisionChannelAnswer) => Promise<void>;
119
- fetchFn?: TelegramFetch;
120
- apiBase?: string;
121
- }): Map<string, TelegramDecisionChannel>;
122
- export declare function verifyTelegramTokenFile(tokenFile: string, fetchFn?: TelegramFetch, apiBase?: string): Promise<void>;
123
- export declare function writeDecisionChannelProfile(options: {
124
- configDir?: string;
125
- audience: string;
126
- profile: string;
127
- credential: string;
128
- tokenFile: string;
129
- allowedUserIds: string[];
130
- allowedChatIds: string[];
131
- }): Promise<void>;
132
- export declare function renderDecisionText(request: HumanDecisionChannelRequest): string;
133
- export declare function renderTelegramParts(request: HumanDecisionChannelRequest, textLimit?: number): string[];
134
- export {};