@osolmaz/pi-workflows 0.9.1 → 0.11.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/README.md +64 -19
- package/dist/builtins/autodoc.workflow.d.ts +58 -0
- package/dist/builtins/autodoc.workflow.js +266 -0
- package/dist/builtins/autodoc.workflow.js.map +1 -0
- package/dist/builtins/autoimplement.workflow.d.ts +353 -0
- package/dist/builtins/autoimplement.workflow.js +961 -0
- package/dist/builtins/autoimplement.workflow.js.map +1 -0
- package/dist/builtins/autoplan.workflow.d.ts +58 -0
- package/dist/builtins/autoplan.workflow.js +190 -0
- package/dist/builtins/autoplan.workflow.js.map +1 -0
- package/dist/builtins/catalog.js +9 -1
- package/dist/builtins/catalog.js.map +1 -1
- package/dist/builtins/index.d.ts +6 -0
- package/dist/builtins/index.js +7 -0
- package/dist/builtins/index.js.map +1 -0
- package/dist/builtins/monitor.workflow.d.ts +29 -3
- package/dist/builtins/monitor.workflow.js +325 -13
- package/dist/builtins/monitor.workflow.js.map +1 -1
- package/dist/builtins/plan-approval.workflow.d.ts +83 -0
- package/dist/builtins/plan-approval.workflow.js +148 -0
- package/dist/builtins/plan-approval.workflow.js.map +1 -0
- package/dist/builtins/plan-presentation.d.ts +7 -0
- package/dist/builtins/plan-presentation.js +44 -0
- package/dist/builtins/plan-presentation.js.map +1 -0
- package/dist/extension/decision-channels.d.ts +132 -0
- package/dist/extension/decision-channels.js +1082 -0
- package/dist/extension/decision-channels.js.map +1 -0
- package/dist/extension/index.d.ts +1 -0
- package/dist/extension/index.js +426 -11
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/widget.js +26 -2
- package/dist/extension/widget.js.map +1 -1
- package/dist/extension/workflow-tool.d.ts +1 -37
- package/dist/extension/workflow-tool.js +1 -42
- package/dist/extension/workflow-tool.js.map +1 -1
- package/dist/host/rpc-bridge.js +4 -21
- package/dist/host/rpc-bridge.js.map +1 -1
- package/dist/render/graph-render.js +46 -10
- package/dist/render/graph-render.js.map +1 -1
- package/dist/viewer/render.js +36 -2
- package/dist/viewer/render.js.map +1 -1
- package/dist/workflows/catalog.d.ts +1 -0
- package/dist/workflows/catalog.js +6 -0
- package/dist/workflows/catalog.js.map +1 -1
- package/dist/workflows/composition.d.ts +45 -0
- package/dist/workflows/composition.js +485 -0
- package/dist/workflows/composition.js.map +1 -0
- package/dist/workflows/decision-presentation.d.ts +18 -0
- package/dist/workflows/decision-presentation.js +417 -0
- package/dist/workflows/decision-presentation.js.map +1 -0
- package/dist/workflows/decision.d.ts +11 -5
- package/dist/workflows/decision.js.map +1 -1
- package/dist/workflows/definition.d.ts +22 -3
- package/dist/workflows/definition.js +46 -3
- package/dist/workflows/definition.js.map +1 -1
- package/dist/workflows/engine.d.ts +2 -1
- package/dist/workflows/engine.js +199 -18
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/graph.js +8 -6
- package/dist/workflows/graph.js.map +1 -1
- package/dist/workflows/human-decision.d.ts +87 -0
- package/dist/workflows/human-decision.js +583 -0
- package/dist/workflows/human-decision.js.map +1 -0
- package/dist/workflows/index.d.ts +5 -2
- package/dist/workflows/index.js +4 -1
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/loader.d.ts +5 -4
- package/dist/workflows/loader.js +118 -18
- package/dist/workflows/loader.js.map +1 -1
- package/dist/workflows/schema.d.ts +3 -1
- package/dist/workflows/schema.js +64 -2
- package/dist/workflows/schema.js.map +1 -1
- package/dist/workflows/store.js +39 -2
- package/dist/workflows/store.js.map +1 -1
- package/dist/workflows/tool-input.d.ts +72 -0
- package/dist/workflows/tool-input.js +141 -0
- package/dist/workflows/tool-input.js.map +1 -0
- package/dist/workflows/types.d.ts +300 -2
- package/docs/CONTROLLERS.md +1 -1
- package/docs/DESIGN_PHILOSOPHY.md +1 -1
- package/docs/HUMAN_DECISIONS.md +371 -0
- package/docs/HUMAN_DECISION_PRESENTATIONS.md +323 -0
- package/docs/MONITOR.md +46 -18
- package/docs/WORKFLOW_COMPOSITION.md +333 -0
- package/docs/plans/2026-08-19-human-decision-gates-plan.md +296 -0
- package/docs/plans/2026-08-19-human-decision-presentations-plan.md +172 -0
- package/docs/plans/2026-08-19-provider-compatible-workflow-tool-schema-plan.md +45 -0
- package/docs/plans/2026-08-19-workflow-composition-plan.md +308 -0
- package/docs/run-bundles.md +45 -10
- package/docs/workflows.md +106 -15
- package/examples/workflows/approved-plan.workflow.ts +58 -0
- package/examples/workflows/autoimplement.workflow.ts +1 -92
- package/examples/workflows/autoplan.workflow.ts +1 -0
- package/examples/workflows/human-decision.workflow.ts +62 -0
- package/herdr-plugin.toml +1 -1
- package/package.json +6 -1
- package/schemas/decision-presentation-v1.schema.json +83 -0
- package/schemas/human-decision-accepted-v1.schema.json +44 -0
- package/schemas/human-decision-accepted-v2.schema.json +50 -0
- package/schemas/human-decision-answer-attempt-v1.schema.json +37 -0
- package/schemas/human-decision-cancellation-v1.schema.json +15 -0
- package/schemas/human-decision-continuation-v1.schema.json +16 -0
- package/schemas/human-decision-delivery-v1.schema.json +28 -0
- package/schemas/human-decision-delivery-v2.schema.json +36 -0
- package/schemas/human-decision-receipt-v1.schema.json +33 -0
- package/schemas/human-decision-receipt-v2.schema.json +39 -0
- package/schemas/human-decision-request-v1.schema.json +59 -0
- package/schemas/human-decision-request-v2.schema.json +69 -0
- package/schemas/human-decision-resolution-v1.schema.json +27 -0
- package/schemas/human-decision-resolution-v2.schema.json +27 -0
- package/schemas/human-decision-settlement-v1.schema.json +28 -0
- package/skills/autodoc/SKILL.md +43 -0
- package/skills/autoimplement/SKILL.md +58 -0
- package/skills/autoimplement/agents/openai.yaml +4 -0
- package/skills/autoplan/SKILL.md +25 -0
- package/skills/monitor/SKILL.md +8 -1
- package/skills/pi-workflows/SKILL.md +5 -3
- package/src/builtins/autodoc.workflow.ts +325 -0
- package/src/builtins/autoimplement.workflow.ts +1123 -0
- package/src/builtins/autoplan.workflow.ts +231 -0
- package/src/builtins/catalog.ts +9 -1
- package/src/builtins/index.ts +32 -0
- package/src/builtins/monitor.workflow.ts +396 -15
- package/src/builtins/plan-approval.workflow.ts +190 -0
- package/src/builtins/plan-presentation.ts +57 -0
- package/src/extension/decision-channels.ts +1533 -0
- package/src/extension/index.ts +499 -9
- package/src/extension/widget.ts +39 -2
- package/src/extension/workflow-tool.ts +5 -81
- package/src/host/rpc-bridge.ts +7 -30
- package/src/render/graph-render.ts +54 -5
- package/src/viewer/render.ts +56 -3
- package/src/workflows/catalog.ts +7 -0
- package/src/workflows/composition.ts +642 -0
- package/src/workflows/decision-presentation.ts +501 -0
- package/src/workflows/decision.ts +12 -5
- package/src/workflows/definition.ts +118 -8
- package/src/workflows/engine.ts +257 -20
- package/src/workflows/graph.ts +8 -6
- package/src/workflows/human-decision.ts +819 -0
- package/src/workflows/index.ts +89 -0
- package/src/workflows/loader.ts +186 -18
- package/src/workflows/schema.ts +79 -2
- package/src/workflows/store.ts +45 -2
- package/src/workflows/tool-input.ts +202 -0
- package/src/workflows/types.ts +374 -2
- package/examples/workflows/elegant-solution.workflow.ts +0 -95
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { compute, defineWorkflow } from "../workflows/definition.js";
|
|
2
|
+
import { choice, defineHumanChoices, humanDecision, humanDecisionEdge, textInput, } from "../workflows/human-decision.js";
|
|
3
|
+
import { presentPlan } from "./plan-presentation.js";
|
|
4
|
+
const planChoices = defineHumanChoices({
|
|
5
|
+
continue: choice({ label: "Yes, continue" }),
|
|
6
|
+
stop: choice({ label: "No, stop" }),
|
|
7
|
+
replan: choice({
|
|
8
|
+
label: "Replan",
|
|
9
|
+
input: textInput({
|
|
10
|
+
name: "instructions",
|
|
11
|
+
prompt: "What should change?",
|
|
12
|
+
minLength: 1,
|
|
13
|
+
maxLength: 4_000,
|
|
14
|
+
}),
|
|
15
|
+
}),
|
|
16
|
+
});
|
|
17
|
+
function requireRecord(value, label) {
|
|
18
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
19
|
+
throw new Error(`${label} must be an object`);
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function requireString(value, label) {
|
|
24
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
25
|
+
throw new Error(`${label} must be a non-empty string`);
|
|
26
|
+
}
|
|
27
|
+
return value.trim();
|
|
28
|
+
}
|
|
29
|
+
function parseInput(value) {
|
|
30
|
+
const input = requireRecord(value, "plan approval input");
|
|
31
|
+
const revision = input.revision;
|
|
32
|
+
if (revision !== undefined && (!Number.isInteger(revision) || revision < 1)) {
|
|
33
|
+
throw new Error("plan approval revision must be a positive integer");
|
|
34
|
+
}
|
|
35
|
+
if (input.plan === undefined)
|
|
36
|
+
throw new Error("plan approval requires a plan");
|
|
37
|
+
return {
|
|
38
|
+
task: requireString(input.task, "plan approval task"),
|
|
39
|
+
plan: input.plan,
|
|
40
|
+
planDigest: requireString(input.planDigest, "plan approval digest"),
|
|
41
|
+
audience: requireString(input.audience, "plan approval audience"),
|
|
42
|
+
...(revision !== undefined ? { revision: revision } : {}),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function acceptedDecision(value) {
|
|
46
|
+
if (value === undefined)
|
|
47
|
+
throw new Error("plan approval continuation is missing its accepted decision");
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
function gateResponse(value) {
|
|
51
|
+
return requireRecord(value, "plan approval response");
|
|
52
|
+
}
|
|
53
|
+
export const planApprovalWorkflow = defineWorkflow({
|
|
54
|
+
source: import.meta.url,
|
|
55
|
+
contractId: "pi-workflows.plan-approval.v1",
|
|
56
|
+
name: "plan-approval",
|
|
57
|
+
input: parseInput,
|
|
58
|
+
title: ({ input }) => `plan approval: ${input.task.slice(0, 60)}`,
|
|
59
|
+
startAt: "approve",
|
|
60
|
+
maxSteps: 8,
|
|
61
|
+
exits: {
|
|
62
|
+
continue: {
|
|
63
|
+
from: "continued",
|
|
64
|
+
validate: (value) => value,
|
|
65
|
+
},
|
|
66
|
+
stop: {
|
|
67
|
+
from: "stopped",
|
|
68
|
+
validate: (value) => value,
|
|
69
|
+
},
|
|
70
|
+
replan: {
|
|
71
|
+
from: "replan",
|
|
72
|
+
validate: (value) => value,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
nodes: {
|
|
76
|
+
approve: humanDecision({
|
|
77
|
+
audience: ({ input }) => input.audience,
|
|
78
|
+
choices: planChoices,
|
|
79
|
+
request: ({ input }) => {
|
|
80
|
+
const request = input;
|
|
81
|
+
const revision = request.revision ?? 1;
|
|
82
|
+
return {
|
|
83
|
+
title: "Approve the implementation plan",
|
|
84
|
+
subject: {
|
|
85
|
+
task: request.task,
|
|
86
|
+
plan: request.plan,
|
|
87
|
+
planDigest: request.planDigest,
|
|
88
|
+
revision,
|
|
89
|
+
},
|
|
90
|
+
presentation: presentPlan({
|
|
91
|
+
task: request.task,
|
|
92
|
+
plan: request.plan,
|
|
93
|
+
planDigest: request.planDigest,
|
|
94
|
+
revision,
|
|
95
|
+
}),
|
|
96
|
+
revision,
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
}),
|
|
100
|
+
continued: compute({
|
|
101
|
+
run: ({ input, state }) => {
|
|
102
|
+
const request = input;
|
|
103
|
+
return {
|
|
104
|
+
status: "continue",
|
|
105
|
+
plan: request.plan,
|
|
106
|
+
planDigest: request.planDigest,
|
|
107
|
+
decision: acceptedDecision(state.humanDecision),
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
}),
|
|
111
|
+
stopped: compute({
|
|
112
|
+
run: ({ input, state }) => {
|
|
113
|
+
const request = input;
|
|
114
|
+
return {
|
|
115
|
+
status: "stop",
|
|
116
|
+
planDigest: request.planDigest,
|
|
117
|
+
decision: acceptedDecision(state.humanDecision),
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
}),
|
|
121
|
+
replan: compute({
|
|
122
|
+
run: ({ input, outputs, state }) => {
|
|
123
|
+
const request = input;
|
|
124
|
+
const response = gateResponse(outputs.approve);
|
|
125
|
+
const instructions = response.input?.instructions;
|
|
126
|
+
if (typeof instructions !== "string" || instructions.length === 0) {
|
|
127
|
+
throw new Error("replan answer is missing exact instructions");
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
status: "replan",
|
|
131
|
+
plan: request.plan,
|
|
132
|
+
planDigest: request.planDigest,
|
|
133
|
+
instructions,
|
|
134
|
+
decision: acceptedDecision(state.humanDecision),
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
}),
|
|
138
|
+
},
|
|
139
|
+
edges: [
|
|
140
|
+
humanDecisionEdge({
|
|
141
|
+
from: "approve",
|
|
142
|
+
choices: planChoices,
|
|
143
|
+
cases: { continue: "continued", stop: "stopped", replan: "replan" },
|
|
144
|
+
}),
|
|
145
|
+
],
|
|
146
|
+
});
|
|
147
|
+
export default planApprovalWorkflow;
|
|
148
|
+
//# sourceMappingURL=plan-approval.workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-approval.workflow.js","sourceRoot":"","sources":["../../src/builtins/plan-approval.workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { legacyDecisionPresentation, normalizeDecisionPresentation, } from "../workflows/decision-presentation.js";
|
|
2
|
+
export function presentPlan(input) {
|
|
3
|
+
const plan = legacyDecisionPresentation(input.plan);
|
|
4
|
+
const summary = readableSummary(planSummary(input.plan)) ??
|
|
5
|
+
readableSummary(`Review the implementation plan for ${input.task}.`);
|
|
6
|
+
return normalizeDecisionPresentation({
|
|
7
|
+
schema: "pi-workflows.decision-presentation.v1",
|
|
8
|
+
summary,
|
|
9
|
+
blocks: [
|
|
10
|
+
{ kind: "section", title: "Task" },
|
|
11
|
+
{ kind: "paragraph", text: input.task },
|
|
12
|
+
{ kind: "section", title: "Plan" },
|
|
13
|
+
...plan.blocks.filter((block, index) => !(index === 0 && block.kind === "section" && block.title === "Decision details")),
|
|
14
|
+
{ kind: "section", title: "Plan identity" },
|
|
15
|
+
{
|
|
16
|
+
kind: "fields",
|
|
17
|
+
items: [
|
|
18
|
+
{ label: "Revision", value: String(input.revision) },
|
|
19
|
+
{ label: "Digest", value: input.planDigest },
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function readableSummary(value) {
|
|
26
|
+
if (value === undefined)
|
|
27
|
+
return undefined;
|
|
28
|
+
const text = [...value]
|
|
29
|
+
.map((character) => {
|
|
30
|
+
const code = character.codePointAt(0) ?? 0;
|
|
31
|
+
return code <= 31 || code === 127 ? " " : character;
|
|
32
|
+
})
|
|
33
|
+
.join("")
|
|
34
|
+
.replaceAll(/\s+/gu, " ")
|
|
35
|
+
.trim();
|
|
36
|
+
return text.length === 0 ? undefined : text;
|
|
37
|
+
}
|
|
38
|
+
function planSummary(plan) {
|
|
39
|
+
if (plan === null || typeof plan !== "object" || Array.isArray(plan))
|
|
40
|
+
return undefined;
|
|
41
|
+
const summary = plan.summary;
|
|
42
|
+
return typeof summary === "string" && summary.trim().length > 0 ? summary : undefined;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=plan-presentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-presentation.js","sourceRoot":"","sources":["../../src/builtins/plan-presentation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,GAC9B,MAAM,uCAAuC,CAAC;AAG/C,MAAM,UAAU,WAAW,CAAC,KAK3B;IACC,MAAM,IAAI,GAAG,0BAA0B,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,OAAO,GACX,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,eAAe,CAAC,sCAAsC,KAAK,CAAC,IAAI,GAAG,CAAE,CAAC;IACxE,OAAO,6BAA6B,CAAC;QACnC,MAAM,EAAE,uCAAuC;QAC/C,OAAO;QACP,MAAM,EAAE;YACN,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE;YAClC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE;YACvC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE;YAClC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CACnB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACf,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,kBAAkB,CAAC,CACnF;YACD,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE;YAC3C;gBACE,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE;oBACL,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE;oBACpD,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE;iBAC7C;aACF;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,KAAyB;IAChD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC;SACpB,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;QACjB,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3C,OAAO,IAAI,IAAI,EAAE,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC;SACR,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC;SACxB,IAAI,EAAE,CAAC;IACV,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED,SAAS,WAAW,CAAC,IAAa;IAChC,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACvF,MAAM,OAAO,GAAI,IAAgC,CAAC,OAAO,CAAC;IAC1D,OAAO,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACxF,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { HumanDecisionStore } from "../workflows/human-decision.js";
|
|
3
|
+
import type { AcceptedHumanDecision, 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 = AcceptedHumanDecision | 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
|
+
settle(decision: SettledHumanDecision): Promise<void>;
|
|
72
|
+
private settleOnce;
|
|
73
|
+
}
|
|
74
|
+
export declare class TelegramDecisionChannel implements HumanDecisionChannel {
|
|
75
|
+
readonly id: string;
|
|
76
|
+
private readonly profile;
|
|
77
|
+
private readonly store;
|
|
78
|
+
private readonly fetchFn;
|
|
79
|
+
private readonly apiBase;
|
|
80
|
+
private readonly onAnswer;
|
|
81
|
+
private readonly projection;
|
|
82
|
+
private running;
|
|
83
|
+
private pollAbort;
|
|
84
|
+
private pollTask;
|
|
85
|
+
private readonly settlementTasks;
|
|
86
|
+
constructor(options: {
|
|
87
|
+
profileName: string;
|
|
88
|
+
token: string;
|
|
89
|
+
allowedUserIds: string[];
|
|
90
|
+
allowedChatIds: string[];
|
|
91
|
+
store: HumanDecisionStore;
|
|
92
|
+
configDir?: string;
|
|
93
|
+
onAnswer: (answer: HumanDecisionChannelAnswer) => Promise<void>;
|
|
94
|
+
fetchFn?: TelegramFetch;
|
|
95
|
+
apiBase?: string;
|
|
96
|
+
ownerId?: string;
|
|
97
|
+
});
|
|
98
|
+
start(): Promise<void>;
|
|
99
|
+
stop(): Promise<void>;
|
|
100
|
+
deliver(request: HumanDecisionChannelRequest): Promise<HumanDecisionDeliveryResult>;
|
|
101
|
+
settle(decision: SettledHumanDecision): Promise<void>;
|
|
102
|
+
private settleOnce;
|
|
103
|
+
handleUpdate(value: unknown): Promise<void>;
|
|
104
|
+
private registerCallbacks;
|
|
105
|
+
private channelPath;
|
|
106
|
+
private allowed;
|
|
107
|
+
private isStale;
|
|
108
|
+
private poll;
|
|
109
|
+
private call;
|
|
110
|
+
}
|
|
111
|
+
export declare function createTelegramChannels(options: {
|
|
112
|
+
config: DecisionChannelConfig;
|
|
113
|
+
credentials: ResolvedDecisionCredentials;
|
|
114
|
+
store: HumanDecisionStore;
|
|
115
|
+
configDir?: string;
|
|
116
|
+
onAnswer: (answer: HumanDecisionChannelAnswer) => Promise<void>;
|
|
117
|
+
fetchFn?: TelegramFetch;
|
|
118
|
+
apiBase?: string;
|
|
119
|
+
}): Map<string, TelegramDecisionChannel>;
|
|
120
|
+
export declare function verifyTelegramTokenFile(tokenFile: string, fetchFn?: TelegramFetch, apiBase?: string): Promise<void>;
|
|
121
|
+
export declare function writeDecisionChannelProfile(options: {
|
|
122
|
+
configDir?: string;
|
|
123
|
+
audience: string;
|
|
124
|
+
profile: string;
|
|
125
|
+
credential: string;
|
|
126
|
+
tokenFile: string;
|
|
127
|
+
allowedUserIds: string[];
|
|
128
|
+
allowedChatIds: string[];
|
|
129
|
+
}): Promise<void>;
|
|
130
|
+
export declare function renderDecisionText(request: HumanDecisionChannelRequest): string;
|
|
131
|
+
export declare function renderTelegramParts(request: HumanDecisionChannelRequest, textLimit?: number): string[];
|
|
132
|
+
export {};
|