@artooi/ag-ui-web-component 0.35.2 → 0.37.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/CHANGELOG.md +112 -1
- package/README.md +53 -5
- package/dist/ag-ui-web-component.bundle.js +37 -37
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +25 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/core/agui_client.d.ts +25 -1
- package/dist/core/agui_client.d.ts.map +1 -1
- package/dist/core/tool_outcome.d.ts +27 -0
- package/dist/core/tool_outcome.d.ts.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +174 -44
- package/dist/index.js.map +3 -3
- package/dist/ui/ui_strings.d.ts +4 -0
- package/dist/ui/ui_strings.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +26 -0
- package/src/core/ag_ui_chat.ts +148 -39
- package/src/core/agui_client.ts +105 -8
- package/src/core/tool_outcome.ts +36 -0
- package/src/index.ts +2 -0
- package/src/ui/ui_strings.ts +6 -0
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -41,6 +41,11 @@ var TOOL_CALL_STATUS = {
|
|
|
41
41
|
ERROR: "error",
|
|
42
42
|
DECLINED: "declined"
|
|
43
43
|
};
|
|
44
|
+
var TOOL_OUTCOME = {
|
|
45
|
+
SUCCESS: "success",
|
|
46
|
+
FAILED: "failed",
|
|
47
|
+
DENIED: "denied"
|
|
48
|
+
};
|
|
44
49
|
var ATTACHMENT_STATUS = {
|
|
45
50
|
UPLOADING: "uploading",
|
|
46
51
|
READY: "ready",
|
|
@@ -824,6 +829,8 @@ var DEFAULT_UI_STRINGS = {
|
|
|
824
829
|
runInterrupted: "The previous response didn\u2019t finish \u2014 the page changed before it arrived.",
|
|
825
830
|
pageMoved: "The page changed since you last looked at it. Call read_page to see the current page, then retry.",
|
|
826
831
|
attachmentsStillUploading: "{n} file still uploading \u2014 it was not sent with this message and is still attached.",
|
|
832
|
+
notConnected: "This chat isn\u2019t connected to an agent, so the message wasn\u2019t sent.",
|
|
833
|
+
continueNeedsTurn: "Type the next turn in the composer first, then pick a run to continue.",
|
|
827
834
|
skillNeeds: "\u201C{title}\u201D needs {fields} \u2014 fill it in below, then send.",
|
|
828
835
|
message: "Message",
|
|
829
836
|
inputPlaceholder: "Ask anything\u2026",
|
|
@@ -10779,6 +10786,25 @@ var AgUiClient = class {
|
|
|
10779
10786
|
* set would miss entirely.
|
|
10780
10787
|
*/
|
|
10781
10788
|
#closedMessageIds = /* @__PURE__ */ new Set();
|
|
10789
|
+
/**
|
|
10790
|
+
* How each tool call ended, keyed by call id, for the transcript this client
|
|
10791
|
+
* persists.
|
|
10792
|
+
*
|
|
10793
|
+
* A side table rather than a field written onto the message, because neither
|
|
10794
|
+
* producer of a tool message will carry it. `@ag-ui/client` builds the
|
|
10795
|
+
* server-side one by destructuring five named fields off the event, so an
|
|
10796
|
+
* `outcome` beside them is dropped before the message exists; and writing it
|
|
10797
|
+
* back onto that message afterwards would put it in `agent.messages`, which is
|
|
10798
|
+
* what the *next* request sends to the server. This keeps the annotation on
|
|
10799
|
+
* the copy handed to the store and off the wire.
|
|
10800
|
+
*
|
|
10801
|
+
* Per client, not per run: `saveMessages` rewrites the whole transcript on
|
|
10802
|
+
* every persist, so an outcome recorded in round one has to still be here in
|
|
10803
|
+
* round five or the earlier card silently reverts to a green one. Bounded by
|
|
10804
|
+
* the number of tool calls in the conversation, which the transcript beside it
|
|
10805
|
+
* already is.
|
|
10806
|
+
*/
|
|
10807
|
+
#outcomes = /* @__PURE__ */ new Map();
|
|
10782
10808
|
#connectionLostMessage;
|
|
10783
10809
|
#maxToolRounds;
|
|
10784
10810
|
// Set by cancel(); reset at the top of each #run(). Checked by the loop so
|
|
@@ -10839,7 +10865,7 @@ var AgUiClient = class {
|
|
|
10839
10865
|
message.attachments = attachments;
|
|
10840
10866
|
}
|
|
10841
10867
|
this.#agent.addMessage(message);
|
|
10842
|
-
this.#
|
|
10868
|
+
this.#persist();
|
|
10843
10869
|
await this.#run();
|
|
10844
10870
|
}
|
|
10845
10871
|
/**
|
|
@@ -10874,7 +10900,7 @@ var AgUiClient = class {
|
|
|
10874
10900
|
}
|
|
10875
10901
|
const kept = messages.slice(0, lastUser + 1);
|
|
10876
10902
|
this.#agent.setMessages(kept);
|
|
10877
|
-
this.#
|
|
10903
|
+
this.#persist();
|
|
10878
10904
|
return kept;
|
|
10879
10905
|
}
|
|
10880
10906
|
/**
|
|
@@ -10888,7 +10914,7 @@ var AgUiClient = class {
|
|
|
10888
10914
|
/** Append a frontend tool result to history (used by the resume path). */
|
|
10889
10915
|
addToolResult(toolCallId, content) {
|
|
10890
10916
|
this.#agent.addMessage({ id: randomUUID2(), role: "tool", content, toolCallId });
|
|
10891
|
-
this.#
|
|
10917
|
+
this.#persist();
|
|
10892
10918
|
}
|
|
10893
10919
|
/**
|
|
10894
10920
|
* Cancel the in-flight run (AG-UI has no server cancel route — aborting the
|
|
@@ -10919,9 +10945,33 @@ var AgUiClient = class {
|
|
|
10919
10945
|
}
|
|
10920
10946
|
}
|
|
10921
10947
|
#onCancelled() {
|
|
10922
|
-
this.#
|
|
10948
|
+
this.#persist();
|
|
10923
10949
|
this.#handlers.onCancelled();
|
|
10924
10950
|
}
|
|
10951
|
+
/**
|
|
10952
|
+
* Hand the transcript to the host's store, annotated with what {@link #outcomes}
|
|
10953
|
+
* knows about how each tool call ended.
|
|
10954
|
+
*
|
|
10955
|
+
* Every persist in this class goes through here, because the store keeps only
|
|
10956
|
+
* the most recent list: annotating one call site would mean the next
|
|
10957
|
+
* unannotated save quietly threw the annotations away.
|
|
10958
|
+
*/
|
|
10959
|
+
#persist() {
|
|
10960
|
+
const messages = this.#agent.messages;
|
|
10961
|
+
if (this.#outcomes.size === 0) {
|
|
10962
|
+
this.#onPersist(messages);
|
|
10963
|
+
return;
|
|
10964
|
+
}
|
|
10965
|
+
this.#onPersist(
|
|
10966
|
+
messages.map((message) => {
|
|
10967
|
+
if (message.role !== "tool") {
|
|
10968
|
+
return message;
|
|
10969
|
+
}
|
|
10970
|
+
const outcome = this.#outcomes.get(message.toolCallId);
|
|
10971
|
+
return outcome === void 0 ? message : { ...message, outcome };
|
|
10972
|
+
})
|
|
10973
|
+
);
|
|
10974
|
+
}
|
|
10925
10975
|
async #runLoop() {
|
|
10926
10976
|
let resume;
|
|
10927
10977
|
for (let round = 0; round < this.#maxToolRounds; round += 1) {
|
|
@@ -10939,7 +10989,7 @@ var AgUiClient = class {
|
|
|
10939
10989
|
}
|
|
10940
10990
|
await this.#agent.runAgent(params, this.#buildSubscriber(pending, runState));
|
|
10941
10991
|
resume = void 0;
|
|
10942
|
-
this.#
|
|
10992
|
+
this.#persist();
|
|
10943
10993
|
if (this.#cancelled) {
|
|
10944
10994
|
return;
|
|
10945
10995
|
}
|
|
@@ -10972,13 +11022,16 @@ var AgUiClient = class {
|
|
|
10972
11022
|
if (result.halt === true) {
|
|
10973
11023
|
return;
|
|
10974
11024
|
}
|
|
11025
|
+
if (result.outcome !== void 0) {
|
|
11026
|
+
this.#outcomes.set(call.id, result.outcome);
|
|
11027
|
+
}
|
|
10975
11028
|
this.#agent.addMessage({
|
|
10976
11029
|
id: randomUUID2(),
|
|
10977
11030
|
role: "tool",
|
|
10978
11031
|
content: result.content,
|
|
10979
11032
|
toolCallId: call.id
|
|
10980
11033
|
});
|
|
10981
|
-
this.#
|
|
11034
|
+
this.#persist();
|
|
10982
11035
|
executed = true;
|
|
10983
11036
|
}
|
|
10984
11037
|
if (!executed) {
|
|
@@ -10989,6 +11042,7 @@ var AgUiClient = class {
|
|
|
10989
11042
|
#buildSubscriber(pending, runState) {
|
|
10990
11043
|
const h = this.#handlers;
|
|
10991
11044
|
const closed = this.#closedMessageIds;
|
|
11045
|
+
const outcomes = this.#outcomes;
|
|
10992
11046
|
const cancelled = () => this.#cancelled;
|
|
10993
11047
|
const pendingDeltas = /* @__PURE__ */ new Set();
|
|
10994
11048
|
return {
|
|
@@ -11019,7 +11073,11 @@ var AgUiClient = class {
|
|
|
11019
11073
|
h.onToolCall(call);
|
|
11020
11074
|
},
|
|
11021
11075
|
onToolCallResultEvent({ event }) {
|
|
11022
|
-
|
|
11076
|
+
const outcome = event["outcome"];
|
|
11077
|
+
if (typeof outcome === "string") {
|
|
11078
|
+
outcomes.set(event.toolCallId, outcome);
|
|
11079
|
+
}
|
|
11080
|
+
h.onToolResult(event.toolCallId, event.content, outcome);
|
|
11023
11081
|
},
|
|
11024
11082
|
onActivitySnapshotEvent({ event, messages }) {
|
|
11025
11083
|
const known = messages.some(
|
|
@@ -11644,6 +11702,17 @@ var RunIndex = class {
|
|
|
11644
11702
|
}
|
|
11645
11703
|
};
|
|
11646
11704
|
|
|
11705
|
+
// src/core/tool_outcome.ts
|
|
11706
|
+
function toolStatusFromOutcome(outcome) {
|
|
11707
|
+
if (outcome === TOOL_OUTCOME.FAILED) {
|
|
11708
|
+
return TOOL_CALL_STATUS.ERROR;
|
|
11709
|
+
}
|
|
11710
|
+
if (outcome === TOOL_OUTCOME.DENIED) {
|
|
11711
|
+
return TOOL_CALL_STATUS.DECLINED;
|
|
11712
|
+
}
|
|
11713
|
+
return TOOL_CALL_STATUS.DONE;
|
|
11714
|
+
}
|
|
11715
|
+
|
|
11647
11716
|
// src/core/transcribe_audio.ts
|
|
11648
11717
|
async function transcribeAudio(audio, options) {
|
|
11649
11718
|
const form = new FormData();
|
|
@@ -12187,7 +12256,17 @@ var AgUiChat = class extends HTMLElement {
|
|
|
12187
12256
|
#checkpoints;
|
|
12188
12257
|
/** Built lazily from `data-runs-url`; `null` when the host didn't opt in. */
|
|
12189
12258
|
#runIndex = null;
|
|
12190
|
-
|
|
12259
|
+
/**
|
|
12260
|
+
* The one-line hint above the composer, cleared by the next keystroke.
|
|
12261
|
+
*
|
|
12262
|
+
* Two things write it -- a skill whose template is short of a field, and a
|
|
12263
|
+
* run continuation picked with nothing typed -- and both say the same kind of
|
|
12264
|
+
* thing: what the composer still needs before this can go. Its `part` stays
|
|
12265
|
+
* `skill-hint`, which the skills feature named and the README documents;
|
|
12266
|
+
* renaming a part is breaking, and a second hint element in the same slot
|
|
12267
|
+
* would be worse than one whose name is a release older than its job.
|
|
12268
|
+
*/
|
|
12269
|
+
#composerHint;
|
|
12191
12270
|
/** File-picker button + hidden input + tray slot; the tray mounts on connect. */
|
|
12192
12271
|
#attachButton;
|
|
12193
12272
|
#fileInput;
|
|
@@ -12377,7 +12456,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
12377
12456
|
this.#input = document.createElement("textarea");
|
|
12378
12457
|
this.#send = document.createElement("button");
|
|
12379
12458
|
this.#title = document.createElement("span");
|
|
12380
|
-
this.#
|
|
12459
|
+
this.#composerHint = document.createElement("div");
|
|
12381
12460
|
this.#attachButton = document.createElement("button");
|
|
12382
12461
|
this.#fileInput = document.createElement("input");
|
|
12383
12462
|
this.#attachSlot = document.createElement("div");
|
|
@@ -12461,6 +12540,9 @@ var AgUiChat = class extends HTMLElement {
|
|
|
12461
12540
|
}
|
|
12462
12541
|
const content = this.#input.value.trim();
|
|
12463
12542
|
if (content === "") {
|
|
12543
|
+
this.#composerHint.textContent = this.#strings.continueNeedsTurn;
|
|
12544
|
+
this.#composerHint.hidden = false;
|
|
12545
|
+
this.#input.focus();
|
|
12464
12546
|
return;
|
|
12465
12547
|
}
|
|
12466
12548
|
this.#input.value = "";
|
|
@@ -12983,20 +13065,37 @@ var AgUiChat = class extends HTMLElement {
|
|
|
12983
13065
|
const value = this.getAttribute(name);
|
|
12984
13066
|
return value !== null && value !== "false";
|
|
12985
13067
|
}
|
|
12986
|
-
/**
|
|
12987
|
-
|
|
12988
|
-
|
|
13068
|
+
/**
|
|
13069
|
+
* Parse a JSON-valued attribute, saying so when it will not parse.
|
|
13070
|
+
*
|
|
13071
|
+
* `null` for an absent attribute, and `null` again for one that is not JSON --
|
|
13072
|
+
* but not quietly the second time. Quoting JSON inside an HTML attribute is
|
|
13073
|
+
* fiddly, and the result of getting it wrong is indistinguishable from the
|
|
13074
|
+
* feature being switched off: no chips appear, or the strings stay English,
|
|
13075
|
+
* with nothing anywhere saying why. That is the same failure `data-paste-attach`
|
|
13076
|
+
* already reports for a value it cannot read.
|
|
13077
|
+
*
|
|
13078
|
+
* Console only. A page author's typo is not the reader's business, nothing the
|
|
13079
|
+
* reader did was refused, and the degraded widget is still perfectly usable.
|
|
13080
|
+
*/
|
|
13081
|
+
#readJsonAttribute(name) {
|
|
13082
|
+
const raw = this.getAttribute(name);
|
|
12989
13083
|
if (raw === null) {
|
|
12990
|
-
return
|
|
13084
|
+
return null;
|
|
12991
13085
|
}
|
|
12992
13086
|
try {
|
|
12993
|
-
|
|
12994
|
-
if (typeof parsed === "object" && parsed !== null) {
|
|
12995
|
-
return parsed;
|
|
12996
|
-
}
|
|
13087
|
+
return JSON.parse(raw);
|
|
12997
13088
|
} catch {
|
|
13089
|
+
console.warn(
|
|
13090
|
+
`<ag-ui-chat>: ${name} is not valid JSON, so it was ignored entirely and the built-in default is being used. Check the quoting -- JSON inside an HTML attribute needs single quotes around the attribute value, or its own double quotes escaped.`
|
|
13091
|
+
);
|
|
13092
|
+
return null;
|
|
12998
13093
|
}
|
|
12999
|
-
|
|
13094
|
+
}
|
|
13095
|
+
/** Parse the inline `data-strings` JSON overrides (empty when absent/malformed). */
|
|
13096
|
+
#readStringOverrides() {
|
|
13097
|
+
const parsed = this.#readJsonAttribute("data-strings");
|
|
13098
|
+
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
13000
13099
|
}
|
|
13001
13100
|
/**
|
|
13002
13101
|
* Enable the composer's file-upload tray when uploads are possible — either a
|
|
@@ -13407,15 +13506,7 @@ ${quoted}`;
|
|
|
13407
13506
|
}
|
|
13408
13507
|
/** Parse the inline `data-skills` JSON catalog (empty when absent/malformed). */
|
|
13409
13508
|
#readEmbeddedSkills() {
|
|
13410
|
-
|
|
13411
|
-
if (raw === null) {
|
|
13412
|
-
return [];
|
|
13413
|
-
}
|
|
13414
|
-
try {
|
|
13415
|
-
return parseSkills(JSON.parse(raw));
|
|
13416
|
-
} catch {
|
|
13417
|
-
return [];
|
|
13418
|
-
}
|
|
13509
|
+
return parseSkills(this.#readJsonAttribute("data-skills"));
|
|
13419
13510
|
}
|
|
13420
13511
|
/** Fetch the backend skills catalog from `data-skills-url`, if set. */
|
|
13421
13512
|
async #fetchSkills() {
|
|
@@ -13454,21 +13545,21 @@ ${quoted}`;
|
|
|
13454
13545
|
*/
|
|
13455
13546
|
#applySkill(skill) {
|
|
13456
13547
|
if (skill.prompt === void 0) {
|
|
13457
|
-
this.#
|
|
13548
|
+
this.#composerHint.hidden = true;
|
|
13458
13549
|
void this.sendMessage(`/${skill.name}`);
|
|
13459
13550
|
return;
|
|
13460
13551
|
}
|
|
13461
13552
|
const { text: text4, missing } = fillTemplate(skill.prompt, this.skillContext());
|
|
13462
13553
|
if (missing.length > 0) {
|
|
13463
|
-
this.#
|
|
13464
|
-
this.#
|
|
13554
|
+
this.#composerHint.textContent = this.#strings.skillNeeds.replace("{title}", skill.title).replace("{fields}", missing.join(", "));
|
|
13555
|
+
this.#composerHint.hidden = false;
|
|
13465
13556
|
this.#input.value = text4;
|
|
13466
13557
|
this.#autoGrow();
|
|
13467
13558
|
this.#input.focus();
|
|
13468
13559
|
this.#selectFirstPlaceholder(text4);
|
|
13469
13560
|
return;
|
|
13470
13561
|
}
|
|
13471
|
-
this.#
|
|
13562
|
+
this.#composerHint.hidden = true;
|
|
13472
13563
|
this.#input.value = text4;
|
|
13473
13564
|
this.#autoGrow();
|
|
13474
13565
|
if (skill.sendImmediately === false) {
|
|
@@ -14770,7 +14861,10 @@ ${quoted}`;
|
|
|
14770
14861
|
if (message.role === "tool") {
|
|
14771
14862
|
const card = this.#toolCards.get(message.toolCallId);
|
|
14772
14863
|
if (card !== void 0) {
|
|
14773
|
-
card.settle(
|
|
14864
|
+
card.settle(
|
|
14865
|
+
toolStatusFromOutcome(message.outcome),
|
|
14866
|
+
message.content
|
|
14867
|
+
);
|
|
14774
14868
|
}
|
|
14775
14869
|
}
|
|
14776
14870
|
}
|
|
@@ -14988,9 +15082,9 @@ ${quoted}`;
|
|
|
14988
15082
|
}
|
|
14989
15083
|
void this.#submit();
|
|
14990
15084
|
});
|
|
14991
|
-
this.#
|
|
14992
|
-
this.#
|
|
14993
|
-
this.#
|
|
15085
|
+
this.#composerHint.className = "skill-hint";
|
|
15086
|
+
this.#composerHint.setAttribute("part", "skill-hint");
|
|
15087
|
+
this.#composerHint.hidden = true;
|
|
14994
15088
|
this.#attachButton.className = "attach-btn";
|
|
14995
15089
|
this.#attachButton.type = "button";
|
|
14996
15090
|
this.#attachButton.setAttribute("part", "attach-button");
|
|
@@ -15018,7 +15112,7 @@ ${quoted}`;
|
|
|
15018
15112
|
this.#messagesWrap,
|
|
15019
15113
|
this.#skillsMenu.palette,
|
|
15020
15114
|
this.#skillsMenu.chips,
|
|
15021
|
-
this.#
|
|
15115
|
+
this.#composerHint,
|
|
15022
15116
|
this.#queuedRow,
|
|
15023
15117
|
this.#attachSlot,
|
|
15024
15118
|
inputRow,
|
|
@@ -15291,10 +15385,16 @@ ${quoted}`;
|
|
|
15291
15385
|
#updateEmptyState() {
|
|
15292
15386
|
this.#emptyWrap.hidden = this.#messages.childElementCount > 1;
|
|
15293
15387
|
}
|
|
15294
|
-
/**
|
|
15388
|
+
/**
|
|
15389
|
+
* Forward input changes to the skills palette and clear any stale hint.
|
|
15390
|
+
*
|
|
15391
|
+
* Typing is the answer to every hint that surface carries -- a skill short of
|
|
15392
|
+
* a field, a continuation short of its next turn -- so the keystroke that
|
|
15393
|
+
* starts answering it is the right moment to take it down.
|
|
15394
|
+
*/
|
|
15295
15395
|
#onInput() {
|
|
15296
15396
|
this.#skillsMenu.onInput(this.#input.value);
|
|
15297
|
-
this.#
|
|
15397
|
+
this.#composerHint.hidden = true;
|
|
15298
15398
|
this.#autoGrow();
|
|
15299
15399
|
this.#recallIndex = null;
|
|
15300
15400
|
}
|
|
@@ -15531,8 +15631,36 @@ ${quoted}`;
|
|
|
15531
15631
|
})
|
|
15532
15632
|
);
|
|
15533
15633
|
}
|
|
15634
|
+
/**
|
|
15635
|
+
* Hand the message to the client, or say why it is going nowhere.
|
|
15636
|
+
*
|
|
15637
|
+
* With no `endpoint` there is nothing to send to, and this used to return
|
|
15638
|
+
* here in silence. That is the worst shape the failure can take, because the
|
|
15639
|
+
* two halves of a send that *did* work have already happened by now: the
|
|
15640
|
+
* user's bubble is on screen and {@link SUBMIT_EVENT} has been dispatched. So
|
|
15641
|
+
* the message looks sent, the composer is empty, the Send button never turns
|
|
15642
|
+
* into Stop, and no request is ever made -- an unanswered question rather
|
|
15643
|
+
* than a broken widget. Nothing reached the console either, so the developer
|
|
15644
|
+
* had no thread to pull and the user had no reason to think anything was
|
|
15645
|
+
* wrong with the page.
|
|
15646
|
+
*
|
|
15647
|
+
* Both audiences are told, because they need different things. The console
|
|
15648
|
+
* carries the developer's version -- the attribute is missing, here is what
|
|
15649
|
+
* to set -- since a missing attribute is a page's mistake and not the
|
|
15650
|
+
* reader's. The transcript carries the reader's, because they are looking at
|
|
15651
|
+
* their own message waiting for a reply that cannot come, and the honest
|
|
15652
|
+
* alternative to one muted line is an indefinite wait.
|
|
15653
|
+
*
|
|
15654
|
+
* Said on every attempt rather than once. Each send is a separate thing the
|
|
15655
|
+
* user asked for and did not get, and a once-only report is silence for every
|
|
15656
|
+
* attempt after the first -- which is the defect again, just later.
|
|
15657
|
+
*/
|
|
15534
15658
|
async #client_send(content, attachments) {
|
|
15535
15659
|
if (this.endpoint === "") {
|
|
15660
|
+
console.error(
|
|
15661
|
+
'<ag-ui-chat>: no endpoint is set, so this message was not sent and no request was made. Point the element at your AG-UI mount with the endpoint attribute (endpoint="/agent/"), or assign chat.endpoint before sending.'
|
|
15662
|
+
);
|
|
15663
|
+
this.#appendNotice("\u26A0", this.#strings.notConnected, "not-connected");
|
|
15536
15664
|
return;
|
|
15537
15665
|
}
|
|
15538
15666
|
await this.#ensureClient().send(content, attachments);
|
|
@@ -15674,7 +15802,7 @@ ${quoted}`;
|
|
|
15674
15802
|
const message = this.#strings.pageMoved;
|
|
15675
15803
|
card.settle(TOOL_CALL_STATUS.ERROR, message);
|
|
15676
15804
|
this.#showPending();
|
|
15677
|
-
return { content: `Error: ${message}`, error: message };
|
|
15805
|
+
return { content: `Error: ${message}`, error: message, outcome: TOOL_OUTCOME.FAILED };
|
|
15678
15806
|
}
|
|
15679
15807
|
const rule = await this.#confirmationRule(call, tool);
|
|
15680
15808
|
if (rule !== null) {
|
|
@@ -15699,7 +15827,7 @@ ${quoted}`;
|
|
|
15699
15827
|
const message = this.#strings.declinedAction;
|
|
15700
15828
|
card.settle(TOOL_CALL_STATUS.DECLINED, message);
|
|
15701
15829
|
this.#showPending();
|
|
15702
|
-
return { content: message };
|
|
15830
|
+
return { content: message, outcome: TOOL_OUTCOME.DENIED };
|
|
15703
15831
|
}
|
|
15704
15832
|
}
|
|
15705
15833
|
const navigates = isNavigates(tool.parameters) && this.navigate === null;
|
|
@@ -15726,7 +15854,7 @@ ${quoted}`;
|
|
|
15726
15854
|
const message = error instanceof Error ? error.message : String(error);
|
|
15727
15855
|
card.settle(TOOL_CALL_STATUS.ERROR, message);
|
|
15728
15856
|
this.#showPending();
|
|
15729
|
-
return { content: `Error: ${message}`, error: message };
|
|
15857
|
+
return { content: `Error: ${message}`, error: message, outcome: TOOL_OUTCOME.FAILED };
|
|
15730
15858
|
}
|
|
15731
15859
|
}
|
|
15732
15860
|
/**
|
|
@@ -15898,12 +16026,12 @@ ${quoted}`;
|
|
|
15898
16026
|
onMessagesSnapshot: () => {
|
|
15899
16027
|
this.#appendNotice("\u{1F504}", this.#strings.historyReplaced, "history-replaced");
|
|
15900
16028
|
},
|
|
15901
|
-
onToolResult: (toolCallId, content) => {
|
|
16029
|
+
onToolResult: (toolCallId, content, outcome) => {
|
|
15902
16030
|
const card = this.#toolCards.get(toolCallId);
|
|
15903
16031
|
if (card === void 0) {
|
|
15904
16032
|
return;
|
|
15905
16033
|
}
|
|
15906
|
-
card.settle(
|
|
16034
|
+
card.settle(toolStatusFromOutcome(outcome), content);
|
|
15907
16035
|
this.#serverSettled.add(toolCallId);
|
|
15908
16036
|
this.#showPending();
|
|
15909
16037
|
},
|
|
@@ -16539,7 +16667,7 @@ function setControlValue(el2, value) {
|
|
|
16539
16667
|
}
|
|
16540
16668
|
|
|
16541
16669
|
// src/version.ts
|
|
16542
|
-
var VERSION = "0.
|
|
16670
|
+
var VERSION = "0.37.0";
|
|
16543
16671
|
export {
|
|
16544
16672
|
ATTACHMENT_EVENT,
|
|
16545
16673
|
AgUiChat,
|
|
@@ -16575,6 +16703,7 @@ export {
|
|
|
16575
16703
|
TOGGLE_EVENT,
|
|
16576
16704
|
TOOL_CALL_STATUS,
|
|
16577
16705
|
TOOL_DISPLAY,
|
|
16706
|
+
TOOL_OUTCOME,
|
|
16578
16707
|
ToolCallCard,
|
|
16579
16708
|
UNREAD_EVENT,
|
|
16580
16709
|
VERSION,
|
|
@@ -16628,6 +16757,7 @@ export {
|
|
|
16628
16757
|
suggestionPrompts,
|
|
16629
16758
|
toggleCheckbox,
|
|
16630
16759
|
toggleControl,
|
|
16760
|
+
toolStatusFromOutcome,
|
|
16631
16761
|
transcribeAudio,
|
|
16632
16762
|
typeInto,
|
|
16633
16763
|
uploadAttachment
|