dsh-wsr-execution 0.2.2 → 0.2.3
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 +1 -1
- package/lib/client.js +39 -10
- package/package.json +4 -4
- package/src/action-presentation/model.js +17 -6
- package/src/action-presentation/view.js +42 -11
- package/src/intake/command.js +7 -1
- package/src/intake/plugin.js +10 -6
package/README.md
CHANGED
|
@@ -21,6 +21,6 @@ and exact MIT provenance are documented under
|
|
|
21
21
|
`src/client/delivery-inventory/UPSTREAM.md`.
|
|
22
22
|
|
|
23
23
|
The compatible `wsr-execution@^0.2.0` peer comes from the immutable GitHub
|
|
24
|
-
`0.2.
|
|
24
|
+
`0.2.2` release asset recorded in `package.json`, not ambient npm resolution. Install that
|
|
25
25
|
asset as an explicit DSH profile root alongside this adapter; its required
|
|
26
26
|
SHA-256 is `0b889b707b5fdc84d934e6c807ce101b4edaa356409253a1f48d6ffca7f53420`.
|
package/lib/client.js
CHANGED
|
@@ -2517,7 +2517,7 @@ var KINDS = /* @__PURE__ */ new Set([
|
|
|
2517
2517
|
"terminal-result",
|
|
2518
2518
|
"error"
|
|
2519
2519
|
]);
|
|
2520
|
-
var ACTION_STATES = /* @__PURE__ */ new Set(["running", "completed", "failed", "cancelled", "waiting", "recovering"]);
|
|
2520
|
+
var ACTION_STATES = /* @__PURE__ */ new Set(["running", "completed", "failed", "cancelled", "waiting", "recovering", "uncertain", "unresolved"]);
|
|
2521
2521
|
var TERMINAL_OUTCOMES = /* @__PURE__ */ new Set(["SUCCEEDED", "FAILED", "CANCELLED"]);
|
|
2522
2522
|
var DELIVERY_STATES = /* @__PURE__ */ new Set([
|
|
2523
2523
|
"BOUND",
|
|
@@ -2573,7 +2573,9 @@ function hasValidTypedData(value) {
|
|
|
2573
2573
|
return typeof value.data.outcome === "string" && TERMINAL_OUTCOMES.has(value.data.outcome) && outputValid;
|
|
2574
2574
|
}
|
|
2575
2575
|
if (value.kind === "delivery-running" || value.kind === "delivery-status") {
|
|
2576
|
-
|
|
2576
|
+
const diagnostic2 = value.data.diagnostic;
|
|
2577
|
+
const diagnosticValid = diagnostic2 === void 0 || diagnostic2 !== null && typeof diagnostic2 === "object" && !Array.isArray(diagnostic2) && Object.keys(diagnostic2).sort().join(",") === "causeCode,stage" && typeof diagnostic2.stage === "string" && /^[A-Z][A-Z0-9_]{0,63}$/u.test(diagnostic2.stage) && typeof diagnostic2.causeCode === "string" && /^[A-Z][A-Z0-9_]{0,127}$/u.test(diagnostic2.causeCode);
|
|
2578
|
+
return diagnosticValid && (value.data.state === void 0 || typeof value.data.state === "string" && DELIVERY_STATES.has(value.data.state));
|
|
2577
2579
|
}
|
|
2578
2580
|
return true;
|
|
2579
2581
|
}
|
|
@@ -2612,8 +2614,10 @@ function normalizedLifecycle(value, fallback) {
|
|
|
2612
2614
|
if (["cancelled", "canceled"].includes(normalized)) return "cancelled";
|
|
2613
2615
|
if (["waiting", "awaiting-input"].includes(normalized)) return "waiting";
|
|
2614
2616
|
if (["start-failed"].includes(normalized)) return "failed";
|
|
2615
|
-
if (
|
|
2616
|
-
if (
|
|
2617
|
+
if (normalized === "start-uncertain") return "uncertain";
|
|
2618
|
+
if (normalized === "result-unresolved") return "unresolved";
|
|
2619
|
+
if (["recovering", "recovery", "terminal-handling"].includes(normalized)) return "recovering";
|
|
2620
|
+
if (["running", "accepted", "running-correlated", "bound"].includes(normalized)) return "running";
|
|
2617
2621
|
return fallback;
|
|
2618
2622
|
}
|
|
2619
2623
|
var STATE_LABELS = Object.freeze({
|
|
@@ -2622,7 +2626,9 @@ var STATE_LABELS = Object.freeze({
|
|
|
2622
2626
|
failed: "Failed",
|
|
2623
2627
|
cancelled: "Cancelled",
|
|
2624
2628
|
waiting: "Waiting for input",
|
|
2625
|
-
recovering: "Recovering"
|
|
2629
|
+
recovering: "Recovering",
|
|
2630
|
+
uncertain: "Start uncertain",
|
|
2631
|
+
unresolved: "Result unresolved"
|
|
2626
2632
|
});
|
|
2627
2633
|
function model(input) {
|
|
2628
2634
|
return deepFreeze(input);
|
|
@@ -2691,13 +2697,14 @@ function projectExecutionPresentation(event) {
|
|
|
2691
2697
|
}
|
|
2692
2698
|
const state = event.kind === "delivery-running" ? normalizedLifecycle(data.state, "running") : normalizedLifecycle(data.state, event.kind === "command-accepted" ? "running" : "running");
|
|
2693
2699
|
const deliveryId = typeof data.deliveryId === "string" ? data.deliveryId : void 0;
|
|
2700
|
+
const diagnostic2 = data.diagnostic;
|
|
2694
2701
|
return model({
|
|
2695
2702
|
correlation,
|
|
2696
2703
|
layer: "progress",
|
|
2697
2704
|
state,
|
|
2698
2705
|
title: "Workflow delivery",
|
|
2699
2706
|
summary: `${STATE_LABELS[state]}${deliveryId === void 0 ? "" : ` \xB7 ${deliveryId}`}`,
|
|
2700
|
-
body: void 0
|
|
2707
|
+
body: diagnostic2 === void 0 ? void 0 : `${diagnostic2.stage} \xB7 ${diagnostic2.causeCode}`,
|
|
2701
2708
|
defaultOpen: false,
|
|
2702
2709
|
focusPolicy: "none",
|
|
2703
2710
|
role: "status",
|
|
@@ -2714,6 +2721,8 @@ function resolveDisclosureOpen({ current, previousState, nextState, containsFocu
|
|
|
2714
2721
|
var DOT_STATE = Object.freeze({
|
|
2715
2722
|
running: "ongoing",
|
|
2716
2723
|
recovering: "ongoing",
|
|
2724
|
+
uncertain: "warning",
|
|
2725
|
+
unresolved: "warning",
|
|
2717
2726
|
completed: "done",
|
|
2718
2727
|
waiting: "warning",
|
|
2719
2728
|
failed: "error",
|
|
@@ -2745,6 +2754,7 @@ function createActionPresentationView({
|
|
|
2745
2754
|
installActionPresentationStyle();
|
|
2746
2755
|
return function WsrExecutionPresentationView({ node, technicalDetails }) {
|
|
2747
2756
|
const presentation = node.data;
|
|
2757
|
+
const presentationKind = typeof technicalDetails?.kind === "string" ? technicalDetails.kind : presentation.layer === "final" ? "terminal-result" : presentation.state === "waiting" ? "action-input-request" : ["action", "tool"].includes(presentation.layer) ? "action-output" : presentation.state === "failed" && presentation.title === "Workflow presentation" ? "error" : presentation.layer === "progress" && presentation.state === "running" ? "command-accepted" : "delivery-status";
|
|
2748
2758
|
const [open, setOpen] = React2.useState(presentation.defaultOpen);
|
|
2749
2759
|
const [copyState, setCopyState] = React2.useState("idle");
|
|
2750
2760
|
const bodyRef = React2.useRef(null);
|
|
@@ -2798,6 +2808,8 @@ function createActionPresentationView({
|
|
|
2798
2808
|
"article",
|
|
2799
2809
|
{
|
|
2800
2810
|
"data-wsr-presentation": "true",
|
|
2811
|
+
"data-wsr-kind": presentationKind,
|
|
2812
|
+
"data-wsr-surface": "chat",
|
|
2801
2813
|
"data-wsr-layer": "final",
|
|
2802
2814
|
"data-wsr-state": presentation.state,
|
|
2803
2815
|
"data-wsr-correlation": presentation.correlation,
|
|
@@ -2822,7 +2834,7 @@ function createActionPresentationView({
|
|
|
2822
2834
|
const expandable = (presentation.body !== void 0 || technicalDetails !== void 0) && !waiting;
|
|
2823
2835
|
const body = presentation.body === void 0 && technicalDetails === void 0 ? void 0 : React2.createElement("div", {
|
|
2824
2836
|
ref: bodyRef,
|
|
2825
|
-
"data-wsr-presentation": "true",
|
|
2837
|
+
"data-wsr-presentation-body": "true",
|
|
2826
2838
|
"data-wsr-layer": presentation.layer,
|
|
2827
2839
|
"data-wsr-state": presentation.state,
|
|
2828
2840
|
"data-wsr-correlation": presentation.correlation,
|
|
@@ -2853,6 +2865,12 @@ function createActionPresentationView({
|
|
|
2853
2865
|
keepContentWhenOpen: true,
|
|
2854
2866
|
collapsedContent: React2.createElement("span", {
|
|
2855
2867
|
role: presentation.role,
|
|
2868
|
+
"data-wsr-presentation": "true",
|
|
2869
|
+
"data-wsr-kind": presentationKind,
|
|
2870
|
+
"data-wsr-surface": "chat",
|
|
2871
|
+
"data-wsr-chat-role": "assistant",
|
|
2872
|
+
"data-wsr-correlation": presentation.correlation,
|
|
2873
|
+
"data-wsr-state": presentation.state,
|
|
2856
2874
|
"aria-live": ["running", "recovering", "waiting"].includes(presentation.state) ? "polite" : void 0
|
|
2857
2875
|
}, presentation.summary)
|
|
2858
2876
|
}, body);
|
|
@@ -2867,14 +2885,25 @@ function reconcileDeliveryPresentation(presentation, admitted, inventoryState) {
|
|
|
2867
2885
|
const deliveryId = admitted?.kind === "delivery-running" && typeof admitted.data.deliveryId === "string" ? admitted.data.deliveryId : void 0;
|
|
2868
2886
|
const deliveries = ["ready", "reconnecting"].includes(inventoryState?.kind) && Array.isArray(inventoryState.snapshot?.deliveries) ? inventoryState.snapshot.deliveries : [];
|
|
2869
2887
|
const matches = deliveryId === void 0 ? [] : deliveries.filter((delivery) => delivery?.deliveryId === deliveryId);
|
|
2870
|
-
const
|
|
2871
|
-
|
|
2872
|
-
return Object.freeze({
|
|
2888
|
+
const exact = matches.length === 1 ? matches[0] : void 0;
|
|
2889
|
+
const terminal = exact?.lifecycle === "TERMINAL" ? TERMINAL_PRESENTATION[exact?.terminal?.outcome] : void 0;
|
|
2890
|
+
if (terminal !== void 0) return Object.freeze({
|
|
2873
2891
|
...presentation,
|
|
2874
2892
|
state: terminal.state,
|
|
2875
2893
|
summary: `${terminal.label} \xB7 ${deliveryId}`,
|
|
2876
2894
|
defaultOpen: false
|
|
2877
2895
|
});
|
|
2896
|
+
if (exact === void 0 || typeof exact.lifecycle !== "string") return presentation;
|
|
2897
|
+
const lifecycle = /* @__PURE__ */ new Set(["BOUND", "START_UNCERTAIN", "RUNNING_CORRELATED", "START_FAILED", "RESULT_UNRESOLVED", "TERMINAL_HANDLING"]);
|
|
2898
|
+
return lifecycle.has(exact.lifecycle) ? projectExecutionPresentation({
|
|
2899
|
+
correlation: presentation.correlation,
|
|
2900
|
+
kind: "delivery-status",
|
|
2901
|
+
data: {
|
|
2902
|
+
deliveryId,
|
|
2903
|
+
state: exact.lifecycle,
|
|
2904
|
+
...admitted?.data?.diagnostic === void 0 ? {} : { diagnostic: admitted.data.diagnostic }
|
|
2905
|
+
}
|
|
2906
|
+
}) : presentation;
|
|
2878
2907
|
}
|
|
2879
2908
|
function commandPresentation(node, admitted, inventoryState) {
|
|
2880
2909
|
if (node.outcome === null) return Object.freeze({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-wsr-execution",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "DeepSeek Harness adapter bundle for WSR Intake, Delivery resources, Session state, Actions, and final results.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"displayName": "WSR",
|
|
40
40
|
"role": "execution-adapter",
|
|
41
41
|
"foundationOnly": false,
|
|
42
|
-
"ownerRevision": "
|
|
42
|
+
"ownerRevision": "b4b3b487af7f163c5934aa758d86b183d64115ec",
|
|
43
43
|
"ownerAsset": {
|
|
44
|
-
"url": "https://github.com/firestige/wsr-execution/releases/download/0.2.
|
|
45
|
-
"sha256": "
|
|
44
|
+
"url": "https://github.com/firestige/wsr-execution/releases/download/0.2.2/wsr-execution-0.2.2.tgz",
|
|
45
|
+
"sha256": "d07eb0aaa4e0498e9e3f5f9bbf3ae4c6a1a9a7ea6c648d15cdfdcccbf53bb41e"
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
@@ -15,7 +15,7 @@ const KINDS = new Set([
|
|
|
15
15
|
"terminal-result",
|
|
16
16
|
"error",
|
|
17
17
|
]);
|
|
18
|
-
const ACTION_STATES = new Set(["running", "completed", "failed", "cancelled", "waiting", "recovering"]);
|
|
18
|
+
const ACTION_STATES = new Set(["running", "completed", "failed", "cancelled", "waiting", "recovering", "uncertain", "unresolved"]);
|
|
19
19
|
const TERMINAL_OUTCOMES = new Set(["SUCCEEDED", "FAILED", "CANCELLED"]);
|
|
20
20
|
const DELIVERY_STATES = new Set([
|
|
21
21
|
"BOUND", "START_UNCERTAIN", "RUNNING_CORRELATED", "START_FAILED", "RESULT_UNRESOLVED", "TERMINAL_HANDLING",
|
|
@@ -70,8 +70,13 @@ function hasValidTypedData(value) {
|
|
|
70
70
|
return typeof value.data.outcome === "string" && TERMINAL_OUTCOMES.has(value.data.outcome) && outputValid;
|
|
71
71
|
}
|
|
72
72
|
if (value.kind === "delivery-running" || value.kind === "delivery-status") {
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
const diagnostic = value.data.diagnostic;
|
|
74
|
+
const diagnosticValid = diagnostic === undefined || (diagnostic !== null && typeof diagnostic === "object" && !Array.isArray(diagnostic)
|
|
75
|
+
&& Object.keys(diagnostic).sort().join(",") === "causeCode,stage"
|
|
76
|
+
&& typeof diagnostic.stage === "string" && /^[A-Z][A-Z0-9_]{0,63}$/u.test(diagnostic.stage)
|
|
77
|
+
&& typeof diagnostic.causeCode === "string" && /^[A-Z][A-Z0-9_]{0,127}$/u.test(diagnostic.causeCode));
|
|
78
|
+
return diagnosticValid && (value.data.state === undefined
|
|
79
|
+
|| (typeof value.data.state === "string" && DELIVERY_STATES.has(value.data.state)));
|
|
75
80
|
}
|
|
76
81
|
return true;
|
|
77
82
|
}
|
|
@@ -120,8 +125,10 @@ function normalizedLifecycle(value, fallback) {
|
|
|
120
125
|
if (["cancelled", "canceled"].includes(normalized)) return "cancelled";
|
|
121
126
|
if (["waiting", "awaiting-input"].includes(normalized)) return "waiting";
|
|
122
127
|
if (["start-failed"].includes(normalized)) return "failed";
|
|
123
|
-
if (
|
|
124
|
-
if (
|
|
128
|
+
if (normalized === "start-uncertain") return "uncertain";
|
|
129
|
+
if (normalized === "result-unresolved") return "unresolved";
|
|
130
|
+
if (["recovering", "recovery", "terminal-handling"].includes(normalized)) return "recovering";
|
|
131
|
+
if (["running", "accepted", "running-correlated", "bound"].includes(normalized)) return "running";
|
|
125
132
|
return fallback;
|
|
126
133
|
}
|
|
127
134
|
|
|
@@ -132,6 +139,8 @@ const STATE_LABELS = Object.freeze({
|
|
|
132
139
|
cancelled: "Cancelled",
|
|
133
140
|
waiting: "Waiting for input",
|
|
134
141
|
recovering: "Recovering",
|
|
142
|
+
uncertain: "Start uncertain",
|
|
143
|
+
unresolved: "Result unresolved",
|
|
135
144
|
});
|
|
136
145
|
|
|
137
146
|
function model(input) {
|
|
@@ -182,10 +191,12 @@ export function projectExecutionPresentation(event) {
|
|
|
182
191
|
? normalizedLifecycle(data.state, "running")
|
|
183
192
|
: normalizedLifecycle(data.state, event.kind === "command-accepted" ? "running" : "running");
|
|
184
193
|
const deliveryId = typeof data.deliveryId === "string" ? data.deliveryId : undefined;
|
|
194
|
+
const diagnostic = data.diagnostic;
|
|
185
195
|
return model({
|
|
186
196
|
correlation, layer: "progress", state, title: "Workflow delivery",
|
|
187
197
|
summary: `${STATE_LABELS[state]}${deliveryId === undefined ? "" : ` · ${deliveryId}`}`,
|
|
188
|
-
body:
|
|
198
|
+
body: diagnostic === undefined ? undefined : `${diagnostic.stage} · ${diagnostic.causeCode}`,
|
|
199
|
+
defaultOpen: false, focusPolicy: "none", role: "status", compatibility: "current",
|
|
189
200
|
});
|
|
190
201
|
}
|
|
191
202
|
|
|
@@ -3,6 +3,8 @@ import { parseExecutionPresentation, projectExecutionPresentation, resolveDisclo
|
|
|
3
3
|
const DOT_STATE = Object.freeze({
|
|
4
4
|
running: "ongoing",
|
|
5
5
|
recovering: "ongoing",
|
|
6
|
+
uncertain: "warning",
|
|
7
|
+
unresolved: "warning",
|
|
6
8
|
completed: "done",
|
|
7
9
|
waiting: "warning",
|
|
8
10
|
failed: "error",
|
|
@@ -42,6 +44,14 @@ export function createActionPresentationView({
|
|
|
42
44
|
|
|
43
45
|
return function WsrExecutionPresentationView({ node, technicalDetails }) {
|
|
44
46
|
const presentation = node.data;
|
|
47
|
+
const presentationKind = typeof technicalDetails?.kind === "string"
|
|
48
|
+
? technicalDetails.kind
|
|
49
|
+
: presentation.layer === "final" ? "terminal-result"
|
|
50
|
+
: presentation.state === "waiting" ? "action-input-request"
|
|
51
|
+
: ["action", "tool"].includes(presentation.layer) ? "action-output"
|
|
52
|
+
: presentation.state === "failed" && presentation.title === "Workflow presentation" ? "error"
|
|
53
|
+
: presentation.layer === "progress" && presentation.state === "running" ? "command-accepted"
|
|
54
|
+
: "delivery-status";
|
|
45
55
|
const [open, setOpen] = React.useState(presentation.defaultOpen);
|
|
46
56
|
const [copyState, setCopyState] = React.useState("idle");
|
|
47
57
|
const bodyRef = React.useRef(null);
|
|
@@ -96,6 +106,8 @@ export function createActionPresentationView({
|
|
|
96
106
|
};
|
|
97
107
|
return React.createElement("article", {
|
|
98
108
|
"data-wsr-presentation": "true",
|
|
109
|
+
"data-wsr-kind": presentationKind,
|
|
110
|
+
"data-wsr-surface": "chat",
|
|
99
111
|
"data-wsr-layer": "final",
|
|
100
112
|
"data-wsr-state": presentation.state,
|
|
101
113
|
"data-wsr-correlation": presentation.correlation,
|
|
@@ -120,7 +132,7 @@ export function createActionPresentationView({
|
|
|
120
132
|
const expandable = (presentation.body !== undefined || technicalDetails !== undefined) && !waiting;
|
|
121
133
|
const body = presentation.body === undefined && technicalDetails === undefined ? undefined : React.createElement("div", {
|
|
122
134
|
ref: bodyRef,
|
|
123
|
-
"data-wsr-presentation": "true",
|
|
135
|
+
"data-wsr-presentation-body": "true",
|
|
124
136
|
"data-wsr-layer": presentation.layer,
|
|
125
137
|
"data-wsr-state": presentation.state,
|
|
126
138
|
"data-wsr-correlation": presentation.correlation,
|
|
@@ -151,7 +163,13 @@ export function createActionPresentationView({
|
|
|
151
163
|
keepContentWhenOpen: true,
|
|
152
164
|
collapsedContent: React.createElement("span", {
|
|
153
165
|
role: presentation.role,
|
|
154
|
-
"
|
|
166
|
+
"data-wsr-presentation": "true",
|
|
167
|
+
"data-wsr-kind": presentationKind,
|
|
168
|
+
"data-wsr-surface": "chat",
|
|
169
|
+
"data-wsr-chat-role": "assistant",
|
|
170
|
+
"data-wsr-correlation": presentation.correlation,
|
|
171
|
+
"data-wsr-state": presentation.state,
|
|
172
|
+
"aria-live": ["running", "recovering", "waiting"].includes(presentation.state) ? "polite" : undefined,
|
|
155
173
|
}, presentation.summary),
|
|
156
174
|
}, body);
|
|
157
175
|
};
|
|
@@ -172,16 +190,29 @@ function reconcileDeliveryPresentation(presentation, admitted, inventoryState) {
|
|
|
172
190
|
? inventoryState.snapshot.deliveries
|
|
173
191
|
: [];
|
|
174
192
|
const matches = deliveryId === undefined ? [] : deliveries.filter((delivery) => delivery?.deliveryId === deliveryId);
|
|
175
|
-
const
|
|
176
|
-
|
|
193
|
+
const exact = matches.length === 1 ? matches[0] : undefined;
|
|
194
|
+
const terminal = exact?.lifecycle === "TERMINAL"
|
|
195
|
+
? TERMINAL_PRESENTATION[exact?.terminal?.outcome]
|
|
177
196
|
: undefined;
|
|
178
|
-
if (terminal
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
197
|
+
if (terminal !== undefined) return Object.freeze({
|
|
198
|
+
...presentation,
|
|
199
|
+
state: terminal.state,
|
|
200
|
+
summary: `${terminal.label} · ${deliveryId}`,
|
|
201
|
+
defaultOpen: false,
|
|
202
|
+
});
|
|
203
|
+
if (exact === undefined || typeof exact.lifecycle !== "string") return presentation;
|
|
204
|
+
const lifecycle = new Set(["BOUND", "START_UNCERTAIN", "RUNNING_CORRELATED", "START_FAILED", "RESULT_UNRESOLVED", "TERMINAL_HANDLING"]);
|
|
205
|
+
return lifecycle.has(exact.lifecycle)
|
|
206
|
+
? projectExecutionPresentation({
|
|
207
|
+
correlation: presentation.correlation,
|
|
208
|
+
kind: "delivery-status",
|
|
209
|
+
data: {
|
|
210
|
+
deliveryId,
|
|
211
|
+
state: exact.lifecycle,
|
|
212
|
+
...(admitted?.data?.diagnostic === undefined ? {} : { diagnostic: admitted.data.diagnostic }),
|
|
213
|
+
},
|
|
214
|
+
})
|
|
215
|
+
: presentation;
|
|
185
216
|
}
|
|
186
217
|
|
|
187
218
|
function commandPresentation(node, admitted, inventoryState) {
|
package/src/intake/command.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
const USAGE = "Usage: /wsr list | create <selector> | recover [delivery-id] | status [delivery-id] | action finish. Usage: /wsr abandon [delivery-id]";
|
|
2
|
+
|
|
1
3
|
function invalid() {
|
|
2
|
-
throw new TypeError("WSR_COMMAND_INVALID");
|
|
4
|
+
throw Object.assign(new TypeError(`WSR_COMMAND_INVALID. ${USAGE}`), { code: "WSR_COMMAND_INVALID" });
|
|
3
5
|
}
|
|
4
6
|
|
|
5
7
|
function split(value) {
|
|
@@ -30,6 +32,10 @@ export function parseWsrCommand(value) {
|
|
|
30
32
|
return Object.freeze({ operation: "status", deliveryId });
|
|
31
33
|
}
|
|
32
34
|
if (line === "action finish") return Object.freeze({ operation: "action-finish", ...(remainder === undefined ? {} : { remainder }) });
|
|
35
|
+
if (line === "abandon") {
|
|
36
|
+
if (remainder !== undefined) invalid();
|
|
37
|
+
return Object.freeze({ operation: "abandon" });
|
|
38
|
+
}
|
|
33
39
|
if (line.startsWith("abandon ")) {
|
|
34
40
|
const deliveryId = line.slice(8);
|
|
35
41
|
if (deliveryId.length === 0 || deliveryId.includes(" ") || remainder !== undefined) invalid();
|
package/src/intake/plugin.js
CHANGED
|
@@ -451,10 +451,12 @@ export async function createPluginRuntime(config, options = {}) {
|
|
|
451
451
|
if (existing === undefined) return error("DELIVERY_UNKNOWN");
|
|
452
452
|
return service.invoke(Object.freeze({ operation: "action-finish", ...(operation.remainder === undefined && attachments.length === 0 ? {} : { turn: Object.freeze({ text: operation.remainder ?? "", attachments }) }), correlation: existing.correlation }));
|
|
453
453
|
}
|
|
454
|
-
const
|
|
454
|
+
const deliveryId = operation.deliveryId ?? existing?.deliveryId;
|
|
455
|
+
if (deliveryId === undefined) return error("WSR_COMMAND_INVALID");
|
|
456
|
+
const result = await service.invoke(Object.freeze({ operation: "abandon", deliveryId, correlation }));
|
|
455
457
|
if (result.kind === "TERMINAL") {
|
|
456
|
-
const detached = await bindings.byDelivery(
|
|
457
|
-
if (detached !== undefined) await archiveTerminal(detached.sessionKey, detached.correlation,
|
|
458
|
+
const detached = await bindings.byDelivery(deliveryId);
|
|
459
|
+
if (detached !== undefined) await archiveTerminal(detached.sessionKey, detached.correlation, deliveryId);
|
|
458
460
|
if (detached !== undefined) sessionByCorrelation.delete(detached.correlation);
|
|
459
461
|
}
|
|
460
462
|
return result;
|
|
@@ -514,7 +516,8 @@ export function mapIntakeToolOperation(args) {
|
|
|
514
516
|
|| Object.keys(args).some((key) => !["operation", "selector", "deliveryId"].includes(key))
|
|
515
517
|
|| !operationNames.includes(args.operation)
|
|
516
518
|
|| (args.operation === "create") !== (typeof args.selector === "string" && args.selector.length > 0)
|
|
517
|
-
|| (args.operation === "abandon" &&
|
|
519
|
+
|| (args.operation === "abandon" && args.deliveryId !== undefined
|
|
520
|
+
&& (typeof args.deliveryId !== "string" || args.deliveryId.length === 0))
|
|
518
521
|
|| (!["recover", "status", "abandon"].includes(args.operation) && args.deliveryId !== undefined)) {
|
|
519
522
|
throw new TypeError("INTAKE_OPERATION_INVALID");
|
|
520
523
|
}
|
|
@@ -536,7 +539,7 @@ export async function apply(ctx, config) {
|
|
|
536
539
|
const command = ctx.commands.register({
|
|
537
540
|
name: "wsr",
|
|
538
541
|
description: "Create, list, recover, inspect, finish, or abandon a Workflow Delivery",
|
|
539
|
-
input: { hint: "list | create <selector> | recover [delivery-id] | status [delivery-id] | action finish | abandon
|
|
542
|
+
input: { hint: "list | create <selector> | recover [delivery-id] | status [delivery-id] | action finish | abandon [delivery-id]", images: true },
|
|
540
543
|
recordInput: true,
|
|
541
544
|
async handler(invocation) {
|
|
542
545
|
return run((async () => {
|
|
@@ -571,7 +574,8 @@ export async function apply(ctx, config) {
|
|
|
571
574
|
} catch (cause) {
|
|
572
575
|
const { createIntakePresentation, serializeIntakePresentation } = await import("wsr-execution");
|
|
573
576
|
const code = typeof cause?.code === "string" ? cause.code : "DSH_INTAKE_FAILED";
|
|
574
|
-
const
|
|
577
|
+
const message = code === "WSR_COMMAND_INVALID" && typeof cause?.message === "string" ? cause.message : code;
|
|
578
|
+
const presentation = createIntakePresentation(`presentation-${randomUUID()}`, "error", { code, message });
|
|
575
579
|
presentToDshSession(invocation.agent, presentation);
|
|
576
580
|
return { kind: "error", text: serializeIntakePresentation(presentation, 4096) };
|
|
577
581
|
}
|