@assistant-ui/react-google-adk 0.0.15 → 0.0.17
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/AdkClient.d.ts +0 -1
- package/dist/AdkClient.d.ts.map +1 -1
- package/dist/AdkClient.js +11 -10
- package/dist/AdkClient.js.map +1 -1
- package/dist/AdkEventAccumulator.d.ts +0 -1
- package/dist/AdkEventAccumulator.d.ts.map +1 -1
- package/dist/AdkEventAccumulator.js +2 -2
- package/dist/AdkEventAccumulator.js.map +1 -1
- package/dist/AdkSessionAdapter.d.ts +0 -1
- package/dist/AdkSessionAdapter.d.ts.map +1 -1
- package/dist/AdkSessionAdapter.js +5 -2
- package/dist/AdkSessionAdapter.js.map +1 -1
- package/dist/adkExtras.d.ts +6 -0
- package/dist/adkExtras.d.ts.map +1 -0
- package/dist/adkExtras.js +7 -0
- package/dist/adkExtras.js.map +1 -0
- package/dist/contentToParts.d.ts +0 -1
- package/dist/contentToParts.d.ts.map +1 -1
- package/dist/convertAdkMessages.d.ts +0 -1
- package/dist/convertAdkMessages.d.ts.map +1 -1
- package/dist/hooks.d.ts +1 -18
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +48 -128
- package/dist/hooks.js.map +1 -1
- package/dist/server/adkEventStream.d.ts.map +1 -1
- package/dist/server/createAdkApiRoute.d.ts +0 -1
- package/dist/server/createAdkApiRoute.d.ts.map +1 -1
- package/dist/server/parseAdkRequest.d.ts +0 -1
- package/dist/server/parseAdkRequest.d.ts.map +1 -1
- package/dist/server/parseAdkRequest.js +2 -2
- package/dist/server/parseAdkRequest.js.map +1 -1
- package/dist/structuredEvents.d.ts +0 -1
- package/dist/structuredEvents.d.ts.map +1 -1
- package/dist/trimTrailingSlashes.d.ts +5 -0
- package/dist/trimTrailingSlashes.d.ts.map +1 -0
- package/dist/trimTrailingSlashes.js +10 -0
- package/dist/trimTrailingSlashes.js.map +1 -0
- package/dist/types.d.ts +17 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/useAdkMessages.d.ts +1 -5
- package/dist/useAdkMessages.d.ts.map +1 -1
- package/dist/useAdkMessages.js +2 -1
- package/dist/useAdkMessages.js.map +1 -1
- package/dist/useAdkRuntime.d.ts +10 -8
- package/dist/useAdkRuntime.d.ts.map +1 -1
- package/dist/useAdkRuntime.js +68 -11
- package/dist/useAdkRuntime.js.map +1 -1
- package/package.json +7 -7
- package/src/AdkClient.test.ts +134 -0
- package/src/AdkClient.ts +15 -20
- package/src/AdkSessionAdapter.test.ts +26 -5
- package/src/AdkSessionAdapter.ts +10 -2
- package/src/adkExtras.ts +4 -0
- package/src/hooks.ts +46 -125
- package/src/server/parseAdkRequest.test.ts +4 -2
- package/src/server/parseAdkRequest.ts +4 -2
- package/src/trimTrailingSlashes.ts +5 -0
- package/src/types.ts +13 -0
- package/src/useAdkRuntime.ts +118 -20
package/src/hooks.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { useAui
|
|
1
|
+
import { useAui } from "@assistant-ui/store";
|
|
2
2
|
import { v4 as uuidv4 } from "uuid";
|
|
3
3
|
import type { ReadonlyJSONValue } from "assistant-stream/utils";
|
|
4
|
+
import { adkExtras } from "./adkExtras";
|
|
4
5
|
import type {
|
|
5
6
|
AdkMessage,
|
|
6
7
|
AdkSendMessageConfig,
|
|
@@ -10,115 +11,50 @@ import type {
|
|
|
10
11
|
AdkMessageMetadata,
|
|
11
12
|
} from "./types";
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
stateDelta: Record<string, unknown>;
|
|
20
|
-
artifactDelta: Record<string, number>;
|
|
21
|
-
longRunningToolIds: string[];
|
|
22
|
-
toolConfirmations: AdkToolConfirmation[];
|
|
23
|
-
authRequests: AdkAuthRequest[];
|
|
24
|
-
escalated: boolean;
|
|
25
|
-
messageMetadata: Map<string, AdkMessageMetadata>;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const asAdkRuntimeExtras = (extras: unknown): AdkRuntimeExtras => {
|
|
29
|
-
if (
|
|
30
|
-
typeof extras !== "object" ||
|
|
31
|
-
extras == null ||
|
|
32
|
-
!(symbolAdkRuntimeExtras in extras)
|
|
33
|
-
)
|
|
34
|
-
throw new Error(
|
|
35
|
-
"This method can only be called when you are using useAdkRuntime",
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
return extras as AdkRuntimeExtras;
|
|
39
|
-
};
|
|
14
|
+
const EMPTY_STATE_DELTA: Record<string, unknown> = {};
|
|
15
|
+
const EMPTY_ARTIFACT_DELTA: Record<string, number> = {};
|
|
16
|
+
const EMPTY_LONG_RUNNING_TOOL_IDS: string[] = [];
|
|
17
|
+
const EMPTY_TOOL_CONFIRMATIONS: AdkToolConfirmation[] = [];
|
|
18
|
+
const EMPTY_AUTH_REQUESTS: AdkAuthRequest[] = [];
|
|
19
|
+
const EMPTY_MESSAGE_METADATA = new Map<string, AdkMessageMetadata>();
|
|
40
20
|
|
|
41
21
|
/** Returns the name and branch of the currently active ADK agent. */
|
|
42
|
-
export const useAdkAgentInfo = () =>
|
|
43
|
-
|
|
44
|
-
const extras = s.thread.extras;
|
|
45
|
-
if (!extras) return undefined;
|
|
46
|
-
return asAdkRuntimeExtras(extras).agentInfo;
|
|
47
|
-
});
|
|
48
|
-
};
|
|
22
|
+
export const useAdkAgentInfo = () =>
|
|
23
|
+
adkExtras.use((e) => e.agentInfo, undefined);
|
|
49
24
|
|
|
50
25
|
/** Returns the accumulated session state delta from ADK events. */
|
|
51
|
-
export const useAdkSessionState = () =>
|
|
52
|
-
|
|
53
|
-
const extras = s.thread.extras;
|
|
54
|
-
if (!extras) return {};
|
|
55
|
-
return asAdkRuntimeExtras(extras).stateDelta;
|
|
56
|
-
});
|
|
57
|
-
};
|
|
26
|
+
export const useAdkSessionState = () =>
|
|
27
|
+
adkExtras.use((e) => e.stateDelta, EMPTY_STATE_DELTA);
|
|
58
28
|
|
|
59
29
|
/** Returns a function to send raw ADK messages. */
|
|
60
30
|
export const useAdkSend = () => {
|
|
61
31
|
const aui = useAui();
|
|
62
|
-
return (messages: AdkMessage[], config: AdkSendMessageConfig) =>
|
|
63
|
-
|
|
64
|
-
const { send } = asAdkRuntimeExtras(extras);
|
|
65
|
-
return send(messages, config);
|
|
66
|
-
};
|
|
32
|
+
return (messages: AdkMessage[], config: AdkSendMessageConfig) =>
|
|
33
|
+
adkExtras.get(aui).send(messages, config);
|
|
67
34
|
};
|
|
68
35
|
|
|
69
36
|
/** Returns the IDs of long-running tools awaiting external input. */
|
|
70
|
-
export const useAdkLongRunningToolIds = () =>
|
|
71
|
-
|
|
72
|
-
const extras = s.thread.extras;
|
|
73
|
-
if (!extras) return [];
|
|
74
|
-
return asAdkRuntimeExtras(extras).longRunningToolIds;
|
|
75
|
-
});
|
|
76
|
-
};
|
|
37
|
+
export const useAdkLongRunningToolIds = () =>
|
|
38
|
+
adkExtras.use((e) => e.longRunningToolIds, EMPTY_LONG_RUNNING_TOOL_IDS);
|
|
77
39
|
|
|
78
40
|
/** Returns pending tool confirmation requests (from SecurityPlugin etc). */
|
|
79
|
-
export const useAdkToolConfirmations = () =>
|
|
80
|
-
|
|
81
|
-
const extras = s.thread.extras;
|
|
82
|
-
if (!extras) return [];
|
|
83
|
-
return asAdkRuntimeExtras(extras).toolConfirmations;
|
|
84
|
-
});
|
|
85
|
-
};
|
|
41
|
+
export const useAdkToolConfirmations = () =>
|
|
42
|
+
adkExtras.use((e) => e.toolConfirmations, EMPTY_TOOL_CONFIRMATIONS);
|
|
86
43
|
|
|
87
44
|
/** Returns pending auth credential requests from tools. */
|
|
88
|
-
export const useAdkAuthRequests = () =>
|
|
89
|
-
|
|
90
|
-
const extras = s.thread.extras;
|
|
91
|
-
if (!extras) return [];
|
|
92
|
-
return asAdkRuntimeExtras(extras).authRequests;
|
|
93
|
-
});
|
|
94
|
-
};
|
|
45
|
+
export const useAdkAuthRequests = () =>
|
|
46
|
+
adkExtras.use((e) => e.authRequests, EMPTY_AUTH_REQUESTS);
|
|
95
47
|
|
|
96
48
|
/** Returns the accumulated artifact delta (filename → version). */
|
|
97
|
-
export const useAdkArtifacts = () =>
|
|
98
|
-
|
|
99
|
-
const extras = s.thread.extras;
|
|
100
|
-
if (!extras) return {};
|
|
101
|
-
return asAdkRuntimeExtras(extras).artifactDelta;
|
|
102
|
-
});
|
|
103
|
-
};
|
|
49
|
+
export const useAdkArtifacts = () =>
|
|
50
|
+
adkExtras.use((e) => e.artifactDelta, EMPTY_ARTIFACT_DELTA);
|
|
104
51
|
|
|
105
52
|
/** Returns whether any agent has escalated (requested human handoff). */
|
|
106
|
-
export const useAdkEscalation = () =>
|
|
107
|
-
return useAuiState((s) => {
|
|
108
|
-
const extras = s.thread.extras;
|
|
109
|
-
if (!extras) return false;
|
|
110
|
-
return asAdkRuntimeExtras(extras).escalated;
|
|
111
|
-
});
|
|
112
|
-
};
|
|
53
|
+
export const useAdkEscalation = () => adkExtras.use((e) => e.escalated, false);
|
|
113
54
|
|
|
114
55
|
/** Returns per-message metadata (grounding, citation, usage). Keyed by message ID. */
|
|
115
|
-
export const useAdkMessageMetadata = () =>
|
|
116
|
-
|
|
117
|
-
const extras = s.thread.extras;
|
|
118
|
-
if (!extras) return new Map<string, AdkMessageMetadata>();
|
|
119
|
-
return asAdkRuntimeExtras(extras).messageMetadata;
|
|
120
|
-
});
|
|
121
|
-
};
|
|
56
|
+
export const useAdkMessageMetadata = () =>
|
|
57
|
+
adkExtras.use((e) => e.messageMetadata, EMPTY_MESSAGE_METADATA);
|
|
122
58
|
|
|
123
59
|
// ── Convenience helpers for interactive flows ──
|
|
124
60
|
|
|
@@ -129,10 +65,8 @@ export const useAdkConfirmTool = () => {
|
|
|
129
65
|
toolCallId: string,
|
|
130
66
|
confirmed: boolean,
|
|
131
67
|
payload?: ReadonlyJSONValue,
|
|
132
|
-
) =>
|
|
133
|
-
|
|
134
|
-
const { send } = asAdkRuntimeExtras(extras);
|
|
135
|
-
return send(
|
|
68
|
+
) =>
|
|
69
|
+
adkExtras.get(aui).send(
|
|
136
70
|
[
|
|
137
71
|
{
|
|
138
72
|
id: uuidv4(),
|
|
@@ -148,16 +82,13 @@ export const useAdkConfirmTool = () => {
|
|
|
148
82
|
],
|
|
149
83
|
{},
|
|
150
84
|
);
|
|
151
|
-
};
|
|
152
85
|
};
|
|
153
86
|
|
|
154
87
|
/** Returns a function to submit auth credentials for a pending auth request. */
|
|
155
88
|
export const useAdkSubmitAuth = () => {
|
|
156
89
|
const aui = useAui();
|
|
157
|
-
return (toolCallId: string, credential: AdkAuthCredential) =>
|
|
158
|
-
|
|
159
|
-
const { send } = asAdkRuntimeExtras(extras);
|
|
160
|
-
return send(
|
|
90
|
+
return (toolCallId: string, credential: AdkAuthCredential) =>
|
|
91
|
+
adkExtras.get(aui).send(
|
|
161
92
|
[
|
|
162
93
|
{
|
|
163
94
|
id: uuidv4(),
|
|
@@ -170,16 +101,13 @@ export const useAdkSubmitAuth = () => {
|
|
|
170
101
|
],
|
|
171
102
|
{},
|
|
172
103
|
);
|
|
173
|
-
};
|
|
174
104
|
};
|
|
175
105
|
|
|
176
106
|
/** Returns a function to submit the user's answer for a pending `adk_request_input` HITL interrupt. */
|
|
177
107
|
export const useAdkSubmitInput = () => {
|
|
178
108
|
const aui = useAui();
|
|
179
|
-
return (toolCallId: string, result: ReadonlyJSONValue) =>
|
|
180
|
-
|
|
181
|
-
const { send } = asAdkRuntimeExtras(extras);
|
|
182
|
-
return send(
|
|
109
|
+
return (toolCallId: string, result: ReadonlyJSONValue) =>
|
|
110
|
+
adkExtras.get(aui).send(
|
|
183
111
|
[
|
|
184
112
|
{
|
|
185
113
|
id: uuidv4(),
|
|
@@ -192,7 +120,6 @@ export const useAdkSubmitInput = () => {
|
|
|
192
120
|
],
|
|
193
121
|
{},
|
|
194
122
|
);
|
|
195
|
-
};
|
|
196
123
|
};
|
|
197
124
|
|
|
198
125
|
// ── State prefix helpers ──
|
|
@@ -215,28 +142,22 @@ const filterByPrefix = (
|
|
|
215
142
|
};
|
|
216
143
|
|
|
217
144
|
/** Returns app-level state (keys prefixed with `app:`, prefix stripped). */
|
|
218
|
-
export const useAdkAppState = () =>
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
});
|
|
224
|
-
};
|
|
145
|
+
export const useAdkAppState = () =>
|
|
146
|
+
adkExtras.use(
|
|
147
|
+
(e) => filterByPrefix(e.stateDelta, APP_PREFIX),
|
|
148
|
+
EMPTY_STATE_DELTA,
|
|
149
|
+
);
|
|
225
150
|
|
|
226
151
|
/** Returns user-level state (keys prefixed with `user:`, prefix stripped). */
|
|
227
|
-
export const useAdkUserState = () =>
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
});
|
|
233
|
-
};
|
|
152
|
+
export const useAdkUserState = () =>
|
|
153
|
+
adkExtras.use(
|
|
154
|
+
(e) => filterByPrefix(e.stateDelta, USER_PREFIX),
|
|
155
|
+
EMPTY_STATE_DELTA,
|
|
156
|
+
);
|
|
234
157
|
|
|
235
158
|
/** Returns temp state (keys prefixed with `temp:`, prefix stripped). Not persisted. */
|
|
236
|
-
export const useAdkTempState = () =>
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
});
|
|
242
|
-
};
|
|
159
|
+
export const useAdkTempState = () =>
|
|
160
|
+
adkExtras.use(
|
|
161
|
+
(e) => filterByPrefix(e.stateDelta, TEMP_PREFIX),
|
|
162
|
+
EMPTY_STATE_DELTA,
|
|
163
|
+
);
|
|
@@ -85,12 +85,14 @@ describe("parseAdkRequest", () => {
|
|
|
85
85
|
method: "POST",
|
|
86
86
|
body: "not json",
|
|
87
87
|
});
|
|
88
|
-
await expect(parseAdkRequest(req)).rejects.toThrow(
|
|
88
|
+
await expect(parseAdkRequest(req)).rejects.toThrow(
|
|
89
|
+
'Invalid JSON in Google ADK proxy request body. Expected a JSON object like {"message":"Hello"} or {"type":"tool-result",...}.',
|
|
90
|
+
);
|
|
89
91
|
});
|
|
90
92
|
|
|
91
93
|
it("throws on non-object body", async () => {
|
|
92
94
|
await expect(parseAdkRequest(makeRequest([1, 2, 3]))).rejects.toThrow(
|
|
93
|
-
"
|
|
95
|
+
"Google ADK proxy request body must be a JSON object",
|
|
94
96
|
);
|
|
95
97
|
});
|
|
96
98
|
});
|
|
@@ -46,11 +46,13 @@ export const parseAdkRequest = async (
|
|
|
46
46
|
try {
|
|
47
47
|
body = (await request.json()) as Record<string, unknown>;
|
|
48
48
|
} catch {
|
|
49
|
-
throw new Error(
|
|
49
|
+
throw new Error(
|
|
50
|
+
'Invalid JSON in Google ADK proxy request body. Expected a JSON object like {"message":"Hello"} or {"type":"tool-result",...}.',
|
|
51
|
+
);
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
53
|
-
throw new Error("
|
|
55
|
+
throw new Error("Google ADK proxy request body must be a JSON object");
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
const config: AdkSendMessageConfig = {};
|
package/src/types.ts
CHANGED
|
@@ -274,3 +274,16 @@ export type OnAdkCustomEventCallback = (
|
|
|
274
274
|
export type OnAdkAgentTransferCallback = (
|
|
275
275
|
toAgent: string,
|
|
276
276
|
) => void | Promise<void>;
|
|
277
|
+
|
|
278
|
+
/** Private state and actions `useAdkRuntime` exposes through `thread.extras`. */
|
|
279
|
+
export type AdkRuntimeExtras = {
|
|
280
|
+
send: (messages: AdkMessage[], config: AdkSendMessageConfig) => Promise<void>;
|
|
281
|
+
agentInfo: { name?: string | undefined; branch?: string | undefined };
|
|
282
|
+
stateDelta: Record<string, unknown>;
|
|
283
|
+
artifactDelta: Record<string, number>;
|
|
284
|
+
longRunningToolIds: string[];
|
|
285
|
+
toolConfirmations: AdkToolConfirmation[];
|
|
286
|
+
authRequests: AdkAuthRequest[];
|
|
287
|
+
escalated: boolean;
|
|
288
|
+
messageMetadata: Map<string, AdkMessageMetadata>;
|
|
289
|
+
};
|
package/src/useAdkRuntime.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
type AppendMessage,
|
|
12
12
|
type ThreadMessage,
|
|
13
13
|
type ToolExecutionStatus,
|
|
14
|
+
generateId,
|
|
14
15
|
} from "@assistant-ui/core";
|
|
15
16
|
import {
|
|
16
17
|
useCloudThreadListAdapter,
|
|
@@ -31,7 +32,7 @@ import type {
|
|
|
31
32
|
} from "./types";
|
|
32
33
|
import { useAdkMessages } from "./useAdkMessages";
|
|
33
34
|
import { convertAdkMessage } from "./convertAdkMessages";
|
|
34
|
-
import {
|
|
35
|
+
import { adkExtras } from "./adkExtras";
|
|
35
36
|
import { v4 as uuidv4 } from "uuid";
|
|
36
37
|
|
|
37
38
|
/** @internal — exported for unit tests. */
|
|
@@ -138,8 +139,26 @@ const truncateAdkMessages = (
|
|
|
138
139
|
return truncated;
|
|
139
140
|
};
|
|
140
141
|
|
|
142
|
+
const toAdkUserMessage = (
|
|
143
|
+
msg: AppendMessage,
|
|
144
|
+
id = generateId(),
|
|
145
|
+
): AdkMessage & { type: "human"; id: string } => ({
|
|
146
|
+
id,
|
|
147
|
+
type: "human",
|
|
148
|
+
content: getMessageContent(msg),
|
|
149
|
+
});
|
|
150
|
+
|
|
141
151
|
export type UseAdkRuntimeOptions = ExternalStoreSharedOptions & {
|
|
142
152
|
stream: AdkStreamCallback;
|
|
153
|
+
/**
|
|
154
|
+
* Called whenever the active thread's canonical (remote) ID changes, so the
|
|
155
|
+
* value can be treated as a managed/controlled variable (e.g. synced to a URL
|
|
156
|
+
* query param). Only the settled remote ID is emitted: while a freshly created
|
|
157
|
+
* thread is still optimistic the value is `undefined`, and the real ID is
|
|
158
|
+
* emitted once the thread is initialized; the transient local ID is never
|
|
159
|
+
* surfaced.
|
|
160
|
+
*/
|
|
161
|
+
onThreadIdChange?: ((threadId: string | undefined) => void) | undefined;
|
|
143
162
|
autoCancelPendingToolCalls?: boolean | undefined;
|
|
144
163
|
unstable_allowCancellation?: boolean | undefined;
|
|
145
164
|
getCheckpointId?: (
|
|
@@ -196,6 +215,7 @@ const useAdkRuntimeImpl = (options: UseAdkRuntimeOptions) => {
|
|
|
196
215
|
messageMetadata,
|
|
197
216
|
sendMessage,
|
|
198
217
|
cancel,
|
|
218
|
+
setMessages,
|
|
199
219
|
replaceMessages,
|
|
200
220
|
} = useAdkMessages({
|
|
201
221
|
stream,
|
|
@@ -232,6 +252,50 @@ const useAdkRuntimeImpl = (options: UseAdkRuntimeOptions) => {
|
|
|
232
252
|
const threadMessagesRef = useRef(threadMessages);
|
|
233
253
|
threadMessagesRef.current = threadMessages;
|
|
234
254
|
|
|
255
|
+
const adkMessagesRef = useRef(messages);
|
|
256
|
+
adkMessagesRef.current = messages;
|
|
257
|
+
|
|
258
|
+
const stagedMessagesRef = useRef(
|
|
259
|
+
new Map<
|
|
260
|
+
string,
|
|
261
|
+
{
|
|
262
|
+
message: AdkMessage & { id: string };
|
|
263
|
+
runConfig: AppendMessage["runConfig"];
|
|
264
|
+
}
|
|
265
|
+
>(),
|
|
266
|
+
);
|
|
267
|
+
const [stagedMessageCount, setStagedMessageCount] = useState(0);
|
|
268
|
+
const hasStagedMessages = stagedMessageCount > 0;
|
|
269
|
+
|
|
270
|
+
const getStagedRun = (parentId: string | null) => {
|
|
271
|
+
if (!parentId || !stagedMessagesRef.current.has(parentId)) return null;
|
|
272
|
+
|
|
273
|
+
const staged: AdkMessage[] = [];
|
|
274
|
+
for (const message of adkMessagesRef.current) {
|
|
275
|
+
if (message.id && stagedMessagesRef.current.has(message.id)) {
|
|
276
|
+
staged.push(stagedMessagesRef.current.get(message.id)!.message);
|
|
277
|
+
}
|
|
278
|
+
if (message.id === parentId) break;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return {
|
|
282
|
+
messages: staged,
|
|
283
|
+
runConfig: stagedMessagesRef.current.get(parentId)!.runConfig,
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const stageUserMessage = (msg: AppendMessage) => {
|
|
288
|
+
const stagedMessage = toAdkUserMessage(msg);
|
|
289
|
+
stagedMessagesRef.current.set(stagedMessage.id, {
|
|
290
|
+
message: stagedMessage,
|
|
291
|
+
runConfig: msg.runConfig,
|
|
292
|
+
});
|
|
293
|
+
setStagedMessageCount(stagedMessagesRef.current.size);
|
|
294
|
+
const nextMessages = [...adkMessagesRef.current, stagedMessage];
|
|
295
|
+
adkMessagesRef.current = nextMessages;
|
|
296
|
+
setMessages(nextMessages);
|
|
297
|
+
};
|
|
298
|
+
|
|
235
299
|
const runtime = useExternalStoreRuntime({
|
|
236
300
|
...pickExternalStoreSharedOptions(options),
|
|
237
301
|
isRunning: effectiveIsRunning,
|
|
@@ -239,8 +303,7 @@ const useAdkRuntimeImpl = (options: UseAdkRuntimeOptions) => {
|
|
|
239
303
|
unstable_enableToolInvocations: true,
|
|
240
304
|
setToolStatuses,
|
|
241
305
|
adapters: { attachments, dictation, feedback, speech, voice },
|
|
242
|
-
extras: {
|
|
243
|
-
[symbolAdkRuntimeExtras]: true,
|
|
306
|
+
extras: adkExtras.provide({
|
|
244
307
|
agentInfo,
|
|
245
308
|
stateDelta,
|
|
246
309
|
artifactDelta,
|
|
@@ -250,8 +313,13 @@ const useAdkRuntimeImpl = (options: UseAdkRuntimeOptions) => {
|
|
|
250
313
|
escalated,
|
|
251
314
|
messageMetadata,
|
|
252
315
|
send: handleSendMessage,
|
|
253
|
-
}
|
|
316
|
+
}),
|
|
254
317
|
onNew: async (msg) => {
|
|
318
|
+
if (!(msg.startRun ?? msg.role === "user")) {
|
|
319
|
+
stageUserMessage(msg);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
255
323
|
const cancellations =
|
|
256
324
|
autoCancelPendingToolCalls !== false
|
|
257
325
|
? getPendingCancellations(messages, longRunningToolIds)
|
|
@@ -276,6 +344,18 @@ const useAdkRuntimeImpl = (options: UseAdkRuntimeOptions) => {
|
|
|
276
344
|
msg.parentId,
|
|
277
345
|
);
|
|
278
346
|
replaceMessages(truncated);
|
|
347
|
+
if (!(msg.startRun ?? msg.role === "user")) {
|
|
348
|
+
const stagedMessage = toAdkUserMessage(msg);
|
|
349
|
+
stagedMessagesRef.current.set(stagedMessage.id, {
|
|
350
|
+
message: stagedMessage,
|
|
351
|
+
runConfig: msg.runConfig,
|
|
352
|
+
});
|
|
353
|
+
setStagedMessageCount(stagedMessagesRef.current.size);
|
|
354
|
+
const nextMessages = [...truncated, stagedMessage];
|
|
355
|
+
adkMessagesRef.current = nextMessages;
|
|
356
|
+
setMessages(nextMessages);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
279
359
|
const externalId = aui.threadListItem().getState().externalId;
|
|
280
360
|
const checkpointId = externalId
|
|
281
361
|
? await getCheckpointId(externalId, truncated)
|
|
@@ -295,23 +375,39 @@ const useAdkRuntimeImpl = (options: UseAdkRuntimeOptions) => {
|
|
|
295
375
|
);
|
|
296
376
|
}
|
|
297
377
|
: undefined,
|
|
298
|
-
|
|
299
|
-
?
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
378
|
+
...(getCheckpointId || hasStagedMessages
|
|
379
|
+
? {
|
|
380
|
+
onReload: async (parentId, config) => {
|
|
381
|
+
const stagedRun = getStagedRun(parentId);
|
|
382
|
+
if (stagedRun) {
|
|
383
|
+
for (const message of stagedRun.messages) {
|
|
384
|
+
stagedMessagesRef.current.delete(message.id);
|
|
385
|
+
}
|
|
386
|
+
setStagedMessageCount(stagedMessagesRef.current.size);
|
|
387
|
+
return handleSendMessage(stagedRun.messages, {
|
|
388
|
+
runConfig: config.runConfig ?? stagedRun.runConfig,
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (!getCheckpointId)
|
|
393
|
+
throw new Error("Runtime does not support reloading messages.");
|
|
394
|
+
|
|
395
|
+
const truncated = truncateAdkMessages(
|
|
396
|
+
threadMessagesRef.current,
|
|
397
|
+
parentId,
|
|
398
|
+
);
|
|
399
|
+
replaceMessages(truncated);
|
|
400
|
+
const externalId = aui.threadListItem().getState().externalId;
|
|
401
|
+
const checkpointId = externalId
|
|
402
|
+
? await getCheckpointId(externalId, truncated)
|
|
403
|
+
: null;
|
|
404
|
+
return handleSendMessage([], {
|
|
405
|
+
runConfig: config.runConfig,
|
|
406
|
+
...(checkpointId && { checkpointId }),
|
|
407
|
+
});
|
|
408
|
+
},
|
|
313
409
|
}
|
|
314
|
-
:
|
|
410
|
+
: {}),
|
|
315
411
|
onAddToolResult: async ({
|
|
316
412
|
toolCallId,
|
|
317
413
|
toolName,
|
|
@@ -373,6 +469,7 @@ export const useAdkRuntime = ({
|
|
|
373
469
|
sessionAdapter,
|
|
374
470
|
create,
|
|
375
471
|
delete: deleteFn,
|
|
472
|
+
onThreadIdChange,
|
|
376
473
|
...options
|
|
377
474
|
}: UseAdkRuntimeOptions) => {
|
|
378
475
|
const aui = useAui();
|
|
@@ -394,5 +491,6 @@ export const useAdkRuntime = ({
|
|
|
394
491
|
},
|
|
395
492
|
adapter,
|
|
396
493
|
allowNesting: true,
|
|
494
|
+
onThreadIdChange,
|
|
397
495
|
});
|
|
398
496
|
};
|