@zaalipro/dsh-workflows 0.1.0-rc.12
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/LICENSE +21 -0
- package/NOTICE.md +224 -0
- package/README.i18n.yaml +4 -0
- package/README.md +111 -0
- package/README.zh.md +111 -0
- package/cordis.patch.yml +10 -0
- package/docs/architecture.i18n.yaml +4 -0
- package/docs/architecture.md +177 -0
- package/docs/architecture.zh.md +177 -0
- package/docs/testing.i18n.yaml +4 -0
- package/docs/testing.md +125 -0
- package/docs/testing.zh.md +125 -0
- package/docs/user-guide.i18n.yaml +4 -0
- package/docs/user-guide.md +351 -0
- package/docs/user-guide.zh.md +351 -0
- package/lib/client-types/WorkflowMemberInspector.d.ts +28 -0
- package/lib/client-types/WorkflowMemberInspector.d.ts.map +1 -0
- package/lib/client-types/WorkflowMemberInspector.js +181 -0
- package/lib/client-types/WorkflowMemberInspector.js.map +1 -0
- package/lib/client-types/WorkflowRunPanel.d.ts +43 -0
- package/lib/client-types/WorkflowRunPanel.d.ts.map +1 -0
- package/lib/client-types/WorkflowRunPanel.js +130 -0
- package/lib/client-types/WorkflowRunPanel.js.map +1 -0
- package/lib/client-types/WorkflowsDashboard.d.ts +49 -0
- package/lib/client-types/WorkflowsDashboard.d.ts.map +1 -0
- package/lib/client-types/WorkflowsDashboard.js +942 -0
- package/lib/client-types/WorkflowsDashboard.js.map +1 -0
- package/lib/client-types/adapter.d.ts +60 -0
- package/lib/client-types/adapter.d.ts.map +1 -0
- package/lib/client-types/adapter.js +117 -0
- package/lib/client-types/adapter.js.map +1 -0
- package/lib/client-types/chat-renderer.d.ts +10 -0
- package/lib/client-types/chat-renderer.d.ts.map +1 -0
- package/lib/client-types/chat-renderer.js +11 -0
- package/lib/client-types/chat-renderer.js.map +1 -0
- package/lib/client-types/contract.d.ts +210 -0
- package/lib/client-types/contract.d.ts.map +1 -0
- package/lib/client-types/contract.js +37 -0
- package/lib/client-types/contract.js.map +1 -0
- package/lib/client-types/controller.d.ts +83 -0
- package/lib/client-types/controller.d.ts.map +1 -0
- package/lib/client-types/controller.js +705 -0
- package/lib/client-types/controller.js.map +1 -0
- package/lib/client-types/index.d.ts +19 -0
- package/lib/client-types/index.d.ts.map +1 -0
- package/lib/client-types/index.js +731 -0
- package/lib/client-types/index.js.map +1 -0
- package/lib/client-types/locales.d.ts +257 -0
- package/lib/client-types/locales.d.ts.map +1 -0
- package/lib/client-types/locales.js +270 -0
- package/lib/client-types/locales.js.map +1 -0
- package/lib/client-types/slot-components.d.ts +38 -0
- package/lib/client-types/slot-components.d.ts.map +1 -0
- package/lib/client-types/slot-components.js +22 -0
- package/lib/client-types/slot-components.js.map +1 -0
- package/lib/client-types/store.d.ts +69 -0
- package/lib/client-types/store.d.ts.map +1 -0
- package/lib/client-types/store.js +135 -0
- package/lib/client-types/store.js.map +1 -0
- package/lib/client-types/workflow-definition.d.ts +52 -0
- package/lib/client-types/workflow-definition.d.ts.map +1 -0
- package/lib/client-types/workflow-definition.js +135 -0
- package/lib/client-types/workflow-definition.js.map +1 -0
- package/lib/client.js +11065 -0
- package/lib/client.js.map +1 -0
- package/lib/compat-engine/index.js +1926 -0
- package/lib/compat-engine/index.js.map +1 -0
- package/lib/compat-engine/worker.cjs +1500 -0
- package/lib/compat-engine/worker.cjs.map +1 -0
- package/lib/typert.host.d.ts +3 -0
- package/lib/typert.host.js +1709 -0
- package/lib/typert.remote-client.d.ts +57 -0
- package/lib/typert.remote-client.js +1662 -0
- package/lib/types/commands/aliases.d.ts +4 -0
- package/lib/types/commands/aliases.d.ts.map +1 -0
- package/lib/types/commands/aliases.js +25 -0
- package/lib/types/commands/aliases.js.map +1 -0
- package/lib/types/commands/index.d.ts +66 -0
- package/lib/types/commands/index.d.ts.map +1 -0
- package/lib/types/commands/index.js +550 -0
- package/lib/types/commands/index.js.map +1 -0
- package/lib/types/commands/parser.d.ts +17 -0
- package/lib/types/commands/parser.d.ts.map +1 -0
- package/lib/types/commands/parser.js +45 -0
- package/lib/types/commands/parser.js.map +1 -0
- package/lib/types/config.d.ts +71 -0
- package/lib/types/config.d.ts.map +1 -0
- package/lib/types/config.js +109 -0
- package/lib/types/config.js.map +1 -0
- package/lib/types/index.d.ts +41 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +483 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/invariant.d.ts +21 -0
- package/lib/types/invariant.d.ts.map +1 -0
- package/lib/types/invariant.js +85 -0
- package/lib/types/invariant.js.map +1 -0
- package/lib/types/registry/definition.d.ts +24 -0
- package/lib/types/registry/definition.d.ts.map +1 -0
- package/lib/types/registry/definition.js +189 -0
- package/lib/types/registry/definition.js.map +1 -0
- package/lib/types/registry/index.d.ts +100 -0
- package/lib/types/registry/index.d.ts.map +1 -0
- package/lib/types/registry/index.js +899 -0
- package/lib/types/registry/index.js.map +1 -0
- package/lib/types/registry/names.d.ts +19 -0
- package/lib/types/registry/names.d.ts.map +1 -0
- package/lib/types/registry/names.js +69 -0
- package/lib/types/registry/names.js.map +1 -0
- package/lib/types/registry/remote.d.ts +15 -0
- package/lib/types/registry/remote.d.ts.map +1 -0
- package/lib/types/registry/remote.js +128 -0
- package/lib/types/registry/remote.js.map +1 -0
- package/lib/types/registry/roots.d.ts +44 -0
- package/lib/types/registry/roots.d.ts.map +1 -0
- package/lib/types/registry/roots.js +118 -0
- package/lib/types/registry/roots.js.map +1 -0
- package/lib/types/registry/types.d.ts +62 -0
- package/lib/types/registry/types.d.ts.map +1 -0
- package/lib/types/registry/types.js +2 -0
- package/lib/types/registry/types.js.map +1 -0
- package/lib/types/registry/watchers.d.ts +70 -0
- package/lib/types/registry/watchers.d.ts.map +1 -0
- package/lib/types/registry/watchers.js +152 -0
- package/lib/types/registry/watchers.js.map +1 -0
- package/lib/types/remote-events.d.ts +42 -0
- package/lib/types/remote-events.d.ts.map +1 -0
- package/lib/types/remote-events.js +21 -0
- package/lib/types/remote-events.js.map +1 -0
- package/lib/types/run-recorder.d.ts +44 -0
- package/lib/types/run-recorder.d.ts.map +1 -0
- package/lib/types/run-recorder.js +356 -0
- package/lib/types/run-recorder.js.map +1 -0
- package/lib/types/supervisor/canned-validate.d.ts +25 -0
- package/lib/types/supervisor/canned-validate.d.ts.map +1 -0
- package/lib/types/supervisor/canned-validate.js +122 -0
- package/lib/types/supervisor/canned-validate.js.map +1 -0
- package/lib/types/supervisor/completion-notice.d.ts +49 -0
- package/lib/types/supervisor/completion-notice.d.ts.map +1 -0
- package/lib/types/supervisor/completion-notice.js +281 -0
- package/lib/types/supervisor/completion-notice.js.map +1 -0
- package/lib/types/supervisor/cursors.d.ts +68 -0
- package/lib/types/supervisor/cursors.d.ts.map +1 -0
- package/lib/types/supervisor/cursors.js +158 -0
- package/lib/types/supervisor/cursors.js.map +1 -0
- package/lib/types/supervisor/engine-compat.d.ts +48 -0
- package/lib/types/supervisor/engine-compat.d.ts.map +1 -0
- package/lib/types/supervisor/engine-compat.js +116 -0
- package/lib/types/supervisor/engine-compat.js.map +1 -0
- package/lib/types/supervisor/index.d.ts +183 -0
- package/lib/types/supervisor/index.d.ts.map +1 -0
- package/lib/types/supervisor/index.js +2040 -0
- package/lib/types/supervisor/index.js.map +1 -0
- package/lib/types/supervisor/parallel-compat.d.ts +36 -0
- package/lib/types/supervisor/parallel-compat.d.ts.map +1 -0
- package/lib/types/supervisor/parallel-compat.js +180 -0
- package/lib/types/supervisor/parallel-compat.js.map +1 -0
- package/lib/types/supervisor/remote.d.ts +25 -0
- package/lib/types/supervisor/remote.d.ts.map +1 -0
- package/lib/types/supervisor/remote.js +478 -0
- package/lib/types/supervisor/remote.js.map +1 -0
- package/lib/types/supervisor/storage/bounded-file.d.ts +41 -0
- package/lib/types/supervisor/storage/bounded-file.d.ts.map +1 -0
- package/lib/types/supervisor/storage/bounded-file.js +186 -0
- package/lib/types/supervisor/storage/bounded-file.js.map +1 -0
- package/lib/types/supervisor/storage/details-codec.d.ts +14 -0
- package/lib/types/supervisor/storage/details-codec.d.ts.map +1 -0
- package/lib/types/supervisor/storage/details-codec.js +359 -0
- package/lib/types/supervisor/storage/details-codec.js.map +1 -0
- package/lib/types/supervisor/storage/index.d.ts +26 -0
- package/lib/types/supervisor/storage/index.d.ts.map +1 -0
- package/lib/types/supervisor/storage/index.js +100 -0
- package/lib/types/supervisor/storage/index.js.map +1 -0
- package/lib/types/supervisor/storage/lease.d.ts +34 -0
- package/lib/types/supervisor/storage/lease.d.ts.map +1 -0
- package/lib/types/supervisor/storage/lease.js +289 -0
- package/lib/types/supervisor/storage/lease.js.map +1 -0
- package/lib/types/supervisor/storage/manifest-codec.d.ts +10 -0
- package/lib/types/supervisor/storage/manifest-codec.d.ts.map +1 -0
- package/lib/types/supervisor/storage/manifest-codec.js +335 -0
- package/lib/types/supervisor/storage/manifest-codec.js.map +1 -0
- package/lib/types/supervisor/storage/manifest-store.d.ts +99 -0
- package/lib/types/supervisor/storage/manifest-store.d.ts.map +1 -0
- package/lib/types/supervisor/storage/manifest-store.js +1606 -0
- package/lib/types/supervisor/storage/manifest-store.js.map +1 -0
- package/lib/types/supervisor/storage/manifest-types.d.ts +269 -0
- package/lib/types/supervisor/storage/manifest-types.d.ts.map +1 -0
- package/lib/types/supervisor/storage/manifest-types.js +2 -0
- package/lib/types/supervisor/storage/manifest-types.js.map +1 -0
- package/lib/types/supervisor/storage/private-root.d.ts +143 -0
- package/lib/types/supervisor/storage/private-root.d.ts.map +1 -0
- package/lib/types/supervisor/storage/private-root.js +860 -0
- package/lib/types/supervisor/storage/private-root.js.map +1 -0
- package/lib/types/supervisor/storage/recovery.d.ts +14 -0
- package/lib/types/supervisor/storage/recovery.d.ts.map +1 -0
- package/lib/types/supervisor/storage/recovery.js +126 -0
- package/lib/types/supervisor/storage/recovery.js.map +1 -0
- package/lib/types/supervisor/storage/run-files.d.ts +67 -0
- package/lib/types/supervisor/storage/run-files.d.ts.map +1 -0
- package/lib/types/supervisor/storage/run-files.js +346 -0
- package/lib/types/supervisor/storage/run-files.js.map +1 -0
- package/lib/types/supervisor/types.d.ts +295 -0
- package/lib/types/supervisor/types.d.ts.map +1 -0
- package/lib/types/supervisor/types.js +3 -0
- package/lib/types/supervisor/types.js.map +1 -0
- package/lib/types/supervisor/value-view.d.ts +19 -0
- package/lib/types/supervisor/value-view.d.ts.map +1 -0
- package/lib/types/supervisor/value-view.js +183 -0
- package/lib/types/supervisor/value-view.js.map +1 -0
- package/lib/types/tool/index.d.ts +86 -0
- package/lib/types/tool/index.d.ts.map +1 -0
- package/lib/types/tool/index.js +810 -0
- package/lib/types/tool/index.js.map +1 -0
- package/lib/types/tool/schema.d.ts +158 -0
- package/lib/types/tool/schema.d.ts.map +1 -0
- package/lib/types/tool/schema.js +137 -0
- package/lib/types/tool/schema.js.map +1 -0
- package/lib/types/types.d.ts +9 -0
- package/lib/types/types.d.ts.map +1 -0
- package/lib/types/types.js +3 -0
- package/lib/types/types.js.map +1 -0
- package/lib/types/user-questions.d.ts +9 -0
- package/lib/types/user-questions.d.ts.map +1 -0
- package/lib/types/user-questions.js +91 -0
- package/lib/types/user-questions.js.map +1 -0
- package/package.json +291 -0
- package/skills/create-workflow/SKILL.md +166 -0
- package/vendor/workflow-engine/LICENSE +21 -0
- package/vendor/workflow-engine/README.md +1 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { boundContextSummary, createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
2
|
+
const encoder = new TextEncoder();
|
|
3
|
+
const FOOTER = 'Open /workflows to inspect the run.';
|
|
4
|
+
const REPORT_REFERENCE = 'The complete report is retained as scratch/report.md.';
|
|
5
|
+
const TRUNCATED = '[notice truncated]';
|
|
6
|
+
function renderThrown(error) {
|
|
7
|
+
try {
|
|
8
|
+
return String(error);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return '[unrenderable thrown value]';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function utf8Prefix(text, maxBytes) {
|
|
15
|
+
let output = '';
|
|
16
|
+
let bytes = 0;
|
|
17
|
+
for (const point of text) {
|
|
18
|
+
const size = encoder.encode(point).byteLength;
|
|
19
|
+
if (bytes + size > maxBytes)
|
|
20
|
+
break;
|
|
21
|
+
output += point;
|
|
22
|
+
bytes += size;
|
|
23
|
+
}
|
|
24
|
+
return output;
|
|
25
|
+
}
|
|
26
|
+
function jsonText(value) {
|
|
27
|
+
try {
|
|
28
|
+
return JSON.stringify(value, null, 2);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return '[result could not be serialized]';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function statusClause(status) {
|
|
35
|
+
switch (status) {
|
|
36
|
+
case 'completed': return 'completed';
|
|
37
|
+
case 'failed': return 'failed';
|
|
38
|
+
case 'cancelled': return 'was stopped';
|
|
39
|
+
case 'interrupted': return 'was interrupted';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function resultText(input) {
|
|
43
|
+
if (input.status !== 'completed')
|
|
44
|
+
return input.error === undefined || input.error === '' ? '' : `\nReason: ${input.error}`;
|
|
45
|
+
const value = input.result;
|
|
46
|
+
if (value?.state !== 'available')
|
|
47
|
+
return '\nResult:\nNo workflow result was retained.';
|
|
48
|
+
return value.content.kind === 'value'
|
|
49
|
+
? `\nResult:\n${jsonText(value.content.value)}`
|
|
50
|
+
: `\nResult preview:\n${value.content.text}`;
|
|
51
|
+
}
|
|
52
|
+
function fitNotice(content, footer, maxBytes) {
|
|
53
|
+
const complete = `${content}\n${footer}`;
|
|
54
|
+
if (encoder.encode(complete).byteLength <= maxBytes)
|
|
55
|
+
return complete;
|
|
56
|
+
const fixed = `\n${TRUNCATED}\n${footer}`;
|
|
57
|
+
const fixedBytes = encoder.encode(fixed).byteLength;
|
|
58
|
+
if (fixedBytes >= maxBytes)
|
|
59
|
+
return utf8Prefix(fixed, maxBytes);
|
|
60
|
+
return `${utf8Prefix(content, maxBytes - fixedBytes)}${fixed}`;
|
|
61
|
+
}
|
|
62
|
+
/** Render one bounded owner-visible notice while preserving the dashboard footer. */
|
|
63
|
+
export function renderWorkflowCompletionNotice(input, maxBytes = 16_384, report = input.report) {
|
|
64
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes < 1) {
|
|
65
|
+
throw new TypeError('workflow completion notice maxBytes must be a positive safe integer');
|
|
66
|
+
}
|
|
67
|
+
const heading = `workflow "${input.displayName}" ${statusClause(input.status)}.`;
|
|
68
|
+
const detail = report === undefined ? resultText(input) : `\nScratch report:\n${report}`;
|
|
69
|
+
const footer = report === undefined ? FOOTER : `${REPORT_REFERENCE}\n${FOOTER}`;
|
|
70
|
+
return fitNotice(`${heading}${detail}`, footer, maxBytes);
|
|
71
|
+
}
|
|
72
|
+
function isStore(value) {
|
|
73
|
+
return typeof value === 'object' && value !== null
|
|
74
|
+
&& typeof value.finalizeCompletionNotice === 'function';
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* At-most-once completion outbox. Durable `claimed` state authorizes one
|
|
78
|
+
* enqueue; this class finalizes that exact claim as delivered or abandoned.
|
|
79
|
+
*/
|
|
80
|
+
export class WorkflowCompletionNotifier {
|
|
81
|
+
ctx;
|
|
82
|
+
store;
|
|
83
|
+
options;
|
|
84
|
+
reservations = new Map();
|
|
85
|
+
attempted = new Set();
|
|
86
|
+
owners = new Map();
|
|
87
|
+
disposed = false;
|
|
88
|
+
disposal;
|
|
89
|
+
constructor(ctx, storeOrOptions, maybeOptions = {}) {
|
|
90
|
+
this.ctx = ctx;
|
|
91
|
+
this.store = isStore(storeOrOptions) ? storeOrOptions : undefined;
|
|
92
|
+
const supplied = isStore(storeOrOptions) ? maybeOptions : (storeOrOptions ?? {});
|
|
93
|
+
this.options = {
|
|
94
|
+
maxBytes: supplied.maxBytes ?? 16_384,
|
|
95
|
+
maxItems: supplied.maxItems ?? 20,
|
|
96
|
+
maxCohortBytes: supplied.maxCohortBytes ?? 262_144,
|
|
97
|
+
};
|
|
98
|
+
for (const [name, value] of Object.entries(this.options)) {
|
|
99
|
+
if (!Number.isSafeInteger(value) || value < 1)
|
|
100
|
+
throw new TypeError(`workflow completion ${name} must be a positive safe integer`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
reserve(key, parent) {
|
|
104
|
+
if (this.disposed)
|
|
105
|
+
return;
|
|
106
|
+
const existing = this.reservations.get(key);
|
|
107
|
+
if (existing !== undefined && existing.parent !== parent)
|
|
108
|
+
throw new Error('workflow completion token changed owner');
|
|
109
|
+
if (existing === undefined)
|
|
110
|
+
this.reservations.set(key, { parent });
|
|
111
|
+
}
|
|
112
|
+
async notify(input) {
|
|
113
|
+
const key = input.runId;
|
|
114
|
+
if (this.attempted.has(key))
|
|
115
|
+
return false;
|
|
116
|
+
const parent = input.parent ?? this.reservations.get(key)?.parent;
|
|
117
|
+
if (parent === undefined)
|
|
118
|
+
return false;
|
|
119
|
+
this.reserve(key, parent);
|
|
120
|
+
this.attempted.add(key);
|
|
121
|
+
const noticeBytes = Math.min(this.options.maxBytes, this.options.maxCohortBytes);
|
|
122
|
+
// Supervisor-owned descriptor reads populate `report` before this queue.
|
|
123
|
+
// Deliberately do not traverse an ambient absolute path here; legacy
|
|
124
|
+
// callers that provide only scratchDir simply fall back to inline result.
|
|
125
|
+
const report = input.report;
|
|
126
|
+
const text = renderWorkflowCompletionNotice(input, noticeBytes, report);
|
|
127
|
+
const bytes = encoder.encode(text).byteLength;
|
|
128
|
+
if (this.disposed) {
|
|
129
|
+
await this.finalizeDirect({ key, input: { ...input, parent }, text, bytes, resolve: () => undefined }, 'abandoned', 'teardown');
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return await new Promise(resolve => {
|
|
133
|
+
const owner = this.owners.get(parent) ?? { pending: [], pendingBytes: 0, scheduled: false };
|
|
134
|
+
this.owners.set(parent, owner);
|
|
135
|
+
owner.pending.push({ key, input: { ...input, parent }, text, bytes, resolve });
|
|
136
|
+
owner.pendingBytes += bytes;
|
|
137
|
+
this.schedule(parent, owner);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
schedule(parent, owner) {
|
|
141
|
+
if (owner.scheduled || owner.processing !== undefined)
|
|
142
|
+
return;
|
|
143
|
+
owner.scheduled = true;
|
|
144
|
+
queueMicrotask(() => {
|
|
145
|
+
owner.scheduled = false;
|
|
146
|
+
if (owner.processing !== undefined)
|
|
147
|
+
return;
|
|
148
|
+
owner.processing = this.drainOwner(parent, owner).finally(() => {
|
|
149
|
+
owner.processing = undefined;
|
|
150
|
+
if (owner.pending.length > 0 && !this.disposed)
|
|
151
|
+
this.schedule(parent, owner);
|
|
152
|
+
else if (owner.pending.length === 0)
|
|
153
|
+
this.owners.delete(parent);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
takeCohort(owner) {
|
|
158
|
+
const cohort = [];
|
|
159
|
+
let bytes = 0;
|
|
160
|
+
while (owner.pending.length > 0 && cohort.length < this.options.maxItems) {
|
|
161
|
+
const candidate = owner.pending[0];
|
|
162
|
+
const separatorBytes = cohort.length === 0 ? 0 : encoder.encode('\n\n').byteLength;
|
|
163
|
+
if (cohort.length > 0 && bytes + separatorBytes + candidate.bytes > this.options.maxCohortBytes)
|
|
164
|
+
break;
|
|
165
|
+
owner.pending.shift();
|
|
166
|
+
owner.pendingBytes -= candidate.bytes;
|
|
167
|
+
cohort.push(candidate);
|
|
168
|
+
bytes += separatorBytes + candidate.bytes;
|
|
169
|
+
if (bytes >= this.options.maxCohortBytes)
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
return cohort;
|
|
173
|
+
}
|
|
174
|
+
async drainOwner(parent, owner) {
|
|
175
|
+
while (owner.pending.length > 0) {
|
|
176
|
+
const cohort = this.takeCohort(owner);
|
|
177
|
+
if (this.disposed) {
|
|
178
|
+
for (const item of cohort) {
|
|
179
|
+
await this.finalize(item, 'abandoned', 'teardown');
|
|
180
|
+
item.resolve(true);
|
|
181
|
+
}
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const text = cohort.map(item => item.text).join('\n\n');
|
|
185
|
+
let delivered = false;
|
|
186
|
+
let failure;
|
|
187
|
+
try {
|
|
188
|
+
const first = cohort[0];
|
|
189
|
+
const message = createUserMessage({
|
|
190
|
+
content: [{ type: 'text', text }],
|
|
191
|
+
source: {
|
|
192
|
+
kind: 'plugin', plugin: 'workflow-supervisor', form: 'notice',
|
|
193
|
+
summary: boundContextSummary(`workflow ${first.input.displayName} ${statusClause(first.input.status)}`),
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
// A completion is a durable conversation notification, not a new
|
|
197
|
+
// prompt. Agent.followup() wakes the model and Agent.inject() stays
|
|
198
|
+
// invisible while the Agent is idle. Session.append() is the public
|
|
199
|
+
// stock-Harness seam that makes plugin context durable and visible
|
|
200
|
+
// immediately without touching either inbox lane.
|
|
201
|
+
const append = parent?.session?.append;
|
|
202
|
+
if (typeof append !== 'function')
|
|
203
|
+
throw new Error('workflow owner session is unavailable');
|
|
204
|
+
await Promise.resolve(append.call(parent.session, 'user/message', message, { surfaceOp: 'append' }));
|
|
205
|
+
delivered = true;
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
failure = error;
|
|
209
|
+
this.ctx?.logger?.warn?.(`workflow-supervisor: completion notice delivery failed: ${renderThrown(error)}`);
|
|
210
|
+
}
|
|
211
|
+
for (const item of cohort) {
|
|
212
|
+
// The version-2 manifest calls its non-waking delivery lane `inject`.
|
|
213
|
+
// Keep that durable vocabulary compatible while delivering through
|
|
214
|
+
// the stronger immediately-visible Session append seam.
|
|
215
|
+
await this.finalize(item, delivered ? 'delivered' : 'abandoned', delivered ? 'inject' : 'enqueue-failed', failure);
|
|
216
|
+
item.resolve(true);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async finalizeDirect(item, state, reason) {
|
|
221
|
+
await this.finalize(item, state, reason);
|
|
222
|
+
}
|
|
223
|
+
async finalize(item, state, laneOrReason, error) {
|
|
224
|
+
const head = item.input.head;
|
|
225
|
+
const notice = head?.completionNotice;
|
|
226
|
+
if (this.store === undefined || head === undefined || notice?.state !== 'claimed' || item.input.sessionId === undefined)
|
|
227
|
+
return;
|
|
228
|
+
const base = {
|
|
229
|
+
claimId: notice.claimId,
|
|
230
|
+
processEpoch: notice.processEpoch,
|
|
231
|
+
claimedAt: notice.claimedAt,
|
|
232
|
+
finalizedAt: Math.max(Date.now(), notice.claimedAt),
|
|
233
|
+
};
|
|
234
|
+
const finalization = state === 'delivered'
|
|
235
|
+
? { state, ...base, lane: laneOrReason }
|
|
236
|
+
: {
|
|
237
|
+
state, ...base, reason: laneOrReason,
|
|
238
|
+
...(error === undefined ? {} : { error: utf8Prefix(renderThrown(error), 65_536) }),
|
|
239
|
+
};
|
|
240
|
+
try {
|
|
241
|
+
await this.store.finalizeCompletionNotice(item.input.sessionId, item.input.runId, head.revision, finalization);
|
|
242
|
+
}
|
|
243
|
+
catch (failure) {
|
|
244
|
+
this.ctx?.logger?.warn?.(`workflow-supervisor: completion notice finalization failed: ${renderThrown(failure)}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
async whenOwnerQuiescent(agent, signal) {
|
|
248
|
+
for (;;) {
|
|
249
|
+
signal?.throwIfAborted();
|
|
250
|
+
const owner = this.owners.get(agent);
|
|
251
|
+
if (owner === undefined)
|
|
252
|
+
return;
|
|
253
|
+
if (owner.processing !== undefined)
|
|
254
|
+
await owner.processing;
|
|
255
|
+
else
|
|
256
|
+
await new Promise(resolve => queueMicrotask(resolve));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
async dispose() {
|
|
260
|
+
if (this.disposal !== undefined)
|
|
261
|
+
return this.disposal;
|
|
262
|
+
this.disposed = true;
|
|
263
|
+
this.disposal = (async () => {
|
|
264
|
+
// Once disposal starts no new owner turn may be opened. Every queued
|
|
265
|
+
// claim is nevertheless finalized so a terminal `claimed` row cannot
|
|
266
|
+
// remain pinned forever.
|
|
267
|
+
const pending = [];
|
|
268
|
+
for (const owner of this.owners.values())
|
|
269
|
+
pending.push(...owner.pending.splice(0));
|
|
270
|
+
await Promise.allSettled(pending.map(async (item) => {
|
|
271
|
+
await this.finalize(item, 'abandoned', 'teardown');
|
|
272
|
+
item.resolve(true);
|
|
273
|
+
}));
|
|
274
|
+
await Promise.allSettled([...this.owners.values()].map(owner => owner.processing).filter((value) => value !== undefined));
|
|
275
|
+
this.owners.clear();
|
|
276
|
+
this.reservations.clear();
|
|
277
|
+
})();
|
|
278
|
+
return this.disposal;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=completion-notice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion-notice.js","sourceRoot":"","sources":["../../../src/supervisor/completion-notice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { WorkflowRunCursor, WorkflowRunFeedEpoch } from './types.js';
|
|
2
|
+
/** Collections which may be paged through the authorized workflow Remote. */
|
|
3
|
+
export type WorkflowCursorKind = 'definitions' | 'runs' | 'members' | 'logs' | 'artifacts' | 'artifact';
|
|
4
|
+
/** Canonical authenticated cursor payload. No protected data belongs here. */
|
|
5
|
+
export interface WorkflowCursorPayload {
|
|
6
|
+
readonly version: 1;
|
|
7
|
+
readonly kind: WorkflowCursorKind;
|
|
8
|
+
/** Exact owning Session identity. */
|
|
9
|
+
readonly sessionId: string;
|
|
10
|
+
/** Selected run/member owner; empty for Session-wide collections. */
|
|
11
|
+
readonly entityId: string;
|
|
12
|
+
/** Process epoch which issued the baseline. */
|
|
13
|
+
readonly processEpoch: string;
|
|
14
|
+
/** Collection revision at which this offset was produced. */
|
|
15
|
+
readonly revision: number;
|
|
16
|
+
/** Row offset, or UTF-8 byte offset for `artifact`. */
|
|
17
|
+
readonly offset: number;
|
|
18
|
+
}
|
|
19
|
+
export interface WorkflowCursorExpectation {
|
|
20
|
+
readonly version?: 1;
|
|
21
|
+
readonly kind: WorkflowCursorKind;
|
|
22
|
+
readonly sessionId: string;
|
|
23
|
+
readonly entityId: string;
|
|
24
|
+
readonly processEpoch: string;
|
|
25
|
+
readonly revision: number;
|
|
26
|
+
/** Inclusive upper bound for the next offset. */
|
|
27
|
+
readonly total: number;
|
|
28
|
+
}
|
|
29
|
+
export type WorkflowCursorDecodeResult = {
|
|
30
|
+
readonly ok: true;
|
|
31
|
+
readonly value: WorkflowCursorPayload;
|
|
32
|
+
} | {
|
|
33
|
+
readonly ok: false;
|
|
34
|
+
readonly reason: 'invalid' | 'stale';
|
|
35
|
+
};
|
|
36
|
+
/** Compatibility error used by the early package Remote adapter. */
|
|
37
|
+
export declare class WorkflowCursorError extends Error {
|
|
38
|
+
readonly code: 'invalid-cursor' | 'stale-cursor';
|
|
39
|
+
constructor(message: string, code: 'invalid-cursor' | 'stale-cursor');
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Encode an authenticated cursor. The two-argument form is the public API;
|
|
43
|
+
* the one-argument form remains for early package consumers and uses the
|
|
44
|
+
* process-local secret.
|
|
45
|
+
*/
|
|
46
|
+
export declare function encodeWorkflowCursor(secret: Uint8Array, payload: WorkflowCursorPayload): WorkflowRunCursor;
|
|
47
|
+
export declare function encodeWorkflowCursor(payload: WorkflowCursorPayload | LegacyCursorPayload): WorkflowRunCursor;
|
|
48
|
+
/** Decode a cursor with the authenticated three-argument API. */
|
|
49
|
+
export declare function decodeWorkflowCursor(secret: Uint8Array, cursor: string, expected: WorkflowCursorExpectation): WorkflowCursorDecodeResult;
|
|
50
|
+
/** Compatibility decoder used by the original Remote adapter. */
|
|
51
|
+
export declare function decodeWorkflowCursor(cursor: WorkflowRunCursor, expected: LegacyCursorExpectation): WorkflowCursorPayload;
|
|
52
|
+
interface LegacyCursorPayload {
|
|
53
|
+
readonly owner?: string;
|
|
54
|
+
readonly collection?: string;
|
|
55
|
+
readonly epoch?: string;
|
|
56
|
+
readonly revision: number;
|
|
57
|
+
readonly offset: number;
|
|
58
|
+
readonly kind?: WorkflowCursorKind;
|
|
59
|
+
readonly sessionId?: string;
|
|
60
|
+
readonly entityId?: string;
|
|
61
|
+
readonly collectionOwner?: string;
|
|
62
|
+
readonly processEpoch?: string;
|
|
63
|
+
}
|
|
64
|
+
interface LegacyCursorExpectation extends LegacyCursorPayload {
|
|
65
|
+
readonly total?: number;
|
|
66
|
+
}
|
|
67
|
+
export type { WorkflowRunCursor, WorkflowRunFeedEpoch };
|
|
68
|
+
//# sourceMappingURL=cursors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursors.d.ts","sourceRoot":"","sources":["../../../src/supervisor/cursors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
/** Compatibility error used by the early package Remote adapter. */
|
|
3
|
+
export class WorkflowCursorError extends Error {
|
|
4
|
+
code;
|
|
5
|
+
constructor(message, code) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'WorkflowCursorError';
|
|
8
|
+
this.code = code;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const PROCESS_SECRET = randomBytes(32);
|
|
12
|
+
const MAX_CURSOR_CHARS = 4096;
|
|
13
|
+
const BASE64URL = /^[A-Za-z0-9_-]+$/u;
|
|
14
|
+
const KINDS = new Set(['definitions', 'runs', 'members', 'logs', 'artifacts', 'artifact']);
|
|
15
|
+
const encoder = new TextEncoder();
|
|
16
|
+
function secretBytes(value) {
|
|
17
|
+
if (!(value instanceof Uint8Array) || value.byteLength !== 32) {
|
|
18
|
+
throw new TypeError('workflow cursor secret must be exactly 32 bytes');
|
|
19
|
+
}
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
function canonicalJson(value) {
|
|
23
|
+
// Deliberately spell the key order. JSON object insertion order is stable,
|
|
24
|
+
// but making it explicit prevents an innocuous refactor from invalidating
|
|
25
|
+
// every cursor in a running Client.
|
|
26
|
+
return JSON.stringify({
|
|
27
|
+
version: value.version,
|
|
28
|
+
kind: value.kind,
|
|
29
|
+
sessionId: value.sessionId,
|
|
30
|
+
entityId: value.entityId,
|
|
31
|
+
processEpoch: value.processEpoch,
|
|
32
|
+
revision: value.revision,
|
|
33
|
+
offset: value.offset,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function b64(value) {
|
|
37
|
+
return Buffer.from(value).toString('base64url');
|
|
38
|
+
}
|
|
39
|
+
function decodeB64(value) {
|
|
40
|
+
if (!BASE64URL.test(value))
|
|
41
|
+
return undefined;
|
|
42
|
+
try {
|
|
43
|
+
const bytes = Buffer.from(value, 'base64url');
|
|
44
|
+
// Node accepts non-canonical spellings. Round-tripping closes that gap.
|
|
45
|
+
if (bytes.length === 0 || b64(bytes) !== value)
|
|
46
|
+
return undefined;
|
|
47
|
+
return new Uint8Array(bytes);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function validText(value) {
|
|
54
|
+
return typeof value === 'string' && value.length > 0 && encoder.encode(value).byteLength <= 1024;
|
|
55
|
+
}
|
|
56
|
+
function validPayload(value) {
|
|
57
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
58
|
+
return false;
|
|
59
|
+
const object = value;
|
|
60
|
+
const keys = Object.keys(object);
|
|
61
|
+
if (keys.length !== 7 || !keys.every(key => ['version', 'kind', 'sessionId', 'entityId', 'processEpoch', 'revision', 'offset'].includes(key)))
|
|
62
|
+
return false;
|
|
63
|
+
return object.version === 1
|
|
64
|
+
&& typeof object.kind === 'string' && KINDS.has(object.kind)
|
|
65
|
+
&& validText(object.sessionId)
|
|
66
|
+
&& typeof object.entityId === 'string' && encoder.encode(object.entityId).byteLength <= 1024
|
|
67
|
+
&& validText(object.processEpoch)
|
|
68
|
+
&& Number.isSafeInteger(object.revision) && Number(object.revision) >= 0
|
|
69
|
+
&& Number.isSafeInteger(object.offset) && Number(object.offset) >= 0;
|
|
70
|
+
}
|
|
71
|
+
function validExpectation(expected) {
|
|
72
|
+
return (expected.version === undefined || expected.version === 1)
|
|
73
|
+
&& KINDS.has(expected.kind)
|
|
74
|
+
&& validText(expected.sessionId)
|
|
75
|
+
&& typeof expected.entityId === 'string'
|
|
76
|
+
&& validText(expected.processEpoch)
|
|
77
|
+
&& Number.isSafeInteger(expected.revision) && expected.revision >= 0
|
|
78
|
+
&& Number.isSafeInteger(expected.total) && expected.total >= 0;
|
|
79
|
+
}
|
|
80
|
+
function encodeWithSecret(secret, payload) {
|
|
81
|
+
secretBytes(secret);
|
|
82
|
+
if (!validPayload(payload))
|
|
83
|
+
throw new TypeError('workflow cursor payload is invalid');
|
|
84
|
+
const body = b64(encoder.encode(canonicalJson(payload)));
|
|
85
|
+
const mac = b64(createHmac('sha256', secret).update(body, 'utf8').digest());
|
|
86
|
+
return `${body}.${mac}`;
|
|
87
|
+
}
|
|
88
|
+
export function encodeWorkflowCursor(secretOrPayload, maybePayload) {
|
|
89
|
+
if (maybePayload !== undefined)
|
|
90
|
+
return encodeWithSecret(secretBytes(secretOrPayload), maybePayload);
|
|
91
|
+
const legacy = secretOrPayload;
|
|
92
|
+
const payload = {
|
|
93
|
+
version: 1,
|
|
94
|
+
kind: legacy.kind ?? legacy.collection,
|
|
95
|
+
sessionId: legacy.sessionId ?? legacy.owner ?? '',
|
|
96
|
+
entityId: legacy.entityId ?? legacy.collectionOwner ?? '',
|
|
97
|
+
processEpoch: legacy.processEpoch ?? legacy.epoch ?? '',
|
|
98
|
+
revision: legacy.revision,
|
|
99
|
+
offset: legacy.offset,
|
|
100
|
+
};
|
|
101
|
+
return encodeWithSecret(PROCESS_SECRET, payload);
|
|
102
|
+
}
|
|
103
|
+
function decodeWithSecret(secret, cursor, expected) {
|
|
104
|
+
try {
|
|
105
|
+
secretBytes(secret);
|
|
106
|
+
if (typeof cursor !== 'string' || cursor.length === 0 || cursor.length > MAX_CURSOR_CHARS)
|
|
107
|
+
return { ok: false, reason: 'invalid' };
|
|
108
|
+
if (!validExpectation(expected))
|
|
109
|
+
return { ok: false, reason: 'invalid' };
|
|
110
|
+
const separator = cursor.indexOf('.');
|
|
111
|
+
if (separator <= 0 || separator !== cursor.lastIndexOf('.'))
|
|
112
|
+
return { ok: false, reason: 'invalid' };
|
|
113
|
+
const bodyText = cursor.slice(0, separator);
|
|
114
|
+
const macText = cursor.slice(separator + 1);
|
|
115
|
+
const body = decodeB64(bodyText);
|
|
116
|
+
const suppliedMac = decodeB64(macText);
|
|
117
|
+
if (!body || !suppliedMac || suppliedMac.byteLength !== 32)
|
|
118
|
+
return { ok: false, reason: 'invalid' };
|
|
119
|
+
const actualMac = createHmac('sha256', secret).update(bodyText, 'utf8').digest();
|
|
120
|
+
if (!timingSafeEqual(actualMac, Buffer.from(suppliedMac)))
|
|
121
|
+
return { ok: false, reason: 'invalid' };
|
|
122
|
+
const decodedText = new TextDecoder('utf-8', { fatal: true }).decode(body);
|
|
123
|
+
const parsed = JSON.parse(decodedText);
|
|
124
|
+
if (!validPayload(parsed) || JSON.stringify(parsed) !== decodedText)
|
|
125
|
+
return { ok: false, reason: 'invalid' };
|
|
126
|
+
if (parsed.kind !== expected.kind || parsed.sessionId !== expected.sessionId || parsed.entityId !== expected.entityId || parsed.processEpoch !== expected.processEpoch)
|
|
127
|
+
return { ok: false, reason: 'invalid' };
|
|
128
|
+
if (parsed.offset > expected.total)
|
|
129
|
+
return { ok: false, reason: 'invalid' };
|
|
130
|
+
if (parsed.revision !== expected.revision)
|
|
131
|
+
return { ok: false, reason: 'stale' };
|
|
132
|
+
return { ok: true, value: parsed };
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return { ok: false, reason: 'invalid' };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
export function decodeWorkflowCursor(secretOrCursor, cursorOrExpected, maybeExpected) {
|
|
139
|
+
if (maybeExpected !== undefined)
|
|
140
|
+
return decodeWithSecret(secretBytes(secretOrCursor), cursorOrExpected, maybeExpected);
|
|
141
|
+
const expected = cursorOrExpected;
|
|
142
|
+
const result = decodeWithSecret(PROCESS_SECRET, secretOrCursor, {
|
|
143
|
+
version: 1,
|
|
144
|
+
kind: (expected.kind ?? expected.collection),
|
|
145
|
+
sessionId: expected.sessionId ?? expected.owner ?? '',
|
|
146
|
+
entityId: expected.entityId ?? expected.collectionOwner ?? '',
|
|
147
|
+
processEpoch: expected.processEpoch ?? expected.epoch ?? '',
|
|
148
|
+
revision: expected.revision,
|
|
149
|
+
total: expected.total ?? Number.MAX_SAFE_INTEGER,
|
|
150
|
+
});
|
|
151
|
+
if (!result.ok) {
|
|
152
|
+
if (result.reason === 'stale')
|
|
153
|
+
throw new WorkflowCursorError('workflow page cursor is stale; refresh the collection', 'stale-cursor');
|
|
154
|
+
throw new WorkflowCursorError('workflow page cursor is invalid or belongs to another collection', 'invalid-cursor');
|
|
155
|
+
}
|
|
156
|
+
return result.value;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=cursors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursors.js","sourceRoot":"","sources":["../../../src/supervisor/cursors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Settlement payload the supervisor already understands. */
|
|
2
|
+
export interface EngineResult {
|
|
3
|
+
readonly value: unknown;
|
|
4
|
+
readonly stopReason: 'completed' | 'cancelled' | 'error';
|
|
5
|
+
readonly error?: string;
|
|
6
|
+
readonly errorCode?: string;
|
|
7
|
+
readonly agentsStarted: number;
|
|
8
|
+
}
|
|
9
|
+
/** Replay journal captured after dispose. Unavailable on partial stock workers. */
|
|
10
|
+
export interface WorkflowCheckpoint {
|
|
11
|
+
readonly journal: readonly {
|
|
12
|
+
readonly callId: readonly [number, ...number[]];
|
|
13
|
+
readonly fingerprint: string;
|
|
14
|
+
readonly kind: string;
|
|
15
|
+
readonly [key: string]: unknown;
|
|
16
|
+
}[];
|
|
17
|
+
readonly agentSpend: number;
|
|
18
|
+
readonly agentSeq: number;
|
|
19
|
+
}
|
|
20
|
+
/** Supervisor-facing live attempt. The stock worker handle implements a subset. */
|
|
21
|
+
export interface EngineHandle {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly result: Promise<EngineResult>;
|
|
24
|
+
/**
|
|
25
|
+
* False only for a compatibility wrapper which cannot provide the replay
|
|
26
|
+
* authority required by Pause/Resume. Complete handles predate this hint, so
|
|
27
|
+
* an absent value means supported.
|
|
28
|
+
*/
|
|
29
|
+
readonly supportsReplay?: boolean;
|
|
30
|
+
cancel(reason?: string): void;
|
|
31
|
+
resume(): void;
|
|
32
|
+
release(): void;
|
|
33
|
+
checkpoint(): WorkflowCheckpoint | undefined;
|
|
34
|
+
dispose(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
/** True when the engine exposes the complete deferred-start and replay face. */
|
|
37
|
+
export declare function isCompleteEngineHandle(raw: unknown): raw is EngineHandle;
|
|
38
|
+
/**
|
|
39
|
+
* Stock `@deepseek-ai/dsh-workflow` `WorkflowRun` may expose only
|
|
40
|
+
* `id`/`result`/`cancel`/`dispose`. Wrap that thin face so the supervisor can
|
|
41
|
+
* admit a run instead of failing with "invalid run handle".
|
|
42
|
+
*/
|
|
43
|
+
export declare function adaptEngineHandle(raw: unknown): EngineHandle | undefined;
|
|
44
|
+
/** Whether Pause/Resume can be offered without replaying committed effects. */
|
|
45
|
+
export declare function supportsEngineReplay(handle: EngineHandle): boolean;
|
|
46
|
+
/** Best-effort cancel/dispose of a handle the supervisor will not keep. */
|
|
47
|
+
export declare function rejectPartialEngineHandle(raw: unknown): void;
|
|
48
|
+
//# sourceMappingURL=engine-compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-compat.d.ts","sourceRoot":"","sources":["../../../src/supervisor/engine-compat.ts"],"names":[],"mappings":"AAEA,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,WAAW,GAAG,WAAW,GAAG,OAAO,CAAA;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B;AAED,mFAAmF;AACnF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,SAAS;QACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAA;QAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;QAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;QACrB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAChC,EAAE,CAAA;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,mFAAmF;AACnF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IACtC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAA;IACjC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,MAAM,IAAI,IAAI,CAAA;IACd,OAAO,IAAI,IAAI,CAAA;IACf,UAAU,IAAI,kBAAkB,GAAG,SAAS,CAAA;IAC5C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACzB;AAUD,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,YAAY,CASxE;AAgBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAgDxE;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAElE;AAED,2EAA2E;AAC3E,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAa5D"}
|