@iqai/adk 0.5.0 → 0.5.3

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.mjs CHANGED
@@ -3389,6 +3389,15 @@ var EventActions = class {
3389
3389
  * Requested authentication configurations.
3390
3390
  */
3391
3391
  requestedAuthConfigs;
3392
+ /**
3393
+ * Event compaction information. When set, this event represents
3394
+ * a compaction of events within the specified timestamp range.
3395
+ */
3396
+ compaction;
3397
+ /**
3398
+ * The invocation id to rewind to. This is only set for rewind event.
3399
+ */
3400
+ rewindBeforeInvocationId;
3392
3401
  /**
3393
3402
  * Constructor for EventActions
3394
3403
  */
@@ -3399,6 +3408,8 @@ var EventActions = class {
3399
3408
  this.transferToAgent = options.transferToAgent;
3400
3409
  this.escalate = options.escalate;
3401
3410
  this.requestedAuthConfigs = options.requestedAuthConfigs;
3411
+ this.compaction = options.compaction;
3412
+ this.rewindBeforeInvocationId = options.rewindBeforeInvocationId;
3402
3413
  }
3403
3414
  };
3404
3415
 
@@ -3941,9 +3952,196 @@ init_logger();
3941
3952
  var events_exports = {};
3942
3953
  __export(events_exports, {
3943
3954
  Event: () => Event,
3944
- EventActions: () => EventActions
3955
+ EventActions: () => EventActions,
3956
+ LlmEventSummarizer: () => LlmEventSummarizer,
3957
+ runCompactionForSlidingWindow: () => runCompactionForSlidingWindow
3945
3958
  });
3946
3959
 
3960
+ // src/events/llm-event-summarizer.ts
3961
+ var DEFAULT_SUMMARIZATION_PROMPT = `You are a helpful assistant tasked with summarizing a conversation history.
3962
+ Please provide a concise summary of the following events, capturing the key information and context.
3963
+ Focus on the main topics discussed, important decisions made, and any action items or results.
3964
+
3965
+ Events to summarize:
3966
+ {events}
3967
+
3968
+ Provide your summary in a clear, concise format.`;
3969
+ var LlmEventSummarizer = class {
3970
+ model;
3971
+ prompt;
3972
+ /**
3973
+ * Creates a new LLM event summarizer.
3974
+ * @param model - The LLM model to use for summarization
3975
+ * @param prompt - Optional custom prompt template. Use {events} as placeholder for event content.
3976
+ */
3977
+ constructor(model, prompt) {
3978
+ this.model = model;
3979
+ this.prompt = prompt || DEFAULT_SUMMARIZATION_PROMPT;
3980
+ }
3981
+ /**
3982
+ * Summarizes events using the configured LLM.
3983
+ */
3984
+ async maybeSummarizeEvents(events) {
3985
+ if (!events || events.length === 0) {
3986
+ return void 0;
3987
+ }
3988
+ const eventsText = this.formatEventsForSummarization(events);
3989
+ const promptWithEvents = this.prompt.replace("{events}", eventsText);
3990
+ const llmRequest = new LlmRequest({
3991
+ contents: [
3992
+ {
3993
+ role: "user",
3994
+ parts: [{ text: promptWithEvents }]
3995
+ }
3996
+ ]
3997
+ });
3998
+ let summaryText = "";
3999
+ for await (const response of this.model.generateContentAsync(llmRequest)) {
4000
+ summaryText += response.content?.parts?.map((part) => part.text || "").join("");
4001
+ }
4002
+ summaryText = summaryText.trim();
4003
+ if (!summaryText) {
4004
+ return void 0;
4005
+ }
4006
+ const summaryContent = {
4007
+ role: "model",
4008
+ parts: [{ text: summaryText }]
4009
+ };
4010
+ const compactionEvent = new Event({
4011
+ invocationId: Event.newId(),
4012
+ author: "user",
4013
+ actions: new EventActions({
4014
+ compaction: {
4015
+ startTimestamp: events[0].timestamp,
4016
+ endTimestamp: events[events.length - 1].timestamp,
4017
+ compactedContent: summaryContent
4018
+ }
4019
+ })
4020
+ });
4021
+ return compactionEvent;
4022
+ }
4023
+ /**
4024
+ * Formats events into a readable text format for summarization.
4025
+ */
4026
+ formatEventsForSummarization(events) {
4027
+ const lines = [];
4028
+ for (const event of events) {
4029
+ const timestamp = new Date(event.timestamp * 1e3).toISOString();
4030
+ const author = event.author;
4031
+ if (event.content?.parts) {
4032
+ for (const part of event.content.parts) {
4033
+ if (part.text) {
4034
+ lines.push(`[${timestamp}] ${author}: ${part.text}`);
4035
+ } else if (part.functionCall) {
4036
+ lines.push(
4037
+ `[${timestamp}] ${author}: Called tool '${part.functionCall.name}' with args ${JSON.stringify(part.functionCall.args)}`
4038
+ );
4039
+ } else if (part.functionResponse) {
4040
+ lines.push(
4041
+ `[${timestamp}] ${author}: Tool '${part.functionResponse.name}' returned: ${JSON.stringify(part.functionResponse.response)}`
4042
+ );
4043
+ }
4044
+ }
4045
+ }
4046
+ }
4047
+ return lines.join("\n");
4048
+ }
4049
+ };
4050
+
4051
+ // src/events/compaction.ts
4052
+ init_logger();
4053
+ var logger = new Logger({ name: "EventCompaction" });
4054
+ async function runCompactionForSlidingWindow(config, session, sessionService, summarizer) {
4055
+ if (!session.events || session.events.length === 0) {
4056
+ return;
4057
+ }
4058
+ const lastCompactedEndTimestamp = findLastCompactedEndTimestamp(
4059
+ session.events
4060
+ );
4061
+ const latestTimestampByInvocation = buildLatestTimestampByInvocation(
4062
+ session.events
4063
+ );
4064
+ const uniqueInvocationIds = Array.from(latestTimestampByInvocation.keys());
4065
+ const newInvocationIds = uniqueInvocationIds.filter(
4066
+ (invId) => (latestTimestampByInvocation.get(invId) || 0) > lastCompactedEndTimestamp
4067
+ );
4068
+ if (newInvocationIds.length < config.compactionInterval) {
4069
+ logger.debug(
4070
+ `Not enough new invocations for compaction. Need ${config.compactionInterval}, have ${newInvocationIds.length}`
4071
+ );
4072
+ return;
4073
+ }
4074
+ const endInvId = newInvocationIds[newInvocationIds.length - 1];
4075
+ const firstNewInvId = newInvocationIds[0];
4076
+ const firstNewInvIdx = uniqueInvocationIds.indexOf(firstNewInvId);
4077
+ const startIdx = Math.max(0, firstNewInvIdx - config.overlapSize);
4078
+ const startInvId = uniqueInvocationIds[startIdx];
4079
+ logger.debug(
4080
+ `Compacting invocations from ${startInvId} to ${endInvId} (${newInvocationIds.length} new invocations, overlap: ${config.overlapSize})`
4081
+ );
4082
+ const eventsToCompact = sliceEventsByInvocationRange(
4083
+ session.events,
4084
+ startInvId,
4085
+ endInvId
4086
+ );
4087
+ if (eventsToCompact.length === 0) {
4088
+ logger.debug("No events to compact after filtering");
4089
+ return;
4090
+ }
4091
+ logger.debug(`Summarizing ${eventsToCompact.length} events`);
4092
+ const compactionEvent = await summarizer.maybeSummarizeEvents(eventsToCompact);
4093
+ if (compactionEvent) {
4094
+ logger.debug(
4095
+ `Compaction created covering timestamps ${compactionEvent.actions.compaction?.startTimestamp} to ${compactionEvent.actions.compaction?.endTimestamp}`
4096
+ );
4097
+ await sessionService.appendEvent(session, compactionEvent);
4098
+ }
4099
+ }
4100
+ function findLastCompactedEndTimestamp(events) {
4101
+ for (let i = events.length - 1; i >= 0; i--) {
4102
+ const event = events[i];
4103
+ if (event.actions?.compaction) {
4104
+ return event.actions.compaction.endTimestamp;
4105
+ }
4106
+ }
4107
+ return 0;
4108
+ }
4109
+ function buildLatestTimestampByInvocation(events) {
4110
+ const latestByInvocation = /* @__PURE__ */ new Map();
4111
+ for (const event of events) {
4112
+ if (event.actions?.compaction) {
4113
+ continue;
4114
+ }
4115
+ const invId = event.invocationId;
4116
+ if (!invId) {
4117
+ continue;
4118
+ }
4119
+ const current = latestByInvocation.get(invId) || 0;
4120
+ if (event.timestamp > current) {
4121
+ latestByInvocation.set(invId, event.timestamp);
4122
+ }
4123
+ }
4124
+ return latestByInvocation;
4125
+ }
4126
+ function sliceEventsByInvocationRange(events, startInvId, endInvId) {
4127
+ let firstIndex = -1;
4128
+ let lastIndex = -1;
4129
+ for (let i = 0; i < events.length; i++) {
4130
+ const event = events[i];
4131
+ if (event.invocationId === startInvId && firstIndex === -1) {
4132
+ firstIndex = i;
4133
+ }
4134
+ if (event.invocationId === endInvId) {
4135
+ lastIndex = i;
4136
+ }
4137
+ }
4138
+ if (firstIndex === -1 || lastIndex === -1 || firstIndex > lastIndex) {
4139
+ return [];
4140
+ }
4141
+ const slicedEvents = events.slice(firstIndex, lastIndex + 1);
4142
+ return slicedEvents.filter((event) => !event.actions?.compaction);
4143
+ }
4144
+
3947
4145
  // src/flows/llm-flows/base-llm-flow.ts
3948
4146
  init_logger();
3949
4147
 
@@ -7393,8 +7591,8 @@ var BasicLlmRequestProcessor = class extends BaseLlmRequestProcessor {
7393
7591
  } else {
7394
7592
  (() => {
7395
7593
  try {
7396
- const logger = new Logger({ name: "BasicLlmRequestProcessor" });
7397
- logger.debug(
7594
+ const logger2 = new Logger({ name: "BasicLlmRequestProcessor" });
7595
+ logger2.debug(
7398
7596
  `Skipping request-level output schema for agent ${agent.name} because tools/transfers are present. Schema will be validated during response processing.`
7399
7597
  );
7400
7598
  } catch (e) {
@@ -8275,8 +8473,30 @@ function rearrangeEventsForLatestFunctionResponse(events) {
8275
8473
  return resultEvents;
8276
8474
  }
8277
8475
  function getContents(currentBranch, events, agentName = "") {
8476
+ const invocationIdToIndex = /* @__PURE__ */ new Map();
8477
+ for (let idx = 0; idx < events.length; idx++) {
8478
+ if (events[idx].invocationId) {
8479
+ invocationIdToIndex.set(events[idx].invocationId, idx);
8480
+ }
8481
+ }
8482
+ const rewindFilteredEvents = [];
8483
+ let i = events.length - 1;
8484
+ while (i >= 0) {
8485
+ const event = events[i];
8486
+ if (event.actions?.rewindBeforeInvocationId) {
8487
+ const rewindInvocationId = event.actions.rewindBeforeInvocationId;
8488
+ const rewindIndex = invocationIdToIndex.get(rewindInvocationId);
8489
+ if (rewindIndex !== void 0 && rewindIndex < i) {
8490
+ i = rewindIndex;
8491
+ }
8492
+ } else {
8493
+ rewindFilteredEvents.push(event);
8494
+ }
8495
+ i--;
8496
+ }
8497
+ rewindFilteredEvents.reverse();
8278
8498
  const filteredEvents = [];
8279
- for (const event of events) {
8499
+ for (const event of rewindFilteredEvents) {
8280
8500
  if (!event.content || !event.content.role || !event.content.parts || event.content.parts.length === 0) {
8281
8501
  continue;
8282
8502
  }
@@ -8296,7 +8516,8 @@ function getContents(currentBranch, events, agentName = "") {
8296
8516
  isOtherAgentReply(agentName, event) ? convertForeignEvent(event) : event
8297
8517
  );
8298
8518
  }
8299
- let resultEvents = rearrangeEventsForLatestFunctionResponse(filteredEvents);
8519
+ const processedEvents = processCompactionEvents(filteredEvents);
8520
+ let resultEvents = rearrangeEventsForLatestFunctionResponse(processedEvents);
8300
8521
  resultEvents = rearrangeEventsForAsyncFunctionResponsesInHistory(resultEvents);
8301
8522
  const contents = [];
8302
8523
  for (const event of resultEvents) {
@@ -8408,6 +8629,31 @@ function isAuthEvent(event) {
8408
8629
  }
8409
8630
  return false;
8410
8631
  }
8632
+ function processCompactionEvents(events) {
8633
+ const result = [];
8634
+ let lastCompactionStartTime = Number.POSITIVE_INFINITY;
8635
+ for (let i = events.length - 1; i >= 0; i--) {
8636
+ const event = events[i];
8637
+ if (event.actions?.compaction) {
8638
+ const compaction = event.actions.compaction;
8639
+ const synthesizedEvent = new Event({
8640
+ timestamp: compaction.endTimestamp,
8641
+ author: "model",
8642
+ content: compaction.compactedContent,
8643
+ branch: event.branch,
8644
+ invocationId: event.invocationId
8645
+ });
8646
+ result.unshift(synthesizedEvent);
8647
+ lastCompactionStartTime = Math.min(
8648
+ lastCompactionStartTime,
8649
+ compaction.startTimestamp
8650
+ );
8651
+ } else if (event.timestamp < lastCompactionStartTime) {
8652
+ result.unshift(event);
8653
+ }
8654
+ }
8655
+ return result;
8656
+ }
8411
8657
 
8412
8658
  // src/flows/llm-flows/identity.ts
8413
8659
  var IdentityLlmRequestProcessor = class extends BaseLlmRequestProcessor {
@@ -8777,14 +9023,7 @@ var NlPlanningRequestProcessor = class extends BaseLlmRequestProcessor {
8777
9023
  llmRequest
8778
9024
  );
8779
9025
  if (planningInstruction) {
8780
- if (llmRequest.appendInstructions) {
8781
- llmRequest.appendInstructions([planningInstruction]);
8782
- } else {
8783
- const existingInstructions = llmRequest.instructions || "";
8784
- llmRequest.instructions = `${existingInstructions}
8785
-
8786
- ${planningInstruction}`;
8787
- }
9026
+ llmRequest.appendInstructions([planningInstruction]);
8788
9027
  }
8789
9028
  removeThoughtFromRequest(llmRequest);
8790
9029
  for await (const _ of []) {
@@ -9876,7 +10115,7 @@ init_logger();
9876
10115
  import { generateId } from "ai";
9877
10116
 
9878
10117
  // src/runners.ts
9879
- import { SpanStatusCode, context as context3, trace as trace3 } from "@opentelemetry/api";
10118
+ import { context as context3, SpanStatusCode, trace as trace3 } from "@opentelemetry/api";
9880
10119
 
9881
10120
  // src/agents/run-config.ts
9882
10121
  var StreamingMode = /* @__PURE__ */ ((StreamingMode2) => {
@@ -9972,6 +10211,48 @@ var RunConfig = class {
9972
10211
  }
9973
10212
  };
9974
10213
 
10214
+ // src/artifacts/artifact-util.ts
10215
+ var SESSION_SCOPED_ARTIFACT_URI_RE = /^artifact:\/\/apps\/([^/]+)\/users\/([^/]+)\/sessions\/([^/]+)\/artifacts\/([^/]+)\/versions\/(\d+)$/;
10216
+ var USER_SCOPED_ARTIFACT_URI_RE = /^artifact:\/\/apps\/([^/]+)\/users\/([^/]+)\/artifacts\/([^/]+)\/versions\/(\d+)$/;
10217
+ function parseArtifactUri(uri) {
10218
+ if (!uri || !uri.startsWith("artifact://")) {
10219
+ return null;
10220
+ }
10221
+ let match = SESSION_SCOPED_ARTIFACT_URI_RE.exec(uri);
10222
+ if (match) {
10223
+ return {
10224
+ appName: match[1],
10225
+ userId: match[2],
10226
+ sessionId: match[3],
10227
+ filename: match[4],
10228
+ version: Number.parseInt(match[5], 10)
10229
+ };
10230
+ }
10231
+ match = USER_SCOPED_ARTIFACT_URI_RE.exec(uri);
10232
+ if (match) {
10233
+ return {
10234
+ appName: match[1],
10235
+ userId: match[2],
10236
+ sessionId: void 0,
10237
+ filename: match[3],
10238
+ version: Number.parseInt(match[4], 10)
10239
+ };
10240
+ }
10241
+ return null;
10242
+ }
10243
+ function getArtifactUri(args) {
10244
+ const { appName, userId, filename, version, sessionId } = args;
10245
+ if (sessionId) {
10246
+ return `artifact://apps/${appName}/users/${userId}/sessions/${sessionId}/artifacts/${filename}/versions/${version}`;
10247
+ }
10248
+ return `artifact://apps/${appName}/users/${userId}/artifacts/${filename}/versions/${version}`;
10249
+ }
10250
+ function isArtifactRef(artifact) {
10251
+ return Boolean(
10252
+ artifact.fileData?.fileUri && artifact.fileData.fileUri.startsWith("artifact://")
10253
+ );
10254
+ }
10255
+
9975
10256
  // src/artifacts/in-memory-artifact-service.ts
9976
10257
  var InMemoryArtifactService = class {
9977
10258
  artifacts = /* @__PURE__ */ new Map();
@@ -10012,7 +10293,29 @@ var InMemoryArtifactService = class {
10012
10293
  if (targetVersion < 0 || targetVersion >= versions.length) {
10013
10294
  return null;
10014
10295
  }
10015
- return versions[targetVersion];
10296
+ const artifactEntry = versions[targetVersion];
10297
+ if (!artifactEntry) {
10298
+ return null;
10299
+ }
10300
+ if (isArtifactRef(artifactEntry)) {
10301
+ const parsedUri = parseArtifactUri(artifactEntry.fileData?.fileUri || "");
10302
+ if (!parsedUri) {
10303
+ throw new Error(
10304
+ `Invalid artifact reference URI: ${artifactEntry.fileData?.fileUri}`
10305
+ );
10306
+ }
10307
+ return await this.loadArtifact({
10308
+ appName: parsedUri.appName,
10309
+ userId: parsedUri.userId,
10310
+ sessionId: parsedUri.sessionId || sessionId,
10311
+ filename: parsedUri.filename,
10312
+ version: parsedUri.version
10313
+ });
10314
+ }
10315
+ if (!artifactEntry.text && (!artifactEntry.inlineData?.data || artifactEntry.inlineData.data.length === 0) && !artifactEntry.fileData) {
10316
+ return null;
10317
+ }
10318
+ return artifactEntry;
10016
10319
  }
10017
10320
  async listArtifactKeys(args) {
10018
10321
  const { appName, userId, sessionId } = args;
@@ -10197,11 +10500,16 @@ var BaseSessionService = class {
10197
10500
  return;
10198
10501
  }
10199
10502
  for (const key in event.actions.stateDelta) {
10200
- if (Object.prototype.hasOwnProperty.call(event.actions.stateDelta, key)) {
10503
+ if (Object.hasOwn(event.actions.stateDelta, key)) {
10201
10504
  if (key.startsWith("temp_")) {
10202
10505
  continue;
10203
10506
  }
10204
- session.state[key] = event.actions.stateDelta[key];
10507
+ const value = event.actions.stateDelta[key];
10508
+ if (value === null || value === void 0) {
10509
+ delete session.state[key];
10510
+ } else {
10511
+ session.state[key] = value;
10512
+ }
10205
10513
  }
10206
10514
  }
10207
10515
  }
@@ -10464,6 +10772,10 @@ var Runner = class {
10464
10772
  * The memory service for the runner.
10465
10773
  */
10466
10774
  memoryService;
10775
+ /**
10776
+ * Configuration for event compaction.
10777
+ */
10778
+ eventsCompactionConfig;
10467
10779
  logger = new Logger({ name: "Runner" });
10468
10780
  /**
10469
10781
  * Initializes the Runner.
@@ -10473,13 +10785,15 @@ var Runner = class {
10473
10785
  agent,
10474
10786
  artifactService,
10475
10787
  sessionService,
10476
- memoryService
10788
+ memoryService,
10789
+ eventsCompactionConfig
10477
10790
  }) {
10478
10791
  this.appName = appName;
10479
10792
  this.agent = agent;
10480
10793
  this.artifactService = artifactService;
10481
10794
  this.sessionService = sessionService;
10482
10795
  this.memoryService = memoryService;
10796
+ this.eventsCompactionConfig = eventsCompactionConfig;
10483
10797
  }
10484
10798
  /**
10485
10799
  * Runs the agent synchronously.
@@ -10581,6 +10895,10 @@ var Runner = class {
10581
10895
  }
10582
10896
  yield event;
10583
10897
  }
10898
+ await context3.with(
10899
+ spanContext,
10900
+ () => this._runCompaction(session, invocationContext)
10901
+ );
10584
10902
  } catch (error) {
10585
10903
  this.logger.debug("Error running agent:", error);
10586
10904
  span.recordException(error);
@@ -10693,6 +11011,188 @@ var Runner = class {
10693
11011
  runConfig
10694
11012
  });
10695
11013
  }
11014
+ /**
11015
+ * Runs compaction if configured.
11016
+ */
11017
+ async _runCompaction(session, _invocationContext) {
11018
+ if (!this.eventsCompactionConfig) {
11019
+ return;
11020
+ }
11021
+ const summarizer = this._getOrCreateSummarizer();
11022
+ if (!summarizer) {
11023
+ this.logger.warn(
11024
+ "Event compaction configured but no summarizer available"
11025
+ );
11026
+ return;
11027
+ }
11028
+ try {
11029
+ await runCompactionForSlidingWindow(
11030
+ this.eventsCompactionConfig,
11031
+ session,
11032
+ this.sessionService,
11033
+ summarizer
11034
+ );
11035
+ } catch (error) {
11036
+ this.logger.error("Error running compaction:", error);
11037
+ }
11038
+ }
11039
+ /**
11040
+ * Gets the configured summarizer or creates a default LLM-based one.
11041
+ */
11042
+ _getOrCreateSummarizer() {
11043
+ if (this.eventsCompactionConfig?.summarizer) {
11044
+ return this.eventsCompactionConfig.summarizer;
11045
+ }
11046
+ if (this.agent instanceof LlmAgent) {
11047
+ try {
11048
+ const model = this.agent.canonicalModel;
11049
+ return new LlmEventSummarizer(model);
11050
+ } catch (error) {
11051
+ this.logger.warn(
11052
+ "Could not get canonical model for default summarizer:",
11053
+ error
11054
+ );
11055
+ return void 0;
11056
+ }
11057
+ }
11058
+ return void 0;
11059
+ }
11060
+ async rewind(args) {
11061
+ const { userId, sessionId, rewindBeforeInvocationId } = args;
11062
+ const session = await this.sessionService.getSession(
11063
+ this.appName,
11064
+ userId,
11065
+ sessionId
11066
+ );
11067
+ if (!session) {
11068
+ throw new Error(`Session not found: ${sessionId}`);
11069
+ }
11070
+ let rewindEventIndex = -1;
11071
+ for (let i = 0; i < session.events.length; i++) {
11072
+ if (session.events[i].invocationId === rewindBeforeInvocationId) {
11073
+ rewindEventIndex = i;
11074
+ break;
11075
+ }
11076
+ }
11077
+ if (rewindEventIndex === -1) {
11078
+ throw new Error(`Invocation ID not found: ${rewindBeforeInvocationId}`);
11079
+ }
11080
+ const stateDelta = await this._computeStateDeltaForRewind(
11081
+ session,
11082
+ rewindEventIndex
11083
+ );
11084
+ const artifactDelta = await this._computeArtifactDeltaForRewind(
11085
+ session,
11086
+ rewindEventIndex
11087
+ );
11088
+ const rewindEvent = new Event({
11089
+ invocationId: newInvocationContextId(),
11090
+ author: "user",
11091
+ actions: new EventActions({
11092
+ rewindBeforeInvocationId,
11093
+ stateDelta,
11094
+ artifactDelta
11095
+ })
11096
+ });
11097
+ this.logger.info(
11098
+ "Rewinding session to invocation:",
11099
+ rewindBeforeInvocationId
11100
+ );
11101
+ await this.sessionService.appendEvent(session, rewindEvent);
11102
+ }
11103
+ async _computeStateDeltaForRewind(session, rewindEventIndex) {
11104
+ const stateAtRewindPoint = {};
11105
+ for (let i = 0; i < rewindEventIndex; i++) {
11106
+ const event = session.events[i];
11107
+ if (event.actions?.stateDelta) {
11108
+ for (const [k, v] of Object.entries(event.actions.stateDelta)) {
11109
+ if (k.startsWith("app:") || k.startsWith("user:")) {
11110
+ continue;
11111
+ }
11112
+ if (v === null || v === void 0) {
11113
+ delete stateAtRewindPoint[k];
11114
+ } else {
11115
+ stateAtRewindPoint[k] = v;
11116
+ }
11117
+ }
11118
+ }
11119
+ }
11120
+ const currentState = session.state;
11121
+ const rewindStateDelta = {};
11122
+ for (const [key, valueAtRewind] of Object.entries(stateAtRewindPoint)) {
11123
+ if (!(key in currentState) || currentState[key] !== valueAtRewind) {
11124
+ rewindStateDelta[key] = valueAtRewind;
11125
+ }
11126
+ }
11127
+ for (const key of Object.keys(currentState)) {
11128
+ if (key.startsWith("app:") || key.startsWith("user:")) {
11129
+ continue;
11130
+ }
11131
+ if (!(key in stateAtRewindPoint)) {
11132
+ rewindStateDelta[key] = null;
11133
+ }
11134
+ }
11135
+ return rewindStateDelta;
11136
+ }
11137
+ async _computeArtifactDeltaForRewind(session, rewindEventIndex) {
11138
+ if (!this.artifactService) {
11139
+ return {};
11140
+ }
11141
+ const versionsAtRewindPoint = {};
11142
+ for (let i = 0; i < rewindEventIndex; i++) {
11143
+ const event = session.events[i];
11144
+ if (event.actions?.artifactDelta) {
11145
+ Object.assign(versionsAtRewindPoint, event.actions.artifactDelta);
11146
+ }
11147
+ }
11148
+ const currentVersions = {};
11149
+ for (const event of session.events) {
11150
+ if (event.actions?.artifactDelta) {
11151
+ Object.assign(currentVersions, event.actions.artifactDelta);
11152
+ }
11153
+ }
11154
+ const rewindArtifactDelta = {};
11155
+ for (const [filename, vn] of Object.entries(currentVersions)) {
11156
+ if (filename.startsWith("user:")) {
11157
+ continue;
11158
+ }
11159
+ const vt = versionsAtRewindPoint[filename];
11160
+ if (vt === vn) {
11161
+ continue;
11162
+ }
11163
+ let artifact;
11164
+ if (vt === void 0 || vt === null) {
11165
+ artifact = {
11166
+ inlineData: {
11167
+ mimeType: "application/octet-stream",
11168
+ data: ""
11169
+ }
11170
+ };
11171
+ } else {
11172
+ const artifactUri = getArtifactUri({
11173
+ appName: this.appName,
11174
+ userId: session.userId,
11175
+ sessionId: session.id,
11176
+ filename,
11177
+ version: vt
11178
+ });
11179
+ artifact = {
11180
+ fileData: {
11181
+ fileUri: artifactUri
11182
+ }
11183
+ };
11184
+ }
11185
+ const newVersion = await this.artifactService.saveArtifact({
11186
+ appName: this.appName,
11187
+ userId: session.userId,
11188
+ sessionId: session.id,
11189
+ filename,
11190
+ artifact
11191
+ });
11192
+ rewindArtifactDelta[filename] = newVersion;
11193
+ }
11194
+ return rewindArtifactDelta;
11195
+ }
10696
11196
  };
10697
11197
  var InMemoryRunner = class extends Runner {
10698
11198
  /**
@@ -10722,6 +11222,7 @@ var AgentBuilder = class _AgentBuilder {
10722
11222
  sessionOptions;
10723
11223
  memoryService;
10724
11224
  artifactService;
11225
+ eventsCompactionConfig;
10725
11226
  agentType = "llm";
10726
11227
  existingSession;
10727
11228
  existingAgent;
@@ -10935,6 +11436,14 @@ var AgentBuilder = class _AgentBuilder {
10935
11436
  this.config.afterToolCallback = callback;
10936
11437
  return this;
10937
11438
  }
11439
+ /**
11440
+ * Convenience method to start building with an existing agent
11441
+ * @param agent The agent instance to wrap
11442
+ * @returns New AgentBuilder instance with agent set
11443
+ */
11444
+ static withAgent(agent) {
11445
+ return new _AgentBuilder(agent.name || "default_agent").withAgent(agent);
11446
+ }
10938
11447
  /**
10939
11448
  * Provide an already constructed agent instance. Further definition-mutating calls
10940
11449
  * (model/tools/instruction/etc.) will be ignored with a dev warning.
@@ -11116,6 +11625,26 @@ var AgentBuilder = class _AgentBuilder {
11116
11625
  this.runConfig = config instanceof RunConfig ? config : new RunConfig({ ...this.runConfig || {}, ...config });
11117
11626
  return this;
11118
11627
  }
11628
+ /**
11629
+ * Configure event compaction for automatic history management
11630
+ * @param config Event compaction configuration
11631
+ * @returns This builder instance for chaining
11632
+ * @example
11633
+ * ```typescript
11634
+ * const { runner } = await AgentBuilder
11635
+ * .create("assistant")
11636
+ * .withModel("gemini-2.5-flash")
11637
+ * .withEventsCompaction({
11638
+ * compactionInterval: 10, // Compact every 10 invocations
11639
+ * overlapSize: 2, // Include 2 prior invocations
11640
+ * })
11641
+ * .build();
11642
+ * ```
11643
+ */
11644
+ withEventsCompaction(config) {
11645
+ this.eventsCompactionConfig = config;
11646
+ return this;
11647
+ }
11119
11648
  /**
11120
11649
  * Configure with an in-memory session with custom IDs
11121
11650
  * Note: In-memory sessions are created automatically by default, use this only if you need custom appName/userId
@@ -11152,7 +11681,8 @@ var AgentBuilder = class _AgentBuilder {
11152
11681
  agent,
11153
11682
  sessionService: this.sessionService,
11154
11683
  memoryService: this.memoryService,
11155
- artifactService: this.artifactService
11684
+ artifactService: this.artifactService,
11685
+ eventsCompactionConfig: this.eventsCompactionConfig
11156
11686
  };
11157
11687
  const baseRunner = new Runner(runnerConfig);
11158
11688
  runner = this.createEnhancedRunner(baseRunner, session);
@@ -11366,6 +11896,9 @@ var AgentBuilder = class _AgentBuilder {
11366
11896
  ...params,
11367
11897
  runConfig: params.runConfig ?? runConfig
11368
11898
  });
11899
+ },
11900
+ rewind(params) {
11901
+ return baseRunner.rewind(params);
11369
11902
  }
11370
11903
  };
11371
11904
  }
@@ -13883,6 +14416,7 @@ export {
13883
14416
  LangGraphAgent,
13884
14417
  LlmAgent,
13885
14418
  LlmCallsLimitExceededError,
14419
+ LlmEventSummarizer,
13886
14420
  LlmRequest,
13887
14421
  LlmResponse,
13888
14422
  LoadArtifactsTool,
@@ -13958,6 +14492,7 @@ export {
13958
14492
  createTool,
13959
14493
  generateAuthEvent,
13960
14494
  generateClientFunctionCallId,
14495
+ getArtifactUri,
13961
14496
  getLongRunningFunctionCalls,
13962
14497
  getMcpTools,
13963
14498
  handleFunctionCallsAsync,
@@ -13966,6 +14501,7 @@ export {
13966
14501
  initializeTelemetry,
13967
14502
  injectSessionState,
13968
14503
  requestProcessor6 as instructionsRequestProcessor,
14504
+ isArtifactRef,
13969
14505
  isEnhancedAuthConfig,
13970
14506
  jsonSchemaToDeclaration,
13971
14507
  mcpSchemaToParameters,
@@ -13975,10 +14511,12 @@ export {
13975
14511
  requestProcessor7 as nlPlanningRequestProcessor,
13976
14512
  responseProcessor2 as nlPlanningResponseProcessor,
13977
14513
  normalizeJsonSchema,
14514
+ parseArtifactUri,
13978
14515
  populateClientFunctionCallId,
13979
14516
  registerProviders,
13980
14517
  removeClientFunctionCallId,
13981
14518
  requestProcessor,
14519
+ runCompactionForSlidingWindow,
13982
14520
  shutdownTelemetry,
13983
14521
  telemetryService,
13984
14522
  traceLlmCall,