@cadraos/sdk 0.3.14-p102.2 → 0.3.14-p139.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.
- package/dist/chat/index.cjs +211 -47
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +109 -5
- package/dist/chat/index.d.ts +109 -5
- package/dist/chat/index.js +211 -47
- package/dist/chat/index.js.map +1 -1
- package/dist/index.cjs +56 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +56 -13
- package/dist/index.js.map +1 -1
- package/dist/kanban/index.cjs +56 -13
- package/dist/kanban/index.cjs.map +1 -1
- package/dist/kanban/index.d.cts +43 -1
- package/dist/kanban/index.d.ts +43 -1
- package/dist/kanban/index.js +56 -13
- package/dist/kanban/index.js.map +1 -1
- package/dist/teams/index.cjs +56 -13
- package/dist/teams/index.cjs.map +1 -1
- package/dist/teams/index.d.cts +37 -1
- package/dist/teams/index.d.ts +37 -1
- package/dist/teams/index.js +56 -13
- package/dist/teams/index.js.map +1 -1
- package/package.json +1 -1
package/dist/chat/index.cjs
CHANGED
|
@@ -12,6 +12,28 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
12
12
|
var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
|
|
13
13
|
var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
|
|
14
14
|
|
|
15
|
+
// src/streaming/steered-refs.ts
|
|
16
|
+
function readSteeredRefs(data) {
|
|
17
|
+
if (!data || typeof data !== "object") return void 0;
|
|
18
|
+
const record = data;
|
|
19
|
+
const metadata = record.metadata;
|
|
20
|
+
const candidates = [
|
|
21
|
+
record.steeredRefs,
|
|
22
|
+
metadata && typeof metadata === "object" ? metadata.steeredRefs : void 0
|
|
23
|
+
];
|
|
24
|
+
for (const value of candidates) {
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
const refs = value.filter((v) => typeof v === "string" && v.length > 0);
|
|
27
|
+
if (refs.length > 0) return refs;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
function readSteeredRefsField(data) {
|
|
33
|
+
const steeredRefs = readSteeredRefs(data);
|
|
34
|
+
return steeredRefs ? { steeredRefs } : {};
|
|
35
|
+
}
|
|
36
|
+
|
|
15
37
|
// src/resources/base.ts
|
|
16
38
|
var BaseResourceAPI = class {
|
|
17
39
|
http;
|
|
@@ -65,6 +87,19 @@ var BaseResourceAPI = class {
|
|
|
65
87
|
}
|
|
66
88
|
};
|
|
67
89
|
|
|
90
|
+
// src/utils/api-paths.ts
|
|
91
|
+
var API_V1 = "/api/v1";
|
|
92
|
+
var EXECUTION_PATH = `${API_V1}/executions`;
|
|
93
|
+
function executionPath(executionId) {
|
|
94
|
+
return `${EXECUTION_PATH}/${executionId}`;
|
|
95
|
+
}
|
|
96
|
+
function executionSteerPath(executionId) {
|
|
97
|
+
return `${EXECUTION_PATH}/${executionId}/steer`;
|
|
98
|
+
}
|
|
99
|
+
function executionCancelPath(executionId) {
|
|
100
|
+
return `${EXECUTION_PATH}/${executionId}/cancel`;
|
|
101
|
+
}
|
|
102
|
+
|
|
68
103
|
// src/errors/sdk-errors.ts
|
|
69
104
|
var CadraError = class extends Error {
|
|
70
105
|
/** Error code */
|
|
@@ -1306,7 +1341,9 @@ var ExecutionStreamControllerImpl = class {
|
|
|
1306
1341
|
tokenUsage: data.tokenUsage,
|
|
1307
1342
|
cost: data.cost,
|
|
1308
1343
|
queuedAt: "",
|
|
1309
|
-
...data
|
|
1344
|
+
...data,
|
|
1345
|
+
// p139: normalise steeredRefs (event top level or record metadata).
|
|
1346
|
+
...readSteeredRefsField(data)
|
|
1310
1347
|
};
|
|
1311
1348
|
this.finalExecution = execution;
|
|
1312
1349
|
this.emit("complete", { execution });
|
|
@@ -1760,16 +1797,6 @@ async function collectImagesFromStream(stream, options = {}) {
|
|
|
1760
1797
|
});
|
|
1761
1798
|
}
|
|
1762
1799
|
|
|
1763
|
-
// src/utils/api-paths.ts
|
|
1764
|
-
var API_V1 = "/api/v1";
|
|
1765
|
-
var EXECUTION_PATH = `${API_V1}/executions`;
|
|
1766
|
-
function executionPath(executionId) {
|
|
1767
|
-
return `${EXECUTION_PATH}/${executionId}`;
|
|
1768
|
-
}
|
|
1769
|
-
function executionCancelPath(executionId) {
|
|
1770
|
-
return `${EXECUTION_PATH}/${executionId}/cancel`;
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1773
1800
|
// src/resources/agents.ts
|
|
1774
1801
|
var AgentsAPI = class extends BaseResourceAPI {
|
|
1775
1802
|
constructor(http, getStreamConfig) {
|
|
@@ -2078,6 +2105,8 @@ var AgentsAPI = class extends BaseResourceAPI {
|
|
|
2078
2105
|
* Cancel a running execution
|
|
2079
2106
|
*
|
|
2080
2107
|
* @param executionId - Execution UUID
|
|
2108
|
+
* @param options - Optional. `scope: 'run_and_work'` stops the run AND the
|
|
2109
|
+
* background work it started in this conversation (p139); omitted = the run only.
|
|
2081
2110
|
* @returns Updated execution with cancelled status
|
|
2082
2111
|
*
|
|
2083
2112
|
* @example
|
|
@@ -2086,10 +2115,10 @@ var AgentsAPI = class extends BaseResourceAPI {
|
|
|
2086
2115
|
* console.log(execution.status); // 'cancelled'
|
|
2087
2116
|
* ```
|
|
2088
2117
|
*/
|
|
2089
|
-
async cancelExecution(executionId) {
|
|
2118
|
+
async cancelExecution(executionId, options) {
|
|
2090
2119
|
return this.http.post(
|
|
2091
2120
|
executionCancelPath(executionId),
|
|
2092
|
-
void 0,
|
|
2121
|
+
options && Object.keys(options).length > 0 ? options : void 0,
|
|
2093
2122
|
{ skipRetry: true }
|
|
2094
2123
|
);
|
|
2095
2124
|
}
|
|
@@ -2106,6 +2135,20 @@ var AgentsAPI = class extends BaseResourceAPI {
|
|
|
2106
2135
|
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
2107
2136
|
}
|
|
2108
2137
|
}
|
|
2138
|
+
// ===== p139 steer =====
|
|
2139
|
+
/**
|
|
2140
|
+
* p139 — forward messages typed while an execution runs. The server answers
|
|
2141
|
+
* `ACCEPTED` (the run will read them between steps), `QUEUED_BEHIND` (not
|
|
2142
|
+
* read yet; send them after the run) or `ENDED` (run finished; send them as
|
|
2143
|
+
* a new turn). Answered = listed in the run's `steeredRefs` on completion.
|
|
2144
|
+
*/
|
|
2145
|
+
async steerExecution(executionId, messages) {
|
|
2146
|
+
return this.http.post(
|
|
2147
|
+
executionSteerPath(executionId),
|
|
2148
|
+
{ messages },
|
|
2149
|
+
{ skipRetry: true }
|
|
2150
|
+
);
|
|
2151
|
+
}
|
|
2109
2152
|
};
|
|
2110
2153
|
|
|
2111
2154
|
// src/resources/skills.ts
|
|
@@ -3579,6 +3622,9 @@ function resolveBaseUrl(config) {
|
|
|
3579
3622
|
if (config.baseUrl) return config.baseUrl;
|
|
3580
3623
|
return "https://api.cadraos.com";
|
|
3581
3624
|
}
|
|
3625
|
+
function steerableField(result) {
|
|
3626
|
+
return typeof result.steerable === "boolean" ? { steerable: result.steerable } : {};
|
|
3627
|
+
}
|
|
3582
3628
|
function createDefaultAdapter(config) {
|
|
3583
3629
|
const client = resolveClient(config);
|
|
3584
3630
|
const baseUrl = resolveBaseUrl(config);
|
|
@@ -3598,7 +3644,8 @@ function createDefaultAdapter(config) {
|
|
|
3598
3644
|
});
|
|
3599
3645
|
return {
|
|
3600
3646
|
executionId: result2.executionId,
|
|
3601
|
-
sessionId: result2.sessionId ?? input.sessionId
|
|
3647
|
+
sessionId: result2.sessionId ?? input.sessionId,
|
|
3648
|
+
...steerableField(result2)
|
|
3602
3649
|
};
|
|
3603
3650
|
}
|
|
3604
3651
|
const pathId = input.agentId || input.teamId || "";
|
|
@@ -3615,7 +3662,8 @@ function createDefaultAdapter(config) {
|
|
|
3615
3662
|
});
|
|
3616
3663
|
return {
|
|
3617
3664
|
executionId: result.executionId,
|
|
3618
|
-
sessionId: result.sessionId ?? ""
|
|
3665
|
+
sessionId: result.sessionId ?? "",
|
|
3666
|
+
...steerableField(result)
|
|
3619
3667
|
};
|
|
3620
3668
|
},
|
|
3621
3669
|
async sendMessage(input) {
|
|
@@ -3630,11 +3678,12 @@ function createDefaultAdapter(config) {
|
|
|
3630
3678
|
});
|
|
3631
3679
|
return {
|
|
3632
3680
|
executionId: result.executionId,
|
|
3633
|
-
sessionId: result.sessionId ?? input.sessionId
|
|
3681
|
+
sessionId: result.sessionId ?? input.sessionId,
|
|
3682
|
+
...steerableField(result)
|
|
3634
3683
|
};
|
|
3635
3684
|
},
|
|
3636
3685
|
async cancelExecution(uuid) {
|
|
3637
|
-
await client.agents.cancelExecution(uuid);
|
|
3686
|
+
await client.agents.cancelExecution(uuid, { scope: "run_and_work" });
|
|
3638
3687
|
},
|
|
3639
3688
|
async getExecution(uuid) {
|
|
3640
3689
|
const exec = await client.agents.getExecution(uuid);
|
|
@@ -3642,9 +3691,15 @@ function createDefaultAdapter(config) {
|
|
|
3642
3691
|
uuid: exec.uuid,
|
|
3643
3692
|
status: exec.status === "queued" ? "pending" : exec.status,
|
|
3644
3693
|
result: exec.output,
|
|
3645
|
-
error: exec.error
|
|
3694
|
+
error: exec.error,
|
|
3695
|
+
...readSteeredRefsField(exec)
|
|
3646
3696
|
};
|
|
3647
3697
|
},
|
|
3698
|
+
// p139: steer a running execution (REST `POST /api/v1/executions/{id}/steer`).
|
|
3699
|
+
async steerExecution(executionId, message) {
|
|
3700
|
+
const res = await client.agents.steerExecution(executionId, [message]);
|
|
3701
|
+
return res.state;
|
|
3702
|
+
},
|
|
3648
3703
|
// -------------------------------------------------------------------------
|
|
3649
3704
|
// Attachment Methods (delegates to CadraClient.attachments)
|
|
3650
3705
|
// -------------------------------------------------------------------------
|
|
@@ -4034,7 +4089,7 @@ function useExecutionStream(options) {
|
|
|
4034
4089
|
clearTimeout(activityTimeoutRef.current);
|
|
4035
4090
|
activityTimeoutRef.current = null;
|
|
4036
4091
|
}
|
|
4037
|
-
onComplete?.();
|
|
4092
|
+
onComplete?.(data);
|
|
4038
4093
|
break;
|
|
4039
4094
|
case "error":
|
|
4040
4095
|
const errorMsg = data.error || "Unknown error";
|
|
@@ -4501,7 +4556,9 @@ function useAgentChat(options) {
|
|
|
4501
4556
|
onClarification,
|
|
4502
4557
|
pollingInterval,
|
|
4503
4558
|
pollingEnabled,
|
|
4504
|
-
historyStaleMs = DEFAULT_HISTORY_STALE_MS
|
|
4559
|
+
historyStaleMs = DEFAULT_HISTORY_STALE_MS,
|
|
4560
|
+
allowSendWhileRunning = false,
|
|
4561
|
+
onSteer
|
|
4505
4562
|
} = options;
|
|
4506
4563
|
const contextConfig = useChatConfigOptional();
|
|
4507
4564
|
const adapter = propsAdapter ?? contextConfig?.adapter;
|
|
@@ -4538,6 +4595,29 @@ function useAgentChat(options) {
|
|
|
4538
4595
|
const firedToolResultsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
4539
4596
|
const streamControllerRef = react.useRef(null);
|
|
4540
4597
|
const pendingDelegationsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
4598
|
+
const onSteerRef = react.useRef(onSteer);
|
|
4599
|
+
onSteerRef.current = onSteer;
|
|
4600
|
+
const adapterRef = react.useRef(adapter);
|
|
4601
|
+
adapterRef.current = adapter;
|
|
4602
|
+
const hasSteerHandler = !!onSteer || typeof adapter.steerExecution === "function";
|
|
4603
|
+
const [runSteerable, setRunSteerable] = react.useState(void 0);
|
|
4604
|
+
const canSendWhileRunning = allowSendWhileRunning && hasSteerHandler && runSteerable === true;
|
|
4605
|
+
const canSendWhileRunningRef = react.useRef(canSendWhileRunning);
|
|
4606
|
+
canSendWhileRunningRef.current = canSendWhileRunning;
|
|
4607
|
+
const runActiveRef = react.useRef(false);
|
|
4608
|
+
const currentExecutionIdRef = react.useRef(null);
|
|
4609
|
+
const pendingSteersRef = react.useRef([]);
|
|
4610
|
+
const flushPendingRef = react.useRef(() => {
|
|
4611
|
+
});
|
|
4612
|
+
const settlePendingSteers = react.useCallback((steeredRefs) => {
|
|
4613
|
+
const pending = pendingSteersRef.current;
|
|
4614
|
+
if (pending.length === 0) return;
|
|
4615
|
+
pendingSteersRef.current = [];
|
|
4616
|
+
const answered = new Set(steeredRefs ?? []);
|
|
4617
|
+
const remaining = pending.filter((p) => !answered.has(p.ref));
|
|
4618
|
+
if (remaining.length === 0) return;
|
|
4619
|
+
setTimeout(() => flushPendingRef.current(remaining), 0);
|
|
4620
|
+
}, []);
|
|
4541
4621
|
const onDelegationRef = react.useRef(options.onDelegation);
|
|
4542
4622
|
react.useEffect(() => {
|
|
4543
4623
|
onDelegationRef.current = options.onDelegation;
|
|
@@ -4964,19 +5044,22 @@ function useAgentChat(options) {
|
|
|
4964
5044
|
[onClarification]
|
|
4965
5045
|
);
|
|
4966
5046
|
const completedRef = react.useRef(false);
|
|
4967
|
-
const handleComplete = react.useCallback((finalOutput) => {
|
|
5047
|
+
const handleComplete = react.useCallback((finalOutput, steeredRefs) => {
|
|
4968
5048
|
if (completedRef.current) {
|
|
4969
5049
|
if (__DEV__) console.log("[useAgentChat] handleComplete: skipping duplicate complete");
|
|
4970
5050
|
return;
|
|
4971
5051
|
}
|
|
4972
5052
|
completedRef.current = true;
|
|
4973
5053
|
if (__DEV__) console.log("[useAgentChat] handleComplete called");
|
|
5054
|
+
runActiveRef.current = false;
|
|
5055
|
+
currentExecutionIdRef.current = null;
|
|
4974
5056
|
setIsLoading(false);
|
|
4975
5057
|
setIsStreamControllerConnected(false);
|
|
4976
5058
|
finalizeStreamingMessage(finalOutput);
|
|
4977
5059
|
setCurrentExecutionId(null);
|
|
4978
5060
|
streamControllerRef.current = null;
|
|
4979
|
-
|
|
5061
|
+
settlePendingSteers(steeredRefs);
|
|
5062
|
+
}, [finalizeStreamingMessage, settlePendingSteers]);
|
|
4980
5063
|
const handleError = react.useCallback(
|
|
4981
5064
|
(errorMsg) => {
|
|
4982
5065
|
if (__DEV__) console.log("[useAgentChat] handleError called:", errorMsg);
|
|
@@ -4985,6 +5068,8 @@ function useAgentChat(options) {
|
|
|
4985
5068
|
message: errorMsg,
|
|
4986
5069
|
retryable: true
|
|
4987
5070
|
};
|
|
5071
|
+
runActiveRef.current = false;
|
|
5072
|
+
currentExecutionIdRef.current = null;
|
|
4988
5073
|
setError(chatError);
|
|
4989
5074
|
setIsLoading(false);
|
|
4990
5075
|
setIsStreamControllerConnected(false);
|
|
@@ -4992,8 +5077,9 @@ function useAgentChat(options) {
|
|
|
4992
5077
|
setCurrentExecutionId(null);
|
|
4993
5078
|
streamControllerRef.current = null;
|
|
4994
5079
|
onError?.(chatError);
|
|
5080
|
+
settlePendingSteers(void 0);
|
|
4995
5081
|
},
|
|
4996
|
-
[finalizeStreamingMessage, onError]
|
|
5082
|
+
[finalizeStreamingMessage, onError, settlePendingSteers]
|
|
4997
5083
|
);
|
|
4998
5084
|
const legacyExecutionId = useStreamController ? void 0 : currentExecutionId;
|
|
4999
5085
|
const { isConnected: legacyIsConnected, isUsingFallback, disconnect } = useExecutionStream({
|
|
@@ -5002,7 +5088,7 @@ function useAgentChat(options) {
|
|
|
5002
5088
|
enabled: !!legacyExecutionId,
|
|
5003
5089
|
onLog: handleStreamLog,
|
|
5004
5090
|
onClarification: handleClarification,
|
|
5005
|
-
onComplete: handleComplete,
|
|
5091
|
+
onComplete: (data) => handleComplete(void 0, readSteeredRefs(data)),
|
|
5006
5092
|
onError: handleError,
|
|
5007
5093
|
// P25 — Action 1: render `progress` / `status_update` / `started`
|
|
5008
5094
|
// labels in the streaming bubble's thinking pill.
|
|
@@ -5072,7 +5158,7 @@ function useAgentChat(options) {
|
|
|
5072
5158
|
if (execution.status === "completed") {
|
|
5073
5159
|
if (__DEV__) console.log("[useAgentChat] Polling: execution completed");
|
|
5074
5160
|
stopPolling();
|
|
5075
|
-
handleComplete(execution.result || void 0);
|
|
5161
|
+
handleComplete(execution.result || void 0, readSteeredRefs(execution));
|
|
5076
5162
|
return;
|
|
5077
5163
|
}
|
|
5078
5164
|
if (execution.status === "failed") {
|
|
@@ -5299,7 +5385,7 @@ function useAgentChat(options) {
|
|
|
5299
5385
|
});
|
|
5300
5386
|
controller.on("complete", ({ execution }) => {
|
|
5301
5387
|
const output = execution?.output || void 0;
|
|
5302
|
-
handleComplete(output);
|
|
5388
|
+
handleComplete(output, readSteeredRefs(execution));
|
|
5303
5389
|
});
|
|
5304
5390
|
controller.on("error", (errorEvent) => {
|
|
5305
5391
|
handleError(errorEvent.error);
|
|
@@ -5315,22 +5401,25 @@ function useAgentChat(options) {
|
|
|
5315
5401
|
},
|
|
5316
5402
|
[adapter, handleExecutionLog, updateStreamingMessage, setStreamingMessageStep, updateToolCall, updateMessageImages, addDelegationEvent, handleClarification, handleComplete, handleError]
|
|
5317
5403
|
);
|
|
5318
|
-
const
|
|
5319
|
-
async (content,
|
|
5320
|
-
if (!content.trim()) return;
|
|
5321
|
-
const attachmentUuids = options2?.attachmentUuids;
|
|
5404
|
+
const startTurn = react.useCallback(
|
|
5405
|
+
async (content, attachmentUuids, addUserBubble) => {
|
|
5322
5406
|
lastMessageContentRef.current = content;
|
|
5407
|
+
runActiveRef.current = true;
|
|
5408
|
+
currentExecutionIdRef.current = null;
|
|
5409
|
+
setRunSteerable(void 0);
|
|
5323
5410
|
setIsLoading(true);
|
|
5324
5411
|
setError(null);
|
|
5325
5412
|
setClarification(null);
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5413
|
+
if (addUserBubble) {
|
|
5414
|
+
const userMessage = {
|
|
5415
|
+
id: generateId(),
|
|
5416
|
+
role: "user",
|
|
5417
|
+
content: content.trim(),
|
|
5418
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
5419
|
+
};
|
|
5420
|
+
setMessages((prev) => [...prev, userMessage]);
|
|
5421
|
+
onMessage?.(userMessage);
|
|
5422
|
+
}
|
|
5334
5423
|
const preparedExecutionId = generateExecutionId2();
|
|
5335
5424
|
const assistantMessageId = generateId();
|
|
5336
5425
|
const assistantMessage = {
|
|
@@ -5375,6 +5464,10 @@ function useAgentChat(options) {
|
|
|
5375
5464
|
onSessionCreated?.(result.sessionId);
|
|
5376
5465
|
onSessionStart?.(result.sessionId);
|
|
5377
5466
|
}
|
|
5467
|
+
if (runActiveRef.current && !completedRef.current) {
|
|
5468
|
+
currentExecutionIdRef.current = result.executionId;
|
|
5469
|
+
}
|
|
5470
|
+
setRunSteerable(result.steerable);
|
|
5378
5471
|
if (useStreamController) {
|
|
5379
5472
|
connectStreamController(
|
|
5380
5473
|
result.executionId,
|
|
@@ -5407,6 +5500,64 @@ function useAgentChat(options) {
|
|
|
5407
5500
|
handleError
|
|
5408
5501
|
]
|
|
5409
5502
|
);
|
|
5503
|
+
flushPendingRef.current = (pending) => {
|
|
5504
|
+
const attachments = pending.flatMap((p) => p.attachmentUuids ?? []);
|
|
5505
|
+
void startTurn(
|
|
5506
|
+
pending.map((p) => p.text).join("\n\n"),
|
|
5507
|
+
attachments.length > 0 ? attachments : void 0,
|
|
5508
|
+
false
|
|
5509
|
+
);
|
|
5510
|
+
};
|
|
5511
|
+
const steerWhileRunning = react.useCallback(
|
|
5512
|
+
async (text, attachmentUuids) => {
|
|
5513
|
+
const ref = generateExecutionId2();
|
|
5514
|
+
pendingSteersRef.current.push({ ref, text, attachmentUuids });
|
|
5515
|
+
const userMessage = {
|
|
5516
|
+
id: ref,
|
|
5517
|
+
role: "user",
|
|
5518
|
+
content: text,
|
|
5519
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
5520
|
+
steerState: "pending"
|
|
5521
|
+
};
|
|
5522
|
+
setMessages((prev) => [...prev, userMessage]);
|
|
5523
|
+
onMessage?.(userMessage);
|
|
5524
|
+
const executionId = currentExecutionIdRef.current;
|
|
5525
|
+
if (!executionId) return;
|
|
5526
|
+
let outcome;
|
|
5527
|
+
try {
|
|
5528
|
+
const handler = onSteerRef.current;
|
|
5529
|
+
const steerMessage = { ref, text, ...attachmentUuids?.length ? { attachmentUuids } : {} };
|
|
5530
|
+
outcome = handler ? await handler(executionId, steerMessage) : await adapterRef.current.steerExecution(executionId, steerMessage);
|
|
5531
|
+
} catch {
|
|
5532
|
+
return;
|
|
5533
|
+
}
|
|
5534
|
+
if (outcome === "ACCEPTED") {
|
|
5535
|
+
setMessages(
|
|
5536
|
+
(prev) => prev.map((m) => m.id === ref ? { ...m, steerState: "delivered" } : m)
|
|
5537
|
+
);
|
|
5538
|
+
return;
|
|
5539
|
+
}
|
|
5540
|
+
if (outcome === "ENDED" && !runActiveRef.current) {
|
|
5541
|
+
const idx = pendingSteersRef.current.findIndex((p) => p.ref === ref);
|
|
5542
|
+
if (idx >= 0) {
|
|
5543
|
+
const entry = pendingSteersRef.current.splice(idx, 1)[0];
|
|
5544
|
+
flushPendingRef.current([entry]);
|
|
5545
|
+
}
|
|
5546
|
+
}
|
|
5547
|
+
},
|
|
5548
|
+
[onMessage]
|
|
5549
|
+
);
|
|
5550
|
+
const sendMessage = react.useCallback(
|
|
5551
|
+
async (content, options2) => {
|
|
5552
|
+
if (!content.trim()) return;
|
|
5553
|
+
if (runActiveRef.current && canSendWhileRunningRef.current) {
|
|
5554
|
+
await steerWhileRunning(content.trim(), options2?.attachmentUuids);
|
|
5555
|
+
return;
|
|
5556
|
+
}
|
|
5557
|
+
await startTurn(content, options2?.attachmentUuids, true);
|
|
5558
|
+
},
|
|
5559
|
+
[startTurn, steerWhileRunning]
|
|
5560
|
+
);
|
|
5410
5561
|
const respondToClarification = react.useCallback(
|
|
5411
5562
|
async (response) => {
|
|
5412
5563
|
if (!clarification) return;
|
|
@@ -5416,7 +5567,10 @@ function useAgentChat(options) {
|
|
|
5416
5567
|
[clarification, sendMessage]
|
|
5417
5568
|
);
|
|
5418
5569
|
const cancel = react.useCallback(async () => {
|
|
5570
|
+
pendingSteersRef.current = [];
|
|
5419
5571
|
if (currentExecutionId) {
|
|
5572
|
+
runActiveRef.current = false;
|
|
5573
|
+
currentExecutionIdRef.current = null;
|
|
5420
5574
|
try {
|
|
5421
5575
|
await adapter.cancelExecution(currentExecutionId);
|
|
5422
5576
|
} catch {
|
|
@@ -5442,6 +5596,7 @@ function useAgentChat(options) {
|
|
|
5442
5596
|
setError(null);
|
|
5443
5597
|
}, []);
|
|
5444
5598
|
const clearMessages = react.useCallback(() => {
|
|
5599
|
+
pendingSteersRef.current = [];
|
|
5445
5600
|
setMessages([]);
|
|
5446
5601
|
setCurrentSessionId(null);
|
|
5447
5602
|
hasLoadedInitialSession.current = false;
|
|
@@ -5655,7 +5810,8 @@ function useAgentChat(options) {
|
|
|
5655
5810
|
retry,
|
|
5656
5811
|
clearError,
|
|
5657
5812
|
clearMessages,
|
|
5658
|
-
loadSession
|
|
5813
|
+
loadSession,
|
|
5814
|
+
canSendWhileRunning
|
|
5659
5815
|
};
|
|
5660
5816
|
}
|
|
5661
5817
|
|
|
@@ -6605,6 +6761,7 @@ function ChatInput({
|
|
|
6605
6761
|
placeholder = "Type a message...",
|
|
6606
6762
|
disabled = false,
|
|
6607
6763
|
isLoading = false,
|
|
6764
|
+
allowSendWhileRunning = false,
|
|
6608
6765
|
enableAttachments = false,
|
|
6609
6766
|
attachments = [],
|
|
6610
6767
|
onRemoveAttachment,
|
|
@@ -6630,6 +6787,7 @@ function ChatInput({
|
|
|
6630
6787
|
});
|
|
6631
6788
|
}, [onInputControlReady, onInputChange]);
|
|
6632
6789
|
const hasAttachments = enableAttachments && attachments.length > 0;
|
|
6790
|
+
const lockedByRun = isLoading && !allowSendWhileRunning;
|
|
6633
6791
|
react.useEffect(() => {
|
|
6634
6792
|
const textarea = textareaRef.current;
|
|
6635
6793
|
if (textarea) {
|
|
@@ -6639,10 +6797,10 @@ function ChatInput({
|
|
|
6639
6797
|
}, [content]);
|
|
6640
6798
|
const handleSubmit = react.useCallback(async () => {
|
|
6641
6799
|
const trimmedContent = content.trim();
|
|
6642
|
-
if (!trimmedContent && !hasAttachments || disabled ||
|
|
6800
|
+
if (!trimmedContent && !hasAttachments || disabled || lockedByRun || isUploadingAttachments) return;
|
|
6643
6801
|
setContent("");
|
|
6644
6802
|
await onSend(trimmedContent);
|
|
6645
|
-
}, [content, hasAttachments, disabled,
|
|
6803
|
+
}, [content, hasAttachments, disabled, lockedByRun, isUploadingAttachments, onSend]);
|
|
6646
6804
|
const handleKeyDown = react.useCallback(
|
|
6647
6805
|
(e) => {
|
|
6648
6806
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
@@ -6658,7 +6816,7 @@ function ChatInput({
|
|
|
6658
6816
|
const handleAttachClick = react.useCallback(() => {
|
|
6659
6817
|
dropZoneRef?.current?.openFileDialog();
|
|
6660
6818
|
}, [dropZoneRef]);
|
|
6661
|
-
const canSend = (content.trim().length > 0 || hasAttachments) && !disabled && !
|
|
6819
|
+
const canSend = (content.trim().length > 0 || hasAttachments) && !disabled && !lockedByRun && !isUploadingAttachments;
|
|
6662
6820
|
const showStopButton = isLoading && onStop;
|
|
6663
6821
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6664
6822
|
"div",
|
|
@@ -6683,7 +6841,7 @@ function ChatInput({
|
|
|
6683
6841
|
{
|
|
6684
6842
|
type: "button",
|
|
6685
6843
|
onClick: handleAttachClick,
|
|
6686
|
-
disabled: disabled ||
|
|
6844
|
+
disabled: disabled || lockedByRun,
|
|
6687
6845
|
className: cn3(
|
|
6688
6846
|
"flex-shrink-0 p-3 rounded-lg transition-colors",
|
|
6689
6847
|
"text-gray-500 dark:text-gray-400",
|
|
@@ -9076,7 +9234,9 @@ function AgentChat({
|
|
|
9076
9234
|
hideTypingIndicator = false,
|
|
9077
9235
|
onInputChange,
|
|
9078
9236
|
onInputControlReady,
|
|
9079
|
-
injectedMessages
|
|
9237
|
+
injectedMessages,
|
|
9238
|
+
allowSendWhileRunning = false,
|
|
9239
|
+
onSteer
|
|
9080
9240
|
}) {
|
|
9081
9241
|
const {
|
|
9082
9242
|
messages,
|
|
@@ -9090,7 +9250,8 @@ function AgentChat({
|
|
|
9090
9250
|
respondToClarification,
|
|
9091
9251
|
cancel,
|
|
9092
9252
|
retry,
|
|
9093
|
-
clearError
|
|
9253
|
+
clearError,
|
|
9254
|
+
canSendWhileRunning
|
|
9094
9255
|
} = useAgentChat({
|
|
9095
9256
|
agentId,
|
|
9096
9257
|
teamId,
|
|
@@ -9106,7 +9267,9 @@ function AgentChat({
|
|
|
9106
9267
|
onClarification,
|
|
9107
9268
|
onDelegation,
|
|
9108
9269
|
pollingInterval,
|
|
9109
|
-
pollingEnabled
|
|
9270
|
+
pollingEnabled,
|
|
9271
|
+
allowSendWhileRunning,
|
|
9272
|
+
onSteer
|
|
9110
9273
|
});
|
|
9111
9274
|
const effectiveVerbosity = showToolCalls === false ? "hidden" : toolCallVerbosity ?? "compact";
|
|
9112
9275
|
const dropZoneRef = react.useRef(null);
|
|
@@ -9188,6 +9351,7 @@ function AgentChat({
|
|
|
9188
9351
|
placeholder,
|
|
9189
9352
|
disabled: !!clarification || isLoadingHistory,
|
|
9190
9353
|
isLoading,
|
|
9354
|
+
allowSendWhileRunning: canSendWhileRunning,
|
|
9191
9355
|
enableAttachments,
|
|
9192
9356
|
attachments: enableAttachments ? attachments.files : void 0,
|
|
9193
9357
|
onRemoveAttachment: enableAttachments ? attachments.removeFile : void 0,
|
|
@@ -9203,7 +9367,7 @@ function AgentChat({
|
|
|
9203
9367
|
{
|
|
9204
9368
|
ref: dropZoneRef,
|
|
9205
9369
|
...attachments.dropZoneProps,
|
|
9206
|
-
disabled: isLoading || !!clarification || isLoadingHistory,
|
|
9370
|
+
disabled: isLoading && !canSendWhileRunning || !!clarification || isLoadingHistory,
|
|
9207
9371
|
children: chatContent
|
|
9208
9372
|
}
|
|
9209
9373
|
) : chatContent });
|