@google/adk 2.4.0 → 2.5.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 +17 -2
- package/dist/cjs/a2a/a2a_remote_agent_utils.js +8 -4
- package/dist/cjs/a2a/agent_card.js +5 -81
- package/dist/cjs/a2a/agent_to_a2a.js +7 -0
- package/dist/cjs/a2a/event_converter_utils.js +10 -3
- package/dist/cjs/agents/agent_engine_client.js +282 -55
- package/dist/cjs/agents/base_agent.js +111 -68
- package/dist/cjs/agents/functions.js +62 -85
- package/dist/cjs/agents/instructions.js +7 -6
- package/dist/cjs/agents/invocation_context.js +2 -2
- package/dist/cjs/agents/llm_agent.js +105 -95
- package/dist/cjs/agents/processors/content_processor_utils.js +42 -15
- package/dist/cjs/agents/processors/content_request_processor.js +28 -11
- package/dist/cjs/agents/processors/context_compactor_request_processor.js +5 -1
- package/dist/cjs/agents/processors/instructions_llm_request_processor.js +1 -1
- package/dist/cjs/agents/processors/nl_planning_processor.js +2 -1
- package/dist/cjs/artifacts/file_artifact_service.js +1 -1
- package/dist/cjs/cli/cli_eval.js +884 -17
- package/dist/cjs/cli/utils/cleanup.js +84 -0
- package/dist/cjs/cli/utils/envs.js +33 -2
- package/dist/cjs/cli/utils/evals.js +75 -8
- package/dist/cjs/cli/utils/logs.js +128 -9
- package/dist/cjs/cli/utils/path_validation.js +83 -0
- package/dist/cjs/code_executors/container_code_executor.js +158 -36
- package/dist/cjs/common.js +50 -12
- package/dist/cjs/context/compaction_utils.js +19 -0
- package/dist/cjs/events/event.js +7 -3
- package/dist/cjs/features/feature_registry.js +5 -0
- package/dist/cjs/index.js +29 -14
- package/dist/cjs/models/google_llm.js +33 -2
- package/dist/cjs/models/interactions_utils.js +3 -0
- package/dist/cjs/plugins/base_plugin.js +45 -21
- package/dist/cjs/plugins/plugin_manager.js +27 -0
- package/dist/cjs/runner/runner.js +306 -189
- package/dist/cjs/sessions/base_session_service.js +1 -4
- package/dist/cjs/sessions/database_session_service.js +191 -19
- package/dist/cjs/sessions/db/operations.js +70 -1
- package/dist/cjs/sessions/db/schema.js +4 -0
- package/dist/cjs/sessions/in_memory_session_service.js +2 -2
- package/dist/cjs/sessions/vertex_ai_session_service.js +11 -3
- package/dist/cjs/skills/loader.js +29 -28
- package/dist/cjs/telemetry/api/instrumentation.js +632 -0
- package/dist/cjs/telemetry/api/internal/common/accumulators.js +169 -0
- package/dist/cjs/telemetry/api/internal/common/attributes.js +131 -0
- package/dist/cjs/telemetry/api/internal/common/config.js +159 -0
- package/dist/cjs/telemetry/api/internal/common/error.js +98 -0
- package/dist/cjs/telemetry/api/internal/common/finish_reason.js +63 -0
- package/dist/cjs/telemetry/api/internal/common/genai_messages.js +217 -0
- package/dist/cjs/telemetry/api/internal/common/http_exchange.js +169 -0
- package/dist/cjs/telemetry/api/internal/common/provider_name.js +87 -0
- package/dist/cjs/telemetry/api/internal/common/redaction.js +148 -0
- package/dist/cjs/telemetry/api/internal/common/serialization.js +58 -0
- package/dist/cjs/telemetry/api/internal/common/token_usage.js +118 -0
- package/dist/cjs/telemetry/api/internal/logs/inference.js +50 -0
- package/dist/cjs/telemetry/api/internal/logs/logger.js +46 -0
- package/dist/cjs/telemetry/api/internal/logs/mcp.js +141 -0
- package/dist/cjs/telemetry/api/internal/metrics/agent.js +128 -0
- package/dist/cjs/telemetry/api/internal/metrics/inference_start_hook.js +56 -0
- package/dist/cjs/telemetry/api/internal/metrics/meters.js +189 -0
- package/dist/cjs/telemetry/api/internal/metrics/tool.js +147 -0
- package/dist/cjs/telemetry/api/internal/metrics/workflow.js +132 -0
- package/dist/cjs/telemetry/api/internal/trace/agent.js +52 -0
- package/dist/cjs/telemetry/api/internal/trace/compaction.js +78 -0
- package/dist/cjs/telemetry/api/internal/trace/inference.js +132 -0
- package/dist/cjs/telemetry/api/internal/trace/live.js +52 -0
- package/dist/cjs/telemetry/api/internal/trace/node.js +73 -0
- package/dist/cjs/telemetry/api/internal/trace/propagation.js +67 -0
- package/dist/cjs/telemetry/api/internal/trace/tool.js +122 -0
- package/dist/cjs/telemetry/api/internal/trace/tracer.js +77 -0
- package/dist/cjs/telemetry/api/internal/trace/workflow.js +77 -0
- package/dist/cjs/telemetry/export/agent_engine.js +90 -0
- package/dist/cjs/telemetry/export/agent_runtime.js +73 -0
- package/dist/cjs/telemetry/export/google_cloud.js +763 -0
- package/dist/cjs/telemetry/export/request_driven_metric_reader.js +303 -0
- package/dist/cjs/telemetry/{setup.js → export/setup.js} +72 -5
- package/dist/cjs/tools/agent_tool.js +9 -1
- package/dist/cjs/tools/application_integration_tool/application_integration_toolset.js +22 -34
- package/dist/cjs/tools/application_integration_tool/clients/connections_client.js +60 -20
- package/dist/cjs/tools/application_integration_tool/clients/integration_client.js +26 -10
- package/dist/cjs/tools/application_integration_tool/integration_connector_tool.js +14 -23
- package/dist/cjs/tools/base_toolset.js +1 -1
- package/dist/cjs/tools/computer_use/base_computer.js +125 -0
- package/dist/cjs/tools/computer_use/computer_use_actions.js +502 -0
- package/dist/cjs/tools/computer_use/computer_use_tool.js +244 -0
- package/dist/cjs/tools/computer_use/computer_use_toolset.js +360 -0
- package/dist/cjs/tools/function_tool.js +15 -5
- package/dist/cjs/tools/google_api_tool/google_api_toolset.js +3 -2
- package/dist/cjs/tools/google_api_tool/googleapi_to_openapi_converter.js +3 -1
- package/dist/cjs/tools/load_artifacts_tool.js +15 -5
- package/dist/cjs/tools/load_memory_tool.js +2 -5
- package/dist/cjs/tools/mcp/mcp_session_manager.js +23 -3
- package/dist/cjs/tools/mcp/mcp_tool.js +7 -3
- package/dist/cjs/tools/mcp/mcp_toolset.js +18 -6
- package/dist/cjs/tools/openapi_tool/auth/auth_helpers.js +30 -29
- package/dist/cjs/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.js +2 -2
- package/dist/cjs/tools/openapi_tool/rest_api_tool.js +45 -14
- package/dist/cjs/tools/skill/load_skill_resource_tool.js +7 -0
- package/dist/cjs/tools/skill/load_skill_tool.js +3 -0
- package/dist/cjs/tools/skill/run_skill_script_tool.js +12 -2
- package/dist/cjs/tools/toolbox_toolset.js +47 -28
- package/dist/cjs/utils/async_queue.js +37 -3
- package/dist/cjs/utils/client_labels.js +9 -11
- package/dist/cjs/utils/env_aware_utils.js +13 -7
- package/dist/cjs/utils/error_utils.js +40 -2
- package/dist/cjs/utils/failover_utils.js +10 -9
- package/dist/cjs/utils/gemini_schema_util.js +125 -12
- package/dist/cjs/utils/id_provider.js +63 -0
- package/dist/cjs/utils/model_name.js +15 -0
- package/dist/cjs/utils/simple_zod_to_json.js +13 -31
- package/dist/cjs/utils/ssrf_guard.js +46 -16
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/index.js +2 -0
- package/dist/cjs/workflow/node_runner.js +24 -80
- package/dist/cjs/workflow/nodes/parallel_worker.js +18 -7
- package/dist/cjs/workflow/run_llm_agent_as_node.js +19 -14
- package/dist/cjs/workflow/utils/retry_utils.js +2 -2
- package/dist/cjs/workflow/workflow.js +12 -12
- package/dist/esm/a2a/a2a_remote_agent.js +23 -3
- package/dist/esm/a2a/a2a_remote_agent_utils.js +8 -4
- package/dist/esm/a2a/agent_card.js +5 -83
- package/dist/esm/a2a/agent_to_a2a.js +7 -0
- package/dist/esm/a2a/event_converter_utils.js +10 -3
- package/dist/esm/agents/agent_engine_client.js +293 -55
- package/dist/esm/agents/base_agent.js +111 -72
- package/dist/esm/agents/functions.js +67 -89
- package/dist/esm/agents/instructions.js +7 -6
- package/dist/esm/agents/invocation_context.js +2 -2
- package/dist/esm/agents/llm_agent.js +111 -100
- package/dist/esm/agents/processors/content_processor_utils.js +42 -15
- package/dist/esm/agents/processors/content_request_processor.js +28 -11
- package/dist/esm/agents/processors/context_compactor_request_processor.js +5 -1
- package/dist/esm/agents/processors/instructions_llm_request_processor.js +1 -1
- package/dist/esm/agents/processors/nl_planning_processor.js +2 -1
- package/dist/esm/artifacts/file_artifact_service.js +1 -1
- package/dist/esm/cli/cli_eval.js +880 -17
- package/dist/esm/cli/utils/cleanup.js +56 -0
- package/dist/esm/cli/utils/envs.js +33 -2
- package/dist/esm/cli/utils/evals.js +74 -8
- package/dist/esm/cli/utils/logs.js +128 -9
- package/dist/esm/cli/utils/path_validation.js +45 -0
- package/dist/esm/code_executors/container_code_executor.js +158 -36
- package/dist/esm/common.js +49 -6
- package/dist/esm/context/compaction_utils.js +19 -0
- package/dist/esm/events/event.js +7 -3
- package/dist/esm/features/feature_registry.js +5 -0
- package/dist/esm/index.js +27 -15
- package/dist/esm/models/google_llm.js +33 -2
- package/dist/esm/models/interactions_utils.js +3 -0
- package/dist/esm/plugins/base_plugin.js +45 -21
- package/dist/esm/plugins/plugin_manager.js +27 -0
- package/dist/esm/runner/runner.js +310 -192
- package/dist/esm/sessions/base_session_service.js +1 -4
- package/dist/esm/sessions/database_session_service.js +191 -19
- package/dist/esm/sessions/db/operations.js +70 -1
- package/dist/esm/sessions/db/schema.js +4 -0
- package/dist/esm/sessions/in_memory_session_service.js +2 -2
- package/dist/esm/sessions/vertex_ai_session_service.js +11 -3
- package/dist/esm/skills/loader.js +29 -28
- package/dist/esm/telemetry/api/instrumentation.js +655 -0
- package/dist/esm/telemetry/api/internal/common/accumulators.js +139 -0
- package/dist/esm/telemetry/api/internal/common/attributes.js +94 -0
- package/dist/esm/telemetry/api/internal/common/config.js +128 -0
- package/dist/esm/telemetry/api/internal/common/error.js +69 -0
- package/dist/esm/telemetry/api/internal/common/finish_reason.js +35 -0
- package/dist/esm/telemetry/api/internal/common/genai_messages.js +188 -0
- package/dist/esm/telemetry/api/internal/common/http_exchange.js +142 -0
- package/dist/esm/telemetry/api/internal/common/provider_name.js +59 -0
- package/dist/esm/telemetry/api/internal/common/redaction.js +121 -0
- package/dist/esm/telemetry/api/internal/common/serialization.js +30 -0
- package/dist/esm/telemetry/api/internal/common/token_usage.js +85 -0
- package/dist/esm/telemetry/api/internal/logs/inference.js +23 -0
- package/dist/esm/telemetry/api/internal/logs/logger.js +19 -0
- package/dist/esm/telemetry/api/internal/logs/mcp.js +113 -0
- package/dist/esm/telemetry/api/internal/metrics/agent.js +107 -0
- package/dist/esm/telemetry/api/internal/metrics/inference_start_hook.js +29 -0
- package/dist/esm/telemetry/api/internal/metrics/meters.js +165 -0
- package/dist/esm/telemetry/api/internal/metrics/tool.js +119 -0
- package/dist/esm/telemetry/api/internal/metrics/workflow.js +112 -0
- package/dist/esm/telemetry/api/internal/trace/agent.js +25 -0
- package/dist/esm/telemetry/api/internal/trace/compaction.js +50 -0
- package/dist/esm/telemetry/api/internal/trace/inference.js +107 -0
- package/dist/esm/telemetry/api/internal/trace/live.js +28 -0
- package/dist/esm/telemetry/api/internal/trace/node.js +44 -0
- package/dist/esm/telemetry/api/internal/trace/propagation.js +39 -0
- package/dist/esm/telemetry/api/internal/trace/tool.js +96 -0
- package/dist/esm/telemetry/api/internal/trace/tracer.js +52 -0
- package/dist/esm/telemetry/api/internal/trace/workflow.js +54 -0
- package/dist/esm/telemetry/export/agent_engine.js +67 -0
- package/dist/esm/telemetry/export/agent_runtime.js +46 -0
- package/dist/esm/telemetry/export/google_cloud.js +733 -0
- package/dist/esm/telemetry/export/request_driven_metric_reader.js +276 -0
- package/dist/esm/telemetry/export/setup.js +160 -0
- package/dist/esm/tools/agent_tool.js +9 -1
- package/dist/esm/tools/application_integration_tool/application_integration_toolset.js +23 -35
- package/dist/esm/tools/application_integration_tool/clients/connections_client.js +64 -21
- package/dist/esm/tools/application_integration_tool/clients/integration_client.js +26 -10
- package/dist/esm/tools/application_integration_tool/integration_connector_tool.js +14 -23
- package/dist/esm/tools/base_toolset.js +1 -1
- package/dist/esm/tools/computer_use/base_computer.js +99 -0
- package/dist/esm/tools/computer_use/computer_use_actions.js +477 -0
- package/dist/esm/tools/computer_use/computer_use_tool.js +217 -0
- package/dist/esm/tools/computer_use/computer_use_toolset.js +344 -0
- package/dist/esm/tools/function_tool.js +15 -5
- package/dist/esm/tools/google_api_tool/google_api_toolset.js +3 -2
- package/dist/esm/tools/google_api_tool/googleapi_to_openapi_converter.js +3 -1
- package/dist/esm/tools/load_artifacts_tool.js +15 -5
- package/dist/esm/tools/load_memory_tool.js +2 -5
- package/dist/esm/tools/mcp/mcp_session_manager.js +23 -3
- package/dist/esm/tools/mcp/mcp_tool.js +7 -3
- package/dist/esm/tools/mcp/mcp_toolset.js +18 -6
- package/dist/esm/tools/openapi_tool/auth/auth_helpers.js +27 -26
- package/dist/esm/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.js +2 -2
- package/dist/esm/tools/openapi_tool/rest_api_tool.js +45 -14
- package/dist/esm/tools/skill/load_skill_resource_tool.js +7 -0
- package/dist/esm/tools/skill/load_skill_tool.js +3 -0
- package/dist/esm/tools/skill/run_skill_script_tool.js +12 -2
- package/dist/esm/tools/toolbox_toolset.js +47 -28
- package/dist/esm/utils/async_queue.js +37 -3
- package/dist/esm/utils/client_labels.js +9 -11
- package/dist/esm/utils/env_aware_utils.js +12 -7
- package/dist/esm/utils/error_utils.js +37 -1
- package/dist/esm/utils/failover_utils.js +10 -9
- package/dist/esm/utils/gemini_schema_util.js +124 -11
- package/dist/esm/utils/id_provider.js +33 -0
- package/dist/esm/utils/model_name.js +14 -0
- package/dist/esm/utils/simple_zod_to_json.js +13 -31
- package/dist/esm/utils/ssrf_guard.js +55 -15
- package/dist/esm/version.js +1 -1
- package/dist/esm/workflow/index.js +2 -1
- package/dist/esm/workflow/node_runner.js +26 -80
- package/dist/esm/workflow/nodes/parallel_worker.js +16 -6
- package/dist/esm/workflow/run_llm_agent_as_node.js +19 -14
- package/dist/esm/workflow/utils/retry_utils.js +2 -2
- package/dist/esm/workflow/workflow.js +12 -12
- package/dist/types/a2a/a2a_remote_agent.d.ts +6 -0
- package/dist/types/a2a/a2a_remote_agent_utils.d.ts +3 -2
- package/dist/types/agents/agent_engine_client.d.ts +121 -3
- package/dist/types/agents/base_agent.d.ts +2 -0
- package/dist/types/agents/processors/content_processor_utils.d.ts +9 -9
- package/dist/types/agents/run_config.d.ts +14 -0
- package/dist/types/cli/cli_eval.d.ts +172 -9
- package/dist/types/cli/utils/cleanup.d.ts +18 -0
- package/dist/types/cli/utils/envs.d.ts +13 -3
- package/dist/types/cli/utils/evals.d.ts +64 -1
- package/dist/types/cli/utils/logs.d.ts +19 -2
- package/dist/types/cli/utils/path_validation.d.ts +30 -0
- package/dist/types/code_executors/container_code_executor.d.ts +49 -8
- package/dist/types/common.d.ts +16 -9
- package/dist/types/context/compaction_utils.d.ts +13 -1
- package/dist/types/events/event.d.ts +3 -0
- package/dist/types/features/feature_registry.d.ts +1 -0
- package/dist/types/index.d.ts +9 -6
- package/dist/types/plugins/base_plugin.d.ts +50 -21
- package/dist/types/plugins/plugin_manager.d.ts +13 -0
- package/dist/types/runner/runner.d.ts +11 -0
- package/dist/types/sessions/base_session_service.d.ts +0 -2
- package/dist/types/sessions/db/operations.d.ts +2 -1
- package/dist/types/sessions/db/schema.d.ts +5 -3
- package/dist/types/telemetry/api/instrumentation.d.ts +259 -0
- package/dist/types/telemetry/api/internal/common/accumulators.d.ts +91 -0
- package/dist/types/telemetry/api/internal/common/attributes.d.ts +90 -0
- package/dist/types/telemetry/api/internal/common/config.d.ts +61 -0
- package/dist/types/telemetry/api/internal/common/error.d.ts +29 -0
- package/dist/types/telemetry/api/internal/common/finish_reason.d.ts +18 -0
- package/dist/types/telemetry/api/internal/common/genai_messages.d.ts +26 -0
- package/dist/types/telemetry/api/internal/common/http_exchange.d.ts +50 -0
- package/dist/types/telemetry/api/internal/common/provider_name.d.ts +16 -0
- package/dist/types/telemetry/api/internal/common/redaction.d.ts +14 -0
- package/dist/types/telemetry/api/internal/common/serialization.d.ts +18 -0
- package/dist/types/telemetry/api/internal/common/token_usage.d.ts +47 -0
- package/dist/types/telemetry/api/internal/logs/inference.d.ts +15 -0
- package/dist/types/telemetry/api/internal/logs/logger.d.ts +13 -0
- package/dist/types/telemetry/api/internal/logs/mcp.d.ts +31 -0
- package/dist/types/telemetry/api/internal/metrics/agent.d.ts +28 -0
- package/dist/types/telemetry/api/internal/metrics/inference_start_hook.d.ts +12 -0
- package/dist/types/telemetry/api/internal/metrics/meters.d.ts +57 -0
- package/dist/types/telemetry/api/internal/metrics/tool.d.ts +44 -0
- package/dist/types/telemetry/api/internal/metrics/workflow.d.ts +32 -0
- package/dist/types/telemetry/api/internal/trace/agent.d.ts +14 -0
- package/dist/types/telemetry/api/internal/trace/compaction.d.ts +20 -0
- package/dist/types/telemetry/api/internal/trace/inference.d.ts +31 -0
- package/dist/types/telemetry/api/internal/trace/live.d.ts +21 -0
- package/dist/types/telemetry/api/internal/trace/node.d.ts +22 -0
- package/dist/types/telemetry/api/internal/trace/propagation.d.ts +22 -0
- package/dist/types/telemetry/api/internal/trace/tool.d.ts +57 -0
- package/dist/types/telemetry/api/internal/trace/tracer.d.ts +31 -0
- package/dist/types/telemetry/api/internal/trace/workflow.d.ts +21 -0
- package/dist/types/telemetry/export/agent_engine.d.ts +23 -0
- package/dist/types/telemetry/export/agent_runtime.d.ts +40 -0
- package/dist/types/telemetry/export/google_cloud.d.ts +189 -0
- package/dist/types/telemetry/export/request_driven_metric_reader.d.ts +144 -0
- package/dist/types/telemetry/{setup.d.ts → export/setup.d.ts} +3 -0
- package/dist/types/tools/agent_tool.d.ts +1 -1
- package/dist/types/tools/application_integration_tool/clients/connections_client.d.ts +13 -4
- package/dist/types/tools/base_toolset.d.ts +1 -1
- package/dist/types/tools/computer_use/base_computer.d.ts +281 -0
- package/dist/types/tools/computer_use/computer_use_actions.d.ts +53 -0
- package/dist/types/tools/computer_use/computer_use_tool.d.ts +108 -0
- package/dist/types/tools/computer_use/computer_use_toolset.d.ts +132 -0
- package/dist/types/tools/google_api_tool/google_api_toolset.d.ts +2 -0
- package/dist/types/tools/load_artifacts_tool.d.ts +5 -1
- package/dist/types/tools/load_memory_tool.d.ts +13 -7
- package/dist/types/tools/mcp/mcp_session_manager.d.ts +16 -0
- package/dist/types/tools/openapi_tool/auth/auth_helpers.d.ts +8 -8
- package/dist/types/tools/openapi_tool/openapi_spec_parser/operation_parser.d.ts +7 -3
- package/dist/types/tools/toolbox_toolset.d.ts +15 -20
- package/dist/types/utils/async_queue.d.ts +14 -0
- package/dist/types/utils/env_aware_utils.d.ts +11 -0
- package/dist/types/utils/error_utils.d.ts +4 -0
- package/dist/types/utils/gemini_schema_util.d.ts +27 -6
- package/dist/types/utils/id_provider.d.ts +43 -0
- package/dist/types/utils/model_name.d.ts +8 -0
- package/dist/types/utils/ssrf_guard.d.ts +2 -0
- package/dist/types/version.d.ts +1 -1
- package/dist/types/workflow/index.d.ts +1 -1
- package/dist/types/workflow/nodes/parallel_worker.d.ts +8 -1
- package/dist/web/index_web.js +86 -88
- package/dist/web/index_web.js.map +4 -4
- package/package.json +13 -15
- package/dist/cjs/telemetry/google_cloud.js +0 -116
- package/dist/cjs/telemetry/tracing.js +0 -393
- package/dist/esm/telemetry/google_cloud.js +0 -99
- package/dist/esm/telemetry/setup.js +0 -88
- package/dist/esm/telemetry/tracing.js +0 -361
- package/dist/types/telemetry/google_cloud.d.ts +0 -9
- package/dist/types/telemetry/tracing.d.ts +0 -143
package/dist/esm/cli/cli_eval.js
CHANGED
|
@@ -37,6 +37,9 @@ import {
|
|
|
37
37
|
isLlmAgent
|
|
38
38
|
} from "../agents/llm_agent.js";
|
|
39
39
|
import { InMemoryArtifactService } from "../artifacts/in_memory_artifact_service.js";
|
|
40
|
+
import { InputValidationError } from "../errors/input_validation_error.js";
|
|
41
|
+
import { NotFoundError } from "../errors/not_found_error.js";
|
|
42
|
+
import { publicSession } from "../events/internal_metadata.js";
|
|
40
43
|
import { Runner } from "../runner/runner.js";
|
|
41
44
|
import { InMemorySessionService } from "../sessions/in_memory_session_service.js";
|
|
42
45
|
import { logger } from "../utils/logger.js";
|
|
@@ -44,6 +47,10 @@ import {
|
|
|
44
47
|
convertSessionToEvalFormat,
|
|
45
48
|
createEmptyState
|
|
46
49
|
} from "./utils/evals.js";
|
|
50
|
+
import {
|
|
51
|
+
isStrictlyInside,
|
|
52
|
+
validatePathSegment
|
|
53
|
+
} from "./utils/path_validation.js";
|
|
47
54
|
const MISSING_EVAL_DEPENDENCIES_MESSAGE = "Eval module is not installed, please install via `pip install google-adk[eval]`.";
|
|
48
55
|
const TOOL_TRAJECTORY_SCORE_KEY = "tool_trajectory_avg_score";
|
|
49
56
|
const RESPONSE_MATCH_SCORE_KEY = "response_match_score";
|
|
@@ -124,8 +131,9 @@ function parseAndGetEvalsToRun(evalSetFilePaths) {
|
|
|
124
131
|
for (const inputEvalSet of evalSetFilePaths) {
|
|
125
132
|
let evalSetFile;
|
|
126
133
|
let evals = [];
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
const hasDrivePrefix = /^[A-Za-z]:[\\/]/.test(inputEvalSet);
|
|
135
|
+
const colonIndex = inputEvalSet.indexOf(":", hasDrivePrefix ? 3 : 0);
|
|
136
|
+
if (colonIndex !== -1) {
|
|
129
137
|
evalSetFile = inputEvalSet.slice(0, colonIndex);
|
|
130
138
|
evals = inputEvalSet.slice(colonIndex + 1).split(",").filter((s) => s.length > 0);
|
|
131
139
|
} else {
|
|
@@ -272,6 +280,23 @@ function evaluateSingleMetric(metric, actualInvocations, expectedInvocations) {
|
|
|
272
280
|
};
|
|
273
281
|
}
|
|
274
282
|
__name(evaluateSingleMetric, "evaluateSingleMetric");
|
|
283
|
+
const MOCK_TOOL_OUTPUT_RESPONSE_KEY = "result";
|
|
284
|
+
const declaredToolResponses = /* @__PURE__ */ new WeakMap();
|
|
285
|
+
function getMockToolResponse(toolUse) {
|
|
286
|
+
const declared = declaredToolResponses.get(toolUse);
|
|
287
|
+
if (declared !== void 0) {
|
|
288
|
+
return declared;
|
|
289
|
+
}
|
|
290
|
+
if (toolUse.mock_tool_output !== void 0) {
|
|
291
|
+
return { [MOCK_TOOL_OUTPUT_RESPONSE_KEY]: toolUse.mock_tool_output };
|
|
292
|
+
}
|
|
293
|
+
return void 0;
|
|
294
|
+
}
|
|
295
|
+
__name(getMockToolResponse, "getMockToolResponse");
|
|
296
|
+
function isEvalEntry(evalCase) {
|
|
297
|
+
return "data" in evalCase && Array.isArray(evalCase.data);
|
|
298
|
+
}
|
|
299
|
+
__name(isEvalEntry, "isEvalEntry");
|
|
275
300
|
function installMockToolOutputCallbacks(agent, interceptor, savedCallbacks) {
|
|
276
301
|
if (isLlmAgent(agent) && !savedCallbacks.has(agent)) {
|
|
277
302
|
savedCallbacks.set(agent, agent.beforeToolCallback);
|
|
@@ -284,7 +309,7 @@ function installMockToolOutputCallbacks(agent, interceptor, savedCallbacks) {
|
|
|
284
309
|
}
|
|
285
310
|
__name(installMockToolOutputCallbacks, "installMockToolOutputCallbacks");
|
|
286
311
|
async function generateActualInvocations(rootAgent, evalCase, resetFunc, sessionService, artifactService) {
|
|
287
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
312
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
288
313
|
if (resetFunc) {
|
|
289
314
|
await resetFunc();
|
|
290
315
|
}
|
|
@@ -306,8 +331,13 @@ async function generateActualInvocations(rootAgent, evalCase, resetFunc, session
|
|
|
306
331
|
const pendingMockToolUses = [];
|
|
307
332
|
for (const turn of evalCase.data) {
|
|
308
333
|
for (const expectedTool of (_g = turn.expected_tool_use) != null ? _g : []) {
|
|
309
|
-
|
|
310
|
-
|
|
334
|
+
const response = getMockToolResponse(expectedTool);
|
|
335
|
+
if (response !== void 0) {
|
|
336
|
+
pendingMockToolUses.push({
|
|
337
|
+
toolName: expectedTool.tool_name,
|
|
338
|
+
toolInput: (_h = expectedTool.tool_input) != null ? _h : {},
|
|
339
|
+
response
|
|
340
|
+
});
|
|
311
341
|
}
|
|
312
342
|
}
|
|
313
343
|
}
|
|
@@ -315,14 +345,11 @@ async function generateActualInvocations(rootAgent, evalCase, resetFunc, session
|
|
|
315
345
|
if (pendingMockToolUses.length > 0) {
|
|
316
346
|
const interceptor = /* @__PURE__ */ __name(({ tool, args }) => {
|
|
317
347
|
const idx = pendingMockToolUses.findIndex(
|
|
318
|
-
(expected) =>
|
|
319
|
-
var _a2;
|
|
320
|
-
return expected.mock_tool_output !== void 0 && tool.name === expected.tool_name && deepEqual(args, (_a2 = expected.tool_input) != null ? _a2 : {});
|
|
321
|
-
}
|
|
348
|
+
(expected) => tool.name === expected.toolName && deepEqual(args, expected.toolInput)
|
|
322
349
|
);
|
|
323
350
|
if (idx !== -1) {
|
|
324
351
|
const [matched] = pendingMockToolUses.splice(idx, 1);
|
|
325
|
-
return
|
|
352
|
+
return matched.response;
|
|
326
353
|
}
|
|
327
354
|
return void 0;
|
|
328
355
|
}, "interceptor");
|
|
@@ -366,27 +393,97 @@ async function generateActualInvocations(rootAgent, evalCase, resetFunc, session
|
|
|
366
393
|
reference: ""
|
|
367
394
|
});
|
|
368
395
|
}
|
|
369
|
-
return { actualInvocations, sessionId, userId };
|
|
396
|
+
return { actualInvocations, sessionId, userId, recordedSession };
|
|
370
397
|
}
|
|
371
398
|
__name(generateActualInvocations, "generateActualInvocations");
|
|
399
|
+
function evalCaseToEvalEntry(evalCase) {
|
|
400
|
+
if (isEvalEntry(evalCase)) {
|
|
401
|
+
return evalCase;
|
|
402
|
+
}
|
|
403
|
+
const structured = evalCase;
|
|
404
|
+
const data = structured.conversation.map((invocation) => {
|
|
405
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
406
|
+
const query = (_c = (_b = (_a = invocation.userContent) == null ? void 0 : _a.parts) == null ? void 0 : _b.map((p) => {
|
|
407
|
+
var _a2;
|
|
408
|
+
return (_a2 = p.text) != null ? _a2 : "";
|
|
409
|
+
}).join("")) != null ? _c : "";
|
|
410
|
+
const reference = (_f = (_e = (_d = invocation.finalResponse) == null ? void 0 : _d.parts) == null ? void 0 : _e.map((p) => {
|
|
411
|
+
var _a2;
|
|
412
|
+
return (_a2 = p.text) != null ? _a2 : "";
|
|
413
|
+
}).join("")) != null ? _f : "";
|
|
414
|
+
const toolResponsesById = /* @__PURE__ */ new Map();
|
|
415
|
+
for (const toolResponse of (_h = (_g = invocation.intermediateData) == null ? void 0 : _g.toolResponses) != null ? _h : []) {
|
|
416
|
+
if (toolResponse.id) {
|
|
417
|
+
toolResponsesById.set(toolResponse.id, toolResponse);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
const expected_tool_use = ((_j = (_i = invocation.intermediateData) == null ? void 0 : _i.toolUses) != null ? _j : []).map((fc) => {
|
|
421
|
+
var _a2, _b2;
|
|
422
|
+
const toolUse = {
|
|
423
|
+
tool_name: (_a2 = fc.name) != null ? _a2 : "",
|
|
424
|
+
tool_input: (_b2 = fc.args) != null ? _b2 : {}
|
|
425
|
+
};
|
|
426
|
+
const toolResponse = fc.id ? toolResponsesById.get(fc.id) : void 0;
|
|
427
|
+
if ((toolResponse == null ? void 0 : toolResponse.response) !== void 0) {
|
|
428
|
+
declaredToolResponses.set(toolUse, toolResponse.response);
|
|
429
|
+
}
|
|
430
|
+
return toolUse;
|
|
431
|
+
});
|
|
432
|
+
const expected_intermediate_agent_responses = ((_l = (_k = invocation.intermediateData) == null ? void 0 : _k.intermediateResponses) != null ? _l : []).map(
|
|
433
|
+
([author, parts]) => [author, parts]
|
|
434
|
+
);
|
|
435
|
+
return {
|
|
436
|
+
query,
|
|
437
|
+
expected_tool_use,
|
|
438
|
+
expected_intermediate_agent_responses,
|
|
439
|
+
reference
|
|
440
|
+
};
|
|
441
|
+
});
|
|
442
|
+
const sessionInput = structured.sessionInput;
|
|
443
|
+
return {
|
|
444
|
+
name: structured.evalId,
|
|
445
|
+
data,
|
|
446
|
+
...sessionInput ? {
|
|
447
|
+
initial_session: {
|
|
448
|
+
...sessionInput.appName ? { app_name: sessionInput.appName } : {},
|
|
449
|
+
...sessionInput.userId ? { user_id: sessionInput.userId } : {},
|
|
450
|
+
state: sessionInput.state
|
|
451
|
+
}
|
|
452
|
+
} : {}
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
__name(evalCaseToEvalEntry, "evalCaseToEvalEntry");
|
|
372
456
|
function resolveEvalCasesForSet(evalSetId, entries) {
|
|
373
457
|
if (entries.length > 0 && typeof entries[0] === "string") {
|
|
374
458
|
const filterNames = entries;
|
|
375
|
-
const
|
|
459
|
+
const rawFileData = JSON.parse(
|
|
376
460
|
fs.readFileSync(evalSetId, "utf-8")
|
|
377
461
|
);
|
|
378
|
-
|
|
462
|
+
if (Array.isArray(rawFileData)) {
|
|
463
|
+
return rawFileData.filter(
|
|
464
|
+
(e) => filterNames.includes(e.name)
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
const loadedSet = loadEvalSetFromFile(evalSetId, evalSetId);
|
|
468
|
+
return loadedSet.evalCases.filter((e) => filterNames.includes(e.evalId)).map(evalCaseToEvalEntry);
|
|
379
469
|
}
|
|
380
470
|
if (entries.length === 0 && fs.existsSync(evalSetId) && fs.statSync(evalSetId).isFile()) {
|
|
381
|
-
|
|
471
|
+
const rawFileData = JSON.parse(
|
|
472
|
+
fs.readFileSync(evalSetId, "utf-8")
|
|
473
|
+
);
|
|
474
|
+
if (Array.isArray(rawFileData)) {
|
|
475
|
+
return rawFileData;
|
|
476
|
+
}
|
|
477
|
+
const loadedSet = loadEvalSetFromFile(evalSetId, evalSetId);
|
|
478
|
+
return loadedSet.evalCases.map(evalCaseToEvalEntry);
|
|
382
479
|
}
|
|
383
|
-
return entries;
|
|
480
|
+
return entries.map(evalCaseToEvalEntry);
|
|
384
481
|
}
|
|
385
482
|
__name(resolveEvalCasesForSet, "resolveEvalCasesForSet");
|
|
386
483
|
function printCaseDetailedResults(result) {
|
|
387
484
|
var _a;
|
|
388
485
|
logger.info(
|
|
389
|
-
`Eval result for ${result.
|
|
486
|
+
`Eval result for ${result.eval_set_id}:${result.eval_id}: ${EvalStatus[result.final_eval_status]}`
|
|
390
487
|
);
|
|
391
488
|
for (const metricResult of result.overall_eval_metric_results) {
|
|
392
489
|
logger.info(
|
|
@@ -435,7 +532,7 @@ async function* runEvals(optionsOrMap, rootAgentArg, resetFuncArg, evalMetricsAr
|
|
|
435
532
|
const evalCases = resolveEvalCasesForSet(evalSetId, rawEntries);
|
|
436
533
|
for (const evalCase of evalCases) {
|
|
437
534
|
const evalName = evalCase.name;
|
|
438
|
-
const { actualInvocations, sessionId, userId } = await generateActualInvocations(
|
|
535
|
+
const { actualInvocations, sessionId, userId, recordedSession } = await generateActualInvocations(
|
|
439
536
|
rootAgent,
|
|
440
537
|
evalCase,
|
|
441
538
|
resetFunc,
|
|
@@ -478,12 +575,14 @@ async function* runEvals(optionsOrMap, rootAgentArg, resetFuncArg, evalMetricsAr
|
|
|
478
575
|
}
|
|
479
576
|
const result = {
|
|
480
577
|
eval_set_file: evalSetId,
|
|
578
|
+
eval_set_id: evalSetId,
|
|
481
579
|
eval_id: evalName,
|
|
482
580
|
final_eval_status: finalEvalStatus,
|
|
483
581
|
eval_metric_results: evalMetricResultsPairs,
|
|
484
582
|
overall_eval_metric_results: overallEvalMetricResults,
|
|
485
583
|
eval_metric_result_per_invocation: perInvocationMap,
|
|
486
584
|
session_id: sessionId,
|
|
585
|
+
session_details: recordedSession && publicSession(recordedSession),
|
|
487
586
|
user_id: userId
|
|
488
587
|
};
|
|
489
588
|
if (printDetailedResults) {
|
|
@@ -494,17 +593,781 @@ async function* runEvals(optionsOrMap, rootAgentArg, resetFuncArg, evalMetricsAr
|
|
|
494
593
|
}
|
|
495
594
|
}
|
|
496
595
|
__name(runEvals, "runEvals");
|
|
596
|
+
const ADK_EVAL_HISTORY_DIR = ".adk/eval_history";
|
|
597
|
+
const EVAL_SET_RESULT_FILE_EXTENSION = ".evalset_result.json";
|
|
598
|
+
function sanitizeEvalSetResultName(evalSetResultName) {
|
|
599
|
+
return evalSetResultName.replace(/\//g, "_");
|
|
600
|
+
}
|
|
601
|
+
__name(sanitizeEvalSetResultName, "sanitizeEvalSetResultName");
|
|
602
|
+
function toRunEvalResult(caseResult, fallbackEvalSetId) {
|
|
603
|
+
const record = caseResult;
|
|
604
|
+
const evalSetFile = typeof record.evalSetFile === "string" ? record.evalSetFile : typeof record.eval_set_file === "string" ? record.eval_set_file : void 0;
|
|
605
|
+
const evalSetId = typeof record.evalSetId === "string" ? record.evalSetId : typeof record.eval_set_id === "string" ? record.eval_set_id : fallbackEvalSetId != null ? fallbackEvalSetId : "";
|
|
606
|
+
const evalId = typeof record.evalId === "string" ? record.evalId : typeof record.eval_id === "string" ? record.eval_id : "";
|
|
607
|
+
const finalEvalStatus = typeof record.finalEvalStatus === "number" ? record.finalEvalStatus : typeof record.final_eval_status === "number" ? record.final_eval_status : 3 /* NOT_EVALUATED */;
|
|
608
|
+
const evalMetricResults = Array.isArray(record.evalMetricResults) ? record.evalMetricResults : Array.isArray(record.eval_metric_results) ? record.eval_metric_results : void 0;
|
|
609
|
+
const overallEvalMetricResults = Array.isArray(
|
|
610
|
+
record.overallEvalMetricResults
|
|
611
|
+
) ? record.overallEvalMetricResults : Array.isArray(record.overall_eval_metric_results) ? record.overall_eval_metric_results : [];
|
|
612
|
+
const evalMetricResultPerInvocation = Array.isArray(
|
|
613
|
+
record.evalMetricResultPerInvocation
|
|
614
|
+
) ? record.evalMetricResultPerInvocation : Array.isArray(record.eval_metric_result_per_invocation) ? record.eval_metric_result_per_invocation : [];
|
|
615
|
+
const sessionId = typeof record.sessionId === "string" ? record.sessionId : typeof record.session_id === "string" ? record.session_id : "";
|
|
616
|
+
const rawSessionDetails = record.sessionDetails !== void 0 && record.sessionDetails !== null ? record.sessionDetails : record.session_details !== void 0 && record.session_details !== null ? record.session_details : void 0;
|
|
617
|
+
const sessionDetails = rawSessionDetails && publicSession(rawSessionDetails);
|
|
618
|
+
const userId = typeof record.userId === "string" ? record.userId : typeof record.user_id === "string" ? record.user_id : void 0;
|
|
619
|
+
return {
|
|
620
|
+
...evalSetFile !== void 0 ? { evalSetFile } : {},
|
|
621
|
+
evalSetId,
|
|
622
|
+
evalId,
|
|
623
|
+
finalEvalStatus,
|
|
624
|
+
...evalMetricResults !== void 0 ? { evalMetricResults } : {},
|
|
625
|
+
overallEvalMetricResults,
|
|
626
|
+
evalMetricResultPerInvocation,
|
|
627
|
+
sessionId,
|
|
628
|
+
...sessionDetails !== void 0 ? { sessionDetails } : {},
|
|
629
|
+
...userId !== void 0 ? { userId } : {}
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
__name(toRunEvalResult, "toRunEvalResult");
|
|
633
|
+
function createEvalSetResult({
|
|
634
|
+
appName,
|
|
635
|
+
evalSetId,
|
|
636
|
+
evalCaseResults,
|
|
637
|
+
creationTimestamp = (performance.timeOrigin + performance.now()) / 1e3
|
|
638
|
+
}) {
|
|
639
|
+
const evalSetResultId = `${appName}_${evalSetId}_${creationTimestamp}`;
|
|
640
|
+
const evalSetResultName = sanitizeEvalSetResultName(evalSetResultId);
|
|
641
|
+
return {
|
|
642
|
+
evalSetResultId,
|
|
643
|
+
evalSetResultName,
|
|
644
|
+
evalSetId,
|
|
645
|
+
evalCaseResults: evalCaseResults.map(
|
|
646
|
+
(caseResult) => toRunEvalResult(caseResult, evalSetId)
|
|
647
|
+
),
|
|
648
|
+
creationTimestamp
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
__name(createEvalSetResult, "createEvalSetResult");
|
|
652
|
+
function parseEvalSetResultJson(evalSetResultJson) {
|
|
653
|
+
var _a, _b;
|
|
654
|
+
const decoded = JSON.parse(evalSetResultJson);
|
|
655
|
+
const target = typeof decoded === "string" ? JSON.parse(decoded) : decoded;
|
|
656
|
+
if (typeof target !== "object" || target === null || Array.isArray(target)) {
|
|
657
|
+
throw new Error("Invalid EvalSetResult JSON: expected an object.");
|
|
658
|
+
}
|
|
659
|
+
const record = target;
|
|
660
|
+
const evalSetResultId = typeof record.evalSetResultId === "string" ? record.evalSetResultId : typeof record.eval_set_result_id === "string" ? record.eval_set_result_id : void 0;
|
|
661
|
+
const evalSetId = typeof record.evalSetId === "string" ? record.evalSetId : typeof record.eval_set_id === "string" ? record.eval_set_id : void 0;
|
|
662
|
+
if (!evalSetResultId || !evalSetId) {
|
|
663
|
+
throw new Error(
|
|
664
|
+
"Invalid EvalSetResult JSON: missing evalSetResultId or evalSetId."
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
const evalSetResultName = typeof record.evalSetResultName === "string" ? record.evalSetResultName : typeof record.eval_set_result_name === "string" ? record.eval_set_result_name : sanitizeEvalSetResultName(evalSetResultId);
|
|
668
|
+
const rawCases = (_b = (_a = record.evalCaseResults) != null ? _a : record.eval_case_results) != null ? _b : [];
|
|
669
|
+
if (!Array.isArray(rawCases)) {
|
|
670
|
+
throw new Error(
|
|
671
|
+
"Invalid EvalSetResult JSON: evalCaseResults must be an array."
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
const evalCaseResults = rawCases.map((rawCase) => {
|
|
675
|
+
if (typeof rawCase !== "object" || rawCase === null || Array.isArray(rawCase)) {
|
|
676
|
+
throw new Error(
|
|
677
|
+
"Invalid EvalSetResult JSON: each evalCaseResult must be an object."
|
|
678
|
+
);
|
|
679
|
+
}
|
|
680
|
+
return toRunEvalResult(rawCase, evalSetId);
|
|
681
|
+
});
|
|
682
|
+
const creationTimestamp = typeof record.creationTimestamp === "number" ? record.creationTimestamp : typeof record.creation_timestamp === "number" ? record.creation_timestamp : 0;
|
|
683
|
+
return {
|
|
684
|
+
evalSetResultId,
|
|
685
|
+
evalSetResultName,
|
|
686
|
+
evalSetId,
|
|
687
|
+
evalCaseResults,
|
|
688
|
+
creationTimestamp
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
__name(parseEvalSetResultJson, "parseEvalSetResultJson");
|
|
692
|
+
const _LocalEvalSetResultsManager = class _LocalEvalSetResultsManager {
|
|
693
|
+
constructor(agentsDir) {
|
|
694
|
+
this.agentsDir = agentsDir;
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Creates and saves a new {@link EvalSetResult} for `evalCaseResults`.
|
|
698
|
+
*/
|
|
699
|
+
saveEvalSetResult({
|
|
700
|
+
appName,
|
|
701
|
+
evalSetId,
|
|
702
|
+
evalCaseResults
|
|
703
|
+
}) {
|
|
704
|
+
validatePathSegment(appName, "appName");
|
|
705
|
+
validatePathSegment(evalSetId, "evalSetId");
|
|
706
|
+
const evalSetResult = createEvalSetResult({
|
|
707
|
+
appName,
|
|
708
|
+
evalSetId,
|
|
709
|
+
evalCaseResults
|
|
710
|
+
});
|
|
711
|
+
const appEvalHistoryDir = this.getEvalHistoryDir(appName);
|
|
712
|
+
if (!fs.existsSync(appEvalHistoryDir)) {
|
|
713
|
+
fs.mkdirSync(appEvalHistoryDir, { recursive: true });
|
|
714
|
+
}
|
|
715
|
+
const evalSetResultFilePath = path.join(
|
|
716
|
+
appEvalHistoryDir,
|
|
717
|
+
`${evalSetResult.evalSetResultName}${EVAL_SET_RESULT_FILE_EXTENSION}`
|
|
718
|
+
);
|
|
719
|
+
logger.info(`Writing eval result to file: ${evalSetResultFilePath}`);
|
|
720
|
+
fs.writeFileSync(
|
|
721
|
+
evalSetResultFilePath,
|
|
722
|
+
JSON.stringify(evalSetResult, null, 2),
|
|
723
|
+
"utf-8"
|
|
724
|
+
);
|
|
725
|
+
return evalSetResult;
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Loads an {@link EvalSetResult} by `appName` and `evalSetResultId`.
|
|
729
|
+
*
|
|
730
|
+
* @throws {NotFoundError} If the result file does not exist.
|
|
731
|
+
*/
|
|
732
|
+
getEvalSetResult(appName, evalSetResultId) {
|
|
733
|
+
const appEvalHistoryDir = this.getEvalHistoryDir(appName);
|
|
734
|
+
validatePathSegment(evalSetResultId, "evalSetResultId");
|
|
735
|
+
const filePath = path.resolve(
|
|
736
|
+
appEvalHistoryDir,
|
|
737
|
+
`${evalSetResultId}${EVAL_SET_RESULT_FILE_EXTENSION}`
|
|
738
|
+
);
|
|
739
|
+
if (!isStrictlyInside(appEvalHistoryDir, filePath)) {
|
|
740
|
+
throw new InputValidationError(
|
|
741
|
+
`evalSetResultId '${evalSetResultId}' resolves outside the eval history directory.`
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
if (!fs.existsSync(filePath)) {
|
|
745
|
+
throw new NotFoundError(
|
|
746
|
+
`Eval set result \`${evalSetResultId}\` not found.`
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
750
|
+
return parseEvalSetResultJson(content);
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Lists all saved eval set result IDs for `appName`.
|
|
754
|
+
*/
|
|
755
|
+
listEvalSetResults(appName) {
|
|
756
|
+
const appEvalHistoryDir = this.getEvalHistoryDir(appName);
|
|
757
|
+
if (!fs.existsSync(appEvalHistoryDir)) {
|
|
758
|
+
return [];
|
|
759
|
+
}
|
|
760
|
+
return fs.readdirSync(appEvalHistoryDir).filter((file) => file.endsWith(EVAL_SET_RESULT_FILE_EXTENSION)).map((file) => file.slice(0, -EVAL_SET_RESULT_FILE_EXTENSION.length));
|
|
761
|
+
}
|
|
762
|
+
getEvalHistoryDir(appName) {
|
|
763
|
+
validatePathSegment(appName, "appName");
|
|
764
|
+
const baseDir = path.resolve(this.agentsDir);
|
|
765
|
+
const appDir = path.resolve(baseDir, appName);
|
|
766
|
+
if (!isStrictlyInside(baseDir, appDir)) {
|
|
767
|
+
throw new InputValidationError(
|
|
768
|
+
`appName '${appName}' resolves outside agentsDir.`
|
|
769
|
+
);
|
|
770
|
+
}
|
|
771
|
+
return path.join(appDir, ADK_EVAL_HISTORY_DIR);
|
|
772
|
+
}
|
|
773
|
+
};
|
|
774
|
+
__name(_LocalEvalSetResultsManager, "LocalEvalSetResultsManager");
|
|
775
|
+
let LocalEvalSetResultsManager = _LocalEvalSetResultsManager;
|
|
776
|
+
const EVAL_SET_FILE_EXTENSION = ".evalset.json";
|
|
777
|
+
const VALID_EVAL_ID_PATTERN = /^[a-zA-Z0-9_]+$/;
|
|
778
|
+
function validateEvalId(idName, idValue) {
|
|
779
|
+
if (!VALID_EVAL_ID_PATTERN.test(idValue)) {
|
|
780
|
+
const formattedName = idName.length > 0 ? idName[0].toUpperCase() + idName.slice(1) : idName;
|
|
781
|
+
throw new InputValidationError(
|
|
782
|
+
`Invalid ${idName}. ${formattedName} should have the \`${VALID_EVAL_ID_PATTERN.source}\` format`
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
__name(validateEvalId, "validateEvalId");
|
|
787
|
+
function readCreationTimestamp(record) {
|
|
788
|
+
if (typeof record.creationTimestamp === "number") {
|
|
789
|
+
return record.creationTimestamp;
|
|
790
|
+
}
|
|
791
|
+
if (typeof record.creation_timestamp === "number") {
|
|
792
|
+
return record.creation_timestamp;
|
|
793
|
+
}
|
|
794
|
+
return void 0;
|
|
795
|
+
}
|
|
796
|
+
__name(readCreationTimestamp, "readCreationTimestamp");
|
|
797
|
+
function normalizeContent(raw, defaultRole) {
|
|
798
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
799
|
+
throw new InputValidationError("Invalid Content: expected an object.");
|
|
800
|
+
}
|
|
801
|
+
const record = raw;
|
|
802
|
+
if (record.parts !== void 0 && !Array.isArray(record.parts)) {
|
|
803
|
+
throw new InputValidationError(
|
|
804
|
+
"Invalid Content: parts must be an array when provided."
|
|
805
|
+
);
|
|
806
|
+
}
|
|
807
|
+
const parts = Array.isArray(record.parts) ? record.parts : [];
|
|
808
|
+
const role = typeof record.role === "string" ? record.role : defaultRole !== void 0 ? defaultRole : void 0;
|
|
809
|
+
return {
|
|
810
|
+
parts,
|
|
811
|
+
...role !== void 0 ? { role } : {}
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
__name(normalizeContent, "normalizeContent");
|
|
815
|
+
function normalizeIntermediateData(raw) {
|
|
816
|
+
var _a, _b, _c, _d, _e, _f;
|
|
817
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
818
|
+
throw new InputValidationError(
|
|
819
|
+
"Invalid EvalIntermediateData: expected an object."
|
|
820
|
+
);
|
|
821
|
+
}
|
|
822
|
+
const record = raw;
|
|
823
|
+
const rawToolUses = (_b = (_a = record.toolUses) != null ? _a : record.tool_uses) != null ? _b : [];
|
|
824
|
+
if (!Array.isArray(rawToolUses)) {
|
|
825
|
+
throw new InputValidationError(
|
|
826
|
+
"Invalid EvalIntermediateData: toolUses must be an array."
|
|
827
|
+
);
|
|
828
|
+
}
|
|
829
|
+
const toolUses = rawToolUses.map((tu) => {
|
|
830
|
+
if (typeof tu !== "object" || tu === null || Array.isArray(tu)) {
|
|
831
|
+
throw new InputValidationError(
|
|
832
|
+
"Invalid FunctionCall in toolUses: expected an object."
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
const fc = tu;
|
|
836
|
+
if (fc.name !== void 0 && typeof fc.name !== "string") {
|
|
837
|
+
throw new InputValidationError(
|
|
838
|
+
"Invalid FunctionCall: name must be a string."
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
if (fc.args !== void 0 && (typeof fc.args !== "object" || fc.args === null || Array.isArray(fc.args))) {
|
|
842
|
+
throw new InputValidationError(
|
|
843
|
+
"Invalid FunctionCall: args must be an object."
|
|
844
|
+
);
|
|
845
|
+
}
|
|
846
|
+
return {
|
|
847
|
+
...typeof fc.id === "string" ? { id: fc.id } : {},
|
|
848
|
+
...typeof fc.name === "string" ? { name: fc.name } : {},
|
|
849
|
+
...fc.args !== void 0 ? { args: fc.args } : {}
|
|
850
|
+
};
|
|
851
|
+
});
|
|
852
|
+
const rawToolResponses = (_d = (_c = record.toolResponses) != null ? _c : record.tool_responses) != null ? _d : [];
|
|
853
|
+
if (!Array.isArray(rawToolResponses)) {
|
|
854
|
+
throw new InputValidationError(
|
|
855
|
+
"Invalid EvalIntermediateData: toolResponses must be an array."
|
|
856
|
+
);
|
|
857
|
+
}
|
|
858
|
+
const toolResponses = rawToolResponses.map((tr) => {
|
|
859
|
+
if (typeof tr !== "object" || tr === null || Array.isArray(tr)) {
|
|
860
|
+
throw new InputValidationError(
|
|
861
|
+
"Invalid FunctionResponse in toolResponses: expected an object."
|
|
862
|
+
);
|
|
863
|
+
}
|
|
864
|
+
const fr = tr;
|
|
865
|
+
if (fr.id !== void 0 && typeof fr.id !== "string") {
|
|
866
|
+
throw new InputValidationError(
|
|
867
|
+
"Invalid FunctionResponse: id must be a string."
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
if (fr.name !== void 0 && typeof fr.name !== "string") {
|
|
871
|
+
throw new InputValidationError(
|
|
872
|
+
"Invalid FunctionResponse: name must be a string."
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
if (fr.response !== void 0 && (typeof fr.response !== "object" || fr.response === null || Array.isArray(fr.response))) {
|
|
876
|
+
throw new InputValidationError(
|
|
877
|
+
"Invalid FunctionResponse: response must be an object."
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
return {
|
|
881
|
+
...typeof fr.id === "string" ? { id: fr.id } : {},
|
|
882
|
+
...typeof fr.name === "string" ? { name: fr.name } : {},
|
|
883
|
+
...fr.response !== void 0 ? { response: fr.response } : {}
|
|
884
|
+
};
|
|
885
|
+
});
|
|
886
|
+
const rawIntermediate = (_f = (_e = record.intermediateResponses) != null ? _e : record.intermediate_responses) != null ? _f : [];
|
|
887
|
+
if (!Array.isArray(rawIntermediate)) {
|
|
888
|
+
throw new InputValidationError(
|
|
889
|
+
"Invalid EvalIntermediateData: intermediateResponses must be an array."
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
const intermediateResponses = rawIntermediate.map((entry) => {
|
|
893
|
+
if (!Array.isArray(entry) || entry.length !== 2 || typeof entry[0] !== "string" || !Array.isArray(entry[1])) {
|
|
894
|
+
throw new InputValidationError(
|
|
895
|
+
"Invalid intermediateResponses entry: expected [author, Part[]]."
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
return [entry[0], entry[1]];
|
|
899
|
+
});
|
|
900
|
+
return {
|
|
901
|
+
toolUses,
|
|
902
|
+
...toolResponses.length > 0 ? { toolResponses } : {},
|
|
903
|
+
intermediateResponses
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
__name(normalizeIntermediateData, "normalizeIntermediateData");
|
|
907
|
+
function normalizeInvocation(raw) {
|
|
908
|
+
var _a, _b, _c;
|
|
909
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
910
|
+
throw new InputValidationError(
|
|
911
|
+
"Invalid EvalInvocation: expected an object."
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
const record = raw;
|
|
915
|
+
const rawUserContent = (_a = record.userContent) != null ? _a : record.user_content;
|
|
916
|
+
if (rawUserContent === void 0) {
|
|
917
|
+
throw new InputValidationError(
|
|
918
|
+
"Invalid EvalInvocation: userContent is required."
|
|
919
|
+
);
|
|
920
|
+
}
|
|
921
|
+
const userContent = normalizeContent(rawUserContent);
|
|
922
|
+
const rawFinalResponse = (_b = record.finalResponse) != null ? _b : record.final_response;
|
|
923
|
+
const finalResponse = rawFinalResponse !== void 0 && rawFinalResponse !== null ? normalizeContent(rawFinalResponse) : void 0;
|
|
924
|
+
const rawIntermediateData = (_c = record.intermediateData) != null ? _c : record.intermediate_data;
|
|
925
|
+
const intermediateData = rawIntermediateData !== void 0 && rawIntermediateData !== null ? normalizeIntermediateData(rawIntermediateData) : void 0;
|
|
926
|
+
const invocationId = typeof record.invocationId === "string" ? record.invocationId : typeof record.invocation_id === "string" ? record.invocation_id : void 0;
|
|
927
|
+
const creationTimestamp = readCreationTimestamp(record);
|
|
928
|
+
return {
|
|
929
|
+
...invocationId !== void 0 ? { invocationId } : {},
|
|
930
|
+
userContent,
|
|
931
|
+
...finalResponse !== void 0 ? { finalResponse } : {},
|
|
932
|
+
...intermediateData !== void 0 ? { intermediateData } : {},
|
|
933
|
+
...creationTimestamp !== void 0 ? { creationTimestamp } : {}
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
__name(normalizeInvocation, "normalizeInvocation");
|
|
937
|
+
function normalizeSessionInput(raw) {
|
|
938
|
+
var _a, _b, _c, _d, _e;
|
|
939
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
940
|
+
throw new InputValidationError(
|
|
941
|
+
"Invalid EvalSessionInput: expected an object."
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
const record = raw;
|
|
945
|
+
const rawAppName = (_b = (_a = record.appName) != null ? _a : record.app_name) != null ? _b : "";
|
|
946
|
+
const rawUserId = (_d = (_c = record.userId) != null ? _c : record.user_id) != null ? _d : "";
|
|
947
|
+
const rawState = (_e = record.state) != null ? _e : {};
|
|
948
|
+
if (typeof rawAppName !== "string") {
|
|
949
|
+
throw new InputValidationError(
|
|
950
|
+
"Invalid EvalSessionInput: appName must be a string."
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
if (typeof rawUserId !== "string") {
|
|
954
|
+
throw new InputValidationError(
|
|
955
|
+
"Invalid EvalSessionInput: userId must be a string."
|
|
956
|
+
);
|
|
957
|
+
}
|
|
958
|
+
if (typeof rawState !== "object" || rawState === null || Array.isArray(rawState)) {
|
|
959
|
+
throw new InputValidationError(
|
|
960
|
+
"Invalid EvalSessionInput: state must be an object."
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
return {
|
|
964
|
+
appName: rawAppName,
|
|
965
|
+
userId: rawUserId,
|
|
966
|
+
state: rawState
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
__name(normalizeSessionInput, "normalizeSessionInput");
|
|
970
|
+
function normalizeEvalCase(raw) {
|
|
971
|
+
var _a, _b;
|
|
972
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
973
|
+
throw new InputValidationError("Invalid EvalCase: expected an object.");
|
|
974
|
+
}
|
|
975
|
+
const record = raw;
|
|
976
|
+
const rawEvalId = (_a = record.evalId) != null ? _a : record.eval_id;
|
|
977
|
+
if (typeof rawEvalId !== "string") {
|
|
978
|
+
throw new InputValidationError(
|
|
979
|
+
"Invalid EvalCase: evalId must be a string."
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
if (!Array.isArray(record.conversation)) {
|
|
983
|
+
throw new InputValidationError(
|
|
984
|
+
"Invalid EvalCase: conversation must be an array."
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
const conversation = record.conversation.map(normalizeInvocation);
|
|
988
|
+
const rawSessionInput = (_b = record.sessionInput) != null ? _b : record.session_input;
|
|
989
|
+
const sessionInput = rawSessionInput !== void 0 && rawSessionInput !== null ? normalizeSessionInput(rawSessionInput) : void 0;
|
|
990
|
+
const creationTimestamp = readCreationTimestamp(record);
|
|
991
|
+
return {
|
|
992
|
+
evalId: rawEvalId,
|
|
993
|
+
conversation,
|
|
994
|
+
...sessionInput !== void 0 ? { sessionInput } : {},
|
|
995
|
+
...creationTimestamp !== void 0 ? { creationTimestamp } : {}
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
__name(normalizeEvalCase, "normalizeEvalCase");
|
|
999
|
+
function convertLegacyInvocationToSchema(rawInvocation) {
|
|
1000
|
+
var _a, _b, _c;
|
|
1001
|
+
if (typeof rawInvocation !== "object" || rawInvocation === null || Array.isArray(rawInvocation)) {
|
|
1002
|
+
throw new InputValidationError(
|
|
1003
|
+
"Invalid legacy invocation: expected an object."
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
const record = rawInvocation;
|
|
1007
|
+
if (typeof record.query !== "string") {
|
|
1008
|
+
throw new InputValidationError(
|
|
1009
|
+
"Invalid legacy invocation: query must be a string."
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
const query = record.query;
|
|
1013
|
+
const rawReference = (_a = record.reference) != null ? _a : "";
|
|
1014
|
+
if (typeof rawReference !== "string") {
|
|
1015
|
+
throw new InputValidationError(
|
|
1016
|
+
"Invalid legacy invocation: reference must be a string."
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
1019
|
+
const rawExpectedToolUse = (_b = record.expected_tool_use) != null ? _b : [];
|
|
1020
|
+
if (!Array.isArray(rawExpectedToolUse)) {
|
|
1021
|
+
throw new InputValidationError(
|
|
1022
|
+
"Invalid legacy invocation: expected_tool_use must be an array."
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
1025
|
+
const toolResponses = [];
|
|
1026
|
+
const toolUses = rawExpectedToolUse.map((oldToolUse) => {
|
|
1027
|
+
var _a2;
|
|
1028
|
+
if (typeof oldToolUse !== "object" || oldToolUse === null || Array.isArray(oldToolUse)) {
|
|
1029
|
+
throw new InputValidationError(
|
|
1030
|
+
"Invalid legacy tool_use entry: expected an object."
|
|
1031
|
+
);
|
|
1032
|
+
}
|
|
1033
|
+
const tu = oldToolUse;
|
|
1034
|
+
if (typeof tu.tool_name !== "string") {
|
|
1035
|
+
throw new InputValidationError(
|
|
1036
|
+
"Invalid legacy tool_use: tool_name must be a string."
|
|
1037
|
+
);
|
|
1038
|
+
}
|
|
1039
|
+
if (tu.tool_input !== void 0 && (typeof tu.tool_input !== "object" || tu.tool_input === null || Array.isArray(tu.tool_input))) {
|
|
1040
|
+
throw new InputValidationError(
|
|
1041
|
+
"Invalid legacy tool_use: tool_input must be an object."
|
|
1042
|
+
);
|
|
1043
|
+
}
|
|
1044
|
+
const toolUse = {
|
|
1045
|
+
name: tu.tool_name,
|
|
1046
|
+
args: (_a2 = tu.tool_input) != null ? _a2 : {}
|
|
1047
|
+
};
|
|
1048
|
+
if (tu.mock_tool_output !== void 0) {
|
|
1049
|
+
toolUse.id = randomUUID();
|
|
1050
|
+
toolResponses.push({
|
|
1051
|
+
id: toolUse.id,
|
|
1052
|
+
name: tu.tool_name,
|
|
1053
|
+
response: { [MOCK_TOOL_OUTPUT_RESPONSE_KEY]: tu.mock_tool_output }
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
return toolUse;
|
|
1057
|
+
});
|
|
1058
|
+
const rawExpectedIntermediate = (_c = record.expected_intermediate_agent_responses) != null ? _c : [];
|
|
1059
|
+
if (!Array.isArray(rawExpectedIntermediate)) {
|
|
1060
|
+
throw new InputValidationError(
|
|
1061
|
+
"Invalid legacy invocation: expected_intermediate_agent_responses must be an array."
|
|
1062
|
+
);
|
|
1063
|
+
}
|
|
1064
|
+
const intermediateResponses = rawExpectedIntermediate.map((oldIntermediate) => {
|
|
1065
|
+
if (Array.isArray(oldIntermediate)) {
|
|
1066
|
+
if (oldIntermediate.length !== 2 || typeof oldIntermediate[0] !== "string" || !Array.isArray(oldIntermediate[1])) {
|
|
1067
|
+
throw new InputValidationError(
|
|
1068
|
+
"Invalid legacy intermediate response tuple: expected [author, Part[]]."
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
return [oldIntermediate[0], oldIntermediate[1]];
|
|
1072
|
+
}
|
|
1073
|
+
if (typeof oldIntermediate === "object" && oldIntermediate !== null) {
|
|
1074
|
+
const ir = oldIntermediate;
|
|
1075
|
+
if (typeof ir.author !== "string" || typeof ir.text !== "string") {
|
|
1076
|
+
throw new InputValidationError(
|
|
1077
|
+
"Invalid legacy intermediate response: author and text must be strings."
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
return [ir.author, [{ text: ir.text }]];
|
|
1081
|
+
}
|
|
1082
|
+
throw new InputValidationError(
|
|
1083
|
+
"Invalid legacy intermediate response: expected an object or tuple."
|
|
1084
|
+
);
|
|
1085
|
+
});
|
|
1086
|
+
return {
|
|
1087
|
+
invocationId: randomUUID(),
|
|
1088
|
+
userContent: {
|
|
1089
|
+
parts: [{ text: query }],
|
|
1090
|
+
role: "user"
|
|
1091
|
+
},
|
|
1092
|
+
finalResponse: {
|
|
1093
|
+
parts: [{ text: rawReference }],
|
|
1094
|
+
role: "model"
|
|
1095
|
+
},
|
|
1096
|
+
intermediateData: {
|
|
1097
|
+
toolUses,
|
|
1098
|
+
...toolResponses.length > 0 ? { toolResponses } : {},
|
|
1099
|
+
intermediateResponses
|
|
1100
|
+
},
|
|
1101
|
+
creationTimestamp: Date.now() / 1e3
|
|
1102
|
+
};
|
|
1103
|
+
}
|
|
1104
|
+
__name(convertLegacyInvocationToSchema, "convertLegacyInvocationToSchema");
|
|
1105
|
+
function convertEvalSetToSchema(evalSetId, evalSetInJsonFormat) {
|
|
1106
|
+
if (!Array.isArray(evalSetInJsonFormat)) {
|
|
1107
|
+
throw new InputValidationError(
|
|
1108
|
+
"Invalid legacy eval set JSON: expected an array of eval entries."
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
const evalCases = [];
|
|
1112
|
+
for (const rawEvalCase of evalSetInJsonFormat) {
|
|
1113
|
+
if (typeof rawEvalCase !== "object" || rawEvalCase === null || Array.isArray(rawEvalCase)) {
|
|
1114
|
+
throw new InputValidationError(
|
|
1115
|
+
"Invalid legacy eval case: expected an object."
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
const oldEvalCase = rawEvalCase;
|
|
1119
|
+
if (typeof oldEvalCase.name !== "string") {
|
|
1120
|
+
throw new InputValidationError(
|
|
1121
|
+
"Invalid legacy eval case: name must be a string."
|
|
1122
|
+
);
|
|
1123
|
+
}
|
|
1124
|
+
if (!Array.isArray(oldEvalCase.data)) {
|
|
1125
|
+
throw new InputValidationError(
|
|
1126
|
+
"Invalid legacy eval case: data must be an array."
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
const newInvocations = oldEvalCase.data.map(
|
|
1130
|
+
convertLegacyInvocationToSchema
|
|
1131
|
+
);
|
|
1132
|
+
let sessionInput;
|
|
1133
|
+
if (oldEvalCase.initial_session !== void 0 && oldEvalCase.initial_session !== null) {
|
|
1134
|
+
if (typeof oldEvalCase.initial_session !== "object" || Array.isArray(oldEvalCase.initial_session)) {
|
|
1135
|
+
throw new InputValidationError(
|
|
1136
|
+
"Invalid legacy eval case: initial_session must be an object."
|
|
1137
|
+
);
|
|
1138
|
+
}
|
|
1139
|
+
const initSess = oldEvalCase.initial_session;
|
|
1140
|
+
if (Object.keys(initSess).length > 0) {
|
|
1141
|
+
sessionInput = normalizeSessionInput(initSess);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
evalCases.push({
|
|
1145
|
+
evalId: oldEvalCase.name,
|
|
1146
|
+
conversation: newInvocations,
|
|
1147
|
+
...sessionInput !== void 0 ? { sessionInput } : {},
|
|
1148
|
+
creationTimestamp: Date.now() / 1e3
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
return {
|
|
1152
|
+
evalSetId,
|
|
1153
|
+
name: evalSetId,
|
|
1154
|
+
creationTimestamp: Date.now() / 1e3,
|
|
1155
|
+
evalCases
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
__name(convertEvalSetToSchema, "convertEvalSetToSchema");
|
|
1159
|
+
function parseEvalSetObject(raw) {
|
|
1160
|
+
var _a, _b;
|
|
1161
|
+
const rawEvalSetId = (_a = raw.evalSetId) != null ? _a : raw.eval_set_id;
|
|
1162
|
+
const rawEvalCases = (_b = raw.evalCases) != null ? _b : raw.eval_cases;
|
|
1163
|
+
if (typeof rawEvalSetId !== "string" || !Array.isArray(rawEvalCases)) {
|
|
1164
|
+
throw new InputValidationError(
|
|
1165
|
+
"Invalid EvalSet JSON: missing evalSetId or evalCases."
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
const name = typeof raw.name === "string" ? raw.name : void 0;
|
|
1169
|
+
const description = typeof raw.description === "string" ? raw.description : void 0;
|
|
1170
|
+
const creationTimestamp = readCreationTimestamp(raw);
|
|
1171
|
+
return {
|
|
1172
|
+
evalSetId: rawEvalSetId,
|
|
1173
|
+
...name !== void 0 ? { name } : {},
|
|
1174
|
+
...description !== void 0 ? { description } : {},
|
|
1175
|
+
evalCases: rawEvalCases.map(normalizeEvalCase),
|
|
1176
|
+
...creationTimestamp !== void 0 ? { creationTimestamp } : {}
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
__name(parseEvalSetObject, "parseEvalSetObject");
|
|
1180
|
+
function loadEvalSetFromFile(evalSetFilePath, evalSetId) {
|
|
1181
|
+
const content = fs.readFileSync(evalSetFilePath, "utf-8");
|
|
1182
|
+
const parsed = JSON.parse(content);
|
|
1183
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && ("evalSetId" in parsed || "eval_set_id" in parsed || "evalCases" in parsed || "eval_cases" in parsed)) {
|
|
1184
|
+
return parseEvalSetObject(parsed);
|
|
1185
|
+
}
|
|
1186
|
+
return convertEvalSetToSchema(evalSetId, parsed);
|
|
1187
|
+
}
|
|
1188
|
+
__name(loadEvalSetFromFile, "loadEvalSetFromFile");
|
|
1189
|
+
const _LocalEvalSetsManager = class _LocalEvalSetsManager {
|
|
1190
|
+
constructor(agentsDir) {
|
|
1191
|
+
this.agentsDir = agentsDir;
|
|
1192
|
+
}
|
|
1193
|
+
/**
|
|
1194
|
+
* Loads an {@link EvalSet} identified by `appName` and `evalSetId`, or
|
|
1195
|
+
* returns `undefined` if the file does not exist.
|
|
1196
|
+
*/
|
|
1197
|
+
getEvalSet(appName, evalSetId) {
|
|
1198
|
+
const evalSetFilePath = this.getEvalSetFilePath(appName, evalSetId);
|
|
1199
|
+
if (!fs.existsSync(evalSetFilePath)) {
|
|
1200
|
+
return void 0;
|
|
1201
|
+
}
|
|
1202
|
+
return loadEvalSetFromFile(evalSetFilePath, evalSetId);
|
|
1203
|
+
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Creates an empty {@link EvalSet} file for `appName` and `evalSetId`.
|
|
1206
|
+
*
|
|
1207
|
+
* @throws {InputValidationError} If `evalSetId` is invalid or the eval set
|
|
1208
|
+
* already exists.
|
|
1209
|
+
*/
|
|
1210
|
+
createEvalSet(appName, evalSetId) {
|
|
1211
|
+
validateEvalId("eval set ID", evalSetId);
|
|
1212
|
+
const newEvalSetPath = this.getEvalSetFilePath(appName, evalSetId);
|
|
1213
|
+
if (fs.existsSync(newEvalSetPath)) {
|
|
1214
|
+
throw new InputValidationError(
|
|
1215
|
+
`EvalSet ${evalSetId} already exists for app ${appName}.`
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
logger.info(`Creating eval set file \`${newEvalSetPath}\``);
|
|
1219
|
+
const newEvalSet = {
|
|
1220
|
+
evalSetId,
|
|
1221
|
+
name: evalSetId,
|
|
1222
|
+
evalCases: [],
|
|
1223
|
+
creationTimestamp: Date.now() / 1e3
|
|
1224
|
+
};
|
|
1225
|
+
this.writeEvalSet(newEvalSetPath, newEvalSet);
|
|
1226
|
+
return newEvalSet;
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* Lists all eval set IDs stored under `appName`, sorted alphabetically.
|
|
1230
|
+
*/
|
|
1231
|
+
listEvalSets(appName) {
|
|
1232
|
+
validatePathSegment(appName, "appName");
|
|
1233
|
+
const baseDir = path.resolve(this.agentsDir);
|
|
1234
|
+
const appDir = path.resolve(baseDir, appName);
|
|
1235
|
+
if (!isStrictlyInside(baseDir, appDir)) {
|
|
1236
|
+
throw new InputValidationError(`Invalid appName '${appName}'.`);
|
|
1237
|
+
}
|
|
1238
|
+
if (!fs.existsSync(appDir)) {
|
|
1239
|
+
return [];
|
|
1240
|
+
}
|
|
1241
|
+
const evalSets = [];
|
|
1242
|
+
for (const file of fs.readdirSync(appDir)) {
|
|
1243
|
+
if (file.endsWith(EVAL_SET_FILE_EXTENSION)) {
|
|
1244
|
+
evalSets.push(file.slice(0, -EVAL_SET_FILE_EXTENSION.length));
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
return evalSets.sort();
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Adds `evalCase` to the {@link EvalSet} identified by `appName` and
|
|
1251
|
+
* `evalSetId`.
|
|
1252
|
+
*
|
|
1253
|
+
* @throws {NotFoundError} If the eval set does not exist.
|
|
1254
|
+
* @throws {InputValidationError} If `evalCase.evalId` is invalid or already exists.
|
|
1255
|
+
*/
|
|
1256
|
+
addEvalCase(appName, evalSetId, evalCase) {
|
|
1257
|
+
const normalizedCase = normalizeEvalCase(evalCase);
|
|
1258
|
+
const evalCaseId = normalizedCase.evalId;
|
|
1259
|
+
validateEvalId("Eval Case ID", evalCaseId);
|
|
1260
|
+
const evalSet = this.getEvalSet(appName, evalSetId);
|
|
1261
|
+
if (!evalSet) {
|
|
1262
|
+
throw new NotFoundError(`Eval set \`${evalSetId}\` not found.`);
|
|
1263
|
+
}
|
|
1264
|
+
if (evalSet.evalCases.some((x) => x.evalId === evalCaseId)) {
|
|
1265
|
+
throw new InputValidationError(
|
|
1266
|
+
`Eval id \`${evalCaseId}\` already exists in \`${evalSetId}\` eval set.`
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
1269
|
+
evalSet.evalCases.push(normalizedCase);
|
|
1270
|
+
const evalSetFilePath = this.getEvalSetFilePath(appName, evalSetId);
|
|
1271
|
+
this.writeEvalSet(evalSetFilePath, evalSet);
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* Returns a single {@link EvalCase} by `appName`, `evalSetId`, and
|
|
1275
|
+
* `evalCaseId`, or `undefined` if not found.
|
|
1276
|
+
*/
|
|
1277
|
+
getEvalCase(appName, evalSetId, evalCaseId) {
|
|
1278
|
+
const evalSet = this.getEvalSet(appName, evalSetId);
|
|
1279
|
+
if (!evalSet) {
|
|
1280
|
+
return void 0;
|
|
1281
|
+
}
|
|
1282
|
+
return evalSet.evalCases.find((c) => c.evalId === evalCaseId);
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* Updates an existing {@link EvalCase} in the {@link EvalSet} identified by
|
|
1286
|
+
* `appName` and `evalSetId`.
|
|
1287
|
+
*
|
|
1288
|
+
* @throws {NotFoundError} If the eval set or eval case is not found.
|
|
1289
|
+
*/
|
|
1290
|
+
updateEvalCase(appName, evalSetId, updatedEvalCase) {
|
|
1291
|
+
const normalizedCase = normalizeEvalCase(updatedEvalCase);
|
|
1292
|
+
const evalCaseId = normalizedCase.evalId;
|
|
1293
|
+
const evalSet = this.getEvalSet(appName, evalSetId);
|
|
1294
|
+
if (!evalSet || !evalSet.evalCases.some((c) => c.evalId === evalCaseId)) {
|
|
1295
|
+
throw new NotFoundError(
|
|
1296
|
+
`Eval Set \`${evalSetId}\` or Eval id \`${evalCaseId}\` not found.`
|
|
1297
|
+
);
|
|
1298
|
+
}
|
|
1299
|
+
evalSet.evalCases = evalSet.evalCases.filter(
|
|
1300
|
+
(c) => c.evalId !== evalCaseId
|
|
1301
|
+
);
|
|
1302
|
+
evalSet.evalCases.push(normalizedCase);
|
|
1303
|
+
const evalSetFilePath = this.getEvalSetFilePath(appName, evalSetId);
|
|
1304
|
+
this.writeEvalSet(evalSetFilePath, evalSet);
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Deletes an {@link EvalCase} identified by `appName`, `evalSetId`, and
|
|
1308
|
+
* `evalCaseId`.
|
|
1309
|
+
*
|
|
1310
|
+
* @throws {NotFoundError} If the eval set or eval case to delete is not found.
|
|
1311
|
+
*/
|
|
1312
|
+
deleteEvalCase(appName, evalSetId, evalCaseId) {
|
|
1313
|
+
const evalSet = this.getEvalSet(appName, evalSetId);
|
|
1314
|
+
if (!evalSet || !evalSet.evalCases.some((c) => c.evalId === evalCaseId)) {
|
|
1315
|
+
throw new NotFoundError(
|
|
1316
|
+
`Eval Set \`${evalSetId}\` or Eval id \`${evalCaseId}\` not found.`
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
logger.info(
|
|
1320
|
+
`EvalCase \`${evalCaseId}\` was found in the eval set. It will be removed permanently.`
|
|
1321
|
+
);
|
|
1322
|
+
evalSet.evalCases = evalSet.evalCases.filter(
|
|
1323
|
+
(c) => c.evalId !== evalCaseId
|
|
1324
|
+
);
|
|
1325
|
+
const evalSetFilePath = this.getEvalSetFilePath(appName, evalSetId);
|
|
1326
|
+
this.writeEvalSet(evalSetFilePath, evalSet);
|
|
1327
|
+
}
|
|
1328
|
+
getEvalSetFilePath(appName, evalSetId) {
|
|
1329
|
+
validatePathSegment(appName, "appName");
|
|
1330
|
+
validatePathSegment(evalSetId, "evalSetId");
|
|
1331
|
+
validateEvalId("eval set ID", evalSetId);
|
|
1332
|
+
const baseDir = path.resolve(this.agentsDir);
|
|
1333
|
+
const appDir = path.resolve(baseDir, appName);
|
|
1334
|
+
if (!isStrictlyInside(baseDir, appDir)) {
|
|
1335
|
+
throw new InputValidationError(`Invalid appName '${appName}'.`);
|
|
1336
|
+
}
|
|
1337
|
+
const filePath = path.resolve(
|
|
1338
|
+
appDir,
|
|
1339
|
+
`${evalSetId}${EVAL_SET_FILE_EXTENSION}`
|
|
1340
|
+
);
|
|
1341
|
+
if (!isStrictlyInside(appDir, filePath)) {
|
|
1342
|
+
throw new InputValidationError(`Invalid evalSetId '${evalSetId}'.`);
|
|
1343
|
+
}
|
|
1344
|
+
return filePath;
|
|
1345
|
+
}
|
|
1346
|
+
writeEvalSet(evalSetPath, evalSet) {
|
|
1347
|
+
fs.mkdirSync(path.dirname(evalSetPath), { recursive: true });
|
|
1348
|
+
fs.writeFileSync(evalSetPath, JSON.stringify(evalSet, null, 2), "utf-8");
|
|
1349
|
+
}
|
|
1350
|
+
};
|
|
1351
|
+
__name(_LocalEvalSetsManager, "LocalEvalSetsManager");
|
|
1352
|
+
let LocalEvalSetsManager = _LocalEvalSetsManager;
|
|
497
1353
|
export {
|
|
498
1354
|
DEFAULT_CRITERIA,
|
|
499
1355
|
EVAL_SESSION_ID_PREFIX,
|
|
500
1356
|
EvalStatus,
|
|
1357
|
+
LocalEvalSetResultsManager,
|
|
1358
|
+
LocalEvalSetsManager,
|
|
501
1359
|
MISSING_EVAL_DEPENDENCIES_MESSAGE,
|
|
502
1360
|
RESPONSE_EVALUATION_SCORE_KEY,
|
|
503
1361
|
RESPONSE_MATCH_SCORE_KEY,
|
|
504
1362
|
TOOL_TRAJECTORY_SCORE_KEY,
|
|
1363
|
+
convertEvalSetToSchema,
|
|
1364
|
+
createEvalSetResult,
|
|
505
1365
|
getEvaluationCriteriaOrDefault,
|
|
506
1366
|
getRootAgent,
|
|
1367
|
+
loadEvalSetFromFile,
|
|
1368
|
+
normalizeEvalCase,
|
|
507
1369
|
parseAndGetEvalsToRun,
|
|
1370
|
+
parseEvalSetResultJson,
|
|
508
1371
|
runEvals,
|
|
509
1372
|
tryGetResetFunc
|
|
510
1373
|
};
|