eve 0.75.1 → 0.76.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/CHANGELOG.md +42 -0
- package/dist/src/_virtual/_rolldown/runtime.js +1 -1
- package/dist/src/acp/adapter.js +1 -1
- package/dist/src/channel/task-card.js +1 -1
- package/dist/src/channel/tool-eligibility.d.ts +1 -2
- package/dist/src/chunks/{use-eve-agent-B2Kne9z6.js → use-eve-agent-D2V9UhLt.js} +68 -10
- package/dist/src/chunks/{use-eve-agent-DK_T88EP.js → use-eve-agent-QmriPA-w.js} +68 -10
- package/dist/src/cli/dev/environment.d.ts +0 -6
- package/dist/src/cli/dev/environment.js +1 -1
- package/dist/src/cli/dev/tui/conversation-view.js +1 -1
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/tool-presentation.js +1 -1
- package/dist/src/cli/dev/tui/transcript.js +1 -1
- package/dist/src/client/message-action-parts.d.ts +3 -0
- package/dist/src/client/message-action-parts.js +1 -1
- package/dist/src/client/message-reducer-types.d.ts +6 -1
- package/dist/src/client/message-reducer.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +3 -2
- package/dist/src/compiled/@eve/catalog/index.js +1 -1
- package/dist/src/compiled/@vercel/queue/index.d.ts +1066 -0
- package/dist/src/compiled/@vercel/queue/index.js +47 -0
- package/dist/src/compiler/connection-ownership.d.ts +6 -0
- package/dist/src/compiler/connection-ownership.js +1 -0
- package/dist/src/compiler/default-tool-policy.d.ts +0 -3
- package/dist/src/compiler/default-tool-policy.js +1 -1
- package/dist/src/compiler/extension-compatibility.d.ts +21 -20
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.d.ts +9 -6
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-connection.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/normalize-skill.d.ts +5 -0
- package/dist/src/compiler/normalize-skill.js +1 -1
- package/dist/src/compiler/normalize-subagent.d.ts +2 -1
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/compiler/remote-agent-node.d.ts +2 -1
- package/dist/src/compiler/remote-agent-node.js +1 -1
- package/dist/src/connections/ownership.d.ts +18 -0
- package/dist/src/connections/ownership.js +1 -0
- package/dist/src/context/build-dynamic-tools.d.ts +3 -9
- package/dist/src/context/build-dynamic-tools.js +1 -1
- package/dist/src/context/dynamic-connection-lifecycle.js +1 -1
- package/dist/src/context/dynamic-skill-lifecycle.d.ts +2 -11
- package/dist/src/context/dynamic-skill-lifecycle.js +1 -1
- package/dist/src/context/dynamic-subagent-lifecycle.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/context/dynamic-tool-metadata.d.ts +1 -0
- package/dist/src/context/keys.d.ts +5 -4
- package/dist/src/context/memory-tools.js +1 -1
- package/dist/src/context/schedule-collection-tools.js +1 -1
- package/dist/src/discover/grammar.d.ts +11 -0
- package/dist/src/discover/grammar.js +1 -1
- package/dist/src/discover/manifest.d.ts +1 -0
- package/dist/src/discover/manifest.js +1 -1
- package/dist/src/discover/skills.d.ts +1 -0
- package/dist/src/discover/skills.js +1 -1
- package/dist/src/dynamic/definition.d.ts +7 -5
- package/dist/src/evals/assertions/collector.d.ts +4 -0
- package/dist/src/evals/assertions/collector.js +1 -1
- package/dist/src/evals/assertions/run.d.ts +2 -3
- package/dist/src/evals/assertions/run.js +2 -2
- package/dist/src/evals/assertions/scoped.js +1 -1
- package/dist/src/evals/index.d.ts +1 -1
- package/dist/src/evals/match.d.ts +9 -6
- package/dist/src/evals/reported-tool-name.d.ts +9 -0
- package/dist/src/evals/reported-tool-name.js +1 -0
- package/dist/src/evals/runner/derive-run-facts.d.ts +3 -3
- package/dist/src/evals/runner/derive-run-facts.js +1 -1
- package/dist/src/evals/runner/execute-task.js +1 -1
- package/dist/src/evals/runner/reporters/braintrust.js +1 -1
- package/dist/src/evals/runner/reporters/datadog-runtime-trace-links.d.ts +11 -0
- package/dist/src/evals/runner/reporters/datadog-runtime-trace-links.js +1 -0
- package/dist/src/evals/runner/reporters/datadog.js +2 -2
- package/dist/src/evals/session.js +2 -2
- package/dist/src/evals/target.d.ts +7 -0
- package/dist/src/evals/target.js +1 -1
- package/dist/src/evals/types.d.ts +17 -1
- package/dist/src/execution/agent-sessions/remote.js +1 -1
- package/dist/src/execution/catalog/connection-auth.d.ts +41 -0
- package/dist/src/execution/catalog/connection-auth.js +1 -0
- package/dist/src/execution/catalog/connection-entry.d.ts +16 -0
- package/dist/src/execution/catalog/connection-entry.js +1 -0
- package/dist/src/execution/catalog/listing.d.ts +9 -0
- package/dist/src/execution/catalog/listing.js +3 -0
- package/dist/src/execution/catalog/rank.d.ts +44 -0
- package/dist/src/execution/catalog/rank.js +1 -0
- package/dist/src/execution/catalog/search.d.ts +28 -0
- package/dist/src/execution/catalog/search.js +1 -0
- package/dist/src/execution/catalog/signatures.d.ts +11 -0
- package/dist/src/execution/catalog/signatures.js +1 -0
- package/dist/src/execution/catalog/skills.d.ts +24 -0
- package/dist/src/execution/catalog/skills.js +1 -0
- package/dist/src/execution/catalog/step-catalog.d.ts +51 -0
- package/dist/src/execution/catalog/step-catalog.js +1 -0
- package/dist/src/execution/coordination-dispatch-shared.js +1 -1
- package/dist/src/execution/dynamic-connections.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/invoke-tool.js +1 -1
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/session/active-turn.d.ts +1 -1
- package/dist/src/execution/session/pending-turn-state.js +1 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session/turn.d.ts +5 -5
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/session.js +1 -1
- package/dist/src/execution/skills/instructions.d.ts +20 -10
- package/dist/src/execution/skills/instructions.js +2 -2
- package/dist/src/execution/tasks/calls.d.ts +6 -5
- package/dist/src/execution/tasks/calls.js +1 -1
- package/dist/src/execution/tasks/model-step.d.ts +10 -10
- package/dist/src/execution/tasks/model-step.js +1 -1
- package/dist/src/execution/tasks/render.d.ts +3 -3
- package/dist/src/execution/tasks/render.js +3 -3
- package/dist/src/execution/tasks/session.d.ts +2 -1
- package/dist/src/execution/tasks/table.d.ts +1 -1
- package/dist/src/execution/tasks/tool-entry-point.d.ts +1 -1
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/workflow/harness-definition.js +1 -1
- package/dist/src/extensions/code/extension/extension.d.ts +4 -18
- package/dist/src/extensions/code/extension/instructions/github.d.ts +3 -0
- package/dist/src/extensions/code/extension/instructions/github.js +1 -0
- package/dist/src/extensions/code/extension/instructions.md +1 -13
- package/dist/src/extensions/code/extension/lib/diagnostics.d.ts +4 -2
- package/dist/src/extensions/code/extension/lib/diagnostics.js +3 -3
- package/dist/src/extensions/code/extension/lib/github-compat.d.ts +28 -0
- package/dist/src/extensions/code/extension/lib/github-compat.js +1 -0
- package/dist/src/extensions/code/extension/lib/grep-search.d.ts +3 -13
- package/dist/src/extensions/code/extension/lib/grep-search.js +2 -2
- package/dist/src/extensions/code/extension/lib/patch.d.ts +8 -2
- package/dist/src/extensions/code/extension/lib/patch.js +4 -4
- package/dist/src/extensions/code/extension/lib/repository-root.d.ts +3 -4
- package/dist/src/extensions/code/extension/lib/repository-root.js +1 -1
- package/dist/src/extensions/code/extension/lib/sandbox.d.ts +2 -1
- package/dist/src/extensions/code/extension/lib/sandbox.js +1 -1
- package/dist/src/extensions/code/extension/lib/tooling.d.ts +4 -4
- package/dist/src/extensions/code/extension/lib/tooling.js +7 -7
- package/dist/src/extensions/code/extension/lib/workspace-root.d.ts +31 -0
- package/dist/src/extensions/code/extension/lib/workspace-root.js +1 -0
- package/dist/src/extensions/code/extension/skills/pr.d.ts +6 -0
- package/dist/src/extensions/code/extension/skills/pr.js +1 -0
- package/dist/src/extensions/code/extension/tools/apply_patch.d.ts +2 -2
- package/dist/src/extensions/code/extension/tools/apply_patch.js +2 -2
- package/dist/src/extensions/code/extension/tools/gh.d.ts +4 -3
- package/dist/src/extensions/code/extension/tools/gh.js +1 -1
- package/dist/src/extensions/code/extension/tools/grep.js +1 -1
- package/dist/src/extensions/code/tools.d.ts +2 -1
- package/dist/src/extensions/code/tools.js +1 -1
- package/dist/src/extensions/git/extension/extension.d.ts +12 -0
- package/dist/src/extensions/git/extension/extension.js +1 -0
- package/dist/src/extensions/git/extension/instructions/github.d.ts +2 -0
- package/dist/src/extensions/git/extension/instructions/github.js +1 -0
- package/dist/src/extensions/git/extension/lib/gh-tool.d.ts +29 -0
- package/dist/src/extensions/git/extension/lib/gh-tool.js +1 -0
- package/dist/src/extensions/git/extension/lib/github-guidance.d.ts +3 -0
- package/dist/src/extensions/git/extension/lib/github-guidance.js +49 -0
- package/dist/src/extensions/{code → git}/extension/lib/github-shell.d.ts +1 -1
- package/dist/src/extensions/git/extension/lib/github-shell.js +1 -0
- package/dist/src/extensions/git/extension/lib/repository-root.d.ts +5 -0
- package/dist/src/extensions/git/extension/lib/repository-root.js +1 -0
- package/dist/src/extensions/git/extension/lib/sandbox.d.ts +6 -0
- package/dist/src/extensions/git/extension/lib/sandbox.js +1 -0
- package/dist/src/extensions/git/extension/lib/shell.d.ts +1 -0
- package/dist/src/extensions/git/extension/lib/shell.js +1 -0
- package/dist/src/extensions/git/extension/lib/tooling.d.ts +4 -0
- package/dist/src/extensions/git/extension/lib/tooling.js +1 -0
- package/dist/src/extensions/git/extension/skills/pr.d.ts +5 -0
- package/dist/src/extensions/git/extension/skills/pr.js +1 -0
- package/dist/src/extensions/git/extension/tools/gh.d.ts +28 -0
- package/dist/src/extensions/git/extension/tools/gh.js +1 -0
- package/dist/src/extensions/git/tools.d.ts +27 -0
- package/dist/src/extensions/git/tools.js +1 -0
- package/dist/src/framework/sources/registry.js +1 -1
- package/dist/src/harness/action-presentation.d.ts +2 -2
- package/dist/src/harness/action-result-helpers.d.ts +10 -2
- package/dist/src/harness/action-result-helpers.js +1 -1
- package/dist/src/harness/announcements.d.ts +2 -8
- package/dist/src/harness/announcements.js +1 -1
- package/dist/src/harness/coordination.d.ts +11 -11
- package/dist/src/harness/coordination.js +1 -1
- package/dist/src/harness/current-messages.d.ts +1 -5
- package/dist/src/harness/current-messages.js +1 -1
- package/dist/src/harness/emission.d.ts +2 -2
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/execute-call.d.ts +48 -0
- package/dist/src/harness/execute-call.js +1 -0
- package/dist/src/harness/execute-tool.d.ts +3 -1
- package/dist/src/harness/final-output.d.ts +2 -6
- package/dist/src/harness/final-output.js +1 -1
- package/dist/src/harness/hitl/approvals.d.ts +5 -0
- package/dist/src/harness/hitl/approvals.js +1 -1
- package/dist/src/harness/hitl/approved-calls.d.ts +3 -2
- package/dist/src/harness/hitl/approved-calls.js +1 -1
- package/dist/src/harness/hitl/candidates.d.ts +13 -2
- package/dist/src/harness/hitl/candidates.js +1 -1
- package/dist/src/harness/hitl/coordinator.d.ts +3 -3
- package/dist/src/harness/hitl/coordinator.js +1 -1
- package/dist/src/harness/hitl/index.d.ts +6 -4
- package/dist/src/harness/hitl/index.js +1 -1
- package/dist/src/harness/hitl/intake.d.ts +3 -3
- package/dist/src/harness/hitl/intake.js +1 -1
- package/dist/src/harness/input-extraction.d.ts +4 -1
- package/dist/src/harness/input-extraction.js +1 -1
- package/dist/src/harness/input-request-resolution.d.ts +15 -0
- package/dist/src/harness/input-request-resolution.js +1 -1
- package/dist/src/harness/model-call/call.d.ts +3 -5
- package/dist/src/harness/model-call/call.js +1 -1
- package/dist/src/harness/model-call/errors.js +1 -1
- package/dist/src/harness/model-call/request.d.ts +3 -2
- package/dist/src/harness/model-call/request.js +1 -1
- package/dist/src/harness/model-call/response.d.ts +2 -1
- package/dist/src/harness/model-call/response.js +1 -1
- package/dist/src/harness/model-call/run.d.ts +5 -3
- package/dist/src/harness/model-call/run.js +1 -1
- package/dist/src/harness/model-call/tools.d.ts +12 -21
- package/dist/src/harness/model-call/tools.js +1 -1
- package/dist/src/harness/model-profile.d.ts +5 -0
- package/dist/src/harness/model-profile.js +1 -1
- package/dist/src/harness/provider-tools.d.ts +6 -5
- package/dist/src/harness/provider-tools.js +1 -1
- package/dist/src/harness/session-machine/commit.js +1 -1
- package/dist/src/harness/session-machine/transitions.d.ts +5 -2
- package/dist/src/harness/session-machine/transitions.js +1 -1
- package/dist/src/harness/step/after-model.js +1 -1
- package/dist/src/harness/step-hooks.d.ts +4 -6
- package/dist/src/harness/step-hooks.js +1 -1
- package/dist/src/harness/tool-call-input-errors.d.ts +2 -2
- package/dist/src/harness/tool-call-io.d.ts +3 -0
- package/dist/src/harness/tool-call-io.js +1 -1
- package/dist/src/harness/tools.d.ts +22 -19
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/harness/types.d.ts +14 -0
- package/dist/src/instrumentation/lifecycle.d.ts +0 -1
- package/dist/src/instrumentation/native-events.js +1 -1
- package/dist/src/instrumentation/runtime.d.ts +2 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/authored-definition/schedule-collection.js +1 -1
- package/dist/src/internal/authored-definition/schema-backed.d.ts +2 -2
- package/dist/src/internal/authored-definition/schema-backed.js +1 -1
- package/dist/src/internal/authored-module.d.ts +2 -1
- package/dist/src/internal/authored-module.js +1 -1
- package/dist/src/internal/helpers/markdown.js +1 -1
- package/dist/src/internal/mcp/skills.js +1 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/dev-host-fingerprint.js +1 -1
- package/dist/src/internal/nitro/host/local-schedules-runtime-plugin.d.ts +5 -0
- package/dist/src/internal/nitro/host/local-schedules-runtime-plugin.js +1 -0
- package/dist/src/internal/nitro/routes/schedule-collection-consumer.d.ts +6 -0
- package/dist/src/internal/nitro/routes/schedule-collection-consumer.js +1 -1
- package/dist/src/internal/schedules/consumer-route.d.ts +2 -0
- package/dist/src/internal/schedules/consumer-route.js +1 -1
- package/dist/src/internal/schedules/dev-environment.d.ts +2 -0
- package/dist/src/internal/schedules/dev-environment.js +1 -0
- package/dist/src/internal/vercel-agent-summary.d.ts +2 -2
- package/dist/src/internal/workflow/vercel-world-defaults.d.ts +1 -1
- package/dist/src/internal/workflow/vercel-world-defaults.js +1 -1
- package/dist/src/protocol/catalog-tools.d.ts +12 -0
- package/dist/src/protocol/catalog-tools.js +1 -0
- package/dist/src/protocol/message-version.js +1 -1
- package/dist/src/protocol/message.d.ts +1 -1
- package/dist/src/protocol/remote-agent-protocol.d.ts +2 -0
- package/dist/src/protocol/remote-agent-protocol.js +1 -1
- package/dist/src/protocol/reply-tool.d.ts +2 -0
- package/dist/src/protocol/reply-tool.js +1 -0
- package/dist/src/protocol/runtime-tools.d.ts +6 -0
- package/dist/src/protocol/runtime-tools.js +1 -0
- package/dist/src/protocol/session-projection.js +1 -1
- package/dist/src/protocol/task-tools.d.ts +4 -4
- package/dist/src/protocol/task-tools.js +1 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +1 -1
- package/dist/src/public/channels/linear/defaults.js +2 -2
- package/dist/src/public/channels/slack/action-status.d.ts +0 -9
- package/dist/src/public/channels/slack/action-status.js +1 -1
- package/dist/src/public/channels/slack/defaults.js +2 -2
- package/dist/src/public/channels/slack/task-card.d.ts +1 -1
- package/dist/src/public/definitions/connections/mcp.d.ts +4 -4
- package/dist/src/public/definitions/connections/openapi.d.ts +6 -7
- package/dist/src/public/definitions/remote-agent.d.ts +6 -3
- package/dist/src/public/definitions/workspace-agent.d.ts +6 -3
- package/dist/src/public/experimental/schedules/index.d.ts +1 -1
- package/dist/src/public/schedules/providers/in-memory.js +1 -1
- package/dist/src/public/schedules/providers/vercel.js +1 -1
- package/dist/src/public/schedules/subscription.d.ts +36 -16
- package/dist/src/public/tools/web-search.d.ts +1 -1
- package/dist/src/runtime/agent/bootstrap.d.ts +2 -1
- package/dist/src/runtime/agent/bootstrap.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +2 -2
- package/dist/src/runtime/agent/mock-model-fixtures.js +2 -2
- package/dist/src/runtime/agent/mock-model-skill-selection.d.ts +2 -0
- package/dist/src/runtime/agent/mock-model-skill-selection.js +2 -2
- package/dist/src/runtime/agent/mock-structured-output.d.ts +1 -1
- package/dist/src/runtime/connections/mcp-client.js +1 -1
- package/dist/src/runtime/connections/registry.js +1 -1
- package/dist/src/runtime/connections/scoped-authorization.js +1 -1
- package/dist/src/runtime/connections/tool-result.d.ts +2 -2
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/resolve-tool.js +1 -1
- package/dist/src/runtime/schedules/collection-client.d.ts +12 -3
- package/dist/src/runtime/schedules/collection-client.js +1 -1
- package/dist/src/runtime/subagents/dynamic-agent-config.d.ts +2 -2
- package/dist/src/runtime/subagents/dynamic-remote-agent-config.d.ts +2 -1
- package/dist/src/runtime/subagents/dynamic-remote-agent-config.js +1 -1
- package/dist/src/runtime/subagents/registry.d.ts +2 -1
- package/dist/src/runtime/subagents/registry.js +1 -1
- package/dist/src/runtime/tools/registry.d.ts +2 -0
- package/dist/src/runtime/tools/registry.js +1 -1
- package/dist/src/runtime/types.d.ts +3 -3
- package/dist/src/setup/connection-connector.js +1 -2
- package/dist/src/setup/index.d.ts +1 -1
- package/dist/src/setup/index.js +1 -1
- package/dist/src/setup/integrations/slack/setup.d.ts +23 -3
- package/dist/src/setup/integrations/slack/setup.js +1 -1
- package/dist/src/setup/primitives/process-output.d.ts +5 -0
- package/dist/src/setup/primitives/process-output.js +2 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +1 -1
- package/dist/src/setup/scaffold/update/update-slack-channel.d.ts +17 -0
- package/dist/src/setup/scaffold/update/update-slack-channel.js +1 -1
- package/dist/src/setup/slack-connect-create.d.ts +10 -2
- package/dist/src/setup/slack-connect-create.js +1 -1
- package/dist/src/setup/slack-connect-lifecycle.d.ts +92 -44
- package/dist/src/setup/slack-connect-lifecycle.js +1 -1
- package/dist/src/setup/slack-connect.d.ts +30 -11
- package/dist/src/setup/slack-connect.js +1 -1
- package/dist/src/setup/slack-setup-plan.d.ts +72 -0
- package/dist/src/setup/slack-setup-plan.js +1 -0
- package/dist/src/setup/slackbot.d.ts +75 -35
- package/dist/src/setup/slackbot.js +2 -1
- package/dist/src/shared/action-label.d.ts +10 -0
- package/dist/src/shared/action-label.js +1 -0
- package/dist/src/shared/action-request-name.d.ts +3 -1
- package/dist/src/shared/action-request-name.js +1 -1
- package/dist/src/shared/action-types.d.ts +7 -8
- package/dist/src/shared/action-types.js +1 -1
- package/dist/src/shared/agent-definition.d.ts +11 -3
- package/dist/src/shared/development-env-files.d.ts +4 -0
- package/dist/src/shared/development-env-files.js +1 -0
- package/dist/src/shared/input.d.ts +0 -1
- package/dist/src/shared/map-with-concurrency.d.ts +2 -0
- package/dist/src/shared/map-with-concurrency.js +1 -0
- package/dist/src/shared/skill-definition.d.ts +6 -0
- package/dist/src/shared/skill-package.d.ts +1 -0
- package/dist/src/shared/skill-package.js +1 -1
- package/dist/src/shared/web-search.d.ts +15 -2
- package/dist/src/shared/web-search.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tool-stubs/execute.d.ts +0 -3
- package/dist/src/tool-stubs/execute.js +1 -1
- package/dist/src/tool-stubs/rules.js +1 -1
- package/dist/src/tool-stubs/validate-targets.js +1 -1
- package/dist/src/tools/behavior.d.ts +3 -6
- package/dist/src/tools/definition.d.ts +5 -0
- package/dist/src/tools/dynamic.d.ts +5 -2
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/tools/provided/task-cancel.d.ts +1 -1
- package/dist/src/tools/provided/task-wait.d.ts +1 -1
- package/dist/src/tools/provided/web-search.d.ts +20 -7
- package/dist/src/tools/provided/web-search.js +1 -1
- package/dist/src/tools/schema.d.ts +5 -0
- package/dist/src/tools/schema.js +1 -1
- package/dist/src/{runtime/connections/tool-signature.d.ts → tools/signature.d.ts} +2 -2
- package/dist/src/tools/workflow-definition.d.ts +1 -1
- package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
- package/dist/src/tracing/agent-otel-provider.js +2 -2
- package/dist/src/tracing/agent-otel-runtime-context.d.ts +1 -0
- package/dist/src/tracing/agent-otel-runtime-context.js +1 -1
- package/dist/src/tracing/agent-otel-turn-state.d.ts +6 -0
- package/dist/src/tracing/agent-otel-turn-state.js +1 -0
- package/dist/src/tracing/agent-tool-instrumentation.js +1 -1
- package/dist/src/tracing/agent-trace-context-codec.js +1 -1
- package/dist/src/tracing/agent-trace-state.d.ts +4 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/agent-config.md +8 -8
- package/docs/channels/chat-sdk.mdx +1 -1
- package/docs/channels/slack.mdx +32 -82
- package/docs/code-extension.mdx +28 -7
- package/docs/concepts/built-in-tools.md +43 -43
- package/docs/concepts/context-control.md +1 -1
- package/docs/concepts/execution-model-and-durability.mdx +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +4 -4
- package/docs/connections/mcp.mdx +5 -5
- package/docs/connections/openapi.mdx +1 -1
- package/docs/connections/overview.mdx +4 -2
- package/docs/evals/assertions.mdx +5 -3
- package/docs/evals/reporters.mdx +3 -1
- package/docs/evals/tool-stubs.mdx +3 -1
- package/docs/extensions.md +2 -0
- package/docs/guides/dev-tui.md +2 -2
- package/docs/guides/dynamic-capabilities.md +14 -4
- package/docs/guides/frontend/overview.mdx +1 -1
- package/docs/guides/remote-agents.md +10 -3
- package/docs/instructions.mdx +5 -5
- package/docs/reference/cli.md +2 -2
- package/docs/reference/typescript-api.md +3 -3
- package/docs/skills.mdx +19 -4
- package/docs/subagents/index.mdx +5 -3
- package/docs/tools/overview.mdx +22 -1
- package/docs/tools/tasks-upgrade.md +1 -1
- package/docs/tools/tasks.md +32 -32
- package/docs/tools/workflows.mdx +6 -6
- package/docs/tutorial/team-playbooks.mdx +2 -2
- package/package.json +22 -6
- package/dist/src/execution/connection-announcement.d.ts +0 -7
- package/dist/src/execution/connection-announcement.js +0 -4
- package/dist/src/execution/tools/connection-approval.d.ts +0 -25
- package/dist/src/execution/tools/connection-approval.js +0 -1
- package/dist/src/execution/tools/connection-search-rank.d.ts +0 -21
- package/dist/src/execution/tools/connection-search-rank.js +0 -1
- package/dist/src/execution/tools/connection-target.d.ts +0 -18
- package/dist/src/execution/tools/connection-target.js +0 -1
- package/dist/src/execution/tools/connection-tools.d.ts +0 -4
- package/dist/src/execution/tools/connection-tools.js +0 -2
- package/dist/src/execution/tools/load-skill.d.ts +0 -10
- package/dist/src/execution/tools/load-skill.js +0 -1
- package/dist/src/extensions/code/extension/lib/github-shell.js +0 -1
- package/dist/src/extensions/code/extension/skills/pr/SKILL.md +0 -53
- package/dist/src/extensions/code/extension/subagents/worker/tools/load_skill.d.ts +0 -2
- package/dist/src/extensions/code/extension/subagents/worker/tools/load_skill.js +0 -1
- package/dist/src/harness/advertised-tools.d.ts +0 -26
- package/dist/src/harness/advertised-tools.js +0 -1
- package/dist/src/harness/nested-actions.d.ts +0 -23
- package/dist/src/harness/nested-actions.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-config@0.2.0/node_modules/@vercel/cli-config/dist/cli-config.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-config@0.2.0/node_modules/@vercel/cli-config/dist/cred-storage.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-config@0.2.0/node_modules/@vercel/cli-config/dist/index.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-config@0.2.0/node_modules/@vercel/cli-config/dist/schema.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-config@0.2.0/node_modules/@vercel/cli-config/dist/schema.zod.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-config@0.2.0/node_modules/@vercel/cli-config/dist/types.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-exec@1.0.0/node_modules/@vercel/cli-exec/dist/envpath.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-exec@1.0.0/node_modules/@vercel/cli-exec/dist/errors.js +0 -2
- package/dist/src/node_modules/.pnpm/@vercel_cli-exec@1.0.0/node_modules/@vercel/cli-exec/dist/errutils.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-exec@1.0.0/node_modules/@vercel/cli-exec/dist/exec.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-exec@1.0.0/node_modules/@vercel/cli-exec/dist/fsutils.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-exec@1.0.0/node_modules/@vercel/cli-exec/dist/index.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-exec@1.0.0/node_modules/@vercel/cli-exec/dist/lookup.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_cli-exec@1.0.0/node_modules/@vercel/cli-exec/dist/safety.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/auth-errors.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/exchange-vercel-oidc-token.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/get-context.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/get-vercel-oidc-token-sync.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/get-vercel-oidc-token-with-refresh.js +0 -2
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/index.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/oauth.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/token-error.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/token-io.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/token-util.js +0 -2
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/token.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/verify-vercel-oidc-token.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_oidc@3.8.0/node_modules/@vercel/oidc/dist/version.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_queue@0.5.1_@opentelemetry_api@1.9.1/node_modules/@vercel/queue/dist/index.js +0 -36
- package/dist/src/node_modules/.pnpm/balanced-match@4.0.4/node_modules/balanced-match/dist/esm/index.js +0 -1
- package/dist/src/node_modules/.pnpm/brace-expansion@5.0.12/node_modules/brace-expansion/dist/esm/index.js +0 -1
- package/dist/src/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/index.js +0 -1
- package/dist/src/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/enoent.js +0 -1
- package/dist/src/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js +0 -1
- package/dist/src/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/escape.js +0 -1
- package/dist/src/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js +0 -1
- package/dist/src/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js +0 -1
- package/dist/src/node_modules/.pnpm/execa@5.1.1/node_modules/execa/index.js +0 -1
- package/dist/src/node_modules/.pnpm/execa@5.1.1/node_modules/execa/lib/command.js +0 -1
- package/dist/src/node_modules/.pnpm/execa@5.1.1/node_modules/execa/lib/error.js +0 -2
- package/dist/src/node_modules/.pnpm/execa@5.1.1/node_modules/execa/lib/kill.js +0 -1
- package/dist/src/node_modules/.pnpm/execa@5.1.1/node_modules/execa/lib/promise.js +0 -1
- package/dist/src/node_modules/.pnpm/execa@5.1.1/node_modules/execa/lib/stdio.js +0 -1
- package/dist/src/node_modules/.pnpm/execa@5.1.1/node_modules/execa/lib/stream.js +0 -1
- package/dist/src/node_modules/.pnpm/get-stream@6.0.1/node_modules/get-stream/buffer-stream.js +0 -1
- package/dist/src/node_modules/.pnpm/get-stream@6.0.1/node_modules/get-stream/index.js +0 -1
- package/dist/src/node_modules/.pnpm/human-signals@2.1.0/node_modules/human-signals/build/src/core.js +0 -1
- package/dist/src/node_modules/.pnpm/human-signals@2.1.0/node_modules/human-signals/build/src/main.js +0 -1
- package/dist/src/node_modules/.pnpm/human-signals@2.1.0/node_modules/human-signals/build/src/realtime.js +0 -1
- package/dist/src/node_modules/.pnpm/human-signals@2.1.0/node_modules/human-signals/build/src/signals.js +0 -1
- package/dist/src/node_modules/.pnpm/is-stream@2.0.1/node_modules/is-stream/index.js +0 -1
- package/dist/src/node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js +0 -1
- package/dist/src/node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js +0 -1
- package/dist/src/node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/index.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwe/compact/decrypt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwe/compact/encrypt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwe/flattened/decrypt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwe/flattened/encrypt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwe/general/decrypt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwe/general/encrypt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwk/embedded.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwk/thumbprint.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwks/local.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwks/remote.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jws/compact/sign.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jws/compact/verify.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jws/flattened/sign.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jws/flattened/verify.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jws/general/sign.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jws/general/verify.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwt/decrypt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwt/encrypt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwt/produce.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwt/sign.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwt/unsecured.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/jwt/verify.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/key/export.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/key/generate_key_pair.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/key/generate_secret.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/key/import.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/aesgcmkw.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/buffer_utils.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/cek.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/check_iv_length.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/check_key_type.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/check_p2s.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/crypto_key.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/decrypt_key_management.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/encrypt_key_management.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/epoch.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/invalid_key_input.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/is_disjoint.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/is_jwk.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/is_object.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/iv.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/jwt_claims_set.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/private_symbols.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/secs.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/validate_algorithms.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/lib/validate_crit.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/aeskw.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/asn1.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/base64url.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/cbc_tag.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/check_cek_length.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/check_key_length.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/ciphers.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/decrypt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/digest.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/dsa_digest.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/ecdhes.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/encrypt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/fetch_jwks.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/generate.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/get_named_curve.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/get_sign_verify_key.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/hmac_digest.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/is_key_like.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/is_key_object.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/jwk_to_key.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/key_to_jwk.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/node_key.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/normalize_key.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/pbes2kw.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/random.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/rsaes.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/runtime.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/sign.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/timing_safe_equal.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/verify.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/runtime/webcrypto.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/util/base64url.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/util/decode_jwt.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/util/decode_protected_header.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/util/errors.js +0 -1
- package/dist/src/node_modules/.pnpm/jose@5.10.0/node_modules/jose/dist/node/cjs/util/runtime.js +0 -1
- package/dist/src/node_modules/.pnpm/merge-stream@2.0.0/node_modules/merge-stream/index.js +0 -1
- package/dist/src/node_modules/.pnpm/mimic-fn@2.1.0/node_modules/mimic-fn/index.js +0 -1
- package/dist/src/node_modules/.pnpm/minimatch@10.2.6/node_modules/minimatch/dist/esm/assert-valid-pattern.js +0 -1
- package/dist/src/node_modules/.pnpm/minimatch@10.2.6/node_modules/minimatch/dist/esm/ast.js +0 -1
- package/dist/src/node_modules/.pnpm/minimatch@10.2.6/node_modules/minimatch/dist/esm/brace-expressions.js +0 -1
- package/dist/src/node_modules/.pnpm/minimatch@10.2.6/node_modules/minimatch/dist/esm/escape.js +0 -1
- package/dist/src/node_modules/.pnpm/minimatch@10.2.6/node_modules/minimatch/dist/esm/index.js +0 -1
- package/dist/src/node_modules/.pnpm/minimatch@10.2.6/node_modules/minimatch/dist/esm/unescape.js +0 -1
- package/dist/src/node_modules/.pnpm/mixpart@0.0.6/node_modules/mixpart/dist/index.js +0 -7
- package/dist/src/node_modules/.pnpm/npm-run-path@4.0.1/node_modules/npm-run-path/index.js +0 -1
- package/dist/src/node_modules/.pnpm/onetime@5.1.2/node_modules/onetime/index.js +0 -1
- package/dist/src/node_modules/.pnpm/os-paths@4.4.0/node_modules/os-paths/src/lib/index.js +0 -1
- package/dist/src/node_modules/.pnpm/path-key@3.1.1/node_modules/path-key/index.js +0 -1
- package/dist/src/node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js +0 -1
- package/dist/src/node_modules/.pnpm/shebang-command@2.0.0/node_modules/shebang-command/index.js +0 -1
- package/dist/src/node_modules/.pnpm/shebang-regex@3.0.0/node_modules/shebang-regex/index.js +0 -1
- package/dist/src/node_modules/.pnpm/signal-exit@3.0.7/node_modules/signal-exit/index.js +0 -1
- package/dist/src/node_modules/.pnpm/signal-exit@3.0.7/node_modules/signal-exit/signals.js +0 -1
- package/dist/src/node_modules/.pnpm/strip-final-newline@2.0.0/node_modules/strip-final-newline/index.js +0 -2
- package/dist/src/node_modules/.pnpm/which@2.0.2/node_modules/which/which.js +0 -1
- package/dist/src/node_modules/.pnpm/xdg-app-paths@5.5.1/node_modules/xdg-app-paths/src/lib/index.js +0 -1
- package/dist/src/node_modules/.pnpm/xdg-portable@7.3.0/node_modules/xdg-portable/src/lib/index.js +0 -1
- package/dist/src/public/tools/load-skill.d.ts +0 -3
- package/dist/src/public/tools/load-skill.js +0 -1
- package/dist/src/runtime/skills/fragment-context.d.ts +0 -4
- package/dist/src/runtime/skills/fragment-context.js +0 -1
- package/dist/src/tools/framework/connection-tools.d.ts +0 -3
- package/dist/src/tools/framework/connection-tools.js +0 -1
- package/dist/src/tools/provided/load-skill.d.ts +0 -2
- package/dist/src/tools/provided/load-skill.js +0 -1
- /package/dist/src/extensions/{code → git}/extension/lib/github-shell-schema.d.ts +0 -0
- /package/dist/src/extensions/{code → git}/extension/lib/github-shell-schema.js +0 -0
- /package/dist/src/extensions/{code → git}/extension/lib/signed-commit.d.ts +0 -0
- /package/dist/src/extensions/{code → git}/extension/lib/signed-commit.js +0 -0
- /package/dist/src/{runtime/connections/tool-signature.js → tools/signature.js} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{deepEquals,eventMatches,subagentCallMatches,testRegExp,toolCallMatches}from"#evals/match.js";
|
|
2
|
-
`)}function failureDetail(e,t){return t===void 0?e:`${e} (code: ${t})`}function formatFailedActionResult(e){let{result:t,status:n}=e.data;return[actionResultLabel(t),`callId=${t.callId}`,`status=${n}`,t.isError===!0?`isError=true`:void 0,e.data.error?.message===void 0?void 0:`error=${e.data.error.message}`,`output=${truncate(formatUnknown(t.output))}`].filter(e=>e!==void 0).join(` `)}function actionResultLabel(e){switch(e.kind){case`tool-result`:return`tool-result:${e.toolName}`;case`subagent-result`:return`subagent-result:${e.subagentName}`;case`load-skill-result`:return
|
|
1
|
+
import{deepEquals,eventMatches,subagentCallMatches,testRegExp,toolCallMatches}from"#evals/match.js";const PASS={score:1},fail=(e,t)=>({score:0,message:e,metadata:t});function succeeded(){return{name:`succeeded`,evaluate(e){let t=runFailure(e);return t===void 0?e.derived.parked?fail(`run parked on ${e.derived.inputRequests.length} unanswered input request(s)`):PASS:t}}}function parked(){return{name:`parked`,evaluate(e){let t=runFailure(e);return t===void 0?e.derived.parked?PASS:fail(`expected the run to park on HITL input; it ended "${e.status}" with no pending requests`):t}}}function messageIncludes(e){return{name:`messageIncludes(${String(e)})`,evaluate(t){let n=joinCompletedMessages(t.events);return(typeof e==`string`?n.includes(e):testRegExp(e,n))?PASS:fail(`assistant messages did not include ${String(e)}; got: ${truncate(n)}`)}}}function calledTool(e,t={}){return validateCount(t.count),{name:`calledTool(${e})`,evaluate(n){let r=n.derived.toolCalls.filter(t=>t.name===e),i=r.filter(e=>toolCallMatches(e,t));if(matchesCount(t.count,i.length))return{score:1,metadata:{matchingCalls:i.length}};let a=r.length>0?`observed ${e} calls: ${r.map(e=>truncate(JSON.stringify(e.input))).join(`, `)}`:`observed tools: [${n.derived.toolCalls.map(e=>e.name).join(`, `)}]`,o;return o=t.count===void 0?`expected a matching call to "${e}"`:typeof t.count==`number`?`expected exactly ${t.count} matching call(s), found ${i.length}`:`expected matching call count to satisfy the count predicate, found ${i.length}`,fail(`${o}; ${a}`)}}}function loadedSkill(e,t={}){return validateCount(t.count),{name:`loadedSkill(${e})`,evaluate(n){let r=n.derived.skillLoads.filter(t=>t.skill===e).filter(e=>toolCallMatches(e,t));if(matchesCount(t.count,r.length))return{score:1,metadata:{matchingLoads:r.length}};let i=n.derived.skillLoads.map(e=>e.skill).join(`, `);return fail(`expected ${describeCount(t.count)} matching load(s) of "${e}", found ${r.length}; observed skill loads: [${i}]`)}}}function notCalledTool(e){return{name:`notCalledTool(${e})`,evaluate(t){let n=t.derived.toolCalls.filter(t=>t.name===e).length;return n===0?PASS:fail(`"${e}" was called ${n} time(s)`)}}}function toolOrder(e){return{name:`toolOrder(${e.join(` → `)})`,evaluate(t){let n=requestedTools(t.events).map(e=>e.name),r=missingOrderedName(e,n);return r===void 0?PASS:fail(`missing "${r.name}" after [${e.slice(0,r.cursor).join(`, `)}]; observed request order: [${n.join(`, `)}]`)}}}function usedNoTools(){return{name:`usedNoTools`,evaluate(e){let t=e.derived.toolCallCount;return t===0?PASS:fail(`expected no tool calls, got ${t}`,{toolCallCount:t})}}}function maxToolCalls(e){return validateCount(e),{name:`maxToolCalls(${e})`,evaluate(t){let n=t.derived.toolCallCount;return n<=e?PASS:fail(`expected at most ${e} tool calls, got ${n}`,{maxAllowed:e,toolCallCount:n})}}}function noFailedActions(){return{name:`noFailedActions`,evaluate(e){let t=e.events.filter(e=>e.type===`action.result`&&(e.data.status===`failed`||e.data.result.isError===!0));if(t.length===0)return PASS;let n=t.map(formatFailedActionResult);return fail(`${t.length} failed action(s): ${n.join(`; `)}`,{failedActions:t.map(e=>({callId:e.data.result.callId,error:e.data.error,kind:e.data.result.kind,output:e.data.result.output,status:e.data.status}))})}}}function calledSubagent(e,t={}){return validateCount(t.count),{name:`calledSubagent(${e})`,evaluate(n){let r=n.derived.subagentCalls.filter(t=>t.name===e),i=r.filter(e=>subagentCallMatches(e,t));if(matchesCount(t.count,i.length))return{score:1,metadata:{matchingCalls:i.length}};if(r.length===0){let t=n.derived.subagentCalls.map(e=>e.name);return fail(`subagent "${e}" was never called; observed: [${t.join(`, `)}]`,{observedSubagentCalls:n.derived.subagentCalls})}return fail(`subagent "${e}" was called but ${i.length} call(s) matched the constraints`,{observedSubagentCalls:r})}}}function eventsSatisfy(e,t){return{name:`eventsSatisfy(${e})`,evaluate(n){return t(n.events)?PASS:fail(`event predicate "${e}" did not hold`)}}}function typedEvent(e){return validateCount(e.count),{name:`event(${e.type})`,evaluate(t){let n=t.events.filter(t=>eventMatches(t,e));if(matchesCount(e.count,n.length))return{score:1,metadata:{matchingEvents:n.length}};let r=describeCount(e.count);return fail(`expected ${r} matching ${e.type} event(s), found ${n.length}; observed: [${t.events.map(e=>e.type).join(`, `)}]`)}}}function notEvent(e){return{name:`notEvent(${e.type})`,evaluate(t){let n=t.events.filter(t=>eventMatches(t,e));return n.length===0?PASS:fail(`expected no matching ${e.type} events, found ${n.length}`)}}}function eventOrder(e){for(let t of e)validateCount(t.count);return{name:`eventOrder(${e.map(e=>e.type).join(` → `)})`,evaluate(t){let n=-1;for(let r of e){let e=t.events.flatMap((e,t)=>eventMatches(e,r)?[t]:[]);if(!matchesCount(r.count,e.length)){let t=describeCount(r.count);return fail(`expected ${t} matching ${r.type} event(s), found ${e.length}`)}let i=e[0];if(i===void 0||i<=n)return fail(`event group ${r.type} did not occur after the previous group`);n=e[e.length-1]??n}return PASS}}}function outputEquals(e){return{name:`outputEquals`,evaluate(t){return deepEquals(t.output,e)?PASS:fail(`output ${truncate(JSON.stringify(t.output))} does not equal expected ${truncate(JSON.stringify(e))}`)}}}function outputMatches(e){return{name:`outputMatches`,async evaluate(t){let n=await e[`~standard`].validate(t.output);if(!(`issues`in n)||n.issues===void 0)return PASS;let r=n.issues.map(e=>e.message).join(`; `);return fail(`output failed schema validation: ${r}`)}}}function joinCompletedMessages(e){let t=[];for(let n of e)n.type===`message.completed`&&t.push(n.data.message);return t.join(`
|
|
2
|
+
`)}function failureDetail(e,t){return t===void 0?e:`${e} (code: ${t})`}function formatFailedActionResult(e){let{result:t,status:n}=e.data;return[actionResultLabel(t),`callId=${t.callId}`,`status=${n}`,t.isError===!0?`isError=true`:void 0,e.data.error?.message===void 0?void 0:`error=${e.data.error.message}`,`output=${truncate(formatUnknown(t.output))}`].filter(e=>e!==void 0).join(` `)}function actionResultLabel(e){switch(e.kind){case`tool-result`:return`tool-result:${e.toolName}`;case`subagent-result`:return`subagent-result:${e.subagentName}`;case`load-skill-result`:return`load-skill-result:${e.name}`}}function runFailure(e){if(e.status===`failed`)return fail(failureDetail(`run failed`,e.derived.failureCode));let t=e.events.find(e=>e.type===`turn.failed`||e.type===`step.failed`);return t===void 0?void 0:fail(`${t.type} (${t.data.code}): ${t.data.message}`)}function truncate(e,t=200){return e===void 0?`undefined`:e.length<=t?e:`${e.slice(0,t)}…`}function formatUnknown(e){if(e!==void 0){if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}}function matchesCount(e,t){return e===void 0?t>0:typeof e==`function`?e(t):t===e}function describeCount(e){return e===void 0?`at least one`:typeof e==`function`?`a count satisfying the predicate`:`exactly ${e}`}function validateCount(e){if(e!==void 0&&typeof e!=`function`&&(typeof e!=`number`||!Number.isInteger(e)||e<0))throw TypeError(`Assertion count must be a non-negative integer or predicate; received ${String(e)}.`)}function missingOrderedName(e,t){let n=0;for(let r of t)if(r===e[n]&&(n+=1),n===e.length)return;let r=e[n];return r===void 0?void 0:{cursor:n,name:r}}function requestedTools(e){let t=[],n=new Set,append=(e,r)=>{n.has(e)||(n.add(e),t.push({callId:e,name:r}))};for(let t of e)if(t.type===`actions.requested`)for(let e of t.data.actions)e.kind===`tool-call`&&append(e.callId,e.toolName);else if(t.type===`input.requested`)for(let e of t.data.requests){let{action:t}=e;t.kind===`tool-call`&&append(t.callId,t.toolName)}return t}export{calledSubagent,calledTool,eventOrder,eventsSatisfy,loadedSkill,maxToolCalls,messageIncludes,noFailedActions,notCalledTool,notEvent,outputEquals,outputMatches,parked,succeeded,toolOrder,typedEvent,usedNoTools};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"#evals/assertions/collector.js";import*as RunAssertions from"#evals/assertions/run.js";function createScopedAssertions(e,t){let n=createRecorder(e,t);return{succeeded:()=>n(RunAssertions.succeeded()),parked:()=>n(RunAssertions.parked()),messageIncludes:e=>n(RunAssertions.messageIncludes(e)),calledTool:(e,t)=>n(RunAssertions.calledTool(e,t)),loadedSkill:(e,t)=>n(RunAssertions.loadedSkill(e,t)),notCalledTool:e=>n(RunAssertions.notCalledTool(e)),toolOrder:e=>n(RunAssertions.toolOrder(e)),usedNoTools:()=>n(RunAssertions.usedNoTools()),maxToolCalls:e=>n(RunAssertions.maxToolCalls(e)),calledSubagent:(e,t)=>n(RunAssertions.calledSubagent(e,t)),noFailedActions:()=>n(RunAssertions.noFailedActions()),event:(e,t)=>n(RunAssertions.typedEvent({...t,type:e})),notEvent:(e,t)=>n(RunAssertions.notEvent({...t,type:e})),eventOrder:e=>n(RunAssertions.eventOrder(e)),eventsSatisfy:(e,t)=>n(RunAssertions.eventsSatisfy(e,t))}}function createOutputAssertions(e,t){let n=createRecorder(e,t);return{outputEquals:e=>n(RunAssertions.outputEquals(e)),outputMatches:e=>n(RunAssertions.outputMatches(e))}}function createRecorder(e,t){return t.timing===`final`?n=>e.recordScoped(n,t.select):n=>{let r=t.select();return e.recordScoped(n,()=>r)}}export{createOutputAssertions,createScopedAssertions};
|
|
1
|
+
import"#evals/assertions/collector.js";import*as RunAssertions from"#evals/assertions/run.js";import{assertReportedToolName}from"#evals/reported-tool-name.js";function createScopedAssertions(e,t){let n=createRecorder(e,t),toolName=t=>(assertReportedToolName(t,e.tools),t);return{succeeded:()=>n(RunAssertions.succeeded()),parked:()=>n(RunAssertions.parked()),messageIncludes:e=>n(RunAssertions.messageIncludes(e)),calledTool:(e,t)=>n(RunAssertions.calledTool(toolName(e),t)),loadedSkill:(e,t)=>n(RunAssertions.loadedSkill(e,t)),notCalledTool:e=>n(RunAssertions.notCalledTool(toolName(e))),toolOrder:e=>n(RunAssertions.toolOrder(e.map(toolName))),usedNoTools:()=>n(RunAssertions.usedNoTools()),maxToolCalls:e=>n(RunAssertions.maxToolCalls(e)),calledSubagent:(e,t)=>n(RunAssertions.calledSubagent(e,t)),noFailedActions:()=>n(RunAssertions.noFailedActions()),event:(e,t)=>n(RunAssertions.typedEvent({...t,type:e})),notEvent:(e,t)=>n(RunAssertions.notEvent({...t,type:e})),eventOrder:e=>n(RunAssertions.eventOrder(e)),eventsSatisfy:(e,t)=>n(RunAssertions.eventsSatisfy(e,t))}}function createOutputAssertions(e,t){let n=createRecorder(e,t);return{outputEquals:e=>n(RunAssertions.outputEquals(e)),outputMatches:e=>n(RunAssertions.outputMatches(e))}}function createRecorder(e,t){return t.timing===`final`?n=>e.recordScoped(n,t.select):n=>{let r=t.select();return e.recordScoped(n,()=>r)}}export{createOutputAssertions,createScopedAssertions};
|
|
@@ -6,6 +6,6 @@ export type { RuntimeIdentity, RuntimeTraceContext } from "#protocol/message.js"
|
|
|
6
6
|
export type { InputRequest } from "#shared/input.js";
|
|
7
7
|
export type { CancelSessionResult } from "#client/types.js";
|
|
8
8
|
export type { EveEvalCountMatcher, EveEvalEventMatch, EveEvalInputRequestMatchOptions, EveEvalValueMatcher, EveEvalToolCallMatchOptions, EveEvalSkillLoadMatchOptions, EveEvalSubagentCallMatchOptions, } from "#evals/match.js";
|
|
9
|
-
export type { Assertion, AssertionEvaluation, AssertionHandle, AssertionResult, AssertionSeverity, EveEvalActionStatus, EveEvalAgentSession, EveEvalAssertions, EveEvalContext, EveEvalDerivedFacts, EveEvalJudgeConfig, EveEvalRunSummary, EveEvalSession, EveEvalSessionResult, EveEvalScheduleDispatchResult, EveEvalSubagentCall, EveEval, EveEvalConfig, EveEvalConfigInput, EveEvalConfigContext, EveEvalDefinition, EveEvalInput, EveEvalLiveTurn, EveEvalResult, EveEvalTarget, EveEvalTargetCapabilities, EveEvalTargetHandle, EveEvalTaskResult, EveEvalTraceContext, EveEvalToolCall, EveEvalTurn, EveEvalStreamEvent, EveEvalWaitForEventOptions, EveEvalVerdict, JudgeBatch, JudgeInput, JudgeQuestion, JudgeContext, JudgeOpts, } from "#evals/types.js";
|
|
9
|
+
export type { Assertion, AssertionEvaluation, AssertionHandle, AssertionResult, AssertionSeverity, EveEvalActionStatus, EveEvalAgentSession, EveEvalAssertions, EveEvalContext, EveEvalDerivedFacts, EveEvalJudgeConfig, EveEvalRunSummary, EveEvalSession, EveEvalSessionResult, EveEvalScheduleDispatchResult, EveEvalSkillLoad, EveEvalSubagentCall, EveEval, EveEvalConfig, EveEvalConfigInput, EveEvalConfigContext, EveEvalDefinition, EveEvalInput, EveEvalLiveTurn, EveEvalResult, EveEvalTarget, EveEvalTargetCapabilities, EveEvalTargetHandle, EveEvalTaskResult, EveEvalTraceContext, EveEvalToolCall, EveEvalTurn, EveEvalStreamEvent, EveEvalWaitForEventOptions, EveEvalVerdict, JudgeBatch, JudgeInput, JudgeQuestion, JudgeContext, JudgeOpts, } from "#evals/types.js";
|
|
10
10
|
export type { MockModelMessage, MockModelOptions, MockModelRequest, MockModelResponder, MockModelResponse, MockModelTool, MockModelToolCall, MockModelToolResult, MockModelUsage, } from "#evals/mock-model.js";
|
|
11
11
|
export type { ToolStub, ToolStubOutcome } from "#tool-stubs/types.js";
|
|
@@ -38,9 +38,9 @@ export interface EveEvalToolCallMatchOptions {
|
|
|
38
38
|
readonly count?: EveEvalCountMatcher;
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
|
-
* Constraints applied to a
|
|
42
|
-
* {@link EveEvalToolCallMatchOptions} without `input`,
|
|
43
|
-
* the
|
|
41
|
+
* Constraints applied to a skill load by `t.loadedSkill`. Identical to
|
|
42
|
+
* {@link EveEvalToolCallMatchOptions} without `input`, since the skill name is
|
|
43
|
+
* the whole input.
|
|
44
44
|
*/
|
|
45
45
|
export type EveEvalSkillLoadMatchOptions = Omit<EveEvalToolCallMatchOptions, "input">;
|
|
46
46
|
/**
|
|
@@ -92,10 +92,13 @@ export type EveEvalEventMatch<TType extends MessageStreamEvent["type"] = Message
|
|
|
92
92
|
*/
|
|
93
93
|
export declare function matchesValue(matcher: unknown, value: unknown): boolean;
|
|
94
94
|
/**
|
|
95
|
-
* Returns true when one derived tool call satisfies the
|
|
96
|
-
* lifecycle constraints (the `count` option is the caller's
|
|
95
|
+
* Returns true when one derived tool call or skill load satisfies the
|
|
96
|
+
* `input`/`output`/lifecycle constraints (the `count` option is the caller's
|
|
97
|
+
* concern).
|
|
97
98
|
*/
|
|
98
|
-
export declare function toolCallMatches(call: EveEvalToolCall,
|
|
99
|
+
export declare function toolCallMatches(call: Pick<EveEvalToolCall, "output" | "status"> & {
|
|
100
|
+
readonly input?: JsonObject;
|
|
101
|
+
}, options: EveEvalToolCallMatchOptions): boolean;
|
|
99
102
|
/**
|
|
100
103
|
* Returns true when one derived subagent call satisfies the `remoteUrl`/
|
|
101
104
|
* `output` constraints.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TargetTools } from "#evals/target.js";
|
|
2
|
+
/**
|
|
3
|
+
* Throws for a tool name no call is reported under, so an assertion on it can't
|
|
4
|
+
* pass or fail without saying why. A retired name outside the `eve` namespace
|
|
5
|
+
* is still an ordinary tool name, so it passes when the root agent declares a
|
|
6
|
+
* tool by that name, has a dynamic tool resolver that might return one, or its
|
|
7
|
+
* tools are unknown.
|
|
8
|
+
*/
|
|
9
|
+
export declare function assertReportedToolName(name: string, tools: TargetTools | undefined): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{TASK_CANCEL_TOOL_NAME,TASK_WAIT_TOOL_NAME}from"#protocol/task-tools.js";import{REPLY_TOOL_NAME}from"#protocol/reply-tool.js";import{CALL_TOOL_NAME,SEARCH_TOOL_NAME,SKILL_TOOL_NAME}from"#protocol/catalog-tools.js";const UNREPORTED_TOOL_NAMES=new Map([[CALL_TOOL_NAME,`Calls through ${CALL_TOOL_NAME} are reported under the entry's name; assert on the tool or agent it reaches.`],[SKILL_TOOL_NAME,`Calls through ${SKILL_TOOL_NAME} are reported as skill loads; use t.loadedSkill(name).`],[`eve__execute`,`eve__execute isn't a tool eve registers (it's reserved for code mode); assert on the tool or agent a call reaches, or use t.loadedSkill(name).`]]),RETIRED_TOOL_NAMES=new Map([[`connection_execute`,"assert on the connection tool's own name, `<connection>__<tool>`"],[`connection_search`,`use ${SEARCH_TOOL_NAME}`],[`final_output`,`use ${REPLY_TOOL_NAME}`],[`load_skill`,`use t.loadedSkill(name)`],[`task_cancel`,`use ${TASK_CANCEL_TOOL_NAME}`],[`task_wait`,`use ${TASK_WAIT_TOOL_NAME}`]]);function assertReportedToolName(e,t){let n=UNREPORTED_TOOL_NAMES.get(e);if(n!==void 0)throw TypeError(n);let r=RETIRED_TOOL_NAMES.get(e);if(r!==void 0&&t!==void 0&&!(t.dynamic||t.static.includes(e)))throw TypeError(`Tool name "${e}" was retired; ${r}.`)}export{assertReportedToolName};
|
|
@@ -4,14 +4,14 @@ import type { EveEvalDerivedFacts } from "#evals/types.js";
|
|
|
4
4
|
* Options for {@link deriveRunFacts}.
|
|
5
5
|
*/
|
|
6
6
|
export interface DeriveRunFactsOptions {
|
|
7
|
-
/** Session id stamped onto every derived tool and subagent call. */
|
|
7
|
+
/** Session id stamped onto every derived tool call, skill load, and subagent call. */
|
|
8
8
|
readonly sessionId?: string;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Extracts derived execution facts from a completed run's stream events.
|
|
12
12
|
*
|
|
13
|
-
* Tool calls pair each `actions.requested` entry with its
|
|
14
|
-
* `action.result` by call id. Subagent calls are the calls to agent tasks,
|
|
13
|
+
* Tool calls and skill loads pair each `actions.requested` entry with its
|
|
14
|
+
* matching `action.result` by call id. Subagent calls are the calls to agent tasks,
|
|
15
15
|
* paired with their `task.settled` the same way. These facts power checks,
|
|
16
16
|
* scorers, and reporters.
|
|
17
17
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
const PARKING_EVENT_TYPES=new Set([`turn.waiting`,`turn.completed`,`session.waiting`,`session.completed`]);function deriveRunFacts(e,t){let n=t?.sessionId,r=[],i=new Map,a=new Map,o=[],s=new Map,c=[],l=[],u=-1,d=0,f=0,p=new Set,m,h,ensureToolCall=(e,t,a)=>{let o=i.get(e);if(o!==void 0)return o;let s={name:t,input:a,output:void 0,status:`pending`,turnIndex:Math.max(u,0),sessionId:n};return r.push(s),i.set(e,s),s};for(let t of e)switch(t.type){case`turn.started`:u+=1;break;case`actions.requested`:for(let e of t.data.actions)e.kind===`tool-call`?ensureToolCall(e.callId,e.toolName,e.input):e.kind===`load-skill`&&a.set(e.callId,{output:void 0,sessionId:n,skill:e.name,status:`pending`,turnIndex:Math.max(u,0)});break;case`action.result`:{let{result:e,status:n}=t.data;if(e.kind===`tool-result`){let t=ensureToolCall(e.callId,e.toolName,{});t.output=e.output,t.status=n}let r=e.kind===`load-skill-result`?a.get(e.callId):void 0;r!==void 0&&(r.output=e.output,r.status=n);break}case`task.started`:{let{callId:e,kind:n,name:r,taskId:i}=t.data;if(n!==`agent`)break;o.push({callId:e,name:r,taskId:i,turnIndex:Math.max(u,0)});break}case`task.settled`:s.set(t.data.callId,t.data);break;case`agent.started`:c.push(t.data);break;case`input.requested`:l.push(...t.data.requests);for(let e of t.data.requests)ensureToolCall(e.action.callId,e.action.toolName,e.action.input);break;case`message.completed`:t.data.finishReason!==`tool-calls`&&(d+=1);break;case`reasoning.completed`:f+=1;break;case`step.started`:p.add(t.data.modelId);break;case`session.waiting`:case`turn.waiting`:m=t.data.usage;break;case`session.completed`:m=t.data?.usage;break;case`session.failed`:m=t.data.usage,h=t.data.code}let g=deriveSubagentCalls({agentCalls:o,agentSessions:c,sessionId:n,settledTaskCalls:s});return{toolCalls:r,toolCallCount:r.length,skillLoads:[...a.values()],subagentCalls:g,subagentCallCount:g.length,inputRequests:l,parked:endedParkedOnInput(e),messageCount:d,reasoningBlockCount:f,models:[...p],usage:m,failureCode:h}}function deriveSubagentCalls(e){let t=new Map;for(let n of e.agentSessions)n.taskId!==void 0&&t.set(n.taskId,n);return e.agentCalls.map(n=>{let r=t.get(n.taskId),i=e.settledTaskCalls.get(n.callId);return{callId:n.callId,childSessionId:r?.sessionId,name:n.name,output:i?.output,remoteUrl:r?.remote?.url,sessionId:e.sessionId,status:i?.status??`working`,turnIndex:n.turnIndex}})}function createEmptyDerivedFacts(){return{toolCalls:[],toolCallCount:0,skillLoads:[],subagentCalls:[],subagentCallCount:0,inputRequests:[],parked:!1,messageCount:0,reasoningBlockCount:0,models:[]}}function endedParkedOnInput(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(!(n===void 0||PARKING_EVENT_TYPES.has(n.type)))return n.type===`input.requested`}return!1}export{createEmptyDerivedFacts,deriveRunFacts};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{toErrorMessage}from"#shared/errors.js";import{AssertionCollector}from"#evals/assertions/collector.js";import{scopeEvalTargetHandle}from"#evals/target.js";import{EvalSessionManager}from"#evals/session-manager.js";import{EvalRequirementFailed,EvalSkipped}from"#evals/control-flow.js";import{runUntilAborted}from"#evals/abort.js";import{createEmptyDerivedFacts}from"#evals/runner/derive-run-facts.js";import{addTokenUsage}from"#shared/token-usage.js";import{createEvalContext}from"#evals/context.js";async function executeTask(e){let{client:t,evaluation:n,target:r,timeoutMs:i}=e,a=i===void 0?neverAbortSignal():AbortSignal.timeout(i),o=new AssertionCollector,s=new EvalSessionManager({client:t,collector:o,onSessionStart:e.onSessionStart,signal:a}),c=scopeEvalTargetHandle(r,{sessions:s}),l=[],{context:u}=createEvalContext({setupContext:e.setupContext,collector:o,manager:s,target:c,signal:a,judge:n.judge,log:t=>{l.push(t),e.onLog?.(t)}}),d,f;try{await runUntilAborted(n.test(u),a),await runUntilAborted(s.verifyStubs(),a)}catch(e){e instanceof EvalSkipped?f=e.reason:e instanceof EvalRequirementFailed||(d=toErrorMessage(e))}if(i!==void 0&&a.aborted){let e=(await s.cleanup(AbortSignal.timeout(5e3))).flatMap(e=>e.status===`rejected`?[toErrorMessage(e.reason)]:[]);if(e.length>0){let t=`Eval timeout cleanup failed: ${e.join(`; `)}`;d=d===void 0?t:`${d}\n${t}`}}let p=buildTaskResult({logs:l,sessions:s.snapshots(),turn:s.lastTurnSession()?.lastTurn});return{result:p,assertions:await o.finalize(p),error:d,skipReason:f}}function buildTaskResult(e){let t=e.sessions.flatMap(e=>e.events),n=e.turn?.message??null;return{output:e.turn?.data===void 0?n:e.turn.data,finalMessage:n,sessionId:selectPrimarySessionId(e.sessions),status:e.turn?.status??`completed`,events:t,logs:e.logs,derived:combineDerivedFacts(e.sessions),sessions:e.sessions,runtimeIdentity:extractRuntimeIdentity(t),traceContexts:collectTraceContexts(e.sessions)}}function collectTraceContexts(e){return e.flatMap(e=>{let t=e.sessionId;return t===void 0?[]:e.traceContexts.map(n=>({...n,primary:e.primary,sessionId:t}))})}function combineDerivedFacts(e){if(e.length===0)return createEmptyDerivedFacts();let t=e.flatMap(e=>e.derived.toolCalls),n=e.flatMap(e=>e.derived.
|
|
1
|
+
import{toErrorMessage}from"#shared/errors.js";import{AssertionCollector}from"#evals/assertions/collector.js";import{scopeEvalTargetHandle,targetTools}from"#evals/target.js";import{EvalSessionManager}from"#evals/session-manager.js";import{EvalRequirementFailed,EvalSkipped}from"#evals/control-flow.js";import{runUntilAborted}from"#evals/abort.js";import{createEmptyDerivedFacts}from"#evals/runner/derive-run-facts.js";import{addTokenUsage}from"#shared/token-usage.js";import{createEvalContext}from"#evals/context.js";async function executeTask(e){let{client:t,evaluation:n,target:r,timeoutMs:i}=e,a=i===void 0?neverAbortSignal():AbortSignal.timeout(i),o=new AssertionCollector(targetTools(r)),s=new EvalSessionManager({client:t,collector:o,onSessionStart:e.onSessionStart,signal:a}),c=scopeEvalTargetHandle(r,{sessions:s}),l=[],{context:u}=createEvalContext({setupContext:e.setupContext,collector:o,manager:s,target:c,signal:a,judge:n.judge,log:t=>{l.push(t),e.onLog?.(t)}}),d,f;try{await runUntilAborted(n.test(u),a),await runUntilAborted(s.verifyStubs(),a)}catch(e){e instanceof EvalSkipped?f=e.reason:e instanceof EvalRequirementFailed||(d=toErrorMessage(e))}if(i!==void 0&&a.aborted){let e=(await s.cleanup(AbortSignal.timeout(5e3))).flatMap(e=>e.status===`rejected`?[toErrorMessage(e.reason)]:[]);if(e.length>0){let t=`Eval timeout cleanup failed: ${e.join(`; `)}`;d=d===void 0?t:`${d}\n${t}`}}let p=buildTaskResult({logs:l,sessions:s.snapshots(),turn:s.lastTurnSession()?.lastTurn});return{result:p,assertions:await o.finalize(p),error:d,skipReason:f}}function buildTaskResult(e){let t=e.sessions.flatMap(e=>e.events),n=e.turn?.message??null;return{output:e.turn?.data===void 0?n:e.turn.data,finalMessage:n,sessionId:selectPrimarySessionId(e.sessions),status:e.turn?.status??`completed`,events:t,logs:e.logs,derived:combineDerivedFacts(e.sessions),sessions:e.sessions,runtimeIdentity:extractRuntimeIdentity(t),traceContexts:collectTraceContexts(e.sessions)}}function collectTraceContexts(e){return e.flatMap(e=>{let t=e.sessionId;return t===void 0?[]:e.traceContexts.map(n=>({...n,primary:e.primary,sessionId:t}))})}function combineDerivedFacts(e){if(e.length===0)return createEmptyDerivedFacts();let t=e.flatMap(e=>e.derived.toolCalls),n=e.flatMap(e=>e.derived.skillLoads),r=e.flatMap(e=>e.derived.subagentCalls),i=e.flatMap(e=>e.derived.inputRequests),a=e.find(e=>e.derived.failureCode!==void 0)?.derived.failureCode;return{toolCalls:t,toolCallCount:t.length,skillLoads:n,subagentCalls:r,subagentCallCount:r.length,inputRequests:i,parked:e.some(e=>e.derived.parked),messageCount:sum(e,e=>e.derived.messageCount),reasoningBlockCount:sum(e,e=>e.derived.reasoningBlockCount),models:[...new Set(e.flatMap(e=>e.derived.models))],usage:evalUsage(e),failureCode:a}}function evalUsage(e){let t=new Set(e.flatMap(e=>e.events.flatMap(e=>e.type===`agent.started`?[e.data.sessionId]:[]))),n=[...new Map(e.map(e=>[e.sessionId,e.derived.usage]))].flatMap(([e,n])=>e!==void 0&&t.has(e)?[]:[n]);if(n.every(e=>e!==void 0))return n.reduce(addTokenUsage)}function selectPrimarySessionId(e){return e.find(e=>e.primary)?.sessionId??e[0]?.sessionId}function extractRuntimeIdentity(e){for(let t of e)if(t.type===`session.started`&&t.data.runtime!==void 0)return t.data.runtime}function sum(e,t){return e.reduce((e,n)=>e+t(n),0)}function neverAbortSignal(){return new AbortController().signal}export{executeTask};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{composeAssertionScoreMetadata,groupAssertionScores}from"#evals/runner/reporters/assertion-scores.js";import{resolveLocalGitMetadata}from"#evals/runner/resolve-git-metadata.js";function Braintrust(e={}){return new BraintrustReporter(e)}var BraintrustReporter=class{#e;#t;#n;#r=new Map;constructor(e){this.#e=e}async onRunStart(e,t){let n=await loadBraintrustSdk();this.#t=n;let r=resolveLocalGitMetadata(process.cwd());this.#r.clear();for(let t of e)this.#r.set(t.id,t);let i=resolveTags(e,t),a=resolveExperimentMetadata(e,t);this.#n=await n.init({project:this.#e.projectName??e[0]?.id??`eve evals`,projectId:this.#e.projectId,experiment:this.#e.experimentName,baseExperiment:this.#e.baseExperimentName,baseExperimentId:this.#e.baseExperimentId,update:this.#e.update,tags:i,metadata:a,noExitFlush:!0,setCurrent:!1,repoInfo:r.sha?{commit:r.sha,branch:r.branch}:null})}onEvalComplete(e){if(!this.#n)return;let t=this.#r.get(e.id),n={},r=groupAssertionScores(e.assertions,e=>e.severity===`gate`?`gate:${e.name}`:e.name);for(let[e,t]of r)n[e]=t.score;let i=e.assertions.filter(e=>!e.passed).map(e=>({...e})),a={...t?.metadata,eveSessionId:e.result.sessionId,eveStatus:e.result.status,eveVerdict:e.verdict,eveSkipReason:e.skipReason,eveToolCalls:e.result.derived.toolCalls.map(e=>e.name),eveSubagentCalls:e.result.derived.subagentCalls.map(e=>e.name),eveParked:e.result.derived.parked,eveAssertionScores:composeAssertionScoreMetadata(e.assertions)};e.result.traceContexts.length>0&&(a.eveTraceIds=[...new Set(e.result.traceContexts.map(e=>e.traceId))],a.eveTraceContexts=e.result.traceContexts),i.length>0&&(a.eveFailedAssertions=i),e.result.derived.failureCode&&(a.eveFailureCode=e.result.derived.failureCode);let o={toolCallCount:e.result.derived.toolCallCount,subagentCallCount:e.result.derived.subagentCallCount,messageCount:e.result.derived.messageCount,reasoningBlockCount:e.result.derived.reasoningBlockCount};this.#n.log({id:e.id,input:t?.description??``,output:e.result.output,error:e.error??void 0,scores:n,metadata:a,metrics:o,tags:t?.tags?[...t.tags]:void 0})}async onRunComplete(e){if(this.#n)try{this.#t&&await this.#t.flush();let e=await this.#n.summarize();e.experimentUrl&&console.log(`Braintrust experiment: ${e.experimentUrl}\n\n`)}finally{await this.#n.close(),this.#n=void 0,this.#t=void 0}}};async function loadBraintrustSdk(){try{return await import(`braintrust`)}catch{throw Error([`The 'braintrust' package is required for Braintrust reporting but was not found.`,``,`Install it with:`,` npm install braintrust`].join(`
|
|
1
|
+
import{composeAssertionScoreMetadata,groupAssertionScores}from"#evals/runner/reporters/assertion-scores.js";import{resolveLocalGitMetadata}from"#evals/runner/resolve-git-metadata.js";function Braintrust(e={}){return new BraintrustReporter(e)}var BraintrustReporter=class{#e;#t;#n;#r=new Map;constructor(e){this.#e=e}async onRunStart(e,t){let n=await loadBraintrustSdk();this.#t=n;let r=resolveLocalGitMetadata(process.cwd());this.#r.clear();for(let t of e)this.#r.set(t.id,t);let i=resolveTags(e,t),a=resolveExperimentMetadata(e,t);this.#n=await n.init({project:this.#e.projectName??e[0]?.id??`eve evals`,projectId:this.#e.projectId,experiment:this.#e.experimentName,baseExperiment:this.#e.baseExperimentName,baseExperimentId:this.#e.baseExperimentId,update:this.#e.update,tags:i,metadata:a,noExitFlush:!0,setCurrent:!1,repoInfo:r.sha?{commit:r.sha,branch:r.branch}:null})}onEvalComplete(e){if(!this.#n)return;let t=this.#r.get(e.id),n={},r=groupAssertionScores(e.assertions,e=>e.severity===`gate`?`gate:${e.name}`:e.name);for(let[e,t]of r)n[e]=t.score;let i=e.assertions.filter(e=>!e.passed).map(e=>({...e})),a={...t?.metadata,eveSessionId:e.result.sessionId,eveStatus:e.result.status,eveVerdict:e.verdict,eveSkipReason:e.skipReason,eveToolCalls:e.result.derived.toolCalls.map(e=>e.name),eveSubagentCalls:e.result.derived.subagentCalls.map(e=>e.name),eveSkillLoads:e.result.derived.skillLoads.map(e=>e.skill),eveParked:e.result.derived.parked,eveAssertionScores:composeAssertionScoreMetadata(e.assertions)};e.result.traceContexts.length>0&&(a.eveTraceIds=[...new Set(e.result.traceContexts.map(e=>e.traceId))],a.eveTraceContexts=e.result.traceContexts),i.length>0&&(a.eveFailedAssertions=i),e.result.derived.failureCode&&(a.eveFailureCode=e.result.derived.failureCode);let o={toolCallCount:e.result.derived.toolCallCount,subagentCallCount:e.result.derived.subagentCallCount,messageCount:e.result.derived.messageCount,reasoningBlockCount:e.result.derived.reasoningBlockCount};this.#n.log({id:e.id,input:t?.description??``,output:e.result.output,error:e.error??void 0,scores:n,metadata:a,metrics:o,tags:t?.tags?[...t.tags]:void 0})}async onRunComplete(e){if(this.#n)try{this.#t&&await this.#t.flush();let e=await this.#n.summarize();e.experimentUrl&&console.log(`Braintrust experiment: ${e.experimentUrl}\n\n`)}finally{await this.#n.close(),this.#n=void 0,this.#t=void 0}}};async function loadBraintrustSdk(){try{return await import(`braintrust`)}catch{throw Error([`The 'braintrust' package is required for Braintrust reporting but was not found.`,``,`Install it with:`,` npm install braintrust`].join(`
|
|
2
2
|
`))}}function resolveTags(e,t){let n=new Set([`eve`,`target:${t.kind}`]);for(let t of e){n.add(`eval:${t.id}`);for(let e of t.tags??[])n.add(e)}return[...n]}function resolveExperimentMetadata(e,t){return{eveEvalIds:e.map(e=>e.id),eveTargetKind:t.kind,eveTargetUrl:t.url,eveTimestamp:new Date().toISOString()}}export{Braintrust};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EveEvalTraceContext } from "#evals/types.js";
|
|
2
|
+
/** Identifies one runtime trace by the IDs Datadog's APM-to-LLMObs indexer assigns. */
|
|
3
|
+
export interface ExperimentRuntimeTraceLink {
|
|
4
|
+
readonly relation: "experiment_runtime";
|
|
5
|
+
readonly traceId: string;
|
|
6
|
+
readonly spanId: string;
|
|
7
|
+
readonly sessionId: string;
|
|
8
|
+
readonly primary: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** Converts sampled runtime trace contexts to Datadog-indexed links; skips the rest. */
|
|
11
|
+
export declare function resolveRuntimeTraceLinks(traceContexts: readonly EveEvalTraceContext[]): ExperimentRuntimeTraceLink[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash}from"node:crypto";const DATADOG_LLMOBS_TRACE_ID_NAMESPACE=Buffer.from(`f47ac10b58cc4372a5670e02b2c3d479`,`hex`),W3C_TRACE_ID_PATTERN=/^[0-9a-f]{32}$/iu,W3C_SPAN_ID_PATTERN=/^[0-9a-f]{16}$/iu;function resolveRuntimeTraceLinks(e){return e.flatMap(e=>{if(!(e.traceFlags&1))return[];let t=toDatadogLlmobsTraceId(e.traceId),n=toDatadogLlmobsSpanId(e.spanId);return t===void 0||n===void 0?[]:[{relation:`experiment_runtime`,traceId:t,spanId:n,sessionId:e.sessionId,primary:e.primary}]})}function toDatadogLlmobsTraceId(e){let t=e.toLowerCase();if(!W3C_TRACE_ID_PATTERN.test(t)||/^0+$/u.test(t))return;let n=t.slice(-16).padStart(32,`0`),r=createHash(`sha1`).update(DATADOG_LLMOBS_TRACE_ID_NAMESPACE).update(n).digest().subarray(0,16);return r[6]=r[6]&15|80,r[8]=r[8]&63|128,r.toString(`hex`)}function toDatadogLlmobsSpanId(e){if(W3C_SPAN_ID_PATTERN.test(e)&&!/^0+$/u.test(e))return BigInt(`0x${e}`).toString(10)}export{resolveRuntimeTraceLinks};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{composeAssertionScoreMetadata,groupAssertionScores}from"#evals/runner/reporters/assertion-scores.js";import{resolveLocalGitMetadata}from"#evals/runner/resolve-git-metadata.js";import{MISSING_DATASET_API_MESSAGE,getDatadogDataset,resolveDatadogClient,toDatadogJsonRecord,toDatadogJsonValue,toOptionalDatadogJsonValue}from"#evals/runner/reporters/datadog-client.js";function Datadog(e={}){return new DatadogReporter(e)}var DatadogReporter=class{#e;#t;#n=new Map;#r=new Map;#i;#a;#o;#s;constructor(e){this.#e=e,this.#t={recordInputs:e.recordInputs??!0,recordOutputs:e.recordOutputs??!0,recordExpectedOutputs:e.recordExpectedOutputs??!0,recordAssertionDetails:e.recordAssertionDetails??!0,recordErrors:e.recordErrors??!0}}async onRunStart(e,t){this.#i=void 0,this.#a=void 0,this.#o=void 0,this.#s=void 0,this.#n.clear();for(let t of e)this.#n.set(t.id,t);if(this.#r=composeDatasetRecordKeys(e),!this.#e.client&&(!process.env.DD_API_KEY||!process.env.DD_APP_KEY)){(this.#e.log??console.log)(`Datadog reporting skipped: set DD_API_KEY and DD_APP_KEY to upload eval results.
|
|
2
|
-
`);return}let n=resolveProjectName(this.#e,e),r=await resolveDatadogClient(this.#e,n),i=resolveLocalGitMetadata(process.cwd()),a=this.#e.experimentName??defaultExperimentName(),o=resolveExperimentMetadata(e,t);i.sha&&(o.eveGitCommit=i.sha,o.eveGitBranch=i.branch),Object.assign(o,this.#e.metadata);let s=this.#t.recordInputs?`${n} evals`:`${a} dataset`,c={name:a,projectName:n,description:this.#e.description,dataset:{name:this.#e.datasetName??s},tags:resolveExperimentTags(this.#e,t),metadata:toDatadogJsonRecord(o),config:toDatadogJsonRecord(this.#e.config)};if(this.#t.recordInputs){if(!r.createDataset||!r.pullDataset)throw Error(MISSING_DATASET_API_MESSAGE);this.#i=r,this.#a=c;return}this.#o=await r.startExperiment(c)}async onEvalComplete(e){!this.#t.recordInputs&&this.#o&&await this.#d(e)}async onRunComplete(e){try{if(this.#t.recordInputs&&await this.#c(e.results),!this.#o)return;let t=e.failed>0||e.errored>0;await this.#o.close({status:t?`failed`:`completed`,error:t?`${e.failed} failed, ${e.errored} errored`:void 0});let n=this.#e.log??console.log;this.#s&&n(`Datadog dataset URL: ${this.#s}\n`);let r=this.#o.url();r&&n(`Datadog experiment URL: ${r}\n`)}finally{this.#i=void 0,this.#a=void 0,this.#o=void 0,this.#s=void 0}}async#c(e){let t=this.#i,n=this.#a;if(!t||!n)return;let r=n.dataset?.name??`${n.projectName} evals`,i=await getDatadogDataset(t,r,{projectName:n.projectName,description:this.#e.description??`eve eval inputs.`}),a=new Map;for(let[e,t]of i.records().entries()){let n=t.metadata[DATASET_RECORD_KEY_METADATA];typeof n==`string`&&a.set(n,e)}let o=[];for(let t of e){let e=this.#u(t),n=a.get(this.#l(t.id));if(n===void 0){o.push({inputData:e.input,metadata:e.metadata,...e.expectedOutput===null?{}:{expectedOutput:e.expectedOutput}});continue}let r=i.records()[n];r&&!isDatasetRecordEqual(r,e)&&i.update(n,e)}o.length>0&&i.addRecords(o),await i.push();let s=i.id();if(!s)throw Error(`Datadog dataset '${r}' has no id after push().`);let c=new Map;for(let e of i.records()){let t=e.metadata[DATASET_RECORD_KEY_METADATA];typeof t==`string`&&e.id&&c.set(t,e.id)}let l={id:s,name:i.name()},u=i.version()??i.latestVersion();u!==null&&(l.version=u),this.#s=i.url()??void 0,this.#o=await t.startExperiment({...n,dataset:l});for(let t of e){let e=this.#l(t.id),n=c.get(e);if(!n)throw Error(`Datadog dataset '${r}' has no record id for '${e}' after push().`);await this.#d(t,n)}}#l(e){return this.#r.get(e)??e}#u(e){let t=this.#n.get(e.id),n=this.#t.recordExpectedOutputs?toOptionalDatadogJsonValue(resolveExpectedOutput(t)):void 0;return{input:toDatadogJsonValue(resolveInput(e,t)),expectedOutput:n??null,metadata:{[DATASET_RECORD_KEY_METADATA]:this.#l(e.id),eveEvalId:e.id}}}async#d(e,t){if(!this.#o)return;let n=this.#n.get(e.id),r={name:e.id,metadata:toDatadogJsonRecord(resolveResultMetadata(e,n,this.#t.recordAssertionDetails)),tags:resolveResultTags(e,n),startedAt:e.startedAt,completedAt:e.completedAt,durationMs:elapsedMs(e.startedAt,e.completedAt)};this.#t.recordInputs&&(r.input=toOptionalDatadogJsonValue(resolveInput(e,n))),this.#t.recordOutputs&&(r.output=toOptionalDatadogJsonValue(e.result.output)),this.#t.recordExpectedOutputs&&(r.expectedOutput=toOptionalDatadogJsonValue(resolveExpectedOutput(n))),this.#t.recordErrors&&e.error!==void 0&&(r.error=e.error),t!==void 0&&(r.datasetRecordId=t);let i=await this.#o.submitSpan(r);await this.#o.submitEvaluationMetrics(i,resolveEvaluationMetrics(e))}};const EXPECTED_OUTPUT_METADATA_KEYS=new Set([`expectedOutput`,`expected`,`expected_output`]),BUILT_IN_METRIC_LABELS=[`eve_tool_call_count`,`eve_subagent_call_count`,`eve_message_count`,`eve_reasoning_block_count`],DATASET_RECORD_KEY_METADATA=`eveRecordKey`;function composeDatasetRecordKeys(e){let t=new Map,n=new Map;for(let r of e){let e=r.description?.trim()||r.id,i=(n.get(e)??0)+1;n.set(e,i),t.set(r.id,i===1?e:`${e} #${i}`)}return t}function isDatasetRecordEqual(e,t){return JSON.stringify(e.input)===JSON.stringify(t.input)&&JSON.stringify(e.expectedOutput??null)===JSON.stringify(t.expectedOutput)&&JSON.stringify(e.metadata)===JSON.stringify(t.metadata)}function resolveProjectName(e,t){return e.projectName??process.env.DD_LLMOBS_PROJECT_NAME??e.mlApp??process.env.DD_LLMOBS_ML_APP??process.env.DD_SERVICE??t[0]?.id??`eve evals`}function defaultExperimentName(){return`eve evals ${new Date().toISOString()}`}function resolveExperimentTags(e,t){return{source:`eve`,target_kind:t.kind,...e.tags}}function resolveExperimentMetadata(e,t){let n={eveEvalIds:e.map(e=>e.id),eveTargetKind:t.kind,eveTimestamp:new Date().toISOString()},r=resolveTargetOrigin(t.url);return r!==void 0&&(n.eveTargetOrigin=r),n}function resolveTargetOrigin(e){try{let t=new URL(e).origin;return t===`null`?void 0:t}catch{return}}function resolveResultTags(e,t){let n={eval_id:e.id,eval_verdict:e.verdict,eval_status:e.result.status};return t?.tags?.length&&(n.eval_tags=t.tags.join(`,`)),n}function resolveInput(e,t){for(let t of e.result.events)if(t.type===`message.received`)return t.data.message;return t?.description??``}function resolveExpectedOutput(e){if(e?.metadata)return e.metadata.expectedOutput??e.metadata.expected??e.metadata.expected_output}function resolveResultMetadata(e,t,n){let r={};for(let[e,n]of Object.entries(t?.metadata??{}))EXPECTED_OUTPUT_METADATA_KEYS.has(e)||(r[e]=n);
|
|
1
|
+
import{composeAssertionScoreMetadata,groupAssertionScores}from"#evals/runner/reporters/assertion-scores.js";import{resolveLocalGitMetadata}from"#evals/runner/resolve-git-metadata.js";import{resolveRuntimeTraceLinks}from"#evals/runner/reporters/datadog-runtime-trace-links.js";import{MISSING_DATASET_API_MESSAGE,getDatadogDataset,resolveDatadogClient,toDatadogJsonRecord,toDatadogJsonValue,toOptionalDatadogJsonValue}from"#evals/runner/reporters/datadog-client.js";function Datadog(e={}){return new DatadogReporter(e)}var DatadogReporter=class{#e;#t;#n=new Map;#r=new Map;#i;#a;#o;#s;constructor(e){this.#e=e,this.#t={recordInputs:e.recordInputs??!0,recordOutputs:e.recordOutputs??!0,recordExpectedOutputs:e.recordExpectedOutputs??!0,recordAssertionDetails:e.recordAssertionDetails??!0,recordErrors:e.recordErrors??!0}}async onRunStart(e,t){this.#i=void 0,this.#a=void 0,this.#o=void 0,this.#s=void 0,this.#n.clear();for(let t of e)this.#n.set(t.id,t);if(this.#r=composeDatasetRecordKeys(e),!this.#e.client&&(!process.env.DD_API_KEY||!process.env.DD_APP_KEY)){(this.#e.log??console.log)(`Datadog reporting skipped: set DD_API_KEY and DD_APP_KEY to upload eval results.
|
|
2
|
+
`);return}let n=resolveProjectName(this.#e,e),r=await resolveDatadogClient(this.#e,n),i=resolveLocalGitMetadata(process.cwd()),a=this.#e.experimentName??defaultExperimentName(),o=resolveExperimentMetadata(e,t);i.sha&&(o.eveGitCommit=i.sha,o.eveGitBranch=i.branch),Object.assign(o,this.#e.metadata);let s=this.#t.recordInputs?`${n} evals`:`${a} dataset`,c={name:a,projectName:n,description:this.#e.description,dataset:{name:this.#e.datasetName??s},tags:resolveExperimentTags(this.#e,t),metadata:toDatadogJsonRecord(o),config:toDatadogJsonRecord(this.#e.config)};if(this.#t.recordInputs){if(!r.createDataset||!r.pullDataset)throw Error(MISSING_DATASET_API_MESSAGE);this.#i=r,this.#a=c;return}this.#o=await r.startExperiment(c)}async onEvalComplete(e){!this.#t.recordInputs&&this.#o&&await this.#d(e)}async onRunComplete(e){try{if(this.#t.recordInputs&&await this.#c(e.results),!this.#o)return;let t=e.failed>0||e.errored>0;await this.#o.close({status:t?`failed`:`completed`,error:t?`${e.failed} failed, ${e.errored} errored`:void 0});let n=this.#e.log??console.log;this.#s&&n(`Datadog dataset URL: ${this.#s}\n`);let r=this.#o.url();r&&n(`Datadog experiment URL: ${r}\n`)}finally{this.#i=void 0,this.#a=void 0,this.#o=void 0,this.#s=void 0}}async#c(e){let t=this.#i,n=this.#a;if(!t||!n)return;let r=n.dataset?.name??`${n.projectName} evals`,i=await getDatadogDataset(t,r,{projectName:n.projectName,description:this.#e.description??`eve eval inputs.`}),a=new Map;for(let[e,t]of i.records().entries()){let n=t.metadata[DATASET_RECORD_KEY_METADATA];typeof n==`string`&&a.set(n,e)}let o=[];for(let t of e){let e=this.#u(t),n=a.get(this.#l(t.id));if(n===void 0){o.push({inputData:e.input,metadata:e.metadata,...e.expectedOutput===null?{}:{expectedOutput:e.expectedOutput}});continue}let r=i.records()[n];r&&!isDatasetRecordEqual(r,e)&&i.update(n,e)}o.length>0&&i.addRecords(o),await i.push();let s=i.id();if(!s)throw Error(`Datadog dataset '${r}' has no id after push().`);let c=new Map;for(let e of i.records()){let t=e.metadata[DATASET_RECORD_KEY_METADATA];typeof t==`string`&&e.id&&c.set(t,e.id)}let l={id:s,name:i.name()},u=i.version()??i.latestVersion();u!==null&&(l.version=u),this.#s=i.url()??void 0,this.#o=await t.startExperiment({...n,dataset:l});for(let t of e){let e=this.#l(t.id),n=c.get(e);if(!n)throw Error(`Datadog dataset '${r}' has no record id for '${e}' after push().`);await this.#d(t,n)}}#l(e){return this.#r.get(e)??e}#u(e){let t=this.#n.get(e.id),n=this.#t.recordExpectedOutputs?toOptionalDatadogJsonValue(resolveExpectedOutput(t)):void 0;return{input:toDatadogJsonValue(resolveInput(e,t)),expectedOutput:n??null,metadata:{[DATASET_RECORD_KEY_METADATA]:this.#l(e.id),eveEvalId:e.id}}}async#d(e,t){if(!this.#o)return;let n=this.#n.get(e.id),r={name:e.id,metadata:toDatadogJsonRecord(resolveResultMetadata(e,n,this.#t.recordAssertionDetails)),tags:resolveResultTags(e,n),startedAt:e.startedAt,completedAt:e.completedAt,durationMs:elapsedMs(e.startedAt,e.completedAt)};this.#t.recordInputs&&(r.input=toOptionalDatadogJsonValue(resolveInput(e,n))),this.#t.recordOutputs&&(r.output=toOptionalDatadogJsonValue(e.result.output)),this.#t.recordExpectedOutputs&&(r.expectedOutput=toOptionalDatadogJsonValue(resolveExpectedOutput(n))),this.#t.recordErrors&&e.error!==void 0&&(r.error=e.error),t!==void 0&&(r.datasetRecordId=t);let i=await this.#o.submitSpan(r);await this.#o.submitEvaluationMetrics(i,resolveEvaluationMetrics(e))}};const EXPECTED_OUTPUT_METADATA_KEYS=new Set([`expectedOutput`,`expected`,`expected_output`]),BUILT_IN_METRIC_LABELS=[`eve_tool_call_count`,`eve_subagent_call_count`,`eve_message_count`,`eve_reasoning_block_count`],DATASET_RECORD_KEY_METADATA=`eveRecordKey`;function composeDatasetRecordKeys(e){let t=new Map,n=new Map;for(let r of e){let e=r.description?.trim()||r.id,i=(n.get(e)??0)+1;n.set(e,i),t.set(r.id,i===1?e:`${e} #${i}`)}return t}function isDatasetRecordEqual(e,t){return JSON.stringify(e.input)===JSON.stringify(t.input)&&JSON.stringify(e.expectedOutput??null)===JSON.stringify(t.expectedOutput)&&JSON.stringify(e.metadata)===JSON.stringify(t.metadata)}function resolveProjectName(e,t){return e.projectName??process.env.DD_LLMOBS_PROJECT_NAME??e.mlApp??process.env.DD_LLMOBS_ML_APP??process.env.DD_SERVICE??t[0]?.id??`eve evals`}function defaultExperimentName(){return`eve evals ${new Date().toISOString()}`}function resolveExperimentTags(e,t){return{source:`eve`,target_kind:t.kind,...e.tags}}function resolveExperimentMetadata(e,t){let n={eveEvalIds:e.map(e=>e.id),eveTargetKind:t.kind,eveTimestamp:new Date().toISOString()},r=resolveTargetOrigin(t.url);return r!==void 0&&(n.eveTargetOrigin=r),n}function resolveTargetOrigin(e){try{let t=new URL(e).origin;return t===`null`?void 0:t}catch{return}}function resolveResultTags(e,t){let n={eval_id:e.id,eval_verdict:e.verdict,eval_status:e.result.status};return t?.tags?.length&&(n.eval_tags=t.tags.join(`,`)),n}function resolveInput(e,t){for(let t of e.result.events)if(t.type===`message.received`)return t.data.message;return t?.description??``}function resolveExpectedOutput(e){if(e?.metadata)return e.metadata.expectedOutput??e.metadata.expected??e.metadata.expected_output}function resolveResultMetadata(e,t,n){let r={};for(let[e,n]of Object.entries(t?.metadata??{}))EXPECTED_OUTPUT_METADATA_KEYS.has(e)||(r[e]=n);Object.assign(r,{eveSessionId:e.result.sessionId,eveStatus:e.result.status,eveVerdict:e.verdict,eveSkipReason:e.skipReason,eveToolCalls:e.result.derived.toolCalls.map(e=>e.name),eveSubagentCalls:e.result.derived.subagentCalls.map(e=>e.name),eveSkillLoads:e.result.derived.skillLoads.map(e=>e.skill),eveParked:e.result.derived.parked});let i=resolveRuntimeTraceLinks(e.result.traceContexts);if(i.length>0&&(r.experimentRuntimeTraceLinks=i),n){let t=e.assertions.filter(e=>!e.passed).map(e=>({name:e.name,message:e.message}));t.length>0&&(r.eveFailedAssertions=t),r.eveAssertionScores=composeAssertionScoreMetadata(e.assertions)}return e.result.derived.failureCode&&(r.eveFailureCode=e.result.derived.failureCode),r}function resolveEvaluationMetrics(e){let t=[],n=new Set(BUILT_IN_METRIC_LABELS),r=groupAssertionScores(e.assertions,e=>toDatadogMetricLabel(e.severity===`gate`?`gate_${e.name}`:e.name));for(let[e,i]of r)t.push({label:reserveDatadogMetricLabel(e,n),value:i.score,tags:{assertion_severity:i.assertions[0]?.severity??`soft`,assertion_passed:String(i.assertions.every(e=>e.passed)),assertion_count:String(i.assertions.length)}});return t.push({label:`eve_tool_call_count`,value:e.result.derived.toolCallCount},{label:`eve_subagent_call_count`,value:e.result.derived.subagentCallCount},{label:`eve_message_count`,value:e.result.derived.messageCount},{label:`eve_reasoning_block_count`,value:e.result.derived.reasoningBlockCount}),t}function toDatadogMetricLabel(e){return e.replace(/[^a-zA-Z0-9_-]+/g,`_`).replace(/^_+|_+$/g,``)||`metric`}function reserveDatadogMetricLabel(e,t){let n=e,r=2;for(;t.has(n);)n=`${e}_${r}`,r+=1;return t.add(n),n}function elapsedMs(e,t){let n=Date.parse(e),r=Date.parse(t);if(Number.isFinite(n)&&Number.isFinite(r))return Math.max(1,r-n)}export{Datadog};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readFile}from"node:fs/promises";import{basename}from"node:path";import{TurnSegment,summarizeTurnEvents}from"#client/session-utils.js";import{isTurnFailureEvent}from"#protocol/message.js";import{createTextWithFileContent}from"#client/file-parts.js";import{extractCompletedResult}from"#client/output-schema.js";import{inputRequestMatches,matchesValue,toolCallMatches}from"#evals/match.js";import"#evals/assertions/collector.js";import{createOutputAssertions,createScopedAssertions}from"#evals/assertions/scoped.js";import{EvalRequirementFailed}from"#evals/control-flow.js";import{deriveRunFacts}from"#evals/runner/derive-run-facts.js";import{formatEvalTranscript,inferMediaType}from"#evals/session-content.js";var EveEvalTurnFailedError=class extends Error{event;turn;constructor(e){let t=e.events.find(isTurnFailureEvent),n=t===void 0?`turn ended with status "${e.status}"`:`${t.type}: ${t.data.code} ${t.data.message}`.trim();super(`Eval turn failed: ${n}`),this.name=`EveEvalTurnFailedError`,this.event=t,this.turn=e}},EvalSessionDriver=class{#e;#t;#n=``;#r;#i;#a=[];#o;#s;#c=[];#l=new Set;#u;#d=!1;#f=[];constructor(e){this.#i=e.collector,this.#s=e.onSessionStart,this.#o=e.primary,this.#e=e.session,this.#t=e.onTurn,this.#r=e.signal,Object.assign(this,createScopedAssertions(this.#i,{timing:`snapshot`,select:()=>this.#_()}),createOutputAssertions(this.#i,{timing:`snapshot`,select:()=>this.#_()}))}get events(){return this.#a}get transcript(){return formatEvalTranscript(this.#a)}get lastInput(){return this.#n}get lastTurn(){return this.#u}get pendingInputRequests(){return this.#f}get sessionId(){return this.#e.state.sessionId}get state(){return this.#e.state}async cancel(){return await this.#e.cancel()}async compact(){if((await this.#e.compact()).status!==`accepted`)throw Error(`compact() found no active session for "${this.sessionId}".`);return await this.readTurn()}agent(e){let t=this.#e.agent(e),n=this.#r;return{name:t.name,sessionId:t.sessionId,stream:(e={})=>t.stream({...e,signal:e.signal??n}),taskId:t.taskId}}async cleanup(e){await this.#e.reset({reason:`Eval timed out`,signal:e})}requireInputRequest(e={}){this.#f.length===0&&this.#v(`requireInputRequest`,`expected one pending input request, but the last turn did not park`);let t=this.#f.filter(t=>inputRequestMatches(t,e));return(this.#f.length!==1||t.length!==1)&&this.#v(`requireInputRequest`,`expected exactly one pending input request matching ${formatInputRequestFilter(e)}, found ${t.length} match(es) across ${this.#f.length} pending request(s)`),this.#i.recordOutcome({name:`requireInputRequest`,outcome:{score:1}}),t[0]}async respond(e,t={}){if(e.length===0)throw Error(`respond() requires at least one input response.`);return await(await this.#p({...t,inputResponses:e})).result()}async startRespond(e,t={}){if(e.length===0)throw Error(`startRespond() requires input responses.`);return await this.#p({...t,inputResponses:e})}async respondAll(e){let t=this.#f;if(t.length===0)throw Error(`respondAll() requires at least one pending input request.`);for(let n of t)assertRequestHasOption(n,e);return await this.respond(t.map(t=>({optionId:e,requestId:t.requestId})))}async send(e,t={}){return await(await this.#p({turnPolicy:`queue`,...t,message:e})).result()}async start(e,t={}){return await this.#p({turnPolicy:`queue`,...t,message:e})}async#p(e){let{inputResponses:t,message:n,...r}=attachSignal(e,this.#r),i=t===void 0?await this.#e.send(n,r):await this.#e.respond(t,r);return this.consume(i,n)}consume(e,t){let n=this.sessionId;return new EvalLiveTurn({events:e,observe:e=>this.#m(n,e),record:e=>(t!==void 0&&(this.#n=typeof t==`string`?t:t.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
2
|
-
`)),this.#g(n,e)),session:this,sessionId:n})}async sendFile(e,t,n){let r=await readFile(t),i=createTextWithFileContent({bytes:r,filename:basename(t),mediaType:n??inferMediaType(t),text:e});return await this.send(i)}async readTurn(e){return await this.watchTurn(e).result()}watchTurn(e){return this.consume(this.#e.stream({signal:this.#r,startIndex:e?.startIndex}))}snapshot(){let e=this.sessionId;return{derived:deriveRunFacts(this.#a,{sessionId:e}),events:[...this.#a],primary:this.#o,sessionId:e,state:this.#e.state,traceContexts:[...this.#c]}}#m(e,t){if(t.type!==`session.started`&&t.type!==`turn.started`)return;let n=t.data.trace;if(n===void 0)return;let r=`${n.traceId}:${n.spanId}`;this.#l.has(r)||(this.#l.add(r),this.#c.push(n),!this.#d&&(this.#d=!0,this.#s?.({primary:this.#o,sessionId:e,startedAt:t.meta.at,traceContext:n})))}#h(e){this.#a.push(...e.events),this.#f=e.status===`waiting`?e.inputRequests:[];let t=deriveRunFacts(e.events,{sessionId:e.sessionId}),n=new EvalTurn({collector:this.#i,data:e.data,derived:t,events:e.events,inputRequests:e.inputRequests,message:e.message,session:this,sessionId:e.sessionId,status:e.status,toolCalls:t.toolCalls});return this.#u=n,this.#t(this),n}#g(e,t){let n=summarizeTurnEvents(t);return this.#h({data:extractCompletedResult(t),events:t,inputRequests:n.inputRequests,message:n.message,sessionId:e,status:n.status})}#_(){let e=this.sessionId;return{derived:deriveRunFacts(this.#a,{sessionId:e}),events:[...this.#a],output:outputOf(this.#u),status:this.#u?.status??`completed`}}#v(e,t){throw this.#i.recordOutcome({name:e,outcome:{score:0,message:t}}),new EvalRequirementFailed}},EvalLiveTurn=class{session;sessionId;#e;#t=[];#n=new Set;#r;constructor(e){this.session=e.session,this.sessionId=e.sessionId,this.#e=this.#i(e.events,e.observe,e.record),this.#e.catch(()=>{})}get events(){return this.#t}async cancel(){return await this.session.cancel()}async result(){return await this.#e}async waitForEvent(e,t){let matches=n=>n.type===e&&(t?.data===void 0||matchesValue(t.data,`data`in n?n.data:void 0)),n=this.#t.find(matches);if(n!==void 0)return n;if(this.#r!==void 0)throw this.#r;return await new Promise((e,t)=>{let n={matches,reject:t,resolve:t=>e(t)};this.#n.add(n)})}async#i(e,t,n){try{let r=!1,i=new TurnSegment;for await(let n of e){this.#t.push(n);let e=i.observe(n);if(t(n),this.#a(n),isTurnFailureEvent(n)&&this.#o(Error(`Session ${this.sessionId} failed before the expected event (${n.type}).`)),e){r=!0,this.#o(Error(`Session ${this.sessionId} reached ${n.type} before the expected event.`));break}}if(!r)throw Error(`Stream for session "${this.sessionId}" closed before a turn boundary.`);return n(this.#t)}catch(e){let t=e instanceof Error?e:Error(String(e));throw this.#o(t),e}}#a(e){for(let t of this.#n)t.matches(e)&&(this.#n.delete(t),t.resolve(e))}#o(e){if(this.#r===void 0){this.#r=e;for(let t of this.#n)t.reject(e);this.#n.clear()}}},EvalTurn=class{data;events;inputRequests;message;session;sessionId;status;toolCalls;#e;#t;constructor(e){this.data=e.data,this.events=e.events,this.inputRequests=e.inputRequests,this.message=e.message,this.sessionId=e.sessionId,this.session=e.session,this.status=e.status,this.toolCalls=e.toolCalls,this.#e=e.collector,this.#t=e.derived,Object.assign(this,createScopedAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}),createOutputAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}))}expectOk(){if(this.status!==`failed`)return this;throw new EveEvalTurnFailedError(this)}requireToolCall(e,t={}){let n=this.toolCalls.filter(n=>n.name===e&&toolCallMatches(n,t));return n.length!==1&&inputRequirementFailed(this.#e,`requireToolCall`,`expected exactly one matching "${e}" tool call in this turn, found ${n.length}; observed [${this.toolCalls.map(e=>e.name).join(`, `)}]`),this.#e.recordOutcome({name:`requireToolCall`,outcome:{score:1}}),n[0]}#n(){return{derived:this.#t,events:this.events,output:outputOf(this),status:this.status}}};function attachSignal(e,t){return t===void 0?e:e.signal===void 0?{...e,signal:t}:e}function formatInputRequestFilter(e){return JSON.stringify(e)}function inputRequirementFailed(e,t,n){throw e.recordOutcome({name:t,outcome:{score:0,message:n}}),new EvalRequirementFailed}function outputOf(e){return e===void 0?null:e.data===void 0?e.message??null:e.data}function assertRequestHasOption(e,t){if(e.options===void 0||e.options.length===0)throw Error(`Input request "${e.requestId}" has no selectable options.`);if(!e.options.some(e=>e.id===t))throw Error(`Input request "${e.requestId}" does not offer option "${t}".`)}export{EvalSessionDriver,EveEvalTurnFailedError};
|
|
1
|
+
import{readFile}from"node:fs/promises";import{basename}from"node:path";import{TurnSegment,summarizeTurnEvents}from"#client/session-utils.js";import{isTurnFailureEvent}from"#protocol/message.js";import{createTextWithFileContent}from"#client/file-parts.js";import{extractCompletedResult}from"#client/output-schema.js";import{inputRequestMatches,matchesValue,toolCallMatches}from"#evals/match.js";import"#evals/assertions/collector.js";import{assertReportedToolName}from"#evals/reported-tool-name.js";import{createOutputAssertions,createScopedAssertions}from"#evals/assertions/scoped.js";import{EvalRequirementFailed}from"#evals/control-flow.js";import{deriveRunFacts}from"#evals/runner/derive-run-facts.js";import{formatEvalTranscript,inferMediaType}from"#evals/session-content.js";var EveEvalTurnFailedError=class extends Error{event;turn;constructor(e){let t=e.events.find(isTurnFailureEvent),n=t===void 0?`turn ended with status "${e.status}"`:`${t.type}: ${t.data.code} ${t.data.message}`.trim();super(`Eval turn failed: ${n}`),this.name=`EveEvalTurnFailedError`,this.event=t,this.turn=e}},EvalSessionDriver=class{#e;#t;#n=``;#r;#i;#a=[];#o;#s;#c=[];#l=new Set;#u;#d=!1;#f=[];constructor(e){this.#i=e.collector,this.#s=e.onSessionStart,this.#o=e.primary,this.#e=e.session,this.#t=e.onTurn,this.#r=e.signal,Object.assign(this,createScopedAssertions(this.#i,{timing:`snapshot`,select:()=>this.#_()}),createOutputAssertions(this.#i,{timing:`snapshot`,select:()=>this.#_()}))}get events(){return this.#a}get transcript(){return formatEvalTranscript(this.#a)}get lastInput(){return this.#n}get lastTurn(){return this.#u}get pendingInputRequests(){return this.#f}get sessionId(){return this.#e.state.sessionId}get state(){return this.#e.state}async cancel(){return await this.#e.cancel()}async compact(){if((await this.#e.compact()).status!==`accepted`)throw Error(`compact() found no active session for "${this.sessionId}".`);return await this.readTurn()}agent(e){let t=this.#e.agent(e),n=this.#r;return{name:t.name,sessionId:t.sessionId,stream:(e={})=>t.stream({...e,signal:e.signal??n}),taskId:t.taskId}}async cleanup(e){await this.#e.reset({reason:`Eval timed out`,signal:e})}requireInputRequest(e={}){this.#f.length===0&&this.#v(`requireInputRequest`,`expected one pending input request, but the last turn did not park`);let t=this.#f.filter(t=>inputRequestMatches(t,e));return(this.#f.length!==1||t.length!==1)&&this.#v(`requireInputRequest`,`expected exactly one pending input request matching ${formatInputRequestFilter(e)}, found ${t.length} match(es) across ${this.#f.length} pending request(s)`),this.#i.recordOutcome({name:`requireInputRequest`,outcome:{score:1}}),t[0]}async respond(e,t={}){if(e.length===0)throw Error(`respond() requires at least one input response.`);return await(await this.#p({...t,inputResponses:e})).result()}async startRespond(e,t={}){if(e.length===0)throw Error(`startRespond() requires input responses.`);return await this.#p({...t,inputResponses:e})}async respondAll(e){let t=this.#f;if(t.length===0)throw Error(`respondAll() requires at least one pending input request.`);for(let n of t)assertRequestHasOption(n,e);return await this.respond(t.map(t=>({optionId:e,requestId:t.requestId})))}async send(e,t={}){return await(await this.#p({turnPolicy:`queue`,...t,message:e})).result()}async start(e,t={}){return await this.#p({turnPolicy:`queue`,...t,message:e})}async#p(e){let{inputResponses:t,message:n,...r}=attachSignal(e,this.#r),i=t===void 0?await this.#e.send(n,r):await this.#e.respond(t,r);return this.consume(i,n)}consume(e,t){let n=this.sessionId;return new EvalLiveTurn({events:e,observe:e=>this.#m(n,e),record:e=>(t!==void 0&&(this.#n=typeof t==`string`?t:t.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
2
|
+
`)),this.#g(n,e)),session:this,sessionId:n})}async sendFile(e,t,n){let r=await readFile(t),i=createTextWithFileContent({bytes:r,filename:basename(t),mediaType:n??inferMediaType(t),text:e});return await this.send(i)}async readTurn(e){return await this.watchTurn(e).result()}watchTurn(e){return this.consume(this.#e.stream({signal:this.#r,startIndex:e?.startIndex}))}snapshot(){let e=this.sessionId;return{derived:deriveRunFacts(this.#a,{sessionId:e}),events:[...this.#a],primary:this.#o,sessionId:e,state:this.#e.state,traceContexts:[...this.#c]}}#m(e,t){if(t.type!==`session.started`&&t.type!==`turn.started`)return;let n=t.data.trace;if(n===void 0)return;let r=`${n.traceId}:${n.spanId}`;this.#l.has(r)||(this.#l.add(r),this.#c.push(n),!this.#d&&(this.#d=!0,this.#s?.({primary:this.#o,sessionId:e,startedAt:t.meta.at,traceContext:n})))}#h(e){this.#a.push(...e.events),this.#f=e.status===`waiting`?e.inputRequests:[];let t=deriveRunFacts(e.events,{sessionId:e.sessionId}),n=new EvalTurn({collector:this.#i,data:e.data,derived:t,events:e.events,inputRequests:e.inputRequests,message:e.message,session:this,sessionId:e.sessionId,status:e.status,toolCalls:t.toolCalls});return this.#u=n,this.#t(this),n}#g(e,t){let n=summarizeTurnEvents(t);return this.#h({data:extractCompletedResult(t),events:t,inputRequests:n.inputRequests,message:n.message,sessionId:e,status:n.status})}#_(){let e=this.sessionId;return{derived:deriveRunFacts(this.#a,{sessionId:e}),events:[...this.#a],output:outputOf(this.#u),status:this.#u?.status??`completed`}}#v(e,t){throw this.#i.recordOutcome({name:e,outcome:{score:0,message:t}}),new EvalRequirementFailed}},EvalLiveTurn=class{session;sessionId;#e;#t=[];#n=new Set;#r;constructor(e){this.session=e.session,this.sessionId=e.sessionId,this.#e=this.#i(e.events,e.observe,e.record),this.#e.catch(()=>{})}get events(){return this.#t}async cancel(){return await this.session.cancel()}async result(){return await this.#e}async waitForEvent(e,t){let matches=n=>n.type===e&&(t?.data===void 0||matchesValue(t.data,`data`in n?n.data:void 0)),n=this.#t.find(matches);if(n!==void 0)return n;if(this.#r!==void 0)throw this.#r;return await new Promise((e,t)=>{let n={matches,reject:t,resolve:t=>e(t)};this.#n.add(n)})}async#i(e,t,n){try{let r=!1,i=new TurnSegment;for await(let n of e){this.#t.push(n);let e=i.observe(n);if(t(n),this.#a(n),isTurnFailureEvent(n)&&this.#o(Error(`Session ${this.sessionId} failed before the expected event (${n.type}).`)),e){r=!0,this.#o(Error(`Session ${this.sessionId} reached ${n.type} before the expected event.`));break}}if(!r)throw Error(`Stream for session "${this.sessionId}" closed before a turn boundary.`);return n(this.#t)}catch(e){let t=e instanceof Error?e:Error(String(e));throw this.#o(t),e}}#a(e){for(let t of this.#n)t.matches(e)&&(this.#n.delete(t),t.resolve(e))}#o(e){if(this.#r===void 0){this.#r=e;for(let t of this.#n)t.reject(e);this.#n.clear()}}},EvalTurn=class{data;events;inputRequests;message;session;sessionId;status;toolCalls;#e;#t;constructor(e){this.data=e.data,this.events=e.events,this.inputRequests=e.inputRequests,this.message=e.message,this.sessionId=e.sessionId,this.session=e.session,this.status=e.status,this.toolCalls=e.toolCalls,this.#e=e.collector,this.#t=e.derived,Object.assign(this,createScopedAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}),createOutputAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}))}expectOk(){if(this.status!==`failed`)return this;throw new EveEvalTurnFailedError(this)}requireToolCall(e,t={}){assertReportedToolName(e,this.#e.tools);let n=this.toolCalls.filter(n=>n.name===e&&toolCallMatches(n,t));return n.length!==1&&inputRequirementFailed(this.#e,`requireToolCall`,`expected exactly one matching "${e}" tool call in this turn, found ${n.length}; observed [${this.toolCalls.map(e=>e.name).join(`, `)}]`),this.#e.recordOutcome({name:`requireToolCall`,outcome:{score:1}}),n[0]}#n(){return{derived:this.#t,events:this.events,output:outputOf(this),status:this.status}}};function attachSignal(e,t){return t===void 0?e:e.signal===void 0?{...e,signal:t}:e}function formatInputRequestFilter(e){return JSON.stringify(e)}function inputRequirementFailed(e,t,n){throw e.recordOutcome({name:t,outcome:{score:0,message:n}}),new EvalRequirementFailed}function outputOf(e){return e===void 0?null:e.data===void 0?e.message??null:e.data}function assertRequestHasOption(e,t){if(e.options===void 0||e.options.length===0)throw Error(`Input request "${e.requestId}" has no selectable options.`);if(!e.options.some(e=>e.id===t))throw Error(`Input request "${e.requestId}" does not offer option "${t}".`)}export{EvalSessionDriver,EveEvalTurnFailedError};
|
|
@@ -7,6 +7,13 @@ export declare function resolveEvalTargetHandle(input: {
|
|
|
7
7
|
readonly kind: "local" | "remote";
|
|
8
8
|
readonly url: string;
|
|
9
9
|
}): Promise<EveEvalTargetHandle>;
|
|
10
|
+
/** The root agent's static tool names, and whether it has a dynamic tool resolver. */
|
|
11
|
+
export interface TargetTools {
|
|
12
|
+
readonly dynamic: boolean;
|
|
13
|
+
readonly static: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
/** The tools of a target resolved from `/eve/v1/info`; undefined for a hand-built handle. */
|
|
16
|
+
export declare function targetTools(target: EveEvalTargetHandle): TargetTools | undefined;
|
|
10
17
|
export declare function createEvalTargetHandle(input: {
|
|
11
18
|
readonly capabilities: EveEvalTargetCapabilities;
|
|
12
19
|
readonly client: Client;
|
package/dist/src/evals/target.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createEveDevDispatchSchedulePath}from"#protocol/routes.js";import{toErrorMessage}from"#shared/errors.js";import"#client/client.js";import{stripNpmPackageScope}from"#shared/package-name.js";import{EvalSessionManager}from"#evals/session-manager.js";import{setTimeout}from"node:timers/promises";async function resolveEvalTargetHandle(e){await waitForTargetHealth(e.client,e.url);let t=await e.client.info();if(assertAgentInfoShape(t,e.url),e.expectedAgentName!==void 0&&!matchesExpectedAgentName(e.expectedAgentName,t.agent.name))throw Error(`Expected eval target ${JSON.stringify(e.expectedAgentName)} at ${e.url}, but ${JSON.stringify(t.agent.name)} is responding there.`);
|
|
1
|
+
import{createEveDevDispatchSchedulePath}from"#protocol/routes.js";import{toErrorMessage}from"#shared/errors.js";import"#client/client.js";import{stripNpmPackageScope}from"#shared/package-name.js";import{EvalSessionManager}from"#evals/session-manager.js";import{setTimeout}from"node:timers/promises";async function resolveEvalTargetHandle(e){await waitForTargetHealth(e.client,e.url);let t=await e.client.info();if(assertAgentInfoShape(t,e.url),e.expectedAgentName!==void 0&&!matchesExpectedAgentName(e.expectedAgentName,t.agent.name))throw Error(`Expected eval target ${JSON.stringify(e.expectedAgentName)} at ${e.url}, but ${JSON.stringify(t.agent.name)} is responding there.`);let n=createEvalTargetHandle({capabilities:capabilitiesFromInfo(t),client:e.client,kind:e.kind,url:e.url});return toolsByTarget.set(n,{dynamic:t.tools.dynamic.length>0,static:t.tools.static.map(e=>e.name)}),n}const toolsByTarget=new WeakMap;function targetTools(e){return toolsByTarget.get(e)}function createEvalTargetHandle(e){return createHandle({capabilities:e.capabilities,client:e.client,kind:e.kind,sessions:void 0,url:e.url})}function scopeEvalTargetHandle(e,t){return createHandle({capabilities:e.capabilities,client:void 0,delegate:e,kind:e.kind,sessions:t.sessions,url:e.url})}function createHandle(e){let t=e.delegate,n=e.client,fetchTarget=async(e,r)=>{if(t!==void 0)return await t.fetch(e,r);if(n===void 0)throw Error(`Eval target cannot fetch without a client.`);return await n.fetch(e,r)};return{capabilities:e.capabilities,kind:e.kind,url:e.url,async attachSession(r,i){if(e.sessions!==void 0)return await e.sessions.attachSession(r,i);if(t!==void 0)return await t.attachSession(r,i);if(n===void 0)throw Error(`Eval target cannot attach sessions without a client.`);return await new EvalSessionManager({client:n}).attachSession(r,i)},watchTurn(r,i){if(e.sessions!==void 0)return e.sessions.watchTurn(r,i);if(t!==void 0)return t.watchTurn(r,i);if(n===void 0)throw Error(`Eval target cannot watch sessions without a client.`);return new EvalSessionManager({client:n}).watchTurn(r,i)},async dispatchSchedule(t){if(!e.capabilities.devRoutes)throw Error(`target.dispatchSchedule() requires a target with dev routes enabled.`);let n=await fetchTarget(createEveDevDispatchSchedulePath(t),{method:`POST`});if(!n.ok){let e=await readResponseBodySafely(n);throw Error(`Schedule dispatch failed: ${n.status} ${n.statusText}`+(e.length>0?`, ${e}`:``))}return parseScheduleDispatchResult(await n.json())},async fetch(e,t){return await fetchTarget(e,t)}}}function capabilitiesFromInfo(e){return{devRoutes:e.capabilities?.devRoutes??e.mode===`development`}}function matchesExpectedAgentName(e,t){return t===e||t===stripNpmPackageScope(e)}async function waitForTargetHealth(e,t){let n=Date.now()+6e4,r;for(;Date.now()<n;)try{await e.health();return}catch(e){r=toErrorMessage(e),await setTimeout(250)}throw Error(`Timed out waiting for eval target health at ${t}.`+(r===void 0?``:` Last error: ${r}`))}function assertAgentInfoShape(e,t){if(e.kind!==`eve-agent-info`||e.version!==5)throw Error(`Eval target ${t} returned an unrecognized /eve/v1/info payload.`)}function parseScheduleDispatchResult(e){if(typeof e!=`object`||!e||!(`scheduleId`in e)||typeof e.scheduleId!=`string`||!(`sessionIds`in e)||!Array.isArray(e.sessionIds)||e.sessionIds.some(e=>typeof e!=`string`))throw Error(`Schedule dispatch returned an unexpected response shape: ${JSON.stringify(e)}`);return{scheduleId:e.scheduleId,sessionIds:[...e.sessionIds]}}async function readResponseBodySafely(e){try{return(await e.text()).trim()}catch{return``}}export{createEvalTargetHandle,resolveEvalTargetHandle,scopeEvalTargetHandle,targetTools};
|
|
@@ -29,6 +29,21 @@ export interface EveEvalToolCall {
|
|
|
29
29
|
/** Owning session id, when the runner knows it. */
|
|
30
30
|
readonly sessionId?: string;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* One skill load extracted from the captured stream, pairing the `load-skill`
|
|
34
|
+
* request with its matching `load-skill-result`.
|
|
35
|
+
*/
|
|
36
|
+
export interface EveEvalSkillLoad {
|
|
37
|
+
/** The loaded skill's name. */
|
|
38
|
+
readonly skill: string;
|
|
39
|
+
/** The skill's instructions; `undefined` when the load never resolved. */
|
|
40
|
+
readonly output: JsonValue | undefined;
|
|
41
|
+
readonly status: EveEvalActionStatus;
|
|
42
|
+
/** Zero-based index of the turn the load happened in. */
|
|
43
|
+
readonly turnIndex: number;
|
|
44
|
+
/** Owning session id, when the runner knows it. */
|
|
45
|
+
readonly sessionId?: string;
|
|
46
|
+
}
|
|
32
47
|
/**
|
|
33
48
|
* One call to an agent task extracted from the captured stream: its
|
|
34
49
|
* `task.started`, joined with its `task.settled` and the task's
|
|
@@ -58,6 +73,7 @@ export interface EveEvalSubagentCall {
|
|
|
58
73
|
export interface EveEvalDerivedFacts {
|
|
59
74
|
readonly toolCalls: readonly EveEvalToolCall[];
|
|
60
75
|
readonly toolCallCount: number;
|
|
76
|
+
readonly skillLoads: readonly EveEvalSkillLoad[];
|
|
61
77
|
readonly subagentCalls: readonly EveEvalSubagentCall[];
|
|
62
78
|
readonly subagentCallCount: number;
|
|
63
79
|
/** Every HITL input request raised during the run (`input.requested`). */
|
|
@@ -209,7 +225,7 @@ export interface EveEvalAssertions {
|
|
|
209
225
|
parked(): AssertionHandle;
|
|
210
226
|
messageIncludes(token: string | RegExp): AssertionHandle;
|
|
211
227
|
calledTool(name: string, options?: EveEvalToolCallMatchOptions): AssertionHandle;
|
|
212
|
-
/**
|
|
228
|
+
/** Asserts a completed load of `skill`, constrained like `calledTool`. */
|
|
213
229
|
loadedSkill(skill: string, options?: EveEvalSkillLoadMatchOptions): AssertionHandle;
|
|
214
230
|
notCalledTool(name: string): AssertionHandle;
|
|
215
231
|
/** Asserts that tool requests appeared in order, allowing unrelated requests between them. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";import{decisionToTraceContentCeiling}from"#shared/forwarded-trace-policy.js";import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{createEveCallbackRoutePath,createEveSessionCancelRoutePath,createEveSessionResetRoutePath,createEveSessionRoutePath}from"#protocol/routes.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{ResetResponseSchema}from"#protocol/reset-session.js";import{formatTraceparent,writeAgentDispatchTracestate}from"#protocol/traceparent.js";import{writeForwardedAudienceBaggage,writeForwardedParentSessionBaggage}from"#protocol/baggage.js";import{writeConversationBaggage}from"#tracing/conversation-context.js";import{REMOTE_AGENT_PROTOCOL_MISMATCH,REMOTE_AGENT_PROTOCOL_VERSION,formatRemoteAgentProtocolMismatch,readRemoteAgentProtocolVersion}from"#protocol/remote-agent-protocol.js";import{FatalError}from"#compiled/@workflow/core/index.js";import{createWorkflowCallbackUrl}from"#execution/workflow-callback-url.js";import{createRemoteAgentRouteUrl}from"#subagents/remote-route-url.js";import{formatSubagentInput}from"#subagents/invocation.js";const CreateSessionResponseSchema=z.object({ok:z.literal(!0),protocolVersion:z.number().optional(),sessionId:z.string().min(1),status:z.literal(`accepted`)});async function startRemoteAgentSession(e){let t=e.parent?.continuationToken??e.session.continuationToken;if(!t)throw Error(`Cannot dispatch remote agent without a parent continuation token.`);if(!e.callbackBaseUrl)throw Error(`Cannot dispatch remote agent without a callback base URL.`);let n=buildForwardedPrincipalField(e),r={capabilities:e.capabilities??{},callback:{callId:e.action.callId,subagentName:e.action.remoteAgentName,token:t,url:createWorkflowCallbackUrl(e.callbackBaseUrl,createEveCallbackRoutePath(t))},message:formatRemoteAgentCallInputMessage({action:e.action,remote:e.remote}),outputSchema:e.action.input.outputSchema,protocolVersion:REMOTE_AGENT_PROTOCOL_VERSION};n!==void 0&&(r.forwardedPrincipal=n),e.operationId!==void 0&&(r.operationId=e.operationId);let i=await resolveRemoteAgentRequestHeaders(e.remote),a=formatTraceparent(e.parent?.traceContext);a!==void 0&&setHeader(i,`traceparent`,a),setHeader(i,`tracestate`,writeAgentDispatchTracestate(readHeader(i,`tracestate`),e.parent?.traceContext));let o=writeForwardedAudienceBaggage(readHeader(i,`baggage`),buildForwardedTraceAssertion({forwardedPrincipal:n,originAudience:e.originAudience,parentTraceContext:e.parent?.traceContext,traceparent:a})),s=writeConversationBaggage(o,e.parent?.conversationId);setHeader(i,`baggage`,writeForwardedParentSessionBaggage(s,e.parent?.lineage));let c=await fetch(createRemoteAgentSessionUrl(e.remote),{body:JSON.stringify(r),headers:{"content-type":`application/json`,...i},method:`POST`});if(!c.ok)throw await throwIfRemoteAgentProtocolMismatch(c,e.action.remoteAgentName),Error(`Remote agent "${e.action.remoteAgentName}" create-session request failed with HTTP ${c.status}.`);let l;try{l=await c.json()}catch{throw Error(`Remote agent "${e.action.remoteAgentName}" create-session response was not valid JSON.`)}let u=CreateSessionResponseSchema.safeParse(l);if(!u.success)throw Error(`Remote agent "${e.action.remoteAgentName}" create-session response was invalid.`);let d=readRemoteAgentProtocolVersion(u.data.protocolVersion);if(d!==REMOTE_AGENT_PROTOCOL_VERSION)throw new FatalError(formatRemoteAgentProtocolMismatch({name:e.action.remoteAgentName,receiverVersion:d}));return{sessionId:u.data.sessionId}}async function throwIfRemoteAgentProtocolMismatch(e,t){let n;try{n=await e.json()}catch{return}if(typeof n!=`object`||!n||Reflect.get(n,`code`)!==REMOTE_AGENT_PROTOCOL_MISMATCH)return;let r=readRemoteAgentProtocolVersion(Reflect.get(n,`protocolVersion`));throw new FatalError(formatRemoteAgentProtocolMismatch({name:t,receiverVersion:r}))}function buildForwardedTraceAssertion(e){let t=decisionToTraceContentCeiling(e.parentTraceContext?.decision);if(e.forwardedPrincipal!==void 0&&e.parentTraceContext!==void 0&&(e.parentTraceContext.traceFlags&1)==1&&e.traceparent!==void 0&&t!==void 0)return{ceiling:t,originAudience:e.originAudience??`unknown`}}async function respondToRemoteAgentSession(e){let t=await fetch(createRemoteAgentRouteUrl(e.remote.url,createEveSessionRoutePath(e.remote.sessionId)),{body:JSON.stringify({inputResponses:e.responses,...e.remote.forwardPrincipal===!0&&e.auth!=null&&{forwardedPrincipal:{current:e.auth}}}),headers:{"content-type":`application/json`,...e.headers},method:`POST`,redirect:`error`});if(!t.ok)throw Error(`Remote agent "${e.remote.name}" input answer failed with HTTP ${t.status}.`)}async function continueRemoteAgentSession(e){let t=buildForwardedPrincipalField(e),n={callback:e.callback,message:e.message,outputSchema:e.outputSchema};t!==void 0&&(n.forwardedPrincipal=t);let r=await fetch(createRemoteAgentContinueUrl(e.remote,e.sessionId),{body:JSON.stringify(n),headers:{"content-type":`application/json`,...await resolveRemoteAgentRequestHeaders(e.remote)},method:`POST`});if(!r.ok){let n=r.status===400&&t!==void 0?` The receiver may support forwarded principals only on session creation; upgrade it before retrying.`:``;throw Error(`Remote agent "${e.remote.name}" continue-session request failed with HTTP ${r.status}.${n}`)}}function buildForwardedPrincipalField(e){if(e.remote.forwardPrincipal!==!0||e.auth===null||e.auth===void 0)return;let t={current:e.auth};return e.initiatorAuth!==null&&e.initiatorAuth!==void 0&&(t.initiator=e.initiatorAuth),t}async function cancelRemoteAgentTurn(e){let t=await fetch(createRemoteAgentCancelTurnUrl(e.remote,e.sessionId),{headers:await resolveRemoteAgentRequestHeaders(e.remote),method:`POST`});if(!t.ok)throw Error(`Remote agent "${e.remote.name}" cancel-turn request failed with HTTP ${t.status}.`);let n;try{n=await t.json()}catch{throw Error(`Remote agent "${e.remote.name}" cancel-turn response was not valid JSON.`)}let r=CancelTurnResponseSchema.safeParse(n);if(!r.success||r.data.status===`accepted`&&r.data.sessionId!==e.sessionId)throw Error(`Remote agent "${e.remote.name}" cancel-turn response was invalid.`);return r.data.status===`accepted`?{sessionId:r.data.sessionId,status:`accepted`}:{status:`no_active_turn`}}function readHeader(e,t){let n=Object.keys(e).find(e=>e.toLowerCase()===t);return n===void 0?void 0:e[n]}function setHeader(e,t,n){for(let n of Object.keys(e))n.toLowerCase()===t&&delete e[n];n!==void 0&&(e[t]=n)}async function resetRemoteAgentSession(e){let t=await resolveRemoteAgentRequestHeaders(e.remote),n=await fetch(createRemoteAgentRouteUrl(e.remote.url,createEveSessionResetRoutePath(e.sessionId)),{body:JSON.stringify({reason:e.reason}),headers:{"content-type":`application/json`,...t},method:`POST`});if(!n.ok)throw Error(`Remote agent "${e.remote.name}" reset-session request failed with HTTP ${n.status}.`);let r=ResetResponseSchema.safeParse(await n.json());if(!r.success||r.data.status===`reset`&&r.data.previousSessionId!==e.sessionId)throw Error(`Remote agent "${e.remote.name}" reset-session response was invalid.`);return r.data}function resolveRemoteAgentForAction(e){let t=e.registry.get(e.nodeId)?.definition;if(e.dynamicRemoteAgent!==void 0){if(t===void 0)throw new FatalError(`Missing remote agent "${e.remoteAgentName}" in runtime registry.`);let n=resolveDynamicRemoteAgentCredentials(e.dynamicRemoteAgent),r=e.dynamicRemoteAgent,i={description:r.description,kind:`remote`,logicalPath:t.logicalPath,name:e.remoteAgentName,nodeId:e.nodeId,path:r.path,sourceId:t.sourceId,sourceKind:`module`,url:r.url};return r.forwardPrincipal!==void 0&&(i.forwardPrincipal=r.forwardPrincipal),n.auth!==void 0&&(i.auth=n.auth),n.headers!==void 0&&(i.headers=n.headers),i}if(t?.kind!==`remote`)throw new FatalError(`Missing remote agent "${e.remoteAgentName}" in runtime registry.`);return t}async function resolveRemoteAgentStreamHeaders(e){if(e.resolverId===void 0)return{};let t=new Set([e.bundle.graph.root,...e.bundle.graph.nodesByNodeId.values()]);for(let n of t){let t=n.subagentRegistry.subagentsByNodeId.get(e.resolverId)?.definition;if(t!==void 0){if(t.kind!==`remote`||t.name!==e.name||t.url!==e.url)throw Error(`Remote child stream resolver does not match the authored remote agent.`);return await resolveRemoteAgentRequestHeaders(t)}}return await resolveRemoteAgentRequestHeaders(resolveDynamicRemoteAgentCredentials({credentialsStepId:e.resolverId,description:``,path:``,url:e.url}))}function resolveDynamicRemoteAgentCredentials(e){if(e.credentialsStepId===void 0)return{};let t=getStepRegistry().get(e.credentialsStepId);if(t===void 0)throw Error(`Dynamic remote subagent credentials function "${e.credentialsStepId}" is not registered.`);let n=expectObjectRecord(t(),`Dynamic remote subagent credentials are invalid.`),r={};return n.auth!==void 0&&(r.auth=expectFunction(n.auth,`Dynamic remote subagent auth is invalid.`)),n.headers!==void 0&&(r.headers=resolveDynamicRemoteAgentHeaders(n.headers)),r}function resolveDynamicRemoteAgentHeaders(e){if(typeof e==`function`)return e;let t=expectObjectRecord(e,`Dynamic remote subagent headers are invalid.`);for(let e of Object.values(t))if(typeof e!=`string`)throw Error(`Dynamic remote subagent headers are invalid.`);return t}function getStepRegistry(){let e=Symbol.for(`@workflow/core//registeredSteps`),t=globalThis,n=t[e];return n===void 0&&(n=new Map,t[e]=n),n}function createRemoteAgentSessionUrl(e){return createRemoteAgentRouteUrl(e.url,e.path)}function createRemoteAgentCancelTurnUrl(e,t){return createRemoteAgentRouteUrl(e.url,createEveSessionCancelRoutePath(t))}function createRemoteAgentContinueUrl(e,t){return createRemoteAgentRouteUrl(e.url,createEveSessionRoutePath(t))}async function resolveRemoteAgentRequestHeaders(e){let t={};return e.headers!==void 0&&Object.assign(t,typeof e.headers==`function`?await e.headers():e.headers),e.auth!==void 0&&Object.assign(t,(await e.auth()).headers),t}function formatRemoteAgentCallInputMessage(e){let t=typeof e.action.input.message==`string`?e.action.input.message:``;return formatSubagentInput({description:e.remote.description,message:t,name:e.action.remoteAgentName,type:`remote`}).message}export{cancelRemoteAgentTurn,continueRemoteAgentSession,resetRemoteAgentSession,resolveRemoteAgentForAction,resolveRemoteAgentStreamHeaders,respondToRemoteAgentSession,startRemoteAgentSession};
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{decisionToTraceContentCeiling}from"#shared/forwarded-trace-policy.js";import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{createEveCallbackRoutePath,createEveSessionCancelRoutePath,createEveSessionResetRoutePath,createEveSessionRoutePath}from"#protocol/routes.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{ResetResponseSchema}from"#protocol/reset-session.js";import{formatTraceparent,writeAgentDispatchTracestate}from"#protocol/traceparent.js";import{writeForwardedAudienceBaggage,writeForwardedParentSessionBaggage}from"#protocol/baggage.js";import{writeConversationBaggage}from"#tracing/conversation-context.js";import{REMOTE_AGENT_PROTOCOL_MISMATCH,REMOTE_AGENT_PROTOCOL_VERSION,UNVERSIONED_REMOTE_AGENT_PROTOCOL,formatRemoteAgentProtocolMismatch,readRemoteAgentProtocolVersion}from"#protocol/remote-agent-protocol.js";import{FatalError}from"#compiled/@workflow/core/index.js";import{createWorkflowCallbackUrl}from"#execution/workflow-callback-url.js";import{createRemoteAgentRouteUrl}from"#subagents/remote-route-url.js";import{formatSubagentInput}from"#subagents/invocation.js";const CreateSessionResponseSchema=z.object({ok:z.literal(!0),protocolVersion:z.number().optional(),sessionId:z.string().min(1),status:z.literal(`accepted`)}),UNKNOWN_REMOTE_OUTCOME=`The request may have completed on the remote agent. Do not retry automatically; check the remote outcome before sending the request again.`;async function startRemoteAgentSession(e){let t=e.parent?.continuationToken??e.session.continuationToken;if(!t)throw Error(`Cannot dispatch remote agent without a parent continuation token.`);if(!e.callbackBaseUrl)throw Error(`Cannot dispatch remote agent without a callback base URL.`);let n=buildForwardedPrincipalField(e),r={capabilities:e.capabilities??{},callback:{callId:e.action.callId,subagentName:e.action.remoteAgentName,token:t,url:createWorkflowCallbackUrl(e.callbackBaseUrl,createEveCallbackRoutePath(t))},message:formatRemoteAgentCallInputMessage({action:e.action,remote:e.remote}),outputSchema:e.action.input.outputSchema,protocolVersion:REMOTE_AGENT_PROTOCOL_VERSION};n!==void 0&&(r.forwardedPrincipal=n),e.operationId!==void 0&&(r.operationId=e.operationId);let i=await resolveRemoteAgentRequestHeaders(e.remote),a=formatTraceparent(e.parent?.traceContext);a!==void 0&&setHeader(i,`traceparent`,a),setHeader(i,`tracestate`,writeAgentDispatchTracestate(readHeader(i,`tracestate`),e.parent?.traceContext));let o=writeForwardedAudienceBaggage(readHeader(i,`baggage`),buildForwardedTraceAssertion({forwardedPrincipal:n,originAudience:e.originAudience,parentTraceContext:e.parent?.traceContext,traceparent:a})),s=writeConversationBaggage(o,e.parent?.conversationId);setHeader(i,`baggage`,writeForwardedParentSessionBaggage(s,e.parent?.lineage));let c=await fetch(createRemoteAgentSessionUrl(e.remote),{body:JSON.stringify(r),headers:{"content-type":`application/json`,...i},method:`POST`});if(!c.ok)throw await throwIfRemoteAgentProtocolMismatch(c,e.action.remoteAgentName),Error(`Remote agent "${e.action.remoteAgentName}" create-session request failed with HTTP ${c.status}.`);let l;try{l=await c.json()}catch{throw new FatalError(`Remote agent "${e.action.remoteAgentName}" create-session response was not valid JSON. ${UNKNOWN_REMOTE_OUTCOME}`)}let u=CreateSessionResponseSchema.safeParse(l);if(!u.success)throw new FatalError(`Remote agent "${e.action.remoteAgentName}" create-session response was invalid. ${UNKNOWN_REMOTE_OUTCOME}`);let d=readRemoteAgentProtocolVersion(u.data.protocolVersion);if(d!==REMOTE_AGENT_PROTOCOL_VERSION&&d!==UNVERSIONED_REMOTE_AGENT_PROTOCOL)throw new FatalError(`${formatRemoteAgentProtocolMismatch({name:e.action.remoteAgentName,receiverVersion:d})} ${UNKNOWN_REMOTE_OUTCOME} Remote session: ${u.data.sessionId}.`);return{sessionId:u.data.sessionId}}async function throwIfRemoteAgentProtocolMismatch(e,t){let n;try{n=await e.json()}catch{return}if(typeof n!=`object`||!n||Reflect.get(n,`code`)!==REMOTE_AGENT_PROTOCOL_MISMATCH)return;let r=readRemoteAgentProtocolVersion(Reflect.get(n,`protocolVersion`));throw new FatalError(formatRemoteAgentProtocolMismatch({name:t,receiverVersion:r}))}function buildForwardedTraceAssertion(e){let t=decisionToTraceContentCeiling(e.parentTraceContext?.decision);if(e.forwardedPrincipal!==void 0&&e.parentTraceContext!==void 0&&(e.parentTraceContext.traceFlags&1)==1&&e.traceparent!==void 0&&t!==void 0)return{ceiling:t,originAudience:e.originAudience??`unknown`}}async function respondToRemoteAgentSession(e){let t=await fetch(createRemoteAgentRouteUrl(e.remote.url,createEveSessionRoutePath(e.remote.sessionId)),{body:JSON.stringify({inputResponses:e.responses,...e.remote.forwardPrincipal===!0&&e.auth!=null&&{forwardedPrincipal:{current:e.auth}}}),headers:{"content-type":`application/json`,...e.headers},method:`POST`,redirect:`error`});if(!t.ok)throw Error(`Remote agent "${e.remote.name}" input answer failed with HTTP ${t.status}.`)}async function continueRemoteAgentSession(e){let t=buildForwardedPrincipalField(e),n={callback:e.callback,message:e.message,outputSchema:e.outputSchema};t!==void 0&&(n.forwardedPrincipal=t);let r=await fetch(createRemoteAgentContinueUrl(e.remote,e.sessionId),{body:JSON.stringify(n),headers:{"content-type":`application/json`,...await resolveRemoteAgentRequestHeaders(e.remote)},method:`POST`});if(!r.ok){let n=r.status===400&&t!==void 0?` The receiver may support forwarded principals only on session creation; upgrade it before retrying.`:``;throw Error(`Remote agent "${e.remote.name}" continue-session request failed with HTTP ${r.status}.${n}`)}}function buildForwardedPrincipalField(e){if(e.remote.forwardPrincipal!==!0||e.auth===null||e.auth===void 0)return;let t={current:e.auth};return e.initiatorAuth!==null&&e.initiatorAuth!==void 0&&(t.initiator=e.initiatorAuth),t}async function cancelRemoteAgentTurn(e){let t=await fetch(createRemoteAgentCancelTurnUrl(e.remote,e.sessionId),{headers:await resolveRemoteAgentRequestHeaders(e.remote),method:`POST`});if(!t.ok)throw Error(`Remote agent "${e.remote.name}" cancel-turn request failed with HTTP ${t.status}.`);let n;try{n=await t.json()}catch{throw Error(`Remote agent "${e.remote.name}" cancel-turn response was not valid JSON.`)}let r=CancelTurnResponseSchema.safeParse(n);if(!r.success||r.data.status===`accepted`&&r.data.sessionId!==e.sessionId)throw Error(`Remote agent "${e.remote.name}" cancel-turn response was invalid.`);return r.data.status===`accepted`?{sessionId:r.data.sessionId,status:`accepted`}:{status:`no_active_turn`}}function readHeader(e,t){let n=Object.keys(e).find(e=>e.toLowerCase()===t);return n===void 0?void 0:e[n]}function setHeader(e,t,n){for(let n of Object.keys(e))n.toLowerCase()===t&&delete e[n];n!==void 0&&(e[t]=n)}async function resetRemoteAgentSession(e){let t=await resolveRemoteAgentRequestHeaders(e.remote),n=await fetch(createRemoteAgentRouteUrl(e.remote.url,createEveSessionResetRoutePath(e.sessionId)),{body:JSON.stringify({reason:e.reason}),headers:{"content-type":`application/json`,...t},method:`POST`});if(!n.ok)throw Error(`Remote agent "${e.remote.name}" reset-session request failed with HTTP ${n.status}.`);let r=ResetResponseSchema.safeParse(await n.json());if(!r.success||r.data.status===`reset`&&r.data.previousSessionId!==e.sessionId)throw Error(`Remote agent "${e.remote.name}" reset-session response was invalid.`);return r.data}function resolveRemoteAgentForAction(e){let t=e.registry.get(e.nodeId)?.definition;if(e.dynamicRemoteAgent!==void 0){if(t===void 0)throw new FatalError(`Missing remote agent "${e.remoteAgentName}" in runtime registry.`);let n=resolveDynamicRemoteAgentCredentials(e.dynamicRemoteAgent),r=e.dynamicRemoteAgent,i={description:r.description,kind:`remote`,logicalPath:t.logicalPath,name:e.remoteAgentName,nodeId:e.nodeId,path:r.path,sourceId:t.sourceId,sourceKind:`module`,url:r.url};return r.forwardPrincipal!==void 0&&(i.forwardPrincipal=r.forwardPrincipal),n.auth!==void 0&&(i.auth=n.auth),n.headers!==void 0&&(i.headers=n.headers),i}if(t?.kind!==`remote`)throw new FatalError(`Missing remote agent "${e.remoteAgentName}" in runtime registry.`);return t}async function resolveRemoteAgentStreamHeaders(e){if(e.resolverId===void 0)return{};let t=new Set([e.bundle.graph.root,...e.bundle.graph.nodesByNodeId.values()]);for(let n of t){let t=n.subagentRegistry.subagentsByNodeId.get(e.resolverId)?.definition;if(t!==void 0){if(t.kind!==`remote`||t.name!==e.name||t.url!==e.url)throw Error(`Remote child stream resolver does not match the authored remote agent.`);return await resolveRemoteAgentRequestHeaders(t)}}return await resolveRemoteAgentRequestHeaders(resolveDynamicRemoteAgentCredentials({credentialsStepId:e.resolverId,description:``,path:``,url:e.url}))}function resolveDynamicRemoteAgentCredentials(e){if(e.credentialsStepId===void 0)return{};let t=getStepRegistry().get(e.credentialsStepId);if(t===void 0)throw Error(`Dynamic remote subagent credentials function "${e.credentialsStepId}" is not registered.`);let n=expectObjectRecord(t(),`Dynamic remote subagent credentials are invalid.`),r={};return n.auth!==void 0&&(r.auth=expectFunction(n.auth,`Dynamic remote subagent auth is invalid.`)),n.headers!==void 0&&(r.headers=resolveDynamicRemoteAgentHeaders(n.headers)),r}function resolveDynamicRemoteAgentHeaders(e){if(typeof e==`function`)return e;let t=expectObjectRecord(e,`Dynamic remote subagent headers are invalid.`);for(let e of Object.values(t))if(typeof e!=`string`)throw Error(`Dynamic remote subagent headers are invalid.`);return t}function getStepRegistry(){let e=Symbol.for(`@workflow/core//registeredSteps`),t=globalThis,n=t[e];return n===void 0&&(n=new Map,t[e]=n),n}function createRemoteAgentSessionUrl(e){return createRemoteAgentRouteUrl(e.url,e.path)}function createRemoteAgentCancelTurnUrl(e,t){return createRemoteAgentRouteUrl(e.url,createEveSessionCancelRoutePath(t))}function createRemoteAgentContinueUrl(e,t){return createRemoteAgentRouteUrl(e.url,createEveSessionRoutePath(t))}async function resolveRemoteAgentRequestHeaders(e){let t={};return e.headers!==void 0&&Object.assign(t,typeof e.headers==`function`?await e.headers():e.headers),e.auth!==void 0&&Object.assign(t,(await e.auth()).headers),t}function formatRemoteAgentCallInputMessage(e){let t=typeof e.action.input.message==`string`?e.action.input.message:``;return formatSubagentInput({description:e.remote.description,message:t,name:e.action.remoteAgentName,type:`remote`}).message}export{cancelRemoteAgentTurn,continueRemoteAgentSession,resetRemoteAgentSession,resolveRemoteAgentForAction,resolveRemoteAgentStreamHeaders,respondToRemoteAgentSession,startRemoteAgentSession};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** Sign-in shared by connection tool calls, searches, and connecting a connection. */
|
|
2
|
+
import type { ConnectionRegistry } from "#runtime/connections/registry-types.js";
|
|
3
|
+
import { createAuthorizationExecution, type ScopedAuthorization } from "#runtime/connections/scoped-authorization.js";
|
|
4
|
+
import type { ResolvedConnectionDefinition } from "#runtime/types.js";
|
|
5
|
+
import { type ConnectionClient, type ConnectionToolMetadata } from "#shared/connection-types.js";
|
|
6
|
+
/** A connection ready for one call, with any sign-in the user finished completed. */
|
|
7
|
+
export interface ConnectionSession {
|
|
8
|
+
/** Completes and starts sign-in for this call, and guards against a sign-in loop. */
|
|
9
|
+
readonly auth: ReturnType<typeof createAuthorizationExecution>;
|
|
10
|
+
readonly client: ConnectionClient;
|
|
11
|
+
/** The connection's interactive sign-in, when it supports one. */
|
|
12
|
+
readonly scoped: ScopedAuthorization | undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Completes the sign-in the user finished for `connection`, if any, before a
|
|
16
|
+
* search, a sign-in, or a tool call uses its client. It never prompts; a caller
|
|
17
|
+
* that needs sign-in starts it through `auth`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function completeConnectionSignIn(registry: ConnectionRegistry, connection: ResolvedConnectionDefinition): Promise<ConnectionSession>;
|
|
20
|
+
/** A connection's tools, or why they can't be listed. */
|
|
21
|
+
export type ConnectionListing = {
|
|
22
|
+
readonly tools: readonly ConnectionToolMetadata[];
|
|
23
|
+
}
|
|
24
|
+
/** Listable once the user signs in; `error` is the listing's request for sign-in. */
|
|
25
|
+
| {
|
|
26
|
+
readonly authorization: ScopedAuthorization;
|
|
27
|
+
readonly error: unknown;
|
|
28
|
+
} | {
|
|
29
|
+
readonly failure: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function listConnectionTools(connection: ResolvedConnectionDefinition, { auth, client, scoped }: ConnectionSession): Promise<ConnectionListing>;
|
|
32
|
+
/**
|
|
33
|
+
* A connection's tools, or a timeout error once listing them takes longer than
|
|
34
|
+
* {@link LISTING_TIMEOUT_MS}, so one hung server can't stall a step. Clients
|
|
35
|
+
* share one in-flight listing and take no signal, so this stops waiting rather
|
|
36
|
+
* than cancelling: a late result fills only that client's cache, and the race
|
|
37
|
+
* handles a late rejection.
|
|
38
|
+
*/
|
|
39
|
+
export declare function listToolMetadata(connectionName: string, client: ConnectionClient): Promise<readonly ConnectionToolMetadata[]>;
|
|
40
|
+
/** Why a connection's tools could not be listed, for a failure other than a needed sign-in. */
|
|
41
|
+
export declare function listingFailureMessage(connectionName: string, error: unknown): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{toErrorMessage}from"#shared/errors.js";import{CALL_TOOL_NAME}from"#protocol/catalog-tools.js";import{isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{getAuthorizationResults}from"#harness/authorization.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{createAuthorizationExecution}from"#runtime/connections/scoped-authorization.js";import{supportsInteractiveAuthorization}from"#shared/connection-types.js";const log=createLogger(`framework.catalog-connections`);async function completeConnectionSignIn(e,t){assertPendingSignInInstance(t);let n=await interactiveAuthorization(t),r=createAuthorizationExecution();n!==void 0&&await r.complete(n);let i=e.getClient(t.connectionName);return n!==void 0&&r.isJustAuthorized(n)&&await i.close(),{auth:r,client:i,scoped:n}}async function listConnectionTools(e,{auth:t,client:n,scoped:r}){let i=e.connectionName;try{return{tools:await listToolMetadata(i,n)}}catch(e){return isConnectionAuthorizationRequiredError(e)?r===void 0?{failure:`"${i}" requires authorization and cannot start interactive sign-in.`}:t.isJustAuthorized(r)?{failure:`Authorization failed for "${i}": the service rejected the token immediately after authorization.`}:{authorization:r,error:e}:(log.warn(`failed to load connection tools`,{connection:i,error:e}),{failure:listingFailureMessage(i,e)})}}const LISTING_TIMEOUT_MS=1e4;var ListingTimeoutError=class extends Error{};async function listToolMetadata(e,t){let n,r=new Promise((t,r)=>{n=setTimeout(()=>{r(new ListingTimeoutError(`"${e}" did not list its tools within ${LISTING_TIMEOUT_MS/1e3}s. Try again later.`))},LISTING_TIMEOUT_MS)});try{return await Promise.race([t.getToolMetadata(),r])}finally{clearTimeout(n)}}function listingFailureMessage(e,t){return t instanceof ListingTimeoutError?t.message:isConnectionAuthorizationFailedError(t)?`Authorization failed for "${e}": ${t.message}`:`Failed to load tools for "${e}": ${toErrorMessage(t)}`}async function interactiveAuthorization(e){let t=await resolveConnectionAuthorization(e);if(t!==void 0&&supportsInteractiveAuthorization(t))return{scope:e.connectionName,instanceId:e.instanceId,connection:{url:e.url??``},authorization:t}}function assertPendingSignInInstance(e){for(let t of getAuthorizationResults())if(t.name===e.connectionName&&t.instanceId!==void 0&&t.instanceId!==e.instanceId)throw Error(`Authorization for "${t.name}" cannot complete because its resolved connection changed while sign-in was pending. Sign in again with ${CALL_TOOL_NAME}({ name: "${t.name}" }).`)}export{completeConnectionSignIn,listConnectionTools,listToolMetadata,listingFailureMessage};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A connection's catalog entries. `<connection>__<tool>` calls one of its
|
|
3
|
+
* tools: it applies the connection's approval under the entry's name and runs
|
|
4
|
+
* an approved call only against the connection instance it was approved for.
|
|
5
|
+
* The connection's own name signs the user in, so its tools become listable.
|
|
6
|
+
*/
|
|
7
|
+
import type { HarnessToolDefinition } from "#harness/execute-tool.js";
|
|
8
|
+
import type { ConnectionRegistry } from "#runtime/connections/registry-types.js";
|
|
9
|
+
import type { ResolvedConnectionDefinition } from "#runtime/types.js";
|
|
10
|
+
/** The entry for one tool of one connection instance in `registry`. */
|
|
11
|
+
export declare function connectionEntry(registry: ConnectionRegistry, connection: ResolvedConnectionDefinition, toolName: string): HarnessToolDefinition;
|
|
12
|
+
/**
|
|
13
|
+
* The entry for a connection's own name: it signs the user in when listing the
|
|
14
|
+
* connection's tools needs that, then points the model at `eve__search`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function connectionSignInEntry(registry: ConnectionRegistry, connection: ResolvedConnectionDefinition): HarnessToolDefinition;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{completeConnectionSignIn,listConnectionTools,listToolMetadata,listingFailureMessage}from"./connection-auth.js";import{closestNames}from"./rank.js";import{connectionToolSignature}from"./signatures.js";import{isObject}from"#shared/guards.js";import{loadContext}from"#context/container.js";import{displayProperName,displayTitle}from"#shared/display-name.js";import{SEARCH_TOOL_NAME}from"#protocol/catalog-tools.js";import{defineJsonSchema,refineJsonSchema}from"#tools/schema.js";import{connectionToolName}from"#connections/ownership.js";import{ContextKey}from"#context/key.js";import{resolveApprovalPolicy}from"#approval/definition.js";import{isApprovalRecheck}from"#harness/approval-recheck.js";import{isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{connectionToolModelOutput,toConnectionToolResult}from"#runtime/connections/tool-result.js";const CONNECTION_CHANGED_MESSAGE=`The connection for this tool call changed or is unavailable. Request a new tool call and approval.`,ConnectionApprovalPinsKey=new ContextKey(`eve.connectionApprovalPins`);function instanceKey(e){return e.instanceId??``}function connectionEntry(e,t,n){let r=`${displayProperName(t.connectionName)}: ${displayTitle(n)}`;return{approval:connectionApproval(t),deferred:!0,description:``,execute:(r,i)=>callConnectionTool(e,t,n,r,i),inputSchema:refineJsonSchema({},r=>checkInput(e,t,n,r)),label:{start:()=>r},name:connectionToolName(t.connectionName,n),toModelOutput:connectionToolModelOutput}}function connectionSignInEntry(e,t){let n=displayProperName(t.connectionName),r=`Sign in to use the ${n} tools`;return{deferred:!0,description:t.description===``?`${r}.`:`${r}: ${t.description}`,execute:()=>connect(e,t),inputSchema:defineJsonSchema({type:`object`,properties:{},additionalProperties:!1}),label:{start:()=>`Sign in to ${n}`},name:t.connectionName}}async function connect(e,t){let n=await completeConnectionSignIn(e,t),r=await listConnectionTools(t,n);if(`failure`in r)throw Error(r.failure);if(`authorization`in r)return await n.auth.handleError(r.error,r.authorization);let i=displayProperName(t.connectionName),a=`${SEARCH_TOOL_NAME}({ query: "${t.connectionName}__" })`;return n.scoped!==void 0&&n.auth.isJustAuthorized(n.scoped)?`Signed in to ${i}. Find the ${i} tools with ${a}.`:`The ${i} tools are available. Find them with ${a}.`}async function callConnectionTool(e,t,n,r,i){releaseApprovalPin(i.toolCallId,t);let a=await completeConnectionSignIn(e,t),{auth:o,client:s,scoped:c}=a,l=await listConnectionTools(t,a);if(`failure`in l)throw Error(l.failure);if(`authorization`in l)return await o.handleError(l.error,l.authorization);let u=await checkCall(t,l.tools,n,r);if(`issues`in u)throw Error(issuesMessage(u.issues));let{input:d,tool:f}=u,p;try{p=await s.executeTool(f.name,d,{abortSignal:i.abortSignal,callId:i.toolCallId})}catch(e){if(isConnectionAuthorizationRequiredError(e))return await o.handleError(e,c);throw e}let m=toConnectionToolResult(t.protocol,f,p);if(!m.ok)throw Error(m.error);return m.value}async function checkInput(e,t,n,r){let i;try{i=await listToolMetadata(t.connectionName,e.getClient(t.connectionName))}catch(e){return isConnectionAuthorizationRequiredError(e)?{value:r}:{issues:[{message:listingFailureMessage(t.connectionName,e)}]}}let a=await checkCall(t,i,n,r);return`issues`in a?{issues:a.issues}:{value:a.input}}async function checkCall(e,t,n,r){let i=t.find(e=>e.name===n);if(i===void 0)return{issues:[{message:unknownToolMessage(e,n,t)}]};let a=await defineJsonSchema(i.inputSchema)[`~standard`].validate(isObject(r)?r:{});return a.issues===void 0?{input:a.value,tool:i}:{issues:[...a.issues,{message:`Signature: ${connectionToolSignature(e,i)}`}]}}function issuesMessage(e){return e.map(({message:e,path:t=[]})=>{let n=t.map(e=>String(typeof e==`object`?e.key:e)).join(`.`);return n.length>0?`${n}: ${e}`:e}).join(` `)}function unknownToolMessage(e,t,n){let{connectionName:r}=e,i=closestNames(t,n).map(e=>connectionToolName(r,e));return`Connection "${r}" has no tool named "${t}".${i.length>0?` Closest tools: ${i.join(`, `)}.`:` Find its tools with ${SEARCH_TOOL_NAME}({ query: "${r}__" }).`}`}function connectionApproval(e){let{approval:t}=e;if(t===void 0)return;let n=resolveApprovalPolicy(t),request=t=>requestApproval(e,n,t),r=typeof t==`function`?void 0:t.response;return r===void 0?request:{request,response:t=>authorizeApprovalResponse(e,r,t)}}async function requestApproval(e,t,n){isApprovalRecheck(n)&&!matchesApprovalPin(n.callId,e)&&markApprovalPinChanged(n.callId);let r=await t(n);return!isApprovalRecheck(n)&&parksForApproval(r)&&pinApprovedInstance(n.callId,e),r}function parksForApproval(e){return e===!0||e===`user-approval`||typeof e==`object`&&e.type===`user-approval`}async function authorizeApprovalResponse(e,t,n){return matchesApprovalPin(n.request.callId,e)?await t(n):{reason:CONNECTION_CHANGED_MESSAGE,status:`rejected`}}function pinApprovedInstance(e,t){let n=loadContext();n.get(ConnectionApprovalPinsKey)?.[e]===void 0&&n.set(ConnectionApprovalPinsKey,(n={})=>Object.fromEntries([...Object.entries(n).slice(-49),[e,instanceKey(t)]]))}function matchesApprovalPin(e,t){let n=loadContext().get(ConnectionApprovalPinsKey)?.[e];return n!==void 0&&n===instanceKey(t)}function markApprovalPinChanged(e){loadContext().set(ConnectionApprovalPinsKey,(t={})=>({...t,[e]:`\0changed`}))}function releaseApprovalPin(e,t){let n=loadContext(),r=n.get(ConnectionApprovalPinsKey);if(r?.[e]===void 0)return;let{[e]:i,...a}=r;if(n.set(ConnectionApprovalPinsKey,a),i!==instanceKey(t))throw Error(CONNECTION_CHANGED_MESSAGE)}export{connectionEntry,connectionSignInEntry};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Announcement } from "#harness/announcements.js";
|
|
2
|
+
import type { StepCatalog } from "./step-catalog.js";
|
|
3
|
+
/**
|
|
4
|
+
* Announces the catalog: the kinds of deferred entries, their namespaces, and
|
|
5
|
+
* the connections, then the whole listing again whenever that changes.
|
|
6
|
+
* Connection tools stay unlisted, since listing them needs a network call and
|
|
7
|
+
* maybe a sign-in. `announced` holds the values announced so far.
|
|
8
|
+
*/
|
|
9
|
+
export declare function catalogAnnouncements(catalog: StepCatalog, announced: Readonly<Record<string, string>> | undefined): Readonly<Record<string, Announcement>>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{compareCodeUnits}from"./rank.js";import{CALL_TOOL_NAME,SEARCH_TOOL_NAME,SKILL_TOOL_NAME}from"#protocol/catalog-tools.js";import{isAgentTool}from"#execution/tasks/tool-entry-point.js";const ANNOUNCEMENT_KEY=`catalog`;function catalogAnnouncements(e,t){let n=listCatalog(e);if(t?.[ANNOUNCEMENT_KEY]===void 0&&isEmpty(n))return{};let r=reachableNames(e);return{[ANNOUNCEMENT_KEY]:{value:JSON.stringify(n),render:e=>renderCatalogAnnouncement(parseListing(e),n,r)}}}function listCatalog(e){let t=[...e.deferred.values()],n=[];t.some(e=>!isAgentTool(e))&&n.push(`tools`),t.some(isAgentTool)&&n.push(`agents`),[...e.skills.values()].some(({deferred:e})=>e)&&n.push(`skills`);let r=capped([...namespaceCounts(e)].sort(([e,t],[n,r])=>r-t||compareCodeUnits(e,n)).map(([e])=>e),20);return{connections:capped(e.connections.map(({connectionName:e,description:t})=>({description:t,name:e})).sort((e,t)=>compareCodeUnits(e.name,t.name)),20),kinds:n,namespaces:{...r,items:[...r.items].sort(compareCodeUnits)}}}function namespaceCounts(e){let t=new Set(e.connections.map(({connectionName:e})=>e)),n=new Map;for(let r of deferredNames(e)){let e=namespaceOf(r);e!==``&&!t.has(e)&&n.set(e,(n.get(e)??0)+1)}return n}function reachableNames(e){return new Set([...[...e.entries.keys(),...e.skills.keys()].map(namespaceOf),...e.connections.map(({connectionName:e})=>e)])}function namespaceOf(e){return e.slice(0,Math.max(0,e.indexOf(`__`)))}function deferredNames(e){return[...[...e.deferred.values()].map(({name:e})=>e),...[...e.skills.values()].filter(({deferred:e})=>e).map(({name:e})=>e)]}function capped(e,t){return{items:e.slice(0,t),more:e.length>t}}function renderCatalogAnnouncement(e,t,n){if(isEmpty(t))return`The catalog changed. It is empty now: ${SEARCH_TOOL_NAME} finds nothing.`;if(e===void 0||isEmpty(e))return renderListing(t);let r=[...e.namespaces.items,...e.connections.items.map(({name:e})=>e)].filter(e=>!n.has(e));return[`The catalog changed.`,renderListing(t),...r.length>0?[`No longer available: ${r.join(`, `)}`]:[]].join(`
|
|
2
|
+
`)}function renderListing({connections:e,kinds:t,namespaces:n}){let r=t.length===0?`Your connections have more tools`:`You have more ${joinWords(t)}`,i=t.includes(`skills`)?t.length===1&&e.items.length===0?`Load them with ${SKILL_TOOL_NAME}({ name }).`:`Call tools with ${CALL_TOOL_NAME}({ name, input }) and load skills with ${SKILL_TOOL_NAME}({ name }).`:`Call them with ${CALL_TOOL_NAME}({ name, input }).`,a=[`${r} than are loaded here. Before saying you have no tool for a task, look for one with ${SEARCH_TOOL_NAME}, which searches your own catalog, not the web. ${i}`];if(n.items.length>0){let e=[...n.items,...n.more?[`and more`]:[]];a.push(`Namespaces, whose entries are named <namespace>__<name>; search one with "<namespace>__": ${e.join(`, `)}`)}return e.items.length>0&&a.push(`Connections, whose tools are named <connection>__<tool>; search one connection's tools with "<connection>__":`,...e.items.map(formatConnection),...e.more?[`- and more`]:[]),a.join(`
|
|
3
|
+
`)}function joinWords(e){return e.length<=2?e.join(` and `):`${e.slice(0,-1).join(`, `)}, and ${e.at(-1)}`}function formatConnection(e){return e.description.length===0?`- ${e.name}`:`- ${e.name}: ${e.description}`}function isEmpty(e){return e.kinds.length===0&&e.connections.items.length===0}function parseListing(e){if(e!==void 0)try{return JSON.parse(e)}catch{return}}export{catalogAnnouncements};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ranking for `eve__search` and for `eve__tool`'s and `eve__skill`'s suggestions when a
|
|
3
|
+
* name is unknown.
|
|
4
|
+
* Query and text split into lowercase words (camelCase, acronyms, and
|
|
5
|
+
* punctuation are boundaries), so `create issue`, `createIssue`, and
|
|
6
|
+
* `create_issue` are the same words. Matches rank in tiers:
|
|
7
|
+
*
|
|
8
|
+
* 1. Exact: the query's words are the full name's words.
|
|
9
|
+
* 2. Exact without namespace: they are the name after its last `__`, so
|
|
10
|
+
* `create_issue` finds `linear__create_issue` and `sre__create_issue`.
|
|
11
|
+
* 3. Connection: they are the connection's name, or its first whole words,
|
|
12
|
+
* so `linear` lists the `linear` connection's tools, while `git` leaves
|
|
13
|
+
* `github`'s tools to the name prefix tier.
|
|
14
|
+
* 4. Name prefix: the full name's words, or those after its last `__`, start
|
|
15
|
+
* with the query's words, the last of which may be partial, so
|
|
16
|
+
* `create_iss` finds `create_issue` and `status page incidents` finds
|
|
17
|
+
* `sre__status_page_incidents_list`.
|
|
18
|
+
* 5. Keyword: any other match. A query word matches a word when either is a
|
|
19
|
+
* prefix of the other, so `repo` finds `repositories` and `issues` finds
|
|
20
|
+
* `issue`, and each query word adds the weight of every field it matches.
|
|
21
|
+
* One-letter and filler words such as `a` and `the` don't score when the
|
|
22
|
+
* query has other words, so `a` doesn't find `assign`.
|
|
23
|
+
*
|
|
24
|
+
* Within a tier, the keyword score orders matches, then connection, then name.
|
|
25
|
+
*/
|
|
26
|
+
/** What the ranker reads from one catalog entry. */
|
|
27
|
+
export interface RankCandidate {
|
|
28
|
+
/** The entry's own name; a connection tool's name without its connection prefix. */
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly description: string;
|
|
31
|
+
readonly inputSchema?: Readonly<Record<string, unknown>>;
|
|
32
|
+
readonly connection?: {
|
|
33
|
+
readonly description: string;
|
|
34
|
+
readonly name: string;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** Candidates matching `query`, best first. */
|
|
38
|
+
export declare function rankCandidates<T extends RankCandidate>(query: string, candidates: readonly T[]): T[];
|
|
39
|
+
/** Whether `query` has no searchable words, such as `"^"` or `" "`. */
|
|
40
|
+
export declare function isEmptyQuery(query: string): boolean;
|
|
41
|
+
/** Names of the candidates closest to an unknown `name`, best first. */
|
|
42
|
+
export declare function closestNames(name: string, candidates: readonly RankCandidate[]): string[];
|
|
43
|
+
/** Orders by UTF-16 code unit, the same in every locale. */
|
|
44
|
+
export declare function compareCodeUnits(a: string, b: string): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{connectionToolName}from"#connections/ownership.js";function rankCandidates(e,t){let n=tokenize(e),r=scoringTerms(n);return t.map(e=>({candidate:e,...rankCandidate(n,r,e)})).filter(e=>e.score>0).sort((e,t)=>e.tier-t.tier||t.score-e.score||compareCodeUnits(e.candidate.connection?.name??``,t.candidate.connection?.name??``)||compareCodeUnits(e.candidate.name,t.candidate.name)).map(e=>e.candidate)}function isEmptyQuery(e){return tokenize(e).length===0}function closestNames(e,t){return isEmptyQuery(e)?[]:rankCandidates(e,t).slice(0,5).map(e=>e.name)}const Tier={exact:0,exactWithoutNamespace:1,connection:2,namePrefix:3,keyword:4};function rankCandidate(e,t,n){let r=n.connection===void 0?n.name:connectionToolName(n.connection.name,n.name),i=tokenize(r),a=r.lastIndexOf(`__`),o=tokenize(a<0?r:r.slice(a+2)),s=sameWords(i,e)?Tier.exact:sameWords(o,e)?Tier.exactWithoutNamespace:n.connection!==void 0&&startsWithWholeWords(tokenize(n.connection.name),e)?Tier.connection:startsWithWords(i,e)||startsWithWords(o,e)?Tier.namePrefix:Tier.keyword;return{score:scoreFields(t,candidateFields(n)),tier:s}}const FILLER_WORDS=new Set([`a`,`an`,`and`,`for`,`in`,`is`,`me`,`my`,`of`,`or`,`please`,`the`,`to`,`with`]);function scoringTerms(e){let t=e.filter(e=>e.length>1&&!FILLER_WORDS.has(e));return t.length>0?t:e}function sameWords(e,t){return e.length===t.length&&startsWithWholeWords(e,t)}function startsWithWholeWords(e,t){return t.length<=e.length&&t.every((t,n)=>e[n]===t)}function startsWithWords(e,t){return t.length<=e.length&&t.every((n,r)=>r===t.length-1?e[r].startsWith(n):e[r]===n)}function candidateFields(e){let t=isObject(e.inputSchema?.properties)?Object.entries(e.inputSchema.properties):[],n=t.flatMap(([,e])=>isObject(e)&&typeof e.description==`string`?[e.description]:[]);return[[tokenize(e.name),6],[tokenize(e.connection?.name??``),4],[t.flatMap(([e])=>tokenize(e)),3],[proseWords(e.description),2],[n.flatMap(proseWords),1],[proseWords(e.connection?.description??``),1]]}function scoreFields(e,t){let n=0;for(let r of e)for(let[e,i]of t)e.some(e=>matchesWord(e,r))&&(n+=i);return n}function matchesWord(e,t){return e.startsWith(t)||e.length>=3&&t.startsWith(e)}function tokenize(e){return e.replaceAll(/([A-Z]+)([A-Z][a-z])/gu,`$1 $2`).replaceAll(/([a-z0-9])([A-Z])/gu,`$1 $2`).toLowerCase().split(/[^a-z0-9]+/u).filter(e=>e!==``)}function proseWords(e){return tokenize(e).filter(e=>e.length>1)}function compareCodeUnits(e,t){return e<t?-1:+(e>t)}export{closestNames,compareCodeUnits,isEmptyQuery,rankCandidates};
|