@copilotkit/runtime 1.64.2-canary.1785380282 → 1.64.2-canary.1785417123
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.cjs +1 -1
- package/dist/runtime/package.mjs +1 -1
- package/dist/v2/runtime/core/channel-activation-config.cjs +1 -1
- package/dist/v2/runtime/core/channel-activation-config.cjs.map +1 -1
- package/dist/v2/runtime/core/channel-activation-config.mjs +1 -1
- package/dist/v2/runtime/core/channel-activation-config.mjs.map +1 -1
- package/dist/v2/runtime/core/channel-manager.cjs +36 -48
- package/dist/v2/runtime/core/channel-manager.cjs.map +1 -1
- package/dist/v2/runtime/core/channel-manager.d.cts +4 -5
- package/dist/v2/runtime/core/channel-manager.d.cts.map +1 -1
- package/dist/v2/runtime/core/channel-manager.d.mts +4 -5
- package/dist/v2/runtime/core/channel-manager.d.mts.map +1 -1
- package/dist/v2/runtime/core/channel-manager.mjs +36 -48
- package/dist/v2/runtime/core/channel-manager.mjs.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.cjs +1 -0
- package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.d.cts.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.d.mts.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.mjs +1 -0
- package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs +13 -0
- package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts +1 -0
- package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts +1 -0
- package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs +13 -0
- package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
- package/package.json +5 -5
package/dist/package.cjs
CHANGED
|
@@ -5,7 +5,7 @@ const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
|
5
5
|
var require_package = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
|
|
6
6
|
module.exports = {
|
|
7
7
|
"name": "@copilotkit/runtime",
|
|
8
|
-
"version": "1.64.2-canary.
|
|
8
|
+
"version": "1.64.2-canary.1785417123",
|
|
9
9
|
"private": false,
|
|
10
10
|
"keywords": [
|
|
11
11
|
"ai",
|
package/dist/runtime/package.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { __commonJSMin } from "../_virtual/_rolldown/runtime.mjs";
|
|
|
5
5
|
var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
6
6
|
module.exports = {
|
|
7
7
|
"name": "@copilotkit/runtime",
|
|
8
|
-
"version": "1.64.2-canary.
|
|
8
|
+
"version": "1.64.2-canary.1785417123",
|
|
9
9
|
"private": false,
|
|
10
10
|
"keywords": [
|
|
11
11
|
"ai",
|
|
@@ -72,7 +72,7 @@ function deriveChannelActivationConfig(args) {
|
|
|
72
72
|
const { intelligence, channel, runtimeInstanceId } = args;
|
|
73
73
|
if (!channel.name) throw new ChannelConfigError("Channel is missing a `name` — pass createChannel({ name }) to activate it.");
|
|
74
74
|
const channelName = channel.name;
|
|
75
|
-
const wsUrl = intelligence.ɵ
|
|
75
|
+
const wsUrl = intelligence.ɵgetChannelsWsUrl();
|
|
76
76
|
const apiUrl = intelligence.ɵgetApiUrl();
|
|
77
77
|
const apiKey = intelligence.ɵgetRunnerAuthToken();
|
|
78
78
|
const projectId = parseProjectIdFromApiKey(apiKey);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-activation-config.cjs","names":[],"sources":["../../../../src/v2/runtime/core/channel-activation-config.ts"],"sourcesContent":["import type { CopilotKitIntelligence } from \"../intelligence-platform\";\n// Type-only: @copilotkit/channels is pure-ESM, so a value import would break this\n// package's CJS output (see `runtime.ts` for the same constraint).\nimport type { Channel } from \"@copilotkit/channels\";\n\n/**\n * Error thrown when a Channel activation config cannot be derived — either the\n * Intelligence API key does not carry a project id in the expected\n * `cpk-{projectId}_...` format, or the {@link Channel} is missing a `name`.\n */\nexport class ChannelConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ChannelConfigError\";\n }\n}\n\n/**\n * Resolved configuration needed to activate a single Channel against a\n * running Intelligence runtime instance.\n */\nexport interface ChannelActivationConfig {\n /** Intelligence runner websocket URL the Channel connects to. */\n wsUrl: string;\n /** Intelligence API key used to authenticate the runner connection. */\n apiKey: string;\n /** Intelligence app-api HTTP base URL (`intelligence.ɵgetApiUrl()`), forwarded\n * to the transport so the managed realtime path enables file/history parity\n * (those are HTTP-only). Without it, Channels started by the normal runtime\n * handler run with no history and no file support (OSS-476). */\n apiUrl: string;\n /** Project id parsed from {@link apiKey}. */\n projectId: number;\n /** The Channel's declared name (`createChannel({ name })`). */\n channelName: string;\n /**\n * The managed provider this Channel declares to the Intelligence gateway on\n * join, resolved from the Channel's per-Channel `provider` (e.g. `\"slack\"` or\n * `\"teams\"`), defaulting to `\"slack\"`. Named `adapter` because that is the\n * field the gateway's join payload expects; the gateway resolves the actual\n * connection for the declared provider.\n */\n adapter: string;\n /**\n * Optional per-Channel override for visible managed tool-call progress.\n * Unset Slack routes default to hidden; other providers retain their existing\n * default.\n */\n showToolStatus?: boolean;\n /** Identifier for the runtime instance activating this Channel. */\n runtimeInstanceId: string;\n}\n\n/** Matches the `cpk-{projectId}_...` Intelligence API key format. */\nconst API_KEY_PROJECT_ID_PATTERN = /^cpk-(\\d+)_/;\n\n/**\n * Parse the project id embedded in an Intelligence API key.\n *\n * Intelligence API keys are formatted `cpk-{projectId}_{rest}` — this\n * extracts and numerically parses the `{projectId}` segment.\n *\n * @param apiKey - The Intelligence API key to parse.\n * @returns The parsed, strictly-positive, safe-integer project id.\n * @throws {ChannelConfigError} If `apiKey` does not match the expected\n * `cpk-{projectId}_...` format — a wrong/missing prefix or an absent project\n * id segment all fail the same match — or if the parsed project id is not a\n * strictly-positive safe integer.\n */\nexport function parseProjectIdFromApiKey(apiKey: string): number {\n const match = API_KEY_PROJECT_ID_PATTERN.exec(apiKey);\n if (!match) {\n // The whole API key is a `cpk-…` secret — everything after the fixed `cpk-`\n // namespace is sensitive, so a fixed-width slice (e.g. `apiKey.slice(0, 8)`)\n // would echo secret bytes for a `cpk-_short_long`-shaped key. This message is\n // logged and surfaced through `ready()`'s AggregateError, so echo NONE of the\n // key value; name only the expected format to aid diagnosis.\n throw new ChannelConfigError(\n `Could not parse a project id from the Intelligence API key — expected the ` +\n `\"cpk-{projectId}_...\" format (the key value is omitted here to avoid ` +\n `leaking secret material).`,\n );\n }\n const projectId = Number(match[1]);\n // Validate the parser's OWN output: `cpk-0_...` matches the pattern but a\n // non-positive project id would otherwise fail deep inside the launcher's\n // `assertValidChannelRealtimeScope` (which requires a positive projectId).\n // A very long digit run also matches `\\d+` but loses precision (or overflows\n // to Infinity) once coerced to `Number`, so it must be rejected too even\n // though it is `> 0` — `Number.isSafeInteger` catches both. This is the\n // parser guarding its own contract, not a channel-name replica, so it\n // belongs here. Reuse the same redaction: never echo the key value.\n if (!Number.isSafeInteger(projectId) || projectId <= 0) {\n throw new ChannelConfigError(\n `Parsed an invalid project id (${projectId}) from the Intelligence API ` +\n `key — the project id in \"cpk-{projectId}_...\" must be a positive safe ` +\n `integer (the key value is omitted here to avoid leaking secret material).`,\n );\n }\n return projectId;\n}\n\n/**\n * Derive the {@link ChannelActivationConfig} needed to activate `channel`\n * against the given Intelligence runtime configuration.\n *\n * @param args.intelligence - The Intelligence runtime client to pull the\n * runner websocket URL and auth token from.\n * @param args.channel - The Channel being activated. Must have a `name`; its\n * per-Channel `provider` selects the managed adapter declared to the gateway,\n * and `showToolStatus` optionally overrides managed tool-call visibility.\n * @param args.runtimeInstanceId - Identifier for the activating runtime\n * instance, passed through unchanged.\n * @returns The resolved {@link ChannelActivationConfig}.\n * @throws {ChannelConfigError} If the Intelligence API key does not carry a\n * parseable, strictly-positive project id, or if `channel.name` is\n * missing/empty.\n *\n * The managed provider is a PER-CHANNEL choice read from `channel.provider`, so\n * one runtime can activate a Slack-backed Channel and a Teams-backed Channel\n * side by side. When `channel.provider` is unset the config adapter defaults to\n * `\"slack\"` — an explicit, documented default, not a silent global. The SDK\n * only DECLARES this provider to the Intelligence gateway on join; the gateway\n * resolves the actual connection and is the authority on which providers it\n * accepts (it accepts only `\"slack\"` today — Teams gateway support is tracked\n * in OSS-450).\n *\n * The Channel-name FORMAT rules (lowercase kebab-case, 3–64 chars) and the\n * reserved-name rule are NOT re-checked here. Their single source of truth is\n * the `@copilotkit/channels-intelligence` launcher\n * (`assertValidChannelRealtimeScope` + `assertValidChannelNames`), which\n * validates them at activation; a malformed name surfaces as a logged `error`\n * status via {@link ChannelManager.ready} rather than an up-front throw. An\n * empty/missing name is still rejected here because that is this config's own\n * precondition (it has no name to forward at all), not a downstream replica.\n */\nexport function deriveChannelActivationConfig(args: {\n intelligence: CopilotKitIntelligence;\n channel: Channel;\n runtimeInstanceId: string;\n}): ChannelActivationConfig {\n const { intelligence, channel, runtimeInstanceId } = args;\n\n if (!channel.name) {\n throw new ChannelConfigError(\n \"Channel is missing a `name` — pass createChannel({ name }) to activate it.\",\n );\n }\n\n const channelName = channel.name;\n\n const wsUrl = intelligence.ɵ
|
|
1
|
+
{"version":3,"file":"channel-activation-config.cjs","names":[],"sources":["../../../../src/v2/runtime/core/channel-activation-config.ts"],"sourcesContent":["import type { CopilotKitIntelligence } from \"../intelligence-platform\";\n// Type-only: @copilotkit/channels is pure-ESM, so a value import would break this\n// package's CJS output (see `runtime.ts` for the same constraint).\nimport type { Channel } from \"@copilotkit/channels\";\n\n/**\n * Error thrown when a Channel activation config cannot be derived — either the\n * Intelligence API key does not carry a project id in the expected\n * `cpk-{projectId}_...` format, or the {@link Channel} is missing a `name`.\n */\nexport class ChannelConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ChannelConfigError\";\n }\n}\n\n/**\n * Resolved configuration needed to activate a single Channel against a\n * running Intelligence runtime instance.\n */\nexport interface ChannelActivationConfig {\n /** Intelligence runner websocket URL the Channel connects to. */\n wsUrl: string;\n /** Intelligence API key used to authenticate the runner connection. */\n apiKey: string;\n /** Intelligence app-api HTTP base URL (`intelligence.ɵgetApiUrl()`), forwarded\n * to the transport so the managed realtime path enables file/history parity\n * (those are HTTP-only). Without it, Channels started by the normal runtime\n * handler run with no history and no file support (OSS-476). */\n apiUrl: string;\n /** Project id parsed from {@link apiKey}. */\n projectId: number;\n /** The Channel's declared name (`createChannel({ name })`). */\n channelName: string;\n /**\n * The managed provider this Channel declares to the Intelligence gateway on\n * join, resolved from the Channel's per-Channel `provider` (e.g. `\"slack\"` or\n * `\"teams\"`), defaulting to `\"slack\"`. Named `adapter` because that is the\n * field the gateway's join payload expects; the gateway resolves the actual\n * connection for the declared provider.\n */\n adapter: string;\n /**\n * Optional per-Channel override for visible managed tool-call progress.\n * Unset Slack routes default to hidden; other providers retain their existing\n * default.\n */\n showToolStatus?: boolean;\n /** Identifier for the runtime instance activating this Channel. */\n runtimeInstanceId: string;\n}\n\n/** Matches the `cpk-{projectId}_...` Intelligence API key format. */\nconst API_KEY_PROJECT_ID_PATTERN = /^cpk-(\\d+)_/;\n\n/**\n * Parse the project id embedded in an Intelligence API key.\n *\n * Intelligence API keys are formatted `cpk-{projectId}_{rest}` — this\n * extracts and numerically parses the `{projectId}` segment.\n *\n * @param apiKey - The Intelligence API key to parse.\n * @returns The parsed, strictly-positive, safe-integer project id.\n * @throws {ChannelConfigError} If `apiKey` does not match the expected\n * `cpk-{projectId}_...` format — a wrong/missing prefix or an absent project\n * id segment all fail the same match — or if the parsed project id is not a\n * strictly-positive safe integer.\n */\nexport function parseProjectIdFromApiKey(apiKey: string): number {\n const match = API_KEY_PROJECT_ID_PATTERN.exec(apiKey);\n if (!match) {\n // The whole API key is a `cpk-…` secret — everything after the fixed `cpk-`\n // namespace is sensitive, so a fixed-width slice (e.g. `apiKey.slice(0, 8)`)\n // would echo secret bytes for a `cpk-_short_long`-shaped key. This message is\n // logged and surfaced through `ready()`'s AggregateError, so echo NONE of the\n // key value; name only the expected format to aid diagnosis.\n throw new ChannelConfigError(\n `Could not parse a project id from the Intelligence API key — expected the ` +\n `\"cpk-{projectId}_...\" format (the key value is omitted here to avoid ` +\n `leaking secret material).`,\n );\n }\n const projectId = Number(match[1]);\n // Validate the parser's OWN output: `cpk-0_...` matches the pattern but a\n // non-positive project id would otherwise fail deep inside the launcher's\n // `assertValidChannelRealtimeScope` (which requires a positive projectId).\n // A very long digit run also matches `\\d+` but loses precision (or overflows\n // to Infinity) once coerced to `Number`, so it must be rejected too even\n // though it is `> 0` — `Number.isSafeInteger` catches both. This is the\n // parser guarding its own contract, not a channel-name replica, so it\n // belongs here. Reuse the same redaction: never echo the key value.\n if (!Number.isSafeInteger(projectId) || projectId <= 0) {\n throw new ChannelConfigError(\n `Parsed an invalid project id (${projectId}) from the Intelligence API ` +\n `key — the project id in \"cpk-{projectId}_...\" must be a positive safe ` +\n `integer (the key value is omitted here to avoid leaking secret material).`,\n );\n }\n return projectId;\n}\n\n/**\n * Derive the {@link ChannelActivationConfig} needed to activate `channel`\n * against the given Intelligence runtime configuration.\n *\n * @param args.intelligence - The Intelligence runtime client to pull the\n * runner websocket URL and auth token from.\n * @param args.channel - The Channel being activated. Must have a `name`; its\n * per-Channel `provider` selects the managed adapter declared to the gateway,\n * and `showToolStatus` optionally overrides managed tool-call visibility.\n * @param args.runtimeInstanceId - Identifier for the activating runtime\n * instance, passed through unchanged.\n * @returns The resolved {@link ChannelActivationConfig}.\n * @throws {ChannelConfigError} If the Intelligence API key does not carry a\n * parseable, strictly-positive project id, or if `channel.name` is\n * missing/empty.\n *\n * The managed provider is a PER-CHANNEL choice read from `channel.provider`, so\n * one runtime can activate a Slack-backed Channel and a Teams-backed Channel\n * side by side. When `channel.provider` is unset the config adapter defaults to\n * `\"slack\"` — an explicit, documented default, not a silent global. The SDK\n * only DECLARES this provider to the Intelligence gateway on join; the gateway\n * resolves the actual connection and is the authority on which providers it\n * accepts (it accepts only `\"slack\"` today — Teams gateway support is tracked\n * in OSS-450).\n *\n * The Channel-name FORMAT rules (lowercase kebab-case, 3–64 chars) and the\n * reserved-name rule are NOT re-checked here. Their single source of truth is\n * the `@copilotkit/channels-intelligence` launcher\n * (`assertValidChannelRealtimeScope` + `assertValidChannelNames`), which\n * validates them at activation; a malformed name surfaces as a logged `error`\n * status via {@link ChannelManager.ready} rather than an up-front throw. An\n * empty/missing name is still rejected here because that is this config's own\n * precondition (it has no name to forward at all), not a downstream replica.\n */\nexport function deriveChannelActivationConfig(args: {\n intelligence: CopilotKitIntelligence;\n channel: Channel;\n runtimeInstanceId: string;\n}): ChannelActivationConfig {\n const { intelligence, channel, runtimeInstanceId } = args;\n\n if (!channel.name) {\n throw new ChannelConfigError(\n \"Channel is missing a `name` — pass createChannel({ name }) to activate it.\",\n );\n }\n\n const channelName = channel.name;\n\n const wsUrl = intelligence.ɵgetChannelsWsUrl();\n const apiUrl = intelligence.ɵgetApiUrl();\n const apiKey = intelligence.ɵgetRunnerAuthToken();\n const projectId = parseProjectIdFromApiKey(apiKey);\n\n // Resolve the managed adapter declared to the gateway from the Channel's OWN\n // `provider` — a per-Channel choice, not a manager-wide default. When\n // `provider` is unset the adapter is the documented default `\"slack\"`; set\n // `createChannel({ provider: \"teams\" })` to declare Teams instead. The value\n // is trimmed so a padded runtime value (one that bypassed the typed union)\n // resolves to its bare provider rather than being forwarded with whitespace,\n // and a blank/whitespace-only provider falls back to `\"slack\"` (`??` alone\n // would keep `\"\"`).\n const trimmedProvider = channel.provider?.trim();\n\n return {\n wsUrl,\n apiUrl,\n apiKey,\n projectId,\n channelName,\n adapter: trimmedProvider ? trimmedProvider : \"slack\",\n ...(channel.showToolStatus !== undefined\n ? { showToolStatus: channel.showToolStatus }\n : {}),\n runtimeInstanceId,\n };\n}\n"],"mappings":";;;;;;;;AAUA,IAAa,qBAAb,cAAwC,MAAM;CAC5C,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;AAyChB,MAAM,6BAA6B;;;;;;;;;;;;;;AAenC,SAAgB,yBAAyB,QAAwB;CAC/D,MAAM,QAAQ,2BAA2B,KAAK,OAAO;AACrD,KAAI,CAAC,MAMH,OAAM,IAAI,mBACR,6KAGD;CAEH,MAAM,YAAY,OAAO,MAAM,GAAG;AASlC,KAAI,CAAC,OAAO,cAAc,UAAU,IAAI,aAAa,EACnD,OAAM,IAAI,mBACR,iCAAiC,UAAU,6KAG5C;AAEH,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCT,SAAgB,8BAA8B,MAIlB;CAC1B,MAAM,EAAE,cAAc,SAAS,sBAAsB;AAErD,KAAI,CAAC,QAAQ,KACX,OAAM,IAAI,mBACR,6EACD;CAGH,MAAM,cAAc,QAAQ;CAE5B,MAAM,QAAQ,aAAa,mBAAmB;CAC9C,MAAM,SAAS,aAAa,YAAY;CACxC,MAAM,SAAS,aAAa,qBAAqB;CACjD,MAAM,YAAY,yBAAyB,OAAO;CAUlD,MAAM,kBAAkB,QAAQ,UAAU,MAAM;AAEhD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA,SAAS,kBAAkB,kBAAkB;EAC7C,GAAI,QAAQ,mBAAmB,SAC3B,EAAE,gBAAgB,QAAQ,gBAAgB,GAC1C,EAAE;EACN;EACD"}
|
|
@@ -71,7 +71,7 @@ function deriveChannelActivationConfig(args) {
|
|
|
71
71
|
const { intelligence, channel, runtimeInstanceId } = args;
|
|
72
72
|
if (!channel.name) throw new ChannelConfigError("Channel is missing a `name` — pass createChannel({ name }) to activate it.");
|
|
73
73
|
const channelName = channel.name;
|
|
74
|
-
const wsUrl = intelligence.ɵ
|
|
74
|
+
const wsUrl = intelligence.ɵgetChannelsWsUrl();
|
|
75
75
|
const apiUrl = intelligence.ɵgetApiUrl();
|
|
76
76
|
const apiKey = intelligence.ɵgetRunnerAuthToken();
|
|
77
77
|
const projectId = parseProjectIdFromApiKey(apiKey);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-activation-config.mjs","names":[],"sources":["../../../../src/v2/runtime/core/channel-activation-config.ts"],"sourcesContent":["import type { CopilotKitIntelligence } from \"../intelligence-platform\";\n// Type-only: @copilotkit/channels is pure-ESM, so a value import would break this\n// package's CJS output (see `runtime.ts` for the same constraint).\nimport type { Channel } from \"@copilotkit/channels\";\n\n/**\n * Error thrown when a Channel activation config cannot be derived — either the\n * Intelligence API key does not carry a project id in the expected\n * `cpk-{projectId}_...` format, or the {@link Channel} is missing a `name`.\n */\nexport class ChannelConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ChannelConfigError\";\n }\n}\n\n/**\n * Resolved configuration needed to activate a single Channel against a\n * running Intelligence runtime instance.\n */\nexport interface ChannelActivationConfig {\n /** Intelligence runner websocket URL the Channel connects to. */\n wsUrl: string;\n /** Intelligence API key used to authenticate the runner connection. */\n apiKey: string;\n /** Intelligence app-api HTTP base URL (`intelligence.ɵgetApiUrl()`), forwarded\n * to the transport so the managed realtime path enables file/history parity\n * (those are HTTP-only). Without it, Channels started by the normal runtime\n * handler run with no history and no file support (OSS-476). */\n apiUrl: string;\n /** Project id parsed from {@link apiKey}. */\n projectId: number;\n /** The Channel's declared name (`createChannel({ name })`). */\n channelName: string;\n /**\n * The managed provider this Channel declares to the Intelligence gateway on\n * join, resolved from the Channel's per-Channel `provider` (e.g. `\"slack\"` or\n * `\"teams\"`), defaulting to `\"slack\"`. Named `adapter` because that is the\n * field the gateway's join payload expects; the gateway resolves the actual\n * connection for the declared provider.\n */\n adapter: string;\n /**\n * Optional per-Channel override for visible managed tool-call progress.\n * Unset Slack routes default to hidden; other providers retain their existing\n * default.\n */\n showToolStatus?: boolean;\n /** Identifier for the runtime instance activating this Channel. */\n runtimeInstanceId: string;\n}\n\n/** Matches the `cpk-{projectId}_...` Intelligence API key format. */\nconst API_KEY_PROJECT_ID_PATTERN = /^cpk-(\\d+)_/;\n\n/**\n * Parse the project id embedded in an Intelligence API key.\n *\n * Intelligence API keys are formatted `cpk-{projectId}_{rest}` — this\n * extracts and numerically parses the `{projectId}` segment.\n *\n * @param apiKey - The Intelligence API key to parse.\n * @returns The parsed, strictly-positive, safe-integer project id.\n * @throws {ChannelConfigError} If `apiKey` does not match the expected\n * `cpk-{projectId}_...` format — a wrong/missing prefix or an absent project\n * id segment all fail the same match — or if the parsed project id is not a\n * strictly-positive safe integer.\n */\nexport function parseProjectIdFromApiKey(apiKey: string): number {\n const match = API_KEY_PROJECT_ID_PATTERN.exec(apiKey);\n if (!match) {\n // The whole API key is a `cpk-…` secret — everything after the fixed `cpk-`\n // namespace is sensitive, so a fixed-width slice (e.g. `apiKey.slice(0, 8)`)\n // would echo secret bytes for a `cpk-_short_long`-shaped key. This message is\n // logged and surfaced through `ready()`'s AggregateError, so echo NONE of the\n // key value; name only the expected format to aid diagnosis.\n throw new ChannelConfigError(\n `Could not parse a project id from the Intelligence API key — expected the ` +\n `\"cpk-{projectId}_...\" format (the key value is omitted here to avoid ` +\n `leaking secret material).`,\n );\n }\n const projectId = Number(match[1]);\n // Validate the parser's OWN output: `cpk-0_...` matches the pattern but a\n // non-positive project id would otherwise fail deep inside the launcher's\n // `assertValidChannelRealtimeScope` (which requires a positive projectId).\n // A very long digit run also matches `\\d+` but loses precision (or overflows\n // to Infinity) once coerced to `Number`, so it must be rejected too even\n // though it is `> 0` — `Number.isSafeInteger` catches both. This is the\n // parser guarding its own contract, not a channel-name replica, so it\n // belongs here. Reuse the same redaction: never echo the key value.\n if (!Number.isSafeInteger(projectId) || projectId <= 0) {\n throw new ChannelConfigError(\n `Parsed an invalid project id (${projectId}) from the Intelligence API ` +\n `key — the project id in \"cpk-{projectId}_...\" must be a positive safe ` +\n `integer (the key value is omitted here to avoid leaking secret material).`,\n );\n }\n return projectId;\n}\n\n/**\n * Derive the {@link ChannelActivationConfig} needed to activate `channel`\n * against the given Intelligence runtime configuration.\n *\n * @param args.intelligence - The Intelligence runtime client to pull the\n * runner websocket URL and auth token from.\n * @param args.channel - The Channel being activated. Must have a `name`; its\n * per-Channel `provider` selects the managed adapter declared to the gateway,\n * and `showToolStatus` optionally overrides managed tool-call visibility.\n * @param args.runtimeInstanceId - Identifier for the activating runtime\n * instance, passed through unchanged.\n * @returns The resolved {@link ChannelActivationConfig}.\n * @throws {ChannelConfigError} If the Intelligence API key does not carry a\n * parseable, strictly-positive project id, or if `channel.name` is\n * missing/empty.\n *\n * The managed provider is a PER-CHANNEL choice read from `channel.provider`, so\n * one runtime can activate a Slack-backed Channel and a Teams-backed Channel\n * side by side. When `channel.provider` is unset the config adapter defaults to\n * `\"slack\"` — an explicit, documented default, not a silent global. The SDK\n * only DECLARES this provider to the Intelligence gateway on join; the gateway\n * resolves the actual connection and is the authority on which providers it\n * accepts (it accepts only `\"slack\"` today — Teams gateway support is tracked\n * in OSS-450).\n *\n * The Channel-name FORMAT rules (lowercase kebab-case, 3–64 chars) and the\n * reserved-name rule are NOT re-checked here. Their single source of truth is\n * the `@copilotkit/channels-intelligence` launcher\n * (`assertValidChannelRealtimeScope` + `assertValidChannelNames`), which\n * validates them at activation; a malformed name surfaces as a logged `error`\n * status via {@link ChannelManager.ready} rather than an up-front throw. An\n * empty/missing name is still rejected here because that is this config's own\n * precondition (it has no name to forward at all), not a downstream replica.\n */\nexport function deriveChannelActivationConfig(args: {\n intelligence: CopilotKitIntelligence;\n channel: Channel;\n runtimeInstanceId: string;\n}): ChannelActivationConfig {\n const { intelligence, channel, runtimeInstanceId } = args;\n\n if (!channel.name) {\n throw new ChannelConfigError(\n \"Channel is missing a `name` — pass createChannel({ name }) to activate it.\",\n );\n }\n\n const channelName = channel.name;\n\n const wsUrl = intelligence.ɵ
|
|
1
|
+
{"version":3,"file":"channel-activation-config.mjs","names":[],"sources":["../../../../src/v2/runtime/core/channel-activation-config.ts"],"sourcesContent":["import type { CopilotKitIntelligence } from \"../intelligence-platform\";\n// Type-only: @copilotkit/channels is pure-ESM, so a value import would break this\n// package's CJS output (see `runtime.ts` for the same constraint).\nimport type { Channel } from \"@copilotkit/channels\";\n\n/**\n * Error thrown when a Channel activation config cannot be derived — either the\n * Intelligence API key does not carry a project id in the expected\n * `cpk-{projectId}_...` format, or the {@link Channel} is missing a `name`.\n */\nexport class ChannelConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ChannelConfigError\";\n }\n}\n\n/**\n * Resolved configuration needed to activate a single Channel against a\n * running Intelligence runtime instance.\n */\nexport interface ChannelActivationConfig {\n /** Intelligence runner websocket URL the Channel connects to. */\n wsUrl: string;\n /** Intelligence API key used to authenticate the runner connection. */\n apiKey: string;\n /** Intelligence app-api HTTP base URL (`intelligence.ɵgetApiUrl()`), forwarded\n * to the transport so the managed realtime path enables file/history parity\n * (those are HTTP-only). Without it, Channels started by the normal runtime\n * handler run with no history and no file support (OSS-476). */\n apiUrl: string;\n /** Project id parsed from {@link apiKey}. */\n projectId: number;\n /** The Channel's declared name (`createChannel({ name })`). */\n channelName: string;\n /**\n * The managed provider this Channel declares to the Intelligence gateway on\n * join, resolved from the Channel's per-Channel `provider` (e.g. `\"slack\"` or\n * `\"teams\"`), defaulting to `\"slack\"`. Named `adapter` because that is the\n * field the gateway's join payload expects; the gateway resolves the actual\n * connection for the declared provider.\n */\n adapter: string;\n /**\n * Optional per-Channel override for visible managed tool-call progress.\n * Unset Slack routes default to hidden; other providers retain their existing\n * default.\n */\n showToolStatus?: boolean;\n /** Identifier for the runtime instance activating this Channel. */\n runtimeInstanceId: string;\n}\n\n/** Matches the `cpk-{projectId}_...` Intelligence API key format. */\nconst API_KEY_PROJECT_ID_PATTERN = /^cpk-(\\d+)_/;\n\n/**\n * Parse the project id embedded in an Intelligence API key.\n *\n * Intelligence API keys are formatted `cpk-{projectId}_{rest}` — this\n * extracts and numerically parses the `{projectId}` segment.\n *\n * @param apiKey - The Intelligence API key to parse.\n * @returns The parsed, strictly-positive, safe-integer project id.\n * @throws {ChannelConfigError} If `apiKey` does not match the expected\n * `cpk-{projectId}_...` format — a wrong/missing prefix or an absent project\n * id segment all fail the same match — or if the parsed project id is not a\n * strictly-positive safe integer.\n */\nexport function parseProjectIdFromApiKey(apiKey: string): number {\n const match = API_KEY_PROJECT_ID_PATTERN.exec(apiKey);\n if (!match) {\n // The whole API key is a `cpk-…` secret — everything after the fixed `cpk-`\n // namespace is sensitive, so a fixed-width slice (e.g. `apiKey.slice(0, 8)`)\n // would echo secret bytes for a `cpk-_short_long`-shaped key. This message is\n // logged and surfaced through `ready()`'s AggregateError, so echo NONE of the\n // key value; name only the expected format to aid diagnosis.\n throw new ChannelConfigError(\n `Could not parse a project id from the Intelligence API key — expected the ` +\n `\"cpk-{projectId}_...\" format (the key value is omitted here to avoid ` +\n `leaking secret material).`,\n );\n }\n const projectId = Number(match[1]);\n // Validate the parser's OWN output: `cpk-0_...` matches the pattern but a\n // non-positive project id would otherwise fail deep inside the launcher's\n // `assertValidChannelRealtimeScope` (which requires a positive projectId).\n // A very long digit run also matches `\\d+` but loses precision (or overflows\n // to Infinity) once coerced to `Number`, so it must be rejected too even\n // though it is `> 0` — `Number.isSafeInteger` catches both. This is the\n // parser guarding its own contract, not a channel-name replica, so it\n // belongs here. Reuse the same redaction: never echo the key value.\n if (!Number.isSafeInteger(projectId) || projectId <= 0) {\n throw new ChannelConfigError(\n `Parsed an invalid project id (${projectId}) from the Intelligence API ` +\n `key — the project id in \"cpk-{projectId}_...\" must be a positive safe ` +\n `integer (the key value is omitted here to avoid leaking secret material).`,\n );\n }\n return projectId;\n}\n\n/**\n * Derive the {@link ChannelActivationConfig} needed to activate `channel`\n * against the given Intelligence runtime configuration.\n *\n * @param args.intelligence - The Intelligence runtime client to pull the\n * runner websocket URL and auth token from.\n * @param args.channel - The Channel being activated. Must have a `name`; its\n * per-Channel `provider` selects the managed adapter declared to the gateway,\n * and `showToolStatus` optionally overrides managed tool-call visibility.\n * @param args.runtimeInstanceId - Identifier for the activating runtime\n * instance, passed through unchanged.\n * @returns The resolved {@link ChannelActivationConfig}.\n * @throws {ChannelConfigError} If the Intelligence API key does not carry a\n * parseable, strictly-positive project id, or if `channel.name` is\n * missing/empty.\n *\n * The managed provider is a PER-CHANNEL choice read from `channel.provider`, so\n * one runtime can activate a Slack-backed Channel and a Teams-backed Channel\n * side by side. When `channel.provider` is unset the config adapter defaults to\n * `\"slack\"` — an explicit, documented default, not a silent global. The SDK\n * only DECLARES this provider to the Intelligence gateway on join; the gateway\n * resolves the actual connection and is the authority on which providers it\n * accepts (it accepts only `\"slack\"` today — Teams gateway support is tracked\n * in OSS-450).\n *\n * The Channel-name FORMAT rules (lowercase kebab-case, 3–64 chars) and the\n * reserved-name rule are NOT re-checked here. Their single source of truth is\n * the `@copilotkit/channels-intelligence` launcher\n * (`assertValidChannelRealtimeScope` + `assertValidChannelNames`), which\n * validates them at activation; a malformed name surfaces as a logged `error`\n * status via {@link ChannelManager.ready} rather than an up-front throw. An\n * empty/missing name is still rejected here because that is this config's own\n * precondition (it has no name to forward at all), not a downstream replica.\n */\nexport function deriveChannelActivationConfig(args: {\n intelligence: CopilotKitIntelligence;\n channel: Channel;\n runtimeInstanceId: string;\n}): ChannelActivationConfig {\n const { intelligence, channel, runtimeInstanceId } = args;\n\n if (!channel.name) {\n throw new ChannelConfigError(\n \"Channel is missing a `name` — pass createChannel({ name }) to activate it.\",\n );\n }\n\n const channelName = channel.name;\n\n const wsUrl = intelligence.ɵgetChannelsWsUrl();\n const apiUrl = intelligence.ɵgetApiUrl();\n const apiKey = intelligence.ɵgetRunnerAuthToken();\n const projectId = parseProjectIdFromApiKey(apiKey);\n\n // Resolve the managed adapter declared to the gateway from the Channel's OWN\n // `provider` — a per-Channel choice, not a manager-wide default. When\n // `provider` is unset the adapter is the documented default `\"slack\"`; set\n // `createChannel({ provider: \"teams\" })` to declare Teams instead. The value\n // is trimmed so a padded runtime value (one that bypassed the typed union)\n // resolves to its bare provider rather than being forwarded with whitespace,\n // and a blank/whitespace-only provider falls back to `\"slack\"` (`??` alone\n // would keep `\"\"`).\n const trimmedProvider = channel.provider?.trim();\n\n return {\n wsUrl,\n apiUrl,\n apiKey,\n projectId,\n channelName,\n adapter: trimmedProvider ? trimmedProvider : \"slack\",\n ...(channel.showToolStatus !== undefined\n ? { showToolStatus: channel.showToolStatus }\n : {}),\n runtimeInstanceId,\n };\n}\n"],"mappings":";;;;;;;AAUA,IAAa,qBAAb,cAAwC,MAAM;CAC5C,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;AAyChB,MAAM,6BAA6B;;;;;;;;;;;;;;AAenC,SAAgB,yBAAyB,QAAwB;CAC/D,MAAM,QAAQ,2BAA2B,KAAK,OAAO;AACrD,KAAI,CAAC,MAMH,OAAM,IAAI,mBACR,6KAGD;CAEH,MAAM,YAAY,OAAO,MAAM,GAAG;AASlC,KAAI,CAAC,OAAO,cAAc,UAAU,IAAI,aAAa,EACnD,OAAM,IAAI,mBACR,iCAAiC,UAAU,6KAG5C;AAEH,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCT,SAAgB,8BAA8B,MAIlB;CAC1B,MAAM,EAAE,cAAc,SAAS,sBAAsB;AAErD,KAAI,CAAC,QAAQ,KACX,OAAM,IAAI,mBACR,6EACD;CAGH,MAAM,cAAc,QAAQ;CAE5B,MAAM,QAAQ,aAAa,mBAAmB;CAC9C,MAAM,SAAS,aAAa,YAAY;CACxC,MAAM,SAAS,aAAa,qBAAqB;CACjD,MAAM,YAAY,yBAAyB,OAAO;CAUlD,MAAM,kBAAkB,QAAQ,UAAU,MAAM;AAEhD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA,SAAS,kBAAkB,kBAAkB;EAC7C,GAAI,QAAQ,mBAAmB,SAC3B,EAAE,gBAAgB,QAAQ,gBAAgB,GAC1C,EAAE;EACN;EACD"}
|
|
@@ -69,7 +69,7 @@ async function defaultActivateChannel(config, channel, importChannelsIntelligenc
|
|
|
69
69
|
...config.showToolStatus !== void 0 ? { showToolStatus: config.showToolStatus } : {},
|
|
70
70
|
appApiBaseUrl: config.apiUrl,
|
|
71
71
|
...log ? { log } : {},
|
|
72
|
-
runCanonical: (args) => runCanonicalChannelAgent(services.runner, services.intelligence, services.lockTtlSeconds ?? 20, services.lockHeartbeatIntervalSeconds ?? 15, args),
|
|
72
|
+
runCanonical: (args) => runCanonicalChannelAgent(services.runner, services.intelligence, services.lockTtlSeconds ?? 20, services.lockHeartbeatIntervalSeconds ?? 15, args, services.lockKeyPrefix),
|
|
73
73
|
loadHistory: async ({ threadId, appUserId }) => {
|
|
74
74
|
return (await services.intelligence.getThreadMessages({
|
|
75
75
|
threadId,
|
|
@@ -109,13 +109,22 @@ var ChannelOuterAgent = class extends _ag_ui_client.AbstractAgent {
|
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
111
|
/** Drive one public Channel run through the runtime's existing AgentRunner. */
|
|
112
|
-
async function runCanonicalChannelAgent(runner, intelligence, lockTtlSeconds, lockHeartbeatIntervalSeconds, args) {
|
|
113
|
-
|
|
112
|
+
async function runCanonicalChannelAgent(runner, intelligence, lockTtlSeconds, lockHeartbeatIntervalSeconds, args, lockKeyPrefix) {
|
|
113
|
+
const lock = await intelligence.ɵacquireThreadLock({
|
|
114
|
+
threadId: args.threadId,
|
|
115
|
+
runId: args.runId,
|
|
116
|
+
userId: args.userId,
|
|
117
|
+
agentId: args.agentId,
|
|
118
|
+
ttlSeconds: lockTtlSeconds,
|
|
119
|
+
...lockKeyPrefix !== void 0 ? { lockKeyPrefix } : {}
|
|
120
|
+
});
|
|
121
|
+
const canonicalThreadId = lock.threadId;
|
|
122
|
+
const canonicalRunId = lock.runId;
|
|
114
123
|
let result = {
|
|
115
124
|
iterations: 0,
|
|
116
125
|
interrupted: false
|
|
117
126
|
};
|
|
118
|
-
const outer = new ChannelOuterAgent(args.agent,
|
|
127
|
+
const outer = new ChannelOuterAgent(args.agent, canonicalThreadId, async (subscriber, canonicalRun) => {
|
|
119
128
|
result = await args.execute(subscriber, canonicalRun);
|
|
120
129
|
return result;
|
|
121
130
|
});
|
|
@@ -123,14 +132,14 @@ async function runCanonicalChannelAgent(runner, intelligence, lockTtlSeconds, lo
|
|
|
123
132
|
let heartbeatError;
|
|
124
133
|
let heartbeatTimer;
|
|
125
134
|
const stopCanonicalRun = () => {
|
|
126
|
-
stopPromise ??= Promise.resolve().then(() => runner.stop({ threadId:
|
|
135
|
+
stopPromise ??= Promise.resolve().then(() => runner.stop({ threadId: canonicalThreadId })).catch(() => false);
|
|
127
136
|
};
|
|
128
|
-
args.abortSignal.addEventListener("abort", stopCanonicalRun, { once: true });
|
|
129
137
|
heartbeatTimer = setInterval(() => {
|
|
130
138
|
intelligence.ɵrenewThreadLock({
|
|
131
|
-
threadId:
|
|
132
|
-
runId:
|
|
133
|
-
ttlSeconds: lockTtlSeconds
|
|
139
|
+
threadId: canonicalThreadId,
|
|
140
|
+
runId: canonicalRunId,
|
|
141
|
+
ttlSeconds: lockTtlSeconds,
|
|
142
|
+
...lockKeyPrefix !== void 0 ? { lockKeyPrefix } : {}
|
|
134
143
|
}).catch((error) => {
|
|
135
144
|
if (heartbeatTimer === void 0) return;
|
|
136
145
|
clearInterval(heartbeatTimer);
|
|
@@ -144,23 +153,21 @@ async function runCanonicalChannelAgent(runner, intelligence, lockTtlSeconds, lo
|
|
|
144
153
|
}, lockHeartbeatIntervalSeconds * 1e3);
|
|
145
154
|
heartbeatTimer.unref?.();
|
|
146
155
|
try {
|
|
147
|
-
if (args.abortSignal.aborted) stopCanonicalRun();
|
|
148
156
|
await new Promise((resolve, reject) => {
|
|
149
157
|
let terminalError;
|
|
150
158
|
runner.run({
|
|
151
|
-
threadId:
|
|
159
|
+
threadId: canonicalThreadId,
|
|
152
160
|
agent: outer,
|
|
153
161
|
input: {
|
|
154
|
-
threadId:
|
|
155
|
-
runId:
|
|
162
|
+
threadId: canonicalThreadId,
|
|
163
|
+
runId: canonicalRunId,
|
|
156
164
|
messages: args.agent.messages,
|
|
157
165
|
state: args.agent.state,
|
|
158
166
|
tools: [...args.tools],
|
|
159
167
|
context: [...args.context],
|
|
160
168
|
forwardedProps: void 0
|
|
161
169
|
},
|
|
162
|
-
persistedInputMessages: args.persistedInputMessages
|
|
163
|
-
authToken: args.runnerToken
|
|
170
|
+
persistedInputMessages: args.persistedInputMessages
|
|
164
171
|
}).subscribe({
|
|
165
172
|
next: (event) => {
|
|
166
173
|
if (event.type !== _ag_ui_client.EventType.RUN_ERROR || terminalError) return;
|
|
@@ -176,35 +183,22 @@ async function runCanonicalChannelAgent(runner, intelligence, lockTtlSeconds, lo
|
|
|
176
183
|
}
|
|
177
184
|
});
|
|
178
185
|
});
|
|
179
|
-
} catch (error) {
|
|
180
|
-
if (args.abortSignal.aborted) {
|
|
181
|
-
await stopPromise;
|
|
182
|
-
throw channelRunCancellationError(args.abortSignal);
|
|
183
|
-
}
|
|
184
|
-
throw error;
|
|
185
186
|
} finally {
|
|
186
187
|
if (heartbeatTimer !== void 0) {
|
|
187
188
|
clearInterval(heartbeatTimer);
|
|
188
189
|
heartbeatTimer = void 0;
|
|
189
190
|
}
|
|
190
|
-
|
|
191
|
+
await intelligence.ɵcleanupThreadLock({
|
|
192
|
+
threadId: canonicalThreadId,
|
|
193
|
+
runId: canonicalRunId
|
|
194
|
+
}).catch(() => void 0);
|
|
191
195
|
}
|
|
192
196
|
if (heartbeatError !== void 0) {
|
|
193
197
|
await stopPromise;
|
|
194
198
|
throw heartbeatError;
|
|
195
199
|
}
|
|
196
|
-
if (args.abortSignal.aborted) {
|
|
197
|
-
await stopPromise;
|
|
198
|
-
throw channelRunCancellationError(args.abortSignal);
|
|
199
|
-
}
|
|
200
200
|
return result;
|
|
201
201
|
}
|
|
202
|
-
function channelRunCancellationError(signal) {
|
|
203
|
-
const reason = typeof signal.reason === "string" && signal.reason.length > 0 ? signal.reason : "channel_run_cancelled";
|
|
204
|
-
const error = new Error(reason);
|
|
205
|
-
error.name = "ChannelCanonicalRunCancelledError";
|
|
206
|
-
return error;
|
|
207
|
-
}
|
|
208
202
|
/** Convert canonical Intelligence history into AG-UI messages. */
|
|
209
203
|
function toAgentMessage(message) {
|
|
210
204
|
return {
|
|
@@ -283,15 +277,12 @@ function withTimeout(inner, timeoutMs, timeoutMessage) {
|
|
|
283
277
|
* and {@link ready} rather than thrown.
|
|
284
278
|
*
|
|
285
279
|
* Reconnection is NOT handled here — it is delegated to the Phoenix connection
|
|
286
|
-
* layer that backs the launcher. When a managed socket drops, Phoenix's
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
* redundant AND broken: re-invoking the engine on an already-started `Channel`
|
|
293
|
-
* throws in `channel.addAdapter` (started=true). The manager therefore never
|
|
294
|
-
* re-activates on a drop.
|
|
280
|
+
* layer that backs the launcher. When a managed control socket drops, Phoenix's
|
|
281
|
+
* `Socket` reconnects and rejoins with the same Runtime declaration. Active
|
|
282
|
+
* deliveries request fresh one-use join tokens through that control link. A
|
|
283
|
+
* re-activation here would be both redundant AND broken: re-invoking the engine
|
|
284
|
+
* on an already-started `Channel` throws in `channel.addAdapter` (started=true).
|
|
285
|
+
* The manager therefore never re-activates on a drop.
|
|
295
286
|
*
|
|
296
287
|
* It DOES, however, reflect real connection health through the session's
|
|
297
288
|
* `onStateChange` observer so {@link ChannelManager.status} stays honest rather
|
|
@@ -309,13 +300,15 @@ var ChannelManager = class {
|
|
|
309
300
|
this.runner = args.runner;
|
|
310
301
|
this.lockTtlSeconds = args.lockTtlSeconds ?? 20;
|
|
311
302
|
this.lockHeartbeatIntervalSeconds = args.lockHeartbeatIntervalSeconds ?? 15;
|
|
303
|
+
this.lockKeyPrefix = args.lockKeyPrefix;
|
|
312
304
|
this.channels = args.channels;
|
|
313
305
|
this.log = args.log;
|
|
314
306
|
this.activateChannel = args.activateChannel ?? ((config, channel) => defaultActivateChannel(config, channel, void 0, this.log, this.runner ? {
|
|
315
307
|
runner: this.runner,
|
|
316
308
|
intelligence: this.intelligence,
|
|
317
309
|
lockTtlSeconds: this.lockTtlSeconds,
|
|
318
|
-
lockHeartbeatIntervalSeconds: this.lockHeartbeatIntervalSeconds
|
|
310
|
+
lockHeartbeatIntervalSeconds: this.lockHeartbeatIntervalSeconds,
|
|
311
|
+
...this.lockKeyPrefix !== void 0 ? { lockKeyPrefix: this.lockKeyPrefix } : {}
|
|
319
312
|
} : void 0));
|
|
320
313
|
this.mintRuntimeInstanceId = args.mintRuntimeInstanceId ?? (() => `rti_${(0, node_crypto.randomUUID)().replace(/-/g, "")}`);
|
|
321
314
|
this.stopHandleTimeoutMs = args.stopHandleTimeoutMs ?? DEFAULT_STOP_HANDLE_TIMEOUT_MS;
|
|
@@ -577,8 +570,7 @@ var ChannelManager = class {
|
|
|
577
570
|
*
|
|
578
571
|
* - `reconnecting` → status `reconnecting` (dropped, Phoenix retrying);
|
|
579
572
|
* - `online` → status `online` (rejoined, sendable again);
|
|
580
|
-
* - `gave_up` → status `error` (dead after the bounded reconnect window)
|
|
581
|
-
* - `fenced` → status `error` immediately (another activation superseded it).
|
|
573
|
+
* - `gave_up` → status `error` (dead after the bounded reconnect window).
|
|
582
574
|
*
|
|
583
575
|
* Makes NO re-activation — reconnection is delegated to the Phoenix connection
|
|
584
576
|
* layer (see {@link ChannelManager}), which auto-rejoins under the persistent
|
|
@@ -607,10 +599,6 @@ var ChannelManager = class {
|
|
|
607
599
|
} else if (state === "gave_up") {
|
|
608
600
|
entry.status = "error";
|
|
609
601
|
this.log?.(`channel "${name}" managed session gave up reconnecting after ${this.downFor(entry)}; marking error (still retrying — a successful rejoin restores online)${because}`);
|
|
610
|
-
} else {
|
|
611
|
-
entry.status = "error";
|
|
612
|
-
this.clearReconnectLog(entry);
|
|
613
|
-
this.log?.(`channel "${name}" managed session was generation-fenced by a replacement; marking error`);
|
|
614
602
|
}
|
|
615
603
|
});
|
|
616
604
|
}
|