@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/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14; var _class15; var _class16; var _class17; var _class18; var _class19; var _class20; var _class21; var _class22; var _class23; var _class24; var _class25; var _class26; var _class27; var _class28;var __defProp = Object.defineProperty;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14; var _class15; var _class16; var _class17; var _class18; var _class19; var _class20; var _class21; var _class22; var _class23; var _class24; var _class25; var _class26; var _class27; var _class28; var _class29;var __defProp = Object.defineProperty;
2
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
@@ -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 = (_class24 = class extends BaseAgent {
8092
8093
  }
8093
8094
  }, _class24);
8094
8095
 
8096
+ // src/runners.ts
8097
+
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/index.ts
8190
- var memory_exports = {};
8191
- __export(memory_exports, {
8192
- InMemoryMemoryService: () => InMemoryMemoryService
8193
- });
8193
+ // src/artifacts/in-memory-artifact-service.ts
8194
+ init_logger();
8195
+ var logger9 = new Logger({ name: "InMemoryArtifactService" });
8196
+ var InMemoryArtifactService = (_class25 = class {constructor() { _class25.prototype.__init45.call(this); }
8197
+ __init45() {this.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
+ }, _class25);
8271
+
8272
+ // src/runners.ts
8273
+ init_logger();
8194
8274
 
8195
8275
  // src/memory/_utils.ts
8196
8276
  function formatTimestamp(timestamp) {
@@ -8214,15 +8294,15 @@ function _extractWordsLower(text) {
8214
8294
  const words = text.match(/[A-Za-z]+/g) || [];
8215
8295
  return new Set(words.map((word) => word.toLowerCase()));
8216
8296
  }
8217
- var InMemoryMemoryService = (_class25 = class {
8297
+ var InMemoryMemoryService = (_class26 = class {
8218
8298
  /**
8219
8299
  * Keys are app_name/user_id, session_id. Values are session event lists.
8220
8300
  */
8221
- __init45() {this._sessionEvents = /* @__PURE__ */ new Map()}
8301
+ __init46() {this._sessionEvents = /* @__PURE__ */ new Map()}
8222
8302
  /**
8223
8303
  * Constructor for InMemoryMemoryService
8224
8304
  */
8225
- constructor() {;_class25.prototype.__init45.call(this);
8305
+ constructor() {;_class26.prototype.__init46.call(this);
8226
8306
  this._sessionEvents = /* @__PURE__ */ new Map();
8227
8307
  }
8228
8308
  /**
@@ -8306,21 +8386,10 @@ var InMemoryMemoryService = (_class25 = class {
8306
8386
  clear() {
8307
8387
  this._sessionEvents.clear();
8308
8388
  }
8309
- }, _class25);
8389
+ }, _class26);
8310
8390
 
8311
- // src/sessions/index.ts
8312
- var sessions_exports = {};
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
+ var _crypto = require('crypto');
8324
8393
 
8325
8394
  // src/sessions/base-session-service.ts
8326
8395
  var BaseSessionService = class {
@@ -8359,20 +8428,19 @@ var BaseSessionService = class {
8359
8428
  };
8360
8429
 
8361
8430
  // src/sessions/in-memory-session-service.ts
8362
- var _crypto = require('crypto');
8363
- var InMemorySessionService = (_class26 = class extends BaseSessionService {constructor(...args2) { super(...args2); _class26.prototype.__init46.call(this);_class26.prototype.__init47.call(this);_class26.prototype.__init48.call(this); }
8431
+ var InMemorySessionService = (_class27 = class extends BaseSessionService {constructor(...args2) { super(...args2); _class27.prototype.__init47.call(this);_class27.prototype.__init48.call(this);_class27.prototype.__init49.call(this); }
8364
8432
  /**
8365
8433
  * A map from app name to a map from user ID to a map from session ID to session.
8366
8434
  */
8367
- __init46() {this.sessions = /* @__PURE__ */ new Map()}
8435
+ __init47() {this.sessions = /* @__PURE__ */ new Map()}
8368
8436
  /**
8369
8437
  * A map from app name to a map from user ID to a map from key to the value.
8370
8438
  */
8371
- __init47() {this.userState = /* @__PURE__ */ new Map()}
8439
+ __init48() {this.userState = /* @__PURE__ */ new Map()}
8372
8440
  /**
8373
8441
  * A map from app name to a map from key to the value.
8374
8442
  */
8375
- __init48() {this.appState = /* @__PURE__ */ new Map()}
8443
+ __init49() {this.appState = /* @__PURE__ */ new Map()}
8376
8444
  /**
8377
8445
  * Creates a new session.
8378
8446
  */
@@ -8569,1337 +8637,1537 @@ var InMemorySessionService = (_class26 = class extends BaseSessionService {const
8569
8637
  storageSession.lastUpdateTime = event.timestamp;
8570
8638
  return event;
8571
8639
  }
8572
- }, _class26);
8640
+ }, _class27);
8573
8641
 
8574
- // src/sessions/vertex-ai-session-service.ts
8575
- var VertexAiSessionService = class extends BaseSessionService {
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;
8648
+ }
8649
+ const lastEvent = events[events.length - 1];
8650
+ if (_optionalChain([lastEvent, 'access', _242 => _242.content, 'optionalAccess', _243 => _243.parts, 'optionalAccess', _244 => _244.some, 'call', _245 => _245((part) => part.functionResponse)])) {
8651
+ const functionCallId = _optionalChain([lastEvent, 'access', _246 => _246.content, 'access', _247 => _247.parts, 'access', _248 => _248.find, 'call', _249 => _249(
8652
+ (part) => part.functionResponse
8653
+ ), 'optionalAccess', _250 => _250.functionResponse, 'optionalAccess', _251 => _251.id]);
8654
+ if (!functionCallId) return null;
8655
+ for (let i = events.length - 2; i >= 0; i--) {
8656
+ const event = events[i];
8657
+ const functionCalls = _optionalChain([event, 'access', _252 => _252.getFunctionCalls, 'optionalCall', _253 => _253()]) || [];
8658
+ for (const functionCall of functionCalls) {
8659
+ if (functionCall.id === functionCallId) {
8660
+ return event;
8661
+ }
8662
+ }
8663
+ }
8664
+ }
8665
+ return null;
8666
+ }
8667
+ var Runner = class {
8668
+ /**
8669
+ * The app name of the runner.
8670
+ */
8576
8671
 
8672
+ /**
8673
+ * The root agent to run.
8674
+ */
8577
8675
 
8676
+ /**
8677
+ * The artifact service for the runner.
8678
+ */
8578
8679
 
8579
8680
  /**
8580
- * Initializes the VertexAiSessionService.
8681
+ * The session service for the runner.
8581
8682
  */
8582
- constructor(options = {}) {
8583
- super();
8584
- this.project = options.project;
8585
- this.location = options.location;
8586
- this.agentEngineId = options.agentEngineId;
8683
+
8684
+ /**
8685
+ * The memory service for the runner.
8686
+ */
8687
+
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;
8587
8703
  }
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 (_optionalChain([lroResponse, 'optionalAccess', _242 => _242.done])) {
8617
- break;
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({
8721
+ userId,
8722
+ sessionId,
8723
+ newMessage,
8724
+ runConfig
8725
+ })) {
8726
+ eventQueue.push(event);
8727
+ }
8728
+ } finally {
8729
+ eventQueue.push(null);
8730
+ asyncCompleted = true;
8618
8731
  }
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
8732
  };
8641
- }
8642
- async getSession(appName, userId, sessionId, config) {
8643
- const reasoningEngineId = this.getReasoningEngineId(appName);
8644
- const apiClient = this.getApiClient();
8645
- try {
8646
- const getSessionApiResponse = await apiClient.async_request({
8647
- http_method: "GET",
8648
- path: `reasoningEngines/${reasoningEngineId}/sessions/${sessionId}`,
8649
- request_dict: {}
8650
- });
8651
- const sessionIdFromResponse = getSessionApiResponse.name.split("/").pop();
8652
- const updateTimestamp = new Date(getSessionApiResponse.updateTime).getTime() / 1e3;
8653
- const session = {
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
- );
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;
8685
8744
  }
8745
+ yield event;
8686
8746
  }
8687
- session.events = session.events.filter(
8688
- (event) => event.timestamp <= updateTimestamp
8747
+ }();
8748
+ }
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");
8759
+ try {
8760
+ const session = await this.sessionService.getSession(
8761
+ this.appName,
8762
+ userId,
8763
+ sessionId
8689
8764
  );
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
- }
8765
+ if (!session) {
8766
+ throw new Error(`Session not found: ${sessionId}`);
8767
+ }
8768
+ const invocationContext = this._newInvocationContext(session, {
8769
+ newMessage,
8770
+ runConfig
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);
8705
8786
  }
8787
+ yield event;
8706
8788
  }
8707
- return session;
8708
8789
  } catch (error) {
8709
- console.error(`Error getting session ${sessionId}:`, error);
8710
- return void 0;
8790
+ logger10.debug("Error running agent:", error);
8791
+ span.recordException(error);
8792
+ span.setStatus({
8793
+ code: _api.SpanStatusCode.ERROR,
8794
+ message: error instanceof Error ? error.message : "Unknown error"
8795
+ });
8796
+ throw error;
8797
+ } finally {
8798
+ span.end();
8711
8799
  }
8712
8800
  }
8713
- async listSessions(appName, userId) {
8714
- const reasoningEngineId = this.getReasoningEngineId(appName);
8715
- const apiClient = this.getApiClient();
8716
- let path2 = `reasoningEngines/${reasoningEngineId}/sessions`;
8717
- if (userId) {
8718
- const parsedUserId = encodeURIComponent(`"${userId}"`);
8719
- path2 = `${path2}?filter=user_id=${parsedUserId}`;
8720
- }
8721
- const apiResponse = await apiClient.async_request({
8722
- http_method: "GET",
8723
- path: path2,
8724
- request_dict: {}
8725
- });
8726
- if (apiResponse.httpHeaders) {
8727
- return { sessions: [] };
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.");
8728
8807
  }
8729
- const sessions = [];
8730
- if (apiResponse.sessions) {
8731
- for (const apiSession of apiResponse.sessions) {
8732
- const session = {
8733
- appName,
8734
- userId,
8735
- id: apiSession.name.split("/").pop(),
8736
- state: {},
8737
- events: [],
8738
- lastUpdateTime: new Date(apiSession.updateTime).getTime() / 1e3
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`
8739
8824
  };
8740
- sessions.push(session);
8741
8825
  }
8742
8826
  }
8743
- return { sessions };
8744
- }
8745
- async deleteSession(appName, userId, sessionId) {
8746
- const reasoningEngineId = this.getReasoningEngineId(appName);
8747
- const apiClient = this.getApiClient();
8748
- try {
8749
- await apiClient.async_request({
8750
- http_method: "DELETE",
8751
- path: `reasoningEngines/${reasoningEngineId}/sessions/${sessionId}`,
8752
- request_dict: {}
8753
- });
8754
- } catch (error) {
8755
- console.error(`Error deleting session ${sessionId}:`, error);
8756
- throw error;
8757
- }
8758
- }
8759
- async appendEvent(session, event) {
8760
- await super.appendEvent(session, event);
8761
- const reasoningEngineId = this.getReasoningEngineId(session.appName);
8762
- const apiClient = this.getApiClient();
8763
- await apiClient.async_request({
8764
- http_method: "POST",
8765
- path: `reasoningEngines/${reasoningEngineId}/sessions/${session.id}:appendEvent`,
8766
- request_dict: this.convertEventToJson(event)
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
- return event;
8837
+ await this.sessionService.appendEvent(session, event);
8769
8838
  }
8770
- getReasoningEngineId(appName) {
8771
- if (this.agentEngineId) {
8772
- return this.agentEngineId;
8773
- }
8774
- if (/^\d+$/.test(appName)) {
8775
- return appName;
8839
+ /**
8840
+ * Finds the agent to run to continue the session.
8841
+ */
8842
+ _findAgentToRun(session, rootAgent) {
8843
+ const event = _findFunctionCallEventIfLastEventIsFunctionResponse(session);
8844
+ if (_optionalChain([event, 'optionalAccess', _254 => _254.author])) {
8845
+ return rootAgent.findAgent(event.author);
8776
8846
  }
8777
- const pattern = /^projects\/([a-zA-Z0-9-_]+)\/locations\/([a-zA-Z0-9-_]+)\/reasoningEngines\/(\d+)$/;
8778
- const match = appName.match(pattern);
8779
- if (!match) {
8780
- throw new Error(
8781
- `App name ${appName} is not valid. It should either be the full ReasoningEngine resource name, or the reasoning engine id.`
8782
- );
8847
+ const nonUserEvents = _optionalChain([session, 'access', _255 => _255.events, 'optionalAccess', _256 => _256.filter, 'call', _257 => _257((e) => e.author !== "user"), 'access', _258 => _258.reverse, 'call', _259 => _259()]) || [];
8848
+ for (const event2 of nonUserEvents) {
8849
+ if (event2.author === rootAgent.name) {
8850
+ return rootAgent;
8851
+ }
8852
+ const agent = _optionalChain([rootAgent, 'access', _260 => _260.findSubAgent, 'optionalCall', _261 => _261(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
+ }
8783
8862
  }
8784
- return match[3];
8785
- }
8786
- getApiClient() {
8787
- const { GoogleGenAI: GoogleGenAI2 } = __require("@google/genai");
8788
- const client = new GoogleGenAI2({
8789
- vertexai: true,
8790
- project: this.project,
8791
- location: this.location
8792
- });
8793
- return client._api_client;
8863
+ return rootAgent;
8794
8864
  }
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;
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;
8805
8878
  }
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;
8879
+ return true;
8834
8880
  }
8835
- fromApiEvent(apiEvent) {
8836
- let eventActions = new EventActions();
8837
- if (apiEvent.actions) {
8838
- eventActions = new EventActions({
8839
- skipSummarization: apiEvent.actions.skipSummarization,
8840
- stateDelta: apiEvent.actions.stateDelta || {},
8841
- artifactDelta: apiEvent.actions.artifactDelta || {},
8842
- transferToAgent: apiEvent.actions.transferAgent,
8843
- escalate: apiEvent.actions.escalate,
8844
- requestedAuthConfigs: apiEvent.actions.requestedAuthConfigs || {}
8845
- });
8846
- }
8847
- const event = new Event({
8848
- id: apiEvent.name.split("/").pop(),
8849
- invocationId: apiEvent.invocationId,
8850
- author: apiEvent.author,
8851
- actions: eventActions,
8852
- content: this.decodeContent(apiEvent.content),
8853
- timestamp: new Date(apiEvent.timestamp).getTime() / 1e3
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
8854
8899
  });
8855
- if (apiEvent.errorCode) {
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
8900
  }
8878
- decodeGroundingMetadata(groundingMetadata) {
8879
- if (!groundingMetadata) return void 0;
8880
- return groundingMetadata;
8901
+ };
8902
+ var InMemoryRunner = class extends Runner {
8903
+ /**
8904
+ * Deprecated. Please don't use. The in-memory session service for the runner.
8905
+ */
8906
+
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()
8918
+ });
8919
+ this._inMemorySessionService = inMemorySessionService;
8881
8920
  }
8882
8921
  };
8883
8922
 
8884
- // src/sessions/database-session-service.ts
8885
- var _kysely = require('kysely');
8886
- var DatabaseSessionService = (_class27 = class extends BaseSessionService {
8923
+ // src/agents/agent-builder.ts
8924
+ var AgentBuilder = (_class28 = class _AgentBuilder {
8887
8925
 
8888
- __init49() {this.initialized = false}
8889
- constructor(config) {
8890
- super();_class27.prototype.__init49.call(this);;
8891
- this.db = config.db;
8892
- if (!config.skipTableCreation) {
8893
- this.initializeDatabase().catch((error) => {
8894
- console.error("Failed to initialize database:", error);
8895
- });
8896
- }
8926
+
8927
+ __init50() {this.agentType = "llm"}
8928
+ /**
8929
+ * Private constructor - use static create() method
8930
+ */
8931
+ constructor(name) {;_class28.prototype.__init50.call(this);
8932
+ this.config = { name };
8897
8933
  }
8898
8934
  /**
8899
- * Initialize the database by creating required tables if they don't exist
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
- async initializeDatabase() {
8902
- if (this.initialized) {
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(_kysely.sql`CURRENT_TIMESTAMP`).notNull()
8910
- ).addColumn(
8911
- "update_time",
8912
- "timestamp",
8913
- (col) => col.defaultTo(_kysely.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(_kysely.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(_kysely.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(_kysely.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
- * Ensure database is initialized before any operation
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
- async ensureInitialized() {
8951
- if (!this.initialized) {
8952
- await this.initializeDatabase();
8953
- }
8947
+ static withModel(model) {
8948
+ return new _AgentBuilder("default_agent").withModel(model);
8954
8949
  }
8955
- generateSessionId() {
8956
- return `session-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
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
- * Helper to safely parse JSON strings
8960
+ * Set the description for the agent
8961
+ * @param description Agent description
8962
+ * @returns This builder instance for chaining
8960
8963
  */
8961
- parseJsonSafely(jsonString, defaultValue) {
8962
- if (!jsonString) return defaultValue;
8963
- try {
8964
- return JSON.parse(jsonString);
8965
- } catch (e3) {
8966
- return defaultValue;
8967
- }
8964
+ withDescription(description) {
8965
+ this.config.description = description;
8966
+ return this;
8968
8967
  }
8969
8968
  /**
8970
- * Convert database timestamp to Unix seconds
8971
- * Handles different timestamp formats from different databases
8969
+ * Set the instruction for the agent
8970
+ * @param instruction System instruction for the agent
8971
+ * @returns This builder instance for chaining
8972
8972
  */
8973
- timestampToUnixSeconds(timestamp) {
8974
- if (timestamp instanceof Date) {
8975
- return timestamp.getTime() / 1e3;
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);
8976
9092
  }
8977
- if (typeof timestamp === "string") {
8978
- return new Date(timestamp).getTime() / 1e3;
9093
+ return { agent, runner, session };
9094
+ }
9095
+ /**
9096
+ * Quick execution helper - build and run a message
9097
+ * @param message Message to send to the agent
9098
+ * @returns Agent response
9099
+ */
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);
8979
9105
  }
8980
- if (typeof timestamp === "number") {
8981
- return timestamp > 1e10 ? timestamp / 1e3 : timestamp;
9106
+ const { runner, session } = await this.build();
9107
+ if (!runner || !session) {
9108
+ throw new Error("Failed to create runner and session");
8982
9109
  }
8983
- return Date.now() / 1e3;
8984
- }
8985
- async createSession(appName, userId, state, sessionId) {
8986
- await this.ensureInitialized();
8987
- const id = _optionalChain([sessionId, 'optionalAccess', _243 => _243.trim, 'call', _244 => _244()]) || this.generateSessionId();
8988
- return await this.db.transaction().execute(async (trx) => {
8989
- const appState = await trx.selectFrom("app_states").selectAll().where("app_name", "=", appName).executeTakeFirst();
8990
- const userState = await trx.selectFrom("user_states").selectAll().where("app_name", "=", appName).where("user_id", "=", userId).executeTakeFirst();
8991
- let currentAppState = this.parseJsonSafely(_optionalChain([appState, 'optionalAccess', _245 => _245.state]), {});
8992
- let currentUserState = this.parseJsonSafely(_optionalChain([userState, 'optionalAccess', _246 => _246.state]), {});
8993
- if (!appState) {
8994
- await trx.insertInto("app_states").values({
8995
- app_name: appName,
8996
- state: "{}"
8997
- }).execute();
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 }]
8998
9116
  }
8999
- if (!userState) {
9000
- await trx.insertInto("user_states").values({
9001
- app_name: appName,
9002
- user_id: userId,
9003
- state: "{}"
9004
- }).execute();
9117
+ })) {
9118
+ if (_optionalChain([event, 'access', _262 => _262.content, 'optionalAccess', _263 => _263.parts])) {
9119
+ const content = event.content.parts.map((part) => part.text || "").join("");
9120
+ if (content) {
9121
+ response += content;
9122
+ }
9005
9123
  }
9006
- const { appStateDelta, userStateDelta, sessionStateDelta } = this.extractStateDelta(state);
9007
- currentAppState = { ...currentAppState, ...appStateDelta };
9008
- currentUserState = { ...currentUserState, ...userStateDelta };
9009
- if (Object.keys(appStateDelta).length > 0) {
9010
- await trx.updateTable("app_states").set({
9011
- state: JSON.stringify(currentAppState),
9012
- update_time: _kysely.sql`CURRENT_TIMESTAMP`
9013
- }).where("app_name", "=", appName).execute();
9014
- }
9015
- if (Object.keys(userStateDelta).length > 0) {
9016
- await trx.updateTable("user_states").set({
9017
- state: JSON.stringify(currentUserState),
9018
- update_time: _kysely.sql`CURRENT_TIMESTAMP`
9019
- }).where("app_name", "=", appName).where("user_id", "=", userId).execute();
9124
+ }
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
+ }, _class28);
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
+
9207
+
9208
+
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;
9217
+ }
9218
+ async createSession(appName, userId, state, sessionId) {
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 (_optionalChain([lroResponse, 'optionalAccess', _264 => _264.done])) {
9247
+ break;
9020
9248
  }
9021
- const result = await trx.insertInto("sessions").values({
9022
- id,
9023
- app_name: appName,
9024
- user_id: userId,
9025
- state: JSON.stringify(sessionStateDelta)
9026
- }).returningAll().executeTakeFirstOrThrow();
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
- return {
9033
- id: result.id,
9034
- appName: result.app_name,
9035
- userId: result.user_id,
9036
- state: mergedState,
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
- await this.ensureInitialized();
9045
- return await this.db.transaction().execute(async (trx) => {
9046
- const storageSession = await trx.selectFrom("sessions").selectAll().where("app_name", "=", appName).where("user_id", "=", userId).where("id", "=", sessionId).executeTakeFirst();
9047
- if (!storageSession) {
9048
- return void 0;
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
- let eventQuery = trx.selectFrom("events").selectAll().where("session_id", "=", sessionId).orderBy("timestamp", "desc");
9051
- if (_optionalChain([config, 'optionalAccess', _247 => _247.afterTimestamp])) {
9052
- eventQuery = eventQuery.where(
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
- if (_optionalChain([config, 'optionalAccess', _248 => _248.numRecentEvents])) {
9059
- eventQuery = eventQuery.limit(config.numRecentEvents);
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
- const storageEvents = await eventQuery.execute();
9062
- const appState = await trx.selectFrom("app_states").selectAll().where("app_name", "=", appName).executeTakeFirst();
9063
- const userState = await trx.selectFrom("user_states").selectAll().where("app_name", "=", appName).where("user_id", "=", userId).executeTakeFirst();
9064
- const currentAppState = this.parseJsonSafely(_optionalChain([appState, 'optionalAccess', _249 => _249.state]), {});
9065
- const currentUserState = this.parseJsonSafely(_optionalChain([userState, 'optionalAccess', _250 => _250.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
- const events = storageEvents.reverse().map((storageEvent) => this.storageEventToEvent(storageEvent));
9073
- return {
9074
- id: sessionId,
9075
- appName,
9076
- userId,
9077
- state: mergedState,
9078
- events,
9079
- // Now properly typed as Event[]
9080
- lastUpdateTime: this.timestampToUnixSeconds(storageSession.update_time)
9081
- };
9082
- });
9083
- }
9084
- async updateSession(session) {
9085
- await this.ensureInitialized();
9086
- await this.db.updateTable("sessions").set({
9087
- state: JSON.stringify(session.state),
9088
- update_time: _kysely.sql`CURRENT_TIMESTAMP`
9089
- }).where("app_name", "=", session.appName).where("user_id", "=", session.userId).where("id", "=", session.id).execute();
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
- await this.ensureInitialized();
9093
- const results = await this.db.selectFrom("sessions").selectAll().where("app_name", "=", appName).where("user_id", "=", userId).execute();
9094
- const sessions = results.map((storageSession) => ({
9095
- id: storageSession.id,
9096
- appName: storageSession.app_name,
9097
- userId: storageSession.user_id,
9098
- state: {},
9099
- events: [],
9100
- // Fixed type annotation
9101
- lastUpdateTime: this.timestampToUnixSeconds(storageSession.update_time)
9102
- }));
9103
- return { sessions };
9104
- }
9105
- async deleteSession(appName, userId, sessionId) {
9106
- await this.ensureInitialized();
9107
- await this.db.deleteFrom("sessions").where("app_name", "=", appName).where("user_id", "=", userId).where("id", "=", sessionId).execute();
9108
- }
9109
- async appendEvent(session, event) {
9110
- await this.ensureInitialized();
9111
- if (event.partial) {
9112
- return event;
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}`;
9113
9350
  }
9114
- return await this.db.transaction().execute(async (trx) => {
9115
- const storageSession = await trx.selectFrom("sessions").selectAll().where("app_name", "=", session.appName).where("user_id", "=", session.userId).where("id", "=", session.id).executeTakeFirstOrThrow();
9116
- if (this.timestampToUnixSeconds(storageSession.update_time) > session.lastUpdateTime) {
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(_optionalChain([appState, 'optionalAccess', _251 => _251.state]), {});
9124
- let currentUserState = this.parseJsonSafely(_optionalChain([userState, 'optionalAccess', _252 => _252.state]), {});
9125
- let sessionState = this.parseJsonSafely(storageSession.state, {});
9126
- let appStateDelta = {};
9127
- let userStateDelta = {};
9128
- let sessionStateDelta = {};
9129
- if (_optionalChain([event, 'access', _253 => _253.actions, 'optionalAccess', _254 => _254.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: _kysely.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: _kysely.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: _kysely.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: _kysely.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;
9351
+ const apiResponse = await apiClient.async_request({
9352
+ http_method: "GET",
9353
+ path: path2,
9354
+ request_dict: {}
9166
9355
  });
9167
- }
9168
- /**
9169
- * Extract state deltas based on prefixes (similar to Python implementation)
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
- }
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);
9184
9371
  }
9185
9372
  }
9186
- return { appStateDelta, userStateDelta, sessionStateDelta };
9373
+ return { sessions };
9187
9374
  }
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;
9375
+ async deleteSession(appName, userId, sessionId) {
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;
9195
9387
  }
9196
- for (const [key, value] of Object.entries(userState)) {
9197
- mergedState[`user_${key}`] = value;
9388
+ }
9389
+ async appendEvent(session, 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)
9397
+ });
9398
+ return event;
9399
+ }
9400
+ getReasoningEngineId(appName) {
9401
+ if (this.agentEngineId) {
9402
+ return this.agentEngineId;
9198
9403
  }
9199
- return mergedState;
9404
+ if (/^\d+$/.test(appName)) {
9405
+ return appName;
9406
+ }
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
+ );
9413
+ }
9414
+ return match[3];
9200
9415
  }
9201
- /**
9202
- * Convert Event to storage event format
9203
- */
9204
- eventToStorageEvent(session, event) {
9205
- return {
9206
- id: event.id,
9207
- app_name: session.appName,
9208
- user_id: session.userId,
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
- * Convert storage event to Event format - Fixed to match Event interface
9226
- */
9227
- storageEventToEvent(storageEvent) {
9228
- const baseEvent = {
9229
- id: storageEvent.id,
9230
- invocationId: storageEvent.invocation_id,
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
- return {
9247
- ...baseEvent,
9248
- // Add any missing required methods from the Event interface
9249
- isFinalResponse: () => baseEvent.turnComplete === true,
9250
- getFunctionCalls: () => {
9251
- if (baseEvent.actions && typeof baseEvent.actions === "object" && "functionCalls" in baseEvent.actions) {
9252
- return baseEvent.actions.functionCalls || [];
9253
- }
9254
- return [];
9255
- },
9256
- getFunctionResponses: () => {
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
- hasTrailingCodeExecutionResult: () => {
9263
- if (baseEvent.actions && typeof baseEvent.actions === "object" && "hasTrailingCodeExecutionResult" in baseEvent.actions) {
9264
- return baseEvent.actions.hasTrailingCodeExecutionResult || false;
9265
- }
9266
- return false;
9267
- }
9445
+ error_code: event.errorCode,
9446
+ error_message: event.errorMessage,
9447
+ event_metadata: metadataJson
9268
9448
  };
9269
- }
9270
- /**
9271
- * Updates the session state based on the event.
9272
- * Overrides the base class method to work with plain object state.
9273
- */
9274
- updateSessionState(session, event) {
9275
- if (!_optionalChain([event, 'access', _255 => _255.actions, 'optionalAccess', _256 => _256.stateDelta])) {
9276
- return;
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
- for (const [key, value] of Object.entries(event.actions.stateDelta)) {
9279
- if (!key.startsWith("temp_")) {
9280
- session.state[key] = value;
9281
- }
9460
+ if (event.content) {
9461
+ eventJson.content = event.content;
9282
9462
  }
9463
+ return eventJson;
9283
9464
  }
9284
- }, _class27);
9285
-
9286
- // src/sessions/database-factories.ts
9287
-
9288
-
9289
- function createDependencyError(packageName, dbType) {
9290
- return new Error(
9291
- _dedent2.default`
9292
- Missing required peer dependency: ${packageName}
9293
- To use ${dbType} sessions, install the required package:
9294
- npm install ${packageName}
9295
- # or
9296
- pnpm add ${packageName}
9297
- # or
9298
- yarn add ${packageName}`
9299
- );
9300
- }
9301
- function createPostgresSessionService(connectionString, options) {
9302
- let Pool;
9303
- try {
9304
- ({ Pool } = __require("pg"));
9305
- } catch (error) {
9306
- throw createDependencyError("pg", "PostgreSQL");
9307
- }
9308
- const db = new (0, _kysely.Kysely)({
9309
- dialect: new (0, _kysely.PostgresDialect)({
9310
- pool: new Pool({
9311
- connectionString,
9312
- ...options
9313
- })
9314
- })
9315
- });
9316
- return new DatabaseSessionService({ db });
9317
- }
9318
- function createMysqlSessionService(connectionString, options) {
9319
- let createPool;
9320
- try {
9321
- ({ createPool } = __require("mysql2"));
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
- const db = new (0, _kysely.Kysely)({
9326
- dialect: new (0, _kysely.MysqlDialect)({
9327
- pool: createPool({
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
- const db = new (0, _kysely.Kysely)({
9343
- dialect: new (0, _kysely.SqliteDialect)({
9344
- database: new Database(filename, options)
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
- if (databaseUrl.startsWith("mysql://")) {
9354
- return createMysqlSessionService(databaseUrl, options);
9512
+ };
9513
+
9514
+ // src/sessions/database-session-service.ts
9515
+ var _kysely = require('kysely');
9516
+ var DatabaseSessionService = (_class29 = class extends BaseSessionService {
9517
+
9518
+ __init51() {this.initialized = false}
9519
+ constructor(config) {
9520
+ super();_class29.prototype.__init51.call(this);;
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
- if (databaseUrl.startsWith("sqlite://") || databaseUrl.includes(".db") || databaseUrl === ":memory:") {
9357
- const filename = databaseUrl.startsWith("sqlite://") ? databaseUrl.substring(9) : databaseUrl;
9358
- return createSqliteSessionService(filename, options);
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(_kysely.sql`CURRENT_TIMESTAMP`).notNull()
9540
+ ).addColumn(
9541
+ "update_time",
9542
+ "timestamp",
9543
+ (col) => col.defaultTo(_kysely.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(_kysely.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(_kysely.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(_kysely.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
- throw new Error(`Unsupported database URL: ${databaseUrl}`);
9361
- }
9362
-
9363
- // src/artifacts/gcs-artifact-service.ts
9364
- init_logger();
9365
-
9366
-
9367
- var _storage = require('@google-cloud/storage');
9368
- var logger9 = new Logger({ name: "GcsArtifactService" });
9369
- var GcsArtifactService = class {
9370
-
9371
-
9372
-
9373
- constructor(bucketName, options) {
9374
- this.bucketName = bucketName;
9375
- this.storageClient = new (0, _storage.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
- fileHasUserNamespace(filename) {
9379
- return filename.startsWith("user:");
9585
+ generateSessionId() {
9586
+ return `session-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
9380
9587
  }
9381
- getBlobName(appName, userId, sessionId, filename, version) {
9382
- if (this.fileHasUserNamespace(filename)) {
9383
- return `${appName}/${userId}/user/${filename}/${version}`;
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 (e3) {
9596
+ return defaultValue;
9384
9597
  }
9385
- return `${appName}/${userId}/${sessionId}/${filename}/${version}`;
9386
9598
  }
9387
- async saveArtifact(args) {
9388
- const { appName, userId, sessionId, filename, artifact } = args;
9389
- const versions = await this.listVersions({
9390
- appName,
9391
- userId,
9392
- sessionId,
9393
- filename
9394
- });
9395
- const version = versions.length === 0 ? 0 : Math.max(...versions) + 1;
9396
- const blobName = this.getBlobName(
9397
- appName,
9398
- userId,
9399
- sessionId,
9400
- filename,
9401
- version
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 loadArtifact(args) {
9411
- let { version } = args;
9412
- const { appName, userId, sessionId, filename } = args;
9413
- if (version === void 0 || version === null) {
9414
- const versions = await this.listVersions({
9415
- appName,
9416
- userId,
9417
- sessionId,
9418
- filename
9419
- });
9420
- if (versions.length === 0) {
9421
- return null;
9615
+ async createSession(appName, userId, state, sessionId) {
9616
+ await this.ensureInitialized();
9617
+ const id = _optionalChain([sessionId, 'optionalAccess', _265 => _265.trim, 'call', _266 => _266()]) || 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(_optionalChain([appState, 'optionalAccess', _267 => _267.state]), {});
9622
+ let currentUserState = this.parseJsonSafely(_optionalChain([userState, 'optionalAccess', _268 => _268.state]), {});
9623
+ if (!appState) {
9624
+ await trx.insertInto("app_states").values({
9625
+ app_name: appName,
9626
+ state: "{}"
9627
+ }).execute();
9422
9628
  }
9423
- version = Math.max(...versions);
9424
- }
9425
- const blobName = this.getBlobName(
9426
- appName,
9427
- userId,
9428
- sessionId,
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 part = {
9440
- inlineData: {
9441
- data: artifactBuffer.toString(),
9442
- mimeType: metadata.contentType || "application/octet-stream"
9443
- }
9444
- };
9445
- return part;
9446
- } catch (error) {
9447
- if (_optionalChain([error, 'optionalAccess', _257 => _257.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: _kysely.sql`CURRENT_TIMESTAMP`
9643
+ }).where("app_name", "=", appName).execute();
9449
9644
  }
9450
- throw error;
9451
- }
9452
- }
9453
- async listArtifactKeys(args) {
9454
- const { appName, userId, sessionId } = args;
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: _kysely.sql`CURRENT_TIMESTAMP`
9649
+ }).where("app_name", "=", appName).where("user_id", "=", userId).execute();
9463
9650
  }
9464
- };
9465
- const sessionPrefix = `${appName}/${userId}/${sessionId}/`;
9466
- const [sessionBlobs] = await this.storageClient.bucket(this.bucketName).getFiles({ prefix: sessionPrefix });
9467
- processBlobs(sessionBlobs.map((b) => b.name));
9468
- const userNamespacePrefix = `${appName}/${userId}/user/`;
9469
- const [userNamespaceBlobs] = await this.storageClient.bucket(this.bucketName).getFiles({ prefix: userNamespacePrefix });
9470
- processBlobs(userNamespaceBlobs.map((b) => b.name));
9471
- return Array.from(filenames).sort();
9472
- }
9473
- async deleteArtifact(args) {
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 this.bucket.file(blobName).delete();
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 listVersions(args) {
9494
- const { appName, userId, sessionId, filename } = args;
9495
- const prefix = this.getBlobName(appName, userId, sessionId, filename, "");
9496
- const [blobs] = await this.bucket.getFiles({ prefix });
9497
- const versions = [];
9498
- for (const blob of blobs) {
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;
9679
+ }
9680
+ let eventQuery = trx.selectFrom("events").selectAll().where("session_id", "=", sessionId).orderBy("timestamp", "desc");
9681
+ if (_optionalChain([config, 'optionalAccess', _269 => _269.afterTimestamp])) {
9682
+ eventQuery = eventQuery.where(
9683
+ "timestamp",
9684
+ ">=",
9685
+ new Date(config.afterTimestamp * 1e3)
9686
+ );
9687
+ }
9688
+ if (_optionalChain([config, 'optionalAccess', _270 => _270.numRecentEvents])) {
9689
+ eventQuery = eventQuery.limit(config.numRecentEvents);
9506
9690
  }
9507
- }
9508
- return versions.sort((a, b) => a - b);
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(_optionalChain([appState, 'optionalAccess', _271 => _271.state]), {});
9695
+ const currentUserState = this.parseJsonSafely(_optionalChain([userState, 'optionalAccess', _272 => _272.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
- // src/artifacts/in-memory-artifact-service.ts
9513
- init_logger();
9514
- var logger10 = new Logger({ name: "InMemoryArtifactService" });
9515
- var InMemoryArtifactService = (_class28 = class {constructor() { _class28.prototype.__init50.call(this); }
9516
- __init50() {this.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: _kysely.sql`CURRENT_TIMESTAMP`
9719
+ }).where("app_name", "=", session.appName).where("user_id", "=", session.userId).where("id", "=", session.id).execute();
9519
9720
  }
9520
- getArtifactPath(appName, userId, sessionId, filename) {
9521
- if (this.fileHasUserNamespace(filename)) {
9522
- return `${appName}/${userId}/user/${filename}`;
9523
- }
9524
- return `${appName}/${userId}/${sessionId}/${filename}`;
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 saveArtifact(args) {
9527
- const { appName, userId, sessionId, filename, artifact } = args;
9528
- const path2 = this.getArtifactPath(appName, userId, sessionId, filename);
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 loadArtifact(args) {
9538
- const { appName, userId, sessionId, filename, version } = args;
9539
- const path2 = this.getArtifactPath(appName, userId, sessionId, filename);
9540
- const versions = this.artifacts.get(path2);
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 versions[targetVersion];
9555
- }
9556
- async listArtifactKeys(args) {
9557
- const { appName, userId, sessionId } = args;
9558
- const sessionPrefix = `${appName}/${userId}/${sessionId}/`;
9559
- const userNamespacePrefix = `${appName}/${userId}/user/`;
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
- return filenames.sort();
9571
- }
9572
- async deleteArtifact(args) {
9573
- const { appName, userId, sessionId, filename } = args;
9574
- const path2 = this.getArtifactPath(appName, userId, sessionId, filename);
9575
- if (!this.artifacts.has(path2)) {
9576
- return;
9577
- }
9578
- this.artifacts.delete(path2);
9579
- }
9580
- async listVersions(args) {
9581
- const { appName, userId, sessionId, filename } = args;
9582
- const path2 = this.getArtifactPath(appName, userId, sessionId, filename);
9583
- const versions = this.artifacts.get(path2);
9584
- if (!versions || versions.length === 0) {
9585
- return [];
9586
- }
9587
- return Array.from({ length: versions.length }, (_, i) => i);
9588
- }
9589
- }, _class28);
9590
-
9591
- // src/flows/index.ts
9592
- var flows_exports = {};
9593
- __export(flows_exports, {
9594
- AF_FUNCTION_CALL_ID_PREFIX: () => AF_FUNCTION_CALL_ID_PREFIX,
9595
- AutoFlow: () => AutoFlow,
9596
- BaseLlmFlow: () => BaseLlmFlow,
9597
- BaseLlmRequestProcessor: () => BaseLlmRequestProcessor,
9598
- BaseLlmResponseProcessor: () => BaseLlmResponseProcessor,
9599
- REQUEST_EUC_FUNCTION_CALL_NAME: () => REQUEST_EUC_FUNCTION_CALL_NAME,
9600
- SingleFlow: () => SingleFlow,
9601
- agentTransferRequestProcessor: () => requestProcessor8,
9602
- basicRequestProcessor: () => requestProcessor,
9603
- codeExecutionRequestProcessor: () => requestProcessor7,
9604
- codeExecutionResponseProcessor: () => responseProcessor2,
9605
- contentRequestProcessor: () => requestProcessor5,
9606
- generateAuthEvent: () => generateAuthEvent,
9607
- generateClientFunctionCallId: () => generateClientFunctionCallId,
9608
- getLongRunningFunctionCalls: () => getLongRunningFunctionCalls,
9609
- handleFunctionCallsAsync: () => handleFunctionCallsAsync,
9610
- handleFunctionCallsLive: () => handleFunctionCallsLive,
9611
- identityRequestProcessor: () => requestProcessor3,
9612
- instructionsRequestProcessor: () => requestProcessor4,
9613
- mergeParallelFunctionResponseEvents: () => mergeParallelFunctionResponseEvents,
9614
- nlPlanningRequestProcessor: () => requestProcessor6,
9615
- nlPlanningResponseProcessor: () => responseProcessor,
9616
- populateClientFunctionCallId: () => populateClientFunctionCallId,
9617
- removeClientFunctionCallId: () => removeClientFunctionCallId
9618
- });
9619
-
9620
- // src/runners.ts
9621
-
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(_optionalChain([appState, 'optionalAccess', _273 => _273.state]), {});
9754
+ let currentUserState = this.parseJsonSafely(_optionalChain([userState, 'optionalAccess', _274 => _274.state]), {});
9755
+ let sessionState = this.parseJsonSafely(storageSession.state, {});
9756
+ let appStateDelta = {};
9757
+ let userStateDelta = {};
9758
+ let sessionStateDelta = {};
9759
+ if (_optionalChain([event, 'access', _275 => _275.actions, 'optionalAccess', _276 => _276.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: _kysely.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: _kysely.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: _kysely.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: _kysely.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
- const lastEvent = events[events.length - 1];
9630
- if (_optionalChain([lastEvent, 'access', _258 => _258.content, 'optionalAccess', _259 => _259.parts, 'optionalAccess', _260 => _260.some, 'call', _261 => _261((part) => part.functionResponse)])) {
9631
- const functionCallId = _optionalChain([lastEvent, 'access', _262 => _262.content, 'access', _263 => _263.parts, 'access', _264 => _264.find, 'call', _265 => _265(
9632
- (part) => part.functionResponse
9633
- ), 'optionalAccess', _266 => _266.functionResponse, 'optionalAccess', _267 => _267.id]);
9634
- if (!functionCallId) return null;
9635
- for (let i = events.length - 2; i >= 0; i--) {
9636
- const event = events[i];
9637
- const functionCalls = _optionalChain([event, 'access', _268 => _268.getFunctionCalls, 'optionalCall', _269 => _269()]) || [];
9638
- for (const functionCall of functionCalls) {
9639
- if (functionCall.id === functionCallId) {
9640
- return event;
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
-
9652
- /**
9653
- * The root agent to run.
9654
- */
9655
-
9656
- /**
9657
- * The artifact service for the runner.
9658
- */
9659
-
9660
- /**
9661
- * The session service for the runner.
9662
- */
9663
-
9664
9818
  /**
9665
- * The memory service for the runner.
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
- * Initializes the Runner.
9832
+ * Convert Event to storage event format
9670
9833
  */
9671
- constructor({
9672
- appName,
9673
- agent,
9674
- artifactService,
9675
- sessionService,
9676
- memoryService
9677
- }) {
9678
- this.appName = appName;
9679
- this.agent = agent;
9680
- this.artifactService = artifactService;
9681
- this.sessionService = sessionService;
9682
- this.memoryService = memoryService;
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
- * Runs the agent synchronously.
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
- run({
9690
- userId,
9691
- sessionId,
9692
- newMessage,
9693
- runConfig = new RunConfig()
9694
- }) {
9695
- const eventQueue = [];
9696
- let queueIndex = 0;
9697
- let asyncCompleted = false;
9698
- const invokeRunAsync = async () => {
9699
- try {
9700
- for await (const event of this.runAsync({
9701
- userId,
9702
- sessionId,
9703
- newMessage,
9704
- runConfig
9705
- })) {
9706
- eventQueue.push(event);
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
- invokeRunAsync();
9714
- return function* () {
9715
- while (true) {
9716
- while (queueIndex >= eventQueue.length && !asyncCompleted) {
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
- if (queueIndex >= eventQueue.length && asyncCompleted) {
9719
- break;
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
- const event = eventQueue[queueIndex++];
9722
- if (event === null) {
9723
- break;
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
- yield event;
9896
+ return false;
9726
9897
  }
9727
- }();
9898
+ };
9728
9899
  }
9729
9900
  /**
9730
- * Main entry method to run the agent in this runner.
9901
+ * Updates the session state based on the event.
9902
+ * Overrides the base class method to work with plain object state.
9731
9903
  */
9732
- async *runAsync({
9733
- userId,
9734
- sessionId,
9735
- newMessage,
9736
- runConfig = new RunConfig()
9737
- }) {
9738
- const span = tracer.startSpan("invocation");
9739
- try {
9740
- const session = await this.sessionService.getSession(
9741
- this.appName,
9904
+ updateSessionState(session, event) {
9905
+ if (!_optionalChain([event, 'access', _277 => _277.actions, 'optionalAccess', _278 => _278.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
+ }, _class29);
9915
+
9916
+ // src/sessions/database-factories.ts
9917
+
9918
+
9919
+ function createDependencyError(packageName, dbType) {
9920
+ return new Error(
9921
+ _dedent2.default`
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 (0, _kysely.Kysely)({
9939
+ dialect: new (0, _kysely.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 (0, _kysely.Kysely)({
9956
+ dialect: new (0, _kysely.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 (0, _kysely.Kysely)({
9973
+ dialect: new (0, _kysely.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
+
9996
+
9997
+ var _storage = require('@google-cloud/storage');
9998
+ var logger11 = new Logger({ name: "GcsArtifactService" });
9999
+ var GcsArtifactService = class {
10000
+
10001
+
10002
+
10003
+ constructor(bucketName, options) {
10004
+ this.bucketName = bucketName;
10005
+ this.storageClient = new (0, _storage.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 (newMessage) {
9753
- await this._appendNewMessageToSession(
9754
- session,
9755
- newMessage,
9756
- invocationContext,
9757
- runConfig.saveInputBlobsAsArtifacts || false
9758
- );
10050
+ if (versions.length === 0) {
10051
+ return null;
9759
10052
  }
9760
- invocationContext.agent = this._findAgentToRun(session, this.agent);
9761
- for await (const event of invocationContext.agent.runAsync(
9762
- invocationContext
9763
- )) {
9764
- if (!event.partial) {
9765
- await this.sessionService.appendEvent(session, event);
9766
- }
9767
- yield event;
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
- logger11.debug("Error running agent:", error);
9771
- span.recordException(error);
9772
- span.setStatus({
9773
- code: _api.SpanStatusCode.ERROR,
9774
- message: error instanceof Error ? error.message : "Unknown error"
9775
- });
10077
+ if (_optionalChain([error, 'optionalAccess', _279 => _279.code]) === 404) {
10078
+ return null;
10079
+ }
9776
10080
  throw error;
9777
- } finally {
9778
- span.end();
9779
10081
  }
9780
10082
  }
9781
- /**
9782
- * Appends a new message to the session.
9783
- */
9784
- async _appendNewMessageToSession(session, newMessage, invocationContext, saveInputBlobsAsArtifacts = false) {
9785
- if (!newMessage.parts) {
9786
- throw new Error("No parts in the new_message.");
9787
- }
9788
- if (this.artifactService && saveInputBlobsAsArtifacts) {
9789
- for (let i = 0; i < newMessage.parts.length; i++) {
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 event = new Event({
9813
- invocationId: invocationContext.invocationId,
9814
- author: "user",
9815
- content: userContent
9816
- });
9817
- await this.sessionService.appendEvent(session, event);
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
- * Finds the agent to run to continue the session.
9821
- */
9822
- _findAgentToRun(session, rootAgent) {
9823
- const event = _findFunctionCallEventIfLastEventIsFunctionResponse(session);
9824
- if (_optionalChain([event, 'optionalAccess', _270 => _270.author])) {
9825
- return rootAgent.findAgent(event.author);
9826
- }
9827
- const nonUserEvents = _optionalChain([session, 'access', _271 => _271.events, 'optionalAccess', _272 => _272.filter, 'call', _273 => _273((e) => e.author !== "user"), 'access', _274 => _274.reverse, 'call', _275 => _275()]) || [];
9828
- for (const event2 of nonUserEvents) {
9829
- if (event2.author === rootAgent.name) {
9830
- return rootAgent;
9831
- }
9832
- const agent = _optionalChain([rootAgent, 'access', _276 => _276.findSubAgent, 'optionalCall', _277 => _277(event2.author)]);
9833
- if (!agent) {
9834
- logger11.debug(
9835
- `Event from an unknown agent: ${event2.author}, event id: ${event2.id}`
9836
- );
9837
- continue;
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
- * Whether the agent to run can transfer to any other agent in the agent tree.
9847
- */
9848
- _isTransferableAcrossAgentTree(agentToRun) {
9849
- let agent = agentToRun;
9850
- while (agent) {
9851
- if (!(agent instanceof LlmAgent)) {
9852
- return false;
9853
- }
9854
- if (agent.disallowTransferToParent) {
9855
- return false;
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 true;
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
-
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
 
@@ -10028,4 +10296,5 @@ var VERSION = "0.1.0";
10028
10296
 
10029
10297
 
10030
10298
 
10031
- exports.AF_FUNCTION_CALL_ID_PREFIX = AF_FUNCTION_CALL_ID_PREFIX; exports.Agent = LlmAgent; exports.Agents = agents_exports; exports.AnthropicLlm = AnthropicLlm; exports.ApiKeyCredential = ApiKeyCredential; exports.ApiKeyScheme = ApiKeyScheme; exports.AuthConfig = AuthConfig; exports.AuthCredential = AuthCredential; exports.AuthCredentialType = AuthCredentialType; exports.AuthHandler = AuthHandler; exports.AuthScheme = AuthScheme; exports.AuthSchemeType = AuthSchemeType; exports.AuthTool = AuthTool; exports.AutoFlow = AutoFlow; exports.BaseAgent = BaseAgent; exports.BaseLLMConnection = BaseLLMConnection; exports.BaseLlm = BaseLlm; exports.BaseLlmFlow = BaseLlmFlow; exports.BaseLlmRequestProcessor = BaseLlmRequestProcessor; exports.BaseLlmResponseProcessor = BaseLlmResponseProcessor; exports.BasePlanner = BasePlanner; exports.BaseSessionService = BaseSessionService; exports.BaseTool = BaseTool; exports.BasicAuthCredential = BasicAuthCredential; exports.BearerTokenCredential = BearerTokenCredential; exports.BuiltInPlanner = BuiltInPlanner; exports.CallbackContext = CallbackContext; exports.DatabaseSessionService = DatabaseSessionService; exports.EnhancedAuthConfig = EnhancedAuthConfig; exports.Event = Event; exports.EventActions = EventActions; exports.Events = events_exports; exports.ExitLoopTool = ExitLoopTool; exports.FileOperationsTool = FileOperationsTool; exports.Flows = flows_exports; exports.FunctionTool = FunctionTool; exports.GcsArtifactService = GcsArtifactService; exports.GetUserChoiceTool = GetUserChoiceTool; exports.GoogleLlm = GoogleLlm; exports.GoogleSearch = GoogleSearch; exports.HttpRequestTool = HttpRequestTool; exports.HttpScheme = HttpScheme; exports.InMemoryArtifactService = InMemoryArtifactService; exports.InMemoryMemoryService = InMemoryMemoryService; exports.InMemoryRunner = InMemoryRunner; exports.InMemorySessionService = InMemorySessionService; exports.InvocationContext = InvocationContext; exports.LLMRegistry = LLMRegistry; exports.LangGraphAgent = LangGraphAgent; exports.LlmAgent = LlmAgent; exports.LlmCallsLimitExceededError = LlmCallsLimitExceededError; exports.LlmRequest = LlmRequest; exports.LlmResponse = LlmResponse; exports.LoadArtifactsTool = LoadArtifactsTool; exports.LoadMemoryTool = LoadMemoryTool; exports.LoopAgent = LoopAgent; exports.McpError = McpError; exports.McpErrorType = McpErrorType; exports.McpSamplingHandler = McpSamplingHandler; exports.McpToolset = McpToolset; exports.Memory = memory_exports; exports.Models = models_exports; exports.OAuth2Credential = OAuth2Credential; exports.OAuth2Scheme = OAuth2Scheme; exports.OpenAiLlm = OpenAiLlm; exports.OpenIdConnectScheme = OpenIdConnectScheme; exports.ParallelAgent = ParallelAgent; exports.PlanReActPlanner = PlanReActPlanner; exports.REQUEST_EUC_FUNCTION_CALL_NAME = REQUEST_EUC_FUNCTION_CALL_NAME; exports.ReadonlyContext = ReadonlyContext; exports.RunConfig = RunConfig; exports.Runner = Runner; exports.SequentialAgent = SequentialAgent; exports.Sessions = sessions_exports; exports.SingleFlow = SingleFlow; exports.State = State; exports.StreamingMode = StreamingMode; exports.TelemetryService = TelemetryService; exports.ToolContext = ToolContext; exports.Tools = tools_exports; exports.TransferToAgentTool = TransferToAgentTool; exports.UserInteractionTool = UserInteractionTool; exports.VERSION = VERSION; exports.VertexAiSessionService = VertexAiSessionService; exports.adkToMcpToolType = adkToMcpToolType; exports.agentTransferRequestProcessor = requestProcessor8; exports.basicRequestProcessor = requestProcessor; exports.buildFunctionDeclaration = buildFunctionDeclaration; exports.codeExecutionRequestProcessor = requestProcessor7; exports.codeExecutionResponseProcessor = responseProcessor2; exports.contentRequestProcessor = requestProcessor5; exports.createAuthToolArguments = createAuthToolArguments; exports.createDatabaseSessionService = createDatabaseSessionService; exports.createFunctionTool = createFunctionTool; exports.createMysqlSessionService = createMysqlSessionService; exports.createPostgresSessionService = createPostgresSessionService; exports.createSamplingHandler = createSamplingHandler; exports.createSqliteSessionService = createSqliteSessionService; exports.generateAuthEvent = generateAuthEvent; exports.generateClientFunctionCallId = generateClientFunctionCallId; exports.getLongRunningFunctionCalls = getLongRunningFunctionCalls; exports.getMcpTools = getMcpTools; exports.handleFunctionCallsAsync = handleFunctionCallsAsync; exports.handleFunctionCallsLive = handleFunctionCallsLive; exports.identityRequestProcessor = requestProcessor3; exports.initializeTelemetry = initializeTelemetry; exports.injectSessionState = injectSessionState; exports.instructionsRequestProcessor = requestProcessor4; exports.isEnhancedAuthConfig = isEnhancedAuthConfig; exports.jsonSchemaToDeclaration = jsonSchemaToDeclaration; exports.mcpSchemaToParameters = mcpSchemaToParameters; exports.mergeParallelFunctionResponseEvents = mergeParallelFunctionResponseEvents; exports.newInvocationContextId = newInvocationContextId; exports.nlPlanningRequestProcessor = requestProcessor6; exports.nlPlanningResponseProcessor = responseProcessor; exports.normalizeJsonSchema = normalizeJsonSchema; exports.populateClientFunctionCallId = populateClientFunctionCallId; exports.registerProviders = registerProviders; exports.removeClientFunctionCallId = removeClientFunctionCallId; exports.requestProcessor = requestProcessor2; exports.shutdownTelemetry = shutdownTelemetry; exports.telemetryService = telemetryService; exports.traceLlmCall = traceLlmCall; exports.traceToolCall = traceToolCall; exports.tracer = tracer;
10299
+
10300
+ exports.AF_FUNCTION_CALL_ID_PREFIX = AF_FUNCTION_CALL_ID_PREFIX; exports.Agent = LlmAgent; exports.AgentBuilder = AgentBuilder; exports.Agents = agents_exports; exports.AnthropicLlm = AnthropicLlm; exports.ApiKeyCredential = ApiKeyCredential; exports.ApiKeyScheme = ApiKeyScheme; exports.AuthConfig = AuthConfig; exports.AuthCredential = AuthCredential; exports.AuthCredentialType = AuthCredentialType; exports.AuthHandler = AuthHandler; exports.AuthScheme = AuthScheme; exports.AuthSchemeType = AuthSchemeType; exports.AuthTool = AuthTool; exports.AutoFlow = AutoFlow; exports.BaseAgent = BaseAgent; exports.BaseLLMConnection = BaseLLMConnection; exports.BaseLlm = BaseLlm; exports.BaseLlmFlow = BaseLlmFlow; exports.BaseLlmRequestProcessor = BaseLlmRequestProcessor; exports.BaseLlmResponseProcessor = BaseLlmResponseProcessor; exports.BasePlanner = BasePlanner; exports.BaseSessionService = BaseSessionService; exports.BaseTool = BaseTool; exports.BasicAuthCredential = BasicAuthCredential; exports.BearerTokenCredential = BearerTokenCredential; exports.BuiltInPlanner = BuiltInPlanner; exports.CallbackContext = CallbackContext; exports.DatabaseSessionService = DatabaseSessionService; exports.EnhancedAuthConfig = EnhancedAuthConfig; exports.Event = Event; exports.EventActions = EventActions; exports.Events = events_exports; exports.ExitLoopTool = ExitLoopTool; exports.FileOperationsTool = FileOperationsTool; exports.Flows = flows_exports; exports.FunctionTool = FunctionTool; exports.GcsArtifactService = GcsArtifactService; exports.GetUserChoiceTool = GetUserChoiceTool; exports.GoogleLlm = GoogleLlm; exports.GoogleSearch = GoogleSearch; exports.HttpRequestTool = HttpRequestTool; exports.HttpScheme = HttpScheme; exports.InMemoryArtifactService = InMemoryArtifactService; exports.InMemoryMemoryService = InMemoryMemoryService; exports.InMemoryRunner = InMemoryRunner; exports.InMemorySessionService = InMemorySessionService; exports.InvocationContext = InvocationContext; exports.LLMRegistry = LLMRegistry; exports.LangGraphAgent = LangGraphAgent; exports.LlmAgent = LlmAgent; exports.LlmCallsLimitExceededError = LlmCallsLimitExceededError; exports.LlmRequest = LlmRequest; exports.LlmResponse = LlmResponse; exports.LoadArtifactsTool = LoadArtifactsTool; exports.LoadMemoryTool = LoadMemoryTool; exports.LoopAgent = LoopAgent; exports.McpError = McpError; exports.McpErrorType = McpErrorType; exports.McpSamplingHandler = McpSamplingHandler; exports.McpToolset = McpToolset; exports.Memory = memory_exports; exports.Models = models_exports; exports.OAuth2Credential = OAuth2Credential; exports.OAuth2Scheme = OAuth2Scheme; exports.OpenAiLlm = OpenAiLlm; exports.OpenIdConnectScheme = OpenIdConnectScheme; exports.ParallelAgent = ParallelAgent; exports.PlanReActPlanner = PlanReActPlanner; exports.REQUEST_EUC_FUNCTION_CALL_NAME = REQUEST_EUC_FUNCTION_CALL_NAME; exports.ReadonlyContext = ReadonlyContext; exports.RunConfig = RunConfig; exports.Runner = Runner; exports.SequentialAgent = SequentialAgent; exports.Sessions = sessions_exports; exports.SingleFlow = SingleFlow; exports.State = State; exports.StreamingMode = StreamingMode; exports.TelemetryService = TelemetryService; exports.ToolContext = ToolContext; exports.Tools = tools_exports; exports.TransferToAgentTool = TransferToAgentTool; exports.UserInteractionTool = UserInteractionTool; exports.VERSION = VERSION; exports.VertexAiSessionService = VertexAiSessionService; exports.adkToMcpToolType = adkToMcpToolType; exports.agentTransferRequestProcessor = requestProcessor8; exports.basicRequestProcessor = requestProcessor; exports.buildFunctionDeclaration = buildFunctionDeclaration; exports.codeExecutionRequestProcessor = requestProcessor7; exports.codeExecutionResponseProcessor = responseProcessor2; exports.contentRequestProcessor = requestProcessor5; exports.createAuthToolArguments = createAuthToolArguments; exports.createDatabaseSessionService = createDatabaseSessionService; exports.createFunctionTool = createFunctionTool; exports.createMysqlSessionService = createMysqlSessionService; exports.createPostgresSessionService = createPostgresSessionService; exports.createSamplingHandler = createSamplingHandler; exports.createSqliteSessionService = createSqliteSessionService; exports.generateAuthEvent = generateAuthEvent; exports.generateClientFunctionCallId = generateClientFunctionCallId; exports.getLongRunningFunctionCalls = getLongRunningFunctionCalls; exports.getMcpTools = getMcpTools; exports.handleFunctionCallsAsync = handleFunctionCallsAsync; exports.handleFunctionCallsLive = handleFunctionCallsLive; exports.identityRequestProcessor = requestProcessor3; exports.initializeTelemetry = initializeTelemetry; exports.injectSessionState = injectSessionState; exports.instructionsRequestProcessor = requestProcessor4; exports.isEnhancedAuthConfig = isEnhancedAuthConfig; exports.jsonSchemaToDeclaration = jsonSchemaToDeclaration; exports.mcpSchemaToParameters = mcpSchemaToParameters; exports.mergeParallelFunctionResponseEvents = mergeParallelFunctionResponseEvents; exports.newInvocationContextId = newInvocationContextId; exports.nlPlanningRequestProcessor = requestProcessor6; exports.nlPlanningResponseProcessor = responseProcessor; exports.normalizeJsonSchema = normalizeJsonSchema; exports.populateClientFunctionCallId = populateClientFunctionCallId; exports.registerProviders = registerProviders; exports.removeClientFunctionCallId = removeClientFunctionCallId; exports.requestProcessor = requestProcessor2; exports.shutdownTelemetry = shutdownTelemetry; exports.telemetryService = telemetryService; exports.traceLlmCall = traceLlmCall; exports.traceToolCall = traceToolCall; exports.tracer = tracer;