experimental-ash 0.27.0 → 0.28.1
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 +20 -0
- package/dist/docs/internals/hooks.md +1 -1
- package/dist/docs/public/channels/README.md +50 -2
- package/dist/docs/public/channels/discord.md +15 -7
- package/dist/docs/public/channels/teams.md +121 -0
- package/dist/docs/public/channels/telegram.md +201 -0
- package/dist/docs/public/typescript-api.md +41 -1
- package/dist/src/channel/adapter.js +1 -1
- package/dist/src/channel/compiled-channel.js +1 -1
- package/dist/src/channel/http.js +1 -1
- package/dist/src/channel/schedule.js +1 -1
- package/dist/src/channel/send.js +1 -1
- package/dist/src/channel/session-callback.js +1 -1
- package/dist/src/channel/session.js +1 -1
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/dev/environment.js +1 -1
- package/dist/src/cli/dev/input-requests.js +1 -1
- package/dist/src/cli/dev/repl.js +1 -1
- package/dist/src/cli/dev/terminal.js +1 -1
- package/dist/src/cli/dev/url.js +1 -1
- package/dist/src/compiler/artifacts.js +1 -1
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/model-catalog.js +1 -1
- package/dist/src/compiler/module-map.js +1 -1
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/compiler/remote-agent-node.js +1 -1
- package/dist/src/compiler/workspace-resources.js +1 -1
- package/dist/src/context/accessors.js +1 -1
- package/dist/src/context/container.js +1 -1
- package/dist/src/context/hook-lifecycle.d.ts +3 -3
- package/dist/src/context/hook-lifecycle.js +1 -1
- package/dist/src/context/key.js +1 -1
- package/dist/src/context/keys.d.ts +31 -10
- package/dist/src/context/keys.js +1 -1
- package/dist/src/context/node.js +1 -1
- package/dist/src/context/providers/connection.js +1 -1
- package/dist/src/context/providers/sandbox.js +1 -1
- package/dist/src/context/providers/session.js +1 -1
- package/dist/src/context/run-step.js +1 -1
- package/dist/src/context/serialize.js +1 -1
- package/dist/src/discover/connections.js +1 -1
- package/dist/src/discover/diagnostics.js +1 -1
- package/dist/src/discover/discover-subagent.js +1 -1
- package/dist/src/discover/filesystem.js +1 -1
- package/dist/src/discover/grammar.js +1 -1
- package/dist/src/discover/lib.js +1 -1
- package/dist/src/discover/manifest.js +1 -1
- package/dist/src/discover/sandbox.js +1 -1
- package/dist/src/discover/schedules.js +1 -1
- package/dist/src/discover/skills.js +1 -1
- package/dist/src/evals/runner/discover.js +1 -1
- package/dist/src/evals/runner/execute-suite.js +1 -1
- package/dist/src/evals/runner/reporters/braintrust.js +1 -1
- package/dist/src/evals/scores/index.js +1 -1
- package/dist/src/execution/await-authorization-orchestrator.js +1 -1
- package/dist/src/execution/connection-auth-steps.js +1 -1
- package/dist/src/execution/runtime-context.d.ts +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/sandbox/bindings/local.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/sandbox/glob-tool.js +1 -1
- package/dist/src/execution/sandbox/grep-tool.js +1 -1
- package/dist/src/execution/sandbox/read-file-tool.js +1 -1
- package/dist/src/execution/sandbox/require-sandbox.js +1 -1
- package/dist/src/execution/sandbox/ripgrep-probe.js +1 -1
- package/dist/src/execution/sandbox/truncate-output.js +1 -1
- package/dist/src/execution/session-callback-step.js +1 -1
- package/dist/src/execution/session.js +1 -1
- package/dist/src/execution/subagent-adapter.js +1 -1
- package/dist/src/execution/tool-compaction.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/web-fetch/html.js +1 -1
- package/dist/src/execution/web-fetch/tool.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/compaction.js +2 -2
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/input-requests.js +1 -1
- package/dist/src/harness/instrumentation-config.js +1 -1
- package/dist/src/harness/model-call-error.js +1 -1
- package/dist/src/harness/otel-integration.js +1 -1
- package/dist/src/harness/prompt-cache.js +1 -1
- package/dist/src/harness/provider-tools.js +1 -1
- package/dist/src/harness/proxy-input-requests.js +1 -1
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/step-hooks.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/tool-result-pruning.js +1 -1
- package/dist/src/internal/application/cache-metadata.js +1 -1
- package/dist/src/internal/application/compiled-artifacts.js +1 -1
- package/dist/src/internal/application/import-specifier.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/attachments/refs.js +1 -1
- package/dist/src/internal/attachments/sandbox-refs.js +1 -1
- package/dist/src/internal/attachments/url-refs.js +1 -1
- package/dist/src/internal/authored-asset-import-plugin.js +1 -1
- package/dist/src/internal/authored-definition/connection.js +1 -1
- package/dist/src/internal/authored-module-loader.js +1 -1
- package/dist/src/internal/authored-package-tsconfig-paths.js +1 -1
- package/dist/src/internal/bundler/nitro-rolldown.js +1 -1
- package/dist/src/internal/helpers/markdown.js +2 -2
- package/dist/src/internal/json-schema.js +1 -1
- package/dist/src/internal/logging.js +1 -1
- package/dist/src/internal/nitro/host/channel-routes.js +1 -1
- package/dist/src/internal/nitro/host/compiled-sandbox-backend-prune-plugin.js +1 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
- package/dist/src/internal/nitro/host/schedule-task-routes.js +1 -1
- package/dist/src/internal/nitro/host/server-external-packages.js +1 -1
- package/dist/src/internal/nitro/host/start-development-server.js +1 -1
- package/dist/src/internal/nitro/routes/index.js +3 -3
- package/dist/src/internal/nitro/routes/workflow-route-helpers.js +1 -1
- package/dist/src/internal/node-esm-compat-banner.js +1 -1
- package/dist/src/internal/package-name.js +1 -1
- package/dist/src/internal/vercel-agent-summary.js +1 -1
- package/dist/src/internal/workflow-bundle/ash-service-route-output.js +1 -1
- package/dist/src/internal/workflow-bundle/builder-support.js +1 -1
- package/dist/src/internal/workflow-bundle/builder.js +2 -2
- package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-transformer.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/ajv.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/code.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/index.js +2 -2
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/scope.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/errors.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/index.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/names.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/ref_error.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/resolve.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/rules.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/util.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/boolSchema.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/dataType.js +2 -2
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/defaults.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/index.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/keyword.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/subschema.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/core.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/equal.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/uri.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/allOf.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/contains.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/dependencies.js +2 -2
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/if.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/index.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/items.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/items2020.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/not.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/oneOf.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/properties.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/thenElse.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/code.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/index.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/ref.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/discriminator/index.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/draft7.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/format/format.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/const.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/enum.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/index.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitItems.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitLength.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitNumber.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitProperties.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/multipleOf.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/pattern.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/required.js +1 -1
- package/dist/src/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js +1 -1
- package/dist/src/node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/index.js +1 -1
- package/dist/src/node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/schemes.js +1 -1
- package/dist/src/node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/utils.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/_vendor/partial-json-parser/parser.js +2 -2
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/auth/workload-identity-auth.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/azure.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/client.js +2 -2
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/detect-platform.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/errors.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/headers.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/qs/formats.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/qs/stringify.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/qs/utils.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/request-options.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/to-file.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/uploads.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/utils/base64.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/utils/bytes.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/utils/env.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/utils/log.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/utils/path.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/utils/sleep.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/utils/uuid.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/internal/utils/values.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/lib/AbstractChatCompletionRunner.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/lib/Util.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/lib/chatCompletionUtils.js +1 -1
- package/dist/src/node_modules/.pnpm/openai@6.39.0_ws@8.21.0_zod@3.25.76/node_modules/openai/version.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/Options.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/Refs.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parseDef.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/date.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/string.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/union.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/selectParser.js +1 -1
- package/dist/src/node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js +1 -1
- package/dist/src/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js +1 -1
- package/dist/src/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js +1 -1
- package/dist/src/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js +1 -1
- package/dist/src/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js +1 -1
- package/dist/src/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js +1 -1
- package/dist/src/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js +1 -1
- package/dist/src/packages/ash-scaffold/src/channels.js +2 -2
- package/dist/src/packages/ash-scaffold/src/module-files.js +1 -1
- package/dist/src/protocol/message.js +1 -1
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/ash.js +2 -2
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/public/channels/discord/api.js +1 -1
- package/dist/src/public/channels/discord/defaults.js +1 -1
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/discord/hitl.js +1 -1
- package/dist/src/public/channels/discord/inbound.js +1 -1
- package/dist/src/public/channels/discord/verify.js +1 -1
- package/dist/src/public/channels/discord/verifyInbound.js +1 -1
- package/dist/src/public/channels/slack/api.js +1 -1
- package/dist/src/public/channels/slack/attachments.js +1 -1
- package/dist/src/public/channels/slack/constants.js +1 -1
- package/dist/src/public/channels/slack/defaults.js +2 -2
- package/dist/src/public/channels/slack/hitl.js +1 -1
- package/dist/src/public/channels/slack/interactions.js +1 -1
- package/dist/src/public/channels/slack/limits.js +1 -1
- package/dist/src/public/channels/slack/mrkdwn.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/slack/verify.js +1 -1
- package/dist/src/public/channels/teams/api.d.ts +140 -0
- package/dist/src/public/channels/teams/api.js +4 -0
- package/dist/src/public/channels/teams/attachments.d.ts +25 -0
- package/dist/src/public/channels/teams/attachments.js +1 -0
- package/dist/src/public/channels/teams/defaults.d.ts +24 -0
- package/dist/src/public/channels/teams/defaults.js +3 -0
- package/dist/src/public/channels/teams/hitl.d.ts +36 -0
- package/dist/src/public/channels/teams/hitl.js +1 -0
- package/dist/src/public/channels/teams/inbound.d.ts +80 -0
- package/dist/src/public/channels/teams/inbound.js +3 -0
- package/dist/src/public/channels/teams/index.d.ts +8 -0
- package/dist/src/public/channels/teams/index.js +1 -0
- package/dist/src/public/channels/teams/limits.d.ts +8 -0
- package/dist/src/public/channels/teams/limits.js +1 -0
- package/dist/src/public/channels/teams/teamsChannel.d.ts +162 -0
- package/dist/src/public/channels/teams/teamsChannel.js +1 -0
- package/dist/src/public/channels/teams/verify.d.ts +43 -0
- package/dist/src/public/channels/teams/verify.js +1 -0
- package/dist/src/public/channels/telegram/api.d.ts +107 -0
- package/dist/src/public/channels/telegram/api.js +2 -0
- package/dist/src/public/channels/telegram/attachments.d.ts +23 -0
- package/dist/src/public/channels/telegram/attachments.js +1 -0
- package/dist/src/public/channels/telegram/defaults.d.ts +9 -0
- package/dist/src/public/channels/telegram/defaults.js +3 -0
- package/dist/src/public/channels/telegram/hitl.d.ts +44 -0
- package/dist/src/public/channels/telegram/hitl.js +1 -0
- package/dist/src/public/channels/telegram/inbound.d.ts +88 -0
- package/dist/src/public/channels/telegram/inbound.js +2 -0
- package/dist/src/public/channels/telegram/index.d.ts +8 -0
- package/dist/src/public/channels/telegram/index.js +1 -0
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +126 -0
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -0
- package/dist/src/public/channels/telegram/verify.d.ts +30 -0
- package/dist/src/public/channels/telegram/verify.js +1 -0
- package/dist/src/public/channels/twilio/defaults.js +1 -1
- package/dist/src/public/channels/twilio/inbound.js +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/channels/twilio/verify.js +1 -1
- package/dist/src/public/channels/upload-policy.js +1 -1
- package/dist/src/public/definitions/channel.js +1 -1
- package/dist/src/public/definitions/tool.js +1 -1
- package/dist/src/public/next/index.js +1 -1
- package/dist/src/public/next/server.js +1 -1
- package/dist/src/public/next/vercel-json.js +1 -1
- package/dist/src/public/tool-result-narrowing.js +1 -1
- package/dist/src/public/tools/defaults.js +1 -1
- package/dist/src/react/use-ash-agent.js +1 -1
- package/dist/src/runtime/actions/types.js +1 -1
- package/dist/src/runtime/agent/bootstrap-model-utils.js +1 -1
- package/dist/src/runtime/agent/bootstrap-model.js +1 -1
- package/dist/src/runtime/agent/bootstrap.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
- package/dist/src/runtime/channels/registry.js +1 -1
- package/dist/src/runtime/connections/authorization-tokens.js +1 -1
- package/dist/src/runtime/connections/callback-route.js +1 -1
- package/dist/src/runtime/connections/principal-context.js +1 -1
- package/dist/src/runtime/connections/principal.js +1 -1
- package/dist/src/runtime/framework-channels/index.js +1 -1
- package/dist/src/runtime/framework-tools/ask-question.js +1 -1
- package/dist/src/runtime/framework-tools/bash.js +1 -1
- package/dist/src/runtime/framework-tools/connection-search.js +1 -1
- package/dist/src/runtime/framework-tools/file-state.js +1 -1
- package/dist/src/runtime/framework-tools/glob.js +1 -1
- package/dist/src/runtime/framework-tools/grep.js +1 -1
- package/dist/src/runtime/framework-tools/index.js +1 -1
- package/dist/src/runtime/framework-tools/pending-connection-tool-calls.js +1 -1
- package/dist/src/runtime/framework-tools/read-file.js +1 -1
- package/dist/src/runtime/framework-tools/skill.js +1 -1
- package/dist/src/runtime/framework-tools/todo.js +2 -2
- package/dist/src/runtime/framework-tools/web-fetch.js +1 -1
- package/dist/src/runtime/framework-tools/web-search.js +1 -1
- package/dist/src/runtime/framework-tools/write-file.js +1 -1
- package/dist/src/runtime/governance/auth/jwt-ecdsa.js +1 -1
- package/dist/src/runtime/governance/auth/oidc.js +1 -1
- package/dist/src/runtime/governance/auth/token-claims.js +1 -1
- package/dist/src/runtime/graph.js +1 -1
- package/dist/src/runtime/input/types.js +1 -1
- package/dist/src/runtime/loaders/compile-metadata.js +1 -1
- package/dist/src/runtime/loaders/manifest.js +1 -1
- package/dist/src/runtime/loaders/module-map.js +1 -1
- package/dist/src/runtime/prompt/compose.js +2 -2
- package/dist/src/runtime/prompt/connections.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/resolve-hook.js +1 -1
- package/dist/src/runtime/sandbox/keys.js +1 -1
- package/dist/src/runtime/sandbox/registry.js +1 -1
- package/dist/src/runtime/schedules/register.js +1 -1
- package/dist/src/runtime/session-callback-route.js +1 -1
- package/dist/src/runtime/sessions/auth.js +1 -1
- package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
- package/dist/src/runtime/sessions/runtime-context-keys.d.ts +11 -0
- package/dist/src/runtime/sessions/runtime-context-keys.js +1 -0
- package/dist/src/runtime/sessions/runtime-session.js +1 -1
- package/dist/src/runtime/skills/fragment-context.js +1 -1
- package/dist/src/runtime/skills/sandbox-access.js +1 -1
- package/dist/src/runtime/subagents/registry.js +1 -1
- package/dist/src/runtime/workspace/types.js +1 -1
- package/dist/src/services/dev-client/request-headers.js +1 -1
- package/dist/src/services/dev-client/vercel-auth-error.js +1 -1
- package/dist/src/shared/json-schemas.js +1 -1
- package/dist/src/shared/json.js +1 -1
- package/dist/src/shared/skill-package.js +1 -1
- package/package.json +11 -1
- package/dist/src/context/seed-keys.d.ts +0 -39
- package/dist/src/context/seed-keys.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# experimental-ash
|
|
2
2
|
|
|
3
|
+
## 0.28.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9be5b5c: Fix `TypeError: Cannot read properties of undefined (reading 'name')` thrown from `resolveRuntimeAgentNode` on Vercel deployments by splitting `#context/keys.ts` along its layering seam and dropping the rolldown setting that hid the bug.
|
|
8
|
+
|
|
9
|
+
A static-import cycle through `BundleKey.codec` (`#context/keys` → `#runtime/sessions/compiled-agent-cache` → `#runtime/resolve-agent-graph` → `#runtime/framework-tools/index` → `#runtime/framework-tools/bash` → `#execution/sandbox/bash-tool` → `#execution/sandbox/require-sandbox` → `#context/keys`) interacted badly with the rolldown build's `topLevelVar: true` setting. When Nitro re-bundled ash's dist into a single concatenated `_libs/experimental-ash.mjs` for a Vercel function, it could land `var BASH_TOOL_DEFINITION = {...}` _after_ the `ALL_FRAMEWORK_TOOLS` array that referenced it. `var` hoisting then silently filled the slot with `undefined` (no TDZ `ReferenceError`), and every downstream `.map(t => t.name)` over that array crashed inside `resolveRuntimeAgentNode`.
|
|
10
|
+
|
|
11
|
+
The structural fix: `#context/keys.ts` was doing two unrelated jobs in one file. The leaf job (declaring `SandboxKey`, `SessionKey`, etc.) is widely imported across the codebase. The heavy job (owning the `ChannelKey` and `BundleKey` codecs that materialize values by calling back into the runtime) drags in the entire runtime layer. Because JS evaluates modules whole, every leaf caller was paying the heavy job's transitive import cost, which is how the cycle got seeded.
|
|
12
|
+
|
|
13
|
+
- Split `#context/keys.ts` into two files. `#context/keys.ts` now only declares leaf context keys (no codec, no runtime imports — safe to import from any tier). `#runtime/sessions/runtime-context-keys.ts` owns `ChannelKey`, `BundleKey`, and `CompiledBundle` next to the modules whose state they carry.
|
|
14
|
+
- Drop `topLevelVar: true` from `packages/ash/scripts/build-rolldown.mjs`. The setting was masking module-evaluation cycles; with `let`/`const` they now surface as a loud `ReferenceError` at module load instead of silent `undefined` reads.
|
|
15
|
+
|
|
16
|
+
## 0.28.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- 2e8ebcb: Add a native Microsoft Teams channel backed by the Bot Framework Activity and Connector protocols, including inbound verification, Teams conversation state, Adaptive Card HITL, proactive receive support, docs, tests, and smoke coverage.
|
|
21
|
+
- 70018bd: Add a native Telegram channel for verified Bot API webhooks, Telegram delivery, HITL interactions, attachments, and proactive sessions.
|
|
22
|
+
|
|
3
23
|
## 0.27.0
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
|
@@ -129,7 +129,7 @@ catches them and emits the recoverable `turn.failed` cascade.
|
|
|
129
129
|
|
|
130
130
|
## `SessionPreparedKey`
|
|
131
131
|
|
|
132
|
-
Lives in `src/context/
|
|
132
|
+
Lives in `src/context/keys.ts`. JSON-safe boolean, no codec. Set
|
|
133
133
|
**before** the `lifecycle.session` chain runs so a thrown hook leaves
|
|
134
134
|
the flag set — the next turn does not retry. Compaction does not clear
|
|
135
135
|
the flag.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Channels"
|
|
3
|
-
description: "Deliver your agent over HTTP, Slack, Discord, Twilio, and custom transports."
|
|
3
|
+
description: "Deliver your agent over HTTP, Slack, Discord, Twilio, Telegram, Microsoft Teams, and custom transports."
|
|
4
4
|
url: /channels
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -23,7 +23,7 @@ Ash ships the public HTTP protocol as channels:
|
|
|
23
23
|
- `ashChannel({ auth })` for the built-in Ash protocol channel
|
|
24
24
|
|
|
25
25
|
Ash also supports authored channels under `agent/channels/` for platform-specific integrations such
|
|
26
|
-
as Slack, Discord, Twilio, or custom webhooks.
|
|
26
|
+
as Slack, Discord, Twilio, Telegram, Microsoft Teams, or custom webhooks.
|
|
27
27
|
|
|
28
28
|
## Filesystem Shape
|
|
29
29
|
|
|
@@ -279,6 +279,53 @@ resolver when the allowed phone numbers come from dynamic state. Use `allowFrom:
|
|
|
279
279
|
|
|
280
280
|
See [Twilio channel setup](./twilio.md) for webhook URLs, environment variables, and overrides.
|
|
281
281
|
|
|
282
|
+
## Telegram Channels
|
|
283
|
+
|
|
284
|
+
Telegram channels are authored with `telegramChannel()`:
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
import { telegramChannel } from "experimental-ash/channels/telegram";
|
|
288
|
+
|
|
289
|
+
export default telegramChannel({
|
|
290
|
+
botUsername: "my_bot",
|
|
291
|
+
});
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
The channel verifies Telegram's `X-Telegram-Bot-Api-Secret-Token` webhook header, accepts updates at
|
|
295
|
+
`/ash/v1/telegram`, dispatches private messages and addressed group messages, and resolves HITL
|
|
296
|
+
inline-keyboard callbacks and ForceReply answers back into Ash input responses. Private chats use
|
|
297
|
+
chat-wide continuation tokens. Group, supergroup, and forum-topic sessions include the chat id,
|
|
298
|
+
optional `message_thread_id`, and a conversation anchor so multiple bot conversations in the same
|
|
299
|
+
chat do not collapse.
|
|
300
|
+
|
|
301
|
+
Default delivery sends plain text through Telegram `sendMessage` with no `parse_mode`, splits text
|
|
302
|
+
at Telegram's 4096-character limit, and uses best-effort `sendChatAction("typing")` progress
|
|
303
|
+
indicators. Photos and documents are exposed as file parts and fetched through Telegram `getFile`
|
|
304
|
+
when the model needs the bytes.
|
|
305
|
+
|
|
306
|
+
See [Telegram channel setup](./telegram.md) for webhook registration, environment variables, group
|
|
307
|
+
privacy notes, HITL behavior, attachments, and proactive sessions.
|
|
308
|
+
|
|
309
|
+
## Microsoft Teams Channels
|
|
310
|
+
|
|
311
|
+
Teams channels are authored with `teamsChannel()`:
|
|
312
|
+
|
|
313
|
+
```ts
|
|
314
|
+
import { teamsChannel } from "experimental-ash/channels/teams";
|
|
315
|
+
|
|
316
|
+
export default teamsChannel();
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
The channel verifies Bot Connector bearer JWTs, accepts Teams Bot Framework Activity POSTs at
|
|
320
|
+
`/ash/v1/teams`, dispatches personal messages and direct bot mentions, renders HITL prompts as
|
|
321
|
+
Adaptive Cards, and sends agent replies through the Bot Framework Connector REST API. Personal chats
|
|
322
|
+
resume by conversation id; channel and group-chat threads resume by conversation id plus root
|
|
323
|
+
activity id.
|
|
324
|
+
|
|
325
|
+
Proactive `receive(teams, args)` sessions require an existing conversation reference
|
|
326
|
+
(`serviceUrl` and `conversationId`). See [Microsoft Teams channel setup](./teams.md) for Azure Bot
|
|
327
|
+
setup, environment variables, proactive handoff, HITL, and file options.
|
|
328
|
+
|
|
282
329
|
## Cross-Channel Hand-off
|
|
283
330
|
|
|
284
331
|
Route handlers can start a session on a different channel via `args.receive(channel, ...)`.
|
|
@@ -472,6 +519,7 @@ See [Channel file uploads](./attachments.md) for the full guide.
|
|
|
472
519
|
## What To Read Next
|
|
473
520
|
|
|
474
521
|
- [Slack channel setup](./slack.md)
|
|
522
|
+
- [Telegram channel setup](./telegram.md)
|
|
475
523
|
- [Channel file uploads](./attachments.md)
|
|
476
524
|
- [Project Layout](../project-layout.md)
|
|
477
525
|
- [TypeScript API](../typescript-api.md)
|
|
@@ -132,19 +132,27 @@ Component and modal submissions resume the parked Ash session automatically.
|
|
|
132
132
|
|
|
133
133
|
## Proactive Sessions
|
|
134
134
|
|
|
135
|
-
Use `receive(discord, args)` from
|
|
135
|
+
Use `receive(discord, { message, args, auth })` from a schedule `run` handler, or
|
|
136
|
+
`args.receive(discord, ...)` from another channel, to start a Discord session:
|
|
136
137
|
|
|
137
138
|
```ts
|
|
138
|
-
import { defineSchedule
|
|
139
|
+
import { defineSchedule } from "experimental-ash/schedules";
|
|
139
140
|
import discord from "../channels/discord.js";
|
|
140
141
|
|
|
141
142
|
export default defineSchedule({
|
|
142
143
|
cron: "0 9 * * 1-5",
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
async run({ receive, waitUntil, appAuth }) {
|
|
145
|
+
waitUntil(
|
|
146
|
+
receive(discord, {
|
|
147
|
+
message: "Post the daily summary.",
|
|
148
|
+
args: {
|
|
149
|
+
channelId: "123456789012345678",
|
|
150
|
+
initialMessage: "Daily summary",
|
|
151
|
+
},
|
|
152
|
+
auth: appAuth,
|
|
153
|
+
}),
|
|
154
|
+
);
|
|
155
|
+
},
|
|
148
156
|
});
|
|
149
157
|
```
|
|
150
158
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Microsoft Teams channel setup"
|
|
3
|
+
description: "Create a Microsoft Teams-backed Ash channel with the Bot Framework Activity protocol."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Microsoft Teams Channel Setup
|
|
7
|
+
|
|
8
|
+
The Teams channel accepts Bot Framework Activity POSTs from Microsoft Teams, verifies Bot
|
|
9
|
+
Connector bearer JWTs, dispatches message activities to Ash, renders HITL prompts as Adaptive
|
|
10
|
+
Cards, and delivers agent responses through the Bot Framework Connector REST API.
|
|
11
|
+
|
|
12
|
+
## Add The Channel
|
|
13
|
+
|
|
14
|
+
Create `agent/channels/teams.ts`:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { teamsChannel } from "experimental-ash/channels/teams";
|
|
18
|
+
|
|
19
|
+
export default teamsChannel();
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Set the credentials Ash needs:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
MICROSOFT_APP_ID=...
|
|
26
|
+
MICROSOFT_APP_PASSWORD=...
|
|
27
|
+
# Optional for single-tenant bots:
|
|
28
|
+
MICROSOFT_TENANT_ID=...
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
By default, the channel mounts `POST /ash/v1/teams`. Configure your Azure Bot or Teams app
|
|
32
|
+
messaging endpoint to that public URL.
|
|
33
|
+
|
|
34
|
+
Use `route` when the bot endpoint needs a different path:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
export default teamsChannel({
|
|
38
|
+
route: "/api/teams/activity",
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Message Dispatch
|
|
43
|
+
|
|
44
|
+
The default `onMessage` behavior dispatches personal-chat messages and channel/group-chat messages
|
|
45
|
+
that directly mention the bot. Ambient messages delivered through Teams resource-specific consent
|
|
46
|
+
are parsed but ignored unless you override `onMessage`.
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { teamsChannel, defaultTeamsAuth } from "experimental-ash/channels/teams";
|
|
50
|
+
|
|
51
|
+
export default teamsChannel({
|
|
52
|
+
onMessage(ctx, message) {
|
|
53
|
+
if (message.scope !== "personal" && !message.isBotMentioned) return null;
|
|
54
|
+
return { auth: defaultTeamsAuth(message) };
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Ash strips the bot mention from channel/group prompts, adds a compact `<teams_context>` block, and
|
|
60
|
+
keeps personal chats scoped to one Ash session per Teams conversation. Channel and group-chat
|
|
61
|
+
threads are scoped by the root activity id (`replyToId ?? id`).
|
|
62
|
+
|
|
63
|
+
## Delivery And HITL
|
|
64
|
+
|
|
65
|
+
Default delivery posts Markdown messages with `textFormat: "markdown"`, splits oversized text, and
|
|
66
|
+
sends typing indicators on turn start and action requests. `input.requested` renders Adaptive Cards:
|
|
67
|
+
buttons/options use `Action.Submit`, select requests use `Input.ChoiceSet`, and freeform requests
|
|
68
|
+
use `Input.Text`.
|
|
69
|
+
|
|
70
|
+
Adaptive Card submit activities are converted into Ash `inputResponses` automatically. Non-HITL
|
|
71
|
+
invoke activities can be handled with `onInvoke(ctx, activity)`.
|
|
72
|
+
|
|
73
|
+
## Proactive Sessions
|
|
74
|
+
|
|
75
|
+
Use `receive(teams, args)` only when you already have a Teams conversation reference. Teams v1 does
|
|
76
|
+
not create new chats by AAD user id.
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { defineSchedule, receive } from "experimental-ash/schedules";
|
|
80
|
+
import teams from "../channels/teams.js";
|
|
81
|
+
|
|
82
|
+
export default defineSchedule({
|
|
83
|
+
cron: "0 9 * * 1-5",
|
|
84
|
+
markdown: "Post the daily summary.",
|
|
85
|
+
channel: receive(teams, {
|
|
86
|
+
serviceUrl: "https://smba.trafficmanager.net/teams",
|
|
87
|
+
conversationId: "19:...",
|
|
88
|
+
conversationType: "channel",
|
|
89
|
+
tenantId: "tenant-id",
|
|
90
|
+
initialMessage: "Daily summary",
|
|
91
|
+
}),
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
For channel/group-chat proactive sessions without `replyToActivityId`, the first posted message
|
|
96
|
+
becomes the thread anchor and the channel re-keys the Ash continuation token to that activity id.
|
|
97
|
+
|
|
98
|
+
## Files
|
|
99
|
+
|
|
100
|
+
Text support is enabled by default. Inbound file parts are opt-in:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
export default teamsChannel({
|
|
104
|
+
files: {
|
|
105
|
+
enabled: true,
|
|
106
|
+
allowedHosts: ["contoso.sharepoint.com"],
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This covers personal-scope Teams file download attachments and simple public media URLs. Graph-based
|
|
112
|
+
channel file retrieval and outbound file-consent upload are intentionally outside v1.
|
|
113
|
+
|
|
114
|
+
## Teams References
|
|
115
|
+
|
|
116
|
+
- [Teams conversational bots](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/build-conversational-capability)
|
|
117
|
+
- [Teams channel and group chat bot conversations](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-and-group-conversations)
|
|
118
|
+
- [Bot Connector authentication](https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-connector-authentication?view=azure-bot-service-4.0)
|
|
119
|
+
- [Bot Connector REST API reference](https://learn.microsoft.com/sr-latn-rs/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0)
|
|
120
|
+
- [Teams proactive messages](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages)
|
|
121
|
+
- [Teams card actions](https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-actions)
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Telegram channel setup"
|
|
3
|
+
description: "Create a Telegram-backed Ash channel for bot webhooks, replies, HITL, and attachments."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Telegram Channel Setup
|
|
7
|
+
|
|
8
|
+
The Telegram channel accepts Telegram Bot API webhooks. It verifies Telegram's
|
|
9
|
+
`X-Telegram-Bot-Api-Secret-Token` header before parsing the update, dispatches private messages and
|
|
10
|
+
addressed group messages, and sends default replies through `sendMessage`.
|
|
11
|
+
|
|
12
|
+
## Add The Channel
|
|
13
|
+
|
|
14
|
+
Create `agent/channels/telegram.ts`:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { telegramChannel } from "experimental-ash/channels/telegram";
|
|
18
|
+
|
|
19
|
+
export default telegramChannel({
|
|
20
|
+
botUsername: "my_bot",
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Set the credentials Ash needs for inbound verification and outbound replies:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
TELEGRAM_BOT_TOKEN=123456:...
|
|
28
|
+
TELEGRAM_WEBHOOK_SECRET_TOKEN=...
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- `TELEGRAM_BOT_TOKEN` sends replies, typing indicators, callback acknowledgements, and proactive
|
|
32
|
+
messages.
|
|
33
|
+
- `TELEGRAM_WEBHOOK_SECRET_TOKEN` must match the `secret_token` value you register with Telegram's
|
|
34
|
+
`setWebhook`.
|
|
35
|
+
|
|
36
|
+
You can also pass the same values in config:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
export default telegramChannel({
|
|
40
|
+
botUsername: "my_bot",
|
|
41
|
+
credentials: {
|
|
42
|
+
botToken: process.env.TELEGRAM_BOT_TOKEN,
|
|
43
|
+
webhookSecretToken: process.env.TELEGRAM_WEBHOOK_SECRET_TOKEN,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
By default, the channel mounts `POST /ash/v1/telegram`.
|
|
49
|
+
|
|
50
|
+
## Register The Webhook
|
|
51
|
+
|
|
52
|
+
Register the deployed public URL with Telegram's Bot API:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/setWebhook" \
|
|
56
|
+
-H "Content-Type: application/json" \
|
|
57
|
+
-d '{
|
|
58
|
+
"url": "https://your-app.example.com/ash/v1/telegram",
|
|
59
|
+
"secret_token": "'"$TELEGRAM_WEBHOOK_SECRET_TOKEN"'",
|
|
60
|
+
"allowed_updates": ["message", "callback_query"]
|
|
61
|
+
}'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Webhook setup is external to Ash; the runtime does not call `setWebhook` for you.
|
|
65
|
+
|
|
66
|
+
## Message Dispatch
|
|
67
|
+
|
|
68
|
+
Private chats dispatch normal text, captions, photos, and documents by default. The default
|
|
69
|
+
`onMessage` derives Telegram user auth, starts a typing indicator, and returns `{ auth }`.
|
|
70
|
+
|
|
71
|
+
Groups and supergroups are gated more narrowly:
|
|
72
|
+
|
|
73
|
+
- bot commands dispatch, including `/ask` and `/ask@my_bot`
|
|
74
|
+
- `@my_bot` mentions dispatch when `botUsername` is configured
|
|
75
|
+
- replies to bot messages dispatch
|
|
76
|
+
- unaddressed group chatter is ignored
|
|
77
|
+
|
|
78
|
+
For Telegram forum topics, the channel includes `message_thread_id` in the continuation token and
|
|
79
|
+
outbound messages so separate topics do not collapse into one session.
|
|
80
|
+
|
|
81
|
+
Override `onMessage` when you need custom auth or additional filtering:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { telegramChannel } from "experimental-ash/channels/telegram";
|
|
85
|
+
|
|
86
|
+
export default telegramChannel({
|
|
87
|
+
botUsername: "my_bot",
|
|
88
|
+
onMessage(ctx, message) {
|
|
89
|
+
if (message.chat.type !== "private" && !message.text.includes("@my_bot")) return null;
|
|
90
|
+
return {
|
|
91
|
+
auth: {
|
|
92
|
+
authenticator: "telegram",
|
|
93
|
+
principalType: "user",
|
|
94
|
+
principalId: message.from?.id ?? message.chat.id,
|
|
95
|
+
attributes: {
|
|
96
|
+
chat_id: message.chat.id,
|
|
97
|
+
chat_type: message.chat.type,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Telegram group privacy is controlled by BotFather. With privacy mode enabled, Telegram only sends
|
|
106
|
+
commands, replies, and service messages to the bot. Disable privacy mode only if your bot should see
|
|
107
|
+
all group messages; Ash still applies the group dispatch gate above.
|
|
108
|
+
|
|
109
|
+
## Delivery
|
|
110
|
+
|
|
111
|
+
The default `"message.completed"` handler sends plain text with `sendMessage`. Ash does not set
|
|
112
|
+
`parse_mode`, so generated Markdown is delivered as literal text rather than being parsed by
|
|
113
|
+
Telegram. Messages longer than Telegram's 4096-character text limit are split into multiple
|
|
114
|
+
`sendMessage` calls.
|
|
115
|
+
|
|
116
|
+
Default progress handlers call `sendChatAction` with `typing`. Typing failures are logged and
|
|
117
|
+
swallowed because the indicator is only a UX hint.
|
|
118
|
+
|
|
119
|
+
Custom event handlers can use `ctx.telegram`:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
export default telegramChannel({
|
|
123
|
+
events: {
|
|
124
|
+
async "message.completed"(event, ctx) {
|
|
125
|
+
if (event.finishReason === "tool-calls" || !event.message) return;
|
|
126
|
+
await ctx.telegram.sendMessage(`Result:\n${event.message}`);
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Human Input
|
|
133
|
+
|
|
134
|
+
Pending Ash input requests render in Telegram:
|
|
135
|
+
|
|
136
|
+
- option requests render as inline keyboard buttons
|
|
137
|
+
- freeform requests render as `ForceReply` prompts
|
|
138
|
+
|
|
139
|
+
Telegram caps `callback_data` at 64 bytes, so Ash stores compact callback ids in durable channel
|
|
140
|
+
state and remaps them to the original Ash input response when the callback query arrives. Freeform
|
|
141
|
+
answers resume when the user replies to the specific prompt message.
|
|
142
|
+
|
|
143
|
+
Callback queries generated by Ash are acknowledged with `answerCallbackQuery` automatically. Other
|
|
144
|
+
callback queries are passed to `onCallbackQuery` when you provide one.
|
|
145
|
+
|
|
146
|
+
## Attachments
|
|
147
|
+
|
|
148
|
+
Inbound photos and documents become AI SDK file parts with internal `telegram-file:` URLs. When the
|
|
149
|
+
model needs the bytes, the channel calls Telegram `getFile`, downloads the file through the Bot API
|
|
150
|
+
file endpoint, and enforces the channel upload policy.
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
export default telegramChannel({
|
|
154
|
+
uploadPolicy: {
|
|
155
|
+
allowedMediaTypes: ["image/*", "application/pdf"],
|
|
156
|
+
maxBytes: 10 * 1024 * 1024,
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
V1 supports inbound photos and documents. Polling, inline mode, payments, business-account updates,
|
|
162
|
+
channel posts, stickers, and outbound sandbox-file sharing are not included.
|
|
163
|
+
|
|
164
|
+
## Proactive Sessions
|
|
165
|
+
|
|
166
|
+
Use `receive(telegram, { message, args, auth })` from a schedule `run` handler, or
|
|
167
|
+
`args.receive(telegram, ...)` from another channel, to start a Telegram session:
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import { defineSchedule } from "experimental-ash/schedules";
|
|
171
|
+
import telegram from "../channels/telegram.js";
|
|
172
|
+
|
|
173
|
+
export default defineSchedule({
|
|
174
|
+
cron: "0 9 * * 1-5",
|
|
175
|
+
async run({ receive, waitUntil, appAuth }) {
|
|
176
|
+
waitUntil(
|
|
177
|
+
receive(telegram, {
|
|
178
|
+
message: "Post the daily summary.",
|
|
179
|
+
args: {
|
|
180
|
+
chatId: "123456789",
|
|
181
|
+
initialMessage: "Daily summary",
|
|
182
|
+
},
|
|
183
|
+
auth: appAuth,
|
|
184
|
+
}),
|
|
185
|
+
);
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
`chatId` is required. Pass `messageThreadId` for forum topics. Pass `conversationId` to resume a
|
|
191
|
+
known group conversation, or `initialMessage` to post an anchor message first; those two options are
|
|
192
|
+
mutually exclusive.
|
|
193
|
+
|
|
194
|
+
## Telegram References
|
|
195
|
+
|
|
196
|
+
- [Telegram Bot API](https://core.telegram.org/bots/api)
|
|
197
|
+
- [setWebhook](https://core.telegram.org/bots/api#setwebhook)
|
|
198
|
+
- [sendMessage](https://core.telegram.org/bots/api#sendmessage)
|
|
199
|
+
- [sendChatAction](https://core.telegram.org/bots/api#sendchataction)
|
|
200
|
+
- [answerCallbackQuery](https://core.telegram.org/bots/api#answercallbackquery)
|
|
201
|
+
- [getFile](https://core.telegram.org/bots/api#getfile)
|
|
@@ -30,7 +30,9 @@ for `defineAgent`.
|
|
|
30
30
|
- `defineChannel(...)` - HTTP channel entrypoints in `channels/` with `routes`, `state`, `context()`, and typed event handlers (`experimental-ash/channels`)
|
|
31
31
|
- `defineHook(...)` - lifecycle and stream-event subscriber in `hooks/<slug>.ts` (`experimental-ash/hooks`)
|
|
32
32
|
- `defineSandbox(...)` - override the agent's single sandbox in `sandbox.ts` (or `sandbox/sandbox.ts` when paired with a `workspace/` folder) (`experimental-ash/sandbox`)
|
|
33
|
-
- `defineSchedule(...)` - recurring jobs in `schedules/<name>.ts` or `schedules/<name>.md`;
|
|
33
|
+
- `defineSchedule(...)` - recurring jobs in `schedules/<name>.ts` or `schedules/<name>.md`;
|
|
34
|
+
TypeScript schedules require `cron` and exactly one of `markdown` or `run`
|
|
35
|
+
(`experimental-ash/schedules`)
|
|
34
36
|
- `defineSkill(...)` - module-authored skills (`experimental-ash/skills`)
|
|
35
37
|
- `defineInstructions(...)` - module-authored instructions prompt (`experimental-ash/instructions`)
|
|
36
38
|
- `defineTool(...)` - typed executable integration in `tools/<name>.ts` (`experimental-ash/tools`)
|
|
@@ -109,6 +111,43 @@ Channel and Twilio types exported from `experimental-ash/channels/twilio`:
|
|
|
109
111
|
`confidence`, ...)
|
|
110
112
|
- `verifyTwilioRequest`, `signTwilioRequest` - Ash-owned Twilio webhook signature helpers
|
|
111
113
|
|
|
114
|
+
Channel and Telegram types exported from `experimental-ash/channels/telegram`:
|
|
115
|
+
|
|
116
|
+
- `telegramChannel` - Telegram Bot API webhook channel factory for messages, callback queries,
|
|
117
|
+
HITL, attachments, typing indicators, and proactive sessions
|
|
118
|
+
- `telegramContinuationToken` - helper for the channel-local raw token
|
|
119
|
+
(`chatId:messageThreadId:conversationId`)
|
|
120
|
+
- `TelegramChannelConfig` - config type for credentials, route, Bot API overrides, upload policy,
|
|
121
|
+
`botUsername`, hooks, and event handlers
|
|
122
|
+
- `TelegramContext` - pre-dispatch context for `onMessage` and `onCallbackQuery` (`telegram`)
|
|
123
|
+
- `TelegramEventContext` - event-handler context (`telegram`, `session`, plus mutable `state`)
|
|
124
|
+
- `TelegramHandle` - Telegram handle with `request()`, `post()`, `sendMessage()`,
|
|
125
|
+
`startTyping()`, `answerCallbackQuery()`, and `editMessageReplyMarkup()`
|
|
126
|
+
- `TelegramMessage` - parsed inbound message payload (`text`, `caption`, `chat`, `from`,
|
|
127
|
+
`attachments`, reply context, ...)
|
|
128
|
+
- `TelegramCallbackQuery` - parsed callback query payload passed to `onCallbackQuery`
|
|
129
|
+
- `TelegramAttachment` - parsed inbound photo or document metadata
|
|
130
|
+
- `TelegramReceiveArgs` - arguments accepted by proactive `receive(telegram, ...)`
|
|
131
|
+
- `verifyTelegramRequest` - Ash-owned webhook secret-token verification helper
|
|
132
|
+
|
|
133
|
+
Channel and Microsoft Teams types exported from `experimental-ash/channels/teams`:
|
|
134
|
+
|
|
135
|
+
- `teamsChannel` - Teams channel factory for Bot Framework Activity webhooks and Connector delivery
|
|
136
|
+
- `TeamsChannelConfig` - config type for credentials, route, event handlers, message/invoke hooks,
|
|
137
|
+
Adaptive Card version, and opt-in file handling
|
|
138
|
+
- `TeamsContext` - pre-dispatch context for `onMessage` and `onInvoke` (`thread`, `teams`)
|
|
139
|
+
- `TeamsEventContext` - event-handler context (`thread`, `teams`, mutable `state`)
|
|
140
|
+
- `TeamsHandle` - low-level Connector handle with `sendActivity`, `replyToActivity`,
|
|
141
|
+
`updateActivity`, `startTyping`, and `request`
|
|
142
|
+
- `TeamsThread` - conversation-scoped `post`, `update`, `startTyping`, and `mentionUser`
|
|
143
|
+
- `TeamsMessageActivity` / `TeamsInvokeActivity` - parsed inbound Activity payloads
|
|
144
|
+
- `TeamsReceiveArgs` - proactive/cross-channel handoff args requiring `serviceUrl` and
|
|
145
|
+
`conversationId`
|
|
146
|
+
- `teamsContinuationToken` - channel-local Teams continuation-token helper
|
|
147
|
+
- `defaultTeamsAuth` - default Teams actor-to-session-auth projection
|
|
148
|
+
- `verifyTeamsRequest`, `verifyTeamsJwt` - Ash-owned Bot Connector request/JWT verification helpers
|
|
149
|
+
- `sendTeamsActivity`, `replyToTeamsActivity`, `updateTeamsActivity` - Connector REST helpers
|
|
150
|
+
|
|
112
151
|
Channel types exported from `experimental-ash/channels`:
|
|
113
152
|
|
|
114
153
|
- `defineChannel` - channel primitive with `routes`, `state`, `context()`, and event handlers
|
|
@@ -138,6 +177,7 @@ import { defineChannel, POST, GET } from "experimental-ash/channels";
|
|
|
138
177
|
import { ashChannel } from "experimental-ash/channels/ash";
|
|
139
178
|
import { vercelOidc } from "experimental-ash/channels/auth";
|
|
140
179
|
import { slackChannel } from "experimental-ash/channels/slack";
|
|
180
|
+
import { telegramChannel } from "experimental-ash/channels/telegram";
|
|
141
181
|
```
|
|
142
182
|
|
|
143
183
|
Inside a route handler, the helpers object exposes:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";
|
|
1
|
+
import{createLogger}from"#internal/logging.js";const log=createLogger(`channel.adapter`);function defaultDeliverResult(e){if(e.message!==void 0)return{inputResponses:e.inputResponses,message:e.message,modelContext:e.modelContext};if(e.inputResponses!==void 0&&e.inputResponses.length>0)return{inputResponses:e.inputResponses,modelContext:e.modelContext};if(e.modelContext!==void 0&&e.modelContext.length>0)return{modelContext:e.modelContext}}function getAdapterKind(e){return e.kind}async function callAdapterEventHandler(e,t,n){let r=e[t.type];if(r===void 0)return t;try{await r(`data`in t?t.data:void 0,n)}catch(n){log.error(`adapter event handler threw — event swallowed`,{adapterKind:getAdapterKind(e),eventType:t.type,error:n})}return t}export{callAdapterEventHandler,defaultDeliverResult,getAdapterKind};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
const CHANNEL_SENTINEL=`ash:channel`;function isCompiledChannel(e){return typeof e==`object`&&!!e&&e.__kind===`ash:channel`}export{CHANNEL_SENTINEL,isCompiledChannel};
|
package/dist/src/channel/http.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
const HTTP_ADAPTER_KIND=`http`,HTTP_ADAPTER={kind:HTTP_ADAPTER_KIND};export{HTTP_ADAPTER,HTTP_ADAPTER_KIND};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createSession}from"#channel/session.js";import{createCrossChannelReceiveFn,toCrossChannelTargets}from"#channel/cross-channel-receive.js";import{expectFunction}from"#internal/authored-module.js";
|
|
1
|
+
import{createSession}from"#channel/session.js";import{createCrossChannelReceiveFn,toCrossChannelTargets}from"#channel/cross-channel-receive.js";import{expectFunction}from"#internal/authored-module.js";const SCHEDULE_APP_AUTH={attributes:{},authenticator:`app`,principalId:`ash:app`,principalType:`runtime`},SCHEDULE_ADAPTER_KIND=`schedule`,SCHEDULE_ADAPTER={kind:SCHEDULE_ADAPTER_KIND};var ScheduleDispatcher=class{runtime;channels;constructor(e){this.runtime=e.runtime,this.channels=e.channels}async trigger(e){let r=[],a=[],o=createCrossChannelReceiveFn(this.runtime,toCrossChannelTargets(this.channels)),s={appAuth:SCHEDULE_APP_AUTH,receive:async(e,t)=>{let n=await o(e,t);return r.push(n),n},waitUntil(e){a.push(e)}};if(e.run)await e.run(s);else if(e.markdown!==void 0){let t=await this.runMarkdown(e.markdown);r.push(t)}else throw Error(`Schedule "${e.scheduleId}" has neither "run" nor "markdown" — at least one must be set.`);return{sessions:r,waitUntilTasks:a}}async runMarkdown(t){let n=await this.runtime.run({adapter:SCHEDULE_ADAPTER,auth:SCHEDULE_APP_AUTH,input:{message:t},mode:`task`});return createSession(n.sessionId,n.continuationToken,this.runtime)}};function expectScheduleRun(e,t,n){let i=e;if(typeof i!=`object`||!i)throw Error(`Schedule export "${n??`default`}" from "${t}" must be an object.`);return expectFunction(i.run,`Expected the schedule export "${n??`default`}" from "${t}" to export a \`run\` handler function.`)}export{SCHEDULE_ADAPTER,SCHEDULE_ADAPTER_KIND,SCHEDULE_APP_AUTH,ScheduleDispatcher,expectScheduleRun};
|
package/dist/src/channel/send.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createSession}from"#channel/session.js";import{createErrorId,createLogger}from"#internal/logging.js";import{isRuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{serializeUrlFilePart}from"#internal/attachments/url-refs.js";import{toErrorMessage}from"#shared/errors.js";
|
|
1
|
+
import{createSession}from"#channel/session.js";import{createErrorId,createLogger}from"#internal/logging.js";import{isRuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{serializeUrlFilePart}from"#internal/attachments/url-refs.js";import{toErrorMessage}from"#shared/errors.js";const log=createLogger(`channel.send`);function createSendFn(n,r,i){return async(a,o)=>{let s=o.auth,c=o.callback,l=o.mode??`conversation`,u=o.state,d=o.continuationToken,f=`${i}:${d}`,{message:p,inputResponses:m,modelContext:h}=normalizeSendInput(a),g=serializeUrlFilePartsInMessage(p);try{let{sessionId:t}=await n.deliver({auth:s,continuationToken:f,payload:{inputResponses:m,message:g,modelContext:h}});return createSession(t,d,n)}catch(e){isRuntimeNoActiveSessionError(e)||log.warn(`deliver failed, falling back to starting a new session`,{continuationToken:f,errorId:createErrorId(),message:toErrorMessage(e)})}if(m&&m.length>0)throw Error(`Cannot deliver inputResponses — the target session was not found via continuation token.`);let _=u?{...r,state:{...r.state,...u}}:r;return createSession((await n.run({adapter:_,auth:s,capabilities:l===`conversation`?{requestInput:!0}:void 0,callback:c,continuationToken:f,input:{message:g??``,modelContext:h},mode:l})).sessionId,d,n)}}function serializeUrlFilePartsInMessage(e){if(e===void 0||typeof e==`string`)return e;let t=!1,n=e.map(e=>e.type===`file`&&e.data instanceof URL&&e.data.protocol!==`data:`?(t=!0,{...e,data:serializeUrlFilePart(e.data)}):e);return t?n:e}function normalizeSendInput(e){return typeof e==`string`||Array.isArray(e)?{message:e}:e}export{createSendFn};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";import{createAshCallbackRoutePath}from"#protocol/routes.js";
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{createAshCallbackRoutePath}from"#protocol/routes.js";const sessionCallbackSchema=z.object({callId:z.string().min(1),subagentName:z.string().min(1),token:z.string().min(1),url:z.string().min(1)}).strict().superRefine((e,t)=>{let n;try{n=new URL(e.url)}catch{t.addIssue({code:`custom`,message:`Callback url must be absolute.`,path:[`url`]});return}readCallbackUrlToken(n)!==e.token&&t.addIssue({code:`custom`,message:`Callback url token must match callback token.`,path:[`url`]})});function parseSessionCallback(e){let t=sessionCallbackSchema.safeParse(e);return t.success?{callback:t.data,ok:!0}:{cause:t.error,message:formatSessionCallbackParseError(t.error),ok:!1}}function readCallbackUrlToken(e){let n=createAshCallbackRoutePath(``);if(!e.pathname.startsWith(n))return null;let r=e.pathname.slice(n.length);if(r.length===0||r.includes(`/`))return null;try{return decodeURIComponent(r)}catch{return null}}function formatSessionCallbackParseError(e){return`Invalid callback metadata: ${e.issues.map(e=>`${e.path.length===0?`callback`:`callback.${e.path.join(`.`)}`}: ${e.message}`).join(`; `)}`}export{parseSessionCallback};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/
|
|
1
|
+
import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";function createSession(e,t,n){return{id:e,continuationToken:t,async getEventStream(t){return n.getEventStream(e,t)}}}function createGetSessionFn(e){return t=>createSession(t,``,e)}function buildSessionHandle(i){return{get id(){return i.get(SessionIdKey)??``},get continuationToken(){return i.get(ContinuationTokenKey)??``},get auth(){return i.get(AuthKey)??null},get initiatorAuth(){return i.get(InitiatorAuthKey)??null},setContinuationToken(e){let n=i.get(ContinuationTokenKey)??``,r=namespaceContinuationToken(n,e);n!==r&&i.set(ContinuationTokenKey,r)}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}export{buildSessionHandle,createGetSessionFn,createSession};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{isAshProject}from"../../packages/ash-scaffold/src/project.js";import{SLACK_CHANNEL_DEFAULT_ROUTE,ensureChannel,listAuthoredChannels}from"../../packages/ash-scaffold/src/channels.js";import"../../packages/ash-scaffold/src/index.js";import{relative}from"node:path";import{createInterface}from"node:readline/promises";
|
|
1
|
+
import{isAshProject}from"../../packages/ash-scaffold/src/project.js";import{SLACK_CHANNEL_DEFAULT_ROUTE,ensureChannel,listAuthoredChannels}from"../../packages/ash-scaffold/src/channels.js";import"../../packages/ash-scaffold/src/index.js";import{relative}from"node:path";import{createInterface}from"node:readline/promises";const NOT_AN_AGENT_MESSAGE="No Ash agent in this directory. Run `pnpm create experimental-ash-agent`, then run this command from inside the new project.",KNOWN_CHANNEL_KINDS=[`slack`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}async function promptChannelKind(){if(!process.stdin.isTTY||!process.stdout.isTTY)throw Error("Pass a channel kind: `ash channels add slack`.");let e=createInterface({input:process.stdin,output:process.stdout});try{let t=(await e.question(`Channel to add (slack): `)).trim();return t.length===0?`slack`:parseChannelKind(t)}finally{e.close()}}function renderSlackNextSteps(e){return[`Next steps:`,` pnpm i`,` vercel deploy --prod`,` # If Connect returns a different UID, use it below and in agent/channels/slack.ts.`,` vercel connect create slack --name ${e} --triggers`,` vercel connect detach slack/${e} --yes`,` vercel connect attach slack/${e} --triggers --trigger-path ${SLACK_CHANNEL_DEFAULT_ROUTE} --yes`].join(`
|
|
2
2
|
`)}function renderExistingSlackChannelNextSteps(e){return[`Next steps:`,` Review ${e} for the configured Slack connector UID.`,` Run Vercel Connect commands only for the UID already used by that file.`].join(`
|
|
3
3
|
`)}function formatProjectPath(e,t){let n=relative(e,t);return n.length===0||n.startsWith(`..`)?t:n}function logPackageJsonMutations(e,t,n){for(let r of n.packageJsonUpdated)e.log(`Updated ${formatProjectPath(t,r.path)} with ${r.dependencies.join(`, `)}.`)}function assertUnhandledChannelMutation(e){throw Error(`Unhandled channel mutation result: ${JSON.stringify(e)}`)}async function runChannelsAddCommand(t,r,i){if(!await isAshProject(r)){t.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{let e=i.kind===void 0?await promptChannelKind():parseChannelKind(i.kind),a=await ensureChannel({projectRoot:r,kind:e,force:i.options.force});switch(logPackageJsonMutations(t,r,a),a.action){case`created`:t.log(`Scaffolded channel: ${e}`),t.log(renderSlackNextSteps(a.slackConnectorSlug));break;case`overwritten`:t.log(`Overwrote channel: ${e}`),t.log(renderSlackNextSteps(a.slackConnectorSlug));break;case`skipped`:{let n=a.filesSkipped[0];t.log(`Channel "${e}" already exists; left existing files unchanged.`),t.log(renderExistingSlackChannelNextSteps(formatProjectPath(r,n)));break}default:assertUnhandledChannelMutation(a)}}catch(e){t.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}async function runChannelsListCommand(t,n,i){if(!await isAshProject(n)){t.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let a=await listAuthoredChannels(n);if(i.json){t.log(JSON.stringify({channels:a},null,2));return}if(a.length===0){t.log("No channels defined. Run `ash channels add slack` to add one.");return}for(let e of a)t.log(e)}export{runChannelsAddCommand,runChannelsListCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join,resolve}from"node:path";import{readFileSync}from"node:fs";import{parseEnv}from"node:util";import{isObject}from"#shared/guards.js";
|
|
1
|
+
import{join,resolve}from"node:path";import{readFileSync}from"node:fs";import{parseEnv}from"node:util";import{isObject}from"#shared/guards.js";const DEVELOPMENT_ENV_FILE_NAMES=[`.env.development.local`,`.env.local`,`.env.development`,`.env`];function isMissingEnvironmentFileError(e){return isObject(e)&&e.code===`ENOENT`}const developmentEnvironmentLoaders=new Map;function getDevelopmentEnvironmentFilePaths(n){let r=resolve(n);return DEVELOPMENT_ENV_FILE_NAMES.map(t=>join(r,t))}function loadDevelopmentEnvironmentFiles(e){getDevelopmentEnvironmentLoader(e).reload()}function getDevelopmentEnvironmentLoader(e){let n=resolve(e),r=developmentEnvironmentLoaders.get(n);if(r!==void 0)return r;let i=createDevelopmentEnvironmentLoader(n);return developmentEnvironmentLoaders.set(n,i),i}function createDevelopmentEnvironmentLoader(e){let t=new Set(Object.keys(process.env)),n=new Map;return{reload(){let r=readDevelopmentEnvironmentValues(e);for(let[e,i]of n)r.has(e)||t.has(e)||(process.env[e]===i&&delete process.env[e],n.delete(e));for(let[e,i]of r)t.has(e)||(process.env[e]=i,n.set(e,i))}}}function readDevelopmentEnvironmentValues(t){let i=new Map;for(let o of[...DEVELOPMENT_ENV_FILE_NAMES].reverse())try{let a=parseEnv(readFileSync(join(t,o),`utf8`));for(let[e,t]of Object.entries(a))t!==void 0&&i.set(e,t)}catch(e){if(!isMissingEnvironmentFileError(e))throw e}return i}export{DEVELOPMENT_ENV_FILE_NAMES,getDevelopmentEnvironmentFilePaths,loadDevelopmentEnvironmentFiles};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{renderCliTaggedLine}from"#cli/ui/output.js";import{resolveTextToResponse}from"#channel/resolve-text.js";
|
|
1
|
+
import{renderCliTaggedLine}from"#cli/ui/output.js";import{resolveTextToResponse}from"#channel/resolve-text.js";const ESCAPED_RUNTIME_INPUT_PROMPT=Symbol(`ash.cli.runtime-input.escaped`);function extractPendingRuntimeInputRequests(e){for(let t=e.length-1;t>=0;--t){let n=e[t];if(n?.type===`input.requested`)return n.data.requests}return[]}async function promptForRuntimeInputRequests(t){let n=[];t.print(renderCliTaggedLine(t.theme,{message:`pending input request${t.requests.length===1?``:`s`}: reply now, press Escape, or type "skip" to return to the normal prompt`,tag:`input`,tone:`info`}));for(let e of t.requests){let r=await promptForRuntimeInputRequest({ask:t.ask,print:t.print,request:e,theme:t.theme});if(r.kind!==`submitted`)return r;n.push(r.inputResponse)}return{inputResponses:n,kind:`submitted`}}function isApprovalRequest(e){return e.display===`confirmation`}async function promptForRuntimeInputRequest(e){return isApprovalRequest(e.request)?await promptForApprovalInputRequest({ask:e.ask,print:e.print,request:e.request,theme:e.theme}):await promptForQuestionInputRequest({ask:e.ask,print:e.print,request:e.request,theme:e.theme})}async function promptForApprovalInputRequest(t){for(t.print(renderCliTaggedLine(t.theme,{message:`approve tool "${t.request.action.toolName}"? (yes/no)`,tag:`approval`,tone:`warning`})),t.print(renderCliTaggedLine(t.theme,{message:JSON.stringify(t.request.action.input,null,2),tag:`tool`,tone:`muted`}));;){let r=await t.ask(`approval> `);if(r===void 0)return{kind:`aborted`};if(r===ESCAPED_RUNTIME_INPUT_PROMPT)return{kind:`deferred`};let i=r.trim().toLowerCase();if(i===`skip`||i===`/skip`)return{kind:`deferred`};if(i===`a`||i===`approve`||i===`y`||i===`yes`)return{inputResponse:{optionId:`approve`,requestId:t.request.requestId},kind:`submitted`};if(i===`d`||i===`deny`||i===`n`||i===`no`)return{inputResponse:{optionId:`deny`,requestId:t.request.requestId},kind:`submitted`};t.print(renderCliTaggedLine(t.theme,{message:`enter "yes" to approve, "no" to deny, press Escape, or type "skip" to return to the normal prompt`,tag:`input`,tone:`warning`}))}}async function promptForQuestionInputRequest(r){r.print(renderCliTaggedLine(r.theme,{message:r.request.prompt,tag:`question`,tone:`info`}));for(let[t,n]of(r.request.options??[]).entries())r.print(renderCliTaggedLine(r.theme,{message:`${t+1}. ${n.label}${n.description===void 0?``:` - ${n.description}`}`,tag:`option`,tone:`muted`}));let i=r.request.allowFreeform===!0||(r.request.options?.length??0)===0;for(;;){let a=await r.ask(`answer> `);if(a===void 0)return{kind:`aborted`};if(a===ESCAPED_RUNTIME_INPUT_PROMPT)return{kind:`deferred`};let o=a.trim();if(o===`skip`||o===`/skip`)return{kind:`deferred`};let s=resolveTextToResponse(o,r.request);if(s!==void 0)return{inputResponse:s,kind:`submitted`};r.print(renderCliTaggedLine(r.theme,{message:r.request.options===void 0||r.request.options.length===0?`enter a response, press Escape, or type "skip" to return to the normal prompt`:i?`enter an option number/id, freeform text, press Escape, or type "skip" to return to the normal prompt`:`enter an option number/id, press Escape, or type "skip" to return to the normal prompt`,tag:`input`,tone:`warning`}))}}export{ESCAPED_RUNTIME_INPUT_PROMPT,extractPendingRuntimeInputRequests,promptForRuntimeInputRequests};
|