@iqai/adk 0.1.0 → 0.1.1
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 +6 -0
- package/README.md +62 -0
- package/dist/index.d.mts +275 -92
- package/dist/index.d.ts +275 -92
- package/dist/index.js +1488 -1219
- package/dist/index.mjs +1480 -1211
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -594,6 +594,7 @@ You could retry calling this tool, but it is IMPORTANT for you to provide all th
|
|
|
594
594
|
var agents_exports = {};
|
|
595
595
|
__export(agents_exports, {
|
|
596
596
|
Agent: () => LlmAgent,
|
|
597
|
+
AgentBuilder: () => AgentBuilder,
|
|
597
598
|
BaseAgent: () => BaseAgent,
|
|
598
599
|
CallbackContext: () => CallbackContext,
|
|
599
600
|
InvocationContext: () => InvocationContext,
|
|
@@ -8092,6 +8093,9 @@ var LangGraphAgent = class extends BaseAgent {
|
|
|
8092
8093
|
}
|
|
8093
8094
|
};
|
|
8094
8095
|
|
|
8096
|
+
// src/runners.ts
|
|
8097
|
+
import { SpanStatusCode } from "@opentelemetry/api";
|
|
8098
|
+
|
|
8095
8099
|
// src/agents/run-config.ts
|
|
8096
8100
|
var StreamingMode = /* @__PURE__ */ ((StreamingMode2) => {
|
|
8097
8101
|
StreamingMode2["NONE"] = "NONE";
|
|
@@ -8186,11 +8190,87 @@ var RunConfig = class {
|
|
|
8186
8190
|
}
|
|
8187
8191
|
};
|
|
8188
8192
|
|
|
8189
|
-
// src/memory
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8193
|
+
// src/artifacts/in-memory-artifact-service.ts
|
|
8194
|
+
init_logger();
|
|
8195
|
+
var logger9 = new Logger({ name: "InMemoryArtifactService" });
|
|
8196
|
+
var InMemoryArtifactService = class {
|
|
8197
|
+
artifacts = /* @__PURE__ */ new Map();
|
|
8198
|
+
fileHasUserNamespace(filename) {
|
|
8199
|
+
return filename.startsWith("user:");
|
|
8200
|
+
}
|
|
8201
|
+
getArtifactPath(appName, userId, sessionId, filename) {
|
|
8202
|
+
if (this.fileHasUserNamespace(filename)) {
|
|
8203
|
+
return `${appName}/${userId}/user/${filename}`;
|
|
8204
|
+
}
|
|
8205
|
+
return `${appName}/${userId}/${sessionId}/${filename}`;
|
|
8206
|
+
}
|
|
8207
|
+
async saveArtifact(args) {
|
|
8208
|
+
const { appName, userId, sessionId, filename, artifact } = args;
|
|
8209
|
+
const path2 = this.getArtifactPath(appName, userId, sessionId, filename);
|
|
8210
|
+
if (!this.artifacts.has(path2)) {
|
|
8211
|
+
this.artifacts.set(path2, []);
|
|
8212
|
+
}
|
|
8213
|
+
const versions = this.artifacts.get(path2);
|
|
8214
|
+
const version = versions.length;
|
|
8215
|
+
versions.push(artifact);
|
|
8216
|
+
return version;
|
|
8217
|
+
}
|
|
8218
|
+
async loadArtifact(args) {
|
|
8219
|
+
const { appName, userId, sessionId, filename, version } = args;
|
|
8220
|
+
const path2 = this.getArtifactPath(appName, userId, sessionId, filename);
|
|
8221
|
+
const versions = this.artifacts.get(path2);
|
|
8222
|
+
if (!versions || versions.length === 0) {
|
|
8223
|
+
return null;
|
|
8224
|
+
}
|
|
8225
|
+
let targetVersion = version;
|
|
8226
|
+
if (targetVersion === void 0 || targetVersion === null) {
|
|
8227
|
+
targetVersion = versions.length - 1;
|
|
8228
|
+
}
|
|
8229
|
+
if (targetVersion < 0) {
|
|
8230
|
+
targetVersion = versions.length + targetVersion;
|
|
8231
|
+
}
|
|
8232
|
+
if (targetVersion < 0 || targetVersion >= versions.length) {
|
|
8233
|
+
return null;
|
|
8234
|
+
}
|
|
8235
|
+
return versions[targetVersion];
|
|
8236
|
+
}
|
|
8237
|
+
async listArtifactKeys(args) {
|
|
8238
|
+
const { appName, userId, sessionId } = args;
|
|
8239
|
+
const sessionPrefix = `${appName}/${userId}/${sessionId}/`;
|
|
8240
|
+
const userNamespacePrefix = `${appName}/${userId}/user/`;
|
|
8241
|
+
const filenames = [];
|
|
8242
|
+
for (const path2 of this.artifacts.keys()) {
|
|
8243
|
+
if (path2.startsWith(sessionPrefix)) {
|
|
8244
|
+
const filename = path2.substring(sessionPrefix.length);
|
|
8245
|
+
filenames.push(filename);
|
|
8246
|
+
} else if (path2.startsWith(userNamespacePrefix)) {
|
|
8247
|
+
const filename = path2.substring(userNamespacePrefix.length);
|
|
8248
|
+
filenames.push(filename);
|
|
8249
|
+
}
|
|
8250
|
+
}
|
|
8251
|
+
return filenames.sort();
|
|
8252
|
+
}
|
|
8253
|
+
async deleteArtifact(args) {
|
|
8254
|
+
const { appName, userId, sessionId, filename } = args;
|
|
8255
|
+
const path2 = this.getArtifactPath(appName, userId, sessionId, filename);
|
|
8256
|
+
if (!this.artifacts.has(path2)) {
|
|
8257
|
+
return;
|
|
8258
|
+
}
|
|
8259
|
+
this.artifacts.delete(path2);
|
|
8260
|
+
}
|
|
8261
|
+
async listVersions(args) {
|
|
8262
|
+
const { appName, userId, sessionId, filename } = args;
|
|
8263
|
+
const path2 = this.getArtifactPath(appName, userId, sessionId, filename);
|
|
8264
|
+
const versions = this.artifacts.get(path2);
|
|
8265
|
+
if (!versions || versions.length === 0) {
|
|
8266
|
+
return [];
|
|
8267
|
+
}
|
|
8268
|
+
return Array.from({ length: versions.length }, (_, i) => i);
|
|
8269
|
+
}
|
|
8270
|
+
};
|
|
8271
|
+
|
|
8272
|
+
// src/runners.ts
|
|
8273
|
+
init_logger();
|
|
8194
8274
|
|
|
8195
8275
|
// src/memory/_utils.ts
|
|
8196
8276
|
function formatTimestamp(timestamp) {
|
|
@@ -8308,19 +8388,8 @@ var InMemoryMemoryService = class {
|
|
|
8308
8388
|
}
|
|
8309
8389
|
};
|
|
8310
8390
|
|
|
8311
|
-
// src/sessions/
|
|
8312
|
-
|
|
8313
|
-
__export(sessions_exports, {
|
|
8314
|
-
BaseSessionService: () => BaseSessionService,
|
|
8315
|
-
DatabaseSessionService: () => DatabaseSessionService,
|
|
8316
|
-
InMemorySessionService: () => InMemorySessionService,
|
|
8317
|
-
State: () => State,
|
|
8318
|
-
VertexAiSessionService: () => VertexAiSessionService,
|
|
8319
|
-
createDatabaseSessionService: () => createDatabaseSessionService,
|
|
8320
|
-
createMysqlSessionService: () => createMysqlSessionService,
|
|
8321
|
-
createPostgresSessionService: () => createPostgresSessionService,
|
|
8322
|
-
createSqliteSessionService: () => createSqliteSessionService
|
|
8323
|
-
});
|
|
8391
|
+
// src/sessions/in-memory-session-service.ts
|
|
8392
|
+
import { randomUUID } from "crypto";
|
|
8324
8393
|
|
|
8325
8394
|
// src/sessions/base-session-service.ts
|
|
8326
8395
|
var BaseSessionService = class {
|
|
@@ -8359,7 +8428,6 @@ var BaseSessionService = class {
|
|
|
8359
8428
|
};
|
|
8360
8429
|
|
|
8361
8430
|
// src/sessions/in-memory-session-service.ts
|
|
8362
|
-
import { randomUUID } from "crypto";
|
|
8363
8431
|
var InMemorySessionService = class extends BaseSessionService {
|
|
8364
8432
|
/**
|
|
8365
8433
|
* A map from app name to a map from user ID to a map from session ID to session.
|
|
@@ -8571,1340 +8639,1541 @@ var InMemorySessionService = class extends BaseSessionService {
|
|
|
8571
8639
|
}
|
|
8572
8640
|
};
|
|
8573
8641
|
|
|
8574
|
-
// src/
|
|
8575
|
-
var
|
|
8576
|
-
|
|
8577
|
-
|
|
8578
|
-
|
|
8579
|
-
|
|
8580
|
-
* Initializes the VertexAiSessionService.
|
|
8581
|
-
*/
|
|
8582
|
-
constructor(options = {}) {
|
|
8583
|
-
super();
|
|
8584
|
-
this.project = options.project;
|
|
8585
|
-
this.location = options.location;
|
|
8586
|
-
this.agentEngineId = options.agentEngineId;
|
|
8587
|
-
}
|
|
8588
|
-
async createSession(appName, userId, state, sessionId) {
|
|
8589
|
-
if (sessionId) {
|
|
8590
|
-
throw new Error(
|
|
8591
|
-
"User-provided Session id is not supported for VertexAISessionService."
|
|
8592
|
-
);
|
|
8593
|
-
}
|
|
8594
|
-
const reasoningEngineId = this.getReasoningEngineId(appName);
|
|
8595
|
-
const apiClient = this.getApiClient();
|
|
8596
|
-
const sessionJsonDict = { user_id: userId };
|
|
8597
|
-
if (state) {
|
|
8598
|
-
sessionJsonDict.session_state = state;
|
|
8599
|
-
}
|
|
8600
|
-
const apiResponse = await apiClient.async_request({
|
|
8601
|
-
http_method: "POST",
|
|
8602
|
-
path: `reasoningEngines/${reasoningEngineId}/sessions`,
|
|
8603
|
-
request_dict: sessionJsonDict
|
|
8604
|
-
});
|
|
8605
|
-
console.info("Create Session response", apiResponse);
|
|
8606
|
-
const createdSessionId = apiResponse.name.split("/").slice(-3, -2)[0];
|
|
8607
|
-
const operationId = apiResponse.name.split("/").pop();
|
|
8608
|
-
let maxRetryAttempt = 5;
|
|
8609
|
-
let lroResponse = null;
|
|
8610
|
-
while (maxRetryAttempt >= 0) {
|
|
8611
|
-
lroResponse = await apiClient.async_request({
|
|
8612
|
-
http_method: "GET",
|
|
8613
|
-
path: `operations/${operationId}`,
|
|
8614
|
-
request_dict: {}
|
|
8615
|
-
});
|
|
8616
|
-
if (lroResponse?.done) {
|
|
8617
|
-
break;
|
|
8618
|
-
}
|
|
8619
|
-
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
8620
|
-
maxRetryAttempt--;
|
|
8621
|
-
}
|
|
8622
|
-
if (!lroResponse || !lroResponse.done) {
|
|
8623
|
-
throw new Error(
|
|
8624
|
-
`Timeout waiting for operation ${operationId} to complete.`
|
|
8625
|
-
);
|
|
8626
|
-
}
|
|
8627
|
-
const getSessionApiResponse = await apiClient.async_request({
|
|
8628
|
-
http_method: "GET",
|
|
8629
|
-
path: `reasoningEngines/${reasoningEngineId}/sessions/${createdSessionId}`,
|
|
8630
|
-
request_dict: {}
|
|
8631
|
-
});
|
|
8632
|
-
const updateTimestamp = new Date(getSessionApiResponse.updateTime).getTime() / 1e3;
|
|
8633
|
-
return {
|
|
8634
|
-
appName: String(appName),
|
|
8635
|
-
userId: String(userId),
|
|
8636
|
-
id: String(createdSessionId),
|
|
8637
|
-
state: getSessionApiResponse.sessionState || {},
|
|
8638
|
-
events: [],
|
|
8639
|
-
lastUpdateTime: updateTimestamp
|
|
8640
|
-
};
|
|
8642
|
+
// src/runners.ts
|
|
8643
|
+
var logger10 = new Logger({ name: "Runner" });
|
|
8644
|
+
function _findFunctionCallEventIfLastEventIsFunctionResponse(session) {
|
|
8645
|
+
const events = session.events;
|
|
8646
|
+
if (!events || events.length === 0) {
|
|
8647
|
+
return null;
|
|
8641
8648
|
}
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
const
|
|
8645
|
-
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
const
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
appName: String(appName),
|
|
8655
|
-
userId: String(userId),
|
|
8656
|
-
id: String(sessionIdFromResponse),
|
|
8657
|
-
state: getSessionApiResponse.sessionState || {},
|
|
8658
|
-
events: [],
|
|
8659
|
-
lastUpdateTime: updateTimestamp
|
|
8660
|
-
};
|
|
8661
|
-
let listEventsApiResponse = await apiClient.async_request({
|
|
8662
|
-
http_method: "GET",
|
|
8663
|
-
path: `reasoningEngines/${reasoningEngineId}/sessions/${sessionId}/events`,
|
|
8664
|
-
request_dict: {}
|
|
8665
|
-
});
|
|
8666
|
-
if (listEventsApiResponse.httpHeaders) {
|
|
8667
|
-
return session;
|
|
8668
|
-
}
|
|
8669
|
-
if (listEventsApiResponse.sessionEvents) {
|
|
8670
|
-
session.events.push(
|
|
8671
|
-
...listEventsApiResponse.sessionEvents.map(this.fromApiEvent)
|
|
8672
|
-
);
|
|
8673
|
-
}
|
|
8674
|
-
while (listEventsApiResponse.nextPageToken) {
|
|
8675
|
-
const pageToken = listEventsApiResponse.nextPageToken;
|
|
8676
|
-
listEventsApiResponse = await apiClient.async_request({
|
|
8677
|
-
http_method: "GET",
|
|
8678
|
-
path: `reasoningEngines/${reasoningEngineId}/sessions/${sessionId}/events?pageToken=${encodeURIComponent(pageToken)}`,
|
|
8679
|
-
request_dict: {}
|
|
8680
|
-
});
|
|
8681
|
-
if (listEventsApiResponse.sessionEvents) {
|
|
8682
|
-
session.events.push(
|
|
8683
|
-
...listEventsApiResponse.sessionEvents.map(this.fromApiEvent)
|
|
8684
|
-
);
|
|
8685
|
-
}
|
|
8686
|
-
}
|
|
8687
|
-
session.events = session.events.filter(
|
|
8688
|
-
(event) => event.timestamp <= updateTimestamp
|
|
8689
|
-
);
|
|
8690
|
-
session.events.sort((a, b) => a.timestamp - b.timestamp);
|
|
8691
|
-
if (config) {
|
|
8692
|
-
if (config.numRecentEvents) {
|
|
8693
|
-
session.events = session.events.slice(-config.numRecentEvents);
|
|
8694
|
-
} else if (config.afterTimestamp) {
|
|
8695
|
-
let i = session.events.length - 1;
|
|
8696
|
-
while (i >= 0) {
|
|
8697
|
-
if (session.events[i].timestamp < config.afterTimestamp) {
|
|
8698
|
-
break;
|
|
8699
|
-
}
|
|
8700
|
-
i--;
|
|
8701
|
-
}
|
|
8702
|
-
if (i >= 0) {
|
|
8703
|
-
session.events = session.events.slice(i);
|
|
8704
|
-
}
|
|
8649
|
+
const lastEvent = events[events.length - 1];
|
|
8650
|
+
if (lastEvent.content?.parts?.some((part) => part.functionResponse)) {
|
|
8651
|
+
const functionCallId = lastEvent.content.parts.find(
|
|
8652
|
+
(part) => part.functionResponse
|
|
8653
|
+
)?.functionResponse?.id;
|
|
8654
|
+
if (!functionCallId) return null;
|
|
8655
|
+
for (let i = events.length - 2; i >= 0; i--) {
|
|
8656
|
+
const event = events[i];
|
|
8657
|
+
const functionCalls = event.getFunctionCalls?.() || [];
|
|
8658
|
+
for (const functionCall of functionCalls) {
|
|
8659
|
+
if (functionCall.id === functionCallId) {
|
|
8660
|
+
return event;
|
|
8705
8661
|
}
|
|
8706
8662
|
}
|
|
8707
|
-
return session;
|
|
8708
|
-
} catch (error) {
|
|
8709
|
-
console.error(`Error getting session ${sessionId}:`, error);
|
|
8710
|
-
return void 0;
|
|
8711
8663
|
}
|
|
8712
8664
|
}
|
|
8713
|
-
|
|
8714
|
-
|
|
8715
|
-
|
|
8716
|
-
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8665
|
+
return null;
|
|
8666
|
+
}
|
|
8667
|
+
var Runner = class {
|
|
8668
|
+
/**
|
|
8669
|
+
* The app name of the runner.
|
|
8670
|
+
*/
|
|
8671
|
+
appName;
|
|
8672
|
+
/**
|
|
8673
|
+
* The root agent to run.
|
|
8674
|
+
*/
|
|
8675
|
+
agent;
|
|
8676
|
+
/**
|
|
8677
|
+
* The artifact service for the runner.
|
|
8678
|
+
*/
|
|
8679
|
+
artifactService;
|
|
8680
|
+
/**
|
|
8681
|
+
* The session service for the runner.
|
|
8682
|
+
*/
|
|
8683
|
+
sessionService;
|
|
8684
|
+
/**
|
|
8685
|
+
* The memory service for the runner.
|
|
8686
|
+
*/
|
|
8687
|
+
memoryService;
|
|
8688
|
+
/**
|
|
8689
|
+
* Initializes the Runner.
|
|
8690
|
+
*/
|
|
8691
|
+
constructor({
|
|
8692
|
+
appName,
|
|
8693
|
+
agent,
|
|
8694
|
+
artifactService,
|
|
8695
|
+
sessionService,
|
|
8696
|
+
memoryService
|
|
8697
|
+
}) {
|
|
8698
|
+
this.appName = appName;
|
|
8699
|
+
this.agent = agent;
|
|
8700
|
+
this.artifactService = artifactService;
|
|
8701
|
+
this.sessionService = sessionService;
|
|
8702
|
+
this.memoryService = memoryService;
|
|
8703
|
+
}
|
|
8704
|
+
/**
|
|
8705
|
+
* Runs the agent synchronously.
|
|
8706
|
+
* NOTE: This sync interface is only for local testing and convenience purpose.
|
|
8707
|
+
* Consider using `runAsync` for production usage.
|
|
8708
|
+
*/
|
|
8709
|
+
run({
|
|
8710
|
+
userId,
|
|
8711
|
+
sessionId,
|
|
8712
|
+
newMessage,
|
|
8713
|
+
runConfig = new RunConfig()
|
|
8714
|
+
}) {
|
|
8715
|
+
const eventQueue = [];
|
|
8716
|
+
let queueIndex = 0;
|
|
8717
|
+
let asyncCompleted = false;
|
|
8718
|
+
const invokeRunAsync = async () => {
|
|
8719
|
+
try {
|
|
8720
|
+
for await (const event of this.runAsync({
|
|
8734
8721
|
userId,
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8740
|
-
|
|
8722
|
+
sessionId,
|
|
8723
|
+
newMessage,
|
|
8724
|
+
runConfig
|
|
8725
|
+
})) {
|
|
8726
|
+
eventQueue.push(event);
|
|
8727
|
+
}
|
|
8728
|
+
} finally {
|
|
8729
|
+
eventQueue.push(null);
|
|
8730
|
+
asyncCompleted = true;
|
|
8741
8731
|
}
|
|
8742
|
-
}
|
|
8743
|
-
|
|
8732
|
+
};
|
|
8733
|
+
invokeRunAsync();
|
|
8734
|
+
return function* () {
|
|
8735
|
+
while (true) {
|
|
8736
|
+
while (queueIndex >= eventQueue.length && !asyncCompleted) {
|
|
8737
|
+
}
|
|
8738
|
+
if (queueIndex >= eventQueue.length && asyncCompleted) {
|
|
8739
|
+
break;
|
|
8740
|
+
}
|
|
8741
|
+
const event = eventQueue[queueIndex++];
|
|
8742
|
+
if (event === null) {
|
|
8743
|
+
break;
|
|
8744
|
+
}
|
|
8745
|
+
yield event;
|
|
8746
|
+
}
|
|
8747
|
+
}();
|
|
8744
8748
|
}
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8749
|
+
/**
|
|
8750
|
+
* Main entry method to run the agent in this runner.
|
|
8751
|
+
*/
|
|
8752
|
+
async *runAsync({
|
|
8753
|
+
userId,
|
|
8754
|
+
sessionId,
|
|
8755
|
+
newMessage,
|
|
8756
|
+
runConfig = new RunConfig()
|
|
8757
|
+
}) {
|
|
8758
|
+
const span = tracer.startSpan("invocation");
|
|
8748
8759
|
try {
|
|
8749
|
-
await
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8760
|
+
const session = await this.sessionService.getSession(
|
|
8761
|
+
this.appName,
|
|
8762
|
+
userId,
|
|
8763
|
+
sessionId
|
|
8764
|
+
);
|
|
8765
|
+
if (!session) {
|
|
8766
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
8767
|
+
}
|
|
8768
|
+
const invocationContext = this._newInvocationContext(session, {
|
|
8769
|
+
newMessage,
|
|
8770
|
+
runConfig
|
|
8753
8771
|
});
|
|
8772
|
+
if (newMessage) {
|
|
8773
|
+
await this._appendNewMessageToSession(
|
|
8774
|
+
session,
|
|
8775
|
+
newMessage,
|
|
8776
|
+
invocationContext,
|
|
8777
|
+
runConfig.saveInputBlobsAsArtifacts || false
|
|
8778
|
+
);
|
|
8779
|
+
}
|
|
8780
|
+
invocationContext.agent = this._findAgentToRun(session, this.agent);
|
|
8781
|
+
for await (const event of invocationContext.agent.runAsync(
|
|
8782
|
+
invocationContext
|
|
8783
|
+
)) {
|
|
8784
|
+
if (!event.partial) {
|
|
8785
|
+
await this.sessionService.appendEvent(session, event);
|
|
8786
|
+
}
|
|
8787
|
+
yield event;
|
|
8788
|
+
}
|
|
8754
8789
|
} catch (error) {
|
|
8755
|
-
|
|
8790
|
+
logger10.debug("Error running agent:", error);
|
|
8791
|
+
span.recordException(error);
|
|
8792
|
+
span.setStatus({
|
|
8793
|
+
code: SpanStatusCode.ERROR,
|
|
8794
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
8795
|
+
});
|
|
8756
8796
|
throw error;
|
|
8797
|
+
} finally {
|
|
8798
|
+
span.end();
|
|
8757
8799
|
}
|
|
8758
8800
|
}
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8801
|
+
/**
|
|
8802
|
+
* Appends a new message to the session.
|
|
8803
|
+
*/
|
|
8804
|
+
async _appendNewMessageToSession(session, newMessage, invocationContext, saveInputBlobsAsArtifacts = false) {
|
|
8805
|
+
if (!newMessage.parts) {
|
|
8806
|
+
throw new Error("No parts in the new_message.");
|
|
8807
|
+
}
|
|
8808
|
+
if (this.artifactService && saveInputBlobsAsArtifacts) {
|
|
8809
|
+
for (let i = 0; i < newMessage.parts.length; i++) {
|
|
8810
|
+
const part = newMessage.parts[i];
|
|
8811
|
+
if (!part.inlineData) {
|
|
8812
|
+
continue;
|
|
8813
|
+
}
|
|
8814
|
+
const fileName = `artifact_${invocationContext.invocationId}_${i}`;
|
|
8815
|
+
await this.artifactService.saveArtifact({
|
|
8816
|
+
appName: this.appName,
|
|
8817
|
+
userId: session.userId,
|
|
8818
|
+
sessionId: session.id,
|
|
8819
|
+
filename: fileName,
|
|
8820
|
+
artifact: part
|
|
8821
|
+
});
|
|
8822
|
+
newMessage.parts[i] = {
|
|
8823
|
+
text: `Uploaded file: ${fileName}. It is saved into artifacts`
|
|
8824
|
+
};
|
|
8825
|
+
}
|
|
8826
|
+
}
|
|
8827
|
+
const userContent = {
|
|
8828
|
+
...newMessage,
|
|
8829
|
+
role: "user"
|
|
8830
|
+
// Ensure role is set for content filtering
|
|
8831
|
+
};
|
|
8832
|
+
const event = new Event({
|
|
8833
|
+
invocationId: invocationContext.invocationId,
|
|
8834
|
+
author: "user",
|
|
8835
|
+
content: userContent
|
|
8767
8836
|
});
|
|
8768
|
-
|
|
8837
|
+
await this.sessionService.appendEvent(session, event);
|
|
8769
8838
|
}
|
|
8770
|
-
|
|
8771
|
-
|
|
8772
|
-
|
|
8839
|
+
/**
|
|
8840
|
+
* Finds the agent to run to continue the session.
|
|
8841
|
+
*/
|
|
8842
|
+
_findAgentToRun(session, rootAgent) {
|
|
8843
|
+
const event = _findFunctionCallEventIfLastEventIsFunctionResponse(session);
|
|
8844
|
+
if (event?.author) {
|
|
8845
|
+
return rootAgent.findAgent(event.author);
|
|
8773
8846
|
}
|
|
8774
|
-
|
|
8775
|
-
|
|
8847
|
+
const nonUserEvents = session.events?.filter((e) => e.author !== "user").reverse() || [];
|
|
8848
|
+
for (const event2 of nonUserEvents) {
|
|
8849
|
+
if (event2.author === rootAgent.name) {
|
|
8850
|
+
return rootAgent;
|
|
8851
|
+
}
|
|
8852
|
+
const agent = rootAgent.findSubAgent?.(event2.author);
|
|
8853
|
+
if (!agent) {
|
|
8854
|
+
logger10.debug(
|
|
8855
|
+
`Event from an unknown agent: ${event2.author}, event id: ${event2.id}`
|
|
8856
|
+
);
|
|
8857
|
+
continue;
|
|
8858
|
+
}
|
|
8859
|
+
if (this._isTransferableAcrossAgentTree(agent)) {
|
|
8860
|
+
return agent;
|
|
8861
|
+
}
|
|
8776
8862
|
}
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
|
|
8782
|
-
|
|
8863
|
+
return rootAgent;
|
|
8864
|
+
}
|
|
8865
|
+
/**
|
|
8866
|
+
* Whether the agent to run can transfer to any other agent in the agent tree.
|
|
8867
|
+
*/
|
|
8868
|
+
_isTransferableAcrossAgentTree(agentToRun) {
|
|
8869
|
+
let agent = agentToRun;
|
|
8870
|
+
while (agent) {
|
|
8871
|
+
if (!(agent instanceof LlmAgent)) {
|
|
8872
|
+
return false;
|
|
8873
|
+
}
|
|
8874
|
+
if (agent.disallowTransferToParent) {
|
|
8875
|
+
return false;
|
|
8876
|
+
}
|
|
8877
|
+
agent = agent.parentAgent || null;
|
|
8783
8878
|
}
|
|
8784
|
-
return
|
|
8879
|
+
return true;
|
|
8785
8880
|
}
|
|
8786
|
-
|
|
8787
|
-
|
|
8788
|
-
|
|
8789
|
-
|
|
8790
|
-
|
|
8791
|
-
|
|
8881
|
+
/**
|
|
8882
|
+
* Creates a new invocation context.
|
|
8883
|
+
*/
|
|
8884
|
+
_newInvocationContext(session, {
|
|
8885
|
+
newMessage,
|
|
8886
|
+
runConfig = new RunConfig()
|
|
8887
|
+
}) {
|
|
8888
|
+
const invocationId = newInvocationContextId();
|
|
8889
|
+
return new InvocationContext({
|
|
8890
|
+
artifactService: this.artifactService,
|
|
8891
|
+
sessionService: this.sessionService,
|
|
8892
|
+
memoryService: this.memoryService,
|
|
8893
|
+
invocationId,
|
|
8894
|
+
agent: this.agent,
|
|
8895
|
+
session,
|
|
8896
|
+
userContent: newMessage || null,
|
|
8897
|
+
liveRequestQueue: null,
|
|
8898
|
+
runConfig
|
|
8792
8899
|
});
|
|
8793
|
-
return client._api_client;
|
|
8794
|
-
}
|
|
8795
|
-
convertEventToJson(event) {
|
|
8796
|
-
const metadataJson = {
|
|
8797
|
-
partial: event.partial,
|
|
8798
|
-
turn_complete: event.turnComplete,
|
|
8799
|
-
interrupted: event.interrupted,
|
|
8800
|
-
branch: event.branch,
|
|
8801
|
-
long_running_tool_ids: event.longRunningToolIds ? Array.from(event.longRunningToolIds) : null
|
|
8802
|
-
};
|
|
8803
|
-
if (event.groundingMetadata) {
|
|
8804
|
-
metadataJson.grounding_metadata = event.groundingMetadata;
|
|
8805
|
-
}
|
|
8806
|
-
const eventJson = {
|
|
8807
|
-
author: event.author,
|
|
8808
|
-
invocation_id: event.invocationId,
|
|
8809
|
-
timestamp: {
|
|
8810
|
-
seconds: Math.floor(event.timestamp),
|
|
8811
|
-
nanos: Math.floor(
|
|
8812
|
-
(event.timestamp - Math.floor(event.timestamp)) * 1e9
|
|
8813
|
-
)
|
|
8814
|
-
},
|
|
8815
|
-
error_code: event.errorCode,
|
|
8816
|
-
error_message: event.errorMessage,
|
|
8817
|
-
event_metadata: metadataJson
|
|
8818
|
-
};
|
|
8819
|
-
if (event.actions) {
|
|
8820
|
-
const actionsJson = {
|
|
8821
|
-
skip_summarization: event.actions.skipSummarization,
|
|
8822
|
-
state_delta: event.actions.stateDelta,
|
|
8823
|
-
artifact_delta: event.actions.artifactDelta,
|
|
8824
|
-
transfer_agent: event.actions.transferToAgent,
|
|
8825
|
-
escalate: event.actions.escalate,
|
|
8826
|
-
requested_auth_configs: event.actions.requestedAuthConfigs
|
|
8827
|
-
};
|
|
8828
|
-
eventJson.actions = actionsJson;
|
|
8829
|
-
}
|
|
8830
|
-
if (event.content) {
|
|
8831
|
-
eventJson.content = event.content;
|
|
8832
|
-
}
|
|
8833
|
-
return eventJson;
|
|
8834
8900
|
}
|
|
8835
|
-
|
|
8836
|
-
|
|
8837
|
-
|
|
8838
|
-
|
|
8839
|
-
|
|
8840
|
-
|
|
8841
|
-
|
|
8842
|
-
|
|
8843
|
-
|
|
8844
|
-
|
|
8845
|
-
|
|
8846
|
-
|
|
8847
|
-
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
content: this.decodeContent(apiEvent.content),
|
|
8853
|
-
timestamp: new Date(apiEvent.timestamp).getTime() / 1e3
|
|
8901
|
+
};
|
|
8902
|
+
var InMemoryRunner = class extends Runner {
|
|
8903
|
+
/**
|
|
8904
|
+
* Deprecated. Please don't use. The in-memory session service for the runner.
|
|
8905
|
+
*/
|
|
8906
|
+
_inMemorySessionService;
|
|
8907
|
+
/**
|
|
8908
|
+
* Initializes the InMemoryRunner.
|
|
8909
|
+
*/
|
|
8910
|
+
constructor(agent, { appName = "InMemoryRunner" } = {}) {
|
|
8911
|
+
const inMemorySessionService = new InMemorySessionService();
|
|
8912
|
+
super({
|
|
8913
|
+
appName,
|
|
8914
|
+
agent,
|
|
8915
|
+
artifactService: new InMemoryArtifactService(),
|
|
8916
|
+
sessionService: inMemorySessionService,
|
|
8917
|
+
memoryService: new InMemoryMemoryService()
|
|
8854
8918
|
});
|
|
8855
|
-
|
|
8856
|
-
event.errorCode = apiEvent.errorCode;
|
|
8857
|
-
}
|
|
8858
|
-
if (apiEvent.errorMessage) {
|
|
8859
|
-
event.errorMessage = apiEvent.errorMessage;
|
|
8860
|
-
}
|
|
8861
|
-
if (apiEvent.eventMetadata) {
|
|
8862
|
-
const longRunningToolIdsList = apiEvent.eventMetadata.longRunningToolIds;
|
|
8863
|
-
event.partial = apiEvent.eventMetadata.partial;
|
|
8864
|
-
event.turnComplete = apiEvent.eventMetadata.turnComplete;
|
|
8865
|
-
event.interrupted = apiEvent.eventMetadata.interrupted;
|
|
8866
|
-
event.branch = apiEvent.eventMetadata.branch;
|
|
8867
|
-
event.groundingMetadata = this.decodeGroundingMetadata(
|
|
8868
|
-
apiEvent.eventMetadata.groundingMetadata
|
|
8869
|
-
);
|
|
8870
|
-
event.longRunningToolIds = longRunningToolIdsList ? new Set(longRunningToolIdsList) : void 0;
|
|
8871
|
-
}
|
|
8872
|
-
return event;
|
|
8873
|
-
}
|
|
8874
|
-
decodeContent(content) {
|
|
8875
|
-
if (!content) return void 0;
|
|
8876
|
-
return content;
|
|
8877
|
-
}
|
|
8878
|
-
decodeGroundingMetadata(groundingMetadata) {
|
|
8879
|
-
if (!groundingMetadata) return void 0;
|
|
8880
|
-
return groundingMetadata;
|
|
8919
|
+
this._inMemorySessionService = inMemorySessionService;
|
|
8881
8920
|
}
|
|
8882
8921
|
};
|
|
8883
8922
|
|
|
8884
|
-
// src/
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
8888
|
-
|
|
8889
|
-
|
|
8890
|
-
|
|
8891
|
-
|
|
8892
|
-
|
|
8893
|
-
|
|
8894
|
-
console.error("Failed to initialize database:", error);
|
|
8895
|
-
});
|
|
8896
|
-
}
|
|
8923
|
+
// src/agents/agent-builder.ts
|
|
8924
|
+
var AgentBuilder = class _AgentBuilder {
|
|
8925
|
+
config;
|
|
8926
|
+
sessionConfig;
|
|
8927
|
+
agentType = "llm";
|
|
8928
|
+
/**
|
|
8929
|
+
* Private constructor - use static create() method
|
|
8930
|
+
*/
|
|
8931
|
+
constructor(name) {
|
|
8932
|
+
this.config = { name };
|
|
8897
8933
|
}
|
|
8898
8934
|
/**
|
|
8899
|
-
*
|
|
8935
|
+
* Create a new AgentBuilder instance
|
|
8936
|
+
* @param name The name of the agent (defaults to "default_agent")
|
|
8937
|
+
* @returns New AgentBuilder instance
|
|
8900
8938
|
*/
|
|
8901
|
-
|
|
8902
|
-
|
|
8903
|
-
return;
|
|
8904
|
-
}
|
|
8905
|
-
try {
|
|
8906
|
-
await this.db.schema.createTable("sessions").ifNotExists().addColumn("id", "varchar(128)", (col) => col.notNull()).addColumn("app_name", "varchar(128)", (col) => col.notNull()).addColumn("user_id", "varchar(128)", (col) => col.notNull()).addColumn("state", "text", (col) => col.defaultTo("{}")).addColumn(
|
|
8907
|
-
"create_time",
|
|
8908
|
-
"timestamp",
|
|
8909
|
-
(col) => col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
8910
|
-
).addColumn(
|
|
8911
|
-
"update_time",
|
|
8912
|
-
"timestamp",
|
|
8913
|
-
(col) => col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
8914
|
-
).addPrimaryKeyConstraint("sessions_pk", ["app_name", "user_id", "id"]).execute();
|
|
8915
|
-
await this.db.schema.createTable("events").ifNotExists().addColumn("id", "varchar(128)", (col) => col.notNull()).addColumn("app_name", "varchar(128)", (col) => col.notNull()).addColumn("user_id", "varchar(128)", (col) => col.notNull()).addColumn("session_id", "varchar(128)", (col) => col.notNull()).addColumn("invocation_id", "varchar(256)").addColumn("author", "varchar(256)").addColumn("branch", "varchar(256)").addColumn(
|
|
8916
|
-
"timestamp",
|
|
8917
|
-
"timestamp",
|
|
8918
|
-
(col) => col.defaultTo(sql`CURRENT_TIMESTAMP`)
|
|
8919
|
-
).addColumn("content", "text").addColumn("actions", "text").addColumn("long_running_tool_ids_json", "text").addColumn("grounding_metadata", "text").addColumn("partial", "boolean").addColumn("turn_complete", "boolean").addColumn("error_code", "varchar(256)").addColumn("error_message", "varchar(1024)").addColumn("interrupted", "boolean").addPrimaryKeyConstraint("events_pk", [
|
|
8920
|
-
"id",
|
|
8921
|
-
"app_name",
|
|
8922
|
-
"user_id",
|
|
8923
|
-
"session_id"
|
|
8924
|
-
]).addForeignKeyConstraint(
|
|
8925
|
-
"events_session_fk",
|
|
8926
|
-
["app_name", "user_id", "session_id"],
|
|
8927
|
-
"sessions",
|
|
8928
|
-
["app_name", "user_id", "id"]
|
|
8929
|
-
).execute();
|
|
8930
|
-
await this.db.schema.createTable("app_states").ifNotExists().addColumn("app_name", "varchar(128)", (col) => col.primaryKey()).addColumn("state", "text", (col) => col.defaultTo("{}")).addColumn(
|
|
8931
|
-
"update_time",
|
|
8932
|
-
"timestamp",
|
|
8933
|
-
(col) => col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
8934
|
-
).execute();
|
|
8935
|
-
await this.db.schema.createTable("user_states").ifNotExists().addColumn("app_name", "varchar(128)", (col) => col.notNull()).addColumn("user_id", "varchar(128)", (col) => col.notNull()).addColumn("state", "text", (col) => col.defaultTo("{}")).addColumn(
|
|
8936
|
-
"update_time",
|
|
8937
|
-
"timestamp",
|
|
8938
|
-
(col) => col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
8939
|
-
).addPrimaryKeyConstraint("user_states_pk", ["app_name", "user_id"]).execute();
|
|
8940
|
-
await this.db.schema.createIndex("idx_sessions_user_id").ifNotExists().on("sessions").column("user_id").execute();
|
|
8941
|
-
this.initialized = true;
|
|
8942
|
-
} catch (error) {
|
|
8943
|
-
console.error("Error initializing database:", error);
|
|
8944
|
-
throw error;
|
|
8945
|
-
}
|
|
8939
|
+
static create(name = "default_agent") {
|
|
8940
|
+
return new _AgentBuilder(name);
|
|
8946
8941
|
}
|
|
8947
8942
|
/**
|
|
8948
|
-
*
|
|
8943
|
+
* Convenience method to start building with a model directly
|
|
8944
|
+
* @param model The model identifier (e.g., "gemini-2.5-flash")
|
|
8945
|
+
* @returns New AgentBuilder instance with model set
|
|
8949
8946
|
*/
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
await this.initializeDatabase();
|
|
8953
|
-
}
|
|
8947
|
+
static withModel(model) {
|
|
8948
|
+
return new _AgentBuilder("default_agent").withModel(model);
|
|
8954
8949
|
}
|
|
8955
|
-
|
|
8956
|
-
|
|
8950
|
+
/**
|
|
8951
|
+
* Set the model for the agent
|
|
8952
|
+
* @param model The model identifier (e.g., "gemini-2.5-flash")
|
|
8953
|
+
* @returns This builder instance for chaining
|
|
8954
|
+
*/
|
|
8955
|
+
withModel(model) {
|
|
8956
|
+
this.config.model = model;
|
|
8957
|
+
return this;
|
|
8957
8958
|
}
|
|
8958
8959
|
/**
|
|
8959
|
-
*
|
|
8960
|
+
* Set the description for the agent
|
|
8961
|
+
* @param description Agent description
|
|
8962
|
+
* @returns This builder instance for chaining
|
|
8960
8963
|
*/
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
|
|
8964
|
-
|
|
8965
|
-
|
|
8966
|
-
|
|
8964
|
+
withDescription(description) {
|
|
8965
|
+
this.config.description = description;
|
|
8966
|
+
return this;
|
|
8967
|
+
}
|
|
8968
|
+
/**
|
|
8969
|
+
* Set the instruction for the agent
|
|
8970
|
+
* @param instruction System instruction for the agent
|
|
8971
|
+
* @returns This builder instance for chaining
|
|
8972
|
+
*/
|
|
8973
|
+
withInstruction(instruction) {
|
|
8974
|
+
this.config.instruction = instruction;
|
|
8975
|
+
return this;
|
|
8976
|
+
}
|
|
8977
|
+
/**
|
|
8978
|
+
* Add tools to the agent
|
|
8979
|
+
* @param tools Tools to add to the agent
|
|
8980
|
+
* @returns This builder instance for chaining
|
|
8981
|
+
*/
|
|
8982
|
+
withTools(...tools) {
|
|
8983
|
+
this.config.tools = [...this.config.tools || [], ...tools];
|
|
8984
|
+
return this;
|
|
8985
|
+
}
|
|
8986
|
+
/**
|
|
8987
|
+
* Set the planner for the agent
|
|
8988
|
+
* @param planner The planner to use
|
|
8989
|
+
* @returns This builder instance for chaining
|
|
8990
|
+
*/
|
|
8991
|
+
withPlanner(planner) {
|
|
8992
|
+
this.config.planner = planner;
|
|
8993
|
+
return this;
|
|
8994
|
+
}
|
|
8995
|
+
/**
|
|
8996
|
+
* Configure as a sequential agent
|
|
8997
|
+
* @param subAgents Sub-agents to execute in sequence
|
|
8998
|
+
* @returns This builder instance for chaining
|
|
8999
|
+
*/
|
|
9000
|
+
asSequential(subAgents) {
|
|
9001
|
+
this.agentType = "sequential";
|
|
9002
|
+
this.config.subAgents = subAgents;
|
|
9003
|
+
return this;
|
|
9004
|
+
}
|
|
9005
|
+
/**
|
|
9006
|
+
* Configure as a parallel agent
|
|
9007
|
+
* @param subAgents Sub-agents to execute in parallel
|
|
9008
|
+
* @returns This builder instance for chaining
|
|
9009
|
+
*/
|
|
9010
|
+
asParallel(subAgents) {
|
|
9011
|
+
this.agentType = "parallel";
|
|
9012
|
+
this.config.subAgents = subAgents;
|
|
9013
|
+
return this;
|
|
9014
|
+
}
|
|
9015
|
+
/**
|
|
9016
|
+
* Configure as a loop agent
|
|
9017
|
+
* @param subAgents Sub-agents to execute iteratively
|
|
9018
|
+
* @param maxIterations Maximum number of iterations
|
|
9019
|
+
* @returns This builder instance for chaining
|
|
9020
|
+
*/
|
|
9021
|
+
asLoop(subAgents, maxIterations = 3) {
|
|
9022
|
+
this.agentType = "loop";
|
|
9023
|
+
this.config.subAgents = subAgents;
|
|
9024
|
+
this.config.maxIterations = maxIterations;
|
|
9025
|
+
return this;
|
|
9026
|
+
}
|
|
9027
|
+
/**
|
|
9028
|
+
* Configure as a LangGraph agent
|
|
9029
|
+
* @param nodes Graph nodes defining the workflow
|
|
9030
|
+
* @param rootNode The starting node name
|
|
9031
|
+
* @returns This builder instance for chaining
|
|
9032
|
+
*/
|
|
9033
|
+
asLangGraph(nodes, rootNode) {
|
|
9034
|
+
this.agentType = "langgraph";
|
|
9035
|
+
this.config.nodes = nodes;
|
|
9036
|
+
this.config.rootNode = rootNode;
|
|
9037
|
+
return this;
|
|
9038
|
+
}
|
|
9039
|
+
/**
|
|
9040
|
+
* Configure session management
|
|
9041
|
+
* @param service Session service to use
|
|
9042
|
+
* @param userId User identifier
|
|
9043
|
+
* @param appName Application name
|
|
9044
|
+
* @param memoryService Optional memory service
|
|
9045
|
+
* @param artifactService Optional artifact service
|
|
9046
|
+
* @returns This builder instance for chaining
|
|
9047
|
+
*/
|
|
9048
|
+
withSession(service, userId, appName, memoryService, artifactService) {
|
|
9049
|
+
this.sessionConfig = {
|
|
9050
|
+
service,
|
|
9051
|
+
userId,
|
|
9052
|
+
appName,
|
|
9053
|
+
memoryService,
|
|
9054
|
+
artifactService
|
|
9055
|
+
};
|
|
9056
|
+
return this;
|
|
9057
|
+
}
|
|
9058
|
+
/**
|
|
9059
|
+
* Configure with an in-memory session (for quick setup)
|
|
9060
|
+
* @param appName Application name
|
|
9061
|
+
* @param userId User identifier
|
|
9062
|
+
* @returns This builder instance for chaining
|
|
9063
|
+
*/
|
|
9064
|
+
withQuickSession(appName, userId) {
|
|
9065
|
+
return this.withSession(new InMemorySessionService(), userId, appName);
|
|
9066
|
+
}
|
|
9067
|
+
/**
|
|
9068
|
+
* Build the agent and optionally create runner and session
|
|
9069
|
+
* @returns Built agent with optional runner and session
|
|
9070
|
+
*/
|
|
9071
|
+
async build() {
|
|
9072
|
+
const agent = this.createAgent();
|
|
9073
|
+
let runner;
|
|
9074
|
+
let session;
|
|
9075
|
+
if (this.sessionConfig) {
|
|
9076
|
+
session = await this.sessionConfig.service.createSession(
|
|
9077
|
+
this.sessionConfig.appName,
|
|
9078
|
+
this.sessionConfig.userId
|
|
9079
|
+
);
|
|
9080
|
+
const runnerConfig = {
|
|
9081
|
+
appName: this.sessionConfig.appName,
|
|
9082
|
+
agent,
|
|
9083
|
+
sessionService: this.sessionConfig.service
|
|
9084
|
+
};
|
|
9085
|
+
if (this.sessionConfig.memoryService) {
|
|
9086
|
+
runnerConfig.memoryService = this.sessionConfig.memoryService;
|
|
9087
|
+
}
|
|
9088
|
+
if (this.sessionConfig.artifactService) {
|
|
9089
|
+
runnerConfig.artifactService = this.sessionConfig.artifactService;
|
|
9090
|
+
}
|
|
9091
|
+
runner = new Runner(runnerConfig);
|
|
8967
9092
|
}
|
|
9093
|
+
return { agent, runner, session };
|
|
8968
9094
|
}
|
|
8969
9095
|
/**
|
|
8970
|
-
*
|
|
8971
|
-
*
|
|
9096
|
+
* Quick execution helper - build and run a message
|
|
9097
|
+
* @param message Message to send to the agent
|
|
9098
|
+
* @returns Agent response
|
|
8972
9099
|
*/
|
|
8973
|
-
|
|
8974
|
-
if (
|
|
8975
|
-
|
|
9100
|
+
async ask(message) {
|
|
9101
|
+
if (!this.sessionConfig) {
|
|
9102
|
+
const userId = `user-${this.config.name}`;
|
|
9103
|
+
const appName = `session-${this.config.name}`;
|
|
9104
|
+
this.withQuickSession(appName, userId);
|
|
8976
9105
|
}
|
|
8977
|
-
|
|
8978
|
-
|
|
9106
|
+
const { runner, session } = await this.build();
|
|
9107
|
+
if (!runner || !session) {
|
|
9108
|
+
throw new Error("Failed to create runner and session");
|
|
8979
9109
|
}
|
|
8980
|
-
|
|
8981
|
-
|
|
9110
|
+
let response = "";
|
|
9111
|
+
for await (const event of runner.runAsync({
|
|
9112
|
+
userId: this.sessionConfig.userId,
|
|
9113
|
+
sessionId: session.id,
|
|
9114
|
+
newMessage: {
|
|
9115
|
+
parts: [{ text: message }]
|
|
9116
|
+
}
|
|
9117
|
+
})) {
|
|
9118
|
+
if (event.content?.parts) {
|
|
9119
|
+
const content = event.content.parts.map((part) => part.text || "").join("");
|
|
9120
|
+
if (content) {
|
|
9121
|
+
response += content;
|
|
9122
|
+
}
|
|
9123
|
+
}
|
|
8982
9124
|
}
|
|
8983
|
-
return
|
|
9125
|
+
return response;
|
|
9126
|
+
}
|
|
9127
|
+
/**
|
|
9128
|
+
* Create the appropriate agent type based on configuration
|
|
9129
|
+
* @returns Created agent instance
|
|
9130
|
+
*/
|
|
9131
|
+
createAgent() {
|
|
9132
|
+
switch (this.agentType) {
|
|
9133
|
+
case "sequential":
|
|
9134
|
+
if (!this.config.subAgents) {
|
|
9135
|
+
throw new Error("Sub-agents required for sequential agent");
|
|
9136
|
+
}
|
|
9137
|
+
return new SequentialAgent({
|
|
9138
|
+
name: this.config.name,
|
|
9139
|
+
description: this.config.description || "",
|
|
9140
|
+
subAgents: this.config.subAgents
|
|
9141
|
+
});
|
|
9142
|
+
case "parallel":
|
|
9143
|
+
if (!this.config.subAgents) {
|
|
9144
|
+
throw new Error("Sub-agents required for parallel agent");
|
|
9145
|
+
}
|
|
9146
|
+
return new ParallelAgent({
|
|
9147
|
+
name: this.config.name,
|
|
9148
|
+
description: this.config.description || "",
|
|
9149
|
+
subAgents: this.config.subAgents
|
|
9150
|
+
});
|
|
9151
|
+
case "loop":
|
|
9152
|
+
if (!this.config.subAgents) {
|
|
9153
|
+
throw new Error("Sub-agents required for loop agent");
|
|
9154
|
+
}
|
|
9155
|
+
return new LoopAgent({
|
|
9156
|
+
name: this.config.name,
|
|
9157
|
+
description: this.config.description || "",
|
|
9158
|
+
subAgents: this.config.subAgents,
|
|
9159
|
+
maxIterations: this.config.maxIterations || 3
|
|
9160
|
+
});
|
|
9161
|
+
case "langgraph":
|
|
9162
|
+
if (!this.config.nodes || !this.config.rootNode) {
|
|
9163
|
+
throw new Error("Nodes and root node required for LangGraph agent");
|
|
9164
|
+
}
|
|
9165
|
+
return new LangGraphAgent({
|
|
9166
|
+
name: this.config.name,
|
|
9167
|
+
description: this.config.description || "",
|
|
9168
|
+
nodes: this.config.nodes,
|
|
9169
|
+
rootNode: this.config.rootNode
|
|
9170
|
+
});
|
|
9171
|
+
default:
|
|
9172
|
+
return new LlmAgent({
|
|
9173
|
+
name: this.config.name,
|
|
9174
|
+
model: this.config.model,
|
|
9175
|
+
description: this.config.description,
|
|
9176
|
+
instruction: this.config.instruction,
|
|
9177
|
+
tools: this.config.tools,
|
|
9178
|
+
planner: this.config.planner
|
|
9179
|
+
});
|
|
9180
|
+
}
|
|
9181
|
+
}
|
|
9182
|
+
};
|
|
9183
|
+
|
|
9184
|
+
// src/memory/index.ts
|
|
9185
|
+
var memory_exports = {};
|
|
9186
|
+
__export(memory_exports, {
|
|
9187
|
+
InMemoryMemoryService: () => InMemoryMemoryService
|
|
9188
|
+
});
|
|
9189
|
+
|
|
9190
|
+
// src/sessions/index.ts
|
|
9191
|
+
var sessions_exports = {};
|
|
9192
|
+
__export(sessions_exports, {
|
|
9193
|
+
BaseSessionService: () => BaseSessionService,
|
|
9194
|
+
DatabaseSessionService: () => DatabaseSessionService,
|
|
9195
|
+
InMemorySessionService: () => InMemorySessionService,
|
|
9196
|
+
State: () => State,
|
|
9197
|
+
VertexAiSessionService: () => VertexAiSessionService,
|
|
9198
|
+
createDatabaseSessionService: () => createDatabaseSessionService,
|
|
9199
|
+
createMysqlSessionService: () => createMysqlSessionService,
|
|
9200
|
+
createPostgresSessionService: () => createPostgresSessionService,
|
|
9201
|
+
createSqliteSessionService: () => createSqliteSessionService
|
|
9202
|
+
});
|
|
9203
|
+
|
|
9204
|
+
// src/sessions/vertex-ai-session-service.ts
|
|
9205
|
+
var VertexAiSessionService = class extends BaseSessionService {
|
|
9206
|
+
project;
|
|
9207
|
+
location;
|
|
9208
|
+
agentEngineId;
|
|
9209
|
+
/**
|
|
9210
|
+
* Initializes the VertexAiSessionService.
|
|
9211
|
+
*/
|
|
9212
|
+
constructor(options = {}) {
|
|
9213
|
+
super();
|
|
9214
|
+
this.project = options.project;
|
|
9215
|
+
this.location = options.location;
|
|
9216
|
+
this.agentEngineId = options.agentEngineId;
|
|
8984
9217
|
}
|
|
8985
9218
|
async createSession(appName, userId, state, sessionId) {
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
|
|
8993
|
-
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
8997
|
-
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
if (Object.keys(userStateDelta).length > 0) {
|
|
9016
|
-
await trx.updateTable("user_states").set({
|
|
9017
|
-
state: JSON.stringify(currentUserState),
|
|
9018
|
-
update_time: sql`CURRENT_TIMESTAMP`
|
|
9019
|
-
}).where("app_name", "=", appName).where("user_id", "=", userId).execute();
|
|
9219
|
+
if (sessionId) {
|
|
9220
|
+
throw new Error(
|
|
9221
|
+
"User-provided Session id is not supported for VertexAISessionService."
|
|
9222
|
+
);
|
|
9223
|
+
}
|
|
9224
|
+
const reasoningEngineId = this.getReasoningEngineId(appName);
|
|
9225
|
+
const apiClient = this.getApiClient();
|
|
9226
|
+
const sessionJsonDict = { user_id: userId };
|
|
9227
|
+
if (state) {
|
|
9228
|
+
sessionJsonDict.session_state = state;
|
|
9229
|
+
}
|
|
9230
|
+
const apiResponse = await apiClient.async_request({
|
|
9231
|
+
http_method: "POST",
|
|
9232
|
+
path: `reasoningEngines/${reasoningEngineId}/sessions`,
|
|
9233
|
+
request_dict: sessionJsonDict
|
|
9234
|
+
});
|
|
9235
|
+
console.info("Create Session response", apiResponse);
|
|
9236
|
+
const createdSessionId = apiResponse.name.split("/").slice(-3, -2)[0];
|
|
9237
|
+
const operationId = apiResponse.name.split("/").pop();
|
|
9238
|
+
let maxRetryAttempt = 5;
|
|
9239
|
+
let lroResponse = null;
|
|
9240
|
+
while (maxRetryAttempt >= 0) {
|
|
9241
|
+
lroResponse = await apiClient.async_request({
|
|
9242
|
+
http_method: "GET",
|
|
9243
|
+
path: `operations/${operationId}`,
|
|
9244
|
+
request_dict: {}
|
|
9245
|
+
});
|
|
9246
|
+
if (lroResponse?.done) {
|
|
9247
|
+
break;
|
|
9020
9248
|
}
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
-
const mergedState = this.mergeState(
|
|
9028
|
-
currentAppState,
|
|
9029
|
-
currentUserState,
|
|
9030
|
-
sessionStateDelta
|
|
9249
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
9250
|
+
maxRetryAttempt--;
|
|
9251
|
+
}
|
|
9252
|
+
if (!lroResponse || !lroResponse.done) {
|
|
9253
|
+
throw new Error(
|
|
9254
|
+
`Timeout waiting for operation ${operationId} to complete.`
|
|
9031
9255
|
);
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
events: [],
|
|
9038
|
-
// Fixed type annotation
|
|
9039
|
-
lastUpdateTime: this.timestampToUnixSeconds(result.update_time)
|
|
9040
|
-
};
|
|
9256
|
+
}
|
|
9257
|
+
const getSessionApiResponse = await apiClient.async_request({
|
|
9258
|
+
http_method: "GET",
|
|
9259
|
+
path: `reasoningEngines/${reasoningEngineId}/sessions/${createdSessionId}`,
|
|
9260
|
+
request_dict: {}
|
|
9041
9261
|
});
|
|
9262
|
+
const updateTimestamp = new Date(getSessionApiResponse.updateTime).getTime() / 1e3;
|
|
9263
|
+
return {
|
|
9264
|
+
appName: String(appName),
|
|
9265
|
+
userId: String(userId),
|
|
9266
|
+
id: String(createdSessionId),
|
|
9267
|
+
state: getSessionApiResponse.sessionState || {},
|
|
9268
|
+
events: [],
|
|
9269
|
+
lastUpdateTime: updateTimestamp
|
|
9270
|
+
};
|
|
9042
9271
|
}
|
|
9043
9272
|
async getSession(appName, userId, sessionId, config) {
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9273
|
+
const reasoningEngineId = this.getReasoningEngineId(appName);
|
|
9274
|
+
const apiClient = this.getApiClient();
|
|
9275
|
+
try {
|
|
9276
|
+
const getSessionApiResponse = await apiClient.async_request({
|
|
9277
|
+
http_method: "GET",
|
|
9278
|
+
path: `reasoningEngines/${reasoningEngineId}/sessions/${sessionId}`,
|
|
9279
|
+
request_dict: {}
|
|
9280
|
+
});
|
|
9281
|
+
const sessionIdFromResponse = getSessionApiResponse.name.split("/").pop();
|
|
9282
|
+
const updateTimestamp = new Date(getSessionApiResponse.updateTime).getTime() / 1e3;
|
|
9283
|
+
const session = {
|
|
9284
|
+
appName: String(appName),
|
|
9285
|
+
userId: String(userId),
|
|
9286
|
+
id: String(sessionIdFromResponse),
|
|
9287
|
+
state: getSessionApiResponse.sessionState || {},
|
|
9288
|
+
events: [],
|
|
9289
|
+
lastUpdateTime: updateTimestamp
|
|
9290
|
+
};
|
|
9291
|
+
let listEventsApiResponse = await apiClient.async_request({
|
|
9292
|
+
http_method: "GET",
|
|
9293
|
+
path: `reasoningEngines/${reasoningEngineId}/sessions/${sessionId}/events`,
|
|
9294
|
+
request_dict: {}
|
|
9295
|
+
});
|
|
9296
|
+
if (listEventsApiResponse.httpHeaders) {
|
|
9297
|
+
return session;
|
|
9049
9298
|
}
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
"timestamp",
|
|
9054
|
-
">=",
|
|
9055
|
-
new Date(config.afterTimestamp * 1e3)
|
|
9299
|
+
if (listEventsApiResponse.sessionEvents) {
|
|
9300
|
+
session.events.push(
|
|
9301
|
+
...listEventsApiResponse.sessionEvents.map(this.fromApiEvent)
|
|
9056
9302
|
);
|
|
9057
9303
|
}
|
|
9058
|
-
|
|
9059
|
-
|
|
9304
|
+
while (listEventsApiResponse.nextPageToken) {
|
|
9305
|
+
const pageToken = listEventsApiResponse.nextPageToken;
|
|
9306
|
+
listEventsApiResponse = await apiClient.async_request({
|
|
9307
|
+
http_method: "GET",
|
|
9308
|
+
path: `reasoningEngines/${reasoningEngineId}/sessions/${sessionId}/events?pageToken=${encodeURIComponent(pageToken)}`,
|
|
9309
|
+
request_dict: {}
|
|
9310
|
+
});
|
|
9311
|
+
if (listEventsApiResponse.sessionEvents) {
|
|
9312
|
+
session.events.push(
|
|
9313
|
+
...listEventsApiResponse.sessionEvents.map(this.fromApiEvent)
|
|
9314
|
+
);
|
|
9315
|
+
}
|
|
9060
9316
|
}
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
const userState = await trx.selectFrom("user_states").selectAll().where("app_name", "=", appName).where("user_id", "=", userId).executeTakeFirst();
|
|
9064
|
-
const currentAppState = this.parseJsonSafely(appState?.state, {});
|
|
9065
|
-
const currentUserState = this.parseJsonSafely(userState?.state, {});
|
|
9066
|
-
const sessionState = this.parseJsonSafely(storageSession.state, {});
|
|
9067
|
-
const mergedState = this.mergeState(
|
|
9068
|
-
currentAppState,
|
|
9069
|
-
currentUserState,
|
|
9070
|
-
sessionState
|
|
9317
|
+
session.events = session.events.filter(
|
|
9318
|
+
(event) => event.timestamp <= updateTimestamp
|
|
9071
9319
|
);
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9086
|
-
|
|
9087
|
-
|
|
9088
|
-
|
|
9089
|
-
|
|
9320
|
+
session.events.sort((a, b) => a.timestamp - b.timestamp);
|
|
9321
|
+
if (config) {
|
|
9322
|
+
if (config.numRecentEvents) {
|
|
9323
|
+
session.events = session.events.slice(-config.numRecentEvents);
|
|
9324
|
+
} else if (config.afterTimestamp) {
|
|
9325
|
+
let i = session.events.length - 1;
|
|
9326
|
+
while (i >= 0) {
|
|
9327
|
+
if (session.events[i].timestamp < config.afterTimestamp) {
|
|
9328
|
+
break;
|
|
9329
|
+
}
|
|
9330
|
+
i--;
|
|
9331
|
+
}
|
|
9332
|
+
if (i >= 0) {
|
|
9333
|
+
session.events = session.events.slice(i);
|
|
9334
|
+
}
|
|
9335
|
+
}
|
|
9336
|
+
}
|
|
9337
|
+
return session;
|
|
9338
|
+
} catch (error) {
|
|
9339
|
+
console.error(`Error getting session ${sessionId}:`, error);
|
|
9340
|
+
return void 0;
|
|
9341
|
+
}
|
|
9090
9342
|
}
|
|
9091
9343
|
async listSessions(appName, userId) {
|
|
9092
|
-
|
|
9093
|
-
const
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9344
|
+
const reasoningEngineId = this.getReasoningEngineId(appName);
|
|
9345
|
+
const apiClient = this.getApiClient();
|
|
9346
|
+
let path2 = `reasoningEngines/${reasoningEngineId}/sessions`;
|
|
9347
|
+
if (userId) {
|
|
9348
|
+
const parsedUserId = encodeURIComponent(`"${userId}"`);
|
|
9349
|
+
path2 = `${path2}?filter=user_id=${parsedUserId}`;
|
|
9350
|
+
}
|
|
9351
|
+
const apiResponse = await apiClient.async_request({
|
|
9352
|
+
http_method: "GET",
|
|
9353
|
+
path: path2,
|
|
9354
|
+
request_dict: {}
|
|
9355
|
+
});
|
|
9356
|
+
if (apiResponse.httpHeaders) {
|
|
9357
|
+
return { sessions: [] };
|
|
9358
|
+
}
|
|
9359
|
+
const sessions = [];
|
|
9360
|
+
if (apiResponse.sessions) {
|
|
9361
|
+
for (const apiSession of apiResponse.sessions) {
|
|
9362
|
+
const session = {
|
|
9363
|
+
appName,
|
|
9364
|
+
userId,
|
|
9365
|
+
id: apiSession.name.split("/").pop(),
|
|
9366
|
+
state: {},
|
|
9367
|
+
events: [],
|
|
9368
|
+
lastUpdateTime: new Date(apiSession.updateTime).getTime() / 1e3
|
|
9369
|
+
};
|
|
9370
|
+
sessions.push(session);
|
|
9371
|
+
}
|
|
9372
|
+
}
|
|
9103
9373
|
return { sessions };
|
|
9104
9374
|
}
|
|
9105
9375
|
async deleteSession(appName, userId, sessionId) {
|
|
9106
|
-
|
|
9107
|
-
|
|
9376
|
+
const reasoningEngineId = this.getReasoningEngineId(appName);
|
|
9377
|
+
const apiClient = this.getApiClient();
|
|
9378
|
+
try {
|
|
9379
|
+
await apiClient.async_request({
|
|
9380
|
+
http_method: "DELETE",
|
|
9381
|
+
path: `reasoningEngines/${reasoningEngineId}/sessions/${sessionId}`,
|
|
9382
|
+
request_dict: {}
|
|
9383
|
+
});
|
|
9384
|
+
} catch (error) {
|
|
9385
|
+
console.error(`Error deleting session ${sessionId}:`, error);
|
|
9386
|
+
throw error;
|
|
9387
|
+
}
|
|
9108
9388
|
}
|
|
9109
9389
|
async appendEvent(session, event) {
|
|
9110
|
-
await
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
throw new Error(
|
|
9118
|
-
`The last_update_time provided in the session object ${new Date(session.lastUpdateTime * 1e3).toISOString()} is earlier than the update_time in the storage_session ${storageSession.update_time.toISOString()}. Please check if it is a stale session.`
|
|
9119
|
-
);
|
|
9120
|
-
}
|
|
9121
|
-
const appState = await trx.selectFrom("app_states").selectAll().where("app_name", "=", session.appName).executeTakeFirst();
|
|
9122
|
-
const userState = await trx.selectFrom("user_states").selectAll().where("app_name", "=", session.appName).where("user_id", "=", session.userId).executeTakeFirst();
|
|
9123
|
-
let currentAppState = this.parseJsonSafely(appState?.state, {});
|
|
9124
|
-
let currentUserState = this.parseJsonSafely(userState?.state, {});
|
|
9125
|
-
let sessionState = this.parseJsonSafely(storageSession.state, {});
|
|
9126
|
-
let appStateDelta = {};
|
|
9127
|
-
let userStateDelta = {};
|
|
9128
|
-
let sessionStateDelta = {};
|
|
9129
|
-
if (event.actions?.stateDelta) {
|
|
9130
|
-
const deltas = this.extractStateDelta(event.actions.stateDelta);
|
|
9131
|
-
appStateDelta = deltas.appStateDelta;
|
|
9132
|
-
userStateDelta = deltas.userStateDelta;
|
|
9133
|
-
sessionStateDelta = deltas.sessionStateDelta;
|
|
9134
|
-
}
|
|
9135
|
-
if (Object.keys(appStateDelta).length > 0) {
|
|
9136
|
-
currentAppState = { ...currentAppState, ...appStateDelta };
|
|
9137
|
-
await trx.updateTable("app_states").set({
|
|
9138
|
-
state: JSON.stringify(currentAppState),
|
|
9139
|
-
update_time: sql`CURRENT_TIMESTAMP`
|
|
9140
|
-
}).where("app_name", "=", session.appName).execute();
|
|
9141
|
-
}
|
|
9142
|
-
if (Object.keys(userStateDelta).length > 0) {
|
|
9143
|
-
currentUserState = { ...currentUserState, ...userStateDelta };
|
|
9144
|
-
await trx.updateTable("user_states").set({
|
|
9145
|
-
state: JSON.stringify(currentUserState),
|
|
9146
|
-
update_time: sql`CURRENT_TIMESTAMP`
|
|
9147
|
-
}).where("app_name", "=", session.appName).where("user_id", "=", session.userId).execute();
|
|
9148
|
-
}
|
|
9149
|
-
if (Object.keys(sessionStateDelta).length > 0) {
|
|
9150
|
-
sessionState = { ...sessionState, ...sessionStateDelta };
|
|
9151
|
-
await trx.updateTable("sessions").set({
|
|
9152
|
-
state: JSON.stringify(sessionState),
|
|
9153
|
-
update_time: sql`CURRENT_TIMESTAMP`
|
|
9154
|
-
}).where("app_name", "=", session.appName).where("user_id", "=", session.userId).where("id", "=", session.id).execute();
|
|
9155
|
-
}
|
|
9156
|
-
await trx.insertInto("events").values({
|
|
9157
|
-
...this.eventToStorageEvent(session, event),
|
|
9158
|
-
timestamp: sql`CURRENT_TIMESTAMP`
|
|
9159
|
-
}).execute();
|
|
9160
|
-
const updatedSession = await trx.selectFrom("sessions").select("update_time").where("app_name", "=", session.appName).where("user_id", "=", session.userId).where("id", "=", session.id).executeTakeFirstOrThrow();
|
|
9161
|
-
session.lastUpdateTime = this.timestampToUnixSeconds(
|
|
9162
|
-
updatedSession.update_time
|
|
9163
|
-
);
|
|
9164
|
-
super.appendEvent(session, event);
|
|
9165
|
-
return event;
|
|
9390
|
+
await super.appendEvent(session, event);
|
|
9391
|
+
const reasoningEngineId = this.getReasoningEngineId(session.appName);
|
|
9392
|
+
const apiClient = this.getApiClient();
|
|
9393
|
+
await apiClient.async_request({
|
|
9394
|
+
http_method: "POST",
|
|
9395
|
+
path: `reasoningEngines/${reasoningEngineId}/sessions/${session.id}:appendEvent`,
|
|
9396
|
+
request_dict: this.convertEventToJson(event)
|
|
9166
9397
|
});
|
|
9398
|
+
return event;
|
|
9167
9399
|
}
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
extractStateDelta(state) {
|
|
9172
|
-
const appStateDelta = {};
|
|
9173
|
-
const userStateDelta = {};
|
|
9174
|
-
const sessionStateDelta = {};
|
|
9175
|
-
if (state) {
|
|
9176
|
-
for (const [key, value] of Object.entries(state)) {
|
|
9177
|
-
if (key.startsWith("app_")) {
|
|
9178
|
-
appStateDelta[key.substring(4)] = value;
|
|
9179
|
-
} else if (key.startsWith("user_")) {
|
|
9180
|
-
userStateDelta[key.substring(5)] = value;
|
|
9181
|
-
} else if (!key.startsWith("temp_")) {
|
|
9182
|
-
sessionStateDelta[key] = value;
|
|
9183
|
-
}
|
|
9184
|
-
}
|
|
9400
|
+
getReasoningEngineId(appName) {
|
|
9401
|
+
if (this.agentEngineId) {
|
|
9402
|
+
return this.agentEngineId;
|
|
9185
9403
|
}
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
/**
|
|
9189
|
-
* Merge states for response (similar to Python implementation)
|
|
9190
|
-
*/
|
|
9191
|
-
mergeState(appState, userState, sessionState) {
|
|
9192
|
-
const mergedState = { ...sessionState };
|
|
9193
|
-
for (const [key, value] of Object.entries(appState)) {
|
|
9194
|
-
mergedState[`app_${key}`] = value;
|
|
9404
|
+
if (/^\d+$/.test(appName)) {
|
|
9405
|
+
return appName;
|
|
9195
9406
|
}
|
|
9196
|
-
|
|
9197
|
-
|
|
9407
|
+
const pattern = /^projects\/([a-zA-Z0-9-_]+)\/locations\/([a-zA-Z0-9-_]+)\/reasoningEngines\/(\d+)$/;
|
|
9408
|
+
const match = appName.match(pattern);
|
|
9409
|
+
if (!match) {
|
|
9410
|
+
throw new Error(
|
|
9411
|
+
`App name ${appName} is not valid. It should either be the full ReasoningEngine resource name, or the reasoning engine id.`
|
|
9412
|
+
);
|
|
9198
9413
|
}
|
|
9199
|
-
return
|
|
9414
|
+
return match[3];
|
|
9200
9415
|
}
|
|
9201
|
-
|
|
9202
|
-
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
session_id: session.id,
|
|
9210
|
-
invocation_id: event.invocationId || "",
|
|
9211
|
-
author: event.author || "",
|
|
9212
|
-
branch: event.branch || null,
|
|
9213
|
-
content: event.content ? JSON.stringify(event.content) : null,
|
|
9214
|
-
actions: event.actions ? JSON.stringify(event.actions) : null,
|
|
9215
|
-
long_running_tool_ids_json: event.longRunningToolIds ? JSON.stringify(Array.from(event.longRunningToolIds)) : null,
|
|
9216
|
-
grounding_metadata: event.groundingMetadata ? JSON.stringify(event.groundingMetadata) : null,
|
|
9217
|
-
partial: event.partial || null,
|
|
9218
|
-
turn_complete: event.turnComplete || null,
|
|
9219
|
-
error_code: event.errorCode || null,
|
|
9220
|
-
error_message: event.errorMessage || null,
|
|
9221
|
-
interrupted: event.interrupted || null
|
|
9222
|
-
};
|
|
9416
|
+
getApiClient() {
|
|
9417
|
+
const { GoogleGenAI: GoogleGenAI2 } = __require("@google/genai");
|
|
9418
|
+
const client = new GoogleGenAI2({
|
|
9419
|
+
vertexai: true,
|
|
9420
|
+
project: this.project,
|
|
9421
|
+
location: this.location
|
|
9422
|
+
});
|
|
9423
|
+
return client._api_client;
|
|
9223
9424
|
}
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
author: storageEvent.author,
|
|
9232
|
-
branch: storageEvent.branch || void 0,
|
|
9233
|
-
timestamp: this.timestampToUnixSeconds(storageEvent.timestamp),
|
|
9234
|
-
content: storageEvent.content ? this.parseJsonSafely(storageEvent.content, null) : void 0,
|
|
9235
|
-
actions: storageEvent.actions ? this.parseJsonSafely(storageEvent.actions, null) : void 0,
|
|
9236
|
-
longRunningToolIds: storageEvent.long_running_tool_ids_json ? new Set(
|
|
9237
|
-
this.parseJsonSafely(storageEvent.long_running_tool_ids_json, [])
|
|
9238
|
-
) : void 0,
|
|
9239
|
-
groundingMetadata: storageEvent.grounding_metadata ? this.parseJsonSafely(storageEvent.grounding_metadata, null) : void 0,
|
|
9240
|
-
partial: storageEvent.partial || void 0,
|
|
9241
|
-
turnComplete: storageEvent.turn_complete || void 0,
|
|
9242
|
-
errorCode: storageEvent.error_code || void 0,
|
|
9243
|
-
errorMessage: storageEvent.error_message || void 0,
|
|
9244
|
-
interrupted: storageEvent.interrupted || void 0
|
|
9425
|
+
convertEventToJson(event) {
|
|
9426
|
+
const metadataJson = {
|
|
9427
|
+
partial: event.partial,
|
|
9428
|
+
turn_complete: event.turnComplete,
|
|
9429
|
+
interrupted: event.interrupted,
|
|
9430
|
+
branch: event.branch,
|
|
9431
|
+
long_running_tool_ids: event.longRunningToolIds ? Array.from(event.longRunningToolIds) : null
|
|
9245
9432
|
};
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
if (baseEvent.actions && typeof baseEvent.actions === "object" && "functionResponses" in baseEvent.actions) {
|
|
9258
|
-
return baseEvent.actions.functionResponses || [];
|
|
9259
|
-
}
|
|
9260
|
-
return [];
|
|
9433
|
+
if (event.groundingMetadata) {
|
|
9434
|
+
metadataJson.grounding_metadata = event.groundingMetadata;
|
|
9435
|
+
}
|
|
9436
|
+
const eventJson = {
|
|
9437
|
+
author: event.author,
|
|
9438
|
+
invocation_id: event.invocationId,
|
|
9439
|
+
timestamp: {
|
|
9440
|
+
seconds: Math.floor(event.timestamp),
|
|
9441
|
+
nanos: Math.floor(
|
|
9442
|
+
(event.timestamp - Math.floor(event.timestamp)) * 1e9
|
|
9443
|
+
)
|
|
9261
9444
|
},
|
|
9262
|
-
|
|
9263
|
-
|
|
9264
|
-
|
|
9265
|
-
}
|
|
9266
|
-
return false;
|
|
9267
|
-
}
|
|
9445
|
+
error_code: event.errorCode,
|
|
9446
|
+
error_message: event.errorMessage,
|
|
9447
|
+
event_metadata: metadataJson
|
|
9268
9448
|
};
|
|
9269
|
-
|
|
9270
|
-
|
|
9271
|
-
|
|
9272
|
-
|
|
9273
|
-
|
|
9274
|
-
|
|
9275
|
-
|
|
9276
|
-
|
|
9449
|
+
if (event.actions) {
|
|
9450
|
+
const actionsJson = {
|
|
9451
|
+
skip_summarization: event.actions.skipSummarization,
|
|
9452
|
+
state_delta: event.actions.stateDelta,
|
|
9453
|
+
artifact_delta: event.actions.artifactDelta,
|
|
9454
|
+
transfer_agent: event.actions.transferToAgent,
|
|
9455
|
+
escalate: event.actions.escalate,
|
|
9456
|
+
requested_auth_configs: event.actions.requestedAuthConfigs
|
|
9457
|
+
};
|
|
9458
|
+
eventJson.actions = actionsJson;
|
|
9277
9459
|
}
|
|
9278
|
-
|
|
9279
|
-
|
|
9280
|
-
session.state[key] = value;
|
|
9281
|
-
}
|
|
9460
|
+
if (event.content) {
|
|
9461
|
+
eventJson.content = event.content;
|
|
9282
9462
|
}
|
|
9463
|
+
return eventJson;
|
|
9283
9464
|
}
|
|
9284
|
-
|
|
9285
|
-
|
|
9286
|
-
|
|
9287
|
-
|
|
9288
|
-
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
|
|
9292
|
-
|
|
9293
|
-
|
|
9294
|
-
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9301
|
-
|
|
9302
|
-
|
|
9303
|
-
|
|
9304
|
-
|
|
9305
|
-
|
|
9306
|
-
|
|
9307
|
-
|
|
9308
|
-
|
|
9309
|
-
|
|
9310
|
-
|
|
9311
|
-
|
|
9312
|
-
|
|
9313
|
-
|
|
9314
|
-
|
|
9315
|
-
|
|
9316
|
-
|
|
9317
|
-
|
|
9318
|
-
|
|
9319
|
-
|
|
9320
|
-
|
|
9321
|
-
|
|
9322
|
-
} catch (error) {
|
|
9323
|
-
throw createDependencyError("mysql2", "MySQL");
|
|
9465
|
+
fromApiEvent(apiEvent) {
|
|
9466
|
+
let eventActions = new EventActions();
|
|
9467
|
+
if (apiEvent.actions) {
|
|
9468
|
+
eventActions = new EventActions({
|
|
9469
|
+
skipSummarization: apiEvent.actions.skipSummarization,
|
|
9470
|
+
stateDelta: apiEvent.actions.stateDelta || {},
|
|
9471
|
+
artifactDelta: apiEvent.actions.artifactDelta || {},
|
|
9472
|
+
transferToAgent: apiEvent.actions.transferAgent,
|
|
9473
|
+
escalate: apiEvent.actions.escalate,
|
|
9474
|
+
requestedAuthConfigs: apiEvent.actions.requestedAuthConfigs || {}
|
|
9475
|
+
});
|
|
9476
|
+
}
|
|
9477
|
+
const event = new Event({
|
|
9478
|
+
id: apiEvent.name.split("/").pop(),
|
|
9479
|
+
invocationId: apiEvent.invocationId,
|
|
9480
|
+
author: apiEvent.author,
|
|
9481
|
+
actions: eventActions,
|
|
9482
|
+
content: this.decodeContent(apiEvent.content),
|
|
9483
|
+
timestamp: new Date(apiEvent.timestamp).getTime() / 1e3
|
|
9484
|
+
});
|
|
9485
|
+
if (apiEvent.errorCode) {
|
|
9486
|
+
event.errorCode = apiEvent.errorCode;
|
|
9487
|
+
}
|
|
9488
|
+
if (apiEvent.errorMessage) {
|
|
9489
|
+
event.errorMessage = apiEvent.errorMessage;
|
|
9490
|
+
}
|
|
9491
|
+
if (apiEvent.eventMetadata) {
|
|
9492
|
+
const longRunningToolIdsList = apiEvent.eventMetadata.longRunningToolIds;
|
|
9493
|
+
event.partial = apiEvent.eventMetadata.partial;
|
|
9494
|
+
event.turnComplete = apiEvent.eventMetadata.turnComplete;
|
|
9495
|
+
event.interrupted = apiEvent.eventMetadata.interrupted;
|
|
9496
|
+
event.branch = apiEvent.eventMetadata.branch;
|
|
9497
|
+
event.groundingMetadata = this.decodeGroundingMetadata(
|
|
9498
|
+
apiEvent.eventMetadata.groundingMetadata
|
|
9499
|
+
);
|
|
9500
|
+
event.longRunningToolIds = longRunningToolIdsList ? new Set(longRunningToolIdsList) : void 0;
|
|
9501
|
+
}
|
|
9502
|
+
return event;
|
|
9324
9503
|
}
|
|
9325
|
-
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
uri: connectionString,
|
|
9329
|
-
...options
|
|
9330
|
-
})
|
|
9331
|
-
})
|
|
9332
|
-
});
|
|
9333
|
-
return new DatabaseSessionService({ db });
|
|
9334
|
-
}
|
|
9335
|
-
function createSqliteSessionService(filename, options) {
|
|
9336
|
-
let Database;
|
|
9337
|
-
try {
|
|
9338
|
-
Database = __require("better-sqlite3");
|
|
9339
|
-
} catch (error) {
|
|
9340
|
-
throw createDependencyError("better-sqlite3", "SQLite");
|
|
9504
|
+
decodeContent(content) {
|
|
9505
|
+
if (!content) return void 0;
|
|
9506
|
+
return content;
|
|
9341
9507
|
}
|
|
9342
|
-
|
|
9343
|
-
|
|
9344
|
-
|
|
9345
|
-
})
|
|
9346
|
-
});
|
|
9347
|
-
return new DatabaseSessionService({ db });
|
|
9348
|
-
}
|
|
9349
|
-
function createDatabaseSessionService(databaseUrl, options) {
|
|
9350
|
-
if (databaseUrl.startsWith("postgres://") || databaseUrl.startsWith("postgresql://")) {
|
|
9351
|
-
return createPostgresSessionService(databaseUrl, options);
|
|
9508
|
+
decodeGroundingMetadata(groundingMetadata) {
|
|
9509
|
+
if (!groundingMetadata) return void 0;
|
|
9510
|
+
return groundingMetadata;
|
|
9352
9511
|
}
|
|
9353
|
-
|
|
9354
|
-
|
|
9512
|
+
};
|
|
9513
|
+
|
|
9514
|
+
// src/sessions/database-session-service.ts
|
|
9515
|
+
import { sql } from "kysely";
|
|
9516
|
+
var DatabaseSessionService = class extends BaseSessionService {
|
|
9517
|
+
db;
|
|
9518
|
+
initialized = false;
|
|
9519
|
+
constructor(config) {
|
|
9520
|
+
super();
|
|
9521
|
+
this.db = config.db;
|
|
9522
|
+
if (!config.skipTableCreation) {
|
|
9523
|
+
this.initializeDatabase().catch((error) => {
|
|
9524
|
+
console.error("Failed to initialize database:", error);
|
|
9525
|
+
});
|
|
9526
|
+
}
|
|
9355
9527
|
}
|
|
9356
|
-
|
|
9357
|
-
|
|
9358
|
-
|
|
9528
|
+
/**
|
|
9529
|
+
* Initialize the database by creating required tables if they don't exist
|
|
9530
|
+
*/
|
|
9531
|
+
async initializeDatabase() {
|
|
9532
|
+
if (this.initialized) {
|
|
9533
|
+
return;
|
|
9534
|
+
}
|
|
9535
|
+
try {
|
|
9536
|
+
await this.db.schema.createTable("sessions").ifNotExists().addColumn("id", "varchar(128)", (col) => col.notNull()).addColumn("app_name", "varchar(128)", (col) => col.notNull()).addColumn("user_id", "varchar(128)", (col) => col.notNull()).addColumn("state", "text", (col) => col.defaultTo("{}")).addColumn(
|
|
9537
|
+
"create_time",
|
|
9538
|
+
"timestamp",
|
|
9539
|
+
(col) => col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
9540
|
+
).addColumn(
|
|
9541
|
+
"update_time",
|
|
9542
|
+
"timestamp",
|
|
9543
|
+
(col) => col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
9544
|
+
).addPrimaryKeyConstraint("sessions_pk", ["app_name", "user_id", "id"]).execute();
|
|
9545
|
+
await this.db.schema.createTable("events").ifNotExists().addColumn("id", "varchar(128)", (col) => col.notNull()).addColumn("app_name", "varchar(128)", (col) => col.notNull()).addColumn("user_id", "varchar(128)", (col) => col.notNull()).addColumn("session_id", "varchar(128)", (col) => col.notNull()).addColumn("invocation_id", "varchar(256)").addColumn("author", "varchar(256)").addColumn("branch", "varchar(256)").addColumn(
|
|
9546
|
+
"timestamp",
|
|
9547
|
+
"timestamp",
|
|
9548
|
+
(col) => col.defaultTo(sql`CURRENT_TIMESTAMP`)
|
|
9549
|
+
).addColumn("content", "text").addColumn("actions", "text").addColumn("long_running_tool_ids_json", "text").addColumn("grounding_metadata", "text").addColumn("partial", "boolean").addColumn("turn_complete", "boolean").addColumn("error_code", "varchar(256)").addColumn("error_message", "varchar(1024)").addColumn("interrupted", "boolean").addPrimaryKeyConstraint("events_pk", [
|
|
9550
|
+
"id",
|
|
9551
|
+
"app_name",
|
|
9552
|
+
"user_id",
|
|
9553
|
+
"session_id"
|
|
9554
|
+
]).addForeignKeyConstraint(
|
|
9555
|
+
"events_session_fk",
|
|
9556
|
+
["app_name", "user_id", "session_id"],
|
|
9557
|
+
"sessions",
|
|
9558
|
+
["app_name", "user_id", "id"]
|
|
9559
|
+
).execute();
|
|
9560
|
+
await this.db.schema.createTable("app_states").ifNotExists().addColumn("app_name", "varchar(128)", (col) => col.primaryKey()).addColumn("state", "text", (col) => col.defaultTo("{}")).addColumn(
|
|
9561
|
+
"update_time",
|
|
9562
|
+
"timestamp",
|
|
9563
|
+
(col) => col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
9564
|
+
).execute();
|
|
9565
|
+
await this.db.schema.createTable("user_states").ifNotExists().addColumn("app_name", "varchar(128)", (col) => col.notNull()).addColumn("user_id", "varchar(128)", (col) => col.notNull()).addColumn("state", "text", (col) => col.defaultTo("{}")).addColumn(
|
|
9566
|
+
"update_time",
|
|
9567
|
+
"timestamp",
|
|
9568
|
+
(col) => col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
9569
|
+
).addPrimaryKeyConstraint("user_states_pk", ["app_name", "user_id"]).execute();
|
|
9570
|
+
await this.db.schema.createIndex("idx_sessions_user_id").ifNotExists().on("sessions").column("user_id").execute();
|
|
9571
|
+
this.initialized = true;
|
|
9572
|
+
} catch (error) {
|
|
9573
|
+
console.error("Error initializing database:", error);
|
|
9574
|
+
throw error;
|
|
9575
|
+
}
|
|
9359
9576
|
}
|
|
9360
|
-
|
|
9361
|
-
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
|
|
9367
|
-
} from "@google-cloud/storage";
|
|
9368
|
-
var logger9 = new Logger({ name: "GcsArtifactService" });
|
|
9369
|
-
var GcsArtifactService = class {
|
|
9370
|
-
bucketName;
|
|
9371
|
-
storageClient;
|
|
9372
|
-
bucket;
|
|
9373
|
-
constructor(bucketName, options) {
|
|
9374
|
-
this.bucketName = bucketName;
|
|
9375
|
-
this.storageClient = new Storage(options);
|
|
9376
|
-
this.bucket = this.storageClient.bucket(this.bucketName);
|
|
9577
|
+
/**
|
|
9578
|
+
* Ensure database is initialized before any operation
|
|
9579
|
+
*/
|
|
9580
|
+
async ensureInitialized() {
|
|
9581
|
+
if (!this.initialized) {
|
|
9582
|
+
await this.initializeDatabase();
|
|
9583
|
+
}
|
|
9377
9584
|
}
|
|
9378
|
-
|
|
9379
|
-
return
|
|
9585
|
+
generateSessionId() {
|
|
9586
|
+
return `session-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
9380
9587
|
}
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9588
|
+
/**
|
|
9589
|
+
* Helper to safely parse JSON strings
|
|
9590
|
+
*/
|
|
9591
|
+
parseJsonSafely(jsonString, defaultValue) {
|
|
9592
|
+
if (!jsonString) return defaultValue;
|
|
9593
|
+
try {
|
|
9594
|
+
return JSON.parse(jsonString);
|
|
9595
|
+
} catch {
|
|
9596
|
+
return defaultValue;
|
|
9384
9597
|
}
|
|
9385
|
-
return `${appName}/${userId}/${sessionId}/${filename}/${version}`;
|
|
9386
9598
|
}
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
|
|
9390
|
-
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
}
|
|
9395
|
-
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
);
|
|
9403
|
-
const blob = this.bucket.file(blobName);
|
|
9404
|
-
await blob.save(artifact.inlineData.data, {
|
|
9405
|
-
contentType: artifact.inlineData.mimeType,
|
|
9406
|
-
preconditionOpts: { ifGenerationMatch: 0 }
|
|
9407
|
-
});
|
|
9408
|
-
return version;
|
|
9599
|
+
/**
|
|
9600
|
+
* Convert database timestamp to Unix seconds
|
|
9601
|
+
* Handles different timestamp formats from different databases
|
|
9602
|
+
*/
|
|
9603
|
+
timestampToUnixSeconds(timestamp) {
|
|
9604
|
+
if (timestamp instanceof Date) {
|
|
9605
|
+
return timestamp.getTime() / 1e3;
|
|
9606
|
+
}
|
|
9607
|
+
if (typeof timestamp === "string") {
|
|
9608
|
+
return new Date(timestamp).getTime() / 1e3;
|
|
9609
|
+
}
|
|
9610
|
+
if (typeof timestamp === "number") {
|
|
9611
|
+
return timestamp > 1e10 ? timestamp / 1e3 : timestamp;
|
|
9612
|
+
}
|
|
9613
|
+
return Date.now() / 1e3;
|
|
9409
9614
|
}
|
|
9410
|
-
async
|
|
9411
|
-
|
|
9412
|
-
const
|
|
9413
|
-
|
|
9414
|
-
const
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
|
|
9419
|
-
|
|
9420
|
-
|
|
9421
|
-
|
|
9615
|
+
async createSession(appName, userId, state, sessionId) {
|
|
9616
|
+
await this.ensureInitialized();
|
|
9617
|
+
const id = sessionId?.trim() || this.generateSessionId();
|
|
9618
|
+
return await this.db.transaction().execute(async (trx) => {
|
|
9619
|
+
const appState = await trx.selectFrom("app_states").selectAll().where("app_name", "=", appName).executeTakeFirst();
|
|
9620
|
+
const userState = await trx.selectFrom("user_states").selectAll().where("app_name", "=", appName).where("user_id", "=", userId).executeTakeFirst();
|
|
9621
|
+
let currentAppState = this.parseJsonSafely(appState?.state, {});
|
|
9622
|
+
let currentUserState = this.parseJsonSafely(userState?.state, {});
|
|
9623
|
+
if (!appState) {
|
|
9624
|
+
await trx.insertInto("app_states").values({
|
|
9625
|
+
app_name: appName,
|
|
9626
|
+
state: "{}"
|
|
9627
|
+
}).execute();
|
|
9422
9628
|
}
|
|
9423
|
-
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
filename,
|
|
9430
|
-
version
|
|
9431
|
-
);
|
|
9432
|
-
const blob = this.bucket.file(blobName);
|
|
9433
|
-
try {
|
|
9434
|
-
const [metadata] = await blob.getMetadata();
|
|
9435
|
-
const [artifactBuffer] = await blob.download();
|
|
9436
|
-
if (!artifactBuffer) {
|
|
9437
|
-
return null;
|
|
9629
|
+
if (!userState) {
|
|
9630
|
+
await trx.insertInto("user_states").values({
|
|
9631
|
+
app_name: appName,
|
|
9632
|
+
user_id: userId,
|
|
9633
|
+
state: "{}"
|
|
9634
|
+
}).execute();
|
|
9438
9635
|
}
|
|
9439
|
-
const
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
if (error?.code === 404) {
|
|
9448
|
-
return null;
|
|
9636
|
+
const { appStateDelta, userStateDelta, sessionStateDelta } = this.extractStateDelta(state);
|
|
9637
|
+
currentAppState = { ...currentAppState, ...appStateDelta };
|
|
9638
|
+
currentUserState = { ...currentUserState, ...userStateDelta };
|
|
9639
|
+
if (Object.keys(appStateDelta).length > 0) {
|
|
9640
|
+
await trx.updateTable("app_states").set({
|
|
9641
|
+
state: JSON.stringify(currentAppState),
|
|
9642
|
+
update_time: sql`CURRENT_TIMESTAMP`
|
|
9643
|
+
}).where("app_name", "=", appName).execute();
|
|
9449
9644
|
}
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
const filenames = /* @__PURE__ */ new Set();
|
|
9456
|
-
const processBlobs = (blobNames) => {
|
|
9457
|
-
for (const name of blobNames) {
|
|
9458
|
-
const parts = name.split("/");
|
|
9459
|
-
if (parts.length === 5) {
|
|
9460
|
-
const filename = parts[3];
|
|
9461
|
-
filenames.add(filename);
|
|
9462
|
-
}
|
|
9645
|
+
if (Object.keys(userStateDelta).length > 0) {
|
|
9646
|
+
await trx.updateTable("user_states").set({
|
|
9647
|
+
state: JSON.stringify(currentUserState),
|
|
9648
|
+
update_time: sql`CURRENT_TIMESTAMP`
|
|
9649
|
+
}).where("app_name", "=", appName).where("user_id", "=", userId).execute();
|
|
9463
9650
|
}
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
const { appName, userId, sessionId, filename } = args;
|
|
9475
|
-
const versions = await this.listVersions({
|
|
9476
|
-
appName,
|
|
9477
|
-
userId,
|
|
9478
|
-
sessionId,
|
|
9479
|
-
filename
|
|
9480
|
-
});
|
|
9481
|
-
const deletePromises = versions.map((version) => {
|
|
9482
|
-
const blobName = this.getBlobName(
|
|
9483
|
-
appName,
|
|
9484
|
-
userId,
|
|
9485
|
-
sessionId,
|
|
9486
|
-
filename,
|
|
9487
|
-
version
|
|
9651
|
+
const result = await trx.insertInto("sessions").values({
|
|
9652
|
+
id,
|
|
9653
|
+
app_name: appName,
|
|
9654
|
+
user_id: userId,
|
|
9655
|
+
state: JSON.stringify(sessionStateDelta)
|
|
9656
|
+
}).returningAll().executeTakeFirstOrThrow();
|
|
9657
|
+
const mergedState = this.mergeState(
|
|
9658
|
+
currentAppState,
|
|
9659
|
+
currentUserState,
|
|
9660
|
+
sessionStateDelta
|
|
9488
9661
|
);
|
|
9489
|
-
return
|
|
9662
|
+
return {
|
|
9663
|
+
id: result.id,
|
|
9664
|
+
appName: result.app_name,
|
|
9665
|
+
userId: result.user_id,
|
|
9666
|
+
state: mergedState,
|
|
9667
|
+
events: [],
|
|
9668
|
+
// Fixed type annotation
|
|
9669
|
+
lastUpdateTime: this.timestampToUnixSeconds(result.update_time)
|
|
9670
|
+
};
|
|
9490
9671
|
});
|
|
9491
|
-
await Promise.all(deletePromises);
|
|
9492
9672
|
}
|
|
9493
|
-
async
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
const parts = blob.name.split("/");
|
|
9500
|
-
if (parts.length === 5) {
|
|
9501
|
-
const versionStr = parts[4];
|
|
9502
|
-
const versionNum = Number.parseInt(versionStr, 10);
|
|
9503
|
-
if (!Number.isNaN(versionNum)) {
|
|
9504
|
-
versions.push(versionNum);
|
|
9505
|
-
}
|
|
9673
|
+
async getSession(appName, userId, sessionId, config) {
|
|
9674
|
+
await this.ensureInitialized();
|
|
9675
|
+
return await this.db.transaction().execute(async (trx) => {
|
|
9676
|
+
const storageSession = await trx.selectFrom("sessions").selectAll().where("app_name", "=", appName).where("user_id", "=", userId).where("id", "=", sessionId).executeTakeFirst();
|
|
9677
|
+
if (!storageSession) {
|
|
9678
|
+
return void 0;
|
|
9506
9679
|
}
|
|
9507
|
-
|
|
9508
|
-
|
|
9680
|
+
let eventQuery = trx.selectFrom("events").selectAll().where("session_id", "=", sessionId).orderBy("timestamp", "desc");
|
|
9681
|
+
if (config?.afterTimestamp) {
|
|
9682
|
+
eventQuery = eventQuery.where(
|
|
9683
|
+
"timestamp",
|
|
9684
|
+
">=",
|
|
9685
|
+
new Date(config.afterTimestamp * 1e3)
|
|
9686
|
+
);
|
|
9687
|
+
}
|
|
9688
|
+
if (config?.numRecentEvents) {
|
|
9689
|
+
eventQuery = eventQuery.limit(config.numRecentEvents);
|
|
9690
|
+
}
|
|
9691
|
+
const storageEvents = await eventQuery.execute();
|
|
9692
|
+
const appState = await trx.selectFrom("app_states").selectAll().where("app_name", "=", appName).executeTakeFirst();
|
|
9693
|
+
const userState = await trx.selectFrom("user_states").selectAll().where("app_name", "=", appName).where("user_id", "=", userId).executeTakeFirst();
|
|
9694
|
+
const currentAppState = this.parseJsonSafely(appState?.state, {});
|
|
9695
|
+
const currentUserState = this.parseJsonSafely(userState?.state, {});
|
|
9696
|
+
const sessionState = this.parseJsonSafely(storageSession.state, {});
|
|
9697
|
+
const mergedState = this.mergeState(
|
|
9698
|
+
currentAppState,
|
|
9699
|
+
currentUserState,
|
|
9700
|
+
sessionState
|
|
9701
|
+
);
|
|
9702
|
+
const events = storageEvents.reverse().map((storageEvent) => this.storageEventToEvent(storageEvent));
|
|
9703
|
+
return {
|
|
9704
|
+
id: sessionId,
|
|
9705
|
+
appName,
|
|
9706
|
+
userId,
|
|
9707
|
+
state: mergedState,
|
|
9708
|
+
events,
|
|
9709
|
+
// Now properly typed as Event[]
|
|
9710
|
+
lastUpdateTime: this.timestampToUnixSeconds(storageSession.update_time)
|
|
9711
|
+
};
|
|
9712
|
+
});
|
|
9509
9713
|
}
|
|
9510
|
-
|
|
9511
|
-
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
artifacts = /* @__PURE__ */ new Map();
|
|
9517
|
-
fileHasUserNamespace(filename) {
|
|
9518
|
-
return filename.startsWith("user:");
|
|
9714
|
+
async updateSession(session) {
|
|
9715
|
+
await this.ensureInitialized();
|
|
9716
|
+
await this.db.updateTable("sessions").set({
|
|
9717
|
+
state: JSON.stringify(session.state),
|
|
9718
|
+
update_time: sql`CURRENT_TIMESTAMP`
|
|
9719
|
+
}).where("app_name", "=", session.appName).where("user_id", "=", session.userId).where("id", "=", session.id).execute();
|
|
9519
9720
|
}
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9524
|
-
|
|
9721
|
+
async listSessions(appName, userId) {
|
|
9722
|
+
await this.ensureInitialized();
|
|
9723
|
+
const results = await this.db.selectFrom("sessions").selectAll().where("app_name", "=", appName).where("user_id", "=", userId).execute();
|
|
9724
|
+
const sessions = results.map((storageSession) => ({
|
|
9725
|
+
id: storageSession.id,
|
|
9726
|
+
appName: storageSession.app_name,
|
|
9727
|
+
userId: storageSession.user_id,
|
|
9728
|
+
state: {},
|
|
9729
|
+
events: [],
|
|
9730
|
+
// Fixed type annotation
|
|
9731
|
+
lastUpdateTime: this.timestampToUnixSeconds(storageSession.update_time)
|
|
9732
|
+
}));
|
|
9733
|
+
return { sessions };
|
|
9525
9734
|
}
|
|
9526
|
-
async
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
if (!this.artifacts.has(path2)) {
|
|
9530
|
-
this.artifacts.set(path2, []);
|
|
9531
|
-
}
|
|
9532
|
-
const versions = this.artifacts.get(path2);
|
|
9533
|
-
const version = versions.length;
|
|
9534
|
-
versions.push(artifact);
|
|
9535
|
-
return version;
|
|
9735
|
+
async deleteSession(appName, userId, sessionId) {
|
|
9736
|
+
await this.ensureInitialized();
|
|
9737
|
+
await this.db.deleteFrom("sessions").where("app_name", "=", appName).where("user_id", "=", userId).where("id", "=", sessionId).execute();
|
|
9536
9738
|
}
|
|
9537
|
-
async
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
if (!versions || versions.length === 0) {
|
|
9542
|
-
return null;
|
|
9543
|
-
}
|
|
9544
|
-
let targetVersion = version;
|
|
9545
|
-
if (targetVersion === void 0 || targetVersion === null) {
|
|
9546
|
-
targetVersion = versions.length - 1;
|
|
9547
|
-
}
|
|
9548
|
-
if (targetVersion < 0) {
|
|
9549
|
-
targetVersion = versions.length + targetVersion;
|
|
9550
|
-
}
|
|
9551
|
-
if (targetVersion < 0 || targetVersion >= versions.length) {
|
|
9552
|
-
return null;
|
|
9739
|
+
async appendEvent(session, event) {
|
|
9740
|
+
await this.ensureInitialized();
|
|
9741
|
+
if (event.partial) {
|
|
9742
|
+
return event;
|
|
9553
9743
|
}
|
|
9554
|
-
return
|
|
9555
|
-
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
const filenames = [];
|
|
9561
|
-
for (const path2 of this.artifacts.keys()) {
|
|
9562
|
-
if (path2.startsWith(sessionPrefix)) {
|
|
9563
|
-
const filename = path2.substring(sessionPrefix.length);
|
|
9564
|
-
filenames.push(filename);
|
|
9565
|
-
} else if (path2.startsWith(userNamespacePrefix)) {
|
|
9566
|
-
const filename = path2.substring(userNamespacePrefix.length);
|
|
9567
|
-
filenames.push(filename);
|
|
9744
|
+
return await this.db.transaction().execute(async (trx) => {
|
|
9745
|
+
const storageSession = await trx.selectFrom("sessions").selectAll().where("app_name", "=", session.appName).where("user_id", "=", session.userId).where("id", "=", session.id).executeTakeFirstOrThrow();
|
|
9746
|
+
if (this.timestampToUnixSeconds(storageSession.update_time) > session.lastUpdateTime) {
|
|
9747
|
+
throw new Error(
|
|
9748
|
+
`The last_update_time provided in the session object ${new Date(session.lastUpdateTime * 1e3).toISOString()} is earlier than the update_time in the storage_session ${storageSession.update_time.toISOString()}. Please check if it is a stale session.`
|
|
9749
|
+
);
|
|
9568
9750
|
}
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
|
|
9572
|
-
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
|
|
9576
|
-
|
|
9577
|
-
|
|
9578
|
-
|
|
9579
|
-
|
|
9580
|
-
|
|
9581
|
-
|
|
9582
|
-
|
|
9583
|
-
|
|
9584
|
-
|
|
9585
|
-
|
|
9586
|
-
|
|
9587
|
-
|
|
9588
|
-
|
|
9589
|
-
}
|
|
9590
|
-
|
|
9591
|
-
|
|
9592
|
-
|
|
9593
|
-
|
|
9594
|
-
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9605
|
-
|
|
9606
|
-
|
|
9607
|
-
|
|
9608
|
-
|
|
9609
|
-
|
|
9610
|
-
|
|
9611
|
-
|
|
9612
|
-
|
|
9613
|
-
|
|
9614
|
-
|
|
9615
|
-
nlPlanningResponseProcessor: () => responseProcessor,
|
|
9616
|
-
populateClientFunctionCallId: () => populateClientFunctionCallId,
|
|
9617
|
-
removeClientFunctionCallId: () => removeClientFunctionCallId
|
|
9618
|
-
});
|
|
9619
|
-
|
|
9620
|
-
// src/runners.ts
|
|
9621
|
-
import { SpanStatusCode } from "@opentelemetry/api";
|
|
9622
|
-
init_logger();
|
|
9623
|
-
var logger11 = new Logger({ name: "Runner" });
|
|
9624
|
-
function _findFunctionCallEventIfLastEventIsFunctionResponse(session) {
|
|
9625
|
-
const events = session.events;
|
|
9626
|
-
if (!events || events.length === 0) {
|
|
9627
|
-
return null;
|
|
9751
|
+
const appState = await trx.selectFrom("app_states").selectAll().where("app_name", "=", session.appName).executeTakeFirst();
|
|
9752
|
+
const userState = await trx.selectFrom("user_states").selectAll().where("app_name", "=", session.appName).where("user_id", "=", session.userId).executeTakeFirst();
|
|
9753
|
+
let currentAppState = this.parseJsonSafely(appState?.state, {});
|
|
9754
|
+
let currentUserState = this.parseJsonSafely(userState?.state, {});
|
|
9755
|
+
let sessionState = this.parseJsonSafely(storageSession.state, {});
|
|
9756
|
+
let appStateDelta = {};
|
|
9757
|
+
let userStateDelta = {};
|
|
9758
|
+
let sessionStateDelta = {};
|
|
9759
|
+
if (event.actions?.stateDelta) {
|
|
9760
|
+
const deltas = this.extractStateDelta(event.actions.stateDelta);
|
|
9761
|
+
appStateDelta = deltas.appStateDelta;
|
|
9762
|
+
userStateDelta = deltas.userStateDelta;
|
|
9763
|
+
sessionStateDelta = deltas.sessionStateDelta;
|
|
9764
|
+
}
|
|
9765
|
+
if (Object.keys(appStateDelta).length > 0) {
|
|
9766
|
+
currentAppState = { ...currentAppState, ...appStateDelta };
|
|
9767
|
+
await trx.updateTable("app_states").set({
|
|
9768
|
+
state: JSON.stringify(currentAppState),
|
|
9769
|
+
update_time: sql`CURRENT_TIMESTAMP`
|
|
9770
|
+
}).where("app_name", "=", session.appName).execute();
|
|
9771
|
+
}
|
|
9772
|
+
if (Object.keys(userStateDelta).length > 0) {
|
|
9773
|
+
currentUserState = { ...currentUserState, ...userStateDelta };
|
|
9774
|
+
await trx.updateTable("user_states").set({
|
|
9775
|
+
state: JSON.stringify(currentUserState),
|
|
9776
|
+
update_time: sql`CURRENT_TIMESTAMP`
|
|
9777
|
+
}).where("app_name", "=", session.appName).where("user_id", "=", session.userId).execute();
|
|
9778
|
+
}
|
|
9779
|
+
if (Object.keys(sessionStateDelta).length > 0) {
|
|
9780
|
+
sessionState = { ...sessionState, ...sessionStateDelta };
|
|
9781
|
+
await trx.updateTable("sessions").set({
|
|
9782
|
+
state: JSON.stringify(sessionState),
|
|
9783
|
+
update_time: sql`CURRENT_TIMESTAMP`
|
|
9784
|
+
}).where("app_name", "=", session.appName).where("user_id", "=", session.userId).where("id", "=", session.id).execute();
|
|
9785
|
+
}
|
|
9786
|
+
await trx.insertInto("events").values({
|
|
9787
|
+
...this.eventToStorageEvent(session, event),
|
|
9788
|
+
timestamp: sql`CURRENT_TIMESTAMP`
|
|
9789
|
+
}).execute();
|
|
9790
|
+
const updatedSession = await trx.selectFrom("sessions").select("update_time").where("app_name", "=", session.appName).where("user_id", "=", session.userId).where("id", "=", session.id).executeTakeFirstOrThrow();
|
|
9791
|
+
session.lastUpdateTime = this.timestampToUnixSeconds(
|
|
9792
|
+
updatedSession.update_time
|
|
9793
|
+
);
|
|
9794
|
+
super.appendEvent(session, event);
|
|
9795
|
+
return event;
|
|
9796
|
+
});
|
|
9628
9797
|
}
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
const
|
|
9638
|
-
|
|
9639
|
-
|
|
9640
|
-
|
|
9798
|
+
/**
|
|
9799
|
+
* Extract state deltas based on prefixes (similar to Python implementation)
|
|
9800
|
+
*/
|
|
9801
|
+
extractStateDelta(state) {
|
|
9802
|
+
const appStateDelta = {};
|
|
9803
|
+
const userStateDelta = {};
|
|
9804
|
+
const sessionStateDelta = {};
|
|
9805
|
+
if (state) {
|
|
9806
|
+
for (const [key, value] of Object.entries(state)) {
|
|
9807
|
+
if (key.startsWith("app_")) {
|
|
9808
|
+
appStateDelta[key.substring(4)] = value;
|
|
9809
|
+
} else if (key.startsWith("user_")) {
|
|
9810
|
+
userStateDelta[key.substring(5)] = value;
|
|
9811
|
+
} else if (!key.startsWith("temp_")) {
|
|
9812
|
+
sessionStateDelta[key] = value;
|
|
9641
9813
|
}
|
|
9642
9814
|
}
|
|
9643
9815
|
}
|
|
9816
|
+
return { appStateDelta, userStateDelta, sessionStateDelta };
|
|
9644
9817
|
}
|
|
9645
|
-
return null;
|
|
9646
|
-
}
|
|
9647
|
-
var Runner = class {
|
|
9648
|
-
/**
|
|
9649
|
-
* The app name of the runner.
|
|
9650
|
-
*/
|
|
9651
|
-
appName;
|
|
9652
|
-
/**
|
|
9653
|
-
* The root agent to run.
|
|
9654
|
-
*/
|
|
9655
|
-
agent;
|
|
9656
|
-
/**
|
|
9657
|
-
* The artifact service for the runner.
|
|
9658
|
-
*/
|
|
9659
|
-
artifactService;
|
|
9660
|
-
/**
|
|
9661
|
-
* The session service for the runner.
|
|
9662
|
-
*/
|
|
9663
|
-
sessionService;
|
|
9664
9818
|
/**
|
|
9665
|
-
*
|
|
9819
|
+
* Merge states for response (similar to Python implementation)
|
|
9666
9820
|
*/
|
|
9667
|
-
|
|
9821
|
+
mergeState(appState, userState, sessionState) {
|
|
9822
|
+
const mergedState = { ...sessionState };
|
|
9823
|
+
for (const [key, value] of Object.entries(appState)) {
|
|
9824
|
+
mergedState[`app_${key}`] = value;
|
|
9825
|
+
}
|
|
9826
|
+
for (const [key, value] of Object.entries(userState)) {
|
|
9827
|
+
mergedState[`user_${key}`] = value;
|
|
9828
|
+
}
|
|
9829
|
+
return mergedState;
|
|
9830
|
+
}
|
|
9668
9831
|
/**
|
|
9669
|
-
*
|
|
9832
|
+
* Convert Event to storage event format
|
|
9670
9833
|
*/
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
|
|
9682
|
-
|
|
9834
|
+
eventToStorageEvent(session, event) {
|
|
9835
|
+
return {
|
|
9836
|
+
id: event.id,
|
|
9837
|
+
app_name: session.appName,
|
|
9838
|
+
user_id: session.userId,
|
|
9839
|
+
session_id: session.id,
|
|
9840
|
+
invocation_id: event.invocationId || "",
|
|
9841
|
+
author: event.author || "",
|
|
9842
|
+
branch: event.branch || null,
|
|
9843
|
+
content: event.content ? JSON.stringify(event.content) : null,
|
|
9844
|
+
actions: event.actions ? JSON.stringify(event.actions) : null,
|
|
9845
|
+
long_running_tool_ids_json: event.longRunningToolIds ? JSON.stringify(Array.from(event.longRunningToolIds)) : null,
|
|
9846
|
+
grounding_metadata: event.groundingMetadata ? JSON.stringify(event.groundingMetadata) : null,
|
|
9847
|
+
partial: event.partial || null,
|
|
9848
|
+
turn_complete: event.turnComplete || null,
|
|
9849
|
+
error_code: event.errorCode || null,
|
|
9850
|
+
error_message: event.errorMessage || null,
|
|
9851
|
+
interrupted: event.interrupted || null
|
|
9852
|
+
};
|
|
9683
9853
|
}
|
|
9684
9854
|
/**
|
|
9685
|
-
*
|
|
9686
|
-
* NOTE: This sync interface is only for local testing and convenience purpose.
|
|
9687
|
-
* Consider using `runAsync` for production usage.
|
|
9855
|
+
* Convert storage event to Event format - Fixed to match Event interface
|
|
9688
9856
|
*/
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
}
|
|
9708
|
-
} finally {
|
|
9709
|
-
eventQueue.push(null);
|
|
9710
|
-
asyncCompleted = true;
|
|
9711
|
-
}
|
|
9857
|
+
storageEventToEvent(storageEvent) {
|
|
9858
|
+
const baseEvent = {
|
|
9859
|
+
id: storageEvent.id,
|
|
9860
|
+
invocationId: storageEvent.invocation_id,
|
|
9861
|
+
author: storageEvent.author,
|
|
9862
|
+
branch: storageEvent.branch || void 0,
|
|
9863
|
+
timestamp: this.timestampToUnixSeconds(storageEvent.timestamp),
|
|
9864
|
+
content: storageEvent.content ? this.parseJsonSafely(storageEvent.content, null) : void 0,
|
|
9865
|
+
actions: storageEvent.actions ? this.parseJsonSafely(storageEvent.actions, null) : void 0,
|
|
9866
|
+
longRunningToolIds: storageEvent.long_running_tool_ids_json ? new Set(
|
|
9867
|
+
this.parseJsonSafely(storageEvent.long_running_tool_ids_json, [])
|
|
9868
|
+
) : void 0,
|
|
9869
|
+
groundingMetadata: storageEvent.grounding_metadata ? this.parseJsonSafely(storageEvent.grounding_metadata, null) : void 0,
|
|
9870
|
+
partial: storageEvent.partial || void 0,
|
|
9871
|
+
turnComplete: storageEvent.turn_complete || void 0,
|
|
9872
|
+
errorCode: storageEvent.error_code || void 0,
|
|
9873
|
+
errorMessage: storageEvent.error_message || void 0,
|
|
9874
|
+
interrupted: storageEvent.interrupted || void 0
|
|
9712
9875
|
};
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9876
|
+
return {
|
|
9877
|
+
...baseEvent,
|
|
9878
|
+
// Add any missing required methods from the Event interface
|
|
9879
|
+
isFinalResponse: () => baseEvent.turnComplete === true,
|
|
9880
|
+
getFunctionCalls: () => {
|
|
9881
|
+
if (baseEvent.actions && typeof baseEvent.actions === "object" && "functionCalls" in baseEvent.actions) {
|
|
9882
|
+
return baseEvent.actions.functionCalls || [];
|
|
9717
9883
|
}
|
|
9718
|
-
|
|
9719
|
-
|
|
9884
|
+
return [];
|
|
9885
|
+
},
|
|
9886
|
+
getFunctionResponses: () => {
|
|
9887
|
+
if (baseEvent.actions && typeof baseEvent.actions === "object" && "functionResponses" in baseEvent.actions) {
|
|
9888
|
+
return baseEvent.actions.functionResponses || [];
|
|
9720
9889
|
}
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9890
|
+
return [];
|
|
9891
|
+
},
|
|
9892
|
+
hasTrailingCodeExecutionResult: () => {
|
|
9893
|
+
if (baseEvent.actions && typeof baseEvent.actions === "object" && "hasTrailingCodeExecutionResult" in baseEvent.actions) {
|
|
9894
|
+
return baseEvent.actions.hasTrailingCodeExecutionResult || false;
|
|
9724
9895
|
}
|
|
9725
|
-
|
|
9896
|
+
return false;
|
|
9726
9897
|
}
|
|
9727
|
-
}
|
|
9898
|
+
};
|
|
9728
9899
|
}
|
|
9729
9900
|
/**
|
|
9730
|
-
*
|
|
9901
|
+
* Updates the session state based on the event.
|
|
9902
|
+
* Overrides the base class method to work with plain object state.
|
|
9731
9903
|
*/
|
|
9732
|
-
|
|
9733
|
-
|
|
9734
|
-
|
|
9735
|
-
|
|
9736
|
-
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9740
|
-
|
|
9741
|
-
|
|
9904
|
+
updateSessionState(session, event) {
|
|
9905
|
+
if (!event.actions?.stateDelta) {
|
|
9906
|
+
return;
|
|
9907
|
+
}
|
|
9908
|
+
for (const [key, value] of Object.entries(event.actions.stateDelta)) {
|
|
9909
|
+
if (!key.startsWith("temp_")) {
|
|
9910
|
+
session.state[key] = value;
|
|
9911
|
+
}
|
|
9912
|
+
}
|
|
9913
|
+
}
|
|
9914
|
+
};
|
|
9915
|
+
|
|
9916
|
+
// src/sessions/database-factories.ts
|
|
9917
|
+
import dedent3 from "dedent";
|
|
9918
|
+
import { Kysely, MysqlDialect, PostgresDialect, SqliteDialect } from "kysely";
|
|
9919
|
+
function createDependencyError(packageName, dbType) {
|
|
9920
|
+
return new Error(
|
|
9921
|
+
dedent3`
|
|
9922
|
+
Missing required peer dependency: ${packageName}
|
|
9923
|
+
To use ${dbType} sessions, install the required package:
|
|
9924
|
+
npm install ${packageName}
|
|
9925
|
+
# or
|
|
9926
|
+
pnpm add ${packageName}
|
|
9927
|
+
# or
|
|
9928
|
+
yarn add ${packageName}`
|
|
9929
|
+
);
|
|
9930
|
+
}
|
|
9931
|
+
function createPostgresSessionService(connectionString, options) {
|
|
9932
|
+
let Pool;
|
|
9933
|
+
try {
|
|
9934
|
+
({ Pool } = __require("pg"));
|
|
9935
|
+
} catch (error) {
|
|
9936
|
+
throw createDependencyError("pg", "PostgreSQL");
|
|
9937
|
+
}
|
|
9938
|
+
const db = new Kysely({
|
|
9939
|
+
dialect: new PostgresDialect({
|
|
9940
|
+
pool: new Pool({
|
|
9941
|
+
connectionString,
|
|
9942
|
+
...options
|
|
9943
|
+
})
|
|
9944
|
+
})
|
|
9945
|
+
});
|
|
9946
|
+
return new DatabaseSessionService({ db });
|
|
9947
|
+
}
|
|
9948
|
+
function createMysqlSessionService(connectionString, options) {
|
|
9949
|
+
let createPool;
|
|
9950
|
+
try {
|
|
9951
|
+
({ createPool } = __require("mysql2"));
|
|
9952
|
+
} catch (error) {
|
|
9953
|
+
throw createDependencyError("mysql2", "MySQL");
|
|
9954
|
+
}
|
|
9955
|
+
const db = new Kysely({
|
|
9956
|
+
dialect: new MysqlDialect({
|
|
9957
|
+
pool: createPool({
|
|
9958
|
+
uri: connectionString,
|
|
9959
|
+
...options
|
|
9960
|
+
})
|
|
9961
|
+
})
|
|
9962
|
+
});
|
|
9963
|
+
return new DatabaseSessionService({ db });
|
|
9964
|
+
}
|
|
9965
|
+
function createSqliteSessionService(filename, options) {
|
|
9966
|
+
let Database;
|
|
9967
|
+
try {
|
|
9968
|
+
Database = __require("better-sqlite3");
|
|
9969
|
+
} catch (error) {
|
|
9970
|
+
throw createDependencyError("better-sqlite3", "SQLite");
|
|
9971
|
+
}
|
|
9972
|
+
const db = new Kysely({
|
|
9973
|
+
dialect: new SqliteDialect({
|
|
9974
|
+
database: new Database(filename, options)
|
|
9975
|
+
})
|
|
9976
|
+
});
|
|
9977
|
+
return new DatabaseSessionService({ db });
|
|
9978
|
+
}
|
|
9979
|
+
function createDatabaseSessionService(databaseUrl, options) {
|
|
9980
|
+
if (databaseUrl.startsWith("postgres://") || databaseUrl.startsWith("postgresql://")) {
|
|
9981
|
+
return createPostgresSessionService(databaseUrl, options);
|
|
9982
|
+
}
|
|
9983
|
+
if (databaseUrl.startsWith("mysql://")) {
|
|
9984
|
+
return createMysqlSessionService(databaseUrl, options);
|
|
9985
|
+
}
|
|
9986
|
+
if (databaseUrl.startsWith("sqlite://") || databaseUrl.includes(".db") || databaseUrl === ":memory:") {
|
|
9987
|
+
const filename = databaseUrl.startsWith("sqlite://") ? databaseUrl.substring(9) : databaseUrl;
|
|
9988
|
+
return createSqliteSessionService(filename, options);
|
|
9989
|
+
}
|
|
9990
|
+
throw new Error(`Unsupported database URL: ${databaseUrl}`);
|
|
9991
|
+
}
|
|
9992
|
+
|
|
9993
|
+
// src/artifacts/gcs-artifact-service.ts
|
|
9994
|
+
init_logger();
|
|
9995
|
+
import {
|
|
9996
|
+
Storage
|
|
9997
|
+
} from "@google-cloud/storage";
|
|
9998
|
+
var logger11 = new Logger({ name: "GcsArtifactService" });
|
|
9999
|
+
var GcsArtifactService = class {
|
|
10000
|
+
bucketName;
|
|
10001
|
+
storageClient;
|
|
10002
|
+
bucket;
|
|
10003
|
+
constructor(bucketName, options) {
|
|
10004
|
+
this.bucketName = bucketName;
|
|
10005
|
+
this.storageClient = new Storage(options);
|
|
10006
|
+
this.bucket = this.storageClient.bucket(this.bucketName);
|
|
10007
|
+
}
|
|
10008
|
+
fileHasUserNamespace(filename) {
|
|
10009
|
+
return filename.startsWith("user:");
|
|
10010
|
+
}
|
|
10011
|
+
getBlobName(appName, userId, sessionId, filename, version) {
|
|
10012
|
+
if (this.fileHasUserNamespace(filename)) {
|
|
10013
|
+
return `${appName}/${userId}/user/${filename}/${version}`;
|
|
10014
|
+
}
|
|
10015
|
+
return `${appName}/${userId}/${sessionId}/${filename}/${version}`;
|
|
10016
|
+
}
|
|
10017
|
+
async saveArtifact(args) {
|
|
10018
|
+
const { appName, userId, sessionId, filename, artifact } = args;
|
|
10019
|
+
const versions = await this.listVersions({
|
|
10020
|
+
appName,
|
|
10021
|
+
userId,
|
|
10022
|
+
sessionId,
|
|
10023
|
+
filename
|
|
10024
|
+
});
|
|
10025
|
+
const version = versions.length === 0 ? 0 : Math.max(...versions) + 1;
|
|
10026
|
+
const blobName = this.getBlobName(
|
|
10027
|
+
appName,
|
|
10028
|
+
userId,
|
|
10029
|
+
sessionId,
|
|
10030
|
+
filename,
|
|
10031
|
+
version
|
|
10032
|
+
);
|
|
10033
|
+
const blob = this.bucket.file(blobName);
|
|
10034
|
+
await blob.save(artifact.inlineData.data, {
|
|
10035
|
+
contentType: artifact.inlineData.mimeType,
|
|
10036
|
+
preconditionOpts: { ifGenerationMatch: 0 }
|
|
10037
|
+
});
|
|
10038
|
+
return version;
|
|
10039
|
+
}
|
|
10040
|
+
async loadArtifact(args) {
|
|
10041
|
+
let { version } = args;
|
|
10042
|
+
const { appName, userId, sessionId, filename } = args;
|
|
10043
|
+
if (version === void 0 || version === null) {
|
|
10044
|
+
const versions = await this.listVersions({
|
|
10045
|
+
appName,
|
|
9742
10046
|
userId,
|
|
9743
|
-
sessionId
|
|
9744
|
-
|
|
9745
|
-
if (!session) {
|
|
9746
|
-
throw new Error(`Session not found: ${sessionId}`);
|
|
9747
|
-
}
|
|
9748
|
-
const invocationContext = this._newInvocationContext(session, {
|
|
9749
|
-
newMessage,
|
|
9750
|
-
runConfig
|
|
10047
|
+
sessionId,
|
|
10048
|
+
filename
|
|
9751
10049
|
});
|
|
9752
|
-
if (
|
|
9753
|
-
|
|
9754
|
-
session,
|
|
9755
|
-
newMessage,
|
|
9756
|
-
invocationContext,
|
|
9757
|
-
runConfig.saveInputBlobsAsArtifacts || false
|
|
9758
|
-
);
|
|
10050
|
+
if (versions.length === 0) {
|
|
10051
|
+
return null;
|
|
9759
10052
|
}
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
|
|
9767
|
-
|
|
10053
|
+
version = Math.max(...versions);
|
|
10054
|
+
}
|
|
10055
|
+
const blobName = this.getBlobName(
|
|
10056
|
+
appName,
|
|
10057
|
+
userId,
|
|
10058
|
+
sessionId,
|
|
10059
|
+
filename,
|
|
10060
|
+
version
|
|
10061
|
+
);
|
|
10062
|
+
const blob = this.bucket.file(blobName);
|
|
10063
|
+
try {
|
|
10064
|
+
const [metadata] = await blob.getMetadata();
|
|
10065
|
+
const [artifactBuffer] = await blob.download();
|
|
10066
|
+
if (!artifactBuffer) {
|
|
10067
|
+
return null;
|
|
9768
10068
|
}
|
|
10069
|
+
const part = {
|
|
10070
|
+
inlineData: {
|
|
10071
|
+
data: artifactBuffer.toString(),
|
|
10072
|
+
mimeType: metadata.contentType || "application/octet-stream"
|
|
10073
|
+
}
|
|
10074
|
+
};
|
|
10075
|
+
return part;
|
|
9769
10076
|
} catch (error) {
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
code: SpanStatusCode.ERROR,
|
|
9774
|
-
message: error instanceof Error ? error.message : "Unknown error"
|
|
9775
|
-
});
|
|
10077
|
+
if (error?.code === 404) {
|
|
10078
|
+
return null;
|
|
10079
|
+
}
|
|
9776
10080
|
throw error;
|
|
9777
|
-
} finally {
|
|
9778
|
-
span.end();
|
|
9779
10081
|
}
|
|
9780
10082
|
}
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
const part = newMessage.parts[i];
|
|
9791
|
-
if (!part.inlineData) {
|
|
9792
|
-
continue;
|
|
10083
|
+
async listArtifactKeys(args) {
|
|
10084
|
+
const { appName, userId, sessionId } = args;
|
|
10085
|
+
const filenames = /* @__PURE__ */ new Set();
|
|
10086
|
+
const processBlobs = (blobNames) => {
|
|
10087
|
+
for (const name of blobNames) {
|
|
10088
|
+
const parts = name.split("/");
|
|
10089
|
+
if (parts.length === 5) {
|
|
10090
|
+
const filename = parts[3];
|
|
10091
|
+
filenames.add(filename);
|
|
9793
10092
|
}
|
|
9794
|
-
const fileName = `artifact_${invocationContext.invocationId}_${i}`;
|
|
9795
|
-
await this.artifactService.saveArtifact({
|
|
9796
|
-
appName: this.appName,
|
|
9797
|
-
userId: session.userId,
|
|
9798
|
-
sessionId: session.id,
|
|
9799
|
-
filename: fileName,
|
|
9800
|
-
artifact: part
|
|
9801
|
-
});
|
|
9802
|
-
newMessage.parts[i] = {
|
|
9803
|
-
text: `Uploaded file: ${fileName}. It is saved into artifacts`
|
|
9804
|
-
};
|
|
9805
10093
|
}
|
|
9806
|
-
}
|
|
9807
|
-
const userContent = {
|
|
9808
|
-
...newMessage,
|
|
9809
|
-
role: "user"
|
|
9810
|
-
// Ensure role is set for content filtering
|
|
9811
10094
|
};
|
|
9812
|
-
const
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
});
|
|
9817
|
-
|
|
10095
|
+
const sessionPrefix = `${appName}/${userId}/${sessionId}/`;
|
|
10096
|
+
const [sessionBlobs] = await this.storageClient.bucket(this.bucketName).getFiles({ prefix: sessionPrefix });
|
|
10097
|
+
processBlobs(sessionBlobs.map((b) => b.name));
|
|
10098
|
+
const userNamespacePrefix = `${appName}/${userId}/user/`;
|
|
10099
|
+
const [userNamespaceBlobs] = await this.storageClient.bucket(this.bucketName).getFiles({ prefix: userNamespacePrefix });
|
|
10100
|
+
processBlobs(userNamespaceBlobs.map((b) => b.name));
|
|
10101
|
+
return Array.from(filenames).sort();
|
|
9818
10102
|
}
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
}
|
|
9827
|
-
const
|
|
9828
|
-
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
}
|
|
9839
|
-
if (this._isTransferableAcrossAgentTree(agent)) {
|
|
9840
|
-
return agent;
|
|
9841
|
-
}
|
|
9842
|
-
}
|
|
9843
|
-
return rootAgent;
|
|
10103
|
+
async deleteArtifact(args) {
|
|
10104
|
+
const { appName, userId, sessionId, filename } = args;
|
|
10105
|
+
const versions = await this.listVersions({
|
|
10106
|
+
appName,
|
|
10107
|
+
userId,
|
|
10108
|
+
sessionId,
|
|
10109
|
+
filename
|
|
10110
|
+
});
|
|
10111
|
+
const deletePromises = versions.map((version) => {
|
|
10112
|
+
const blobName = this.getBlobName(
|
|
10113
|
+
appName,
|
|
10114
|
+
userId,
|
|
10115
|
+
sessionId,
|
|
10116
|
+
filename,
|
|
10117
|
+
version
|
|
10118
|
+
);
|
|
10119
|
+
return this.bucket.file(blobName).delete();
|
|
10120
|
+
});
|
|
10121
|
+
await Promise.all(deletePromises);
|
|
9844
10122
|
}
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
|
|
10123
|
+
async listVersions(args) {
|
|
10124
|
+
const { appName, userId, sessionId, filename } = args;
|
|
10125
|
+
const prefix = this.getBlobName(appName, userId, sessionId, filename, "");
|
|
10126
|
+
const [blobs] = await this.bucket.getFiles({ prefix });
|
|
10127
|
+
const versions = [];
|
|
10128
|
+
for (const blob of blobs) {
|
|
10129
|
+
const parts = blob.name.split("/");
|
|
10130
|
+
if (parts.length === 5) {
|
|
10131
|
+
const versionStr = parts[4];
|
|
10132
|
+
const versionNum = Number.parseInt(versionStr, 10);
|
|
10133
|
+
if (!Number.isNaN(versionNum)) {
|
|
10134
|
+
versions.push(versionNum);
|
|
10135
|
+
}
|
|
9856
10136
|
}
|
|
9857
|
-
agent = agent.parentAgent || null;
|
|
9858
10137
|
}
|
|
9859
|
-
return
|
|
9860
|
-
}
|
|
9861
|
-
/**
|
|
9862
|
-
* Creates a new invocation context.
|
|
9863
|
-
*/
|
|
9864
|
-
_newInvocationContext(session, {
|
|
9865
|
-
newMessage,
|
|
9866
|
-
runConfig = new RunConfig()
|
|
9867
|
-
}) {
|
|
9868
|
-
const invocationId = newInvocationContextId();
|
|
9869
|
-
return new InvocationContext({
|
|
9870
|
-
artifactService: this.artifactService,
|
|
9871
|
-
sessionService: this.sessionService,
|
|
9872
|
-
memoryService: this.memoryService,
|
|
9873
|
-
invocationId,
|
|
9874
|
-
agent: this.agent,
|
|
9875
|
-
session,
|
|
9876
|
-
userContent: newMessage || null,
|
|
9877
|
-
liveRequestQueue: null,
|
|
9878
|
-
runConfig
|
|
9879
|
-
});
|
|
9880
|
-
}
|
|
9881
|
-
};
|
|
9882
|
-
var InMemoryRunner = class extends Runner {
|
|
9883
|
-
/**
|
|
9884
|
-
* Deprecated. Please don't use. The in-memory session service for the runner.
|
|
9885
|
-
*/
|
|
9886
|
-
_inMemorySessionService;
|
|
9887
|
-
/**
|
|
9888
|
-
* Initializes the InMemoryRunner.
|
|
9889
|
-
*/
|
|
9890
|
-
constructor(agent, { appName = "InMemoryRunner" } = {}) {
|
|
9891
|
-
const inMemorySessionService = new InMemorySessionService();
|
|
9892
|
-
super({
|
|
9893
|
-
appName,
|
|
9894
|
-
agent,
|
|
9895
|
-
artifactService: new InMemoryArtifactService(),
|
|
9896
|
-
sessionService: inMemorySessionService,
|
|
9897
|
-
memoryService: new InMemoryMemoryService()
|
|
9898
|
-
});
|
|
9899
|
-
this._inMemorySessionService = inMemorySessionService;
|
|
10138
|
+
return versions.sort((a, b) => a - b);
|
|
9900
10139
|
}
|
|
9901
10140
|
};
|
|
9902
10141
|
|
|
10142
|
+
// src/flows/index.ts
|
|
10143
|
+
var flows_exports = {};
|
|
10144
|
+
__export(flows_exports, {
|
|
10145
|
+
AF_FUNCTION_CALL_ID_PREFIX: () => AF_FUNCTION_CALL_ID_PREFIX,
|
|
10146
|
+
AutoFlow: () => AutoFlow,
|
|
10147
|
+
BaseLlmFlow: () => BaseLlmFlow,
|
|
10148
|
+
BaseLlmRequestProcessor: () => BaseLlmRequestProcessor,
|
|
10149
|
+
BaseLlmResponseProcessor: () => BaseLlmResponseProcessor,
|
|
10150
|
+
REQUEST_EUC_FUNCTION_CALL_NAME: () => REQUEST_EUC_FUNCTION_CALL_NAME,
|
|
10151
|
+
SingleFlow: () => SingleFlow,
|
|
10152
|
+
agentTransferRequestProcessor: () => requestProcessor8,
|
|
10153
|
+
basicRequestProcessor: () => requestProcessor,
|
|
10154
|
+
codeExecutionRequestProcessor: () => requestProcessor7,
|
|
10155
|
+
codeExecutionResponseProcessor: () => responseProcessor2,
|
|
10156
|
+
contentRequestProcessor: () => requestProcessor5,
|
|
10157
|
+
generateAuthEvent: () => generateAuthEvent,
|
|
10158
|
+
generateClientFunctionCallId: () => generateClientFunctionCallId,
|
|
10159
|
+
getLongRunningFunctionCalls: () => getLongRunningFunctionCalls,
|
|
10160
|
+
handleFunctionCallsAsync: () => handleFunctionCallsAsync,
|
|
10161
|
+
handleFunctionCallsLive: () => handleFunctionCallsLive,
|
|
10162
|
+
identityRequestProcessor: () => requestProcessor3,
|
|
10163
|
+
instructionsRequestProcessor: () => requestProcessor4,
|
|
10164
|
+
mergeParallelFunctionResponseEvents: () => mergeParallelFunctionResponseEvents,
|
|
10165
|
+
nlPlanningRequestProcessor: () => requestProcessor6,
|
|
10166
|
+
nlPlanningResponseProcessor: () => responseProcessor,
|
|
10167
|
+
populateClientFunctionCallId: () => populateClientFunctionCallId,
|
|
10168
|
+
removeClientFunctionCallId: () => removeClientFunctionCallId
|
|
10169
|
+
});
|
|
10170
|
+
|
|
9903
10171
|
// src/version.ts
|
|
9904
10172
|
var VERSION = "0.1.0";
|
|
9905
10173
|
export {
|
|
9906
10174
|
AF_FUNCTION_CALL_ID_PREFIX,
|
|
9907
10175
|
LlmAgent as Agent,
|
|
10176
|
+
AgentBuilder,
|
|
9908
10177
|
agents_exports as Agents,
|
|
9909
10178
|
AnthropicLlm,
|
|
9910
10179
|
ApiKeyCredential,
|