copilotkit 4.7.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -77,7 +77,17 @@ persistence, insights), and `init` provisions a free license automatically —
77
77
  you sign in with your browser during scaffolding. The `-i`/`--intelligence`
78
78
  flag is retained as a deprecated no-op for backward compatibility.
79
79
 
80
- Supported framework values include `langgraph-py`, `langgraph-js`, `claude-sdk-typescript`, `claude-sdk-python`, `mastra`, `pydantic-ai`, `aws-strands-py`, `adk`, `adk-angular`, `a2a`, `microsoft-agent-framework-dotnet`, `microsoft-agent-framework-py`, `flows`, `llamaindex`, `agno`, `ag2`, `mcp-apps`, `agentcore-langgraph`, `agentcore-strands`, `a2ui`, and `opengenui`.
80
+ Rather than maintaining the list of framework values here, ask the CLI:
81
+
82
+ ```bash
83
+ copilotkit framework list
84
+ copilotkit framework list --json
85
+ ```
86
+
87
+ It reports every value `-f` accepts, the language each framework's agent is
88
+ written in, and which init flags that framework supports — `-i`, `--mock`, and
89
+ `--channel` are each accepted only for some. It answers from a catalog compiled into the
90
+ binary, so it needs no API call, no authentication, and no TTY.
81
91
 
82
92
  `init` and `create` collect your starter choices, then connect project creation
83
93
  to your CopilotKit workspace through Ops/Clerk before scaffolding. If you
@@ -104,8 +114,15 @@ copilotkit channels status
104
114
  copilotkit channels list
105
115
  copilotkit channels rotate support --adapter slack
106
116
  copilotkit channels setup
117
+ copilotkit channels providers
107
118
  ```
108
119
 
120
+ `channels providers` lists the chat providers a Channel can use and the
121
+ credentials each one asks for, named as that provider's own console names them.
122
+ Unlike every other `channels` subcommand it answers from a compiled-in catalog, so
123
+ it needs no selected project, no credentials, and no API call. Note it is distinct
124
+ from `channels list`, which reports the Channels that exist in _your_ project.
125
+
109
126
  This configures **managed Intelligence Channels**. It does not configure the
110
127
  open-source `@copilotkit/channels` adapter packages, which are a separate product
111
128
  that shares the words "channels" and "Slack".
@@ -2,20 +2,20 @@
2
2
  "schemaVersion": 1,
3
3
  "package": {
4
4
  "name": "copilotkit",
5
- "version": "4.7.0"
5
+ "version": "4.8.0"
6
6
  },
7
7
  "intelligence": {
8
- "commit": "932bad4f3c97b61dd0ee5c20b99362e302e5e48a"
8
+ "commit": "9b3d51575a8ad5fcbe2a24f898b6c33b3f8d5239"
9
9
  },
10
10
  "copilotKit": {
11
- "submittedInput": "8e59bfd16b415b9f776a4742aa43942a8d02c2ef",
12
- "commit": "8e59bfd16b415b9f776a4742aa43942a8d02c2ef"
11
+ "submittedInput": "b30527ca8a430490ba3b8866304f1451baa252af",
12
+ "commit": "b30527ca8a430490ba3b8866304f1451baa252af"
13
13
  },
14
14
  "channel": "production",
15
15
  "triggeringActor": "BenTaylorDev",
16
16
  "workflow": {
17
- "runId": "30933084879",
18
- "runUrl": "https://github.com/CopilotKit/Intelligence/actions/runs/30933084879"
17
+ "runId": "31015215100",
18
+ "runUrl": "https://github.com/CopilotKit/Intelligence/actions/runs/31015215100"
19
19
  },
20
20
  "validationResult": "passed",
21
21
  "ag2": {
@@ -24,5 +24,5 @@
24
24
  "revision": "main",
25
25
  "pinned": false
26
26
  },
27
- "builtAt": "2026-08-04T17:17:46Z"
27
+ "builtAt": "2026-08-05T14:28:27Z"
28
28
  }
package/index.js CHANGED
@@ -87,14 +87,14 @@ function getTelemetryEndpointUrl() {
87
87
  }
88
88
  function getBuildInfo() {
89
89
  return {
90
- version: true ? "4.7.0" : "dev",
91
- buildNumber: true ? "30933084879" : "dev",
92
- commitSha: true ? "932bad4f3c97b61dd0ee5c20b99362e302e5e48a" : "dev",
90
+ version: true ? "4.8.0" : "dev",
91
+ buildNumber: true ? "31015215100" : "dev",
92
+ commitSha: true ? "9b3d51575a8ad5fcbe2a24f898b6c33b3f8d5239" : "dev",
93
93
  copilotKitCommit: getTemplateRef()
94
94
  };
95
95
  }
96
96
  function getTemplateRef() {
97
- return true ? "8e59bfd16b415b9f776a4742aa43942a8d02c2ef" : "main";
97
+ return true ? "b30527ca8a430490ba3b8866304f1451baa252af" : "main";
98
98
  }
99
99
  function getC15tBackendUrl() {
100
100
  return true ? "https://calm-hazelnut-joy-copilotkit.inth.app" : "";
@@ -460,7 +460,7 @@ function formatIntelligenceUnavailableError(framework) {
460
460
  ...THREADS_FRAMEWORKS
461
461
  ].join(", ")}.`;
462
462
  }
463
- var AGENT_FRAMEWORKS, FRAMEWORK_ALIASES, FRAMEWORK_EMOJI, FRAMEWORK_CHOICES, TEMPLATE_REPOS, UV_PREREQUISITE, DOTNET_PREREQUISITE, PYTHON3_PREREQUISITE, OPENAI_ENV_KEY, ANTHROPIC_ENV_KEY, GOOGLE_ENV_KEY, COPILOTKIT_LICENSE_ENV_KEY, FRAMEWORK_TEMPLATES, THREADS_FRAMEWORKS;
463
+ var AGENT_FRAMEWORKS, FRAMEWORK_ALIASES, FRAMEWORK_EMOJI, FRAMEWORK_CHOICES, TEMPLATE_REPOS, UV_PREREQUISITE, DOTNET_PREREQUISITE, PYTHON3_PREREQUISITE, OPENAI_ENV_KEY, ANTHROPIC_ENV_KEY, GOOGLE_ENV_KEY, COPILOTKIT_LICENSE_ENV_KEY, FRAMEWORK_TEMPLATES, THREADS_FRAMEWORKS, FRAMEWORK_LANGUAGE, CHANNEL_HOST_FRAMEWORKS, INIT_CHANNEL_NONE;
464
464
  var init_types = __esm({
465
465
  "apps/cli/src/types.ts"() {
466
466
  "use strict";
@@ -805,6 +805,49 @@ var init_types = __esm({
805
805
  "a2ui",
806
806
  "opengenui"
807
807
  ]);
808
+ FRAMEWORK_LANGUAGE = {
809
+ "langgraph-py": "python",
810
+ "langgraph-js": "typescript",
811
+ "claude-sdk-typescript": "typescript",
812
+ "claude-sdk-python": "python",
813
+ flows: "python",
814
+ mastra: "typescript",
815
+ "pydantic-ai": "python",
816
+ llamaindex: "python",
817
+ agno: "python",
818
+ ag2: "python",
819
+ adk: "python",
820
+ "adk-angular": "python",
821
+ a2a: "typescript",
822
+ "aws-strands-py": "python",
823
+ "microsoft-agent-framework-dotnet": "dotnet",
824
+ "microsoft-agent-framework-py": "python",
825
+ "mcp-apps": "typescript",
826
+ "agentcore-langgraph": "python",
827
+ "agentcore-strands": "python",
828
+ a2ui: "python",
829
+ opengenui: "python"
830
+ };
831
+ CHANNEL_HOST_FRAMEWORKS = /* @__PURE__ */ new Set([
832
+ "langgraph-py",
833
+ "langgraph-js",
834
+ "claude-sdk-typescript",
835
+ "claude-sdk-python",
836
+ "flows",
837
+ "mastra",
838
+ "pydantic-ai",
839
+ "llamaindex",
840
+ "agno",
841
+ "adk",
842
+ "a2a",
843
+ "aws-strands-py",
844
+ "microsoft-agent-framework-dotnet",
845
+ "microsoft-agent-framework-py",
846
+ "mcp-apps",
847
+ "a2ui",
848
+ "opengenui"
849
+ ]);
850
+ INIT_CHANNEL_NONE = "none";
808
851
  }
809
852
  });
810
853
 
@@ -847,9 +890,21 @@ function initTelemetryBase(invokedAs, flags) {
847
890
  command: "init",
848
891
  subcommand: subcommandForInit(flags),
849
892
  invoked_as: invokedAs,
850
- mock_mode: "none"
893
+ mock_mode: "none",
894
+ channel_flag: channelFlagFor(flags)
851
895
  };
852
896
  }
897
+ function channelFlagFor(flags) {
898
+ switch (flags.channel) {
899
+ case "slack":
900
+ case "teams":
901
+ return flags.channel;
902
+ case "none":
903
+ return "declined";
904
+ default:
905
+ return "unset";
906
+ }
907
+ }
853
908
  function resolveMockSubcommand(raw2) {
854
909
  if (raw2 === "enable" || raw2 === "disable")
855
910
  return raw2;
@@ -94019,6 +94074,137 @@ var init_license = __esm({
94019
94074
  }
94020
94075
  });
94021
94076
 
94077
+ // apps/cli/src/commands/framework-catalog.ts
94078
+ function listFrameworks() {
94079
+ return [...AGENT_FRAMEWORKS].sort((left, right) => left.localeCompare(right)).map((id) => ({
94080
+ id,
94081
+ label: LABELS_WITHOUT_EMOJI.get(id) ?? id,
94082
+ aliases: ALIASES_BY_FRAMEWORK.get(id) ?? [],
94083
+ language: FRAMEWORK_LANGUAGE[id],
94084
+ supportsIntelligence: THREADS_FRAMEWORKS.has(id),
94085
+ supportsMock: isMockSupported(id),
94086
+ supportsChannels: CHANNEL_HOST_FRAMEWORKS.has(id),
94087
+ environment: FRAMEWORK_TEMPLATES[id].environment
94088
+ }));
94089
+ }
94090
+ var LABELS_WITHOUT_EMOJI, ALIASES_BY_FRAMEWORK;
94091
+ var init_framework_catalog = __esm({
94092
+ "apps/cli/src/commands/framework-catalog.ts"() {
94093
+ "use strict";
94094
+ init_types();
94095
+ init_mock_llm();
94096
+ LABELS_WITHOUT_EMOJI = new Map(
94097
+ FRAMEWORK_CHOICES.map((choice) => {
94098
+ const emoji3 = FRAMEWORK_EMOJI[choice.value];
94099
+ const label = choice.label.startsWith(`${emoji3} `) ? choice.label.slice(emoji3.length + 1) : choice.label;
94100
+ return [choice.value, label];
94101
+ })
94102
+ );
94103
+ ALIASES_BY_FRAMEWORK = /* @__PURE__ */ new Map();
94104
+ for (const [alias, framework] of Object.entries(FRAMEWORK_ALIASES)) {
94105
+ const existing = ALIASES_BY_FRAMEWORK.get(framework);
94106
+ if (existing === void 0) {
94107
+ ALIASES_BY_FRAMEWORK.set(framework, [alias]);
94108
+ } else {
94109
+ existing.push(alias);
94110
+ }
94111
+ }
94112
+ }
94113
+ });
94114
+
94115
+ // apps/cli/src/commands/framework-list.ts
94116
+ var framework_list_exports = {};
94117
+ __export(framework_list_exports, {
94118
+ renderFrameworkJson: () => renderFrameworkJson,
94119
+ renderFrameworkTable: () => renderFrameworkTable,
94120
+ runFrameworkList: () => runFrameworkList
94121
+ });
94122
+ function acceptedFlags(framework) {
94123
+ const flags = [
94124
+ framework.supportsIntelligence ? "-i" : void 0,
94125
+ framework.supportsMock ? "--mock" : void 0,
94126
+ framework.supportsChannels ? "--channel" : void 0
94127
+ ].filter((flag) => flag !== void 0);
94128
+ return flags.length === 0 ? "\u2014" : flags.join(" ");
94129
+ }
94130
+ function renderFrameworkTable(frameworks) {
94131
+ if (frameworks.length === 0) {
94132
+ return "No agent frameworks are available.\n";
94133
+ }
94134
+ const idWidth = Math.max(...frameworks.map((one) => one.id.length));
94135
+ const languageWidth = Math.max(
94136
+ ...frameworks.map((one) => one.language.length)
94137
+ );
94138
+ const labelWidth = Math.max(...frameworks.map((one) => one.label.length));
94139
+ const rows = frameworks.map((framework) => {
94140
+ const emoji3 = FRAMEWORK_EMOJI[framework.id];
94141
+ return ` ${framework.id.padEnd(idWidth)} ${framework.language.padEnd(
94142
+ languageWidth
94143
+ )} ${emoji3} ${framework.label.padEnd(labelWidth)} ${acceptedFlags(
94144
+ framework
94145
+ )}`;
94146
+ });
94147
+ const aliased = frameworks.filter((one) => one.aliases.length > 0);
94148
+ const withEnvironment = frameworks.filter(
94149
+ (one) => one.environment.length > 0
94150
+ );
94151
+ const notes = [
94152
+ "Flags shown are the ones each framework accepts: -i (Intelligence threads),",
94153
+ "--mock (keyless mock model), --channel (starter ships a managed Channel host)."
94154
+ ];
94155
+ if (aliased.length > 0) {
94156
+ const pairs2 = aliased.flatMap(
94157
+ (one) => one.aliases.map((alias) => `${alias} \u2192 ${one.id}`)
94158
+ );
94159
+ notes.push(`Accepted aliases: ${pairs2.join(", ")}.`);
94160
+ }
94161
+ if (withEnvironment.length > 0) {
94162
+ const frameworksByKey = /* @__PURE__ */ new Map();
94163
+ for (const framework of withEnvironment) {
94164
+ for (const { key } of framework.environment) {
94165
+ const existing = frameworksByKey.get(key);
94166
+ if (existing === void 0) {
94167
+ frameworksByKey.set(key, [framework.id]);
94168
+ } else {
94169
+ existing.push(framework.id);
94170
+ }
94171
+ }
94172
+ }
94173
+ notes.push("Vendor keys each framework reads from .env:");
94174
+ for (const [key, ids] of [...frameworksByKey.entries()].sort(
94175
+ ([left], [right]) => left.localeCompare(right)
94176
+ )) {
94177
+ notes.push(` ${key} ${ids.join(", ")}`);
94178
+ }
94179
+ }
94180
+ return `Agent frameworks \u2014 pass one to \`copilotkit init -f <id>\`:
94181
+
94182
+ ${rows.join(
94183
+ "\n"
94184
+ )}
94185
+
94186
+ ${notes.join("\n")}
94187
+ `;
94188
+ }
94189
+ function renderFrameworkJson(frameworks) {
94190
+ return `${JSON.stringify({ frameworks }, null, 2)}
94191
+ `;
94192
+ }
94193
+ async function runFrameworkList(options) {
94194
+ const frameworks = listFrameworks();
94195
+ process.stdout.write(
94196
+ options.json ? renderFrameworkJson(frameworks) : renderFrameworkTable(frameworks)
94197
+ );
94198
+ return Promise.resolve();
94199
+ }
94200
+ var init_framework_list = __esm({
94201
+ "apps/cli/src/commands/framework-list.ts"() {
94202
+ "use strict";
94203
+ init_framework_catalog();
94204
+ init_types();
94205
+ }
94206
+ });
94207
+
94022
94208
  // apps/cli/src/services/project-config.ts
94023
94209
  import * as fs15 from "node:fs";
94024
94210
  import * as path12 from "node:path";
@@ -228820,19 +229006,19 @@ import { createRequire as topLevelCreateRequire86 } from "module";
228820
229006
  function mapLanguage(lang) {
228821
229007
  switch (lang) {
228822
229008
  case CodeExecutionLanguage.PYTHON:
228823
- return import_types7.Language.LANGUAGE_PYTHON;
229009
+ return import_types9.Language.LANGUAGE_PYTHON;
228824
229010
  case CodeExecutionLanguage.JAVASCRIPT:
228825
- return import_types7.Language.LANGUAGE_JAVASCRIPT;
229011
+ return import_types9.Language.LANGUAGE_JAVASCRIPT;
228826
229012
  default:
228827
229013
  throw new Error(`Unsupported language for Agent Engine Sandbox: ${lang}`);
228828
229014
  }
228829
229015
  }
228830
- var import_vertexai, import_types7, require87, __defProp3, __getOwnPropDesc3, __decorateClass2, SANDBOX_PATTERN, ENGINE_PATTERN, DEFAULT_MAX_ATTEMPTS, DEFAULT_SANDBOX_TTL, DEFAULT_SANDBOX_DISPLAY_NAME, DEFAULT_ENGINE_DISPLAY_NAME, AgentEngineSandboxCodeExecutor;
229016
+ var import_vertexai, import_types9, require87, __defProp3, __getOwnPropDesc3, __decorateClass2, SANDBOX_PATTERN, ENGINE_PATTERN, DEFAULT_MAX_ATTEMPTS, DEFAULT_SANDBOX_TTL, DEFAULT_SANDBOX_DISPLAY_NAME, DEFAULT_ENGINE_DISPLAY_NAME, AgentEngineSandboxCodeExecutor;
228831
229017
  var init_agent_engine_sandbox_code_executor = __esm({
228832
229018
  "node_modules/.pnpm/@google+adk@1.3.0_@bufbuild+protobuf@2.12.1_@cfworker+json-schema@4.1.1_@grpc+grpc-js@1.14.4__5mkmwgy3xddtjib6vsxkdydt4e/node_modules/@google/adk/dist/esm/code_executors/agent_engine_sandbox_code_executor.js"() {
228833
229019
  "use strict";
228834
229020
  import_vertexai = __toESM(require_src17(), 1);
228835
- import_types7 = __toESM(require_types3(), 1);
229021
+ import_types9 = __toESM(require_types3(), 1);
228836
229022
  init_experimental();
228837
229023
  init_file_utils();
228838
229024
  init_logger();
@@ -356937,6 +357123,77 @@ var init_init_flow = __esm({
356937
357123
  }
356938
357124
  });
356939
357125
 
357126
+ // apps/cli/src/commands/init-channel-flag.ts
357127
+ var init_channel_flag_exports = {};
357128
+ __export(init_channel_flag_exports, {
357129
+ INIT_CHANNEL_NONE: () => INIT_CHANNEL_NONE,
357130
+ channelFlagUnsupportedError: () => channelFlagUnsupportedError,
357131
+ channelOfferFromFlag: () => channelOfferFromFlag,
357132
+ formatChannelUnsupportedError: () => formatChannelUnsupportedError,
357133
+ resolveInitChannelFlag: () => resolveInitChannelFlag
357134
+ });
357135
+ function resolveInitChannelFlag(input) {
357136
+ if (input.value === void 0) {
357137
+ return { status: "ok", channel: null };
357138
+ }
357139
+ const value = input.value;
357140
+ if (!ACCEPTED_VALUES.includes(value)) {
357141
+ return {
357142
+ status: "invalid",
357143
+ message: `Unknown channel: "${value}". Expected one of: ${ACCEPTED_VALUES.join(
357144
+ ", "
357145
+ )}.
357146
+ Run \`copilotkit channels providers\` to see what each provider needs.`
357147
+ };
357148
+ }
357149
+ if (value === INIT_CHANNEL_NONE) {
357150
+ return { status: "ok", channel: INIT_CHANNEL_NONE };
357151
+ }
357152
+ const framework = input.framework === void 0 ? void 0 : resolveFrameworkAlias(input.framework);
357153
+ if (framework !== void 0 && isAgentFramework(framework) && !CHANNEL_HOST_FRAMEWORKS.has(framework)) {
357154
+ return {
357155
+ status: "invalid",
357156
+ message: formatChannelUnsupportedError(framework, value)
357157
+ };
357158
+ }
357159
+ return { status: "ok", channel: value };
357160
+ }
357161
+ function formatChannelUnsupportedError(framework, provider) {
357162
+ return `The ${framework} starter ships no Channel host, so --channel cannot be used with it.
357163
+ Run \`copilotkit framework list\` to see which frameworks accept --channel, or scaffold without it and run \`copilotkit channels add --adapter ${provider}\` against a runtime you host yourself.`;
357164
+ }
357165
+ function channelOfferFromFlag(channel2) {
357166
+ if (channel2 === null) {
357167
+ return void 0;
357168
+ }
357169
+ const adapter2 = channel2 === INIT_CHANNEL_NONE ? void 0 : channel2;
357170
+ return () => Promise.resolve(adapter2);
357171
+ }
357172
+ function channelFlagUnsupportedError(channel2, framework) {
357173
+ if (channel2 === null || channel2 === INIT_CHANNEL_NONE) {
357174
+ return void 0;
357175
+ }
357176
+ if (!isAgentFramework(framework)) {
357177
+ return void 0;
357178
+ }
357179
+ if (CHANNEL_HOST_FRAMEWORKS.has(framework)) {
357180
+ return void 0;
357181
+ }
357182
+ return formatChannelUnsupportedError(framework, channel2);
357183
+ }
357184
+ var ACCEPTED_VALUES;
357185
+ var init_init_channel_flag = __esm({
357186
+ "apps/cli/src/commands/init-channel-flag.ts"() {
357187
+ "use strict";
357188
+ init_channels();
357189
+ init_types();
357190
+ ACCEPTED_VALUES = [
357191
+ ...CHANNEL_ADAPTERS,
357192
+ INIT_CHANNEL_NONE
357193
+ ];
357194
+ }
357195
+ });
357196
+
356940
357197
  // apps/cli/src/services/channel-artifacts.ts
356941
357198
  import * as fs26 from "node:fs";
356942
357199
  import * as path25 from "node:path";
@@ -358277,6 +358534,36 @@ var init_channel_credential_prompt = __esm({
358277
358534
  }
358278
358535
  });
358279
358536
 
358537
+ // apps/cli/src/services/channel-provider-catalog.ts
358538
+ function listChannelProviders() {
358539
+ return CHANNEL_ADAPTERS.map((id) => ({
358540
+ id,
358541
+ label: CHANNEL_PROVIDER_LABELS[id],
358542
+ credentialFields: CREDENTIAL_FIELDS_BY_PROVIDER[id].map((field) => {
358543
+ const label = credentialFieldLabel(field);
358544
+ return { field, name: label.name, where: label.where };
358545
+ }),
358546
+ supportsProvisioning: id === "teams",
358547
+ requiresInvite: id === "slack"
358548
+ }));
358549
+ }
358550
+ var CHANNEL_PROVIDER_LABELS, CREDENTIAL_FIELDS_BY_PROVIDER;
358551
+ var init_channel_provider_catalog = __esm({
358552
+ "apps/cli/src/services/channel-provider-catalog.ts"() {
358553
+ "use strict";
358554
+ init_channels();
358555
+ init_channel_credentials();
358556
+ CHANNEL_PROVIDER_LABELS = Object.freeze({
358557
+ slack: "Slack",
358558
+ teams: "Microsoft Teams"
358559
+ });
358560
+ CREDENTIAL_FIELDS_BY_PROVIDER = Object.freeze({
358561
+ slack: ["channelToken", "signingSecret"],
358562
+ teams: ["clientId", "clientSecret", "tenantId"]
358563
+ });
358564
+ }
358565
+ });
358566
+
358280
358567
  // apps/cli/src/ui/channel-offer.tsx
358281
358568
  function ChannelOffer(props) {
358282
358569
  const indexRef = (0, import_react47.useRef)(0);
@@ -358340,10 +358627,11 @@ var init_channel_offer = __esm({
358340
358627
  await init_build2();
358341
358628
  import_react47 = __toESM(require_react(), 1);
358342
358629
  init_theme();
358630
+ init_channel_provider_catalog();
358343
358631
  import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1);
358344
358632
  CHOICES2 = [
358345
- { adapter: "slack", label: "Slack" },
358346
- { adapter: "teams", label: "Microsoft Teams" },
358633
+ { adapter: "slack", label: CHANNEL_PROVIDER_LABELS.slack },
358634
+ { adapter: "teams", label: CHANNEL_PROVIDER_LABELS.teams },
358347
358635
  { adapter: void 0, label: "Not now" }
358348
358636
  ];
358349
358637
  }
@@ -359014,6 +359302,17 @@ function ScaffoldProgress({
359014
359302
  const installAlreadyRanRef = (0, import_react48.useRef)(false);
359015
359303
  const [credentialRequest, setCredentialRequest] = (0, import_react48.useState)(null);
359016
359304
  const [attachingChannel, setAttachingChannel] = (0, import_react48.useState)(false);
359305
+ const channelFlagError = (0, import_react48.useMemo)(
359306
+ () => options.framework === null ? void 0 : channelFlagUnsupportedError(
359307
+ options.channel ?? null,
359308
+ options.framework
359309
+ ),
359310
+ [options.channel, options.framework]
359311
+ );
359312
+ const flagChannelOffer = (0, import_react48.useMemo)(
359313
+ () => channelOfferFromFlag(options.channel ?? null),
359314
+ [options.channel]
359315
+ );
359017
359316
  const scaffoldDependencies = (0, import_react48.useMemo)(
359018
359317
  () => ({
359019
359318
  ...defaultInitScaffoldDependencies,
@@ -359033,18 +359332,32 @@ function ScaffoldProgress({
359033
359332
  // render branch, so a non-interactive run has nothing to drive it and would
359034
359333
  // wait on a deferred that never settles -- an init that hangs forever is far
359035
359334
  // worse than an init that simply does not offer a Channel.
359036
- ...(dependencies?.isVendorKeyPromptInteractive ?? vendorKeyPromptInteractive)() ? {
359037
- offerChannelAdapter: () => new Promise((resolve4) => {
359335
+ //
359336
+ // A `--channel` value overrides that entirely: the offer is pre-answered,
359337
+ // so it resolves immediately, nothing renders, and there is no keypress to
359338
+ // mistime. That is what makes the flag safe under a pty, where stdin looks
359339
+ // interactive but nobody is watching and the cursor starts on Slack.
359340
+ ...flagChannelOffer !== void 0 || (dependencies?.isVendorKeyPromptInteractive ?? vendorKeyPromptInteractive)() ? {
359341
+ offerChannelAdapter: flagChannelOffer ?? (() => new Promise((resolve4) => {
359038
359342
  channelOfferDeferredRef.current = { resolve: resolve4 };
359039
- }),
359343
+ })),
359040
359344
  setUpChannel: (input) => runInitChannelSetup(input),
359041
- completeChannelSetup: (input) => runInitChannelCompletion(input)
359345
+ // Guided completion is a PROMPT -- it renders ChannelCredentialPrompt
359346
+ // and asks for a provider secret -- so it is wired only for a run that
359347
+ // may legitimately prompt. Gating it on interactivity alone was wrong:
359348
+ // under a pty vendorKeyPromptInteractive() is true, so a `--channel`
359349
+ // run had its offer suppressed and was then asked for a Slack token
359350
+ // anyway. A flag-driven Channel stays silent end to end and reports
359351
+ // what is outstanding instead.
359352
+ ...flagChannelOffer === void 0 ? {
359353
+ completeChannelSetup: (input) => runInitChannelCompletion(input)
359354
+ } : {}
359042
359355
  } : {},
359043
359356
  // Test-injected deps win over the inline wiring above; the production
359044
359357
  // shell (InitApp) passes none, so the inline selectHostedProject stands.
359045
359358
  ...dependencies
359046
359359
  }),
359047
- [browserLogin.runLogin, dependencies]
359360
+ [browserLogin.runLogin, dependencies, flagChannelOffer]
359048
359361
  );
359049
359362
  (0, import_react48.useEffect)(() => {
359050
359363
  if (phase === "success" || phase === "error") {
@@ -359076,6 +359389,16 @@ function ScaffoldProgress({
359076
359389
  }, [phase, scaffoldResult]);
359077
359390
  (0, import_react48.useEffect)(() => {
359078
359391
  let cancelled = false;
359392
+ if (channelFlagError !== void 0) {
359393
+ const error48 = new Error(channelFlagError);
359394
+ error48.displayed = true;
359395
+ scaffoldErrorRef.current = error48;
359396
+ setErrorMessage(channelFlagError);
359397
+ setPhase("error");
359398
+ return () => {
359399
+ cancelled = true;
359400
+ };
359401
+ }
359079
359402
  async function run() {
359080
359403
  const result = await scaffoldInitProject(
359081
359404
  options,
@@ -359485,18 +359808,20 @@ function InitApp({
359485
359808
  initialFramework,
359486
359809
  noBanner = false,
359487
359810
  initialMock = false,
359811
+ initialChannel = null,
359488
359812
  renderScaffoldProgress = renderDefaultScaffoldProgress,
359489
359813
  onIntelligenceSelected,
359490
359814
  onFrameworkSelected,
359491
359815
  telemetry
359492
359816
  }) {
359493
359817
  const mock = initialMock === true;
359494
- const prefilled = resolvePrefilledOptions(
359818
+ const prefilledBase = resolvePrefilledOptions(
359495
359819
  initialName,
359496
359820
  initialIntelligence,
359497
359821
  initialFramework,
359498
359822
  mock
359499
359823
  );
359824
+ const prefilled = prefilledBase === null ? null : { ...prefilledBase, channel: initialChannel };
359500
359825
  const [options, setOptions] = (0, import_react48.useState)(prefilled);
359501
359826
  (0, import_react48.useEffect)(() => {
359502
359827
  if (prefilled !== null) {
@@ -359530,7 +359855,7 @@ function InitApp({
359530
359855
  onFrameworkSelected,
359531
359856
  onComplete: (resolved) => {
359532
359857
  if (resolved !== null) {
359533
- setOptions({ ...resolved, mock });
359858
+ setOptions({ ...resolved, mock, channel: initialChannel });
359534
359859
  }
359535
359860
  }
359536
359861
  }
@@ -359573,6 +359898,7 @@ async function runInit(flags, callbacks) {
359573
359898
  initialIntelligence,
359574
359899
  initialFramework,
359575
359900
  initialMock: flags.mock ?? false,
359901
+ initialChannel: flags.channel ?? null,
359576
359902
  noBanner: flags.noBanner === true,
359577
359903
  onIntelligenceSelected: callbacks?.onIntelligenceSelected,
359578
359904
  onFrameworkSelected: callbacks?.onFrameworkSelected,
@@ -359611,6 +359937,7 @@ var init_init = __esm({
359611
359937
  await init_spinner();
359612
359938
  await init_success_text();
359613
359939
  await init_channels_events();
359940
+ init_init_channel_flag();
359614
359941
  init_config();
359615
359942
  init_init_channel_setup();
359616
359943
  await init_channel_completion();
@@ -360397,6 +360724,79 @@ var init_channels_preflight = __esm({
360397
360724
  }
360398
360725
  });
360399
360726
 
360727
+ // apps/cli/src/commands/channel-providers.ts
360728
+ var channel_providers_exports = {};
360729
+ __export(channel_providers_exports, {
360730
+ listChannelProviders: () => listChannelProviders,
360731
+ renderChannelProviderJson: () => renderChannelProviderJson,
360732
+ renderChannelProviderTable: () => renderChannelProviderTable,
360733
+ runChannelProviders: () => runChannelProviders
360734
+ });
360735
+ function renderChannelProviderTable(providers) {
360736
+ const blocks = providers.map((provider) => {
360737
+ const header = ` ${provider.id} (${provider.label})`;
360738
+ const notes = [];
360739
+ if (provider.supportsProvisioning) {
360740
+ notes.push(
360741
+ ` The CLI can create the provider-side app for you: \`channels add --adapter ${provider.id} --provision\`.`
360742
+ );
360743
+ } else {
360744
+ notes.push(
360745
+ ` You create the ${provider.label} app yourself; the CLI attaches to it.`
360746
+ );
360747
+ }
360748
+ if (provider.requiresInvite) {
360749
+ notes.push(
360750
+ " Invite the bot to a conversation after attaching. Installed but",
360751
+ " invited nowhere, it answers nothing and looks like a broken Channel."
360752
+ );
360753
+ }
360754
+ const credentials = provider.credentialFields.map(
360755
+ (credential) => ` ${credential.field} \u2014 "${credential.name}", from ${credential.where}`
360756
+ );
360757
+ return [
360758
+ header,
360759
+ ...notes,
360760
+ " Credentials it will ask for:",
360761
+ ...credentials
360762
+ ].join("\n");
360763
+ });
360764
+ return `Chat providers a managed Channel can use:
360765
+
360766
+ ${blocks.join("\n\n")}
360767
+
360768
+ Pass one to \`channels add --adapter <id>\` or \`init --channel <id>\`.
360769
+ No flag accepts a credential value: credentials are read from your .env, from
360770
+ a named variable, or from a JSON document on stdin.
360771
+ `;
360772
+ }
360773
+ function renderChannelProviderJson(providers) {
360774
+ return `${JSON.stringify(
360775
+ {
360776
+ envelopeVersion: CHANNELS_ENVELOPE_VERSION,
360777
+ command: "channels providers",
360778
+ providers
360779
+ },
360780
+ null,
360781
+ 2
360782
+ )}
360783
+ `;
360784
+ }
360785
+ async function runChannelProviders(options) {
360786
+ const providers = listChannelProviders();
360787
+ process.stdout.write(
360788
+ options.json ? renderChannelProviderJson(providers) : renderChannelProviderTable(providers)
360789
+ );
360790
+ return Promise.resolve();
360791
+ }
360792
+ var init_channel_providers = __esm({
360793
+ "apps/cli/src/commands/channel-providers.ts"() {
360794
+ "use strict";
360795
+ init_src11();
360796
+ init_channel_provider_catalog();
360797
+ }
360798
+ });
360799
+
360400
360800
  // apps/cli/src/commands/channels.ts
360401
360801
  var channels_exports = {};
360402
360802
  __export(channels_exports, {
@@ -360566,6 +360966,51 @@ async function runChannels(argv) {
360566
360966
  process.exitCode = 1;
360567
360967
  return;
360568
360968
  }
360969
+ if (subcommand === "providers") {
360970
+ let providersJson = false;
360971
+ try {
360972
+ const providersArgs = parseArgs2({
360973
+ allowPositionals: false,
360974
+ args: [...argv.slice(1)],
360975
+ options: { json: { type: "boolean" } },
360976
+ strict: true
360977
+ });
360978
+ providersJson = providersArgs.values.json === true;
360979
+ } catch (error48) {
360980
+ recordTelemetryEvent({
360981
+ properties: {
360982
+ command: "channels",
360983
+ subcommand: "providers",
360984
+ outcome: "failed",
360985
+ error_code: "validation"
360986
+ }
360987
+ });
360988
+ process.stderr.write(
360989
+ `${error48 instanceof Error ? error48.message : String(error48)}
360990
+ Usage: copilotkit channels providers [--json]
360991
+ `
360992
+ );
360993
+ process.exitCode = 1;
360994
+ return;
360995
+ }
360996
+ recordTelemetryEvent({
360997
+ properties: {
360998
+ command: "channels",
360999
+ subcommand: "providers",
361000
+ outcome: "started"
361001
+ }
361002
+ });
361003
+ const { runChannelProviders: runChannelProviders2 } = await Promise.resolve().then(() => (init_channel_providers(), channel_providers_exports));
361004
+ await runChannelProviders2({ json: providersJson });
361005
+ recordTelemetryEvent({
361006
+ properties: {
361007
+ command: "channels",
361008
+ subcommand: "providers",
361009
+ outcome: "succeeded"
361010
+ }
361011
+ });
361012
+ return;
361013
+ }
360569
361014
  const parsed = parseArgs2({
360570
361015
  allowPositionals: true,
360571
361016
  args: [...argv.slice(1)],
@@ -360847,6 +361292,7 @@ var init_channels2 = __esm({
360847
361292
  SUBCOMMANDS = [
360848
361293
  "add",
360849
361294
  "list",
361295
+ "providers",
360850
361296
  "rotate",
360851
361297
  "status"
360852
361298
  ];
@@ -361368,7 +361814,9 @@ Commands:
361368
361814
  license list List CopilotKit license metadata
361369
361815
  license ls Alias of license list
361370
361816
  project select Select or create a hosted Intelligence project
361817
+ framework list List the agent frameworks init accepts, and their flags
361371
361818
  channels Set up managed Intelligence Channels (Slack, Teams)
361819
+ channels providers List the chat providers a Channel can use
361372
361820
  skills install Install the CopilotKit agent skills
361373
361821
  skills onboard Install skills and start agent-assisted onboarding
361374
361822
  ${isCliFlagEnabled("cli.aimock-mock-mode") ? " mock enable Wire a scaffolded project to run keyless against a local mock LLM\n mock disable Restore a real vendor API key and remove mock wiring\n" : ""} import [options] Import ADK/LangGraph threads into Intelligence
@@ -361440,7 +361888,18 @@ Options:
361440
361888
  persistence, insights) ships with every supported
361441
361889
  framework and a free license is provisioned during init.
361442
361890
  ${isCliFlagEnabled("cli.aimock-mock-mode") ? ` --mock Run keyless against a local mock LLM (supported: ${formatMockSupportedFrameworks()}).
361443
- ` : ""} --no-banner Suppress the CopilotKit welcome banner (used when a
361891
+ ` : ""} --channel <what> Pre-answer the managed Channel offer: slack, teams, or
361892
+ none. With this flag the offer is never shown, so a
361893
+ scripted run cannot land on a provider by mistiming a
361894
+ keystroke. \`none\` declines it outright.
361895
+
361896
+ Accepted only for frameworks whose starter ships a
361897
+ Channel host; run \`copilotkit framework list\` to see
361898
+ which, and \`copilotkit channels providers\` for what each
361899
+ provider will ask you for. A named provider is set up as
361900
+ far as it can go without credentials, then reports what
361901
+ is left -- it never prompts for a secret.
361902
+ --no-banner Suppress the CopilotKit welcome banner (used when a
361444
361903
  parent tool, e.g. create-ag-ui-app, shows its own)
361445
361904
  -h, --help Show help for init
361446
361905
  `,
@@ -361479,6 +361938,12 @@ Subcommands:
361479
361938
  add [name] Declare a Channel, reconcile it, and report the next step
361480
361939
  status Compare your configuration, your code, and the server
361481
361940
  list List Channels and their attachment state
361941
+ providers List the chat providers a Channel can use, and the
361942
+ credentials each one asks for. Answers from a catalog
361943
+ compiled into this CLI: no project, no credentials, no
361944
+ API call, no TTY. Emits a catalog response rather than the
361945
+ operation envelope. Distinct from \`list\`, which reports
361946
+ YOUR Channels.
361482
361947
  rotate <name> Explicitly replace stored provider credentials
361483
361948
  setup Print a setup prompt for your coding agent and copy it
361484
361949
  to the clipboard, then paste it into Claude
@@ -361534,6 +361999,44 @@ persist the choice to .copilotkit/project.json.
361534
361999
 
361535
362000
  Options:
361536
362001
  -h, --help Show help for project select
362002
+ `,
362003
+ framework: `Usage: copilotkit framework <subcommand>
362004
+
362005
+ Inspect the agent frameworks \`copilotkit init\` can scaffold.
362006
+
362007
+ Subcommands:
362008
+ list List every framework and the init flags it accepts
362009
+
362010
+ Options:
362011
+ -h, --help Show help for framework
362012
+ `,
362013
+ "framework-list": `Usage: copilotkit framework list [options]
362014
+
362015
+ List every agent framework \`copilotkit init -f <id>\` accepts, with the id to
362016
+ pass, the language its agent is written in, and the init flags that framework
362017
+ supports.
362018
+
362019
+ Answers from a catalog compiled into this CLI binary, so it needs no API call, no
362020
+ authentication and no TTY, and cannot fail once the arguments parse \u2014 there is no
362021
+ signed-out or offline case to handle. (Anonymous usage telemetry is still sent
362022
+ unless you have opted out; it is best-effort and never blocks or alters the
362023
+ output.)
362024
+
362025
+ Each row lists only the flags that framework accepts:
362026
+ -i Intelligence threads are available to license
362027
+ --mock A keyless mock model can stand in for a vendor key
362028
+ --channel The starter ships a managed Channel host, so
362029
+ \`init --channel\` can serve Slack or Teams
362030
+
362031
+ Frameworks needing a vendor API key are footnoted with the variable name, so you
362032
+ can have the value ready before scaffolding rather than meeting the prompt.
362033
+
362034
+ Options:
362035
+ --json Emit a machine-readable payload as the ONLY thing on
362036
+ stdout, safe to pipe into a parser. Each entry adds the
362037
+ accepted \`-f\` aliases and whether each environment key
362038
+ is required.
362039
+ -h, --help Show help for framework list
361537
362040
  `,
361538
362041
  skills: `Usage: copilotkit skills <subcommand>
361539
362042
 
@@ -361732,6 +362235,12 @@ function resolveCommandHelpTopic(argv) {
361732
362235
  }
361733
362236
  return "project";
361734
362237
  }
362238
+ if (command === "framework" || command === "frameworks") {
362239
+ if (subcommand === "list" || subcommand === "ls") {
362240
+ return "framework-list";
362241
+ }
362242
+ return "framework";
362243
+ }
361735
362244
  if (command === "skills") {
361736
362245
  if (subcommand === "install") {
361737
362246
  return "skills-install";
@@ -361958,6 +362467,39 @@ ${HELP_TEXT_BY_TOPIC.root}`
361958
362467
  }
361959
362468
  );
361960
362469
  }
362470
+ async function runFrameworkCommand(argv) {
362471
+ const subcommand = argv[0];
362472
+ if (subcommand !== "list" && subcommand !== "ls") {
362473
+ recordTelemetryEvent({
362474
+ properties: {
362475
+ command: "framework",
362476
+ outcome: "failed",
362477
+ error_code: "validation"
362478
+ }
362479
+ });
362480
+ const lead = subcommand === void 0 ? "Error: copilotkit framework requires a subcommand (list).\n\n" : `Unknown framework subcommand: "${subcommand}"
362481
+
362482
+ `;
362483
+ process.stderr.write(`${lead}${HELP_TEXT_BY_TOPIC.framework}`);
362484
+ await exitWithFlush(1);
362485
+ return;
362486
+ }
362487
+ const parsed = parseArgs3({
362488
+ args: [...argv.slice(1)],
362489
+ options: {
362490
+ json: { type: "boolean" }
362491
+ },
362492
+ strict: true,
362493
+ allowPositionals: false
362494
+ });
362495
+ const { runFrameworkList: runFrameworkList2 } = await Promise.resolve().then(() => (init_framework_list(), framework_list_exports));
362496
+ await withTelemetry(
362497
+ { command: "framework", subcommand: "list" },
362498
+ async () => {
362499
+ await runFrameworkList2({ json: parsed.values["json"] === true });
362500
+ }
362501
+ );
362502
+ }
361961
362503
  async function runProjectCommand(argv) {
361962
362504
  const subcommand = argv[0];
361963
362505
  if (subcommand !== "select") {
@@ -362272,6 +362814,7 @@ var INIT_PARSE_OPTIONS = {
362272
362814
  intelligence: { type: "boolean", short: "i" },
362273
362815
  framework: { type: "string", short: "f" },
362274
362816
  mock: { type: "boolean" },
362817
+ channel: { type: "string" },
362275
362818
  "no-banner": { type: "boolean" }
362276
362819
  };
362277
362820
  async function runInitCommand(invokedAs, argv) {
@@ -362289,8 +362832,29 @@ async function runInitCommand(invokedAs, argv) {
362289
362832
  const telemetryBase = initTelemetryBase(invokedAs, {
362290
362833
  intelligence,
362291
362834
  framework,
362292
- mock
362835
+ mock,
362836
+ // Raw, and read before validation on purpose: the base has to exist for the
362837
+ // validation-failure event below to be reportable.
362838
+ channel: parsed.values["channel"]
362839
+ });
362840
+ const { resolveInitChannelFlag: resolveInitChannelFlag2 } = await Promise.resolve().then(() => (init_init_channel_flag(), init_channel_flag_exports));
362841
+ const channelResolution = resolveInitChannelFlag2({
362842
+ value: parsed.values["channel"],
362843
+ framework: frameworkFlag
362293
362844
  });
362845
+ if (channelResolution.status === "invalid") {
362846
+ recordTelemetryEvent({
362847
+ properties: {
362848
+ ...telemetryBase,
362849
+ outcome: "failed",
362850
+ error_code: "validation"
362851
+ }
362852
+ });
362853
+ process.stderr.write(`Error: ${channelResolution.message}
362854
+ `);
362855
+ await exitWithFlush(1);
362856
+ return;
362857
+ }
362294
362858
  if (!process.stdin.isTTY) {
362295
362859
  recordTelemetryEvent({
362296
362860
  properties: {
@@ -362338,6 +362902,7 @@ async function runInitCommand(invokedAs, argv) {
362338
362902
  intelligence,
362339
362903
  framework,
362340
362904
  mock,
362905
+ channel: channelResolution.channel,
362341
362906
  noBanner: parsed.values["no-banner"]
362342
362907
  };
362343
362908
  await withTelemetry(telemetryBase, async (ctx) => {
@@ -362413,6 +362978,18 @@ var COMMAND_TABLE = {
362413
362978
  await runProjectCommand(argv);
362414
362979
  }
362415
362980
  },
362981
+ framework: {
362982
+ kind: "self",
362983
+ run: async (argv) => {
362984
+ await runFrameworkCommand(argv);
362985
+ }
362986
+ },
362987
+ frameworks: {
362988
+ kind: "self",
362989
+ run: async (argv) => {
362990
+ await runFrameworkCommand(argv);
362991
+ }
362992
+ },
362416
362993
  skills: {
362417
362994
  kind: "self",
362418
362995
  run: async (argv) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "copilotkit",
3
- "version": "4.7.0",
3
+ "version": "4.8.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14683,7 +14683,7 @@ import * as path4 from "node:path";
14683
14683
 
14684
14684
  // apps/cli/src/config.ts
14685
14685
  function getTemplateRef() {
14686
- return true ? "8e59bfd16b415b9f776a4742aa43942a8d02c2ef" : "main";
14686
+ return true ? "b30527ca8a430490ba3b8866304f1451baa252af" : "main";
14687
14687
  }
14688
14688
 
14689
14689
  // apps/cli/src/services/agentcore-config.ts