@google/adk 1.2.0 → 1.4.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/agents/active_streaming_tool.js +6 -1
- package/dist/cjs/agents/base_agent.js +19 -1
- package/dist/cjs/agents/context.js +1 -11
- package/dist/cjs/agents/functions.js +35 -16
- package/dist/cjs/agents/instructions.js +99 -33
- package/dist/cjs/agents/invocation_context.js +2 -6
- package/dist/cjs/agents/llm_agent.js +60 -11
- package/dist/cjs/agents/processors/agent_transfer_llm_request_processor.js +7 -0
- package/dist/cjs/agents/processors/basic_llm_request_processor.js +8 -1
- package/dist/cjs/agents/processors/code_execution_request_processor.js +0 -3
- package/dist/cjs/agents/processors/content_processor_utils.js +51 -25
- package/dist/cjs/agents/processors/content_request_processor.js +7 -0
- package/dist/cjs/agents/processors/context_compactor_request_processor.js +16 -2
- package/dist/cjs/agents/processors/identity_llm_request_processor.js +7 -0
- package/dist/cjs/agents/processors/instructions_llm_request_processor.js +5 -0
- package/dist/cjs/agents/processors/interactions_request_processor.js +63 -0
- package/dist/cjs/agents/processors/request_confirmation_llm_request_processor.js +9 -1
- package/dist/cjs/agents/processors/tool_filter_request_processor.js +7 -1
- package/dist/cjs/apps/app.js +79 -0
- package/dist/cjs/apps/resumability_config.js +44 -0
- package/dist/cjs/artifacts/file_artifact_service.js +14 -1
- package/dist/cjs/artifacts/gcs_artifact_service.js +57 -15
- package/dist/cjs/artifacts/in_memory_artifact_service.js +5 -1
- package/dist/cjs/artifacts/scoped_artifact_service.js +101 -0
- package/dist/cjs/artifacts/session_artifact_service.js +27 -0
- package/dist/cjs/auth/auth_preprocessor.js +12 -10
- package/dist/cjs/auth/oauth2/oauth2_discovery.js +17 -5
- package/dist/cjs/auth/oauth2/oauth2_utils.js +12 -1
- package/dist/cjs/code_executors/code_executor_context.js +7 -7
- package/dist/cjs/common.js +86 -0
- package/dist/cjs/context/agent_controlled_context_compactor.js +109 -0
- package/dist/cjs/context/summarizers/llm_summarizer.js +11 -0
- package/dist/cjs/context/token_based_context_compactor.js +43 -11
- package/dist/cjs/context/trajectory_thought_pruning_compactor.js +71 -0
- package/dist/cjs/events/event.js +25 -1
- package/dist/cjs/integrations/agent_registry/agent_registry_mcp_toolset.js +21 -2
- package/dist/cjs/models/gemini_llm_connection.js +62 -19
- package/dist/cjs/models/google_llm.js +51 -18
- package/dist/cjs/models/interactions_utils.js +732 -0
- package/dist/cjs/plugins/base_plugin.js +1 -0
- package/dist/cjs/plugins/security_plugin.js +16 -0
- package/dist/cjs/runner/in_memory_runner.js +13 -2
- package/dist/cjs/runner/runner.js +93 -72
- package/dist/cjs/sessions/base_session_service.js +19 -3
- package/dist/cjs/sessions/database_session_service.js +26 -9
- package/dist/cjs/sessions/db/schema.js +45 -10
- package/dist/cjs/sessions/in_memory_session_service.js +2 -1
- package/dist/cjs/sessions/vertex_ai_session_service.js +21 -5
- package/dist/cjs/skills/gcp_skill_registry.js +104 -0
- package/dist/cjs/skills/loader.js +67 -2
- package/dist/cjs/skills/skill_registry.js +27 -0
- package/dist/cjs/tools/base_toolset.js +1 -1
- package/dist/cjs/tools/consolidate_context_tool.js +79 -0
- package/dist/cjs/tools/forwarding_artifact_service.js +16 -28
- package/dist/cjs/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.js +232 -0
- package/dist/cjs/tools/openapi_tool/openapi_spec_parser/operation_parser.js +224 -0
- package/dist/cjs/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +117 -0
- package/dist/cjs/tools/openapi_tool/openapi_toolset.js +133 -0
- package/dist/cjs/tools/openapi_tool/rest_api_tool.js +256 -0
- package/dist/cjs/tools/skill/load_skill_resource_tool.js +25 -3
- package/dist/cjs/tools/skill/load_skill_tool.js +12 -1
- package/dist/cjs/tools/skill/run_skill_script_tool.js +12 -1
- package/dist/cjs/tools/skill/search_skills_tool.js +108 -0
- package/dist/cjs/tools/skill/skill_toolset.js +40 -5
- package/dist/cjs/utils/async_hooks_shim.js +52 -0
- package/dist/cjs/utils/async_queue.js +88 -0
- package/dist/cjs/utils/case_utils.js +53 -0
- package/dist/cjs/utils/client_labels.js +41 -3
- package/dist/cjs/utils/env_aware_utils.js +14 -1
- package/dist/cjs/utils/live_connection_utils.js +284 -0
- package/dist/cjs/utils/model_name.js +9 -0
- package/dist/cjs/utils/streaming_utils.js +18 -11
- package/dist/cjs/utils/task.js +62 -0
- package/dist/cjs/version.js +1 -1
- package/dist/esm/agents/active_streaming_tool.js +6 -1
- package/dist/esm/agents/base_agent.js +19 -1
- package/dist/esm/agents/context.js +1 -11
- package/dist/esm/agents/functions.js +36 -15
- package/dist/esm/agents/instructions.js +99 -33
- package/dist/esm/agents/invocation_context.js +2 -6
- package/dist/esm/agents/llm_agent.js +61 -11
- package/dist/esm/agents/processors/agent_transfer_llm_request_processor.js +7 -0
- package/dist/esm/agents/processors/basic_llm_request_processor.js +8 -1
- package/dist/esm/agents/processors/code_execution_request_processor.js +0 -3
- package/dist/esm/agents/processors/content_processor_utils.js +48 -24
- package/dist/esm/agents/processors/content_request_processor.js +7 -0
- package/dist/esm/agents/processors/context_compactor_request_processor.js +16 -2
- package/dist/esm/agents/processors/identity_llm_request_processor.js +7 -0
- package/dist/esm/agents/processors/instructions_llm_request_processor.js +5 -0
- package/dist/esm/agents/processors/interactions_request_processor.js +34 -0
- package/dist/esm/agents/processors/request_confirmation_llm_request_processor.js +9 -1
- package/dist/esm/agents/processors/tool_filter_request_processor.js +7 -1
- package/dist/esm/apps/app.js +49 -0
- package/dist/esm/apps/resumability_config.js +16 -0
- package/dist/esm/artifacts/file_artifact_service.js +14 -1
- package/dist/esm/artifacts/gcs_artifact_service.js +57 -15
- package/dist/esm/artifacts/in_memory_artifact_service.js +5 -1
- package/dist/esm/artifacts/scoped_artifact_service.js +73 -0
- package/dist/esm/artifacts/session_artifact_service.js +7 -0
- package/dist/esm/auth/auth_preprocessor.js +12 -10
- package/dist/esm/auth/oauth2/oauth2_discovery.js +14 -4
- package/dist/esm/auth/oauth2/oauth2_utils.js +12 -1
- package/dist/esm/code_executors/code_executor_context.js +7 -7
- package/dist/esm/common.js +75 -3
- package/dist/esm/context/agent_controlled_context_compactor.js +81 -0
- package/dist/esm/context/summarizers/llm_summarizer.js +11 -0
- package/dist/esm/context/token_based_context_compactor.js +43 -11
- package/dist/esm/context/trajectory_thought_pruning_compactor.js +43 -0
- package/dist/esm/events/event.js +23 -1
- package/dist/esm/integrations/agent_registry/agent_registry_mcp_toolset.js +21 -2
- package/dist/esm/models/gemini_llm_connection.js +62 -19
- package/dist/esm/models/google_llm.js +49 -17
- package/dist/esm/models/interactions_utils.js +697 -0
- package/dist/esm/plugins/base_plugin.js +1 -0
- package/dist/esm/plugins/security_plugin.js +16 -0
- package/dist/esm/runner/in_memory_runner.js +13 -2
- package/dist/esm/runner/runner.js +91 -73
- package/dist/esm/sessions/base_session_service.js +17 -2
- package/dist/esm/sessions/database_session_service.js +26 -9
- package/dist/esm/sessions/db/schema.js +44 -10
- package/dist/esm/sessions/in_memory_session_service.js +4 -2
- package/dist/esm/sessions/vertex_ai_session_service.js +21 -5
- package/dist/esm/skills/gcp_skill_registry.js +78 -0
- package/dist/esm/skills/loader.js +66 -2
- package/dist/esm/skills/skill_registry.js +7 -0
- package/dist/esm/tools/base_toolset.js +1 -1
- package/dist/esm/tools/consolidate_context_tool.js +51 -0
- package/dist/esm/tools/forwarding_artifact_service.js +16 -28
- package/dist/esm/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.js +206 -0
- package/dist/esm/tools/openapi_tool/openapi_spec_parser/operation_parser.js +198 -0
- package/dist/esm/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +91 -0
- package/dist/esm/tools/openapi_tool/openapi_toolset.js +97 -0
- package/dist/esm/tools/openapi_tool/rest_api_tool.js +229 -0
- package/dist/esm/tools/skill/load_skill_resource_tool.js +25 -3
- package/dist/esm/tools/skill/load_skill_tool.js +12 -1
- package/dist/esm/tools/skill/run_skill_script_tool.js +12 -1
- package/dist/esm/tools/skill/search_skills_tool.js +82 -0
- package/dist/esm/tools/skill/skill_toolset.js +40 -5
- package/dist/esm/utils/async_hooks_shim.js +24 -0
- package/dist/esm/utils/async_queue.js +60 -0
- package/dist/esm/utils/case_utils.js +25 -0
- package/dist/esm/utils/client_labels.js +38 -2
- package/dist/esm/utils/env_aware_utils.js +14 -1
- package/dist/esm/utils/live_connection_utils.js +256 -0
- package/dist/esm/utils/model_name.js +8 -0
- package/dist/esm/utils/streaming_utils.js +18 -11
- package/dist/esm/utils/task.js +34 -0
- package/dist/esm/version.js +1 -1
- package/dist/types/a2a/a2a_remote_agent_utils.d.ts +29 -4
- package/dist/types/a2a/event_converter_utils.d.ts +14 -1
- package/dist/types/a2a/metadata_converter_utils.d.ts +18 -0
- package/dist/types/a2a/part_converter_utils.d.ts +51 -6
- package/dist/types/agents/active_streaming_tool.d.ts +3 -4
- package/dist/types/agents/functions.d.ts +12 -9
- package/dist/types/agents/invocation_context.d.ts +7 -12
- package/dist/types/agents/llm_agent.d.ts +14 -0
- package/dist/types/agents/processors/agent_transfer_llm_request_processor.d.ts +14 -0
- package/dist/types/agents/processors/basic_llm_request_processor.d.ts +7 -0
- package/dist/types/agents/processors/content_processor_utils.d.ts +34 -0
- package/dist/types/agents/processors/content_request_processor.d.ts +16 -0
- package/dist/types/agents/processors/context_compactor_request_processor.d.ts +12 -0
- package/dist/types/agents/processors/identity_llm_request_processor.d.ts +7 -0
- package/dist/types/agents/processors/interactions_request_processor.d.ts +17 -0
- package/dist/types/agents/processors/request_confirmation_llm_request_processor.d.ts +9 -1
- package/dist/types/agents/processors/tool_filter_request_processor.d.ts +12 -1
- package/dist/types/apps/app.d.ts +52 -0
- package/dist/types/apps/resumability_config.d.ts +27 -0
- package/dist/types/artifacts/base_artifact_service.d.ts +6 -36
- package/dist/types/artifacts/gcs_artifact_service.d.ts +2 -1
- package/dist/types/artifacts/scoped_artifact_service.d.ts +25 -0
- package/dist/types/artifacts/session_artifact_service.d.ts +25 -0
- package/dist/types/auth/oauth2/oauth2_discovery.d.ts +11 -0
- package/dist/types/common.d.ts +35 -4
- package/dist/types/context/agent_controlled_context_compactor.d.ts +24 -0
- package/dist/types/context/base_context_compactor.d.ts +3 -0
- package/dist/types/context/summarizers/llm_summarizer.d.ts +17 -0
- package/dist/types/context/token_based_context_compactor.d.ts +6 -1
- package/dist/types/context/trajectory_thought_pruning_compactor.d.ts +27 -0
- package/dist/types/events/event.d.ts +8 -0
- package/dist/types/events/event_actions.d.ts +1 -2
- package/dist/types/integrations/agent_registry/agent_registry_mcp_toolset.d.ts +21 -2
- package/dist/types/models/base_llm_connection.d.ts +10 -0
- package/dist/types/models/gemini_llm_connection.d.ts +15 -4
- package/dist/types/models/google_llm.d.ts +15 -1
- package/dist/types/models/interactions_utils.d.ts +92 -0
- package/dist/types/models/llm_request.d.ts +4 -0
- package/dist/types/models/llm_response.d.ts +14 -1
- package/dist/types/plugins/base_plugin.d.ts +2 -1
- package/dist/types/plugins/security_plugin.d.ts +30 -0
- package/dist/types/runner/in_memory_runner.d.ts +7 -1
- package/dist/types/runner/runner.d.ts +43 -9
- package/dist/types/sessions/base_session_service.d.ts +7 -16
- package/dist/types/sessions/db/schema.d.ts +1 -0
- package/dist/types/sessions/session.d.ts +11 -0
- package/dist/types/sessions/vertex_ai_session_service.d.ts +9 -1
- package/dist/types/skills/gcp_skill_registry.d.ts +24 -0
- package/dist/types/skills/loader.d.ts +7 -0
- package/dist/types/skills/skill.d.ts +1 -1
- package/dist/types/skills/skill_registry.d.ts +29 -0
- package/dist/types/tools/consolidate_context_tool.d.ts +19 -0
- package/dist/types/tools/forwarding_artifact_service.d.ts +3 -2
- package/dist/types/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.d.ts +34 -0
- package/dist/types/tools/openapi_tool/openapi_spec_parser/operation_parser.d.ts +59 -0
- package/dist/types/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.d.ts +23 -0
- package/dist/types/tools/openapi_tool/openapi_toolset.d.ts +27 -0
- package/dist/types/tools/openapi_tool/rest_api_tool.d.ts +50 -0
- package/dist/types/tools/skill/load_skill_resource_tool.d.ts +1 -1
- package/dist/types/tools/skill/search_skills_tool.d.ts +14 -0
- package/dist/types/tools/skill/skill_toolset.d.ts +5 -0
- package/dist/types/utils/async_hooks_shim.d.ts +10 -0
- package/dist/types/utils/async_queue.d.ts +18 -0
- package/dist/types/utils/case_utils.d.ts +12 -0
- package/dist/types/utils/client_labels.d.ts +10 -0
- package/dist/types/utils/env_aware_utils.d.ts +3 -3
- package/dist/types/utils/live_connection_utils.d.ts +30 -0
- package/dist/types/utils/model_name.d.ts +7 -0
- package/dist/types/utils/streaming_utils.d.ts +0 -1
- package/dist/types/utils/task.d.ts +24 -0
- package/dist/types/version.d.ts +1 -1
- package/dist/web/agents/active_streaming_tool.js +6 -1
- package/dist/web/agents/base_agent.js +31 -1
- package/dist/web/agents/context.js +1 -11
- package/dist/web/agents/functions.js +36 -15
- package/dist/web/agents/instructions.js +99 -33
- package/dist/web/agents/invocation_context.js +2 -6
- package/dist/web/agents/llm_agent.js +61 -11
- package/dist/web/agents/processors/agent_transfer_llm_request_processor.js +7 -0
- package/dist/web/agents/processors/basic_llm_request_processor.js +8 -1
- package/dist/web/agents/processors/code_execution_request_processor.js +0 -3
- package/dist/web/agents/processors/content_processor_utils.js +66 -24
- package/dist/web/agents/processors/content_request_processor.js +7 -0
- package/dist/web/agents/processors/context_compactor_request_processor.js +16 -2
- package/dist/web/agents/processors/identity_llm_request_processor.js +7 -0
- package/dist/web/agents/processors/instructions_llm_request_processor.js +5 -0
- package/dist/web/agents/processors/interactions_request_processor.js +52 -0
- package/dist/web/agents/processors/request_confirmation_llm_request_processor.js +9 -1
- package/dist/web/agents/processors/tool_filter_request_processor.js +7 -1
- package/dist/web/apps/app.js +49 -0
- package/dist/web/apps/resumability_config.js +31 -0
- package/dist/web/artifacts/file_artifact_service.js +14 -1
- package/dist/web/artifacts/gcs_artifact_service.js +55 -15
- package/dist/web/artifacts/in_memory_artifact_service.js +5 -1
- package/dist/web/artifacts/scoped_artifact_service.js +86 -0
- package/dist/web/artifacts/session_artifact_service.js +7 -0
- package/dist/web/auth/auth_preprocessor.js +12 -10
- package/dist/web/auth/oauth2/oauth2_discovery.js +14 -4
- package/dist/web/auth/oauth2/oauth2_utils.js +12 -1
- package/dist/web/code_executors/code_executor_context.js +7 -7
- package/dist/web/common.js +75 -3
- package/dist/web/context/agent_controlled_context_compactor.js +81 -0
- package/dist/web/context/summarizers/llm_summarizer.js +11 -0
- package/dist/web/context/token_based_context_compactor.js +43 -11
- package/dist/web/context/trajectory_thought_pruning_compactor.js +43 -0
- package/dist/web/events/event.js +21 -1
- package/dist/web/integrations/agent_registry/agent_registry_mcp_toolset.js +21 -2
- package/dist/web/models/gemini_llm_connection.js +75 -19
- package/dist/web/models/google_llm.js +80 -17
- package/dist/web/models/interactions_utils.js +728 -0
- package/dist/web/plugins/base_plugin.js +1 -0
- package/dist/web/plugins/security_plugin.js +16 -0
- package/dist/web/runner/in_memory_runner.js +13 -2
- package/dist/web/runner/runner.js +111 -75
- package/dist/web/sessions/base_session_service.js +17 -2
- package/dist/web/sessions/database_session_service.js +26 -9
- package/dist/web/sessions/db/schema.js +44 -10
- package/dist/web/sessions/in_memory_session_service.js +4 -2
- package/dist/web/sessions/vertex_ai_session_service.js +21 -5
- package/dist/web/skills/gcp_skill_registry.js +78 -0
- package/dist/web/skills/loader.js +66 -2
- package/dist/web/skills/skill_registry.js +7 -0
- package/dist/web/tools/base_toolset.js +1 -1
- package/dist/web/tools/consolidate_context_tool.js +51 -0
- package/dist/web/tools/forwarding_artifact_service.js +16 -28
- package/dist/web/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.js +221 -0
- package/dist/web/tools/openapi_tool/openapi_spec_parser/operation_parser.js +198 -0
- package/dist/web/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +91 -0
- package/dist/web/tools/openapi_tool/openapi_toolset.js +97 -0
- package/dist/web/tools/openapi_tool/rest_api_tool.js +229 -0
- package/dist/web/tools/skill/load_skill_resource_tool.js +25 -3
- package/dist/web/tools/skill/load_skill_tool.js +12 -1
- package/dist/web/tools/skill/run_skill_script_tool.js +12 -1
- package/dist/web/tools/skill/search_skills_tool.js +82 -0
- package/dist/web/tools/skill/skill_toolset.js +40 -5
- package/dist/web/utils/async_hooks_shim.js +24 -0
- package/dist/web/utils/async_queue.js +60 -0
- package/dist/web/utils/case_utils.js +25 -0
- package/dist/web/utils/client_labels.js +38 -2
- package/dist/web/utils/env_aware_utils.js +14 -1
- package/dist/web/utils/live_connection_utils.js +254 -0
- package/dist/web/utils/model_name.js +8 -0
- package/dist/web/utils/streaming_utils.js +18 -11
- package/dist/web/utils/task.js +34 -0
- package/dist/web/version.js +1 -1
- package/package.json +4 -2
|
@@ -7,24 +7,38 @@ const require = topLevelCreateRequire(import.meta.url);
|
|
|
7
7
|
*/
|
|
8
8
|
import { ContextCompactionTrigger } from "../../plugins/base_plugin.js";
|
|
9
9
|
class ContextCompactorRequestProcessor {
|
|
10
|
+
/**
|
|
11
|
+
* @param compactors - Ordered list of compactors to evaluate; the first one
|
|
12
|
+
* that reports it should compact will perform the compaction.
|
|
13
|
+
*/
|
|
10
14
|
constructor(compactors) {
|
|
11
15
|
this.compactors = compactors;
|
|
12
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Evaluates compactors in priority order. The first compactor that indicates
|
|
19
|
+
* it should compact will compact the session history, fire plugin hooks, and
|
|
20
|
+
* yield any newly generated events. Iteration stops after one compaction.
|
|
21
|
+
*
|
|
22
|
+
* @param invocationContext - The current invocation context.
|
|
23
|
+
* @param _llmRequest - Unused; present to satisfy the {@link BaseLlmRequestProcessor} interface.
|
|
24
|
+
*/
|
|
13
25
|
async *runAsync(invocationContext, _llmRequest) {
|
|
26
|
+
var _a;
|
|
14
27
|
for (const compactor of this.compactors) {
|
|
15
28
|
const shouldCompact = await Promise.resolve(
|
|
16
29
|
compactor.shouldCompact(invocationContext)
|
|
17
30
|
);
|
|
18
31
|
if (shouldCompact) {
|
|
32
|
+
const trigger = (_a = compactor.trigger) != null ? _a : ContextCompactionTrigger.Auto;
|
|
19
33
|
await invocationContext.pluginManager.runBeforeContextCompaction({
|
|
20
34
|
invocationContext,
|
|
21
|
-
trigger
|
|
35
|
+
trigger
|
|
22
36
|
});
|
|
23
37
|
const oldEvents = new Set(invocationContext.session.events);
|
|
24
38
|
await Promise.resolve(compactor.compact(invocationContext));
|
|
25
39
|
await invocationContext.pluginManager.runAfterContextCompaction({
|
|
26
40
|
invocationContext,
|
|
27
|
-
trigger
|
|
41
|
+
trigger
|
|
28
42
|
});
|
|
29
43
|
const newEvents = invocationContext.session.events.filter(
|
|
30
44
|
(e) => !oldEvents.has(e)
|
|
@@ -8,6 +8,13 @@ const require = topLevelCreateRequire(import.meta.url);
|
|
|
8
8
|
import { appendInstructions } from "../../models/llm_request.js";
|
|
9
9
|
import { BaseLlmRequestProcessor } from "./base_llm_processor.js";
|
|
10
10
|
class IdentityLlmRequestProcessor extends BaseLlmRequestProcessor {
|
|
11
|
+
/**
|
|
12
|
+
* Appends agent name and description as identity instructions to the system
|
|
13
|
+
* prompt of the request.
|
|
14
|
+
*
|
|
15
|
+
* @param invocationContext - The current invocation context.
|
|
16
|
+
* @param llmRequest - The request object to append instructions to.
|
|
17
|
+
*/
|
|
11
18
|
// eslint-disable-next-line require-yield
|
|
12
19
|
async *runAsync(invocationContext, llmRequest) {
|
|
13
20
|
const agent = invocationContext.agent;
|
|
@@ -47,6 +47,11 @@ class InstructionsLlmRequestProcessor extends BaseLlmRequestProcessor {
|
|
|
47
47
|
}
|
|
48
48
|
appendInstructions(llmRequest, [instructionWithState]);
|
|
49
49
|
}
|
|
50
|
+
if (agent.outputSchema && agent.tools && agent.tools.length > 0) {
|
|
51
|
+
appendInstructions(llmRequest, [
|
|
52
|
+
'To output the final result, you must call the "set_model_response" function with the appropriate values. Do not output anything else.'
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
50
55
|
}
|
|
51
56
|
}
|
|
52
57
|
const INSTRUCTIONS_LLM_REQUEST_PROCESSOR = new InstructionsLlmRequestProcessor();
|
|
@@ -0,0 +1,34 @@
|
|
|
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 { isGemini } from "../../models/google_llm.js";
|
|
9
|
+
import { isLlmAgent } from "../llm_agent.js";
|
|
10
|
+
class InteractionsRequestProcessor {
|
|
11
|
+
// eslint-disable-next-line require-yield
|
|
12
|
+
async *runAsync(invocationContext, llmRequest) {
|
|
13
|
+
const agent = invocationContext.agent;
|
|
14
|
+
if (!agent || !isLlmAgent(agent)) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const model = agent.canonicalModel;
|
|
18
|
+
if (isGemini(model) && model.useInteractionsApi) {
|
|
19
|
+
const events = invocationContext.session.events;
|
|
20
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
21
|
+
const event = events[i];
|
|
22
|
+
if (event.branch === invocationContext.branch && event.author === agent.name && event.interactionId) {
|
|
23
|
+
llmRequest.previousInteractionId = event.interactionId;
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const INTERACTIONS_REQUEST_PROCESSOR = new InteractionsRequestProcessor();
|
|
31
|
+
export {
|
|
32
|
+
INTERACTIONS_REQUEST_PROCESSOR,
|
|
33
|
+
InteractionsRequestProcessor
|
|
34
|
+
};
|
|
@@ -18,7 +18,15 @@ import { isLlmAgent } from "../llm_agent.js";
|
|
|
18
18
|
import { ReadonlyContext } from "../readonly_context.js";
|
|
19
19
|
import { BaseLlmRequestProcessor } from "./base_llm_processor.js";
|
|
20
20
|
class RequestConfirmationLlmRequestProcessor extends BaseLlmRequestProcessor {
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Resumes tool calls that were paused for user confirmation, re-invoking
|
|
23
|
+
* them with the confirmed or denied decision before the next LLM turn.
|
|
24
|
+
*
|
|
25
|
+
* @param invocationContext - The current invocation context, including the
|
|
26
|
+
* session event history used to locate pending confirmation responses.
|
|
27
|
+
* @yields Function response events for tools that have been confirmed and
|
|
28
|
+
* are ready to resume.
|
|
29
|
+
*/
|
|
22
30
|
async *runAsync(invocationContext) {
|
|
23
31
|
const agent = invocationContext.agent;
|
|
24
32
|
if (!isLlmAgent(agent)) {
|
|
@@ -10,7 +10,13 @@ import { isLlmAgent } from "../llm_agent.js";
|
|
|
10
10
|
import { ReadonlyContext } from "../readonly_context.js";
|
|
11
11
|
import { BaseLlmRequestProcessor } from "./base_llm_processor.js";
|
|
12
12
|
class ToolFilterRequestProcessor extends BaseLlmRequestProcessor {
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Invokes plugin-based tool filtering and updates {@link LlmRequest.allowedTools}
|
|
15
|
+
* with the reduced tool set if any plugin returns a filtered result.
|
|
16
|
+
*
|
|
17
|
+
* @param invocationContext - The current invocation context.
|
|
18
|
+
* @param llmRequest - The request whose allowed tools may be restricted.
|
|
19
|
+
*/
|
|
14
20
|
// eslint-disable-next-line require-yield
|
|
15
21
|
async *runAsync(invocationContext, llmRequest) {
|
|
16
22
|
const agent = invocationContext.agent;
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
var _a;
|
|
9
|
+
import { isBaseAgent } from "../agents/base_agent.js";
|
|
10
|
+
const VALID_APP_NAME_RE = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
|
|
11
|
+
function validateAppName(name) {
|
|
12
|
+
if (!VALID_APP_NAME_RE.test(name)) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
`Invalid app name '${name}': must start with a letter and can only consist of letters, digits, underscores, and hyphens.`
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
if (name === "user") {
|
|
18
|
+
throw new Error("App name cannot be 'user'; reserved for end-user input.");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const APP_SIGNATURE_SYMBOL = Symbol.for("google.adk.app");
|
|
22
|
+
function isApp(obj) {
|
|
23
|
+
return typeof obj === "object" && obj !== null && APP_SIGNATURE_SYMBOL in obj && obj[APP_SIGNATURE_SYMBOL] === true;
|
|
24
|
+
}
|
|
25
|
+
_a = APP_SIGNATURE_SYMBOL;
|
|
26
|
+
class App {
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this[_a] = true;
|
|
29
|
+
var _a2, _b, _c, _d;
|
|
30
|
+
validateAppName(options.name);
|
|
31
|
+
if (options.rootAgent === void 0 || options.rootAgent === null) {
|
|
32
|
+
throw new Error("rootAgent must be provided.");
|
|
33
|
+
}
|
|
34
|
+
if (!isBaseAgent(options.rootAgent)) {
|
|
35
|
+
throw new TypeError(
|
|
36
|
+
`rootAgent must be a BaseAgent instance, got ${(_c = (_b = (_a2 = options.rootAgent) == null ? void 0 : _a2.constructor) == null ? void 0 : _b.name) != null ? _c : typeof options.rootAgent}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
this.name = options.name;
|
|
40
|
+
this.rootAgent = options.rootAgent;
|
|
41
|
+
this.plugins = (_d = options.plugins) != null ? _d : [];
|
|
42
|
+
this.resumabilityConfig = options.resumabilityConfig;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
App,
|
|
47
|
+
isApp,
|
|
48
|
+
validateAppName
|
|
49
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
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 createResumabilityConfig(params = {}) {
|
|
9
|
+
return {
|
|
10
|
+
isResumable: false,
|
|
11
|
+
...params
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
createResumabilityConfig
|
|
16
|
+
};
|
|
@@ -26,7 +26,7 @@ class FileArtifactService {
|
|
|
26
26
|
artifact,
|
|
27
27
|
customMetadata
|
|
28
28
|
}) {
|
|
29
|
-
if (!artifact.inlineData && !artifact.text) {
|
|
29
|
+
if (!artifact.inlineData && !artifact.text && !artifact.fileData) {
|
|
30
30
|
throw new Error("Artifact must have either inlineData or text content.");
|
|
31
31
|
}
|
|
32
32
|
const artifactDir = getArtifactDir(
|
|
@@ -44,12 +44,19 @@ class FileArtifactService {
|
|
|
44
44
|
const storedFilename = path.basename(artifactDir);
|
|
45
45
|
const contentPath = path.join(versionDir, storedFilename);
|
|
46
46
|
let mimeType;
|
|
47
|
+
let fileUri;
|
|
47
48
|
if (artifact.inlineData) {
|
|
48
49
|
const data = artifact.inlineData.data || "";
|
|
49
50
|
await fs.writeFile(contentPath, Buffer.from(data, "base64"));
|
|
50
51
|
mimeType = artifact.inlineData.mimeType || "application/octet-stream";
|
|
51
52
|
} else if (artifact.text !== void 0) {
|
|
52
53
|
await fs.writeFile(contentPath, artifact.text, "utf-8");
|
|
54
|
+
} else {
|
|
55
|
+
fileUri = artifact.fileData.fileUri;
|
|
56
|
+
if (!fileUri) {
|
|
57
|
+
throw new Error("Artifact fileData must have a fileUri.");
|
|
58
|
+
}
|
|
59
|
+
mimeType = artifact.fileData.mimeType;
|
|
53
60
|
}
|
|
54
61
|
const canonicalUri = await getCanonicalUri(
|
|
55
62
|
this.rootDir,
|
|
@@ -61,6 +68,7 @@ class FileArtifactService {
|
|
|
61
68
|
const metadata = {
|
|
62
69
|
fileName: filename,
|
|
63
70
|
mimeType,
|
|
71
|
+
fileUri,
|
|
64
72
|
version: nextVersion,
|
|
65
73
|
canonicalUri,
|
|
66
74
|
customMetadata
|
|
@@ -112,6 +120,11 @@ class FileArtifactService {
|
|
|
112
120
|
);
|
|
113
121
|
const metadataPath = path.join(versionDir, "metadata.json");
|
|
114
122
|
const metadata = await readMetadata(metadataPath);
|
|
123
|
+
if (metadata.fileUri) {
|
|
124
|
+
return {
|
|
125
|
+
fileData: { fileUri: metadata.fileUri, mimeType: metadata.mimeType }
|
|
126
|
+
};
|
|
127
|
+
}
|
|
115
128
|
const storedFilename = path.basename(artifactDir);
|
|
116
129
|
let contentPath = path.join(versionDir, storedFilename);
|
|
117
130
|
if (metadata.canonicalUri) {
|
|
@@ -8,12 +8,16 @@ const require = topLevelCreateRequire(import.meta.url);
|
|
|
8
8
|
import { Storage } from "@google-cloud/storage";
|
|
9
9
|
import { createPartFromBase64, createPartFromText } from "@google/genai";
|
|
10
10
|
import { logger } from "../utils/logger.js";
|
|
11
|
+
const GCS_FILE_URI_METADATA_KEY = "adkFileUri";
|
|
12
|
+
const GCS_FILE_MIME_TYPE_METADATA_KEY = "adkFileMimeType";
|
|
13
|
+
const GCS_DISPLAY_NAME_METADATA_KEY = "adkDisplayName";
|
|
14
|
+
const GCS_IS_TEXT_METADATA_KEY = "adkIsText";
|
|
11
15
|
class GcsArtifactService {
|
|
12
|
-
constructor(bucket) {
|
|
13
|
-
this.bucket = new Storage().bucket(bucket);
|
|
16
|
+
constructor(bucket, options) {
|
|
17
|
+
this.bucket = new Storage(options).bucket(bucket);
|
|
14
18
|
}
|
|
15
19
|
async saveArtifact(request) {
|
|
16
|
-
if (!request.artifact.inlineData && !request.artifact.text) {
|
|
20
|
+
if (!request.artifact.inlineData && !request.artifact.text && !request.artifact.fileData) {
|
|
17
21
|
throw new Error("Artifact must have either inlineData or text content.");
|
|
18
22
|
}
|
|
19
23
|
const versions = await this.listVersions(request);
|
|
@@ -24,24 +28,48 @@ class GcsArtifactService {
|
|
|
24
28
|
version
|
|
25
29
|
})
|
|
26
30
|
);
|
|
27
|
-
const
|
|
31
|
+
const customMetadata = {
|
|
32
|
+
...request.customMetadata
|
|
33
|
+
};
|
|
28
34
|
if (request.artifact.inlineData) {
|
|
35
|
+
if (request.artifact.inlineData.displayName) {
|
|
36
|
+
customMetadata[GCS_DISPLAY_NAME_METADATA_KEY] = request.artifact.inlineData.displayName;
|
|
37
|
+
}
|
|
29
38
|
await file.save(
|
|
30
39
|
Buffer.from(request.artifact.inlineData.data || "", "base64"),
|
|
31
40
|
{
|
|
32
41
|
contentType: request.artifact.inlineData.mimeType,
|
|
33
|
-
metadata
|
|
42
|
+
metadata: { metadata: customMetadata }
|
|
34
43
|
}
|
|
35
44
|
);
|
|
36
45
|
return version;
|
|
46
|
+
} else if (request.artifact.text !== void 0) {
|
|
47
|
+
await file.save(request.artifact.text, {
|
|
48
|
+
contentType: "text/plain",
|
|
49
|
+
metadata: {
|
|
50
|
+
metadata: { ...customMetadata, [GCS_IS_TEXT_METADATA_KEY]: "true" }
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return version;
|
|
54
|
+
} else {
|
|
55
|
+
const fileData = request.artifact.fileData;
|
|
56
|
+
const fileUri = fileData == null ? void 0 : fileData.fileUri;
|
|
57
|
+
if (!fileUri) {
|
|
58
|
+
throw new Error("Artifact fileData must have a fileUri.");
|
|
59
|
+
}
|
|
60
|
+
customMetadata[GCS_FILE_URI_METADATA_KEY] = fileUri;
|
|
61
|
+
if (fileData.mimeType) {
|
|
62
|
+
customMetadata[GCS_FILE_MIME_TYPE_METADATA_KEY] = fileData.mimeType;
|
|
63
|
+
}
|
|
64
|
+
await file.save("", {
|
|
65
|
+
contentType: fileData.mimeType || void 0,
|
|
66
|
+
metadata: { metadata: customMetadata }
|
|
67
|
+
});
|
|
68
|
+
return version;
|
|
37
69
|
}
|
|
38
|
-
await file.save(request.artifact.text, {
|
|
39
|
-
contentType: "text/plain",
|
|
40
|
-
metadata
|
|
41
|
-
});
|
|
42
|
-
return version;
|
|
43
70
|
}
|
|
44
71
|
async loadArtifact(request) {
|
|
72
|
+
var _a, _b, _c;
|
|
45
73
|
try {
|
|
46
74
|
let version = request.version;
|
|
47
75
|
if (version === void 0) {
|
|
@@ -57,11 +85,25 @@ class GcsArtifactService {
|
|
|
57
85
|
version
|
|
58
86
|
})
|
|
59
87
|
);
|
|
60
|
-
const [
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
88
|
+
const [metadata] = await file.getMetadata();
|
|
89
|
+
const customMeta = (_a = metadata.metadata) != null ? _a : {};
|
|
90
|
+
const fileUri = customMeta[GCS_FILE_URI_METADATA_KEY];
|
|
91
|
+
if (fileUri) {
|
|
92
|
+
const mimeType = (_c = (_b = customMeta[GCS_FILE_MIME_TYPE_METADATA_KEY]) != null ? _b : metadata.contentType) != null ? _c : void 0;
|
|
93
|
+
return { fileData: { fileUri, mimeType } };
|
|
94
|
+
}
|
|
95
|
+
const [rawDataBuffer] = await file.download();
|
|
96
|
+
const displayName = customMeta[GCS_DISPLAY_NAME_METADATA_KEY];
|
|
97
|
+
if (displayName) {
|
|
98
|
+
return {
|
|
99
|
+
inlineData: {
|
|
100
|
+
data: rawDataBuffer.toString("base64"),
|
|
101
|
+
mimeType: metadata.contentType,
|
|
102
|
+
displayName
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (customMeta[GCS_IS_TEXT_METADATA_KEY] === "true" || metadata.contentType === "text/plain") {
|
|
65
107
|
return createPartFromText(rawDataBuffer.toString("utf-8"));
|
|
66
108
|
}
|
|
67
109
|
return createPartFromBase64(
|
|
@@ -20,7 +20,7 @@ class InMemoryArtifactService {
|
|
|
20
20
|
artifact,
|
|
21
21
|
customMetadata
|
|
22
22
|
}) {
|
|
23
|
-
if (!artifact.inlineData && !artifact.text) {
|
|
23
|
+
if (!artifact.inlineData && !artifact.text && !artifact.fileData) {
|
|
24
24
|
return Promise.reject(
|
|
25
25
|
new Error("Artifact must have either inlineData or text content.")
|
|
26
26
|
);
|
|
@@ -34,6 +34,10 @@ class InMemoryArtifactService {
|
|
|
34
34
|
version,
|
|
35
35
|
customMetadata
|
|
36
36
|
};
|
|
37
|
+
if (!artifact.inlineData && artifact.text === void 0) {
|
|
38
|
+
const fileData = artifact.fileData;
|
|
39
|
+
metadata.mimeType = fileData.mimeType;
|
|
40
|
+
}
|
|
37
41
|
this.artifacts[path].push({ part: artifact, metadata });
|
|
38
42
|
return Promise.resolve(version);
|
|
39
43
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
class ScopedArtifactService {
|
|
9
|
+
constructor(delegate, appName, userId, sessionId) {
|
|
10
|
+
this.delegate = delegate;
|
|
11
|
+
this.appName = appName;
|
|
12
|
+
this.userId = userId;
|
|
13
|
+
this.sessionId = sessionId;
|
|
14
|
+
}
|
|
15
|
+
async saveArtifact(request) {
|
|
16
|
+
return this.delegate.saveArtifact({
|
|
17
|
+
appName: this.appName,
|
|
18
|
+
userId: this.userId,
|
|
19
|
+
sessionId: this.sessionId,
|
|
20
|
+
...request
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async loadArtifact(request) {
|
|
24
|
+
return this.delegate.loadArtifact({
|
|
25
|
+
appName: this.appName,
|
|
26
|
+
userId: this.userId,
|
|
27
|
+
sessionId: this.sessionId,
|
|
28
|
+
...request
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async listArtifactKeys() {
|
|
32
|
+
return this.delegate.listArtifactKeys({
|
|
33
|
+
appName: this.appName,
|
|
34
|
+
userId: this.userId,
|
|
35
|
+
sessionId: this.sessionId
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async deleteArtifact(filename) {
|
|
39
|
+
return this.delegate.deleteArtifact({
|
|
40
|
+
appName: this.appName,
|
|
41
|
+
userId: this.userId,
|
|
42
|
+
sessionId: this.sessionId,
|
|
43
|
+
filename
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
async listVersions(filename) {
|
|
47
|
+
return this.delegate.listVersions({
|
|
48
|
+
appName: this.appName,
|
|
49
|
+
userId: this.userId,
|
|
50
|
+
sessionId: this.sessionId,
|
|
51
|
+
filename
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async listArtifactVersions(filename) {
|
|
55
|
+
return this.delegate.listArtifactVersions({
|
|
56
|
+
appName: this.appName,
|
|
57
|
+
userId: this.userId,
|
|
58
|
+
sessionId: this.sessionId,
|
|
59
|
+
filename
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
async getArtifactVersion(request) {
|
|
63
|
+
return this.delegate.getArtifactVersion({
|
|
64
|
+
appName: this.appName,
|
|
65
|
+
userId: this.userId,
|
|
66
|
+
sessionId: this.sessionId,
|
|
67
|
+
...request
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export {
|
|
72
|
+
ScopedArtifactService
|
|
73
|
+
};
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
getFunctionResponses
|
|
18
18
|
} from "../events/event.js";
|
|
19
19
|
import { State } from "../sessions/state.js";
|
|
20
|
+
import { camelCaseKeys } from "../utils/case_utils.js";
|
|
20
21
|
import { AuthHandler } from "./auth_handler.js";
|
|
21
22
|
const TOOLSET_AUTH_CREDENTIAL_ID_PREFIX = "_adk_toolset_auth_";
|
|
22
23
|
async function storeAuthAndCollectResumeTargets(events, authFcIds, authResponses, state) {
|
|
@@ -25,17 +26,15 @@ async function storeAuthAndCollectResumeTargets(events, authFcIds, authResponses
|
|
|
25
26
|
const eventFunctionCalls = getFunctionCalls(event);
|
|
26
27
|
for (const functionCall of eventFunctionCalls) {
|
|
27
28
|
if (functionCall.id && authFcIds.has(functionCall.id) && functionCall.name === REQUEST_EUC_FUNCTION_CALL_NAME) {
|
|
28
|
-
const args = functionCall.args;
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
const args = camelCaseKeys(functionCall.args);
|
|
30
|
+
const authConfig = args == null ? void 0 : args.authConfig;
|
|
31
|
+
if (authConfig) {
|
|
32
|
+
requestedAuthConfigById[functionCall.id] = authConfig;
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
for (const fcId of authFcIds) {
|
|
36
|
-
if (!(fcId in authResponses)) {
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
38
|
const authConfig = authResponses[fcId];
|
|
40
39
|
const requestedAuthConfig = requestedAuthConfigById[fcId];
|
|
41
40
|
if (requestedAuthConfig && requestedAuthConfig.credentialKey) {
|
|
@@ -53,12 +52,15 @@ async function storeAuthAndCollectResumeTargets(events, authFcIds, authResponses
|
|
|
53
52
|
const eventFunctionCalls = getFunctionCalls(event);
|
|
54
53
|
for (const functionCall of eventFunctionCalls) {
|
|
55
54
|
if (functionCall.id === fcId && functionCall.name === REQUEST_EUC_FUNCTION_CALL_NAME) {
|
|
56
|
-
const args =
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
const args = camelCaseKeys(
|
|
56
|
+
functionCall.args
|
|
57
|
+
);
|
|
58
|
+
const functionCallId = args == null ? void 0 : args.functionCallId;
|
|
59
|
+
if (functionCallId) {
|
|
60
|
+
if (functionCallId.startsWith(TOOLSET_AUTH_CREDENTIAL_ID_PREFIX)) {
|
|
59
61
|
continue;
|
|
60
62
|
}
|
|
61
|
-
toolsToResume.add(
|
|
63
|
+
toolsToResume.add(functionCallId);
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
}
|
|
@@ -55,7 +55,11 @@ class OAuth2DiscoveryManager {
|
|
|
55
55
|
method: "GET",
|
|
56
56
|
headers: {
|
|
57
57
|
Accept: "application/json"
|
|
58
|
-
}
|
|
58
|
+
},
|
|
59
|
+
// Never follow redirects: validateDiscoveryUrl only checks the
|
|
60
|
+
// initial URL, so following a 3xx would let a validated host
|
|
61
|
+
// redirect discovery to a private/cloud-metadata address (CWE-918).
|
|
62
|
+
redirect: "error"
|
|
59
63
|
});
|
|
60
64
|
if (!response.ok) {
|
|
61
65
|
continue;
|
|
@@ -103,7 +107,11 @@ class OAuth2DiscoveryManager {
|
|
|
103
107
|
method: "GET",
|
|
104
108
|
headers: {
|
|
105
109
|
Accept: "application/json"
|
|
106
|
-
}
|
|
110
|
+
},
|
|
111
|
+
// Never follow redirects: validateDiscoveryUrl only checks the
|
|
112
|
+
// initial URL, so following a 3xx would let a validated host
|
|
113
|
+
// redirect discovery to a private/cloud-metadata address (CWE-918).
|
|
114
|
+
redirect: "error"
|
|
107
115
|
});
|
|
108
116
|
if (!response.ok) {
|
|
109
117
|
return void 0;
|
|
@@ -143,7 +151,7 @@ function validateDiscoveryUrl(urlStr) {
|
|
|
143
151
|
return false;
|
|
144
152
|
}
|
|
145
153
|
const host = normaliseHostname(url.hostname.toLowerCase());
|
|
146
|
-
if (host === "localhost" || host === "
|
|
154
|
+
if (host === "localhost" || host === "metadata.google.internal" || host === "metadata.goog" || host.startsWith("127.") || host === "[::1]" || host === "[::]" || host === "0.0.0.0" || host.startsWith("10.") || host.startsWith("192.168.") || host.startsWith("169.254.")) {
|
|
147
155
|
logger.warn(`Unsafe host for discovery URL: ${host}`);
|
|
148
156
|
return false;
|
|
149
157
|
}
|
|
@@ -176,5 +184,7 @@ function validateDiscoveryUrl(urlStr) {
|
|
|
176
184
|
export {
|
|
177
185
|
AuthorizationServerMetadataSchema,
|
|
178
186
|
OAuth2DiscoveryManager,
|
|
179
|
-
ProtectedResourceMetadataSchema
|
|
187
|
+
ProtectedResourceMetadataSchema,
|
|
188
|
+
normaliseHostname,
|
|
189
|
+
validateDiscoveryUrl
|
|
180
190
|
};
|
|
@@ -6,6 +6,7 @@ const require = topLevelCreateRequire(import.meta.url);
|
|
|
6
6
|
* SPDX-License-Identifier: Apache-2.0
|
|
7
7
|
*/
|
|
8
8
|
import { logger } from "../../utils/logger.js";
|
|
9
|
+
import { validateDiscoveryUrl } from "./oauth2_discovery.js";
|
|
9
10
|
function getTokenEndpoint(authScheme) {
|
|
10
11
|
if (authScheme.type === "openIdConnect" && authScheme.tokenEndpoint) {
|
|
11
12
|
return authScheme.tokenEndpoint;
|
|
@@ -20,13 +21,23 @@ function getTokenEndpoint(authScheme) {
|
|
|
20
21
|
return void 0;
|
|
21
22
|
}
|
|
22
23
|
async function fetchOAuth2Tokens(endpoint, body) {
|
|
24
|
+
if (!validateDiscoveryUrl(endpoint)) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`SSRF protection: OAuth2 token endpoint '${endpoint}' is not allowed. Must use HTTPS and must not target private/loopback/cloud-metadata addresses.`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
23
29
|
try {
|
|
24
30
|
const response = await fetch(endpoint, {
|
|
25
31
|
method: "POST",
|
|
26
32
|
headers: {
|
|
27
33
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
28
34
|
},
|
|
29
|
-
body: body.toString()
|
|
35
|
+
body: body.toString(),
|
|
36
|
+
// Never follow redirects: the SSRF blocklist only validates `endpoint`,
|
|
37
|
+
// so a validated host that responds with a 3xx could otherwise redirect
|
|
38
|
+
// this credential-bearing POST (client_secret/refresh_token) to a
|
|
39
|
+
// private/cloud-metadata address (CWE-918).
|
|
40
|
+
redirect: "error"
|
|
30
41
|
});
|
|
31
42
|
if (!response.ok) {
|
|
32
43
|
throw new Error(`Token request failed with status ${response.status}`);
|
|
@@ -70,7 +70,7 @@ class CodeExecutorContext {
|
|
|
70
70
|
* @return A list of input files in the code executor context.
|
|
71
71
|
*/
|
|
72
72
|
getInputFiles() {
|
|
73
|
-
if (!
|
|
73
|
+
if (!this.sessionState.has(INPUT_FILE_KEY)) {
|
|
74
74
|
return [];
|
|
75
75
|
}
|
|
76
76
|
return this.sessionState.get(INPUT_FILE_KEY);
|
|
@@ -80,13 +80,13 @@ class CodeExecutorContext {
|
|
|
80
80
|
* @param inputFiles The input files to add to the session state.
|
|
81
81
|
*/
|
|
82
82
|
addInputFiles(inputFiles) {
|
|
83
|
-
if (!
|
|
83
|
+
if (!this.sessionState.has(INPUT_FILE_KEY)) {
|
|
84
84
|
this.sessionState.set(INPUT_FILE_KEY, []);
|
|
85
85
|
}
|
|
86
86
|
this.sessionState.get(INPUT_FILE_KEY).push(...inputFiles);
|
|
87
87
|
}
|
|
88
88
|
clearInputFiles() {
|
|
89
|
-
if (
|
|
89
|
+
if (this.sessionState.has(INPUT_FILE_KEY)) {
|
|
90
90
|
this.sessionState.set(INPUT_FILE_KEY, []);
|
|
91
91
|
}
|
|
92
92
|
if (PROCESSED_FILE_NAMES_KEY in this.context) {
|
|
@@ -99,7 +99,7 @@ class CodeExecutorContext {
|
|
|
99
99
|
* @return The error count for the given invocation ID.
|
|
100
100
|
*/
|
|
101
101
|
getErrorCount(invocationId) {
|
|
102
|
-
if (!
|
|
102
|
+
if (!this.sessionState.has(ERROR_COUNT_KEY)) {
|
|
103
103
|
return 0;
|
|
104
104
|
}
|
|
105
105
|
return this.sessionState.get(ERROR_COUNT_KEY)[invocationId] || 0;
|
|
@@ -109,7 +109,7 @@ class CodeExecutorContext {
|
|
|
109
109
|
* @param invocationId The invocation ID to increment the error count for.
|
|
110
110
|
*/
|
|
111
111
|
incrementErrorCount(invocationId) {
|
|
112
|
-
if (!
|
|
112
|
+
if (!this.sessionState.has(ERROR_COUNT_KEY)) {
|
|
113
113
|
this.sessionState.set(ERROR_COUNT_KEY, {});
|
|
114
114
|
}
|
|
115
115
|
this.sessionState.get(ERROR_COUNT_KEY)[invocationId] = this.getErrorCount(invocationId) + 1;
|
|
@@ -119,7 +119,7 @@ class CodeExecutorContext {
|
|
|
119
119
|
* @param invocationId The invocation ID to reset the error count for.
|
|
120
120
|
*/
|
|
121
121
|
resetErrorCount(invocationId) {
|
|
122
|
-
if (!
|
|
122
|
+
if (!this.sessionState.has(ERROR_COUNT_KEY)) {
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
125
|
const errorCounts = this.sessionState.get(ERROR_COUNT_KEY);
|
|
@@ -141,7 +141,7 @@ class CodeExecutorContext {
|
|
|
141
141
|
resultStdout,
|
|
142
142
|
resultStderr
|
|
143
143
|
}) {
|
|
144
|
-
if (!
|
|
144
|
+
if (!this.sessionState.has(CODE_EXECUTION_RESULTS_KEY)) {
|
|
145
145
|
this.sessionState.set(CODE_EXECUTION_RESULTS_KEY, {});
|
|
146
146
|
}
|
|
147
147
|
const codeExecutionResults = this.sessionState.get(
|