eve 0.47.7 → 0.49.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 +35 -0
- package/dist/src/channel/channel-address.js +1 -1
- package/dist/src/channel/delivery-metadata.d.ts +1 -0
- package/dist/src/channel/delivery-metadata.js +1 -1
- package/dist/src/channel/types.d.ts +20 -8
- package/dist/src/chunks/{use-eve-agent-Dg5S44kG.js → use-eve-agent-BZnOzAVd.js} +25 -5
- package/dist/src/chunks/{use-eve-agent-B5zw1dwj.js → use-eve-agent-Bgp6INfi.js} +25 -5
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/commands/integration-connect.d.ts +2 -1
- package/dist/src/cli/commands/integration-connect.js +1 -1
- package/dist/src/cli/commands/register-integration-commands.d.ts +3 -1
- package/dist/src/cli/commands/register-integration-commands.js +1 -1
- package/dist/src/cli/commands/registry-metadata.d.ts +30 -0
- package/dist/src/cli/commands/registry-metadata.js +1 -1
- package/dist/src/cli/commands/registry-package.d.ts +6 -0
- package/dist/src/cli/commands/registry-package.js +1 -1
- package/dist/src/cli/commands/registry-pnpm-build-policy-flow.d.ts +30 -0
- package/dist/src/cli/commands/registry-pnpm-build-policy-flow.js +1 -0
- package/dist/src/cli/commands/registry-pnpm-build-policy.d.ts +12 -0
- package/dist/src/cli/commands/registry-pnpm-build-policy.js +6 -0
- package/dist/src/cli/commands/registry-recovery.d.ts +4 -0
- package/dist/src/cli/commands/registry-recovery.js +1 -1
- package/dist/src/cli/commands/registry.d.ts +1 -1
- package/dist/src/cli/commands/registry.js +1 -1
- package/dist/src/cli/dev/command-options.d.ts +2 -0
- package/dist/src/cli/dev/run-interactive-ui.js +1 -1
- package/dist/src/cli/dev/tui/blocks.js +1 -1
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/registry-result-message.d.ts +17 -0
- package/dist/src/cli/dev/tui/registry-result-message.js +3 -0
- package/dist/src/cli/dev/tui/runner.d.ts +11 -4
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +9 -3
- package/dist/src/cli/dev/tui/setup-commands.js +2 -3
- package/dist/src/cli/dev/tui/setup-flow.d.ts +15 -5
- package/dist/src/cli/dev/tui/setup-panel.d.ts +6 -1
- package/dist/src/cli/dev/tui/setup-panel.js +4 -4
- package/dist/src/cli/dev/tui/setup-selection-input.d.ts +1 -0
- package/dist/src/cli/dev/tui/setup-selection-input.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
- package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
- package/dist/src/cli/dev/tui/tui.d.ts +3 -4
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/run.js +2 -2
- package/dist/src/client/agent-info-schema.d.ts +1 -0
- package/dist/src/client/agent-info-schema.js +1 -1
- package/dist/src/client/open-stream.d.ts +1 -0
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +7 -6
- package/dist/src/compiled/@opentelemetry/api/index.d.ts +6 -0
- package/dist/src/compiled/@workflow/builders/LICENSE.md +201 -0
- package/dist/src/compiled/@workflow/builders/index.d.ts +62 -0
- package/dist/src/compiled/@workflow/builders/index.js +1 -0
- package/dist/src/compiled/@workflow/core/attribute-changes.d.ts +2 -4
- package/dist/src/compiled/@workflow/core/capabilities.d.ts +10 -9
- package/dist/src/compiled/@workflow/core/capture-stack.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/class-serialization.d.ts +8 -8
- package/dist/src/compiled/@workflow/core/context-violation-error.d.ts +5 -5
- package/dist/src/compiled/@workflow/core/create-hook.d.ts +2 -2
- package/dist/src/compiled/@workflow/core/describe-error.d.ts +7 -7
- package/dist/src/compiled/@workflow/core/encryption.d.ts +5 -5
- package/dist/src/compiled/@workflow/core/events-consumer.d.ts +49 -14
- package/dist/src/compiled/@workflow/core/flushable-stream.d.ts +4 -4
- package/dist/src/compiled/@workflow/core/global.d.ts +4 -2
- package/dist/src/compiled/@workflow/core/index.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/log-format.d.ts +2 -2
- package/dist/src/compiled/@workflow/core/private.d.ts +40 -78
- package/dist/src/compiled/@workflow/core/private.js +1 -1
- package/dist/src/compiled/@workflow/core/replay-payload-cache.d.ts +13 -17
- package/dist/src/compiled/@workflow/core/runtime/compute-instance.d.ts +4 -3
- package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +27 -27
- package/dist/src/compiled/@workflow/core/runtime/count-step-started-events.d.ts +7 -7
- package/dist/src/compiled/@workflow/core/runtime/deployment-guard.d.ts +7 -7
- package/dist/src/compiled/@workflow/core/runtime/get-port-lazy.d.ts +2 -2
- package/dist/src/compiled/@workflow/core/runtime/get-world-lazy.d.ts +2 -2
- package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +30 -49
- package/dist/src/compiled/@workflow/core/runtime/quickjs-entrypoint.d.ts +21 -10
- package/dist/src/compiled/@workflow/core/runtime/quickjs-runtime.d.ts +31 -15
- package/dist/src/compiled/@workflow/core/runtime/quickjs-serde.d.ts +10 -10
- package/dist/src/compiled/@workflow/core/runtime/replay-budget.d.ts +4 -4
- package/dist/src/compiled/@workflow/core/runtime/replay-recovery-reporter.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/runtime/resume-hook.d.ts +20 -12
- package/dist/src/compiled/@workflow/core/runtime/resume-latency.d.ts +37 -30
- package/dist/src/compiled/@workflow/core/runtime/run-id-time.d.ts +2 -2
- package/dist/src/compiled/@workflow/core/runtime/run.d.ts +22 -5
- package/dist/src/compiled/@workflow/core/runtime/runs.d.ts +4 -4
- package/dist/src/compiled/@workflow/core/runtime/start.d.ts +3 -3
- package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +14 -14
- package/dist/src/compiled/@workflow/core/runtime/step-latency.d.ts +42 -25
- package/dist/src/compiled/@workflow/core/runtime/step-ownership.d.ts +6 -6
- package/dist/src/compiled/@workflow/core/runtime/step-single-flight.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +38 -24
- package/dist/src/compiled/@workflow/core/runtime/unserializable-step.d.ts +34 -0
- package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +2 -2
- package/dist/src/compiled/@workflow/core/runtime/wait-continuation.d.ts +31 -9
- package/dist/src/compiled/@workflow/core/runtime/wait-until.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/runtime/world-compatibility.d.ts +20 -9
- package/dist/src/compiled/@workflow/core/runtime/world-init.d.ts +5 -5
- package/dist/src/compiled/@workflow/core/runtime.js +3 -3
- package/dist/src/compiled/@workflow/core/sealed-box.d.ts +7 -7
- package/dist/src/compiled/@workflow/core/serialization/codec-devalue-vm.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/serialization/codec-devalue.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/serialization/codec.d.ts +4 -4
- package/dist/src/compiled/@workflow/core/serialization/compression.d.ts +12 -11
- package/dist/src/compiled/@workflow/core/serialization/encryption.d.ts +7 -7
- package/dist/src/compiled/@workflow/core/serialization/format.d.ts +6 -6
- package/dist/src/compiled/@workflow/core/serialization/hardened.d.ts +23 -22
- package/dist/src/compiled/@workflow/core/serialization/index.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/serialization/reducers/class-vm.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/serialization/reducers/step-function-vm.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/serialization/types.d.ts +5 -5
- package/dist/src/compiled/@workflow/core/serialization/workflow-vm.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/serialization-format.d.ts +11 -11
- package/dist/src/compiled/@workflow/core/serialization.d.ts +18 -19
- package/dist/src/compiled/@workflow/core/source-map.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/step/context-storage.d.ts +5 -5
- package/dist/src/compiled/@workflow/core/step/writable-stream.d.ts +3 -3
- package/dist/src/compiled/@workflow/core/symbols.d.ts +2 -2
- package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +71 -20
- package/dist/src/compiled/@workflow/core/telemetry.d.ts +15 -3
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/vm/script-cache.d.ts +9 -11
- package/dist/src/compiled/@workflow/core/workflow/abort-controller.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow/set-attributes.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow/world-init-stub.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/errors/index.d.ts +18 -18
- package/dist/src/compiled/@workflow/errors/index.js +1 -1
- package/dist/src/compiled/@workflow/world/analytics.d.ts +3 -2
- package/dist/src/compiled/@workflow/world/attributes-validation.d.ts +28 -0
- package/dist/src/compiled/@workflow/world/attributes.d.ts +8 -107
- package/dist/src/compiled/@workflow/world/env-config.d.ts +5 -5
- package/dist/src/compiled/@workflow/world/event-metadata.d.ts +132 -0
- package/dist/src/compiled/@workflow/world/events.d.ts +42 -96
- package/dist/src/compiled/@workflow/world/hooks.d.ts +12 -11
- package/dist/src/compiled/@workflow/world/index.d.ts +3 -3
- package/dist/src/compiled/@workflow/world/interfaces.d.ts +94 -39
- package/dist/src/compiled/@workflow/world/queue.d.ts +29 -22
- package/dist/src/compiled/@workflow/world/runs.d.ts +20 -0
- package/dist/src/compiled/@workflow/world/slot-identity.d.ts +3 -3
- package/dist/src/compiled/@workflow/world/spec-version.d.ts +82 -15
- package/dist/src/compiled/@workflow/world/ulid.d.ts +2 -2
- package/dist/src/compiled/@workflow/world-local/index.js +5 -5
- package/dist/src/compiled/@workflow/world-vercel/index.js +12 -12
- package/dist/src/compiled/_chunks/workflow/{attribute-changes-DXbpwBdw.js → attribute-changes-BwAadFfB.js} +3 -3
- package/dist/src/compiled/_chunks/workflow/debug-log-CVPstO1D.js +1 -0
- package/dist/src/compiled/_chunks/workflow/dist-CgbVZs5l.js +40 -0
- package/dist/src/compiled/_chunks/workflow/dist-DjojkP5e.js +3 -0
- package/dist/src/compiled/_chunks/workflow/frames-CZ9eHShe.js +3 -0
- package/dist/src/compiled/_chunks/workflow/global-singleton-BNinwFrL.js +1 -0
- package/dist/src/compiled/_chunks/workflow/private-CZFMABEf.js +1 -0
- package/dist/src/compiled/_chunks/workflow/resume-hook-BToMtPbH.js +1 -0
- package/dist/src/compiled/_chunks/workflow/run-DzyAoGh4.js +1 -0
- package/dist/src/compiled/_chunks/workflow/sleep-3_A5uOp-.js +1 -0
- package/dist/src/compiled/_chunks/workflow/undici-DfxNX5og.js +95 -0
- package/dist/src/compiled/_chunks/workflow/wait-until-BtySPYD0.js +15 -0
- package/dist/src/compiled/_chunks/workflow/ws-transport-PnVVxT0R.js +1 -0
- package/dist/src/compiler/extension-compatibility.d.ts +2 -2
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.d.ts +2 -2
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/keys.d.ts +3 -8
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/eve-channel/types.d.ts +7 -7
- package/dist/src/execution/accepted-delivery-deployment.d.ts +7 -0
- package/dist/src/execution/accepted-delivery-deployment.js +1 -0
- package/dist/src/execution/agent-handle-dispatch.js +1 -1
- package/dist/src/execution/cancel-descendant-turns-step.d.ts +4 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/continuation-conflict-step.d.ts +10 -0
- package/dist/src/execution/continuation-conflict-step.js +1 -0
- package/dist/src/execution/delegated-parent-notification.js +1 -1
- package/dist/src/execution/delegation-tool.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-shared.d.ts +14 -31
- package/dist/src/execution/dispatch-runtime-actions-shared.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-start.d.ts +33 -0
- package/dist/src/execution/dispatch-runtime-actions-start.js +1 -0
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/dispatch-turn-step.js +1 -1
- package/dist/src/execution/durable-session-migrations/turn-workflow-v1-to-v2.d.ts +2 -0
- package/dist/src/execution/durable-session-migrations/turn-workflow-v1-to-v2.js +1 -0
- package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +25 -3
- package/dist/src/execution/durable-session-migrations/turn-workflow.js +1 -1
- package/dist/src/execution/dynamic-connections.js +1 -1
- package/dist/src/execution/eve-workflow-attributes.js +1 -1
- package/dist/src/execution/finalize-terminal-session.d.ts +17 -0
- package/dist/src/execution/finalize-terminal-session.js +1 -0
- package/dist/src/execution/inline-turn.d.ts +29 -0
- package/dist/src/execution/inline-turn.js +1 -0
- package/dist/src/execution/next-driver-action.d.ts +9 -4
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/parked-delivery-wait.js +1 -1
- package/dist/src/execution/pending-turn-state.d.ts +1 -0
- package/dist/src/execution/pending-turn-state.js +1 -1
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/remote-agent-dispatch.d.ts +2 -0
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/runtime-errors.d.ts +0 -12
- package/dist/src/execution/runtime-errors.js +1 -1
- package/dist/src/execution/session-command-token.d.ts +2 -0
- package/dist/src/execution/session-command-token.js +1 -1
- package/dist/src/execution/session-timeout-steps.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/stable-workflow-names.d.ts +12 -0
- package/dist/src/execution/stable-workflow-names.js +1 -0
- package/dist/src/execution/subagent-event-proxy-step.d.ts +3 -0
- package/dist/src/execution/subagent-event-proxy-step.js +1 -1
- package/dist/src/execution/subagent-hitl-proxy.d.ts +2 -1
- package/dist/src/execution/subagent-hitl-proxy.js +1 -1
- package/dist/src/execution/subagent-start-local.js +1 -1
- package/dist/src/execution/subagent-start-remote.d.ts +2 -0
- package/dist/src/execution/subagent-start-remote.js +1 -1
- package/dist/src/execution/tasks/child/steps.d.ts +2 -0
- package/dist/src/execution/tasks/child/steps.js +1 -1
- package/dist/src/execution/tasks/child/workflow.js +1 -1
- package/dist/src/execution/tasks/parent/dispatch-task-step.js +1 -1
- package/dist/src/execution/tasks/parent/dispatch.js +1 -1
- package/dist/src/execution/tasks/parent/hitl-proxy-steps.js +1 -1
- package/dist/src/execution/tasks/parent/run-parent.js +1 -1
- package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
- package/dist/src/execution/terminal-session-completion-step.js +1 -1
- package/dist/src/execution/terminal-session-event.d.ts +13 -0
- package/dist/src/execution/terminal-session-event.js +1 -0
- package/dist/src/execution/terminal-session-failure-step.d.ts +1 -0
- package/dist/src/execution/terminal-session-failure-step.js +1 -1
- package/dist/src/execution/tool-run/answer.d.ts +3 -0
- package/dist/src/execution/tool-run/answer.js +1 -0
- package/dist/src/execution/tool-run/background.d.ts +14 -0
- package/dist/src/execution/tool-run/background.js +1 -0
- package/dist/src/execution/tool-run/cancel.d.ts +7 -0
- package/dist/src/execution/tool-run/cancel.js +1 -0
- package/dist/src/execution/tool-run/dispatch.d.ts +24 -0
- package/dist/src/execution/tool-run/dispatch.js +1 -0
- package/dist/src/execution/tool-run/emit-run-report-step.d.ts +7 -0
- package/dist/src/execution/tool-run/emit-run-report-step.js +1 -0
- package/dist/src/execution/tool-run/messages.d.ts +70 -0
- package/dist/src/execution/tool-run/messages.js +1 -0
- package/dist/src/execution/tool-run/owner-channels.d.ts +29 -0
- package/dist/src/execution/tool-run/owner-channels.js +1 -0
- package/dist/src/execution/tool-run/owner-inbox.d.ts +11 -0
- package/dist/src/execution/tool-run/owner-inbox.js +1 -0
- package/dist/src/execution/tool-run/owner.d.ts +13 -0
- package/dist/src/execution/tool-run/owner.js +1 -0
- package/dist/src/execution/tool-run/resume-hook-step.d.ts +4 -0
- package/dist/src/execution/tool-run/resume-hook-step.js +1 -0
- package/dist/src/execution/tool-run/run-control.d.ts +18 -0
- package/dist/src/execution/tool-run/run-control.js +1 -0
- package/dist/src/execution/tool-run/start.d.ts +11 -0
- package/dist/src/execution/tool-run/start.js +1 -0
- package/dist/src/execution/tool-run/types.d.ts +21 -0
- package/dist/src/execution/tool-run/types.js +1 -0
- package/dist/src/execution/tool-run/workflow.d.ts +9 -0
- package/dist/src/execution/tool-run/workflow.js +1 -0
- package/dist/src/execution/tools/subagent/local.js +1 -1
- package/dist/src/execution/turn-cancellation-control.d.ts +2 -0
- package/dist/src/execution/turn-cancellation-control.js +1 -1
- package/dist/src/execution/turn-control-receiver.js +1 -1
- package/dist/src/execution/turn-dispatch.d.ts +4 -2
- package/dist/src/execution/turn-dispatch.js +1 -1
- package/dist/src/execution/turn-execution-cursor.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/wire/session-inbox-contract.d.ts +2 -2
- package/dist/src/execution/wire/session-inbox-contract.js +1 -1
- package/dist/src/execution/wire/session-inbox-encoder.d.ts +6 -2
- package/dist/src/execution/wire/session-inbox-encoder.js +1 -1
- package/dist/src/execution/wire/session-inbox-resume.js +1 -1
- package/dist/src/execution/wire/session-inbox-wire.js +1 -1
- package/dist/src/execution/wire/session-inbox-wire.v1.js +1 -1
- package/dist/src/execution/wire/session-inbox-wire.v2-migration.d.ts +0 -2
- package/dist/src/execution/wire/session-inbox-wire.v2-migration.js +1 -1
- package/dist/src/execution/wire/session-inbox-wire.v2.migration.d.ts +3 -0
- package/dist/src/execution/wire/session-inbox-wire.v2.migration.js +1 -0
- package/dist/src/execution/wire/session-inbox-wire.v3.d.ts +480 -0
- package/dist/src/execution/wire/session-inbox-wire.v3.js +1 -0
- package/dist/src/execution/wire/session-inbox-wire.v3.migration.d.ts +3 -0
- package/dist/src/execution/wire/session-inbox-wire.v3.migration.js +1 -0
- package/dist/src/execution/workflow-entry-finalization.js +1 -1
- package/dist/src/execution/workflow-entry.d.ts +5 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-registry.d.ts +5 -0
- package/dist/src/execution/workflow-registry.js +1 -0
- package/dist/src/execution/workflow-runtime.d.ts +17 -19
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/execution/workflow-webhook-route.d.ts +4 -0
- package/dist/src/execution/workflow-webhook-route.js +1 -0
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/proxy-input-requests.d.ts +10 -0
- package/dist/src/harness/proxy-input-requests.js +1 -1
- package/dist/src/harness/runtime-actions.d.ts +2 -0
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/tool-runs.d.ts +21 -0
- package/dist/src/harness/tool-runs.js +1 -0
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/instrumentation/content-policy.d.ts +3 -1
- package/dist/src/instrumentation/content-policy.js +1 -1
- package/dist/src/instrumentation/runtime.d.ts +2 -2
- package/dist/src/instrumentation/runtime.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/attachments/errors.d.ts +3 -0
- package/dist/src/internal/authored-module-loader.d.ts +7 -1
- package/dist/src/internal/authored-module-loader.js +3 -3
- package/dist/src/internal/authored-package-boundary.js +1 -1
- package/dist/src/internal/authored-runtime-modules.d.ts +2 -0
- package/dist/src/internal/authored-runtime-modules.js +1 -1
- package/dist/src/internal/nitro/development-generation.d.ts +2 -0
- package/dist/src/internal/nitro/development-generation.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/routes/agent-info/build-agent-info-response.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/workflow/development-world-client.js +1 -1
- package/dist/src/internal/workflow-bundle/authored-workflow-directives.d.ts +17 -0
- package/dist/src/internal/workflow-bundle/authored-workflow-directives.js +1 -0
- package/dist/src/internal/workflow-bundle/authored-workflow-modules.d.ts +19 -0
- package/dist/src/internal/workflow-bundle/authored-workflow-modules.js +1 -0
- package/dist/src/internal/workflow-bundle/builder-support.d.ts +17 -2
- package/dist/src/internal/workflow-bundle/builder-support.js +4 -3
- package/dist/src/internal/workflow-bundle/builder.d.ts +2 -2
- package/dist/src/internal/workflow-bundle/builder.js +2 -2
- package/dist/src/internal/workflow-bundle/dynamic-capability-transform-plugin.d.ts +2 -0
- package/dist/src/internal/workflow-bundle/dynamic-capability-transform-plugin.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.d.ts +3 -0
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-builders.d.ts +6 -2
- package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +3 -0
- package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-directive-ast.d.ts +7 -0
- package/dist/src/internal/workflow-bundle/workflow-directive-ast.js +1 -0
- package/dist/src/internal/workflow-bundle/workflow-transformer.d.ts +15 -1
- package/dist/src/internal/workflow-bundle/workflow-transformer.js +4 -4
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/protocol/baggage.d.ts +6 -0
- package/dist/src/protocol/baggage.js +1 -0
- package/dist/src/public/channels/slack/attachments.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +7 -1
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/attachments.d.ts +2 -2
- package/dist/src/public/channels/teams/attachments.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/attachments.js +1 -1
- package/dist/src/public/definitions/remote-agent.d.ts +6 -3
- package/dist/src/public/workflow/index.d.ts +3 -0
- package/dist/src/public/workflow/index.js +1 -0
- package/dist/src/public/workflow-modules.d.js +1 -0
- package/dist/src/public/workflow-modules.d.ts +11 -0
- package/dist/src/runtime/actions/keys.js +1 -1
- package/dist/src/runtime/tools/registry.js +1 -1
- package/dist/src/setup/connection-connector.d.ts +4 -2
- package/dist/src/setup/connection-connector.js +2 -2
- package/dist/src/setup/flows/login.js +1 -1
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/flows/provider.d.ts +5 -0
- package/dist/src/setup/flows/provider.js +4 -4
- package/dist/src/setup/flows/registry-session.d.ts +24 -7
- package/dist/src/setup/flows/registry-session.js +1 -1
- package/dist/src/setup/flows/registry.d.ts +35 -29
- package/dist/src/setup/flows/registry.js +2 -1
- package/dist/src/setup/integrations/web/setup.d.ts +0 -2
- package/dist/src/setup/integrations/web/setup.js +1 -1
- package/dist/src/setup/prompter.d.ts +24 -4
- package/dist/src/setup/prompter.js +1 -1
- package/dist/src/setup/scaffold/connections/catalog.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +2 -2
- package/dist/src/setup/vercel-project.js +0 -0
- package/dist/src/shared/dispatch-action.d.ts +6 -0
- package/dist/src/shared/forwarded-trace-policy.d.ts +28 -0
- package/dist/src/shared/forwarded-trace-policy.js +1 -0
- package/dist/src/shared/instrumentation-decision.d.ts +3 -0
- package/dist/src/shared/instrumentation-decision.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tools/behavior.d.ts +6 -0
- package/dist/src/tools/definition.d.ts +39 -3
- package/dist/src/tracing/agent-otel-provider.js +2 -2
- package/dist/src/tracing/agent-otel-session-context.js +1 -1
- package/dist/src/tracing/agent-trace-context-store.d.ts +1 -1
- package/dist/src/tracing/agent-trace-context-store.js +1 -1
- package/dist/src/tracing/otel-declaration.d.ts +5 -3
- package/dist/src/tracing/otel-registration.d.ts +1 -1
- package/dist/src/tracing/otel-registration.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/custom.mdx +6 -0
- package/docs/channels/eve.mdx +14 -6
- package/docs/channels/mcp.mdx +4 -1
- package/docs/channels/teams.mdx +6 -1
- package/docs/concepts/sessions-runs-and-streaming.md +4 -2
- package/docs/guides/auth-and-route-protection.md +5 -1
- package/docs/guides/client/messages.mdx +6 -0
- package/docs/guides/dev-tui.md +30 -18
- package/docs/guides/instrumentation.md +1 -1
- package/docs/guides/remote-agents.md +25 -0
- package/docs/install-integrations.mdx +2 -0
- package/docs/instructions.mdx +1 -1
- package/docs/memory/custom-provider.md +214 -0
- package/docs/memory/file.md +129 -0
- package/docs/memory/meta.json +5 -0
- package/docs/memory/overview.mdx +282 -0
- package/docs/patterns/multi-tenant-memory.md +12 -20
- package/docs/reference/cli.md +2 -2
- package/docs/tools/meta.json +1 -1
- package/docs/tools/overview.mdx +7 -0
- package/docs/tools/workflows.mdx +288 -0
- package/package.json +18 -7
- package/dist/src/compiled/_chunks/workflow/dist-CqvWKNQv.js +0 -3
- package/dist/src/compiled/_chunks/workflow/dist-Dk0aQqFO.js +0 -40
- package/dist/src/compiled/_chunks/workflow/dist-DpYyXbJv.js +0 -1
- package/dist/src/compiled/_chunks/workflow/env-config-L94XftKz.js +0 -1
- package/dist/src/compiled/_chunks/workflow/frames-Dl2Hcma4.js +0 -3
- package/dist/src/compiled/_chunks/workflow/private-CuQ4HTFC.js +0 -1
- package/dist/src/compiled/_chunks/workflow/resume-hook-E-Nkx8q_.js +0 -1
- package/dist/src/compiled/_chunks/workflow/run-cIeex2KF.js +0 -1
- package/dist/src/compiled/_chunks/workflow/sleep-CxFsdxB_.js +0 -1
- package/dist/src/compiled/_chunks/workflow/spec-version-DBUVfF_R.js +0 -1
- package/dist/src/compiled/_chunks/workflow/undici-DznrXKcM.js +0 -95
- package/dist/src/compiled/_chunks/workflow/wait-until-BZHmJCAW.js +0 -15
- package/dist/src/compiled/_chunks/workflow/ws-transport-Ct6yyRWZ.js +0 -1
- package/dist/src/internal/authored-directive-prologue.d.ts +0 -4
- package/dist/src/internal/authored-directive-prologue.js +0 -1
- package/docs/memory.md +0 -408
|
@@ -1,6 +1,18 @@
|
|
|
1
|
+
import { type WorkflowDirective } from "#internal/workflow-bundle/workflow-directive-ast.js";
|
|
1
2
|
import type { WorkflowManifest } from "./workflow-builders.js";
|
|
2
3
|
type WorkflowDirectiveMode = "workflow" | "step" | "client" | false;
|
|
4
|
+
/** Reads the syntax tree, so a directive quoted in a string or comment never counts. */
|
|
5
|
+
export declare function findWorkflowDirectiveFunctions(filename: string, source: string): Promise<readonly {
|
|
6
|
+
readonly directive: WorkflowDirective;
|
|
7
|
+
readonly name: string;
|
|
8
|
+
}[]>;
|
|
3
9
|
export declare function transformWorkflowDirectives(input: {
|
|
10
|
+
/**
|
|
11
|
+
* Authored modules keep their body in workflow mode (steps become proxies in
|
|
12
|
+
* place) and lose an eve-definer default export, so the driver never
|
|
13
|
+
* evaluates the tool definition or its schema dependencies.
|
|
14
|
+
*/
|
|
15
|
+
authored?: boolean;
|
|
4
16
|
filename: string;
|
|
5
17
|
mode: WorkflowDirectiveMode;
|
|
6
18
|
moduleSpecifier: string | undefined;
|
|
@@ -15,11 +27,13 @@ export declare function transformWorkflowDirectives(input: {
|
|
|
15
27
|
/**
|
|
16
28
|
* Workflow function names whose bundled id should be emitted without
|
|
17
29
|
* the package version stamp. See `STABLE_WORKFLOW_NAMES` in
|
|
18
|
-
* `workflow-
|
|
30
|
+
* `stable-workflow-names.ts` for the canonical set eve itself uses.
|
|
19
31
|
*/
|
|
20
32
|
stableWorkflowNames?: ReadonlySet<string>;
|
|
21
33
|
}): Promise<{
|
|
22
34
|
code: string;
|
|
23
35
|
workflowManifest: WorkflowManifest;
|
|
24
36
|
}>;
|
|
37
|
+
export declare function stripJavaScriptExtension(path: string): string;
|
|
38
|
+
export declare function createWorkflowId(idBase: string, functionName: string): string;
|
|
25
39
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{parseWithNitroRolldownAst}from"#internal/bundler/nitro-rolldown.js";const BUILTIN_STEP_NAMES=new Set([`__builtin_response_array_buffer`,`__builtin_response_json`,`__builtin_response_text`,`__builtin_set_attributes`]);async function
|
|
2
|
-
`)}\n`:``}`,workflowManifest:
|
|
3
|
-
`)}\n`:``}function findDirectiveFunctions(e){let t=[],n=collectLocalNamesReExportedAtModuleLevel(e);for(let r of e.body??[]){let e=readTopLevelFunctionDeclaration(r);if(e===null)continue;let i=e.fn,a=i.id?.name,o=readBlockStatements(i.body);if(i.async!==!0||a===void 0||o===void 0)continue;let s=readFunctionDirective(o[0]);s!==null&&t.push({directive:s.value,directiveEnd:s.end,directiveStart:s.start,exportPrefix:e.exported?`export `:``,exported:e.exported||n.has(a),name:a,rangeEnd:e.end,rangeStart:e.start})}return t}function collectLocalNamesReExportedAtModuleLevel(e){let t=new Set;for(let n of e.body??[])if(n.type===`ExportNamedDeclaration`&&!(n.source!==void 0&&n.source!==null)&&!(n.declaration!==void 0&&n.declaration!==null))for(let e of n.specifiers??[]){let n=e.local?.name;n!==void 0&&t.add(n)}return t}function readTopLevelFunctionDeclaration(e){return e.type===`FunctionDeclaration`?readFunctionDeclarationRange(e,!1,e):e.type!==`ExportNamedDeclaration`||e.declaration?.type!==`FunctionDeclaration`?null:readFunctionDeclarationRange(e.declaration,!0,e)}function readFunctionDeclarationRange(e,t,n){return e.start===void 0||e.end===void 0||n.start===void 0||n.end===void 0?null:{end:n.end,exported:t,fn:e,start:n.start}}function readBlockStatements(e){return e===void 0||Array.isArray(e)?e:e.body}function readFunctionDirective(e){let t=
|
|
1
|
+
import{WORKFLOW_REGISTRY_GLOBAL}from"#execution/workflow-registry.js";import{parseWithNitroRolldownAst}from"#internal/bundler/nitro-rolldown.js";import{readWorkflowDirective}from"#internal/workflow-bundle/workflow-directive-ast.js";const BUILTIN_STEP_NAMES=new Set([`__builtin_response_array_buffer`,`__builtin_response_json`,`__builtin_response_text`,`__builtin_set_attributes`]);async function findWorkflowDirectiveFunctions(e,t){return findDirectiveFunctions(await parseWorkflowSource(e,t)).map(e=>({directive:e.directive,name:e.name}))}async function transformWorkflowDirectives(t){if(t.mode===!1)return{code:t.source,workflowManifest:{}};let n=await parseWorkflowSource(t.filename,t.source),r=findDirectiveFunctions(n);if(r.length===0)return{code:t.source,workflowManifest:{}};let i=t.moduleSpecifier??`./${stripJavaScriptExtension(t.filename)}`,a=t.stableModuleSpecifier??i,o={},s=[],c=[],l=!1;for(let n of r){if(n.directive===`use step`){let e=createStepId(i,n.name);o.steps??={};let r=o.steps[t.filename]??={};if(r[n.name]={stepId:e},t.mode===`workflow`){let t=n.exportPrefix.length>0?`export `:``;s.push({end:n.rangeEnd,start:n.rangeStart,text:`${t}var ${n.name} = globalThis[Symbol.for("WORKFLOW_USE_STEP")](${JSON.stringify(e)});`})}else s.push({end:n.directiveEnd,start:n.directiveStart,text:``}),t.mode===`step`?(l=!0,c.push(`registerStepFunction(${JSON.stringify(e)}, ${n.name});`)):c.push(`${n.name}.stepId = ${JSON.stringify(e)};`);continue}let r=createWorkflowId(t.stableWorkflowNames?.has(n.name)===!0?a:i,n.name);o.workflows??={};let u=o.workflows[t.filename]??={};u[n.name]={workflowId:r},t.mode===`workflow`?(s.push({end:n.directiveEnd,start:n.directiveStart,text:``}),c.push(`${n.name}.workflowId = ${JSON.stringify(r)};`),c.push(`globalThis.${WORKFLOW_REGISTRY_GLOBAL}.set(${JSON.stringify(r)}, ${n.name});`)):(s.push({end:n.directiveEnd,start:n.directiveStart,text:`throw new Error(${JSON.stringify(`You attempted to execute workflow ${n.name} function directly. To start a workflow, use start(${n.name}) from workflow/api`)});`}),c.push(`${n.name}.workflowId = ${JSON.stringify(r)};`))}let u=`/**__internal_workflows${JSON.stringify(o)}*/;`,d=r.some(e=>e.directive===`use workflow`);if(t.mode===`workflow`&&!d&&t.authored!==!0)return{code:`${u}\n${createWorkflowStepProxySource(t.source,n,r,i)}`,workflowManifest:o};t.mode===`workflow`&&t.authored===!0&&s.push(...removeEveDefinerDefaultExport(n));let f=applySourceReplacements(t.source,s),p=t.mode===`workflow`?await stripUnusedValueImports(t.filename,f):f;return{code:`${l?`import { registerStepFunction } from "workflow/internal/private";\n${u}\n`:`${u}\n`}${p}${c.length>0?`\n${c.join(`
|
|
2
|
+
`)}\n`:``}`,workflowManifest:o}}async function parseWorkflowSource(e,n){return await parseWithNitroRolldownAst(e,n)}function createWorkflowStepProxySource(e,t,n,r){let i=findExportedLiteralValueDeclarations(e,t),a=n.filter(e=>e.directive===`use step`).map(e=>{let t=e.exported?`export `:``,n=createStepId(r,e.name);return`${t}var ${e.name} = globalThis[Symbol.for("WORKFLOW_USE_STEP")](${JSON.stringify(n)});`}),o=[...i,...a];return o.length>0?`${o.join(`
|
|
3
|
+
`)}\n`:``}function findDirectiveFunctions(e){let t=[],n=collectLocalNamesReExportedAtModuleLevel(e);for(let r of e.body??[]){let e=readTopLevelFunctionDeclaration(r);if(e===null)continue;let i=e.fn,a=i.id?.name,o=readBlockStatements(i.body);if(i.async!==!0||a===void 0||o===void 0)continue;let s=readFunctionDirective(o[0]);s!==null&&t.push({directive:s.value,directiveEnd:s.end,directiveStart:s.start,exportPrefix:e.exported?`export `:``,exported:e.exported||n.has(a),name:a,rangeEnd:e.end,rangeStart:e.start})}return t}function collectLocalNamesReExportedAtModuleLevel(e){let t=new Set;for(let n of e.body??[])if(n.type===`ExportNamedDeclaration`&&!(n.source!==void 0&&n.source!==null)&&!(n.declaration!==void 0&&n.declaration!==null))for(let e of n.specifiers??[]){let n=e.local?.name;n!==void 0&&t.add(n)}return t}function readTopLevelFunctionDeclaration(e){return e.type===`FunctionDeclaration`?readFunctionDeclarationRange(e,!1,e):e.type!==`ExportNamedDeclaration`||e.declaration?.type!==`FunctionDeclaration`?null:readFunctionDeclarationRange(e.declaration,!0,e)}function readFunctionDeclarationRange(e,t,n){return e.start===void 0||e.end===void 0||n.start===void 0||n.end===void 0?null:{end:n.end,exported:t,fn:e,start:n.start}}function readBlockStatements(e){return e===void 0||Array.isArray(e)?e:e.body}function readFunctionDirective(e){let t=readWorkflowDirective(e);return t===void 0||e?.start===void 0||e.end===void 0?null:{end:e.end,start:e.start,value:t}}function applySourceReplacements(e,t){let n=``,r=0;for(let i of[...t].sort((e,t)=>e.start-t.start))n+=e.slice(r,i.start),n+=i.text,r=i.end;return n+e.slice(r)}function removeEveDefinerDefaultExport(e){let t=new Set;for(let n of e.body??[]){if(n.type!==`ImportDeclaration`||n.importKind===`type`)continue;let e=n.source?.value;if(!(typeof e!=`string`||!/^eve(?:\/|$)/.test(e)))for(let e of n.specifiers??[]){if(e.importKind===`type`)continue;let n=e.local?.name;n!==void 0&&t.add(n)}}let n=[];for(let r of e.body??[]){if(r.type!==`ExportDefaultDeclaration`||r.start===void 0)continue;let e=r.declaration;if(e?.type!==`CallExpression`||r.end===void 0)continue;let i=e.callee;i?.type!==`Identifier`||!t.has(i.name??``)||n.push({end:r.end,start:r.start,text:``})}return n}async function stripUnusedValueImports(e,t){let n=await parseWorkflowSource(e,t),r=collectReferencedIdentifiers(n),i=[];for(let e of n.body??[]){if(e.type!==`ImportDeclaration`||e.start===void 0||e.end===void 0)continue;let n=readValueImportBindings(e);n.length>0&&n.every(e=>!r.has(e))&&i.push({end:extendRemovalEnd(t,e.end),start:e.start,text:``})}return i.length>0?applySourceReplacements(t,i):t}function findExportedLiteralValueDeclarations(e,t){let n=[],r=collectLocalReExportAliases(t);for(let i of t.body??[]){if(i.type===`ExportNamedDeclaration`&&i.declaration?.type===`VariableDeclaration`&&i.declaration.kind===`const`&&i.start!==void 0&&i.end!==void 0&&(i.declaration.declarations??[]).every(isLiteralValueDeclarator)){n.push(e.slice(i.start,i.end).trim());continue}if(i.type===`VariableDeclaration`&&(i.kind===`const`||i.kind===`var`||i.kind===`let`))for(let t of i.declarations??[]){if(!isLiteralValueDeclarator(t)||t.start===void 0||t.end===void 0)continue;let a=t.id?.name;if(a===void 0)continue;let o=r.get(a);if(o===void 0||o.length===0)continue;let s=e.slice(t.start,t.end).trim(),c=o.map(e=>e===a?a:`${a} as ${e}`);n.push(`${i.kind} ${s};\nexport { ${c.join(`, `)} };`)}}return n}function collectLocalReExportAliases(e){let t=new Map;for(let n of e.body??[])if(n.type===`ExportNamedDeclaration`&&!(n.source!==void 0&&n.source!==null)&&!(n.declaration!==void 0&&n.declaration!==null))for(let e of n.specifiers??[]){let n=e.local?.name,r=e.exported?.name??n;if(n!==void 0&&r!==void 0){let e=t.get(n)??[];e.push(r),t.set(n,e)}}return t}function isLiteralValueDeclarator(e){return isLiteralValueExpression(e.init)}function isLiteralValueExpression(e){return e==null?!1:e.type===`Literal`?e.value===null||typeof e.value==`boolean`||typeof e.value==`number`||typeof e.value==`string`:e.type===`TemplateLiteral`&&(e.expressions??[]).length===0?!0:e.type===`TSAsExpression`||e.type===`TSSatisfiesExpression`||e.type===`TSNonNullExpression`||e.type===`TSTypeAssertion`?isLiteralValueExpression(e.expression):e.type===`UnaryExpression`&&e.argument?.type===`Literal`&&typeof e.argument.value==`number`}function readValueImportBindings(e){return e.importKind===`type`?[]:(e.specifiers??[]).filter(e=>e.importKind!==`type`).map(e=>e.local?.name).filter(e=>e!==void 0)}function collectReferencedIdentifiers(e){let t=new Set;return visitAstNode(e,e=>{e.type===`Identifier`&&typeof e.name==`string`&&t.add(e.name)}),t}function visitAstNode(e,t){if(!(e.type===`ImportDeclaration`||e.type?.startsWith(`TS`))){t(e);for(let n of Object.values(e))if(Array.isArray(n))for(let e of n)isAstNode(e)&&visitAstNode(e,t);else isAstNode(n)&&visitAstNode(n,t)}}function isAstNode(e){return typeof e==`object`&&!!e&&typeof e.type==`string`}function extendRemovalEnd(e,t){let n=t;for(;n<e.length&&(e[n]===` `||e[n]===` `);)n+=1;return e[n]===`\r`&&e[n+1]===`
|
|
4
4
|
`?n+2:e[n]===`
|
|
5
|
-
`?n+1:n}function stripJavaScriptExtension(e){return e.replace(/\.(?:[cm]?[jt]sx?)$/,``)}function createStepId(e,
|
|
5
|
+
`?n+1:n}function stripJavaScriptExtension(e){return e.replace(/\.(?:[cm]?[jt]sx?)$/,``)}function createWorkflowId(e,t){return`workflow//${e}//${t}`}function createStepId(e,t){return BUILTIN_STEP_NAMES.has(t)?t:`step//${e}//${t}`}export{createWorkflowId,findWorkflowDirectiveFunctions,stripJavaScriptExtension,transformWorkflowDirectives};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function connectionProtocols(e){return[e.mcp?`mcp`:null,e.openapi?`openapi`:null].filter(e=>e!==null)}const INTEGRATIONS=[{slug:`slack`,name:`Slack`,kind:`channel`,tagline:`Mention your agent in channels and DMs, with Connect-managed auth.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0}},{slug:`discord`,name:`Discord`,kind:`channel`,tagline:`Run your agent as a Discord bot across servers and threads.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`teams`,name:`Microsoft Teams`,kind:`channel`,tagline:`Bring your agent into Teams chats and channels.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`telegram`,name:`Telegram`,kind:`channel`,tagline:`Connect your agent to a Telegram bot for 1:1 and group chats.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`twilio`,name:`Twilio`,kind:`channel`,tagline:`Put your agent on a phone number: SMS and speech-transcribed calls.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`blooio`,name:`Blooio`,kind:`channel`,tagline:`Send and receive iMessage, RCS, and SMS through Blooio.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`github`,name:`GitHub`,kind:`channel`,tagline:`Drive your agent from issues, pull requests, and comments, with guided Connect setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`linear-agent`,name:`Linear Agent`,kind:`channel`,tagline:`Delegate Linear issues and comments through Agent Sessions, with guided Connect setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`eve`,name:`Web Chat`,kind:`channel`,tagline:`Embed a first-party web chat UI backed by your agent.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0}},{slug:`buzz`,name:`Buzz`,kind:`channel`,tagline:`Talk to your eve agent from Buzz through its ACP desktop harness.`,surfaces:{scaffoldable:!1,registry:!1,gallery:!0}},{slug:`chat-sdk-gchat`,name:`Google Chat`,kind:`channel`,tagline:`Google Chat spaces and DMs via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-whatsapp`,name:`WhatsApp`,kind:`channel`,tagline:`Customer messaging through WhatsApp Business Cloud via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-x`,name:`X`,kind:`channel`,tagline:`Public mentions and DMs on X via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-messenger`,name:`Messenger`,kind:`channel`,tagline:`Facebook Messenger bots with templates, buttons, and reactions via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-zernio`,name:`Zernio`,kind:`channel`,tagline:`Reach seven social and messaging platforms through one Zernio integration.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-velt`,name:`Velt`,kind:`channel`,tagline:`Add agents to anchored comments across documents, canvases, PDFs, and video.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-sendblue`,name:`Sendblue`,kind:`channel`,tagline:`Send and receive iMessage, SMS, and RCS through Sendblue.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-novu`,name:`Novu`,kind:`channel`,tagline:`Reach Slack, Teams, WhatsApp, Telegram, and email through Novu.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-liveblocks`,name:`Liveblocks`,kind:`channel`,tagline:`Bring your agent into Liveblocks comment threads, mentions, and reactions.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`linq`,name:`Linq`,kind:`channel`,tagline:`iMessage and SMS conversations through Linq, with guided Connect or portable setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-kapso`,name:`Kapso`,kind:`channel`,tagline:`Managed WhatsApp conversations, media, buttons, and history through Kapso.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`photon`,name:`Photon`,kind:`channel`,tagline:`iMessage through Photon, with guided project and phone setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-dial`,name:`Dial`,kind:`channel`,tagline:`Give your agent a phone number for SMS, MMS, iMessage, and voice transcripts.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-agentphone`,name:`AgentPhone`,kind:`channel`,tagline:`SMS, MMS, iMessage, and voice conversations through AgentPhone.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-lark`,name:`Lark / Feishu`,kind:`channel`,tagline:`Lark and Feishu chats with native card streaming via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-beeper`,name:`Beeper`,kind:`channel`,tagline:`Matrix rooms and bridged messaging networks through Beeper.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-resend`,name:`Resend`,kind:`channel`,tagline:`Send and receive threaded email through Resend via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`agent-browser`,name:`agent-browser`,kind:`extension`,tagline:`Add browser automation tools backed by agent-browser to an eve agent.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`blitzreels`,name:`BlitzReels`,kind:`extension`,tagline:`Turn long videos into short clips, generate media, repair edits, and export.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`browserbase`,name:`Browserbase`,kind:`extension`,tagline:`Search, fetch, and automate the web with Browserbase and Stagehand.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`github-tools`,name:`GitHub Tools`,kind:`extension`,tagline:`Add scoped GitHub tools with Vercel Connect authentication and approval rules.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`jetty`,name:`Jetty`,kind:`extension`,tagline:`Grade agent turns, compare experiments, and store durable evaluation trajectories.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`kernel`,name:`KERNEL`,kind:`extension`,tagline:`Let your eve agent use the Internet with KERNEL browser infra, o11y, and stealth. Integrated natively with Vercel Connect and AI Gateway.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`upstash-agentkit`,name:`Upstash AgentKit`,kind:`extension`,tagline:`Add long-term memory, Redis Search, and durable chat history with Upstash Redis.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`supermemory`,name:`Supermemory`,kind:`memory`,tagline:`Give your agents long-term memory, user profiles, and SuperRAG across conversations and context.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`arcana`,name:`Kybernesis Arcana`,kind:`extension`,tagline:`Give your agent workspace-scoped long-term memory with recall, storage, and brain notes.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`hindsight`,name:`Hindsight`,kind:`extension`,tagline:`Recall relevant context before every turn and retain each exchange automatically.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`browser-use`,name:`Browser Use`,kind:`connection`,tagline:`Run managed browser automation tasks through Browser Use's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Browser Use: run browser automation tasks, inspect sessions, and manage browser profiles.`,mcp:{url:`https://api.browser-use.com/v3/mcp`}}},{slug:`vercel`,name:`Vercel`,kind:`connection`,tagline:`Manage Vercel projects, deployments, and logs through Vercel's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Vercel: manage projects and deployments, inspect logs, and search documentation.`,mcp:{url:`https://mcp.vercel.com`}}},{slug:`linear`,name:`Linear`,kind:`connection`,tagline:`Issues, projects, cycles, and comments via Linear's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Linear workspace: issues, projects, cycles, and comments.`,mcp:{url:`https://mcp.linear.app/mcp`}}},{slug:`notion`,name:`Notion`,kind:`connection`,tagline:`Search and edit Notion pages and databases over MCP or OpenAPI.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Notion workspace: search and edit pages and databases.`,mcp:{url:`https://mcp.notion.com/mcp`},openapi:{spec:`https://developers.notion.com/openapi.json`,baseUrl:`https://api.notion.com`,headers:{"Notion-Version":`2022-06-28`}}}},{slug:`datadog`,name:`Datadog`,kind:`connection`,tagline:`Query metrics, monitors, and logs through Datadog's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Datadog: query metrics, monitors, logs, and incidents.`,mcp:{url:`https://mcp.datadoghq.com/api/mcp`}}},{slug:`honeycomb`,name:`Honeycomb`,kind:`connection`,tagline:`Explore traces and run queries through Honeycomb's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Honeycomb: explore traces, run queries, and inspect datasets.`,mcp:{url:`https://mcp.honeycomb.io/mcp`}}},{slug:`agentcard`,name:`Agentcard`,kind:`connection`,tagline:`let agents buy online`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:"Agentcard: the agent's wallet. Shop and check out at real merchants (DoorDash, Good Eggs, flights) with the conversational `buy` tool (thread conversation_id on follow-ups), issue a single-use virtual card to pay at any checkout, let the user add their own card, and manage the cash that funds it: balance, top-ups, transactions, KYC, human support.",mcp:{url:`https://mcp.agentcard.sh/mcp`}}},{slug:`airtable`,name:`Airtable`,kind:`connection`,tagline:`Bases, tables, and records through Airtable's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Airtable: bases, tables, and records.`,mcp:{url:`https://mcp.airtable.com/mcp`}}},{slug:`bitly`,name:`Bitly`,kind:`connection`,tagline:`Shorten links, generate QR Codes, and track performance.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Bitly: shorten links, generate QR Codes, and track link performance.`,mcp:{url:`https://api-ssl.bitly.com/v4/mcp`}}},{slug:`brex`,name:`Brex`,kind:`connection`,tagline:`Expenses, cards, and cash through Brex's finance automation.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Brex: expenses, cards, budgets, and cash.`,mcp:{url:`https://api.brex.com/mcp`}}},{slug:`candid`,name:`Candid`,kind:`connection`,tagline:`Research nonprofits and funders using Candid's data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Candid: research nonprofits, funders, and grants.`,mcp:{url:`https://mcp.candid.org/mcp`}}},{slug:`clickhouse`,name:`ClickHouse`,kind:`connection`,tagline:`Query and explore your ClickHouse Cloud data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`ClickHouse Cloud: query and explore databases and tables.`,mcp:{url:`https://mcp.clickhouse.cloud/mcp`}}},{slug:`cloudinary`,name:`Cloudinary`,kind:`connection`,tagline:`Manage, transform, and deliver your images and videos.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Cloudinary: manage, transform, and deliver image and video assets.`,mcp:{url:`https://asset-management.mcp.cloudinary.com/sse`}}},{slug:`coda`,name:`Coda`,kind:`connection`,tagline:`Create, search, and update docs and tables.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Coda: create, search, and update docs and tables.`,mcp:{url:`https://coda.io/apis/mcp`}}},{slug:`context`,name:`context.dev`,kind:`connection`,tagline:`search, scrape, extract, and monitor live web data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`context.dev: search the live web, scrape and crawl sites, extract structured data, parse files, retrieve brand intelligence, monitor changes, and run batch jobs.`,mcp:{url:`https://mcp.context.dev/mcp`}}},{slug:`egnyte`,name:`Egnyte`,kind:`connection`,tagline:`Securely access and analyze Egnyte content.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Egnyte: search, access, and analyze governed content.`,mcp:{url:`https://mcp-server.egnyte.com/mcp`}}},{slug:`embat`,name:`Embat`,kind:`connection`,tagline:`Ask Embat about cash, debt, payments, and accounting.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Embat: cash, debt, payments, and accounting.`,mcp:{url:`https://tellme.embat.io/mcp`}}},{slug:`hugging-face`,name:`Hugging Face`,kind:`connection`,tagline:`Access the Hugging Face Hub and thousands of Gradio apps.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Hugging Face: models, datasets, Spaces, and Gradio apps on the Hub.`,mcp:{url:`https://huggingface.co/mcp?login&gradio=none`}}},{slug:`local-falcon`,name:`Local Falcon`,kind:`connection`,tagline:`AI visibility and local search intelligence.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Local Falcon: local search rankings and AI visibility reports.`,mcp:{url:`https://mcp.localfalcon.com`}}},{slug:`make`,name:`Make`,kind:`connection`,tagline:`Run Make scenarios and manage your Make account.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Make: run scenarios and manage automations.`,mcp:{url:`https://mcp.make.com`}}},{slug:`manufact`,name:`Manufact`,kind:`connection`,tagline:`Deploy and monitor MCP servers with Manufact.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Manufact: deploy and monitor MCP servers.`,mcp:{url:`https://mcp.manufact.com/mcp`}}},{slug:`mem0`,name:`Mem0`,kind:`connection`,tagline:`Persistent memory for AI agents and assistants.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Mem0: store and retrieve persistent agent memory.`,mcp:{url:`https://mcp.mem0.ai/mcp`}}},{slug:`miro`,name:`Miro`,kind:`connection`,tagline:`Access and create content on Miro boards.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Miro: read and create content on boards.`,mcp:{url:`https://mcp.miro.com/`}}},{slug:`mixpanel`,name:`Mixpanel`,kind:`connection`,tagline:`Analyze, query, and manage your Mixpanel data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Mixpanel: analyze, query, and manage analytics data.`,mcp:{url:`https://mcp.mixpanel.com/mcp`}}},{slug:`natural`,name:`Natural`,kind:`connection`,tagline:`Send, request, and manage payments with Natural.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Natural: agentic payments — send and request payments, check balances, and move funds.`,mcp:{url:`https://mcp.natural.com/mcp`}}},{slug:`netlify`,name:`Netlify`,kind:`connection`,tagline:`Create, deploy, manage, and secure websites on Netlify.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Netlify: create, deploy, manage, and secure sites.`,mcp:{url:`https://netlify-mcp.netlify.app/mcp`}}},{slug:`oreilly`,name:`O'Reilly`,kind:`connection`,tagline:`Discover O'Reilly's expert learning content.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`O'Reilly: search books, courses, and learning content.`,mcp:{url:`https://api.oreilly.com/api/content-discovery/v1/mcp/`}}},{slug:`planetscale`,name:`PlanetScale`,kind:`connection`,tagline:`Authenticated access to your PlanetScale Postgres and MySQL databases.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`PlanetScale: query Postgres and MySQL databases.`,mcp:{url:`https://mcp.pscale.dev/mcp/planetscale`}}},{slug:`posthog`,name:`PostHog`,kind:`connection`,tagline:`Query, analyze, and manage your PostHog insights.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`PostHog: insights, events, and feature flags.`,mcp:{url:`https://mcp.posthog.com/mcp`}}},{slug:`postman`,name:`Postman`,kind:`connection`,tagline:`Give API context to your coding agents with Postman.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Postman: APIs, collections, and workspaces.`,mcp:{url:`https://mcp.postman.com/minimal`}}},{slug:`razorpay`,name:`Razorpay`,kind:`connection`,tagline:`Razorpay payments, settlements, and dashboard data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Razorpay: payments, settlements, and dashboard data.`,mcp:{url:`https://mcp.razorpay.com/mcp`}}},{slug:`sentry`,name:`Sentry`,kind:`connection`,tagline:`Search, query, and debug errors intelligently.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Sentry: search, query, and debug errors and issues.`,mcp:{url:`https://mcp.sentry.dev/mcp`}}},{slug:`similarweb`,name:`Similarweb`,kind:`connection`,tagline:`Real-time web, mobile app, and market data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Similarweb: web traffic, app, and market intelligence data.`,mcp:{url:`https://mcp.similarweb.com`}}},{slug:`shopify`,name:`Shopify`,kind:`connection`,tagline:`Search products and manage carts and checkouts on a Shopify storefront.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Search products and build carts and checkouts on a Shopify storefront.`,mcp:{url:`https://{shop}.myshopify.com/api/ucp/mcp`}}},{slug:`stripe`,name:`Stripe`,kind:`connection`,tagline:`Payment processing and financial infrastructure tools.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Stripe: payments, customers, billing, and financial infrastructure.`,mcp:{url:`https://mcp.stripe.com`}}},{slug:`supabase`,name:`Supabase`,kind:`connection`,tagline:`Manage databases, authentication, and storage.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Supabase: databases, authentication, and storage.`,mcp:{url:`https://mcp.supabase.com/mcp`}}},{slug:`ticket-tailor`,name:`Ticket Tailor`,kind:`connection`,tagline:`Manage tickets, orders, and events with Ticket Tailor.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Ticket Tailor: events, tickets, and orders.`,mcp:{url:`https://mcp.tickettailor.ai/mcp`}}},{slug:`ticktick`,name:`TickTick`,kind:`connection`,tagline:`Search, create, and manage your tasks and habits in TickTick.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`TickTick: tasks, habits, and lists.`,mcp:{url:`https://mcp.ticktick.com`}}},{slug:`tinybird`,name:`Tinybird`,kind:`connection`,tagline:`Query pipes and data sources in your Tinybird Workspace.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Tinybird: query pipes and data sources, and run SQL. A token grants one Workspace, so add a connection per Workspace.`,mcp:{url:`https://mcp.tinybird.co`}}},{slug:`todoist`,name:`Todoist`,kind:`connection`,tagline:`Search, complete, and manage your tasks in Todoist.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Todoist: search, complete, and manage tasks.`,mcp:{url:`https://ai.todoist.net/mcp`}}},{slug:`webflow`,name:`Webflow`,kind:`connection`,tagline:`Manage Webflow CMS, pages, assets, and sites.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Webflow: CMS items, pages, assets, and sites.`,mcp:{url:`https://mcp.webflow.com/mcp`}}},{slug:`wix`,name:`Wix`,kind:`connection`,tagline:`Manage and build sites and apps on Wix.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Wix: manage and build sites and apps.`,mcp:{url:`https://mcp.wix.com/mcp`}}},{slug:`zapier`,name:`Zapier`,kind:`connection`,tagline:`Automate workflows across thousands of apps.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Zapier: run and manage automations across apps.`,mcp:{url:`https://mcp.zapier.com/api/v1/connect`}}},{slug:`zomato`,name:`Zomato`,kind:`connection`,tagline:`Online food ordering and delivery through Zomato.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Zomato: food ordering and delivery.`,mcp:{url:`https://mcp-server.zomato.com/mcp`}}},{slug:`braintrust`,name:`Braintrust`,kind:`instrumentation`,tagline:`Export AI SDK spans to Braintrust for tracing, evals, and monitoring.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`posthog-instrumentation`,name:`PostHog`,kind:`instrumentation`,tagline:`Send agent traces and generations to PostHog AI Observability.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`sentry-instrumentation`,name:`Sentry`,kind:`instrumentation`,tagline:`Send agent traces to Sentry's OTLP endpoint for tracing and debugging.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`datadog-instrumentation`,name:`Datadog`,kind:`instrumentation`,tagline:`Export agent traces to Datadog APM alongside the rest of your stack.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`honeycomb-instrumentation`,name:`Honeycomb`,kind:`instrumentation`,tagline:`Send OpenTelemetry traces to Honeycomb and query every agent turn.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`arize`,name:`Arize`,kind:`instrumentation`,tagline:`Export traces to Arize AX for LLM observability and evaluation.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`raindrop`,name:`Raindrop`,kind:`instrumentation`,tagline:`Send agent traces to Raindrop to detect and debug AI product issues.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`jaeger`,name:`Jaeger`,kind:`instrumentation`,tagline:`Trace your agent with a local or self-hosted Jaeger OTLP backend.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}}];new Map(INTEGRATIONS.map(e=>[e.slug,e]));function integrationsByKind(t){return INTEGRATIONS.filter(e=>e.kind===t)}function connectionEntries(){return integrationsByKind(`connection`)}function channelEntries(){return integrationsByKind(`channel`)}export{INTEGRATIONS,channelEntries,connectionEntries,connectionProtocols,integrationsByKind};
|
|
1
|
+
function connectionProtocols(e){return[e.mcp?`mcp`:null,e.openapi?`openapi`:null].filter(e=>e!==null)}const INTEGRATIONS=[{slug:`slack`,name:`Slack`,kind:`channel`,tagline:`Mention your agent in channels and DMs, with Connect-managed auth.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0}},{slug:`discord`,name:`Discord`,kind:`channel`,tagline:`Run your agent as a Discord bot across servers and threads.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`teams`,name:`Microsoft Teams`,kind:`channel`,tagline:`Bring your agent into Teams chats and channels.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`telegram`,name:`Telegram`,kind:`channel`,tagline:`Connect your agent to a Telegram bot for 1:1 and group chats.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`twilio`,name:`Twilio`,kind:`channel`,tagline:`Put your agent on a phone number: SMS and speech-transcribed calls.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`blooio`,name:`Blooio`,kind:`channel`,tagline:`Send and receive iMessage, RCS, and SMS through Blooio.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`github`,name:`GitHub`,kind:`channel`,tagline:`Drive your agent from issues, pull requests, and comments, with guided Connect setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`linear-agent`,name:`Linear Agent`,kind:`channel`,tagline:`Delegate Linear issues and comments through Agent Sessions, with guided Connect setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`eve`,name:`Web Chat`,kind:`channel`,tagline:`Embed a first-party web chat UI backed by your agent.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0}},{slug:`buzz`,name:`Buzz`,kind:`channel`,tagline:`Talk to your eve agent from Buzz through its ACP desktop harness.`,surfaces:{scaffoldable:!1,registry:!1,gallery:!0}},{slug:`chat-sdk-gchat`,name:`Google Chat`,kind:`channel`,tagline:`Google Chat spaces and DMs via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-whatsapp`,name:`WhatsApp`,kind:`channel`,tagline:`Customer messaging through WhatsApp Business Cloud via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-x`,name:`X`,kind:`channel`,tagline:`Public mentions and DMs on X via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-messenger`,name:`Messenger`,kind:`channel`,tagline:`Facebook Messenger bots with templates, buttons, and reactions via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-zernio`,name:`Zernio`,kind:`channel`,tagline:`Reach seven social and messaging platforms through one Zernio integration.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-velt`,name:`Velt`,kind:`channel`,tagline:`Add agents to anchored comments across documents, canvases, PDFs, and video.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-sendblue`,name:`Sendblue`,kind:`channel`,tagline:`Send and receive iMessage, SMS, and RCS through Sendblue.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-novu`,name:`Novu`,kind:`channel`,tagline:`Reach Slack, Teams, WhatsApp, Telegram, and email through Novu.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-liveblocks`,name:`Liveblocks`,kind:`channel`,tagline:`Bring your agent into Liveblocks comment threads, mentions, and reactions.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`linq`,name:`Linq`,kind:`channel`,tagline:`iMessage and SMS conversations through Linq, with guided Connect or portable setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-kapso`,name:`Kapso`,kind:`channel`,tagline:`Managed WhatsApp conversations, media, buttons, and history through Kapso.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`photon`,name:`Photon`,kind:`channel`,tagline:`iMessage through Photon, with guided project and phone setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-dial`,name:`Dial`,kind:`channel`,tagline:`Give your agent a phone number for SMS, MMS, iMessage, and voice transcripts.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-agentphone`,name:`AgentPhone`,kind:`channel`,tagline:`SMS, MMS, iMessage, and voice conversations through AgentPhone.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-lark`,name:`Lark / Feishu`,kind:`channel`,tagline:`Lark and Feishu chats with native card streaming via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-beeper`,name:`Beeper`,kind:`channel`,tagline:`Matrix rooms and bridged messaging networks through Beeper.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-resend`,name:`Resend`,kind:`channel`,tagline:`Send and receive threaded email through Resend via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`agent-browser`,name:`agent-browser`,kind:`extension`,tagline:`Add browser automation tools backed by agent-browser to an eve agent.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`blitzreels`,name:`BlitzReels`,kind:`extension`,tagline:`Turn long videos into short clips, generate media, repair edits, and export.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`browserbase`,name:`Browserbase`,kind:`extension`,tagline:`Search, fetch, and automate the web with Browserbase and Stagehand.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`github-tools`,name:`GitHub Tools`,kind:`extension`,tagline:`Add scoped GitHub tools with Vercel Connect authentication and approval rules.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`jetty`,name:`Jetty`,kind:`extension`,tagline:`Grade agent turns, compare experiments, and store durable evaluation trajectories.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`kernel`,name:`KERNEL`,kind:`extension`,tagline:`Let your eve agent use the Internet with KERNEL browser infra, o11y, and stealth. Integrated natively with Vercel Connect and AI Gateway.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`upstash-agentkit`,name:`Upstash AgentKit`,kind:`extension`,tagline:`Add long-term memory, Redis Search, and durable chat history with Upstash Redis.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`supermemory`,name:`Supermemory`,kind:`memory`,tagline:`Give your agents long-term memory, user profiles, and SuperRAG across conversations and context.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`arcana`,name:`Kybernesis Arcana`,kind:`extension`,tagline:`Give your agent workspace-scoped long-term memory with recall, storage, and brain notes.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`hindsight`,name:`Hindsight`,kind:`extension`,tagline:`Recall relevant context before every turn and retain each exchange automatically.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`browser-use`,name:`Browser Use`,kind:`connection`,tagline:`Run managed browser automation tasks through Browser Use's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Browser Use: run browser automation tasks, inspect sessions, and manage browser profiles.`,mcp:{url:`https://api.browser-use.com/v3/mcp`}}},{slug:`vercel`,name:`Vercel`,kind:`connection`,tagline:`Manage Vercel projects, deployments, and logs through Vercel's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Vercel: manage projects and deployments, inspect logs, and search documentation.`,mcp:{url:`https://mcp.vercel.com`}}},{slug:`linear`,name:`Linear`,kind:`connection`,tagline:`Issues, projects, cycles, and comments via Linear's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Linear workspace: issues, projects, cycles, and comments.`,mcp:{url:`https://mcp.linear.app/mcp`}}},{slug:`notion`,name:`Notion`,kind:`connection`,tagline:`Search and edit Notion pages and databases over MCP or OpenAPI.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Notion workspace: search and edit pages and databases.`,mcp:{url:`https://mcp.notion.com/mcp`},openapi:{spec:`https://developers.notion.com/openapi.json`,baseUrl:`https://api.notion.com`,headers:{"Notion-Version":`2022-06-28`}}}},{slug:`datadog`,name:`Datadog`,kind:`connection`,tagline:`Query metrics, monitors, and logs through Datadog's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Datadog: query metrics, monitors, logs, and incidents.`,mcp:{url:`https://mcp.datadoghq.com/api/mcp`}}},{slug:`honeycomb`,name:`Honeycomb`,kind:`connection`,tagline:`Explore traces and run queries through Honeycomb's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Honeycomb: explore traces, run queries, and inspect datasets.`,mcp:{url:`https://mcp.honeycomb.io/mcp`}}},{slug:`agentcard`,name:`Agentcard`,kind:`connection`,tagline:`let agents buy online`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:"Agentcard: the agent's wallet. Shop and check out at real merchants (DoorDash, Good Eggs, flights) with the conversational `buy` tool (thread conversation_id on follow-ups), issue a single-use virtual card to pay at any checkout, let the user add their own card, and manage the cash that funds it: balance, top-ups, transactions, KYC, human support.",mcp:{url:`https://mcp.agentcard.sh/mcp`}}},{slug:`airtable`,name:`Airtable`,kind:`connection`,tagline:`Bases, tables, and records through Airtable's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Airtable: bases, tables, and records.`,mcp:{url:`https://mcp.airtable.com/mcp`}}},{slug:`bitly`,name:`Bitly`,kind:`connection`,tagline:`Shorten links, generate QR Codes, and track performance.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Bitly: shorten links, generate QR Codes, and track link performance.`,mcp:{url:`https://api-ssl.bitly.com/v4/mcp`}}},{slug:`brex`,name:`Brex`,kind:`connection`,tagline:`Expenses, cards, and cash through Brex's finance automation.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Brex: expenses, cards, budgets, and cash.`,mcp:{url:`https://api.brex.com/mcp`}}},{slug:`candid`,name:`Candid`,kind:`connection`,tagline:`Research nonprofits and funders using Candid's data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Candid: research nonprofits, funders, and grants.`,mcp:{url:`https://mcp.candid.org/mcp`}}},{slug:`clickhouse`,name:`ClickHouse`,kind:`connection`,tagline:`Query and explore your ClickHouse Cloud data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`ClickHouse Cloud: query and explore databases and tables.`,mcp:{url:`https://mcp.clickhouse.cloud/mcp`}}},{slug:`cloudinary`,name:`Cloudinary`,kind:`connection`,tagline:`Manage, transform, and deliver your images and videos.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Cloudinary: manage, transform, and deliver image and video assets.`,mcp:{url:`https://asset-management.mcp.cloudinary.com/sse`}}},{slug:`coda`,name:`Coda`,kind:`connection`,tagline:`Create, search, and update docs and tables.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Coda: create, search, and update docs and tables.`,mcp:{url:`https://coda.io/apis/mcp`}}},{slug:`context`,name:`context.dev`,kind:`connection`,tagline:`search, scrape, extract, and monitor live web data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`context.dev: search the live web, scrape and crawl sites, extract structured data, parse files, retrieve brand intelligence, monitor changes, and run batch jobs.`,mcp:{url:`https://mcp.context.dev/mcp`}}},{slug:`egnyte`,name:`Egnyte`,kind:`connection`,tagline:`Securely access and analyze Egnyte content.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Egnyte: search, access, and analyze governed content.`,mcp:{url:`https://mcp-server.egnyte.com/mcp`}}},{slug:`embat`,name:`Embat`,kind:`connection`,tagline:`Ask Embat about cash, debt, payments, and accounting.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Embat: cash, debt, payments, and accounting.`,mcp:{url:`https://tellme.embat.io/mcp`}}},{slug:`hugging-face`,name:`Hugging Face`,kind:`connection`,tagline:`Access the Hugging Face Hub and thousands of Gradio apps.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Hugging Face: models, datasets, Spaces, and Gradio apps on the Hub.`,mcp:{url:`https://huggingface.co/mcp?login&gradio=none`}}},{slug:`local-falcon`,name:`Local Falcon`,kind:`connection`,tagline:`AI visibility and local search intelligence.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Local Falcon: local search rankings and AI visibility reports.`,mcp:{url:`https://mcp.localfalcon.com`}}},{slug:`make`,name:`Make`,kind:`connection`,tagline:`Run Make scenarios and manage your Make account.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Make: run scenarios and manage automations.`,mcp:{url:`https://mcp.make.com`}}},{slug:`manufact`,name:`Manufact`,kind:`connection`,tagline:`Deploy and monitor MCP servers with Manufact.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Manufact: deploy and monitor MCP servers.`,mcp:{url:`https://mcp.manufact.com/mcp`}}},{slug:`mem0`,name:`Mem0`,kind:`connection`,tagline:`Persistent memory for AI agents and assistants.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Mem0: store and retrieve persistent agent memory.`,mcp:{url:`https://mcp.mem0.ai/mcp`}}},{slug:`miro`,name:`Miro`,kind:`connection`,tagline:`Access and create content on Miro boards.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Miro: read and create content on boards.`,mcp:{url:`https://mcp.miro.com/`}}},{slug:`mixpanel`,name:`Mixpanel`,kind:`connection`,tagline:`Analyze, query, and manage your Mixpanel data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Mixpanel: analyze, query, and manage analytics data.`,mcp:{url:`https://mcp.mixpanel.com/mcp`}}},{slug:`natural`,name:`Natural`,kind:`connection`,tagline:`Send, request, and manage payments with Natural.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Natural: agentic payments — send and request payments, check balances, and move funds.`,mcp:{url:`https://mcp.natural.com/mcp`}}},{slug:`neon`,name:`Neon`,kind:`connection`,tagline:`Manage Neon projects, run queries, and make schema changes.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Neon: manage projects, run queries, and make schema changes.`,mcp:{url:`https://mcp.neon.tech/mcp`}}},{slug:`netlify`,name:`Netlify`,kind:`connection`,tagline:`Create, deploy, manage, and secure websites on Netlify.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Netlify: create, deploy, manage, and secure sites.`,mcp:{url:`https://netlify-mcp.netlify.app/mcp`}}},{slug:`oreilly`,name:`O'Reilly`,kind:`connection`,tagline:`Discover O'Reilly's expert learning content.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`O'Reilly: search books, courses, and learning content.`,mcp:{url:`https://api.oreilly.com/api/content-discovery/v1/mcp/`}}},{slug:`planetscale`,name:`PlanetScale`,kind:`connection`,tagline:`Authenticated access to your PlanetScale Postgres and MySQL databases.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`PlanetScale: query Postgres and MySQL databases.`,mcp:{url:`https://mcp.pscale.dev/mcp/planetscale`}}},{slug:`posthog`,name:`PostHog`,kind:`connection`,tagline:`Query, analyze, and manage your PostHog insights.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`PostHog: insights, events, and feature flags.`,mcp:{url:`https://mcp.posthog.com/mcp`}}},{slug:`postman`,name:`Postman`,kind:`connection`,tagline:`Give API context to your coding agents with Postman.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Postman: APIs, collections, and workspaces.`,mcp:{url:`https://mcp.postman.com/minimal`}}},{slug:`razorpay`,name:`Razorpay`,kind:`connection`,tagline:`Razorpay payments, settlements, and dashboard data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Razorpay: payments, settlements, and dashboard data.`,mcp:{url:`https://mcp.razorpay.com/mcp`}}},{slug:`sentry`,name:`Sentry`,kind:`connection`,tagline:`Search, query, and debug errors intelligently.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Sentry: search, query, and debug errors and issues.`,mcp:{url:`https://mcp.sentry.dev/mcp`}}},{slug:`similarweb`,name:`Similarweb`,kind:`connection`,tagline:`Real-time web, mobile app, and market data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Similarweb: web traffic, app, and market intelligence data.`,mcp:{url:`https://mcp.similarweb.com`}}},{slug:`shopify`,name:`Shopify`,kind:`connection`,tagline:`Search products and manage carts and checkouts on a Shopify storefront.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Search products and build carts and checkouts on a Shopify storefront.`,mcp:{url:`https://{shop}.myshopify.com/api/ucp/mcp`}}},{slug:`stripe`,name:`Stripe`,kind:`connection`,tagline:`Payment processing and financial infrastructure tools.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Stripe: payments, customers, billing, and financial infrastructure.`,mcp:{url:`https://mcp.stripe.com`}}},{slug:`supabase`,name:`Supabase`,kind:`connection`,tagline:`Manage databases, authentication, and storage.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Supabase: databases, authentication, and storage.`,mcp:{url:`https://mcp.supabase.com/mcp`}}},{slug:`ticket-tailor`,name:`Ticket Tailor`,kind:`connection`,tagline:`Manage tickets, orders, and events with Ticket Tailor.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Ticket Tailor: events, tickets, and orders.`,mcp:{url:`https://mcp.tickettailor.ai/mcp`}}},{slug:`ticktick`,name:`TickTick`,kind:`connection`,tagline:`Search, create, and manage your tasks and habits in TickTick.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`TickTick: tasks, habits, and lists.`,mcp:{url:`https://mcp.ticktick.com`}}},{slug:`tinybird`,name:`Tinybird`,kind:`connection`,tagline:`Query pipes and data sources in your Tinybird Workspace.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Tinybird: query pipes and data sources, and run SQL. A token grants one Workspace, so add a connection per Workspace.`,mcp:{url:`https://mcp.tinybird.co`}}},{slug:`todoist`,name:`Todoist`,kind:`connection`,tagline:`Search, complete, and manage your tasks in Todoist.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Todoist: search, complete, and manage tasks.`,mcp:{url:`https://ai.todoist.net/mcp`}}},{slug:`webflow`,name:`Webflow`,kind:`connection`,tagline:`Manage Webflow CMS, pages, assets, and sites.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Webflow: CMS items, pages, assets, and sites.`,mcp:{url:`https://mcp.webflow.com/mcp`}}},{slug:`wix`,name:`Wix`,kind:`connection`,tagline:`Manage and build sites and apps on Wix.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Wix: manage and build sites and apps.`,mcp:{url:`https://mcp.wix.com/mcp`}}},{slug:`zapier`,name:`Zapier`,kind:`connection`,tagline:`Automate workflows across thousands of apps.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Zapier: run and manage automations across apps.`,mcp:{url:`https://mcp.zapier.com/api/v1/connect`}}},{slug:`zomato`,name:`Zomato`,kind:`connection`,tagline:`Online food ordering and delivery through Zomato.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Zomato: food ordering and delivery.`,mcp:{url:`https://mcp-server.zomato.com/mcp`}}},{slug:`braintrust`,name:`Braintrust`,kind:`instrumentation`,tagline:`Export AI SDK spans to Braintrust for tracing, evals, and monitoring.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`posthog-instrumentation`,name:`PostHog`,kind:`instrumentation`,tagline:`Send agent traces and generations to PostHog AI Observability.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`sentry-instrumentation`,name:`Sentry`,kind:`instrumentation`,tagline:`Send agent traces to Sentry's OTLP endpoint for tracing and debugging.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`datadog-instrumentation`,name:`Datadog`,kind:`instrumentation`,tagline:`Export agent traces to Datadog APM alongside the rest of your stack.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`honeycomb-instrumentation`,name:`Honeycomb`,kind:`instrumentation`,tagline:`Send OpenTelemetry traces to Honeycomb and query every agent turn.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`arize`,name:`Arize`,kind:`instrumentation`,tagline:`Export traces to Arize AX for LLM observability and evaluation.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`raindrop`,name:`Raindrop`,kind:`instrumentation`,tagline:`Send agent traces to Raindrop to detect and debug AI product issues.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`jaeger`,name:`Jaeger`,kind:`instrumentation`,tagline:`Trace your agent with a local or self-hosted Jaeger OTLP backend.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}}];new Map(INTEGRATIONS.map(e=>[e.slug,e]));function integrationsByKind(t){return INTEGRATIONS.filter(e=>e.kind===t)}function connectionEntries(){return integrationsByKind(`connection`)}function channelEntries(){return integrationsByKind(`channel`)}export{INTEGRATIONS,channelEntries,connectionEntries,connectionProtocols,integrationsByKind};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ForwardedTraceAssertion } from "#shared/forwarded-trace-policy.js";
|
|
2
|
+
export type ForwardedTraceBaggage = "absent" | "malformed" | ForwardedTraceAssertion;
|
|
3
|
+
/** Reads Eve's audience member without interpreting or rejecting unrelated baggage. */
|
|
4
|
+
export declare function readForwardedAudienceBaggage(value: string | null): ForwardedTraceBaggage;
|
|
5
|
+
/** Replaces any authored Eve audience member while preserving unrelated baggage entries. */
|
|
6
|
+
export declare function writeForwardedAudienceBaggage(value: string | undefined, assertion: ForwardedTraceAssertion | undefined): string | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{formatTraceContentCeiling}from"#shared/forwarded-trace-policy.js";const EVE_AUDIENCE_KEY=`eve.audience`,CEILING_PROPERTY_KEY=`ceiling`;function readForwardedAudienceBaggage(e){if(e===null)return`absent`;let t=baggageMembers(e).filter(isEveAudienceMember);return t.length===0?`absent`:t.length===1?parseEveAudienceMember(t[0]):`malformed`}function writeForwardedAudienceBaggage(r,i){let a=baggageMembers(r??``).filter(e=>!isEveAudienceMember(e));return i!==void 0&&a.push(`${EVE_AUDIENCE_KEY}=${i.originAudience};${CEILING_PROPERTY_KEY}=${formatTraceContentCeiling(i.ceiling)}`),a.length>0?a.join(`,`):void 0}function baggageMembers(e){return e.split(`,`).map(trimOws).filter(Boolean)}function parseEveAudienceMember(e){let r=e.split(`;`);if(r.length!==2)return`malformed`;let i=parsePair(r[0]);if(i===void 0||i.key!==EVE_AUDIENCE_KEY)return`malformed`;let a=i.value;if(a!==`public`&&a!==`private`&&a!==`unknown`)return`malformed`;let o=parsePair(r[1]);if(o===void 0||o.key!==CEILING_PROPERTY_KEY)return`malformed`;let s=parseCeiling(o.value);return s===void 0?`malformed`:{ceiling:s,originAudience:a}}function parsePair(e){let t=e.indexOf(`=`);if(t<=0||e.indexOf(`=`,t+1)!==-1)return;let n=trimOws(e.slice(0,t)),r=trimOws(e.slice(t+1));if(!(n.length===0||r.length===0)&&n===e.slice(0,t).trim()&&r===e.slice(t+1).trim())return{key:n,value:r}}function parseCeiling(e){let t=/^i([01])o([01])$/u.exec(e);return t===null?void 0:{recordInputs:t[1]===`1`,recordOutputs:t[2]===`1`}}function trimOws(e){return e.replace(/^[\t ]+|[\t ]+$/gu,``)}function baggageKey(e){let t=e.split(`;`,1)[0],n=t.indexOf(`=`);return n>0?t.slice(0,n).trim():void 0}function isEveAudienceMember(e){let n=e.split(`;`,1)[0];return(baggageKey(e)??n.trim())===EVE_AUDIENCE_KEY}export{readForwardedAudienceBaggage,writeForwardedAudienceBaggage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{evaluateFilePart,formatUploadPolicyViolation,isUploadsDisabled}from"#public/channels/upload-policy.js";import{resolveSlackBotToken}from"#public/channels/slack/api.js";const log=createLogger(`slack.attachments`);function collectSlackFileParts(e,r){let i=[];for(let
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{evaluateFilePart,formatUploadPolicyViolation,isUploadsDisabled}from"#public/channels/upload-policy.js";import{EveAttachmentError}from"#internal/attachments/errors.js";import{resolveSlackBotToken}from"#public/channels/slack/api.js";const log=createLogger(`slack.attachments`);function collectSlackFileParts(e,r){let i=[];for(let a of e??[]){let e=toSlackFilePart(a,i.length);if(e===null)continue;let s=evaluateFilePart(e,r);if(s!==null){log.warn(`dropped attachment — ${formatUploadPolicyViolation(s)}`,{name:a.name});continue}i.push(e)}return i}function toSlackFilePart(e,t){return e.type===`audio`||e.type===`video`?null:e.url?{type:`file`,mediaType:e.mimeType??`application/octet-stream`,filename:e.name??`attachment-${t}`,data:new URL(e.url)}:(log.warn(`dropped attachment — no url available`,{name:e.name}),null)}async function collectInboundFileParts(e){let t=collectSlackFileParts(e.mention.attachments,e.policy);if(t.length>0)return t;if(isUploadsDisabled(e.policy))return[];if(e.thread.recentMessages.length===0)try{await e.thread.refresh()}catch(e){return log.warn(`slack thread refresh failed for attachment collection`,{error:e}),[]}let n=e.thread.recentMessages;for(let t=n.length-1;t>=0;--t){let r=n[t];if(!r||r.isMe)continue;let i=r.raw,a=collectSlackFileParts(extractAttachmentsFromRaw(i?.files),e.policy);return a.length>0?a:[]}return[]}function extractAttachmentsFromRaw(e){return Array.isArray(e)?e.map(e=>{let t=typeof e.mimetype==`string`?e.mimetype:void 0;return{id:typeof e.id==`string`?e.id:``,type:inferAttachmentType(t),url:typeof e.url_private==`string`?e.url_private:void 0,name:typeof e.name==`string`?e.name:void 0,mimeType:t,size:typeof e.size==`number`?e.size:void 0}}):[]}function inferAttachmentType(e){return e===void 0?`file`:e.startsWith(`image/`)?`image`:e.startsWith(`video/`)?`video`:e.startsWith(`audio/`)?`audio`:`file`}function buildSlackTurnMessage(e,t){return t.length===0?e:e.trim().length===0?[...t]:[{type:`text`,text:e},...t]}function createSlackFetchFile(e){return async(t,n)=>{if(!isSlackFileUrl(t))return null;let r=n?.state.installationTeamId,o=await resolveSlackBotToken(e.botToken,{teamId:typeof r==`string`?r:void 0}),s=await fetch(t,{headers:{authorization:`Bearer ${o}`}});if(!s.ok)throw new EveAttachmentError({adapterKind:`slack`,kind:`resolver-threw`,message:`Slack file fetch returned HTTP ${s.status}.`});let c=s.headers.get(`content-type`)??void 0;if(c?.split(`;`,1)[0]?.trim().toLowerCase()===`text/html`)throw new EveAttachmentError({adapterKind:`slack`,kind:`resolver-threw`,message:`Slack returned an HTML sign-in page instead of file bytes. The bot token may be missing the files:read scope. Add the scope, reinstall the Slack app, and retry.`});return{bytes:Buffer.from(await s.arrayBuffer()),mediaType:c}}}function isSlackFileUrl(e){let t=URL.parse(e);return t?.protocol===`https:`?t.hostname===`files.slack.com`||(t.hostname===`enterprise.slack.com`||t.hostname.endsWith(`.enterprise.slack.com`))&&t.pathname.startsWith(`/files/`):!1}export{buildSlackTurnMessage,collectInboundFileParts,collectSlackFileParts,createSlackFetchFile};
|
|
@@ -14,7 +14,7 @@ import { type SlackSessionOperations } from "#public/channels/slack/session-oper
|
|
|
14
14
|
import { type UploadPolicyInput } from "#public/channels/upload-policy.js";
|
|
15
15
|
import { type SlackWebhookVerifier } from "#public/channels/slack/verify.js";
|
|
16
16
|
import { type Channel } from "#public/definitions/channel.js";
|
|
17
|
-
import type
|
|
17
|
+
import { type ChannelAudience } from "#shared/channel-audience.js";
|
|
18
18
|
export type { SlackRespondOptions, SlackSendOptions, SlackSessionOperations, } from "#public/channels/slack/session-operations.js";
|
|
19
19
|
type EventData<T extends UnstampedMessageStreamEvent["type"]> = Extract<UnstampedMessageStreamEvent, {
|
|
20
20
|
type: T;
|
|
@@ -184,6 +184,12 @@ export interface SlackChannelCredentials {
|
|
|
184
184
|
export interface SlackReceiveTarget {
|
|
185
185
|
readonly channelId: string;
|
|
186
186
|
readonly threadTs?: string;
|
|
187
|
+
/**
|
|
188
|
+
* Optional audience for proactive receives. Omit to leave `unknown`.
|
|
189
|
+
* Pass when the caller already knows channel visibility, for example a
|
|
190
|
+
* webhook or schedule that classified the Slack destination before handoff.
|
|
191
|
+
*/
|
|
192
|
+
readonly audience?: ChannelAudience;
|
|
187
193
|
/** Slack workspace whose app installation supplies credentials for this send. */
|
|
188
194
|
readonly installationTeamId?: string;
|
|
189
195
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{markEventHandled}from"./utils.js";import{createLogger,logError}from"#internal/logging.js";import{defaultDeliverResult}from"#channel/adapter.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{mergeUploadPolicy}from"#public/channels/upload-policy.js";import{buildSlackBinding,buildSlackWorkspaceHandle,slackContinuationToken}from"#public/channels/slack/api.js";import{buildSlackAuthContext,slackUserIdFromAuthContext}from"#public/channels/slack/auth.js";import{defaultEvents,defaultInputRequestedHandler,defaultOnAppMention,defaultOnDirectMessage}from"#public/channels/slack/defaults.js";import{loadThreadContextMessages}from"#public/channels/slack/thread.js";import{parseSlackWebhookBody}from"#compiled/@chat-adapter/slack/webhook.js";import{bindSlackSessionOperations}from"#public/channels/slack/session-operations.js";import{buildSlackTurnMessage,collectInboundFileParts,createSlackFetchFile}from"#public/channels/slack/attachments.js";import{parseMessageEvent,parseSlackEventEnvelope,slackEventBotUserId,slackEventInstallationTeamId,slackEventReceivingBotUserId,slackMessageFromWebhookPayload}from"#public/channels/slack/inbound.js";import{formatSlackInboundMessage,formatSlackThreadContext}from"#public/channels/slack/model-context.js";import{isPrivateSlackConversation}from"#public/channels/slack/privacy.js";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#public/channels/slack/constants.js";import{handleInteractionPost}from"#public/channels/slack/interactions.js";import{verifySlackRequest as verifySlackRequest$1}from"#public/channels/slack/verify.js";const log=createLogger(`slack.channel`);function rebuildSlackContext(e,t,n){let{thread:r,slack:i}=buildSlackBinding({botToken:n?.botToken,channelId:e.channelId??``,threadTs:e.threadTs??``,installationTeamId:e.installationTeamId??void 0,teamId:e.teamId??void 0,onThreadTsChanged(n){e.threadTs=n,e.channelId&&t.continuation?.rekey(slackContinuationToken(e.channelId,n))}});return{thread:r,slack:i,state:e}}function slackChannel(e={}){let t=mergeUploadPolicy(e.uploadPolicy),n=createSlackFetchFile({botToken:e.credentials?.botToken}),s=e.onInputResponse??defaultOnInputResponse,c=e.events?.[`authorization.required`],l=e.events?.[`approval.candidate`]??defaultEvents[`approval.candidate`],u=e.events?.[`turn.started`]??defaultEvents[`turn.started`],m={...defaultEvents,...e.events,async"approval.candidate"(e,t,n){let r=t.state.approvalResponderUsers?.[e.responderPrincipalId];if(e.outcome===`pending`&&r!==void 0&&(t.state.pendingApprovalCandidateUsers={...t.state.pendingApprovalCandidateUsers,[e.candidateId]:r}),await l(e,t,n),e.outcome!==`pending`){let n={...t.state.pendingApprovalCandidateUsers};delete n[e.candidateId],t.state.pendingApprovalCandidateUsers=n}},async"turn.started"(e,t,n){let r=slackUserIdFromAuthContext(n.session.auth.current);r!==void 0&&(t.state.triggeringUserId=r),await u(e,t,n)},"input.requested":e.events?.[`input.requested`]??defaultInputRequestedHandler(),"authorization.required":c===void 0?defaultEvents[`authorization.required`]:constrainAuthorizationRequired(c)},h=new Set;return defineChannel({kindHint:`slack`,turnPolicy:e.turnPolicy,state:{audience:`unknown`,channelId:null,threadTs:null,teamId:null,installationTeamId:null,triggeringUserId:null,pendingToolCallMessage:null,lastReasoningTypingAtMs:null,lastReasoningTypingStatus:null,pendingAuthMessageTs:{},pendingApprovalCards:{},pendingApprovalCandidateUsers:{},approvalResponderUsers:{}},fetchFile:n,metadata(e){return{audience:e.audience??`unknown`,channelId:e.channelId,teamId:e.teamId,threadTs:e.threadTs,triggeringUserId:e.triggeringUserId??null}},context(t,n){return rebuildSlackContext(t,n,e.credentials)},deliver(e,t){let n=e.pendingApprovalCards;typeof n==`object`&&n&&(t.state.pendingApprovalCards={...t.state.pendingApprovalCards,...n});let i=e.state?.approvalResponderUsers;return typeof i==`object`&&i&&(t.state.approvalResponderUsers={...t.state.approvalResponderUsers,...i}),defaultDeliverResult(e)},routes:[POST(e.route??SLACK_CHANNEL_DEFAULT_ROUTE,async(n,r)=>{let{waitUntil:i}=r,{from:a,resolveSession:o}=r,c=await verifyInbound(n,e.credentials);return c===null?new Response(`unauthorized`,{status:401}):shouldDropSlackHttpTimeoutRetry(n.headers)?new Response(`ok`):(n.headers.get(`content-type`)??``).includes(`application/x-www-form-urlencoded`)?handleInteractionPost(c,{from:a,resolveSession:o,waitUntil:i},{config:e,onInputResponse:s}):handleEventPost({body:c,from:a,resolveSession:o,waitUntil:i,config:e,uploadPolicy:t,handledEvents:h,headers:n.headers})})],receive(t,{from:n}){return receiveOnSlack(t,{from:n,credentials:e.credentials})},events:m})}function defaultOnInputResponse(e){return{auth:e.defaultAuth}}async function receiveOnSlack(e,t){let n=e.target,r=n.channelId;if(!r||typeof r!=`string`)throw Error(`slackChannel().receive requires target.channelId.`);let i=typeof n.threadTs==`string`?n.threadTs:``,a=typeof n.installationTeamId==`string`?n.installationTeamId:t.installationTeamId,o=n.initialMessage;if(o&&i.length>0)throw Error("slackChannel().receive: `threadTs` and `initialMessage` are mutually exclusive.");let c=i;if(o){let{thread:e}=buildSlackBinding({botToken:t.credentials?.botToken,channelId:r,threadTs:``,installationTeamId:a,teamId:t.teamId}),n={card:o.card};o.fallbackText!==void 0&&(n.fallbackText=o.fallbackText),c=(await e.post(n)).id}let u=c||crypto.randomUUID();return t.from(slackContinuationToken(r,u)).send(e.message,{auth:e.auth,state:{channelId:r,installationTeamId:a??null,threadTs:c||null,teamId:t.teamId??null,triggeringUserId:t.triggeringUserId??null},title:e.title})}function constrainAuthorizationRequired(e){return(t,n,r)=>e(t,{postEphemeral:(e,t)=>n.thread.postEphemeral(e,t),postDirectMessage:(e,t)=>n.thread.postDirectMessage(e,t),state:n.state},r)}function shouldDropSlackHttpTimeoutRetry(e){return Number(e.get(`x-slack-retry-num`)??`0`)>=1&&e.get(`x-slack-retry-reason`)===`http_timeout`}async function handleEventPost(t){let{config:n}=t,r,i;try{r=parseSlackWebhookBody(t.body,{headers:t.headers}),i=parseSlackEventEnvelope(t.body)}catch(e){return log.warn(`inbound webhook body is not valid JSON`,{error:e}),new Response(`ok`)}if(r.kind===`url_verification`)return new Response(r.challenge,{status:200,headers:{"content-type":`text/plain`}});if(i===null)return new Response(`ok`);let a=typeof i.api_app_id==`string`?i.api_app_id:void 0,o=slackEventBotUserId(i),s=slackEventReceivingBotUserId(i),c=slackEventInstallationTeamId(i),dispatch=null,l=null;if(r.kind===`app_mention`||r.kind===`direct_message`){let e=r.kind,i=slackMessageFromWebhookPayload(r);if(i!==null&&!isSelfAuthoredSlackMessage({appId:a,botUserId:o},i)){let dispatchMessageWith=r=>()=>dispatchSlackMessage({appId:a,botUserId:o,receivingBotUserId:s,from:t.from,resolveSession:t.resolveSession,credentials:n.credentials,handler:r,installationTeamId:c,kind:e,message:i,threadContext:n.threadContext,uploadPolicy:t.uploadPolicy}),r=(e===`app_mention`?n.onAppMention:n.onDirectMessage)??n.onMessage;r===void 0?l=dispatchMessageWith(e===`app_mention`?defaultOnAppMention:defaultOnDirectMessage):dispatch=()=>dispatchSlackMessage({appId:a,botUserId:o,receivingBotUserId:s,from:t.from,resolveSession:t.resolveSession,credentials:n.credentials,handler:r,installationTeamId:c,kind:e,message:i,threadContext:n.threadContext,uploadPolicy:t.uploadPolicy})}}if(dispatch===null&&n.onMessage!==void 0){let e=parseMessageEvent(i);e!==null&&!isSelfAuthoredSlackMessage({appId:a,botUserId:o},e)&&(o===void 0||!e.text.includes(`<@${o}`))&&(dispatch=()=>dispatchSlackMessage({appId:a,botUserId:o,receivingBotUserId:s,from:t.from,resolveSession:t.resolveSession,credentials:n.credentials,handler:n.onMessage,installationTeamId:c,kind:`channel_message`,message:e,threadContext:n.threadContext,uploadPolicy:t.uploadPolicy}))}let u=n.onEvent;if(dispatch===null&&u!==void 0&&(dispatch=()=>dispatchSlackEvent({from:t.from,resolveSession:t.resolveSession,credentials:n.credentials,envelope:i,handler:u,installationTeamId:c})),dispatch??=l,dispatch===null)return new Response(`ok`);let d=i.event_id;if(d){if(t.handledEvents.has(d))return log.warn(`received a duplicate event`,{event_id:d,event_time:i.event_time,retry_num:r.retry?.num??`(null)`,retry_reason:r.retry?.reason??`(null)`}),new Response(`ok`);markEventHandled(d,t.handledEvents)}return t.waitUntil(dispatch()),new Response(`ok`)}function isSelfAuthoredSlackMessage(e,t){return e.botUserId!==void 0&&t.author?.userId===e.botUserId||e.appId!==void 0&&t.raw.app_id===e.appId}async function dispatchSlackMessage(e){let t=slackContinuationToken(e.message.channelId,e.message.threadTs),{thread:r,slack:i}=buildSlackBinding({appId:e.appId,botToken:e.credentials?.botToken,botUserId:e.botUserId,channelId:e.message.channelId,threadTs:e.message.threadTs,installationTeamId:e.installationTeamId,teamId:e.message.teamId}),a=e.message.author,o={audience:`unknown`,channelId:e.message.channelId,installationTeamId:e.installationTeamId??null,teamId:e.message.teamId??null,threadTs:e.message.threadTs,triggeringUserId:a?.userId??null},c=bindSlackSessionOperations({address:t,defaultAuth:a===void 0?null:buildSlackAuthContext({channelId:e.message.channelId,fullName:a.fullName,isBot:a.isBot,teamId:e.message.teamId,threadTs:e.message.threadTs,userId:a.userId,userName:a.userName}),from:e.from,resolveSession:e.resolveSession,state:o}),d,isDMOrPrivateChannel=()=>d??=isPrivateSlackConversation({channelId:e.message.channelId,raw:e.message.raw,request:i.request}),f=e.kind===`app_mention`||e.botUserId!==void 0&&e.message.text.includes(`<@${e.botUserId}`),p={...c,isBotMentioned:()=>f,isDMOrPrivateChannel,isSubscribed:async()=>await c.resolveSession()!==void 0,slack:i,thread:r},m;try{m=await e.handler(p,e.message)}catch(t){logError(log,`${e.kind} handler failed`,t,{channelId:e.message.channelId});return}if(m==null)return;let h=await isDMOrPrivateChannel();o.audience=e.kind===`direct_message`||h?`private`:`public`,await deliverSlackMessage({botUserId:e.receivingBotUserId,credentials:e.credentials,kind:e.kind,isPrivateConversation:h,isMentioned:f,message:e.message,result:m,sessionOperations:c,thread:r,threadContext:e.threadContext,uploadPolicy:e.uploadPolicy})}async function dispatchSlackEvent(e){let t=e.envelope.event.team_id,r=typeof t==`string`?t:typeof e.envelope.team_id==`string`?e.envelope.team_id:void 0,i=[],sourceFor=t=>e.from(slackContinuationToken(t.channelId,t.threadTs)),a={cancel:({target:e,turnId:t})=>sourceFor(e).cancel({turnId:t}),clear:({target:e})=>sourceFor(e).clear(),compact:({target:e})=>sourceFor(e).compact(),envelope:e.envelope,reset:({reason:e,target:t})=>sourceFor(t).reset({reason:e}),resolveSession:({target:t})=>e.resolveSession(slackContinuationToken(t.channelId,t.threadTs)),respond:(e,{auth:t,target:n})=>sourceFor(n).respond(e,{auth:t}),send:(t,{auth:n,target:i,title:a})=>receiveOnSlack({auth:n,message:t,target:i,title:a},{from:e.from,credentials:e.credentials,installationTeamId:e.installationTeamId,teamId:r,...typeof e.envelope.event.user==`string`?{triggeringUserId:e.envelope.event.user}:{}}),slack:buildSlackWorkspaceHandle({botToken:e.credentials?.botToken,installationTeamId:e.installationTeamId,teamId:r}),waitUntil(e){i.push(e)}};try{await e.handler(a,e.envelope.event)}catch(t){logError(log,`event handler failed`,t,{eventId:e.envelope.event_id,eventType:e.envelope.event.type})}await Promise.allSettled(i)}async function verifyInbound(e,t){try{return await verifySlackRequest$1(e,{signingSecret:t?.signingSecret??(t?.webhookVerifier?void 0:process.env.SLACK_SIGNING_SECRET),webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`slack inbound verification failed`,{error:e}),null}}async function deliverSlackMessage(e){let{message:t,thread:r}=e;try{let n=formatSlackThreadContext(e.threadContext===void 0?[]:await loadThreadContextMessages(r,t,e.threadContext)),i=await collectInboundFileParts({mention:t,thread:r,policy:e.uploadPolicy}),a=formatSlackInboundMessage({botUserId:e.botUserId,channelId:t.channelId,fullName:t.author?.fullName,isMentioned:e.isMentioned,teamId:t.teamId,threadTs:t.threadTs,userId:t.author?.userId??``,userName:t.author?.userName},t),o=buildSlackTurnMessage(n===void 0?a:`${n}\n\n${a}`,i),s=e.result.context??[],c=e.isPrivateConversation?`Private message`:e.result.title??t.markdown,l=s.length===0?{auth:e.result.auth,title:c}:{auth:e.result.auth,context:s,title:c};await e.sessionOperations.send(o,l)}catch(r){logError(log,`${e.kind} delivery failed`,r,{channelId:t.channelId})}}export{constrainAuthorizationRequired,slackChannel};
|
|
1
|
+
import{markEventHandled}from"./utils.js";import{createLogger,logError}from"#internal/logging.js";import{defaultDeliverResult}from"#channel/adapter.js";import{normalizeChannelAudience}from"#shared/channel-audience.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{mergeUploadPolicy}from"#public/channels/upload-policy.js";import{buildSlackBinding,buildSlackWorkspaceHandle,slackContinuationToken}from"#public/channels/slack/api.js";import{buildSlackAuthContext,slackUserIdFromAuthContext}from"#public/channels/slack/auth.js";import{defaultEvents,defaultInputRequestedHandler,defaultOnAppMention,defaultOnDirectMessage}from"#public/channels/slack/defaults.js";import{loadThreadContextMessages}from"#public/channels/slack/thread.js";import{parseSlackWebhookBody}from"#compiled/@chat-adapter/slack/webhook.js";import{bindSlackSessionOperations}from"#public/channels/slack/session-operations.js";import{buildSlackTurnMessage,collectInboundFileParts,createSlackFetchFile}from"#public/channels/slack/attachments.js";import{parseMessageEvent,parseSlackEventEnvelope,slackEventBotUserId,slackEventInstallationTeamId,slackEventReceivingBotUserId,slackMessageFromWebhookPayload}from"#public/channels/slack/inbound.js";import{formatSlackInboundMessage,formatSlackThreadContext}from"#public/channels/slack/model-context.js";import{isPrivateSlackConversation}from"#public/channels/slack/privacy.js";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#public/channels/slack/constants.js";import{handleInteractionPost}from"#public/channels/slack/interactions.js";import{verifySlackRequest as verifySlackRequest$1}from"#public/channels/slack/verify.js";const log=createLogger(`slack.channel`);function rebuildSlackContext(e,t,n){let{thread:r,slack:i}=buildSlackBinding({botToken:n?.botToken,channelId:e.channelId??``,threadTs:e.threadTs??``,installationTeamId:e.installationTeamId??void 0,teamId:e.teamId??void 0,onThreadTsChanged(n){e.threadTs=n,e.channelId&&t.continuation?.rekey(slackContinuationToken(e.channelId,n))}});return{thread:r,slack:i,state:e}}function slackChannel(e={}){let t=mergeUploadPolicy(e.uploadPolicy),n=createSlackFetchFile({botToken:e.credentials?.botToken}),i=e.onInputResponse??defaultOnInputResponse,c=e.events?.[`authorization.required`],l=e.events?.[`approval.candidate`]??defaultEvents[`approval.candidate`],u=e.events?.[`turn.started`]??defaultEvents[`turn.started`],d={...defaultEvents,...e.events,async"approval.candidate"(e,t,n){let r=t.state.approvalResponderUsers?.[e.responderPrincipalId];if(e.outcome===`pending`&&r!==void 0&&(t.state.pendingApprovalCandidateUsers={...t.state.pendingApprovalCandidateUsers,[e.candidateId]:r}),await l(e,t,n),e.outcome!==`pending`){let n={...t.state.pendingApprovalCandidateUsers};delete n[e.candidateId],t.state.pendingApprovalCandidateUsers=n}},async"turn.started"(e,t,n){let r=slackUserIdFromAuthContext(n.session.auth.current);r!==void 0&&(t.state.triggeringUserId=r),await u(e,t,n)},"input.requested":e.events?.[`input.requested`]??defaultInputRequestedHandler(),"authorization.required":c===void 0?defaultEvents[`authorization.required`]:constrainAuthorizationRequired(c)},h=new Set;return defineChannel({kindHint:`slack`,turnPolicy:e.turnPolicy,state:{audience:`unknown`,channelId:null,threadTs:null,teamId:null,installationTeamId:null,triggeringUserId:null,pendingToolCallMessage:null,lastReasoningTypingAtMs:null,lastReasoningTypingStatus:null,pendingAuthMessageTs:{},pendingApprovalCards:{},pendingApprovalCandidateUsers:{},approvalResponderUsers:{}},fetchFile:n,metadata(e){return{audience:e.audience??`unknown`,channelId:e.channelId,teamId:e.teamId,threadTs:e.threadTs,triggeringUserId:e.triggeringUserId??null}},context(t,n){return rebuildSlackContext(t,n,e.credentials)},deliver(e,t){let n=e.pendingApprovalCards;typeof n==`object`&&n&&(t.state.pendingApprovalCards={...t.state.pendingApprovalCards,...n});let i=e.state?.approvalResponderUsers;return typeof i==`object`&&i&&(t.state.approvalResponderUsers={...t.state.approvalResponderUsers,...i}),defaultDeliverResult(e)},routes:[POST(e.route??SLACK_CHANNEL_DEFAULT_ROUTE,async(n,r)=>{let{waitUntil:a}=r,{from:o,resolveSession:s}=r,c=await verifyInbound(n,e.credentials);return c===null?new Response(`unauthorized`,{status:401}):shouldDropSlackHttpTimeoutRetry(n.headers)?new Response(`ok`):(n.headers.get(`content-type`)??``).includes(`application/x-www-form-urlencoded`)?handleInteractionPost(c,{from:o,resolveSession:s,waitUntil:a},{config:e,onInputResponse:i}):handleEventPost({body:c,from:o,resolveSession:s,waitUntil:a,config:e,uploadPolicy:t,handledEvents:h,headers:n.headers})})],receive(t,{from:n}){return receiveOnSlack(t,{from:n,credentials:e.credentials})},events:d})}function defaultOnInputResponse(e){return{auth:e.defaultAuth}}async function receiveOnSlack(e,t){let n=e.target,r=n.channelId;if(!r||typeof r!=`string`)throw Error(`slackChannel().receive requires target.channelId.`);let a=typeof n.threadTs==`string`?n.threadTs:``,o=typeof n.installationTeamId==`string`?n.installationTeamId:t.installationTeamId,s=n.initialMessage;if(s&&a.length>0)throw Error("slackChannel().receive: `threadTs` and `initialMessage` are mutually exclusive.");let l=a;if(s){let{thread:e}=buildSlackBinding({botToken:t.credentials?.botToken,channelId:r,threadTs:``,installationTeamId:o,teamId:t.teamId}),n={card:s.card};s.fallbackText!==void 0&&(n.fallbackText=s.fallbackText),l=(await e.post(n)).id}let d=l||crypto.randomUUID(),f=n.audience===void 0?void 0:normalizeChannelAudience(n.audience),p={channelId:r,installationTeamId:o??null,threadTs:l||null,teamId:t.teamId??null,triggeringUserId:t.triggeringUserId??null};return f!==void 0&&(p.audience=f),t.from(slackContinuationToken(r,d)).send(e.message,{auth:e.auth,state:p,title:e.title})}function constrainAuthorizationRequired(e){return(t,n,r)=>e(t,{postEphemeral:(e,t)=>n.thread.postEphemeral(e,t),postDirectMessage:(e,t)=>n.thread.postDirectMessage(e,t),state:n.state},r)}function shouldDropSlackHttpTimeoutRetry(e){return Number(e.get(`x-slack-retry-num`)??`0`)>=1&&e.get(`x-slack-retry-reason`)===`http_timeout`}async function handleEventPost(t){let{config:n}=t,r,i;try{r=parseSlackWebhookBody(t.body,{headers:t.headers}),i=parseSlackEventEnvelope(t.body)}catch(e){return log.warn(`inbound webhook body is not valid JSON`,{error:e}),new Response(`ok`)}if(r.kind===`url_verification`)return new Response(r.challenge,{status:200,headers:{"content-type":`text/plain`}});if(i===null)return new Response(`ok`);let a=typeof i.api_app_id==`string`?i.api_app_id:void 0,o=slackEventBotUserId(i),s=slackEventReceivingBotUserId(i),c=slackEventInstallationTeamId(i),dispatch=null,l=null;if(r.kind===`app_mention`||r.kind===`direct_message`){let e=r.kind,i=slackMessageFromWebhookPayload(r);if(i!==null&&!isSelfAuthoredSlackMessage({appId:a,botUserId:o},i)){let dispatchMessageWith=r=>()=>dispatchSlackMessage({appId:a,botUserId:o,receivingBotUserId:s,from:t.from,resolveSession:t.resolveSession,credentials:n.credentials,handler:r,installationTeamId:c,kind:e,message:i,threadContext:n.threadContext,uploadPolicy:t.uploadPolicy}),r=(e===`app_mention`?n.onAppMention:n.onDirectMessage)??n.onMessage;r===void 0?l=dispatchMessageWith(e===`app_mention`?defaultOnAppMention:defaultOnDirectMessage):dispatch=()=>dispatchSlackMessage({appId:a,botUserId:o,receivingBotUserId:s,from:t.from,resolveSession:t.resolveSession,credentials:n.credentials,handler:r,installationTeamId:c,kind:e,message:i,threadContext:n.threadContext,uploadPolicy:t.uploadPolicy})}}if(dispatch===null&&n.onMessage!==void 0){let e=parseMessageEvent(i);e!==null&&!isSelfAuthoredSlackMessage({appId:a,botUserId:o},e)&&(o===void 0||!e.text.includes(`<@${o}`))&&(dispatch=()=>dispatchSlackMessage({appId:a,botUserId:o,receivingBotUserId:s,from:t.from,resolveSession:t.resolveSession,credentials:n.credentials,handler:n.onMessage,installationTeamId:c,kind:`channel_message`,message:e,threadContext:n.threadContext,uploadPolicy:t.uploadPolicy}))}let u=n.onEvent;if(dispatch===null&&u!==void 0&&(dispatch=()=>dispatchSlackEvent({from:t.from,resolveSession:t.resolveSession,credentials:n.credentials,envelope:i,handler:u,installationTeamId:c})),dispatch??=l,dispatch===null)return new Response(`ok`);let d=i.event_id;if(d){if(t.handledEvents.has(d))return log.warn(`received a duplicate event`,{event_id:d,event_time:i.event_time,retry_num:r.retry?.num??`(null)`,retry_reason:r.retry?.reason??`(null)`}),new Response(`ok`);markEventHandled(d,t.handledEvents)}return t.waitUntil(dispatch()),new Response(`ok`)}function isSelfAuthoredSlackMessage(e,t){return e.botUserId!==void 0&&t.author?.userId===e.botUserId||e.appId!==void 0&&t.raw.app_id===e.appId}async function dispatchSlackMessage(e){let t=slackContinuationToken(e.message.channelId,e.message.threadTs),{thread:r,slack:i}=buildSlackBinding({appId:e.appId,botToken:e.credentials?.botToken,botUserId:e.botUserId,channelId:e.message.channelId,threadTs:e.message.threadTs,installationTeamId:e.installationTeamId,teamId:e.message.teamId}),a=e.message.author,o={audience:`unknown`,channelId:e.message.channelId,installationTeamId:e.installationTeamId??null,teamId:e.message.teamId??null,threadTs:e.message.threadTs,triggeringUserId:a?.userId??null},s=bindSlackSessionOperations({address:t,defaultAuth:a===void 0?null:buildSlackAuthContext({channelId:e.message.channelId,fullName:a.fullName,isBot:a.isBot,teamId:e.message.teamId,threadTs:e.message.threadTs,userId:a.userId,userName:a.userName}),from:e.from,resolveSession:e.resolveSession,state:o}),l,isDMOrPrivateChannel=()=>l??=isPrivateSlackConversation({channelId:e.message.channelId,raw:e.message.raw,request:i.request}),f=e.kind===`app_mention`||e.botUserId!==void 0&&e.message.text.includes(`<@${e.botUserId}`),p={...s,isBotMentioned:()=>f,isDMOrPrivateChannel,isSubscribed:async()=>await s.resolveSession()!==void 0,slack:i,thread:r},m;try{m=await e.handler(p,e.message)}catch(t){logError(log,`${e.kind} handler failed`,t,{channelId:e.message.channelId});return}if(m==null)return;let h=await isDMOrPrivateChannel();o.audience=e.kind===`direct_message`||h?`private`:`public`,await deliverSlackMessage({botUserId:e.receivingBotUserId,credentials:e.credentials,kind:e.kind,isPrivateConversation:h,isMentioned:f,message:e.message,result:m,sessionOperations:s,thread:r,threadContext:e.threadContext,uploadPolicy:e.uploadPolicy})}async function dispatchSlackEvent(e){let t=e.envelope.event.team_id,r=typeof t==`string`?t:typeof e.envelope.team_id==`string`?e.envelope.team_id:void 0,i=[],sourceFor=t=>e.from(slackContinuationToken(t.channelId,t.threadTs)),a={cancel:({target:e,turnId:t})=>sourceFor(e).cancel({turnId:t}),clear:({target:e})=>sourceFor(e).clear(),compact:({target:e})=>sourceFor(e).compact(),envelope:e.envelope,reset:({reason:e,target:t})=>sourceFor(t).reset({reason:e}),resolveSession:({target:t})=>e.resolveSession(slackContinuationToken(t.channelId,t.threadTs)),respond:(e,{auth:t,target:n})=>sourceFor(n).respond(e,{auth:t}),send:(t,{auth:n,target:i,title:a})=>receiveOnSlack({auth:n,message:t,target:i,title:a},{from:e.from,credentials:e.credentials,installationTeamId:e.installationTeamId,teamId:r,...typeof e.envelope.event.user==`string`?{triggeringUserId:e.envelope.event.user}:{}}),slack:buildSlackWorkspaceHandle({botToken:e.credentials?.botToken,installationTeamId:e.installationTeamId,teamId:r}),waitUntil(e){i.push(e)}};try{await e.handler(a,e.envelope.event)}catch(t){logError(log,`event handler failed`,t,{eventId:e.envelope.event_id,eventType:e.envelope.event.type})}await Promise.allSettled(i)}async function verifyInbound(e,t){try{return await verifySlackRequest$1(e,{signingSecret:t?.signingSecret??(t?.webhookVerifier?void 0:process.env.SLACK_SIGNING_SECRET),webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`slack inbound verification failed`,{error:e}),null}}async function deliverSlackMessage(e){let{message:t,thread:r}=e;try{let n=formatSlackThreadContext(e.threadContext===void 0?[]:await loadThreadContextMessages(r,t,e.threadContext)),i=await collectInboundFileParts({mention:t,thread:r,policy:e.uploadPolicy}),a=formatSlackInboundMessage({botUserId:e.botUserId,channelId:t.channelId,fullName:t.author?.fullName,isMentioned:e.isMentioned,teamId:t.teamId,threadTs:t.threadTs,userId:t.author?.userId??``,userName:t.author?.userName},t),o=buildSlackTurnMessage(n===void 0?a:`${n}\n\n${a}`,i),s=e.result.context??[],c=e.isPrivateConversation?`Private message`:e.result.title??t.markdown,l=s.length===0?{auth:e.result.auth,title:c}:{auth:e.result.auth,context:s,title:c};await e.sessionOperations.send(o,l)}catch(r){logError(log,`${e.kind} delivery failed`,r,{channelId:t.channelId})}}export{constrainAuthorizationRequired,slackChannel};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FilePart, UserContent } from "ai";
|
|
2
2
|
import type { FetchFileResult } from "#channel/adapter.js";
|
|
3
|
-
import type
|
|
3
|
+
import { type TeamsApiOptions, type TeamsAttachment } from "#public/channels/teams/api.js";
|
|
4
4
|
import { type UploadPolicyInput } from "#public/channels/upload-policy.js";
|
|
5
5
|
import type { UploadPolicy } from "#public/channels/upload-policy.js";
|
|
6
6
|
/** File handling options for the native Teams channel. */
|
|
@@ -32,4 +32,4 @@ export declare function buildTeamsTurnMessage(text: string, fileParts: readonly
|
|
|
32
32
|
* files are disabled or the URL host is not in `allowedHosts`; otherwise fetches
|
|
33
33
|
* the bytes and throws on a non-2xx response.
|
|
34
34
|
*/
|
|
35
|
-
export declare function createTeamsFetchFile(policy: TeamsFilesPolicy): (url: string) => Promise<FetchFileResult | null>;
|
|
35
|
+
export declare function createTeamsFetchFile(policy: TeamsFilesPolicy, api?: TeamsApiOptions): (url: string) => Promise<FetchFileResult | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{evaluateFilePart,formatUploadPolicyViolation,isUploadsDisabled,mergeUploadPolicy}from"#public/channels/upload-policy.js";const log=createLogger(`teams.attachments`);function normalizeTeamsFilesPolicy(e){return{allowedHosts:e?.allowedHosts??[],enabled:e?.enabled===!0,uploadPolicy:mergeUploadPolicy(e?.uploadPolicy)}}function collectTeamsFileParts(e,t){if(!t.enabled||isUploadsDisabled(t.uploadPolicy))return[];let a=[];for(let i of e){let e=toTeamsFilePart(i,a.length,t);if(e===null)continue;let o=evaluateFilePart(e,t.uploadPolicy);if(o!==null){log.warn(`dropped Teams attachment — ${formatUploadPolicyViolation(o)}`,{name:i.name});continue}a.push(e)}return a}function buildTeamsTurnMessage(e,t){return t.length===0?e:e.trim().length===0?[...t]:[{type:`text`,text:e},...t]}function createTeamsFetchFile(e){return async
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{evaluateFilePart,formatUploadPolicyViolation,isUploadsDisabled,mergeUploadPolicy}from"#public/channels/upload-policy.js";import{EveAttachmentError}from"#internal/attachments/errors.js";import{resolveTeamsAccessToken}from"#public/channels/teams/api.js";const log=createLogger(`teams.attachments`),BOT_CONNECTOR_HOSTS=new Set([`smba.trafficmanager.net`,`smba.infra.gcc.teams.microsoft.com`,`smba.infra.gov.teams.microsoft.us`,`smba.infra.dod.teams.microsoft.us`]),REDIRECT_STATUSES=new Set([301,302,303,307,308]);function normalizeTeamsFilesPolicy(e){return{allowedHosts:e?.allowedHosts??[],enabled:e?.enabled===!0,uploadPolicy:mergeUploadPolicy(e?.uploadPolicy)}}function collectTeamsFileParts(e,t){if(!t.enabled||isUploadsDisabled(t.uploadPolicy))return[];let a=[];for(let i of e){let e=toTeamsFilePart(i,a.length,t);if(e===null)continue;let o=evaluateFilePart(e,t.uploadPolicy);if(o!==null){log.warn(`dropped Teams attachment — ${formatUploadPolicyViolation(o)}`,{name:i.name});continue}a.push(e)}return a}function buildTeamsTurnMessage(e,t){return t.length===0?e:e.trim().length===0?[...t]:[{type:`text`,text:e},...t]}function createTeamsFetchFile(e,t={}){return async n=>{if(!e.enabled||!isAllowedUrl(n,e.allowedHosts))return null;let{response:r,finalUrl:i}=await fetchTeamsFile(n,e.allowedHosts,t);if(!r.ok)throw attachmentError(`Teams file fetch returned HTTP ${r.status} for host ${i.hostname}.`);return{bytes:Buffer.from(await r.arrayBuffer()),mediaType:r.headers.get(`content-type`)??void 0}}}async function fetchTeamsFile(e,t,n){let r=n.fetch??fetch,i=new URL(e),a;for(let e=0;e<=5;e+=1){let o=i.port===``&&BOT_CONNECTOR_HOSTS.has(i.hostname),s=new Headers;o&&(a??=await resolveTeamsAccessToken(n),s.set(`authorization`,`Bearer ${a}`));let c=await r(i,{headers:s,redirect:`manual`});if(!REDIRECT_STATUSES.has(c.status))return{finalUrl:i,response:c};if(e===5)throw attachmentError(`Teams file fetch exceeded 5 redirects.`);let l=c.headers.get(`location`);if(l===null)throw attachmentError(`Teams file fetch redirect from host ${i.hostname} had no location.`);let u=new URL(l,i);if(!isAllowedUrl(u.href,t))throw attachmentError(`Teams file fetch redirect to host ${u.hostname} is not allowed.`);i=u}throw attachmentError(`Teams file fetch exceeded 5 redirects.`)}function attachmentError(e){return new EveAttachmentError({adapterKind:`teams`,kind:`resolver-threw`,message:e})}function toTeamsFilePart(e,t,n){let r=readAttachmentUrl(e);return!r||!isAllowedUrl(r,n.allowedHosts)?null:{data:new URL(r),filename:e.name??`teams-attachment-${t}`,mediaType:inferMediaType(e),type:`file`}}function readAttachmentUrl(e){return e.contentType===`application/vnd.microsoft.teams.file.download.info`&&isObject(e.content)&&typeof e.content.downloadUrl==`string`?e.content.downloadUrl:e.contentUrl&&!e.contentType.startsWith(`application/vnd.microsoft.card.`)?e.contentUrl:null}function inferMediaType(e){return e.contentType===`application/vnd.microsoft.teams.file.download.info`&&(isObject(e.content)&&typeof e.content.fileType==`string`?e.content.fileType:void 0)===`txt`?`text/plain`:e.contentType||`application/octet-stream`}function isAllowedUrl(e,t){let n;try{n=new URL(e)}catch{return!1}return n.protocol===`https:`?t===`*`||t.some(e=>e.includes(`:`)?n.host===e:n.port===``&&n.hostname===e):!1}export{buildTeamsTurnMessage,collectTeamsFileParts,createTeamsFetchFile,normalizeTeamsFilesPolicy};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{defaultDeliverResult}from"#channel/adapter.js";import{readNonEmptyString}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{callTeamsConnectorApi,normalizeTeamsContinuationAddress,normalizeTeamsPostInput,replyToTeamsActivity,sendTeamsActivity,teamsContinuationToken,triggerTeamsTypingIndicator,updateTeamsActivity}from"#public/channels/teams/api.js";import{deriveTeamsInputResponses,isTeamsInputResponseActivity,isTeamsToolApprovalResponseActivity,readTeamsInputReplyToActivityId,readTeamsToolApprovalPrompt,teamsInvokeResponse}from"#public/channels/teams/hitl.js";import{formatTeamsContextBlock,parseTeamsActivity,teamsThreadRootActivityId}from"#public/channels/teams/inbound.js";import{buildTeamsTurnMessage,collectTeamsFileParts,createTeamsFetchFile,normalizeTeamsFilesPolicy}from"#public/channels/teams/attachments.js";import{defaultEvents,defaultOnMessage,defaultTeamsAuth,teamsMentionUser}from"#public/channels/teams/defaults.js";import{verifyTeamsRequest}from"#public/channels/teams/verify.js";const log=createLogger(`teams.channel`);function teamsChannel(e={}){let t=normalizeTeamsFilesPolicy(e.files),s=e.onMessage??defaultOnMessage,c=e.onInputResponse??(e.onMessage===void 0?defaultOnInputResponse:rejectInput),l={...defaultEvents,...e.events};return defineChannel({kindHint:`teams`,turnPolicy:e.turnPolicy,state:initialTeamsState(),fetchFile:createTeamsFetchFile(t),metadata:e=>({audience:teamsAudience(e.conversationType),channelId:e.channelId,conversationType:e.conversationType,teamId:e.teamId}),context(t,n){return rebuildTeamsContext(t,n,e)},deliver(e,t){let r=e.state,i=r?.pendingApprovalCards;i!==void 0&&(t.state.pendingApprovalCards={...i,...t.state.pendingApprovalCards});let a=r?.approvalResponderAccounts;return a!==void 0&&(t.state.approvalResponderAccounts={...t.state.approvalResponderAccounts,...a}),defaultDeliverResult(e)},routes:[POST(e.route??`/eve/v1/teams`,async(n,{from:r,resolveSession:a,waitUntil:o})=>{let l=await verifyInbound(n,e.credentials);if(l===null)return new Response(`unauthorized`,{status:401});let u;try{u=parseJsonObject(JSON.parse(l))}catch(e){return log.warn(`inbound Teams body is not valid JSON`,{error:e}),teamsOk()}let d=parseTeamsActivity(u);return d===null?teamsOk():d.type===`message`?(o(isTeamsInputResponseActivity(d)?dispatchInputResponses({activity:d,config:e,from:r,onInputResponse:c}):dispatchMessage({activity:d,config:e,filesPolicy:t,onMessage:s,from:r,resolveSession:a})),teamsOk()):d.type===`invoke`?handleInvoke({activity:d,config:e,onInputResponse:c,waitUntil:o,from:r}):teamsOk()})],async receive(t,{from:n}){let i=t.target,a=readNonEmptyString(i.serviceUrl),o=readNonEmptyString(i.conversationId);if(!a||!o)throw Error(`teamsChannel().receive requires target.serviceUrl and target.conversationId.`);let s=readNonEmptyString(i.conversationType)??null,c=readNonEmptyString(i.replyToActivityId)??null,l=i.initialMessage;if(l!==void 0&&c!==null)throw Error("teamsChannel().receive: `replyToActivityId` and `initialMessage` are mutually exclusive.");let u={...initialTeamsState(),channelId:readNonEmptyString(i.channelId)??null,conversationId:o,conversationType:s,replyToActivityId:c,serviceUrl:a,teamId:readNonEmptyString(i.teamId)??null,tenantId:readNonEmptyString(i.tenantId)??null};if(l!==void 0){let t=await buildTeamsBinding({config:e,state:u}).thread.post(l);s!==`personal`&&t.id&&(c=t.id,u.replyToActivityId=t.id)}return n(teamsContinuationToken({conversationId:o,replyToActivityId:c,tenantId:u.tenantId})).send(t.message,{auth:t.auth,state:u})},events:l})}function teamsAudience(e){return e===`personal`||e===`groupChat`?`private`:`unknown`}function rebuildTeamsContext(e,t,n){return{...buildTeamsBinding({config:n,session:t,state:e}),adaptiveCardVersion:n.adaptiveCardVersion??`1.5`,state:e}}function buildTeamsBinding(e){let n=buildTeamsHandle(e);return{teams:n,thread:{mentionUser:teamsMentionUser,post(e){return n.sendActivity(e)},async startTyping(){try{await n.startTyping()}catch(e){logError(log,`Teams typing indicator failed — swallowed`,e)}},update(e,t){return n.updateActivity(e,t)}}}}function buildTeamsHandle(e){let t=e.state,n=e.config.api,r=e.config.credentials;function requireAddress(){let e=t.conversationId??``,n=t.serviceUrl??``;if(!e||!n)throw Error(`teamsChannel: missing serviceUrl or conversationId for outbound message.`);return{conversationId:e,serviceUrl:n}}function anchor(n){if(!n.id||t.replyToActivityId||t.conversationType===`personal`)return;t.replyToActivityId=n.id;let r=t.conversationId;r&&e.session?.continuation?.rekey(teamsContinuationToken({conversationId:r,replyToActivityId:n.id,tenantId:t.tenantId}))}async function send(e){let i=requireAddress(),a=buildOutboundActivity(t,e),o=t.replyToActivityId===null?await sendTeamsActivity({...n,body:a,credentials:r,conversationId:i.conversationId,serviceUrl:i.serviceUrl}):await replyToTeamsActivity({...n,body:a,credentials:r,activityId:t.replyToActivityId,conversationId:i.conversationId,serviceUrl:i.serviceUrl});return anchor(o),o}return{channelId:t.channelId??void 0,conversationId:t.conversationId??``,conversationType:t.conversationType??void 0,replyToActivityId:t.replyToActivityId??void 0,serviceUrl:t.serviceUrl??``,teamId:t.teamId??void 0,tenantId:t.tenantId??void 0,request(e,t,i){let a=requireAddress();return callTeamsConnectorApi({...n,body:t,credentials:r,method:i?.method,path:e,serviceUrl:a.serviceUrl})},sendActivity:send,replyToActivity(e){let i=requireAddress(),a=t.replyToActivityId??``;if(!a)throw Error(`teamsChannel: missing reply activity id.`);return replyToTeamsActivity({...n,body:buildOutboundActivity(t,e),credentials:r,activityId:a,conversationId:i.conversationId,serviceUrl:i.serviceUrl})},updateActivity(e,i){let a=requireAddress();return updateTeamsActivity({...n,body:buildUpdateActivity(t,i),credentials:r,activityId:e,conversationId:normalizeTeamsContinuationAddress({conversationId:a.conversationId}).conversationId,serviceUrl:a.serviceUrl})},async startTyping(){let e=requireAddress();await triggerTeamsTypingIndicator({...n,credentials:r,conversationId:e.conversationId,serviceUrl:e.serviceUrl})}}}async function verifyInbound(e,t){try{return await verifyTeamsRequest(e,{appId:t?.webhookVerifier?void 0:t?.appId,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`teams inbound verification failed`,{error:e}),null}}async function dispatchMessage(e){let t=stateFromActivity(e.activity),n=buildTeamsBinding({config:e.config,state:t}),r=stateToken(t),i={...n,isSubscribed:async()=>await e.resolveSession(r)!==void 0},a;try{a=await e.onMessage(i,e.activity)}catch(e){log.error(`Teams message handler failed`,{error:e});return}if(a==null)return;let o=collectTeamsFileParts(e.activity.attachments,e.filesPolicy),s=buildTeamsTurnMessage(e.activity.text,o),c={activityId:e.activity.id,botId:e.activity.recipient.id,channelId:e.activity.teamsChannelId,conversationId:e.activity.conversation.id,conversationType:e.activity.conversationType,isMentioned:e.activity.isBotMentioned,scope:e.activity.scope,teamId:e.activity.teamId,tenantId:e.activity.tenantId,userId:e.activity.from.id,userName:e.activity.from.name},l=a.context??[];try{await e.from(r).send(s,{auth:a.auth,context:[formatTeamsContextBlock(c),...l],state:t,title:a.title})}catch(e){log.error(`Teams message delivery failed`,{error:e})}}async function handleInvoke(e){if(isTeamsInputResponseActivity(e.activity))return e.waitUntil(dispatchInputResponses({activity:e.activity,config:e.config,onInputResponse:e.onInputResponse,from:e.from})),Response.json(teamsInvokeResponse());if(e.config.onInvoke===void 0)return teamsOk();let t=buildTeamsBinding({config:e.config,state:stateFromActivity(e.activity)}),n=await e.config.onInvoke(t,e.activity);return n instanceof Response?n:n&&typeof n==`object`?Response.json(n):teamsOk()}async function dispatchInputResponses(e){let t=deriveTeamsInputResponses(e.activity);if(t.length===0)return;let n=stateFromActivity(e.activity),r=buildTeamsBinding({config:e.config,state:n}),i;try{i=await e.onInputResponse(r,e.activity)}catch(e){log.error(`Teams input response authorization failed`,{error:e});return}if(i!==null)try{await e.from(resolveInputContinuationToken(e.activity,n)).respond(t,{auth:i.auth,state:approvalResponseStatePatch(e.activity,i.auth)})}catch(e){log.error(`Teams input response delivery failed`,{error:e})}}function stateFromActivity(e){let t=normalizeTeamsContinuationAddress({conversationId:e.conversation.id,replyToActivityId:teamsThreadRootActivityId(e)});return{bot:e.recipient,channelId:e.teamsChannelId??null,conversationId:e.conversation.id,conversationType:e.conversationType??e.scope,pendingAuthActivityId:null,replyToActivityId:t.replyToActivityId,serviceUrl:e.serviceUrl,teamId:e.teamId??null,tenantId:e.tenantId??null,triggeringUser:e.from}}function resolveInputContinuationToken(e,t){let n=readTeamsInputReplyToActivityId(e);return n===null?stateToken(t):teamsContinuationToken({conversationId:e.conversation.id,replyToActivityId:n,tenantId:e.tenantId})}function approvalResponseStatePatch(e,t){if(t?.principalId===void 0||!isTeamsToolApprovalResponseActivity(e))return;let n=deriveTeamsInputResponses(e)[0]?.requestId,r=e.replyToId;return n===void 0||r===void 0?{approvalResponderAccounts:{[t.principalId]:e.from}}:{approvalResponderAccounts:{[t.principalId]:e.from},pendingApprovalCards:{[n]:{activityId:r,prompt:readTeamsToolApprovalPrompt(e)??`Tool approval`}}}}function defaultOnInputResponse(e,t){return{auth:defaultTeamsAuth(t)}}function rejectInput(){return null}function initialTeamsState(){return{bot:null,channelId:null,conversationId:null,conversationType:null,approvalResponderAccounts:{},pendingApprovalCards:{},pendingAuthActivityId:null,replyToActivityId:null,serviceUrl:null,teamId:null,tenantId:null,triggeringUser:null}}function stateToken(e){let t=e.conversationId??``;if(!t)throw Error(`teamsChannel: missing conversation id.`);return teamsContinuationToken({conversationId:t,replyToActivityId:e.replyToActivityId,tenantId:e.tenantId})}function buildOutboundActivity(e,t){if(typeof t!=`string`&&`type`in t&&t.type===`typing`)return t;let n=normalizeTeamsPostInput(t),r=mergeChannelData(e,n.channelData);return{...n,channelData:r,conversation:e.conversationId?{id:e.conversationId}:void 0,from:e.bot??void 0,replyToId:e.replyToActivityId??void 0,type:`message`}}function buildUpdateActivity(e,t){if(typeof t!=`string`&&`type`in t&&t.type===`typing`)throw Error(`teamsChannel: cannot replace an activity with a typing indicator.`);let{channelData:n,conversation:r,from:i,recipient:a,replyToId:o,type:s,...c}=normalizeTeamsPostInput(t);return{...c,type:`message`}}function mergeChannelData(e,t){let n={...t};return e.tenantId&&(n.tenant={id:e.tenantId}),e.teamId&&(n.team={id:e.teamId}),e.channelId&&(n.channel={id:e.channelId}),Object.keys(n).length>0?parseJsonObject(n):void 0}function teamsOk(){return new Response(`ok`,{status:200})}export{teamsChannel};
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{defaultDeliverResult}from"#channel/adapter.js";import{readNonEmptyString}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{callTeamsConnectorApi,normalizeTeamsContinuationAddress,normalizeTeamsPostInput,replyToTeamsActivity,sendTeamsActivity,teamsContinuationToken,triggerTeamsTypingIndicator,updateTeamsActivity}from"#public/channels/teams/api.js";import{deriveTeamsInputResponses,isTeamsInputResponseActivity,isTeamsToolApprovalResponseActivity,readTeamsInputReplyToActivityId,readTeamsToolApprovalPrompt,teamsInvokeResponse}from"#public/channels/teams/hitl.js";import{formatTeamsContextBlock,parseTeamsActivity,teamsThreadRootActivityId}from"#public/channels/teams/inbound.js";import{buildTeamsTurnMessage,collectTeamsFileParts,createTeamsFetchFile,normalizeTeamsFilesPolicy}from"#public/channels/teams/attachments.js";import{defaultEvents,defaultOnMessage,defaultTeamsAuth,teamsMentionUser}from"#public/channels/teams/defaults.js";import{verifyTeamsRequest}from"#public/channels/teams/verify.js";const log=createLogger(`teams.channel`);function teamsChannel(e={}){let t=normalizeTeamsFilesPolicy(e.files),s=e.onMessage??defaultOnMessage,c=e.onInputResponse??(e.onMessage===void 0?defaultOnInputResponse:rejectInput),l={...defaultEvents,...e.events};return defineChannel({kindHint:`teams`,turnPolicy:e.turnPolicy,state:initialTeamsState(),fetchFile:createTeamsFetchFile(t,{...e.api,credentials:e.credentials}),metadata:e=>({audience:teamsAudience(e.conversationType),channelId:e.channelId,conversationType:e.conversationType,teamId:e.teamId}),context(t,n){return rebuildTeamsContext(t,n,e)},deliver(e,t){let r=e.state,i=r?.pendingApprovalCards;i!==void 0&&(t.state.pendingApprovalCards={...i,...t.state.pendingApprovalCards});let a=r?.approvalResponderAccounts;return a!==void 0&&(t.state.approvalResponderAccounts={...t.state.approvalResponderAccounts,...a}),defaultDeliverResult(e)},routes:[POST(e.route??`/eve/v1/teams`,async(n,{from:r,resolveSession:a,waitUntil:o})=>{let l=await verifyInbound(n,e.credentials);if(l===null)return new Response(`unauthorized`,{status:401});let u;try{u=parseJsonObject(JSON.parse(l))}catch(e){return log.warn(`inbound Teams body is not valid JSON`,{error:e}),teamsOk()}let d=parseTeamsActivity(u);return d===null?teamsOk():d.type===`message`?(o(isTeamsInputResponseActivity(d)?dispatchInputResponses({activity:d,config:e,from:r,onInputResponse:c}):dispatchMessage({activity:d,config:e,filesPolicy:t,onMessage:s,from:r,resolveSession:a})),teamsOk()):d.type===`invoke`?handleInvoke({activity:d,config:e,onInputResponse:c,waitUntil:o,from:r}):teamsOk()})],async receive(t,{from:n}){let i=t.target,a=readNonEmptyString(i.serviceUrl),o=readNonEmptyString(i.conversationId);if(!a||!o)throw Error(`teamsChannel().receive requires target.serviceUrl and target.conversationId.`);let s=readNonEmptyString(i.conversationType)??null,c=readNonEmptyString(i.replyToActivityId)??null,l=i.initialMessage;if(l!==void 0&&c!==null)throw Error("teamsChannel().receive: `replyToActivityId` and `initialMessage` are mutually exclusive.");let u={...initialTeamsState(),channelId:readNonEmptyString(i.channelId)??null,conversationId:o,conversationType:s,replyToActivityId:c,serviceUrl:a,teamId:readNonEmptyString(i.teamId)??null,tenantId:readNonEmptyString(i.tenantId)??null};if(l!==void 0){let t=await buildTeamsBinding({config:e,state:u}).thread.post(l);s!==`personal`&&t.id&&(c=t.id,u.replyToActivityId=t.id)}return n(teamsContinuationToken({conversationId:o,replyToActivityId:c,tenantId:u.tenantId})).send(t.message,{auth:t.auth,state:u})},events:l})}function teamsAudience(e){return e===`personal`||e===`groupChat`?`private`:`unknown`}function rebuildTeamsContext(e,t,n){return{...buildTeamsBinding({config:n,session:t,state:e}),adaptiveCardVersion:n.adaptiveCardVersion??`1.5`,state:e}}function buildTeamsBinding(e){let n=buildTeamsHandle(e);return{teams:n,thread:{mentionUser:teamsMentionUser,post(e){return n.sendActivity(e)},async startTyping(){try{await n.startTyping()}catch(e){logError(log,`Teams typing indicator failed — swallowed`,e)}},update(e,t){return n.updateActivity(e,t)}}}}function buildTeamsHandle(e){let t=e.state,n=e.config.api,r=e.config.credentials;function requireAddress(){let e=t.conversationId??``,n=t.serviceUrl??``;if(!e||!n)throw Error(`teamsChannel: missing serviceUrl or conversationId for outbound message.`);return{conversationId:e,serviceUrl:n}}function anchor(n){if(!n.id||t.replyToActivityId||t.conversationType===`personal`)return;t.replyToActivityId=n.id;let r=t.conversationId;r&&e.session?.continuation?.rekey(teamsContinuationToken({conversationId:r,replyToActivityId:n.id,tenantId:t.tenantId}))}async function send(e){let i=requireAddress(),a=buildOutboundActivity(t,e),o=t.replyToActivityId===null?await sendTeamsActivity({...n,body:a,credentials:r,conversationId:i.conversationId,serviceUrl:i.serviceUrl}):await replyToTeamsActivity({...n,body:a,credentials:r,activityId:t.replyToActivityId,conversationId:i.conversationId,serviceUrl:i.serviceUrl});return anchor(o),o}return{channelId:t.channelId??void 0,conversationId:t.conversationId??``,conversationType:t.conversationType??void 0,replyToActivityId:t.replyToActivityId??void 0,serviceUrl:t.serviceUrl??``,teamId:t.teamId??void 0,tenantId:t.tenantId??void 0,request(e,t,i){let a=requireAddress();return callTeamsConnectorApi({...n,body:t,credentials:r,method:i?.method,path:e,serviceUrl:a.serviceUrl})},sendActivity:send,replyToActivity(e){let i=requireAddress(),a=t.replyToActivityId??``;if(!a)throw Error(`teamsChannel: missing reply activity id.`);return replyToTeamsActivity({...n,body:buildOutboundActivity(t,e),credentials:r,activityId:a,conversationId:i.conversationId,serviceUrl:i.serviceUrl})},updateActivity(e,i){let a=requireAddress();return updateTeamsActivity({...n,body:buildUpdateActivity(t,i),credentials:r,activityId:e,conversationId:normalizeTeamsContinuationAddress({conversationId:a.conversationId}).conversationId,serviceUrl:a.serviceUrl})},async startTyping(){let e=requireAddress();await triggerTeamsTypingIndicator({...n,credentials:r,conversationId:e.conversationId,serviceUrl:e.serviceUrl})}}}async function verifyInbound(e,t){try{return await verifyTeamsRequest(e,{appId:t?.webhookVerifier?void 0:t?.appId,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`teams inbound verification failed`,{error:e}),null}}async function dispatchMessage(e){let t=stateFromActivity(e.activity),n=buildTeamsBinding({config:e.config,state:t}),r=stateToken(t),i={...n,isSubscribed:async()=>await e.resolveSession(r)!==void 0},a;try{a=await e.onMessage(i,e.activity)}catch(e){log.error(`Teams message handler failed`,{error:e});return}if(a==null)return;let o=collectTeamsFileParts(e.activity.attachments,e.filesPolicy),s=buildTeamsTurnMessage(e.activity.text,o),c={activityId:e.activity.id,botId:e.activity.recipient.id,channelId:e.activity.teamsChannelId,conversationId:e.activity.conversation.id,conversationType:e.activity.conversationType,isMentioned:e.activity.isBotMentioned,scope:e.activity.scope,teamId:e.activity.teamId,tenantId:e.activity.tenantId,userId:e.activity.from.id,userName:e.activity.from.name},l=a.context??[];try{await e.from(r).send(s,{auth:a.auth,context:[formatTeamsContextBlock(c),...l],state:t,title:a.title})}catch(e){log.error(`Teams message delivery failed`,{error:e})}}async function handleInvoke(e){if(isTeamsInputResponseActivity(e.activity))return e.waitUntil(dispatchInputResponses({activity:e.activity,config:e.config,onInputResponse:e.onInputResponse,from:e.from})),Response.json(teamsInvokeResponse());if(e.config.onInvoke===void 0)return teamsOk();let t=buildTeamsBinding({config:e.config,state:stateFromActivity(e.activity)}),n=await e.config.onInvoke(t,e.activity);return n instanceof Response?n:n&&typeof n==`object`?Response.json(n):teamsOk()}async function dispatchInputResponses(e){let t=deriveTeamsInputResponses(e.activity);if(t.length===0)return;let n=stateFromActivity(e.activity),r=buildTeamsBinding({config:e.config,state:n}),i;try{i=await e.onInputResponse(r,e.activity)}catch(e){log.error(`Teams input response authorization failed`,{error:e});return}if(i!==null)try{await e.from(resolveInputContinuationToken(e.activity,n)).respond(t,{auth:i.auth,state:approvalResponseStatePatch(e.activity,i.auth)})}catch(e){log.error(`Teams input response delivery failed`,{error:e})}}function stateFromActivity(e){let t=normalizeTeamsContinuationAddress({conversationId:e.conversation.id,replyToActivityId:teamsThreadRootActivityId(e)});return{bot:e.recipient,channelId:e.teamsChannelId??null,conversationId:e.conversation.id,conversationType:e.conversationType??e.scope,pendingAuthActivityId:null,replyToActivityId:t.replyToActivityId,serviceUrl:e.serviceUrl,teamId:e.teamId??null,tenantId:e.tenantId??null,triggeringUser:e.from}}function resolveInputContinuationToken(e,t){let n=readTeamsInputReplyToActivityId(e);return n===null?stateToken(t):teamsContinuationToken({conversationId:e.conversation.id,replyToActivityId:n,tenantId:e.tenantId})}function approvalResponseStatePatch(e,t){if(t?.principalId===void 0||!isTeamsToolApprovalResponseActivity(e))return;let n=deriveTeamsInputResponses(e)[0]?.requestId,r=e.replyToId;return n===void 0||r===void 0?{approvalResponderAccounts:{[t.principalId]:e.from}}:{approvalResponderAccounts:{[t.principalId]:e.from},pendingApprovalCards:{[n]:{activityId:r,prompt:readTeamsToolApprovalPrompt(e)??`Tool approval`}}}}function defaultOnInputResponse(e,t){return{auth:defaultTeamsAuth(t)}}function rejectInput(){return null}function initialTeamsState(){return{bot:null,channelId:null,conversationId:null,conversationType:null,approvalResponderAccounts:{},pendingApprovalCards:{},pendingAuthActivityId:null,replyToActivityId:null,serviceUrl:null,teamId:null,tenantId:null,triggeringUser:null}}function stateToken(e){let t=e.conversationId??``;if(!t)throw Error(`teamsChannel: missing conversation id.`);return teamsContinuationToken({conversationId:t,replyToActivityId:e.replyToActivityId,tenantId:e.tenantId})}function buildOutboundActivity(e,t){if(typeof t!=`string`&&`type`in t&&t.type===`typing`)return t;let n=normalizeTeamsPostInput(t),r=mergeChannelData(e,n.channelData);return{...n,channelData:r,conversation:e.conversationId?{id:e.conversationId}:void 0,from:e.bot??void 0,replyToId:e.replyToActivityId??void 0,type:`message`}}function buildUpdateActivity(e,t){if(typeof t!=`string`&&`type`in t&&t.type===`typing`)throw Error(`teamsChannel: cannot replace an activity with a typing indicator.`);let{channelData:n,conversation:r,from:i,recipient:a,replyToId:o,type:s,...c}=normalizeTeamsPostInput(t);return{...c,type:`message`}}function mergeChannelData(e,t){let n={...t};return e.tenantId&&(n.tenant={id:e.tenantId}),e.teamId&&(n.team={id:e.teamId}),e.channelId&&(n.channel={id:e.channelId}),Object.keys(n).length>0?parseJsonObject(n):void 0}function teamsOk(){return new Response(`ok`,{status:200})}export{teamsChannel};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{evaluateFilePart,formatUploadPolicyViolation,isMediaTypeAllowed,isUploadsDisabled}from"#public/channels/upload-policy.js";import{downloadTelegramFile,getTelegramFile}from"#public/channels/telegram/api.js";const log=createLogger(`telegram.attachments`),TELEGRAM_FILE_URL_PROTOCOL=`telegram-file:`;function collectTelegramFileParts(e,t){if(isUploadsDisabled(t))return[];let r=[];for(let i of e){let e=toTelegramFilePart(i,r.length);if(e===null)continue;let a=evaluateTelegramFilePart(e,i.size,t);if(a!==null){log.warn(`dropped attachment — ${formatUploadPolicyViolation(a)}`,{fileId:i.fileId,name:i.fileName});continue}r.push(e)}return r}function buildTelegramTurnMessage(e,t){let n=e.text||e.caption;return t.length===0?n:n.trim().length===0?[...t]:[{type:`text`,text:n},...t]}function createTelegramFetchFile(e){return async r=>{let i=parseTelegramFileUrl(r);if(i===null)return null;let o=await getTelegramFile({apiBaseUrl:e.api?.apiBaseUrl,credentials:e.credentials,fetch:e.api?.fetch,fileId:i.fileId}),s=await downloadTelegramFile({apiBaseUrl:e.api?.apiBaseUrl,credentials:e.credentials,fetch:e.api?.fetch,fileBaseUrl:e.api?.fileBaseUrl,filePath:o.filePath});if(!s.ok)throw
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{evaluateFilePart,formatUploadPolicyViolation,isMediaTypeAllowed,isUploadsDisabled}from"#public/channels/upload-policy.js";import{EveAttachmentError}from"#internal/attachments/errors.js";import{downloadTelegramFile,getTelegramFile}from"#public/channels/telegram/api.js";const log=createLogger(`telegram.attachments`),TELEGRAM_FILE_URL_PROTOCOL=`telegram-file:`;function collectTelegramFileParts(e,t){if(isUploadsDisabled(t))return[];let r=[];for(let i of e){let e=toTelegramFilePart(i,r.length);if(e===null)continue;let a=evaluateTelegramFilePart(e,i.size,t);if(a!==null){log.warn(`dropped attachment — ${formatUploadPolicyViolation(a)}`,{fileId:i.fileId,name:i.fileName});continue}r.push(e)}return r}function buildTelegramTurnMessage(e,t){let n=e.text||e.caption;return t.length===0?n:n.trim().length===0?[...t]:[{type:`text`,text:n},...t]}function createTelegramFetchFile(e){return async r=>{let i=parseTelegramFileUrl(r);if(i===null)return null;let o=await getTelegramFile({apiBaseUrl:e.api?.apiBaseUrl,credentials:e.credentials,fetch:e.api?.fetch,fileId:i.fileId}),s=await downloadTelegramFile({apiBaseUrl:e.api?.apiBaseUrl,credentials:e.credentials,fetch:e.api?.fetch,fileBaseUrl:e.api?.fileBaseUrl,filePath:o.filePath});if(!s.ok)throw new EveAttachmentError({adapterKind:`telegram`,kind:`resolver-threw`,message:`Telegram file fetch returned HTTP ${s.status}.`});let c=Buffer.from(await s.arrayBuffer()),l=s.headers.get(`content-type`)??i.mediaType??`application/octet-stream`,u={bytes:c,filename:i.filename,mediaType:l},d=evaluateFilePart({data:u.bytes,filename:u.filename,mediaType:l,type:`file`},e.policy);if(d!==null)throw new EveAttachmentError({adapterKind:`telegram`,kind:`resolver-threw`,message:`Telegram file rejected — ${formatUploadPolicyViolation(d)}`});return u}}function createTelegramFileUrl(e){let t=new URLSearchParams;e.filename!==void 0&&t.set(`filename`,e.filename),e.mediaType!==void 0&&t.set(`mediaType`,e.mediaType);let n=t.size>0?`?${t.toString()}`:``;return new URL(`${TELEGRAM_FILE_URL_PROTOCOL}${encodeURIComponent(e.fileId)}${n}`)}function toTelegramFilePart(e,t){let n=e.mediaType??(e.kind===`photo`?`image/jpeg`:`application/octet-stream`),r=e.fileName??(e.kind===`photo`?`photo-${t}.jpg`:`file-${t}`);return{data:createTelegramFileUrl({fileId:e.fileId,filename:r,mediaType:n}),filename:r,mediaType:n,type:`file`}}function parseTelegramFileUrl(e){let t;try{t=new URL(e)}catch{return null}if(t.protocol!==`telegram-file:`)return null;let n=decodeURIComponent(t.pathname);return n?{fileId:n,filename:t.searchParams.get(`filename`)??void 0,mediaType:t.searchParams.get(`mediaType`)??void 0}:null}function evaluateTelegramFilePart(e,n,i){return i===`disabled`||!isMediaTypeAllowed(e.mediaType,i)?evaluateFilePart(e,i):n!==void 0&&n>i.maxBytes?{byteLength:n,filename:e.filename,kind:`too-large`,limit:i.maxBytes,mediaType:e.mediaType}:null}export{TELEGRAM_FILE_URL_PROTOCOL,buildTelegramTurnMessage,collectTelegramFileParts,createTelegramFetchFile,createTelegramFileUrl};
|
|
@@ -29,9 +29,12 @@ export interface RemoteAgentDefinition {
|
|
|
29
29
|
* session's initiator pinned. Defaults to `false` — forwarding identity to
|
|
30
30
|
* another deployment is an explicit decision, never ambient.
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* When the parent trace is sampled and its audience is public, the same
|
|
33
|
+
* option adds `eve.audience=public` to W3C Baggage. A receiver that accepts
|
|
34
|
+
* this deployment through `eveChannel({ trustedForwarders })` uses that
|
|
35
|
+
* audience for its own trace policy. Only principal and public-audience
|
|
36
|
+
* metadata cross the wire, never tokens or credentials — {@link auth} keeps
|
|
37
|
+
* authenticating *this* deployment to the remote.
|
|
35
38
|
* a receiver that refuses the forwarder (or accepts no forwarded principal
|
|
36
39
|
* at all) rejects with 403 and the dispatch fails.
|
|
37
40
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ask}from"#execution/tool-run/messages.js";export{ask};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the `workflow` specifiers eve resolves to its vendored SDK. Ambient,
|
|
3
|
+
* so an installed `workflow` package takes precedence.
|
|
4
|
+
*/
|
|
5
|
+
declare module "workflow" {
|
|
6
|
+
export * from "#internal/workflow/index.js";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare module "workflow/api" {
|
|
10
|
+
export * from "#internal/workflow/runtime.js";
|
|
11
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function getRuntimeActionRequestKey(e){switch(e.kind){case`load-skill`:return`runtime-action:${e.kind}:${e.callId}`;case`remote-agent-call`:return`subagent-call:${e.remoteAgentName}:${e.callId}`;case`subagent-call`:return`subagent-call:${e.subagentName}:${e.callId}`;case`tool-call`:return`tool-call:${e.toolName}:${e.callId}`}}function getPendingDispatchActionKey(e){switch(e.target.kind){case`remote-agent-call`:return`subagent-call:${e.target.remoteAgentName}:${e.callId}`;case`self-agent-call`:case`subagent-call`:return`subagent-call:${e.target.subagentName}:${e.callId}`;case`task-cancel`:case`task-update`:return`tool-call:${e.toolName}:${e.callId}`;default:return e.target}}function getRuntimeActionResultKey(e){switch(e.kind){case`load-skill-result`:return`runtime-action:load-skill:${e.callId}`;case`subagent-result`:return`subagent-call:${e.subagentName}:${e.callId}`;case`tool-result`:return`tool-call:${e.toolName}:${e.callId}`}}export{getPendingDispatchActionKey,getRuntimeActionRequestKey,getRuntimeActionResultKey};
|
|
1
|
+
function getRuntimeActionRequestKey(e){switch(e.kind){case`load-skill`:return`runtime-action:${e.kind}:${e.callId}`;case`remote-agent-call`:return`subagent-call:${e.remoteAgentName}:${e.callId}`;case`subagent-call`:return`subagent-call:${e.subagentName}:${e.callId}`;case`tool-call`:return`tool-call:${e.toolName}:${e.callId}`}}function getPendingDispatchActionKey(e){switch(e.target.kind){case`remote-agent-call`:return`subagent-call:${e.target.remoteAgentName}:${e.callId}`;case`self-agent-call`:case`subagent-call`:return`subagent-call:${e.target.subagentName}:${e.callId}`;case`task-cancel`:case`task-update`:case`workflow-tool-call`:return`tool-call:${e.toolName}:${e.callId}`;default:return e.target}}function getRuntimeActionResultKey(e){switch(e.kind){case`load-skill-result`:return`runtime-action:load-skill:${e.callId}`;case`subagent-result`:return`subagent-call:${e.subagentName}:${e.callId}`;case`tool-result`:return`tool-call:${e.toolName}:${e.callId}`}}export{getPendingDispatchActionKey,getRuntimeActionRequestKey,getRuntimeActionResultKey};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{serializeInputSchema,serializeOutputSchema}from"#tools/schema.js";import{RuntimeRegistry}from"#internal/runtime-registry.js";async function createRuntimeToolRegistry(e,t={}){let r=[],i=new RuntimeRegistry(`tool`,t.reservedToolNames??[]);for(let n of e.tools){let e=await createPreparedRuntimeTool(n,t.nodeId);i.register(n.name,{definition:n,prepared:e},{location:{logicalPath:n.logicalPath,sourceId:n.sourceId},duplicateMessage:`Found multiple authored tools named "${n.name}". Tool names must be unique at runtime.`,reservedMessage:`Tool "${n.name}" collides with another runtime-visible tool name.`}),r.push(e)}return{preparedTools:r,toolsByName:i.asMap()}}function findRegisteredRuntimeTool(e,t){return e.toolsByName.get(t)??null}async function createPreparedRuntimeTool(n,r){return{behavior:prepareToolBehavior(n.behavior,r),description:n.description,inputSchema:serializeInputSchema(n.inputSchema),kind:`authored-tool`,logicalPath:n.logicalPath,name:n.name,owner:n.owner,outputSchema:serializeOutputSchema(n.outputSchema),sourceId:n.sourceId}}function prepareToolBehavior(e,t){if(e===void 0)return;if(e.handling===void 0)return{availability:e.availability,presentation:e.presentation};if(e.handling.kind!==`dispatch`)return{...e,handling:e.handling};let n;switch(e.handling.action){case`self-agent`:if(t===void 0)throw Error(`The self-agent tool requires a concrete runtime node id.`);n={kind:`self-agent-call`,nodeId:t,subagentName:`agent`};break;case`task-cancel`:n={kind:`task-cancel`};break;case`task-update`:n={kind:`task-update`};break;default:return e.handling.action}return{...e,handling:{kind:`dispatch`,target:n}}}export{createRuntimeToolRegistry,findRegisteredRuntimeTool};
|
|
1
|
+
import{serializeInputSchema,serializeOutputSchema}from"#tools/schema.js";import{RuntimeRegistry}from"#internal/runtime-registry.js";async function createRuntimeToolRegistry(e,t={}){let r=[],i=new RuntimeRegistry(`tool`,t.reservedToolNames??[]);for(let n of e.tools){let e=await createPreparedRuntimeTool(n,t.nodeId);i.register(n.name,{definition:n,prepared:e},{location:{logicalPath:n.logicalPath,sourceId:n.sourceId},duplicateMessage:`Found multiple authored tools named "${n.name}". Tool names must be unique at runtime.`,reservedMessage:`Tool "${n.name}" collides with another runtime-visible tool name.`}),r.push(e)}return{preparedTools:r,toolsByName:i.asMap()}}function findRegisteredRuntimeTool(e,t){return e.toolsByName.get(t)??null}async function createPreparedRuntimeTool(n,r){return{behavior:prepareToolBehavior(n.behavior,r),description:n.description,inputSchema:serializeInputSchema(n.inputSchema),kind:`authored-tool`,logicalPath:n.logicalPath,name:n.name,owner:n.owner,outputSchema:serializeOutputSchema(n.outputSchema),sourceId:n.sourceId}}function prepareToolBehavior(e,t){if(e===void 0)return;if(e.handling===void 0)return{availability:e.availability,presentation:e.presentation};if(e.handling.kind===`workflow-tool`)return{...e,handling:{kind:`dispatch`,target:{kind:`workflow-tool-call`,workflowId:e.handling.workflowId}}};if(e.handling.kind!==`dispatch`)return{...e,handling:e.handling};let n;switch(e.handling.action){case`self-agent`:if(t===void 0)throw Error(`The self-agent tool requires a concrete runtime node id.`);n={kind:`self-agent-call`,nodeId:t,subagentName:`agent`};break;case`task-cancel`:n={kind:`task-cancel`};break;case`task-update`:n={kind:`task-update`};break;default:return e.handling.action}return{...e,handling:{kind:`dispatch`,target:n}}}export{createRuntimeToolRegistry,findRegisteredRuntimeTool};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ChannelSetupLog } from "#setup/cli/index.js";
|
|
2
2
|
import type { Prompter } from "#setup/prompter.js";
|
|
3
3
|
import { type VercelProjectReference } from "#setup/project-resolution.js";
|
|
4
|
+
export type ConnectPrincipalType = "app" | "user";
|
|
4
5
|
/** Controls connector selection while adding a Connect-backed connection. */
|
|
5
6
|
export interface SetupConnectionConnectorOptions {
|
|
6
7
|
log: ChannelSetupLog;
|
|
@@ -10,6 +11,7 @@ export interface SetupConnectionConnectorOptions {
|
|
|
10
11
|
service: string;
|
|
11
12
|
creationType?: string;
|
|
12
13
|
connectionMethod?: "mcp" | "oauth";
|
|
14
|
+
principalType?: ConnectPrincipalType;
|
|
13
15
|
canonicalConnectorName: string;
|
|
14
16
|
project: VercelProjectReference;
|
|
15
17
|
signal?: AbortSignal;
|
|
@@ -28,8 +30,8 @@ export type SetupConnectionConnectorResult = {
|
|
|
28
30
|
connectorUid: string;
|
|
29
31
|
connectorId: string;
|
|
30
32
|
};
|
|
31
|
-
/** Parses a created connector that can issue
|
|
32
|
-
export declare function parseCreatedConnector(stdout: string): ConnectConnectorRef | undefined;
|
|
33
|
+
/** Parses a created connector that can issue credentials for the requested principal type. */
|
|
34
|
+
export declare function parseCreatedConnector(stdout: string, principalType?: ConnectPrincipalType): ConnectConnectorRef | undefined;
|
|
33
35
|
/** Removes a connector created by this setup attempt. */
|
|
34
36
|
export declare function cleanupCreatedConnectionConnector(input: {
|
|
35
37
|
log: ChannelSetupLog;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import{readProjectLink}from"#setup/project-resolution.js";import{captureVercel,runVercel,runVercelCaptureStdout}from"#setup/primitives/run-vercel.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";const CREATED_CONNECTOR=/\bConnector created:\s*(scl_[A-Za-z0-9_-]+)\b/u;function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function parseJson(e){try{return JSON.parse(e)}catch{return}}function connectorCreationFailure(e,t){let n=t?.split(`
|
|
2
|
-
`).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`Vercel CLI `)).at(-1);return n===void 0?`Could not create the ${e} connector.`:`Could not create the ${e} connector. Vercel returned: ${n}`}function parseConnectorRef(e){if(!isRecord(e)||typeof e.uid!=`string`||typeof e.id!=`string`)return;let t={uid:e.uid,id:e.id};return typeof e.name==`string`&&(t.name=e.name),t}function parseCreatedConnector(e){let
|
|
3
|
-
`))?.[1],
|
|
2
|
+
`).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`Vercel CLI `)).at(-1);return n===void 0?`Could not create the ${e} connector.`:`Could not create the ${e} connector. Vercel returned: ${n}`}function parseConnectorRef(e){if(!isRecord(e)||typeof e.uid!=`string`||typeof e.id!=`string`)return;let t={uid:e.uid,id:e.id};return typeof e.name==`string`&&(t.name=e.name),t}function parseCreatedConnector(e,t=`user`){let n=parseJson(e),r=parseConnectorRef(n);if(!isRecord(n)||r===void 0)return;let i=n.supportedSubjectTypes;return Array.isArray(i)&&i.includes(t)?r:void 0}function parseConnectorList(e,t){let n=[];for(let r of e){if(!isRecord(r)||typeof r.service==`string`&&r.service!==t)continue;let e=parseConnectorRef(r);e!==void 0&&n.push(e)}return n}function parseConnectorListPage(e,t){if(!isRecord(e)||!Array.isArray(e.connectors))return;let n=typeof e.cursor==`string`?e.cursor:void 0;return n===void 0?{connectors:parseConnectorList(e.connectors,t)}:{connectors:parseConnectorList(e.connectors,t),cursor:n}}async function listConnectors(e,n,r){let i=[],a=new Set,o;do{let s=[`connect`,`list`,`-F`,`json`,`--all-projects`,`--service`,e.service,`--scope`,n.orgId];o!==void 0&&s.push(`--next`,o);let c=await captureVercel(s,{cwd:e.projectRoot,onOutput:r,signal:e.signal});if(!c.ok)throw Error(c.failure.message);let l=parseConnectorListPage(parseJson(c.stdout),e.service);if(l===void 0)throw Error(`Vercel returned an invalid connector list for ${e.service}.`);i.push(...l.connectors);let u=l.cursor;if(u!==void 0&&a.has(u))throw Error(`The connector list repeated cursor ${u}.`);u!==void 0&&a.add(u),o=u}while(o!==void 0);return i}async function supportsPrincipalType(e,n,r,i){let a=await captureVercel([`api`,`/v1/connect/connectors/${encodeURIComponent(r.id)}`,`--scope`,n.orgId,`--raw`],{cwd:e.projectRoot,onOutput:i,signal:e.signal});if(!a.ok)throw Error(`Could not verify connector ${r.uid}.`);let o=parseJson(a.stdout);if(!isRecord(o)||o.id!==r.id||o.uid!==r.uid||typeof o.service==`string`&&o.service!==e.service)throw Error(`Vercel returned invalid details for connector ${r.uid}.`);let s=o.supportedSubjectTypes;return Array.isArray(s)&&s.includes(e.principalType??`user`)}function connectorNames(e){let t=new Set;for(let n of e){n.name!==void 0&&t.add(n.name.toLowerCase());let e=n.uid.slice(n.uid.lastIndexOf(`/`)+1).trim();e.length>0&&t.add(e.toLowerCase())}return t}function connectorMatchesCanonicalName(e,t){let n=t.toLowerCase();return e.name?.toLowerCase()===n||e.uid.slice(e.uid.lastIndexOf(`/`)+1).trim().toLowerCase()===n}function nextConnectorName(e,t){if(!t.has(e.toLowerCase()))return e;let n=2;for(;t.has(`${e}-${n}`.toLowerCase());)n+=1;return`${e}-${n}`}async function cleanupCreatedConnectionConnector(t){let r=t.orgId??(await readProjectLink(t.projectRoot))?.orgId,a=[`connect`,`remove`,t.connectorId,`--disconnect-all`,`--yes`];if(r!==void 0&&a.push(`--scope`,r),!await runVercel(a,{cwd:t.projectRoot,onOutput:createPromptCommandOutput(t.log)}))throw Error(`Could not remove connector ${t.connectorId}; run \`vercel connect remove ${t.connectorId} --disconnect-all --yes\`.`)}async function attach(e,t,r,i){return runVercel([`connect`,`attach`,r,`--yes`,`--scope`,t.orgId],{cwd:e.projectRoot,onOutput:i,signal:e.signal})}async function resolveFallbackConnector(e,t,n,i,s){let c=e.principalType??`user`,l=s;for(;;){if(await e.prompter.select({message:`Which connector should ${e.slug} use?`,hintLayout:`inline`,notices:[{tone:`warning`,text:l}],options:[{value:`find`,label:`Find a new one`,hint:`Browse existing connectors`},{value:`create`,label:`Create a new one`,hint:`Register another connector`}]})===`find`){let r=[];for(let a of i)await supportsPrincipalType(e,t,a,n)&&r.push(a);if(r.length===0){l=`No existing ${e.service} connectors support ${c} credentials.`;continue}let a=new Map(r.map(e=>[e.uid,e])),o=await e.prompter.select({message:`Select a connector for ${e.slug}`,hintLayout:`inline`,search:!0,placeholder:`type to search connectors`,options:r.map(e=>({value:e.uid,label:e.uid,hint:e.name??e.id}))}),s=a.get(o);if(s===void 0)throw Error(`Connector ${o} is no longer available.`);return{kind:`existing`,connector:s}}let s=connectorNames(i),u=(await e.prompter.text({message:`New connector name`,defaultValue:nextConnectorName(e.slug,s),validate:e=>{let t=e.trim().toLowerCase();return t.length===0?`A name is required.`:s.has(t)?`A connector with this name already exists.`:void 0}})).trim(),d=[],createOutput=e=>{d.push(e.text),n(e)},f=await withPhase(e.log,`Waiting for you to complete setup in the browser…`,()=>runVercelCaptureStdout([`connect`,`create`,e.creationType??e.service,`--name`,u,...e.connectionMethod===void 0?[]:[`--connection-method`,e.connectionMethod],`-F`,`json`,`--scope`,t.orgId],{cwd:e.projectRoot,onOutput:createOutput,signal:e.signal}),{kind:`external-action`,emphasis:`browser`}),p=parseConnectorRef(parseJson(f.stdout))?.id??CREATED_CONNECTOR.exec(d.join(`
|
|
3
|
+
`))?.[1],m=f.ok?parseCreatedConnector(f.stdout,c):void 0;if(m!==void 0)return{kind:`created`,connector:m};let h=f.ok?`The ${e.service} connector does not support ${c} credentials.`:connectorCreationFailure(e.service,f.stderr);if(p!==void 0){try{await cleanupCreatedConnectionConnector({log:e.log,projectRoot:e.projectRoot,connectorId:p,orgId:t.orgId})}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`${h} ${t}`)}e.signal?.throwIfAborted()}throw Error(h)}}async function setupConnectionConnector(e){let t=e.principalType??`user`,n=createPromptCommandOutput(e.log),r=e.project,a=await listConnectors(e,r,n),o=a.find(t=>connectorMatchesCanonicalName(t,e.canonicalConnectorName)),s=`Could not find a connector named ${e.canonicalConnectorName}.`;if(o!==void 0)if(await supportsPrincipalType(e,r,o,n)){if(await attach(e,r,o.uid,n))return e.log.success(`Attached ${o.uid} connector`),{kind:`existing`,connectorUid:o.uid};e.signal?.throwIfAborted(),s=`Could not attach ${o.uid}.`}else s=`${o.uid} does not support ${t} credentials.`;let c=await resolveFallbackConnector(e,r,n,a,s);if(!await attach(e,r,c.connector.uid,n)){if(c.kind===`created`){let t=`Could not attach ${c.connector.uid} to the linked project.`;try{await cleanupCreatedConnectionConnector({log:e.log,projectRoot:e.projectRoot,connectorId:c.connector.id,orgId:r.orgId})}catch(e){let n=e instanceof Error?e.message:String(e);throw Error(`${t} ${n}`)}throw e.signal?.throwIfAborted(),Error(t)}throw Error(`Could not attach ${c.connector.uid} to the linked project.`)}return e.log.success(`Attached ${c.connector.uid} connector`),c.kind===`created`?{kind:`created`,connectorUid:c.connector.uid,connectorId:c.connector.id}:{kind:`existing`,connectorUid:c.connector.uid}}export{cleanupCreatedConnectionConnector,parseCreatedConnector,setupConnectionConnector};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{withSpinner}from"../with-spinner.js";import{runVercel}from"#setup/primitives/run-vercel.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{createPromptCommandOutput}from"#setup/cli/index.js";const defaultDeps={getVercelAuthStatus,runVercelLogin:({cwd:e,onOutput:n,signal:r})=>runVercel([`login`],{cwd:e,nonInteractive:!0,onOutput:n,timeoutMs:3e5,signal:r})};async function runVercelLoginWithControls(t,n,r,i,a){if(i.awaitChoice===void 0)return withSpinner(i,`Opening Vercel login in your browser…`,()=>t.runVercelLogin({cwd:n,onOutput:r,signal:a}));let o=new AbortController,s=a?AbortSignal.any([a,o.signal]):o.signal,c=i.awaitChoice({status:`Logging in to Vercel…`,context:`Complete the login in your browser`,actions:[{value:`cancel`,label:`Cancel`}]}),l=t.runVercelLogin({cwd:n,onOutput:r,signal:s});try{let e=await Promise.race([l.then(e=>({via:`work`,ok:e})),c.choice.then(()=>({via:`choice`}))]);return e.via===`work`?e.ok:(o.abort(),await l.catch(()=>{}),`cancelled`)}finally{c.close()}}async function runLoginFlow(t){let{appRoot:n,prompter:a,signal:o}=t,s={...defaultDeps,...t.deps},c=createPromptCommandOutput(a.log),probeAuth=()=>s.getVercelAuthStatus(n,{signal:o}),
|
|
1
|
+
import{withSpinner}from"../with-spinner.js";import{runVercel}from"#setup/primitives/run-vercel.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";import{createPromptCommandOutput}from"#setup/cli/index.js";function vercelLoginUrl(e){return e.match(/https:\/\/vercel\.com\/oauth\/device\?[^\s]+/u)?.[0]}const defaultDeps={getVercelAuthStatus,runVercelLogin:({cwd:e,onOutput:n,signal:r})=>runVercel([`login`],{cwd:e,nonInteractive:!0,onOutput:n,timeoutMs:3e5,signal:r})};async function runVercelLoginWithControls(t,n,r,i,a){if(i.awaitChoice===void 0)return withSpinner(i,`Opening Vercel login in your browser…`,()=>t.runVercelLogin({cwd:n,onOutput:r,signal:a}));let o=new AbortController,s=a?AbortSignal.any([a,o.signal]):o.signal,c=i.awaitChoice({status:`Logging in to Vercel…`,context:`Complete the login in your browser`,actions:[{value:`cancel`,label:`Cancel`}]}),l=t.runVercelLogin({cwd:n,onOutput:r,signal:s});try{let e=await Promise.race([l.then(e=>({via:`work`,ok:e})),c.choice.then(()=>({via:`choice`}))]);return e.via===`work`?e.ok:(o.abort(),await l.catch(()=>{}),`cancelled`)}finally{c.close()}}async function runLoginFlow(t){let{appRoot:n,prompter:a,signal:o}=t,s={...defaultDeps,...t.deps},c=createPromptCommandOutput(a.log),l,onOutput=e=>{c(e);let t=vercelLoginUrl(e.text);t!==void 0&&t!==l&&(l=t,a.log.info(`Open ${t}`))},probeAuth=()=>s.getVercelAuthStatus(n,{signal:o}),u=await withSpinner(a,`Checking your Vercel login…`,probeAuth);switch(o?.throwIfAborted(),u){case`authenticated`:if(t.force!==!0)return{kind:`already`};break;case`cli-missing`:return{kind:`cli-missing`};case`unavailable`:return{kind:`unavailable`};case`logged-out`:break;default:return u}let d=await runVercelLoginWithControls(s,n,onOutput,a,o);if(d===`cancelled`)return{kind:`cancelled`};if(!d)return{kind:`failed`};let f=await withSpinner(a,`Confirming your Vercel login…`,probeAuth);switch(o?.throwIfAborted(),f){case`authenticated`:return{kind:`logged-in`};case`logged-out`:return{kind:`failed`};case`cli-missing`:return{kind:`cli-missing`};case`unavailable`:return{kind:`unavailable`};default:return f}}export{runLoginFlow};
|