@teaflask/assistant 0.9.0 → 0.10.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/dist/components/teaflask-assistant-provider.d.ts +4 -3
- package/dist/contract/telemetry.d.ts +23 -2
- package/dist/core/assistant-session-registry.js +10 -0
- package/dist/core/connection-epoch.d.ts +3 -0
- package/dist/core/connection-epoch.js +18 -1
- package/dist/core/conversation-adoption.js +7 -0
- package/dist/core/conversation-contract.d.ts +1 -0
- package/dist/core/epoch-sync.js +2 -0
- package/dist/core/turn-failed-anchors.d.ts +7 -0
- package/dist/core/turn-failed-anchors.js +42 -0
- package/dist/generated/models/failureReasonCode.d.ts +33 -0
- package/dist/generated/models/failureReasonCode.js +10 -0
- package/dist/generated/models/index.d.ts +1 -0
- package/dist/generated/models/index.js +1 -0
- package/dist/generated/models/turnFailedMarker.d.ts +3 -0
- package/dist/headless.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/transport/stream-resume.d.ts +2 -0
- package/dist/transport/stream-resume.js +8 -0
- package/package.json +1 -1
|
@@ -86,9 +86,10 @@ export interface TeaflaskAssistantProviderBaseProps {
|
|
|
86
86
|
*/
|
|
87
87
|
onError?: (error: Error) => void;
|
|
88
88
|
/**
|
|
89
|
-
* Called with product analytics events (approval submits
|
|
90
|
-
*
|
|
91
|
-
* error goes to `onError`.
|
|
89
|
+
* Called with product analytics events (approval submits, stream failures
|
|
90
|
+
* and failed replies) that you can forward to your own analytics. If it
|
|
91
|
+
* throws, the error goes to `onError`. Without it, each failed reply writes
|
|
92
|
+
* one console warning with its reason code instead.
|
|
92
93
|
*/
|
|
93
94
|
onTelemetry?: (event: AssistantTelemetryEvent) => void;
|
|
94
95
|
/**
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export type { FailureReasonCode } from "../generated/models/index.js";
|
|
2
|
+
import type { FailureReasonCode } from "../generated/models/index.js";
|
|
1
3
|
/**
|
|
2
4
|
* Why clicking approve or deny sent nothing. "no_active_thread" means no
|
|
3
5
|
* conversation was open; "card_missing" means the request was no longer shown;
|
|
@@ -64,12 +66,31 @@ export interface StreamFailedTelemetryEvent {
|
|
|
64
66
|
last_committed_sse_id: string | null;
|
|
65
67
|
};
|
|
66
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Reported to onTelemetry when a reply fails while the user is watching. The
|
|
71
|
+
* user sees one general sentence, so this event's reason_code is how your page
|
|
72
|
+
* learns why; log it and never show it. Failures replayed when a conversation
|
|
73
|
+
* reopens are not reported again.
|
|
74
|
+
*/
|
|
75
|
+
export interface TurnFailedTelemetryEvent {
|
|
76
|
+
/** Always "turn_failed". */
|
|
77
|
+
name: "turn_failed";
|
|
78
|
+
/**
|
|
79
|
+
* The conversation's thread_id, the failed reply's turn_id, and its
|
|
80
|
+
* reason_code, the same code the stream's turn_failed event carries as
|
|
81
|
+
* reasonCode.
|
|
82
|
+
*/
|
|
83
|
+
properties: {
|
|
84
|
+
thread_id: string;
|
|
85
|
+
turn_id: string;
|
|
86
|
+
reason_code: FailureReasonCode;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
67
89
|
/**
|
|
68
90
|
* Any event passed to the provider's onTelemetry callback, for forwarding to
|
|
69
91
|
* your own analytics. None carry message text, tool arguments or prompts.
|
|
70
92
|
*/
|
|
71
|
-
export type AssistantTelemetryEvent = ApprovalSubmitTelemetryEvent | StreamFailedTelemetryEvent;
|
|
93
|
+
export type AssistantTelemetryEvent = ApprovalSubmitTelemetryEvent | StreamFailedTelemetryEvent | TurnFailedTelemetryEvent;
|
|
72
94
|
export declare function streamFailureClassOf(error: Error, context: {
|
|
73
95
|
sawBodyBytes: boolean;
|
|
74
96
|
}): StreamFailureClass;
|
|
75
|
-
export {};
|
|
@@ -167,6 +167,7 @@ class SessionEntry {
|
|
|
167
167
|
this._reportToEveryRegistrant(error);
|
|
168
168
|
},
|
|
169
169
|
onTelemetry: (event) => {
|
|
170
|
+
this._warnOfAFailureNoHostLogs(event);
|
|
170
171
|
for (const registration of [...this.registrations]) {
|
|
171
172
|
try {
|
|
172
173
|
registration.registrant.onTelemetry?.(event);
|
|
@@ -230,6 +231,15 @@ class SessionEntry {
|
|
|
230
231
|
}
|
|
231
232
|
return merged;
|
|
232
233
|
}
|
|
234
|
+
_warnOfAFailureNoHostLogs(event) {
|
|
235
|
+
if (event.name !== "turn_failed" || this._someRegistrantLogsTelemetry()) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
console.warn("[teaflask] reply failed:", event.properties.reason_code, event.properties.turn_id);
|
|
239
|
+
}
|
|
240
|
+
_someRegistrantLogsTelemetry() {
|
|
241
|
+
return [...this.registrations].some((registration) => registration.registrant.onTelemetry !== null);
|
|
242
|
+
}
|
|
233
243
|
_reportToEveryRegistrant(error) {
|
|
234
244
|
for (const registration of [...this.registrations]) {
|
|
235
245
|
try {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Message } from "@ag-ui/core";
|
|
2
|
+
import type { AssistantTelemetryEvent } from "../contract/telemetry.js";
|
|
2
3
|
import { ServingReplayStreamAgent } from "../transport/replay-stream-agent.js";
|
|
3
4
|
import { type StreamResumeStore } from "../transport/stream-resume.js";
|
|
4
5
|
import type { TokenSession } from "../transport/token-session.js";
|
|
@@ -109,6 +110,8 @@ export interface ConnectionEpochDeps {
|
|
|
109
110
|
onRunSettled: () => void;
|
|
110
111
|
onQuietClose: (stillStreaming: () => boolean) => void;
|
|
111
112
|
onWorkflowRestarted: () => void;
|
|
113
|
+
onTelemetry: (event: AssistantTelemetryEvent) => void;
|
|
114
|
+
settledFailedTurnId: string | null;
|
|
112
115
|
}
|
|
113
116
|
export interface ConnectionEpoch {
|
|
114
117
|
epochId: number;
|
|
@@ -15,7 +15,7 @@ import { toolErrorRecorder, wellFormedToolErrorAnchorsOf, } from "./tool-error-a
|
|
|
15
15
|
import { toolDecisionRecorder, wellFormedToolDecisionAnchorsOf, } from "./tool-decision-anchors.js";
|
|
16
16
|
import { toolDenialRecorder, wellFormedToolDenialAnchorsOf, } from "./tool-denial-anchors.js";
|
|
17
17
|
import { toolRefusalRecorder, wellFormedToolRefusalAnchorsOf, } from "./tool-refusal-anchors.js";
|
|
18
|
-
import { turnFailedMarkerRecorder, wellFormedFailAnchorsOf, } from "./turn-failed-anchors.js";
|
|
18
|
+
import { failedTurnRecorder, turnFailedMarkerRecorder, wellFormedFailAnchorsOf, } from "./turn-failed-anchors.js";
|
|
19
19
|
import { turnUsageRecorder, wellFormedTurnUsageAnchorsOf, } from "./turn-usage-anchors.js";
|
|
20
20
|
import { messagesRecorder, streamErrorRecorder } from "./messages-cell.js";
|
|
21
21
|
import { withdrawnReplyRecorder, withoutWithdrawnReplies, } from "./withdrawn-anchors.js";
|
|
@@ -110,6 +110,19 @@ function _runMarkerSubscriptionsOf(agent, deps) {
|
|
|
110
110
|
deps.publishMarkerAnchors();
|
|
111
111
|
}
|
|
112
112
|
})),
|
|
113
|
+
agent.subscribe(failedTurnRecorder((failed) => {
|
|
114
|
+
if (!_isNewsToTheHost(failed, deps)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
deps.onTelemetry({
|
|
118
|
+
name: "turn_failed",
|
|
119
|
+
properties: {
|
|
120
|
+
thread_id: deps.threadId,
|
|
121
|
+
turn_id: failed.turnId,
|
|
122
|
+
reason_code: failed.reasonCode,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
})),
|
|
113
126
|
agent.subscribe(subagentDeliveryMarkerRecorder((deliveryRunId, messageId, results) => {
|
|
114
127
|
if (deps.resume.recordSubagentDelivery(deliveryRunId, messageId, results)) {
|
|
115
128
|
deps.publishMarkerAnchors();
|
|
@@ -124,6 +137,10 @@ function _runMarkerSubscriptionsOf(agent, deps) {
|
|
|
124
137
|
})),
|
|
125
138
|
];
|
|
126
139
|
}
|
|
140
|
+
function _isNewsToTheHost(failed, deps) {
|
|
141
|
+
return (failed.turnId !== deps.settledFailedTurnId &&
|
|
142
|
+
deps.resume.recordFailedTurnReported(failed.turnId));
|
|
143
|
+
}
|
|
127
144
|
function _visibleAnchorOf(messageId, agent, deps) {
|
|
128
145
|
const visible = _visibleMessagesOf(agent, deps);
|
|
129
146
|
if (visible.some((message) => message.id === messageId)) {
|
|
@@ -117,6 +117,7 @@ function _finishAdoption(store, detail) {
|
|
|
117
117
|
resume,
|
|
118
118
|
approvalInbox,
|
|
119
119
|
coworkerRequestTurns: detail.turns,
|
|
120
|
+
settledFailedTurnId: _settledFailedTurnIdOf(detail.turns),
|
|
120
121
|
};
|
|
121
122
|
if (!continuing) {
|
|
122
123
|
store.questionDrafts.clearAll();
|
|
@@ -152,6 +153,10 @@ function adoptCoworkerRequests(store, turns) {
|
|
|
152
153
|
publishApprovalCards(store, active.approvalInbox.cards());
|
|
153
154
|
}
|
|
154
155
|
}
|
|
156
|
+
function _settledFailedTurnIdOf(turns) {
|
|
157
|
+
const newest = turns.at(-1);
|
|
158
|
+
return newest?.status === "failed" ? newest.id : null;
|
|
159
|
+
}
|
|
155
160
|
export function adoptRefreshedDetail(store, detail) {
|
|
156
161
|
const active = store._active;
|
|
157
162
|
if (active?.thread.id !== detail.thread.id) {
|
|
@@ -168,6 +173,7 @@ export function adoptRefreshedDetail(store, detail) {
|
|
|
168
173
|
resume: active.resume,
|
|
169
174
|
approvalInbox: active.approvalInbox,
|
|
170
175
|
coworkerRequestTurns: active.coworkerRequestTurns,
|
|
176
|
+
settledFailedTurnId: active.settledFailedTurnId,
|
|
171
177
|
};
|
|
172
178
|
}
|
|
173
179
|
_adoptWireModelPick(store, detail.thread, { evenWhenDirty: false });
|
|
@@ -217,6 +223,7 @@ export function enterConversationFromSend(store, thread, turn, sentPick) {
|
|
|
217
223
|
resume,
|
|
218
224
|
approvalInbox,
|
|
219
225
|
coworkerRequestTurns: [],
|
|
226
|
+
settledFailedTurnId: null,
|
|
220
227
|
};
|
|
221
228
|
if (sameModelPick(store._modelPick, sentPick)) {
|
|
222
229
|
_adoptWireModelPick(store, thread, { evenWhenDirty: true });
|
|
@@ -17,6 +17,7 @@ export interface ActiveConversation {
|
|
|
17
17
|
resume: StreamResumeStore;
|
|
18
18
|
approvalInbox: ApprovalInbox;
|
|
19
19
|
coworkerRequestTurns: readonly ServingAssistantTurn[];
|
|
20
|
+
settledFailedTurnId: string | null;
|
|
20
21
|
}
|
|
21
22
|
/**
|
|
22
23
|
* State and controls for writing and sending messages in the open conversation,
|
package/dist/core/epoch-sync.js
CHANGED
|
@@ -89,6 +89,8 @@ function _mintEpochDeps(store, active, epochId) {
|
|
|
89
89
|
onRunSettled: store.handleRunSettled,
|
|
90
90
|
onQuietClose: store.handleStreamClosedQuietly,
|
|
91
91
|
onWorkflowRestarted: store.handleWorkflowRestarted,
|
|
92
|
+
onTelemetry: store.deps.onTelemetry,
|
|
93
|
+
settledFailedTurnId: active.settledFailedTurnId,
|
|
92
94
|
};
|
|
93
95
|
}
|
|
94
96
|
export function retireEpoch(store) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { receiptOf, wellFormedReceiptAnchorsOf, withReceiptAnchored, type AnchoredReceipts } from "./receipt-anchors.js";
|
|
2
|
+
import { FailureReasonCode } from "../generated/models/index.js";
|
|
2
3
|
import type { AgentSubscriber } from "@ag-ui/client";
|
|
3
4
|
/**
|
|
4
5
|
* The failure sentences for a failed turn, split by whether they are shown
|
|
@@ -10,3 +11,9 @@ export declare const turnFailedReceiptOf: typeof receiptOf;
|
|
|
10
11
|
export declare const withTurnFailedAnchored: typeof withReceiptAnchored;
|
|
11
12
|
export declare const wellFormedFailAnchorsOf: typeof wellFormedReceiptAnchorsOf;
|
|
12
13
|
export declare function turnFailedMarkerRecorder(onReceiptAnchored: (failedRunId: string, messageId: string, position: keyof AnchoredTurnFailReceipts, receipts: string[]) => void): AgentSubscriber;
|
|
14
|
+
export interface FailedTurn {
|
|
15
|
+
turnId: string;
|
|
16
|
+
reasonCode: FailureReasonCode;
|
|
17
|
+
}
|
|
18
|
+
export declare function failedTurnOf(value: unknown): FailedTurn | null;
|
|
19
|
+
export declare function failedTurnRecorder(onFailedLive: (failed: FailedTurn) => void): AgentSubscriber;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { receiptMarkerRecorder, receiptOf, wellFormedReceiptAnchorsOf, withReceiptAnchored, } from "./receipt-anchors.js";
|
|
2
2
|
import { TURN_FAILED_EVENT_NAME } from "../contract/events.js";
|
|
3
|
+
import { FailureReasonCode, } from "../generated/models/index.js";
|
|
3
4
|
export const EMPTY_TURN_FAILED_ANCHORS = new Map();
|
|
4
5
|
export const turnFailedReceiptOf = receiptOf;
|
|
5
6
|
export const withTurnFailedAnchored = withReceiptAnchored;
|
|
@@ -7,3 +8,44 @@ export const wellFormedFailAnchorsOf = wellFormedReceiptAnchorsOf;
|
|
|
7
8
|
export function turnFailedMarkerRecorder(onReceiptAnchored) {
|
|
8
9
|
return receiptMarkerRecorder(TURN_FAILED_EVENT_NAME, onReceiptAnchored);
|
|
9
10
|
}
|
|
11
|
+
export function failedTurnOf(value) {
|
|
12
|
+
if (typeof value !== "object" || value === null) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const payload = value;
|
|
16
|
+
if (typeof payload.turnId !== "string" || payload.turnId === "") {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
turnId: payload.turnId,
|
|
21
|
+
reasonCode: _knownCodeOf(payload.reasonCode),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function _knownCodeOf(code) {
|
|
25
|
+
const known = Object.values(FailureReasonCode);
|
|
26
|
+
return known.includes(code)
|
|
27
|
+
? code
|
|
28
|
+
: FailureReasonCode.internal_error;
|
|
29
|
+
}
|
|
30
|
+
export function failedTurnRecorder(onFailedLive) {
|
|
31
|
+
let pending = null;
|
|
32
|
+
return {
|
|
33
|
+
onRunInitialized() {
|
|
34
|
+
pending = null;
|
|
35
|
+
},
|
|
36
|
+
onCustomEvent({ event }) {
|
|
37
|
+
if (event.name === TURN_FAILED_EVENT_NAME) {
|
|
38
|
+
pending = failedTurnOf(event.value);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
onRunFinishedEvent() {
|
|
42
|
+
pending = null;
|
|
43
|
+
},
|
|
44
|
+
onRunErrorEvent() {
|
|
45
|
+
if (pending !== null) {
|
|
46
|
+
onFailedLive(pending);
|
|
47
|
+
}
|
|
48
|
+
pending = null;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a reply failed, coarse on purpose since it is visible in the browser.
|
|
3
|
+
* "model_unavailable": the AI model did not respond; "rate_limited": too many
|
|
4
|
+
* requests right now; "credential_declined": an API key or connected ChatGPT
|
|
5
|
+
* plan was refused; "out_of_credit": your Teaflask organization has no funds to
|
|
6
|
+
* pay for replies; "too_long": the message or conversation is too long;
|
|
7
|
+
* "content_refused": the model's content policy refused the message;
|
|
8
|
+
* "configuration_error": the assistant's setup asks for something its model
|
|
9
|
+
* cannot do; "internal_error": anything else. Treat an unknown code as
|
|
10
|
+
* "internal_error".
|
|
11
|
+
*/
|
|
12
|
+
export type FailureReasonCode = (typeof FailureReasonCode)[keyof typeof FailureReasonCode];
|
|
13
|
+
/**
|
|
14
|
+
* Why a reply failed, coarse on purpose since it is visible in the browser.
|
|
15
|
+
* "model_unavailable": the AI model did not respond; "rate_limited": too many
|
|
16
|
+
* requests right now; "credential_declined": an API key or connected ChatGPT
|
|
17
|
+
* plan was refused; "out_of_credit": your Teaflask organization has no funds to
|
|
18
|
+
* pay for replies; "too_long": the message or conversation is too long;
|
|
19
|
+
* "content_refused": the model's content policy refused the message;
|
|
20
|
+
* "configuration_error": the assistant's setup asks for something its model
|
|
21
|
+
* cannot do; "internal_error": anything else. Treat an unknown code as
|
|
22
|
+
* "internal_error".
|
|
23
|
+
*/
|
|
24
|
+
export declare const FailureReasonCode: {
|
|
25
|
+
readonly model_unavailable: "model_unavailable";
|
|
26
|
+
readonly rate_limited: "rate_limited";
|
|
27
|
+
readonly credential_declined: "credential_declined";
|
|
28
|
+
readonly out_of_credit: "out_of_credit";
|
|
29
|
+
readonly too_long: "too_long";
|
|
30
|
+
readonly content_refused: "content_refused";
|
|
31
|
+
readonly configuration_error: "configuration_error";
|
|
32
|
+
readonly internal_error: "internal_error";
|
|
33
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const FailureReasonCode = {
|
|
2
|
+
model_unavailable: "model_unavailable",
|
|
3
|
+
rate_limited: "rate_limited",
|
|
4
|
+
credential_declined: "credential_declined",
|
|
5
|
+
out_of_credit: "out_of_credit",
|
|
6
|
+
too_long: "too_long",
|
|
7
|
+
content_refused: "content_refused",
|
|
8
|
+
configuration_error: "configuration_error",
|
|
9
|
+
internal_error: "internal_error",
|
|
10
|
+
};
|
|
@@ -45,6 +45,7 @@ export * from "./errorEnvelope.js";
|
|
|
45
45
|
export * from "./evidenceAfterVoidRecordedMarker.js";
|
|
46
46
|
export * from "./evidenceAfterVoidRecordedMarkerError.js";
|
|
47
47
|
export * from "./evidenceAfterVoidRecordedMarkerResult.js";
|
|
48
|
+
export * from "./failureReasonCode.js";
|
|
48
49
|
export * from "./fileSource.js";
|
|
49
50
|
export * from "./functionCall.js";
|
|
50
51
|
export * from "./getServingAssistantThreadParams.js";
|
|
@@ -45,6 +45,7 @@ export * from "./errorEnvelope.js";
|
|
|
45
45
|
export * from "./evidenceAfterVoidRecordedMarker.js";
|
|
46
46
|
export * from "./evidenceAfterVoidRecordedMarkerError.js";
|
|
47
47
|
export * from "./evidenceAfterVoidRecordedMarkerResult.js";
|
|
48
|
+
export * from "./failureReasonCode.js";
|
|
48
49
|
export * from "./fileSource.js";
|
|
49
50
|
export * from "./functionCall.js";
|
|
50
51
|
export * from "./getServingAssistantThreadParams.js";
|
package/dist/headless.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { TeaflaskAssistantProvider, type TeaflaskAssistantAnonymousProps, type TeaflaskAssistantIdentityProps, type TeaflaskAssistantProviderBaseProps, type TeaflaskAssistantProviderProps, } from "./components/teaflask-assistant-provider.js";
|
|
2
2
|
export type { AssistantTheme, AssistantThemeDarkTokens, AssistantThemeMode, AssistantThemeTokens, } from "./appearance/theme.js";
|
|
3
3
|
export type { ActionsAdapter, ActionIntent, ActionIntentAction, ActionIntentGraphQL, CookiesActionsAdapter, HeadersActionsAdapter, RequestActionsAdapter, } from "./contract/actions-adapter.js";
|
|
4
|
-
export type { ApprovalSubmitTelemetryEvent, AssistantTelemetryEvent, StreamFailedTelemetryEvent, } from "./contract/telemetry.js";
|
|
4
|
+
export type { ApprovalSubmitTelemetryEvent, AssistantTelemetryEvent, StreamFailedTelemetryEvent, TurnFailedTelemetryEvent, } from "./contract/telemetry.js";
|
|
5
5
|
export type { AssistantSuggestion, AssistantSuggestionInput, AssistantSuggestionKind, } from "./components/conversation-view.js";
|
|
6
6
|
export type { IconAdapter, JsonSchema, ToolViewAdapter, ToolViewCall, ToolViewInstance, ToolViewProps, ToolViewRegistration, ToolViewRegistry, } from "./core/tool-view.js";
|
|
7
7
|
export { useAssistantConversation, type AssistantConversation, type OpenConversation, } from "./components/use-assistant-conversation.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export type { ServingErrorCode, ServingErrorCodeOnTheWire, } from "./contract/er
|
|
|
14
14
|
export type { ServingAssistantThread, TurnStatus } from "./contract/threads.js";
|
|
15
15
|
export { activeFoldElapsedOf, settledFoldDurationOf, type BlockTiming, type SegmentDuration, } from "./core/segment-timing.js";
|
|
16
16
|
export type { MemoryUpdated } from "./core/memory-provenance-anchors.js";
|
|
17
|
-
export type { ApprovalSubmitDropReason, ApprovalSubmitTelemetryEvent, AssistantTelemetryEvent, StreamFailedTelemetryEvent, StreamFailureClass, } from "./contract/telemetry.js";
|
|
17
|
+
export type { ApprovalSubmitDropReason, ApprovalSubmitTelemetryEvent, AssistantTelemetryEvent, FailureReasonCode, StreamFailedTelemetryEvent, StreamFailureClass, TurnFailedTelemetryEvent, } from "./contract/telemetry.js";
|
|
18
18
|
export type { ToolCallDisplay, ToolCallState, ToolCallViewModel, } from "./core/tool-call-display.js";
|
|
19
19
|
export { TOOL_CALL_ICONS, toolCallPresentationOf, type ToolCallIcon, type ToolCallPresentation, } from "./core/tool-call-presentation.js";
|
|
20
20
|
export { actionToolName, actionToolViews, resolvedToolViewsOf, type IconAdapter, type JsonSchema, type ResolvedToolView, type ResolvedToolViewIcon, type ToolViewAdapter, type ToolViewCall, type ToolViewInstance, type ToolViewProps, type ToolViewRegistration, type ToolViewRegistry, type ToolViewResolution, type ToolViewThemeMode, } from "./core/tool-view.js";
|
|
@@ -36,8 +36,10 @@ export declare class StreamResumeStore {
|
|
|
36
36
|
private readonly anchoredResumptions;
|
|
37
37
|
private readonly anchoredFailedRuns;
|
|
38
38
|
private readonly anchoredDeliveryRuns;
|
|
39
|
+
private readonly reportedFailedTurns;
|
|
39
40
|
recordResumeAnchor(runId: string | null, messageId: string, markerValue: unknown, markerTimestamp: number | null): boolean;
|
|
40
41
|
recordTurnFailedReceipts(failedRunId: string, messageId: string, position: keyof AnchoredTurnFailReceipts, receipts: string[]): boolean;
|
|
42
|
+
recordFailedTurnReported(turnId: string): boolean;
|
|
41
43
|
recordSubagentDelivery(deliveryRunId: string, messageId: string, results: DeliveredResult[]): boolean;
|
|
42
44
|
recordToolError(toolCallId: string, errorText: string): void;
|
|
43
45
|
recordToolRefusal(toolCallId: string, sentence: string): void;
|
|
@@ -37,6 +37,7 @@ export class StreamResumeStore {
|
|
|
37
37
|
anchoredResumptions = new Set();
|
|
38
38
|
anchoredFailedRuns = new Set();
|
|
39
39
|
anchoredDeliveryRuns = new Set();
|
|
40
|
+
reportedFailedTurns = new Set();
|
|
40
41
|
recordResumeAnchor(runId, messageId, markerValue, markerTimestamp) {
|
|
41
42
|
const attempt = _wireCounterOf(markerValue, "attempt");
|
|
42
43
|
const carriesRound = typeof markerValue === "object" &&
|
|
@@ -60,6 +61,13 @@ export class StreamResumeStore {
|
|
|
60
61
|
this.turnFailedAnchors = withTurnFailedAnchored(this.turnFailedAnchors, messageId, position, receipts);
|
|
61
62
|
return true;
|
|
62
63
|
}
|
|
64
|
+
recordFailedTurnReported(turnId) {
|
|
65
|
+
if (this.reportedFailedTurns.has(turnId)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
this.reportedFailedTurns.add(turnId);
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
63
71
|
recordSubagentDelivery(deliveryRunId, messageId, results) {
|
|
64
72
|
if (this.anchoredDeliveryRuns.has(deliveryRunId)) {
|
|
65
73
|
return false;
|
package/package.json
CHANGED