@google/adk 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/a2a/a2a_remote_agent.js +12 -2
- package/dist/cjs/a2a/agent_to_a2a.js +0 -1
- package/dist/cjs/a2a/auth.js +65 -0
- package/dist/cjs/a2a/event_converter_utils.js +40 -15
- package/dist/cjs/agents/functions.js +20 -7
- package/dist/cjs/agents/llm_agent.js +2 -1
- package/dist/cjs/agents/processors/basic_llm_request_processor.js +3 -2
- package/dist/cjs/agents/processors/content_request_processor.js +2 -21
- package/dist/cjs/agents/processors/instructions_llm_request_processor.js +3 -1
- package/dist/cjs/artifacts/in_memory_artifact_service.js +10 -9
- package/dist/cjs/auth/credential_service/in_memory_credential_service.js +14 -3
- package/dist/cjs/code_executors/unsafe_local_code_executor.js +23 -12
- package/dist/cjs/common.js +6 -0
- package/dist/cjs/context/agent_controlled_context_compactor.js +2 -11
- package/dist/cjs/context/compaction_utils.js +14 -2
- package/dist/cjs/context/token_based_context_compactor.js +2 -20
- package/dist/cjs/index.js +3 -0
- package/dist/cjs/memory/in_memory_memory_service.js +13 -2
- package/dist/cjs/memory/vertex_ai_memory_bank_service.js +3 -0
- package/dist/cjs/plugins/base_plugin.js +4 -2
- package/dist/cjs/runner/runner.js +18 -11
- package/dist/cjs/sessions/base_session_service.js +8 -3
- package/dist/cjs/sessions/in_memory_session_service.js +8 -8
- package/dist/cjs/sessions/vertex_ai_session_service.js +22 -10
- package/dist/cjs/skills/loader.js +40 -6
- package/dist/cjs/tools/get_user_choice_tool.js +53 -0
- package/dist/cjs/tools/mcp/mcp_session_manager.js +35 -21
- package/dist/cjs/tools/request_input_tool.js +54 -0
- package/dist/cjs/utils/crypto_shim.js +43 -0
- package/dist/cjs/utils/env_aware_utils.js +15 -13
- package/dist/cjs/utils/error_utils.js +120 -0
- package/dist/cjs/utils/file_utils.js +5 -2
- package/dist/cjs/utils/output_schema_utils.js +43 -0
- package/dist/cjs/utils/vertex_ai_utils.js +3 -0
- package/dist/cjs/version.js +1 -1
- package/dist/esm/a2a/a2a_remote_agent.js +12 -2
- package/dist/esm/a2a/agent_to_a2a.js +0 -1
- package/dist/esm/a2a/auth.js +37 -0
- package/dist/esm/a2a/event_converter_utils.js +40 -15
- package/dist/esm/agents/functions.js +20 -7
- package/dist/esm/agents/llm_agent.js +2 -1
- package/dist/esm/agents/processors/basic_llm_request_processor.js +3 -2
- package/dist/esm/agents/processors/content_request_processor.js +2 -21
- package/dist/esm/agents/processors/instructions_llm_request_processor.js +3 -1
- package/dist/esm/artifacts/in_memory_artifact_service.js +10 -9
- package/dist/esm/auth/credential_service/in_memory_credential_service.js +14 -3
- package/dist/esm/code_executors/unsafe_local_code_executor.js +22 -11
- package/dist/esm/common.js +4 -0
- package/dist/esm/context/agent_controlled_context_compactor.js +2 -11
- package/dist/esm/context/compaction_utils.js +12 -1
- package/dist/esm/context/token_based_context_compactor.js +6 -21
- package/dist/esm/index.js +2 -0
- package/dist/esm/memory/in_memory_memory_service.js +13 -2
- package/dist/esm/memory/vertex_ai_memory_bank_service.js +7 -1
- package/dist/esm/plugins/base_plugin.js +4 -2
- package/dist/esm/runner/runner.js +18 -11
- package/dist/esm/sessions/base_session_service.js +8 -3
- package/dist/esm/sessions/in_memory_session_service.js +8 -8
- package/dist/esm/sessions/vertex_ai_session_service.js +26 -11
- package/dist/esm/skills/loader.js +40 -6
- package/dist/esm/tools/get_user_choice_tool.js +25 -0
- package/dist/esm/tools/mcp/mcp_session_manager.js +35 -21
- package/dist/esm/tools/request_input_tool.js +26 -0
- package/dist/esm/utils/crypto_shim.js +15 -0
- package/dist/esm/utils/env_aware_utils.js +15 -13
- package/dist/esm/utils/error_utils.js +92 -0
- package/dist/esm/utils/file_utils.js +5 -2
- package/dist/esm/utils/output_schema_utils.js +15 -0
- package/dist/esm/utils/vertex_ai_utils.js +2 -0
- package/dist/esm/version.js +1 -1
- package/dist/types/a2a/auth.d.ts +30 -0
- package/dist/types/a2a/event_converter_utils.d.ts +4 -1
- package/dist/types/auth/credential_service/in_memory_credential_service.d.ts +11 -0
- package/dist/types/code_executors/unsafe_local_code_executor.d.ts +5 -1
- package/dist/types/common.d.ts +2 -0
- package/dist/types/context/agent_controlled_context_compactor.d.ts +0 -1
- package/dist/types/context/compaction_utils.d.ts +8 -0
- package/dist/types/context/token_based_context_compactor.d.ts +0 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/memory/in_memory_memory_service.d.ts +11 -0
- package/dist/types/plugins/base_plugin.d.ts +4 -2
- package/dist/types/sessions/base_session_service.d.ts +8 -0
- package/dist/types/sessions/in_memory_session_service.d.ts +9 -0
- package/dist/types/sessions/vertex_ai_session_service.d.ts +19 -1
- package/dist/types/skills/loader.d.ts +5 -0
- package/dist/types/tools/get_user_choice_tool.d.ts +14 -0
- package/dist/types/tools/request_input_tool.d.ts +15 -0
- package/dist/types/utils/crypto_shim.d.ts +16 -0
- package/dist/types/utils/env_aware_utils.d.ts +23 -0
- package/dist/types/utils/error_utils.d.ts +18 -0
- package/dist/types/utils/output_schema_utils.d.ts +18 -0
- package/dist/types/utils/vertex_ai_utils.d.ts +1 -0
- package/dist/types/version.d.ts +1 -1
- package/dist/web/a2a/a2a_remote_agent.js +12 -2
- package/dist/web/a2a/agent_to_a2a.js +0 -1
- package/dist/web/a2a/auth.js +37 -0
- package/dist/web/a2a/event_converter_utils.js +40 -15
- package/dist/web/agents/functions.js +20 -7
- package/dist/web/agents/llm_agent.js +2 -1
- package/dist/web/agents/processors/basic_llm_request_processor.js +3 -2
- package/dist/web/agents/processors/content_request_processor.js +2 -21
- package/dist/web/agents/processors/instructions_llm_request_processor.js +3 -1
- package/dist/web/artifacts/in_memory_artifact_service.js +10 -9
- package/dist/web/auth/credential_service/in_memory_credential_service.js +14 -3
- package/dist/web/code_executors/unsafe_local_code_executor.js +22 -11
- package/dist/web/common.js +4 -0
- package/dist/web/context/agent_controlled_context_compactor.js +2 -11
- package/dist/web/context/compaction_utils.js +12 -1
- package/dist/web/context/token_based_context_compactor.js +6 -21
- package/dist/web/index.js +2 -0
- package/dist/web/memory/in_memory_memory_service.js +13 -2
- package/dist/web/memory/vertex_ai_memory_bank_service.js +7 -1
- package/dist/web/plugins/base_plugin.js +4 -2
- package/dist/web/runner/runner.js +17 -11
- package/dist/web/sessions/base_session_service.js +8 -3
- package/dist/web/sessions/in_memory_session_service.js +8 -8
- package/dist/web/sessions/vertex_ai_session_service.js +24 -11
- package/dist/web/skills/loader.js +40 -6
- package/dist/web/tools/get_user_choice_tool.js +25 -0
- package/dist/web/tools/mcp/mcp_session_manager.js +35 -21
- package/dist/web/tools/request_input_tool.js +26 -0
- package/dist/web/utils/crypto_shim.js +15 -0
- package/dist/web/utils/env_aware_utils.js +15 -13
- package/dist/web/utils/error_utils.js +92 -0
- package/dist/web/utils/file_utils.js +5 -2
- package/dist/web/utils/output_schema_utils.js +15 -0
- package/dist/web/utils/vertex_ai_utils.js +2 -0
- package/dist/web/version.js +1 -1
- package/package.json +1 -1
|
@@ -5,9 +5,9 @@ const require = topLevelCreateRequire(import.meta.url);
|
|
|
5
5
|
* Copyright 2026 Google LLC
|
|
6
6
|
* SPDX-License-Identifier: Apache-2.0
|
|
7
7
|
*/
|
|
8
|
-
import { isCompactedEvent } from "../events/compacted_event.js";
|
|
9
8
|
import { createEvent } from "../events/event.js";
|
|
10
9
|
import { ContextCompactionTrigger } from "../plugins/base_plugin.js";
|
|
10
|
+
import { getActiveEvents } from "./compaction_utils.js";
|
|
11
11
|
class AgentControlledContextCompactor {
|
|
12
12
|
constructor(options) {
|
|
13
13
|
this.trigger = ContextCompactionTrigger.AgentControlled;
|
|
@@ -18,7 +18,7 @@ class AgentControlledContextCompactor {
|
|
|
18
18
|
}
|
|
19
19
|
async compact(invocationContext) {
|
|
20
20
|
const events = invocationContext.session.events;
|
|
21
|
-
const activeEvents =
|
|
21
|
+
const activeEvents = getActiveEvents(events);
|
|
22
22
|
const consolidateToolCallIndex = activeEvents.reduce(
|
|
23
23
|
(acc, e, idx) => {
|
|
24
24
|
var _a, _b;
|
|
@@ -66,15 +66,6 @@ class AgentControlledContextCompactor {
|
|
|
66
66
|
delete invocationContext.session.state["temp:consolidate_context"];
|
|
67
67
|
delete invocationContext.session.state["temp:consolidate_context_detail"];
|
|
68
68
|
}
|
|
69
|
-
getActiveEvents(events) {
|
|
70
|
-
const latest = events.filter(isCompactedEvent).pop();
|
|
71
|
-
return latest ? [
|
|
72
|
-
latest,
|
|
73
|
-
...events.filter(
|
|
74
|
-
(e) => !isCompactedEvent(e) && e.timestamp > latest.endTime
|
|
75
|
-
)
|
|
76
|
-
] : events;
|
|
77
|
-
}
|
|
78
69
|
}
|
|
79
70
|
export {
|
|
80
71
|
AgentControlledContextCompactor
|
|
@@ -5,10 +5,20 @@ const require = topLevelCreateRequire(import.meta.url);
|
|
|
5
5
|
* Copyright 2026 Google LLC
|
|
6
6
|
* SPDX-License-Identifier: Apache-2.0
|
|
7
7
|
*/
|
|
8
|
+
import { isCompactedEvent } from "../events/compacted_event.js";
|
|
8
9
|
import {
|
|
9
10
|
getFunctionCalls,
|
|
10
11
|
getFunctionResponses
|
|
11
12
|
} from "../events/event.js";
|
|
13
|
+
function getActiveEvents(events) {
|
|
14
|
+
const latest = events.filter(isCompactedEvent).pop();
|
|
15
|
+
return latest ? [
|
|
16
|
+
latest,
|
|
17
|
+
...events.filter(
|
|
18
|
+
(e) => !isCompactedEvent(e) && e.timestamp > latest.endTime
|
|
19
|
+
)
|
|
20
|
+
] : events;
|
|
21
|
+
}
|
|
12
22
|
function calculateRetainStartIndex(rawEvents, eventRetentionSize) {
|
|
13
23
|
let retainStartIndex = Math.max(0, rawEvents.length - eventRetentionSize);
|
|
14
24
|
while (retainStartIndex > 0) {
|
|
@@ -23,5 +33,6 @@ function calculateRetainStartIndex(rawEvents, eventRetentionSize) {
|
|
|
23
33
|
return retainStartIndex;
|
|
24
34
|
}
|
|
25
35
|
export {
|
|
26
|
-
calculateRetainStartIndex
|
|
36
|
+
calculateRetainStartIndex,
|
|
37
|
+
getActiveEvents
|
|
27
38
|
};
|
|
@@ -7,7 +7,10 @@ const require = topLevelCreateRequire(import.meta.url);
|
|
|
7
7
|
*/
|
|
8
8
|
import { getContents } from "../agents/processors/content_processor_utils.js";
|
|
9
9
|
import { isCompactedEvent } from "../events/compacted_event.js";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
calculateRetainStartIndex,
|
|
12
|
+
getActiveEvents
|
|
13
|
+
} from "./compaction_utils.js";
|
|
11
14
|
const CHARS_PER_TOKEN = 4;
|
|
12
15
|
class TokenBasedContextCompactor {
|
|
13
16
|
constructor(options) {
|
|
@@ -15,27 +18,9 @@ class TokenBasedContextCompactor {
|
|
|
15
18
|
this.eventRetentionSize = options.eventRetentionSize;
|
|
16
19
|
this.summarizer = options.summarizer;
|
|
17
20
|
}
|
|
18
|
-
getActiveEvents(events) {
|
|
19
|
-
let latestCompactedEvent = void 0;
|
|
20
|
-
for (let i = events.length - 1; i >= 0; i--) {
|
|
21
|
-
const e = events[i];
|
|
22
|
-
if (isCompactedEvent(e)) {
|
|
23
|
-
if (!latestCompactedEvent || e.endTime > latestCompactedEvent.endTime) {
|
|
24
|
-
latestCompactedEvent = e;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (!latestCompactedEvent) {
|
|
29
|
-
return events;
|
|
30
|
-
}
|
|
31
|
-
const activeRawEvents = events.filter(
|
|
32
|
-
(e) => !isCompactedEvent(e) && e.timestamp > latestCompactedEvent.endTime
|
|
33
|
-
);
|
|
34
|
-
return [latestCompactedEvent, ...activeRawEvents];
|
|
35
|
-
}
|
|
36
21
|
shouldCompact(invocationContext) {
|
|
37
22
|
const events = invocationContext.session.events;
|
|
38
|
-
const activeEvents =
|
|
23
|
+
const activeEvents = getActiveEvents(events);
|
|
39
24
|
const rawEvents = activeEvents.filter((e) => !isCompactedEvent(e));
|
|
40
25
|
if (rawEvents.length <= this.eventRetentionSize) {
|
|
41
26
|
return false;
|
|
@@ -58,7 +43,7 @@ class TokenBasedContextCompactor {
|
|
|
58
43
|
}
|
|
59
44
|
async compact(invocationContext) {
|
|
60
45
|
const events = invocationContext.session.events;
|
|
61
|
-
const activeEvents =
|
|
46
|
+
const activeEvents = getActiveEvents(events);
|
|
62
47
|
const rawEvents = activeEvents.filter((e) => !isCompactedEvent(e));
|
|
63
48
|
if (rawEvents.length <= this.eventRetentionSize) {
|
|
64
49
|
return;
|
package/dist/web/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { AGENT_CARD_PATH, RemoteA2AAgent } from "./a2a/a2a_remote_agent.js";
|
|
|
9
9
|
import { getA2AAgentCard } from "./a2a/agent_card.js";
|
|
10
10
|
import { A2AAgentExecutor } from "./a2a/agent_executor.js";
|
|
11
11
|
import { toA2a } from "./a2a/agent_to_a2a.js";
|
|
12
|
+
import { bearerTokenUserBuilder } from "./a2a/auth.js";
|
|
12
13
|
import { InvocationContext } from "./agents/invocation_context.js";
|
|
13
14
|
import { FileArtifactService } from "./artifacts/file_artifact_service.js";
|
|
14
15
|
import { GcsArtifactService } from "./artifacts/gcs_artifact_service.js";
|
|
@@ -56,6 +57,7 @@ export {
|
|
|
56
57
|
RunSkillScriptTool,
|
|
57
58
|
UnsafeLocalCodeExecutor,
|
|
58
59
|
VertexAiSessionService,
|
|
60
|
+
bearerTokenUserBuilder,
|
|
59
61
|
getA2AAgentCard,
|
|
60
62
|
getArtifactServiceFromUri,
|
|
61
63
|
getSessionServiceFromUri,
|
|
@@ -8,12 +8,23 @@ const require = topLevelCreateRequire(import.meta.url);
|
|
|
8
8
|
class InMemoryMemoryService {
|
|
9
9
|
constructor() {
|
|
10
10
|
this.memories = [];
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* A map from user key to a map from session ID to events.
|
|
13
|
+
*
|
|
14
|
+
* The inner map is keyed by `session.id`, which arrives off the request path
|
|
15
|
+
* and contains no `/`, so it can be exactly `__proto__`. On a plain object
|
|
16
|
+
* literal that key would reach the inherited `__proto__` setter and
|
|
17
|
+
* re-parent the map instead of creating an own property, silently dropping
|
|
18
|
+
* the session from the `Object.values` scan in `searchMemory`. The outer key
|
|
19
|
+
* always contains a `/` (see `getUserKey`) and cannot collide, but is
|
|
20
|
+
* created the same way for consistency.
|
|
21
|
+
*/
|
|
22
|
+
this.sessionEvents = /* @__PURE__ */ Object.create(null);
|
|
12
23
|
}
|
|
13
24
|
async addSessionToMemory(session) {
|
|
14
25
|
const userKey = getUserKey(session.appName, session.userId);
|
|
15
26
|
if (!this.sessionEvents[userKey]) {
|
|
16
|
-
this.sessionEvents[userKey] =
|
|
27
|
+
this.sessionEvents[userKey] = /* @__PURE__ */ Object.create(null);
|
|
17
28
|
}
|
|
18
29
|
this.sessionEvents[userKey][session.id] = session.events.filter(
|
|
19
30
|
(event) => {
|
|
@@ -24,7 +24,10 @@ var __spreadValues = (a, b) => {
|
|
|
24
24
|
import { Client } from "@google-cloud/vertexai";
|
|
25
25
|
import { createUserContent } from "@google/genai";
|
|
26
26
|
import { logger } from "../utils/logger.js";
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
EXPRESS_MODE_UNSUPPORTED_MESSAGE,
|
|
29
|
+
getExpressModeApiKey
|
|
30
|
+
} from "../utils/vertex_ai_utils.js";
|
|
28
31
|
const GENERATE_MEMORIES_KNOWN_FIELDS = [
|
|
29
32
|
"disableConsolidation",
|
|
30
33
|
"waitForCompletion",
|
|
@@ -105,6 +108,9 @@ class VertexAiMemoryBankService {
|
|
|
105
108
|
if (options.client) {
|
|
106
109
|
this.memories = options.client.agentEnginesInternal.memories;
|
|
107
110
|
} else {
|
|
111
|
+
if (this.expressModeApiKey && (!this.projectId || !this.location)) {
|
|
112
|
+
throw new Error(EXPRESS_MODE_UNSUPPORTED_MESSAGE);
|
|
113
|
+
}
|
|
108
114
|
const client = new Client({
|
|
109
115
|
project: this.projectId,
|
|
110
116
|
location: this.location
|
|
@@ -73,8 +73,10 @@ class BasePlugin {
|
|
|
73
73
|
* @param params.invocationContext The context for the entire invocation.
|
|
74
74
|
* @param params.event The event raised by the runner.
|
|
75
75
|
* @returns An optional value. A non-`undefined` return may be used by the
|
|
76
|
-
* framework to modify or replace the response.
|
|
77
|
-
*
|
|
76
|
+
* framework to modify or replace the response. Copy `params.event` when
|
|
77
|
+
* constructing a replacement to preserve fields that are not being
|
|
78
|
+
* modified, such as event actions. Returning `undefined` allows the
|
|
79
|
+
* original response to be used.
|
|
78
80
|
*/
|
|
79
81
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
80
82
|
async onEventCallback(params) {
|
|
@@ -191,7 +191,7 @@ class Runner {
|
|
|
191
191
|
this,
|
|
192
192
|
function() {
|
|
193
193
|
return __asyncGenerator(this, null, function* () {
|
|
194
|
-
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
194
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
195
195
|
const session = yield new __await(this.sessionService.getSession({
|
|
196
196
|
appName: this.appName,
|
|
197
197
|
userId,
|
|
@@ -310,21 +310,27 @@ class Runner {
|
|
|
310
310
|
if ((_h = params.abortSignal) == null ? void 0 : _h.aborted) {
|
|
311
311
|
return;
|
|
312
312
|
}
|
|
313
|
-
if (!event.partial) {
|
|
314
|
-
yield new __await(this.sessionService.appendEvent({ session, event }));
|
|
315
|
-
}
|
|
316
313
|
const modifiedEvent = yield new __await(this.pluginManager.runOnEventCallback({
|
|
317
314
|
invocationContext,
|
|
318
315
|
event
|
|
319
316
|
}));
|
|
320
|
-
|
|
321
|
-
|
|
317
|
+
const outputEvent = modifiedEvent ? __spreadProps(__spreadValues({}, modifiedEvent), {
|
|
318
|
+
id: event.id,
|
|
319
|
+
invocationId: event.invocationId,
|
|
320
|
+
timestamp: event.timestamp,
|
|
321
|
+
author: modifiedEvent.author || event.author,
|
|
322
|
+
branch: (_i = modifiedEvent.branch) != null ? _i : event.branch
|
|
323
|
+
}) : event;
|
|
324
|
+
if (!event.partial) {
|
|
325
|
+
yield new __await(this.sessionService.appendEvent({
|
|
326
|
+
session,
|
|
327
|
+
event: outputEvent
|
|
328
|
+
}));
|
|
322
329
|
}
|
|
323
|
-
if (
|
|
324
|
-
|
|
325
|
-
} else {
|
|
326
|
-
yield event;
|
|
330
|
+
if ((_j = params.abortSignal) == null ? void 0 : _j.aborted) {
|
|
331
|
+
return;
|
|
327
332
|
}
|
|
333
|
+
yield outputEvent;
|
|
328
334
|
}
|
|
329
335
|
} catch (temp) {
|
|
330
336
|
error = [temp];
|
|
@@ -337,7 +343,7 @@ class Runner {
|
|
|
337
343
|
}
|
|
338
344
|
}
|
|
339
345
|
yield new __await(this.pluginManager.runAfterRunCallback({ invocationContext }));
|
|
340
|
-
if ((
|
|
346
|
+
if ((_k = params.abortSignal) == null ? void 0 : _k.aborted) {
|
|
341
347
|
return;
|
|
342
348
|
}
|
|
343
349
|
}
|
|
@@ -61,7 +61,12 @@ class BaseSessionService {
|
|
|
61
61
|
if (key.startsWith(State.TEMP_PREFIX)) {
|
|
62
62
|
continue;
|
|
63
63
|
}
|
|
64
|
-
session.state
|
|
64
|
+
Object.defineProperty(session.state, key, {
|
|
65
|
+
value,
|
|
66
|
+
writable: true,
|
|
67
|
+
enumerable: true,
|
|
68
|
+
configurable: true
|
|
69
|
+
});
|
|
65
70
|
}
|
|
66
71
|
}
|
|
67
72
|
}
|
|
@@ -70,7 +75,7 @@ function trimTempDeltaState(event) {
|
|
|
70
75
|
return event;
|
|
71
76
|
}
|
|
72
77
|
const stateDelta = event.actions.stateDelta;
|
|
73
|
-
const filteredStateDelta =
|
|
78
|
+
const filteredStateDelta = /* @__PURE__ */ Object.create(null);
|
|
74
79
|
for (const [key, value] of Object.entries(stateDelta)) {
|
|
75
80
|
if (!key.startsWith(State.TEMP_PREFIX)) {
|
|
76
81
|
filteredStateDelta[key] = value;
|
|
@@ -80,7 +85,7 @@ function trimTempDeltaState(event) {
|
|
|
80
85
|
return event;
|
|
81
86
|
}
|
|
82
87
|
function trimTempState(state) {
|
|
83
|
-
const filteredState =
|
|
88
|
+
const filteredState = /* @__PURE__ */ Object.create(null);
|
|
84
89
|
for (const [key, value] of Object.entries(state)) {
|
|
85
90
|
if (!key.startsWith(State.TEMP_PREFIX)) {
|
|
86
91
|
filteredState[key] = value;
|
|
@@ -25,15 +25,15 @@ class InMemorySessionService extends BaseSessionService {
|
|
|
25
25
|
* A map from app name to a map from user ID to a map from session ID to
|
|
26
26
|
* session.
|
|
27
27
|
*/
|
|
28
|
-
this.sessions =
|
|
28
|
+
this.sessions = /* @__PURE__ */ Object.create(null);
|
|
29
29
|
/**
|
|
30
30
|
* A map from app name to a map from user ID to a map from key to the value.
|
|
31
31
|
*/
|
|
32
|
-
this.userState =
|
|
32
|
+
this.userState = /* @__PURE__ */ Object.create(null);
|
|
33
33
|
/**
|
|
34
34
|
* A map from app name to a map from key to the value.
|
|
35
35
|
*/
|
|
36
|
-
this.appState =
|
|
36
|
+
this.appState = /* @__PURE__ */ Object.create(null);
|
|
37
37
|
}
|
|
38
38
|
async createSession({
|
|
39
39
|
appName,
|
|
@@ -52,10 +52,10 @@ class InMemorySessionService extends BaseSessionService {
|
|
|
52
52
|
lastUpdateTime: Date.now()
|
|
53
53
|
});
|
|
54
54
|
if (!this.sessions[appName]) {
|
|
55
|
-
this.sessions[appName] =
|
|
55
|
+
this.sessions[appName] = /* @__PURE__ */ Object.create(null);
|
|
56
56
|
}
|
|
57
57
|
if (!this.sessions[appName][userId]) {
|
|
58
|
-
this.sessions[appName][userId] =
|
|
58
|
+
this.sessions[appName][userId] = /* @__PURE__ */ Object.create(null);
|
|
59
59
|
}
|
|
60
60
|
this.sessions[appName][userId][session.id] = session;
|
|
61
61
|
const copiedSession = cloneDeep(session);
|
|
@@ -220,12 +220,12 @@ class InMemorySessionService extends BaseSessionService {
|
|
|
220
220
|
if (event.actions && event.actions.stateDelta) {
|
|
221
221
|
for (const key of Object.keys(event.actions.stateDelta)) {
|
|
222
222
|
if (key.startsWith(State.APP_PREFIX)) {
|
|
223
|
-
this.appState[appName] = this.appState[appName] ||
|
|
223
|
+
this.appState[appName] = this.appState[appName] || /* @__PURE__ */ Object.create(null);
|
|
224
224
|
this.appState[appName][key.replace(State.APP_PREFIX, "")] = event.actions.stateDelta[key];
|
|
225
225
|
}
|
|
226
226
|
if (key.startsWith(State.USER_PREFIX)) {
|
|
227
|
-
this.userState[appName] = this.userState[appName] ||
|
|
228
|
-
this.userState[appName][userId] = this.userState[appName][userId] ||
|
|
227
|
+
this.userState[appName] = this.userState[appName] || /* @__PURE__ */ Object.create(null);
|
|
228
|
+
this.userState[appName][userId] = this.userState[appName][userId] || /* @__PURE__ */ Object.create(null);
|
|
229
229
|
this.userState[appName][userId][key.replace(State.USER_PREFIX, "")] = event.actions.stateDelta[key];
|
|
230
230
|
}
|
|
231
231
|
}
|
|
@@ -37,7 +37,10 @@ import { Client } from "@google-cloud/vertexai/build/src/genai/client.js";
|
|
|
37
37
|
import { isCompactedEvent } from "../events/compacted_event.js";
|
|
38
38
|
import { experimental } from "../utils/experimental.js";
|
|
39
39
|
import { logger } from "../utils/logger.js";
|
|
40
|
-
import {
|
|
40
|
+
import {
|
|
41
|
+
EXPRESS_MODE_UNSUPPORTED_MESSAGE,
|
|
42
|
+
getExpressModeApiKey
|
|
43
|
+
} from "../utils/vertex_ai_utils.js";
|
|
41
44
|
import { partialCopy } from "../utils/partial_copy.js";
|
|
42
45
|
import {
|
|
43
46
|
BaseSessionService,
|
|
@@ -65,16 +68,14 @@ let VertexAiSessionService = class extends BaseSessionService {
|
|
|
65
68
|
this.location,
|
|
66
69
|
options.expressModeApiKey
|
|
67
70
|
);
|
|
68
|
-
if (!options.sessions) {
|
|
69
|
-
if (!this.expressModeApiKey && (!this.projectId || !this.location)) {
|
|
70
|
-
throw new Error(
|
|
71
|
-
"Either (Project ID and Location) or an expressModeApiKey is required."
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
71
|
if (options.sessions) {
|
|
76
72
|
this.sessions = options.sessions;
|
|
77
73
|
} else {
|
|
74
|
+
if (!this.projectId || !this.location) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
this.expressModeApiKey ? EXPRESS_MODE_UNSUPPORTED_MESSAGE : "Project ID and Location are required."
|
|
77
|
+
);
|
|
78
|
+
}
|
|
78
79
|
const client = new Client({
|
|
79
80
|
project: this.projectId,
|
|
80
81
|
location: this.location
|
|
@@ -98,19 +99,31 @@ let VertexAiSessionService = class extends BaseSessionService {
|
|
|
98
99
|
}
|
|
99
100
|
return match[3];
|
|
100
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Creates a session on Vertex AI Agent Engine.
|
|
104
|
+
*
|
|
105
|
+
* @throws if both `ttl` and `expireTime` are specified.
|
|
106
|
+
*/
|
|
101
107
|
async createSession({
|
|
102
108
|
appName,
|
|
103
109
|
userId,
|
|
104
110
|
state,
|
|
105
|
-
sessionId
|
|
111
|
+
sessionId,
|
|
112
|
+
ttl,
|
|
113
|
+
expireTime
|
|
106
114
|
}) {
|
|
107
115
|
var _a;
|
|
116
|
+
if (ttl != null && expireTime != null) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
"Cannot specify both 'ttl' and 'expireTime' simultaneously."
|
|
119
|
+
);
|
|
120
|
+
}
|
|
108
121
|
const reasoningEngineId = this.getReasoningEngineId(appName);
|
|
109
122
|
const filteredState = state ? trimTempState(state) : void 0;
|
|
110
123
|
let apiResponse = await this.sessions.createInternal({
|
|
111
124
|
name: "reasoningEngines/".concat(reasoningEngineId),
|
|
112
125
|
userId,
|
|
113
|
-
config: __spreadValues(__spreadValues({}, filteredState ? { sessionState: filteredState } : {}), sessionId ? { sessionId } : {})
|
|
126
|
+
config: __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, filteredState ? { sessionState: filteredState } : {}), sessionId ? { sessionId } : {}), ttl != null ? { ttl } : {}), expireTime != null ? { expireTime } : {})
|
|
114
127
|
});
|
|
115
128
|
const operationName = apiResponse.name;
|
|
116
129
|
let attempts = 0;
|
|
@@ -195,7 +208,7 @@ let VertexAiSessionService = class extends BaseSessionService {
|
|
|
195
208
|
return session;
|
|
196
209
|
} catch (error) {
|
|
197
210
|
const err = error;
|
|
198
|
-
if (err.code === GRPC_NOT_FOUND || err.code === HTTP_NOT_FOUND) {
|
|
211
|
+
if (err.code === GRPC_NOT_FOUND || err.code === HTTP_NOT_FOUND || err.status === HTTP_NOT_FOUND) {
|
|
199
212
|
return void 0;
|
|
200
213
|
}
|
|
201
214
|
logger.error("Error getting session from Vertex AI: ".concat(err.message));
|
|
@@ -37,6 +37,9 @@ const ALLOWED_FRONTMATTER_KEYS = /* @__PURE__ */ new Set([
|
|
|
37
37
|
"description",
|
|
38
38
|
"license",
|
|
39
39
|
"allowed-tools",
|
|
40
|
+
// Camel-case alias: FrontmatterSchema's preprocessor derives `allowedTools`
|
|
41
|
+
// from `allowed-tools`, and `.loose()` passes either spelling through.
|
|
42
|
+
"allowedTools",
|
|
40
43
|
"metadata",
|
|
41
44
|
"compatibility"
|
|
42
45
|
]);
|
|
@@ -99,7 +102,7 @@ async function loadDir(directoryPath) {
|
|
|
99
102
|
}
|
|
100
103
|
return files;
|
|
101
104
|
}
|
|
102
|
-
function
|
|
105
|
+
function parseFrontmatterYaml(content) {
|
|
103
106
|
if (!content.startsWith("---")) {
|
|
104
107
|
throw new Error("SKILL.md must start with YAML frontmatter (---)");
|
|
105
108
|
}
|
|
@@ -111,15 +114,34 @@ function parseSkillMdContent(content) {
|
|
|
111
114
|
const body = parts.filter((_, i) => i >= 2).join("---").trim();
|
|
112
115
|
try {
|
|
113
116
|
const parsed = yaml.load(frontmatterStr);
|
|
114
|
-
if (typeof parsed !== "object" || parsed === null) {
|
|
117
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
115
118
|
throw new Error("SKILL.md frontmatter must be a YAML mapping");
|
|
116
119
|
}
|
|
117
|
-
|
|
118
|
-
return { frontmatter, body };
|
|
120
|
+
return { raw: parsed, body };
|
|
119
121
|
} catch (e) {
|
|
120
122
|
throw new Error("Invalid YAML in frontmatter: ".concat(e.message));
|
|
121
123
|
}
|
|
122
124
|
}
|
|
125
|
+
function validateFrontmatter(raw) {
|
|
126
|
+
try {
|
|
127
|
+
return FrontmatterSchema.parse(raw);
|
|
128
|
+
} catch (e) {
|
|
129
|
+
throw new Error("Invalid YAML in frontmatter: ".concat(e.message));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function parseSkillMdContent(content) {
|
|
133
|
+
const { raw, body } = parseFrontmatterYaml(content);
|
|
134
|
+
return { frontmatter: validateFrontmatter(raw), body };
|
|
135
|
+
}
|
|
136
|
+
function isDangerousZipEntryName(entryName) {
|
|
137
|
+
if (path.posix.isAbsolute(entryName) || path.win32.isAbsolute(entryName)) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
return entryName.split(/[/\\]/).some((segment) => segment === "..");
|
|
141
|
+
}
|
|
142
|
+
function isBareSkillName(name) {
|
|
143
|
+
return name !== "." && name !== ".." && path.basename(name) === name;
|
|
144
|
+
}
|
|
123
145
|
async function loadSkillFromDir(skillDir) {
|
|
124
146
|
const resolvedDir = path.resolve(skillDir);
|
|
125
147
|
const skill = await loadSkillFile(skillDir);
|
|
@@ -258,6 +280,11 @@ async function loadAllSkillsInDir(skillsBasePath) {
|
|
|
258
280
|
function loadSkillFromZipBuffer(zipBuffer) {
|
|
259
281
|
const zip = new AdmZip(zipBuffer);
|
|
260
282
|
const entries = zip.getEntries();
|
|
283
|
+
for (const entry of entries) {
|
|
284
|
+
if (isDangerousZipEntryName(entry.entryName)) {
|
|
285
|
+
throw new Error("Dangerous zip entry ignored: ".concat(entry.entryName));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
261
288
|
let skillMdContent = "";
|
|
262
289
|
for (const entry of entries) {
|
|
263
290
|
if (entry.isDirectory) continue;
|
|
@@ -269,8 +296,15 @@ function loadSkillFromZipBuffer(zipBuffer) {
|
|
|
269
296
|
if (!skillMdContent) {
|
|
270
297
|
throw new Error("SKILL.md not found in zipped filesystem.");
|
|
271
298
|
}
|
|
272
|
-
const {
|
|
273
|
-
const
|
|
299
|
+
const { raw, body } = parseFrontmatterYaml(skillMdContent);
|
|
300
|
+
const skillName = raw["name"];
|
|
301
|
+
if (!skillName) {
|
|
302
|
+
throw new Error("SKILL.md frontmatter must contain 'name'");
|
|
303
|
+
}
|
|
304
|
+
if (typeof skillName !== "string" || !isBareSkillName(skillName)) {
|
|
305
|
+
throw new Error("Invalid skill name in SKILL.md: ".concat(String(skillName)));
|
|
306
|
+
}
|
|
307
|
+
const frontmatter = validateFrontmatter(raw);
|
|
274
308
|
const references = {};
|
|
275
309
|
const assets = {};
|
|
276
310
|
const scripts = {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {createRequire as topLevelCreateRequire} from 'module';
|
|
2
|
+
const require = topLevelCreateRequire(import.meta.url);
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright 2026 Google LLC
|
|
6
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { LongRunningFunctionTool } from "./long_running_tool.js";
|
|
10
|
+
const getUserChoiceTool = new LongRunningFunctionTool({
|
|
11
|
+
name: "get_user_choice",
|
|
12
|
+
description: "Presents a list of options to the user and awaits their selection.",
|
|
13
|
+
parameters: z.object({
|
|
14
|
+
options: z.array(z.string()).describe("List of options to present to the user.")
|
|
15
|
+
}),
|
|
16
|
+
execute: async (input, context) => {
|
|
17
|
+
if (context) {
|
|
18
|
+
context.actions.skipSummarization = true;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
export {
|
|
24
|
+
getUserChoiceTool
|
|
25
|
+
};
|
|
@@ -12,6 +12,11 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
StreamableHTTPClientTransport
|
|
14
14
|
} from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
15
|
+
import { formatError } from "../../utils/error_utils.js";
|
|
16
|
+
import { logger } from "../../utils/logger.js";
|
|
17
|
+
function logTransportError(err) {
|
|
18
|
+
logger.error("MCP transport error: " + formatError(err));
|
|
19
|
+
}
|
|
15
20
|
class MCPSessionManager {
|
|
16
21
|
constructor(connectionParams) {
|
|
17
22
|
this.activeSessions = /* @__PURE__ */ new Set();
|
|
@@ -20,31 +25,40 @@ class MCPSessionManager {
|
|
|
20
25
|
async createSession() {
|
|
21
26
|
var _a;
|
|
22
27
|
const client = new Client({ name: "MCPClient", version: "1.0.0" });
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
new StdioClientTransport(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
options.requestInit = {
|
|
33
|
-
headers: this.connectionParams.header
|
|
34
|
-
};
|
|
28
|
+
try {
|
|
29
|
+
switch (this.connectionParams.type) {
|
|
30
|
+
case "StdioConnectionParams": {
|
|
31
|
+
const transport = new StdioClientTransport(
|
|
32
|
+
this.connectionParams.serverParams
|
|
33
|
+
);
|
|
34
|
+
transport.onerror = logTransportError;
|
|
35
|
+
await client.connect(transport);
|
|
36
|
+
break;
|
|
35
37
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
case "StreamableHTTPConnectionParams": {
|
|
39
|
+
const options = (_a = this.connectionParams.transportOptions) != null ? _a : {};
|
|
40
|
+
if (!options.requestInit && this.connectionParams.header !== void 0) {
|
|
41
|
+
options.requestInit = {
|
|
42
|
+
headers: this.connectionParams.header
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const transport = new StreamableHTTPClientTransport(
|
|
38
46
|
new URL(this.connectionParams.url),
|
|
39
47
|
options
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
);
|
|
49
|
+
transport.onerror = logTransportError;
|
|
50
|
+
await client.connect(transport);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
default: {
|
|
54
|
+
const _exhaustiveCheck = this.connectionParams;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
47
57
|
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
throw new Error("Failed to create MCP session: " + formatError(err), {
|
|
60
|
+
cause: err
|
|
61
|
+
});
|
|
48
62
|
}
|
|
49
63
|
this.activeSessions.add(client);
|
|
50
64
|
return client;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {createRequire as topLevelCreateRequire} from 'module';
|
|
2
|
+
const require = topLevelCreateRequire(import.meta.url);
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright 2026 Google LLC
|
|
6
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { LongRunningFunctionTool } from "./long_running_tool.js";
|
|
10
|
+
const requestInputTool = new LongRunningFunctionTool({
|
|
11
|
+
name: "adk_request_input",
|
|
12
|
+
description: "Presents a custom message to the user and awaits unstructured or structured input.",
|
|
13
|
+
parameters: z.object({
|
|
14
|
+
message: z.string().describe("The prompt for the user."),
|
|
15
|
+
responseSchema: z.record(z.string(), z.unknown()).optional().describe("Expected schema of the response.")
|
|
16
|
+
}),
|
|
17
|
+
execute: async (input, context) => {
|
|
18
|
+
if (context) {
|
|
19
|
+
context.actions.skipSummarization = true;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
export {
|
|
25
|
+
requestInputTool
|
|
26
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {createRequire as topLevelCreateRequire} from 'module';
|
|
2
|
+
const require = topLevelCreateRequire(import.meta.url);
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright 2026 Google LLC
|
|
6
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
function randomUUID() {
|
|
9
|
+
throw new Error(
|
|
10
|
+
"randomUUID: no cryptographically secure source of randomness is available. Neither crypto.randomUUID() nor crypto.getRandomValues() is present in this environment."
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
randomUUID
|
|
15
|
+
};
|