copilotkit 1.54.0 → 2.0.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/index.js +89779 -0
- package/package.json +4 -114
- package/src/commands/docs.d.ts +17 -0
- package/src/commands/docs.d.ts.map +1 -0
- package/src/commands/init.d.ts +103 -0
- package/src/commands/init.d.ts.map +1 -0
- package/src/commands/kite.d.ts +8 -0
- package/src/commands/kite.d.ts.map +1 -0
- package/src/commands/license.d.ts +17 -0
- package/src/commands/license.d.ts.map +1 -0
- package/src/commands/login.d.ts +13 -0
- package/src/commands/login.d.ts.map +1 -0
- package/src/commands/logs.d.ts +32 -0
- package/src/commands/logs.d.ts.map +1 -0
- package/src/commands/version.d.ts +8 -0
- package/src/commands/version.d.ts.map +1 -0
- package/src/config.d.ts +31 -0
- package/src/config.d.ts.map +1 -0
- package/src/index.d.ts +21 -0
- package/src/index.d.ts.map +1 -0
- package/src/services/api-client.d.ts +106 -0
- package/src/services/api-client.d.ts.map +1 -0
- package/src/services/auth.service.d.ts +107 -0
- package/src/services/auth.service.d.ts.map +1 -0
- package/src/services/cli-auth-diagnostics.d.ts +71 -0
- package/src/services/cli-auth-diagnostics.d.ts.map +1 -0
- package/src/services/cli-logs.d.ts +45 -0
- package/src/services/cli-logs.d.ts.map +1 -0
- package/src/services/config.service.d.ts +53 -0
- package/src/services/config.service.d.ts.map +1 -0
- package/src/services/feature-flags.d.ts +14 -0
- package/src/services/feature-flags.d.ts.map +1 -0
- package/src/services/kite-game-engine.d.ts +99 -0
- package/src/services/kite-game-engine.d.ts.map +1 -0
- package/src/services/kite-game-score.d.ts +33 -0
- package/src/services/kite-game-score.d.ts.map +1 -0
- package/src/services/project-scaffold.d.ts +49 -0
- package/src/services/project-scaffold.d.ts.map +1 -0
- package/src/types.d.ts +205 -0
- package/src/types.d.ts.map +1 -0
- package/src/ui/banner.d.ts +3 -0
- package/src/ui/banner.d.ts.map +1 -0
- package/src/ui/browser-login.d.ts +71 -0
- package/src/ui/browser-login.d.ts.map +1 -0
- package/src/ui/init-flow.d.ts +35 -0
- package/src/ui/init-flow.d.ts.map +1 -0
- package/src/ui/kite-game.d.ts +26 -0
- package/src/ui/kite-game.d.ts.map +1 -0
- package/src/ui/login-flow.d.ts +22 -0
- package/src/ui/login-flow.d.ts.map +1 -0
- package/src/ui/spinner.d.ts +9 -0
- package/src/ui/spinner.d.ts.map +1 -0
- package/LICENSE +0 -21
- package/README.md +0 -83
- package/bin/dev.cmd +0 -3
- package/bin/dev.js +0 -8
- package/bin/run.cmd +0 -3
- package/bin/run.js +0 -17
- package/dist/commands/base-command.d.ts +0 -12
- package/dist/commands/base-command.js +0 -65
- package/dist/commands/base-command.js.map +0 -1
- package/dist/commands/create.d.ts +0 -24
- package/dist/commands/create.js +0 -507
- package/dist/commands/create.js.map +0 -1
- package/dist/commands/dev.d.ts +0 -25
- package/dist/commands/dev.js +0 -776
- package/dist/commands/dev.js.map +0 -1
- package/dist/commands/init.d.ts +0 -11
- package/dist/commands/init.js +0 -523
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/login.d.ts +0 -13
- package/dist/commands/login.js +0 -374
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts +0 -13
- package/dist/commands/logout.js +0 -375
- package/dist/commands/logout.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -6
- package/dist/index.js.map +0 -1
- package/dist/lib/init/ide-docs.d.ts +0 -25
- package/dist/lib/init/ide-docs.js +0 -170
- package/dist/lib/init/ide-docs.js.map +0 -1
- package/dist/lib/init/index.d.ts +0 -14
- package/dist/lib/init/index.js +0 -1104
- package/dist/lib/init/index.js.map +0 -1
- package/dist/lib/init/questions.d.ts +0 -9
- package/dist/lib/init/questions.js +0 -508
- package/dist/lib/init/questions.js.map +0 -1
- package/dist/lib/init/scaffold/agent.d.ts +0 -20
- package/dist/lib/init/scaffold/agent.js +0 -173
- package/dist/lib/init/scaffold/agent.js.map +0 -1
- package/dist/lib/init/scaffold/crew-inputs.d.ts +0 -3
- package/dist/lib/init/scaffold/crew-inputs.js +0 -59
- package/dist/lib/init/scaffold/crew-inputs.js.map +0 -1
- package/dist/lib/init/scaffold/env.d.ts +0 -7
- package/dist/lib/init/scaffold/env.js +0 -124
- package/dist/lib/init/scaffold/env.js.map +0 -1
- package/dist/lib/init/scaffold/github.d.ts +0 -17
- package/dist/lib/init/scaffold/github.js +0 -114
- package/dist/lib/init/scaffold/github.js.map +0 -1
- package/dist/lib/init/scaffold/index.d.ts +0 -10
- package/dist/lib/init/scaffold/index.js +0 -690
- package/dist/lib/init/scaffold/index.js.map +0 -1
- package/dist/lib/init/scaffold/langgraph-assistants.d.ts +0 -18
- package/dist/lib/init/scaffold/langgraph-assistants.js +0 -26
- package/dist/lib/init/scaffold/langgraph-assistants.js.map +0 -1
- package/dist/lib/init/scaffold/packages.d.ts +0 -7
- package/dist/lib/init/scaffold/packages.js +0 -62
- package/dist/lib/init/scaffold/packages.js.map +0 -1
- package/dist/lib/init/scaffold/shadcn.d.ts +0 -7
- package/dist/lib/init/scaffold/shadcn.js +0 -279
- package/dist/lib/init/scaffold/shadcn.js.map +0 -1
- package/dist/lib/init/types/index.d.ts +0 -4
- package/dist/lib/init/types/index.js +0 -238
- package/dist/lib/init/types/index.js.map +0 -1
- package/dist/lib/init/types/questions.d.ts +0 -209
- package/dist/lib/init/types/questions.js +0 -214
- package/dist/lib/init/types/questions.js.map +0 -1
- package/dist/lib/init/types/templates.d.ts +0 -17
- package/dist/lib/init/types/templates.js +0 -26
- package/dist/lib/init/types/templates.js.map +0 -1
- package/dist/lib/init/utils.d.ts +0 -3
- package/dist/lib/init/utils.js +0 -8
- package/dist/lib/init/utils.js.map +0 -1
- package/dist/services/analytics.service.d.ts +0 -38
- package/dist/services/analytics.service.js +0 -134
- package/dist/services/analytics.service.js.map +0 -1
- package/dist/services/auth.service.d.ts +0 -26
- package/dist/services/auth.service.js +0 -299
- package/dist/services/auth.service.js.map +0 -1
- package/dist/services/events.d.ts +0 -119
- package/dist/services/events.js +0 -1
- package/dist/services/events.js.map +0 -1
- package/dist/services/tunnel.service.d.ts +0 -15
- package/dist/services/tunnel.service.js +0 -21
- package/dist/services/tunnel.service.js.map +0 -1
- package/dist/utils/detect-endpoint-type.utils.d.ts +0 -15
- package/dist/utils/detect-endpoint-type.utils.js +0 -157
- package/dist/utils/detect-endpoint-type.utils.js.map +0 -1
- package/dist/utils/trpc.d.ts +0 -4
- package/dist/utils/trpc.js +0 -25
- package/dist/utils/trpc.js.map +0 -1
- package/dist/utils/version.d.ts +0 -3
- package/dist/utils/version.js +0 -6
- package/dist/utils/version.js.map +0 -1
- package/oclif.manifest.json +0 -208
package/dist/commands/dev.js
DELETED
|
@@ -1,776 +0,0 @@
|
|
|
1
|
-
// src/commands/dev.ts
|
|
2
|
-
import { Flags } from "@oclif/core";
|
|
3
|
-
import inquirer2 from "inquirer";
|
|
4
|
-
import { createId } from "@paralleldrive/cuid2";
|
|
5
|
-
import ora2 from "ora";
|
|
6
|
-
import chalk3 from "chalk";
|
|
7
|
-
|
|
8
|
-
// src/services/auth.service.ts
|
|
9
|
-
import Conf2 from "conf";
|
|
10
|
-
import cors from "cors";
|
|
11
|
-
import express from "express";
|
|
12
|
-
import crypto2 from "crypto";
|
|
13
|
-
import open from "open";
|
|
14
|
-
import getPort from "get-port";
|
|
15
|
-
import ora from "ora";
|
|
16
|
-
import chalk from "chalk";
|
|
17
|
-
import inquirer from "inquirer";
|
|
18
|
-
|
|
19
|
-
// src/utils/trpc.ts
|
|
20
|
-
import { createTRPCClient as trpcClient, httpBatchLink } from "@trpc/client";
|
|
21
|
-
import superjson from "superjson";
|
|
22
|
-
var COPILOT_CLOUD_BASE_URL = process.env.COPILOT_CLOUD_BASE_URL || "https://cloud.copilotkit.ai";
|
|
23
|
-
function createTRPCClient(cliToken) {
|
|
24
|
-
return trpcClient({
|
|
25
|
-
links: [
|
|
26
|
-
httpBatchLink({
|
|
27
|
-
url: `${COPILOT_CLOUD_BASE_URL}/api/trpc-cli`,
|
|
28
|
-
transformer: superjson,
|
|
29
|
-
headers: () => {
|
|
30
|
-
return {
|
|
31
|
-
"x-trpc-source": "cli",
|
|
32
|
-
"x-cli-token": cliToken
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
})
|
|
36
|
-
]
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// src/services/analytics.service.ts
|
|
41
|
-
import { Analytics } from "@segment/analytics-node";
|
|
42
|
-
import { PostHog } from "posthog-node";
|
|
43
|
-
import Conf from "conf";
|
|
44
|
-
var AnalyticsService = class {
|
|
45
|
-
constructor(authData) {
|
|
46
|
-
this.authData = authData;
|
|
47
|
-
if (process.env.SEGMENT_DISABLED === "true") {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const segmentWriteKey = process.env.SEGMENT_WRITE_KEY || "9Pv6QyExYef2P4hPz4gks6QAvNMi2AOf";
|
|
51
|
-
this.globalProperties = {
|
|
52
|
-
service: "cli"
|
|
53
|
-
};
|
|
54
|
-
if (this.authData?.userId) {
|
|
55
|
-
this.userId = this.authData.userId;
|
|
56
|
-
}
|
|
57
|
-
if (this.authData?.email) {
|
|
58
|
-
this.email = this.authData.email;
|
|
59
|
-
this.globalProperties.email = this.authData.email;
|
|
60
|
-
}
|
|
61
|
-
if (this.authData?.organizationId) {
|
|
62
|
-
this.organizationId = this.authData.organizationId;
|
|
63
|
-
}
|
|
64
|
-
this.segment = new Analytics({
|
|
65
|
-
writeKey: segmentWriteKey,
|
|
66
|
-
disable: process.env.SEGMENT_DISABLE === "true"
|
|
67
|
-
});
|
|
68
|
-
if (process.env.POSTHOG_DISABLED !== "true") {
|
|
69
|
-
const posthogKey = process.env.POSTHOG_KEY || "phc_XZdymVYjrph9Mi0xZYGNyCKexxgblXRR1jMENCtdz5Q";
|
|
70
|
-
const posthogHost = process.env.POSTHOG_HOST || "https://eu.i.posthog.com";
|
|
71
|
-
this.posthog = new PostHog(posthogKey, {
|
|
72
|
-
host: posthogHost
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
const config = new Conf({ projectName: "CopilotKitCLI" });
|
|
76
|
-
if (!config.get("anonymousId")) {
|
|
77
|
-
config.set("anonymousId", crypto.randomUUID());
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
segment;
|
|
81
|
-
posthog;
|
|
82
|
-
globalProperties = {};
|
|
83
|
-
userId;
|
|
84
|
-
email;
|
|
85
|
-
organizationId;
|
|
86
|
-
config = new Conf({ projectName: "CopilotKitCLI" });
|
|
87
|
-
getAnonymousId() {
|
|
88
|
-
const anonymousId = this.config.get("anonymousId");
|
|
89
|
-
if (!anonymousId) {
|
|
90
|
-
const anonymousId2 = crypto.randomUUID();
|
|
91
|
-
this.config.set("anonymousId", anonymousId2);
|
|
92
|
-
return anonymousId2;
|
|
93
|
-
}
|
|
94
|
-
return anonymousId;
|
|
95
|
-
}
|
|
96
|
-
track(event) {
|
|
97
|
-
if (!this.segment) {
|
|
98
|
-
return Promise.resolve();
|
|
99
|
-
}
|
|
100
|
-
const payload = {
|
|
101
|
-
userId: this.userId ? this.userId : void 0,
|
|
102
|
-
email: this.email ? this.email : void 0,
|
|
103
|
-
anonymousId: this.getAnonymousId(),
|
|
104
|
-
event: event.event,
|
|
105
|
-
properties: {
|
|
106
|
-
...this.globalProperties,
|
|
107
|
-
...event.properties,
|
|
108
|
-
$groups: this.organizationId ? {
|
|
109
|
-
segment_group: this.organizationId
|
|
110
|
-
} : void 0,
|
|
111
|
-
eventProperties: {
|
|
112
|
-
...event.properties,
|
|
113
|
-
...this.globalProperties
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
return new Promise((resolve, reject) => {
|
|
118
|
-
this.segment.track(payload, (err) => {
|
|
119
|
-
if (err) {
|
|
120
|
-
resolve();
|
|
121
|
-
}
|
|
122
|
-
resolve();
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Check if a feature flag is enabled
|
|
128
|
-
*/
|
|
129
|
-
async isFeatureEnabled(flagKey) {
|
|
130
|
-
if (!this.posthog) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
const distinctId = this.userId || this.getAnonymousId();
|
|
135
|
-
const flag = await this.posthog.isFeatureEnabled(flagKey, distinctId);
|
|
136
|
-
return Boolean(flag);
|
|
137
|
-
} catch (error) {
|
|
138
|
-
console.warn(`Failed to check feature flag ${flagKey}:`, error);
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Get feature flag payload
|
|
144
|
-
*/
|
|
145
|
-
async getFeatureFlagPayload(flagKey) {
|
|
146
|
-
if (!this.posthog) {
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
try {
|
|
150
|
-
const distinctId = this.userId || this.getAnonymousId();
|
|
151
|
-
const payload = await this.posthog.getFeatureFlagPayload(
|
|
152
|
-
flagKey,
|
|
153
|
-
distinctId
|
|
154
|
-
);
|
|
155
|
-
return payload;
|
|
156
|
-
} catch (error) {
|
|
157
|
-
console.warn(`Failed to get feature flag payload ${flagKey}:`, error);
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Shutdown analytics services
|
|
163
|
-
*/
|
|
164
|
-
async shutdown() {
|
|
165
|
-
if (this.posthog) {
|
|
166
|
-
await this.posthog.shutdown();
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
// src/services/auth.service.ts
|
|
172
|
-
var AuthService = class {
|
|
173
|
-
config = new Conf2({ projectName: "CopilotKitCLI" });
|
|
174
|
-
COPILOT_CLOUD_BASE_URL = process.env.COPILOT_CLOUD_BASE_URL || "https://cloud.copilotkit.ai";
|
|
175
|
-
getToken() {
|
|
176
|
-
return this.config.get("cliToken");
|
|
177
|
-
}
|
|
178
|
-
getCLIToken() {
|
|
179
|
-
const cliToken = this.config.get("cliToken");
|
|
180
|
-
return cliToken;
|
|
181
|
-
}
|
|
182
|
-
async logout(cmd) {
|
|
183
|
-
this.config.delete("cliToken");
|
|
184
|
-
}
|
|
185
|
-
async requireLogin(cmd, context) {
|
|
186
|
-
let cliToken = this.getCLIToken();
|
|
187
|
-
if (!cliToken) {
|
|
188
|
-
try {
|
|
189
|
-
let shouldLogin = true;
|
|
190
|
-
if (context !== "cloud-features") {
|
|
191
|
-
const response = await inquirer.prompt([
|
|
192
|
-
{
|
|
193
|
-
name: "shouldLogin",
|
|
194
|
-
type: "confirm",
|
|
195
|
-
message: "\u{1FA81} You are not yet authenticated. Authenticate with Copilot Cloud? (press Enter to confirm)",
|
|
196
|
-
default: true
|
|
197
|
-
}
|
|
198
|
-
]);
|
|
199
|
-
shouldLogin = response.shouldLogin;
|
|
200
|
-
}
|
|
201
|
-
if (shouldLogin) {
|
|
202
|
-
if (context === "cloud-features") {
|
|
203
|
-
cmd.log(
|
|
204
|
-
chalk.cyan("\n\u{1F680} Setting up Copilot Cloud authentication...\n")
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
const loginResult = await this.login({ exitAfterLogin: false });
|
|
208
|
-
cliToken = loginResult.cliToken;
|
|
209
|
-
return loginResult;
|
|
210
|
-
} else {
|
|
211
|
-
cmd.error("Authentication required to proceed.");
|
|
212
|
-
}
|
|
213
|
-
} catch (error) {
|
|
214
|
-
if (error instanceof Error && error.name === "ExitPromptError") {
|
|
215
|
-
cmd.error(chalk.yellow("\nAuthentication cancelled"));
|
|
216
|
-
}
|
|
217
|
-
throw error;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
let me;
|
|
221
|
-
const trpcClient2 = createTRPCClient(cliToken);
|
|
222
|
-
try {
|
|
223
|
-
me = await trpcClient2.me.query();
|
|
224
|
-
} catch (error) {
|
|
225
|
-
cmd.log(
|
|
226
|
-
chalk.yellow("Your authentication has expired. Re-authenticating...")
|
|
227
|
-
);
|
|
228
|
-
try {
|
|
229
|
-
const loginResult = await this.login({ exitAfterLogin: false });
|
|
230
|
-
return loginResult;
|
|
231
|
-
} catch (loginError) {
|
|
232
|
-
cmd.log(
|
|
233
|
-
chalk.red(
|
|
234
|
-
"Could not authenticate with Copilot Cloud. Please run: npx copilotkit@latest login"
|
|
235
|
-
)
|
|
236
|
-
);
|
|
237
|
-
process.exit(1);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
if (!me.organization || !me.user) {
|
|
241
|
-
cmd.error("Authentication required to proceed.");
|
|
242
|
-
}
|
|
243
|
-
return { cliToken, user: me.user, organization: me.organization };
|
|
244
|
-
}
|
|
245
|
-
async login({ exitAfterLogin } = { exitAfterLogin: true }) {
|
|
246
|
-
const spinner = ora("\u{1FA81} Opening browser for authentication...").start();
|
|
247
|
-
let analytics;
|
|
248
|
-
analytics = new AnalyticsService();
|
|
249
|
-
const app = express();
|
|
250
|
-
app.use(cors());
|
|
251
|
-
app.use(express.urlencoded({ extended: true }));
|
|
252
|
-
app.use(express.json());
|
|
253
|
-
const port = await getPort();
|
|
254
|
-
const state = crypto2.randomBytes(16).toString("hex");
|
|
255
|
-
return new Promise(async (resolve, reject) => {
|
|
256
|
-
const server = app.listen(port, () => {
|
|
257
|
-
});
|
|
258
|
-
await analytics.track({
|
|
259
|
-
event: "cli.login.initiated",
|
|
260
|
-
properties: {}
|
|
261
|
-
});
|
|
262
|
-
spinner.text = "\u{1FA81} Waiting for browser authentication to complete...";
|
|
263
|
-
app.post("/callback", async (req, res) => {
|
|
264
|
-
const { cliToken, user, organization } = req.body;
|
|
265
|
-
if (state !== req.query.state) {
|
|
266
|
-
res.status(401).json({ message: "Invalid state" });
|
|
267
|
-
spinner.fail("Invalid state");
|
|
268
|
-
server.close();
|
|
269
|
-
reject(new Error("OAuth state mismatch"));
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
analytics = new AnalyticsService({
|
|
273
|
-
userId: user.id,
|
|
274
|
-
organizationId: organization.id,
|
|
275
|
-
email: user.email
|
|
276
|
-
});
|
|
277
|
-
await analytics.track({
|
|
278
|
-
event: "cli.login.success",
|
|
279
|
-
properties: {
|
|
280
|
-
organizationId: organization.id,
|
|
281
|
-
userId: user.id,
|
|
282
|
-
email: user.email
|
|
283
|
-
}
|
|
284
|
-
});
|
|
285
|
-
this.config.set("cliToken", cliToken);
|
|
286
|
-
res.status(200).json({ message: "Callback called" });
|
|
287
|
-
spinner.succeed(
|
|
288
|
-
`\u{1FA81} Successfully logged in as ${chalk.hex("#7553fc")(user.email)}`
|
|
289
|
-
);
|
|
290
|
-
if (exitAfterLogin) {
|
|
291
|
-
process.exit(0);
|
|
292
|
-
} else {
|
|
293
|
-
server.close();
|
|
294
|
-
resolve({ cliToken, user, organization });
|
|
295
|
-
}
|
|
296
|
-
});
|
|
297
|
-
open(
|
|
298
|
-
`${this.COPILOT_CLOUD_BASE_URL}/cli-auth?callbackUrl=http://localhost:${port}/callback&state=${state}`
|
|
299
|
-
);
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
// src/utils/detect-endpoint-type.utils.ts
|
|
305
|
-
var removeTrailingSlash = (url) => url.replace(/\/$/, "");
|
|
306
|
-
var getHumanReadableEndpointType = (type) => {
|
|
307
|
-
switch (type) {
|
|
308
|
-
case "LangGraphPlatform" /* LangGraphPlatform */:
|
|
309
|
-
return "LangGraph Platform";
|
|
310
|
-
case "CopilotKit" /* CopilotKit */:
|
|
311
|
-
return "CopilotKit";
|
|
312
|
-
case "CrewAI" /* CrewAI */:
|
|
313
|
-
return "CrewAI";
|
|
314
|
-
case "MCP" /* MCP */:
|
|
315
|
-
return "MCP";
|
|
316
|
-
default:
|
|
317
|
-
return "Invalid";
|
|
318
|
-
}
|
|
319
|
-
};
|
|
320
|
-
async function detectRemoteEndpointType(url) {
|
|
321
|
-
const [isLangGraph, isLangGraphFastAPI, isCopilot, isCrewAI, isMCP] = await Promise.all([
|
|
322
|
-
isLangGraphPlatformEndpoint(url),
|
|
323
|
-
isLangGraphFastAPIEndpoint(url),
|
|
324
|
-
isCopilotKitEndpoint(url),
|
|
325
|
-
isCrewAIEndpoint(url),
|
|
326
|
-
isMCPEndpoint(url)
|
|
327
|
-
]);
|
|
328
|
-
if (isLangGraph || isLangGraphFastAPI) {
|
|
329
|
-
return {
|
|
330
|
-
url,
|
|
331
|
-
type: "LangGraphPlatform" /* LangGraphPlatform */,
|
|
332
|
-
humanReadableType: "LangGraph Platform"
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
if (isCopilot) {
|
|
336
|
-
return {
|
|
337
|
-
url,
|
|
338
|
-
type: "CopilotKit" /* CopilotKit */,
|
|
339
|
-
humanReadableType: "CopilotKit"
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
if (isCrewAI) {
|
|
343
|
-
return {
|
|
344
|
-
url,
|
|
345
|
-
type: "CrewAI" /* CrewAI */,
|
|
346
|
-
humanReadableType: "CrewAI"
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
if (isMCP) {
|
|
350
|
-
return {
|
|
351
|
-
url,
|
|
352
|
-
type: "MCP" /* MCP */,
|
|
353
|
-
humanReadableType: "MCP"
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
if (!url.endsWith("/copilotkit")) {
|
|
357
|
-
const copilotKitUrl = `${removeTrailingSlash(url)}/copilotkit`;
|
|
358
|
-
const isCopilotWithPath = await isCopilotKitEndpoint(copilotKitUrl);
|
|
359
|
-
if (isCopilotWithPath) {
|
|
360
|
-
return {
|
|
361
|
-
url: copilotKitUrl,
|
|
362
|
-
type: "CopilotKit" /* CopilotKit */,
|
|
363
|
-
humanReadableType: "CopilotKit"
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
return {
|
|
368
|
-
url,
|
|
369
|
-
type: "Invalid" /* Invalid */,
|
|
370
|
-
humanReadableType: "Invalid"
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
async function isLangGraphPlatformEndpoint(url, retries = 0) {
|
|
374
|
-
let response;
|
|
375
|
-
try {
|
|
376
|
-
response = await fetch(`${url}/assistants/search`, {
|
|
377
|
-
method: "POST",
|
|
378
|
-
body: JSON.stringify({
|
|
379
|
-
metadata: {},
|
|
380
|
-
limit: 99,
|
|
381
|
-
offset: 0
|
|
382
|
-
})
|
|
383
|
-
});
|
|
384
|
-
} catch (error) {
|
|
385
|
-
return false;
|
|
386
|
-
}
|
|
387
|
-
if (!response.ok) {
|
|
388
|
-
if (response.status === 502) {
|
|
389
|
-
if (retries < 3) {
|
|
390
|
-
console.log("RETRYING LGC", retries + 1);
|
|
391
|
-
return isLangGraphPlatformEndpoint(url, retries + 1);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
if (response.status === 403) {
|
|
395
|
-
return true;
|
|
396
|
-
}
|
|
397
|
-
return false;
|
|
398
|
-
}
|
|
399
|
-
const data = await response.json();
|
|
400
|
-
if (data[0].assistant_id) {
|
|
401
|
-
return true;
|
|
402
|
-
}
|
|
403
|
-
return false;
|
|
404
|
-
}
|
|
405
|
-
async function isLangGraphFastAPIEndpoint(url) {
|
|
406
|
-
let response;
|
|
407
|
-
try {
|
|
408
|
-
response = await fetch(`${url}/health`, {
|
|
409
|
-
method: "GET"
|
|
410
|
-
});
|
|
411
|
-
} catch (error) {
|
|
412
|
-
return false;
|
|
413
|
-
}
|
|
414
|
-
return response.ok;
|
|
415
|
-
}
|
|
416
|
-
async function isCopilotKitEndpoint(url, retries = 0) {
|
|
417
|
-
let response;
|
|
418
|
-
try {
|
|
419
|
-
response = await fetch(`${url}/info`, {
|
|
420
|
-
method: "POST",
|
|
421
|
-
body: JSON.stringify({})
|
|
422
|
-
});
|
|
423
|
-
} catch (error) {
|
|
424
|
-
return false;
|
|
425
|
-
}
|
|
426
|
-
if (!response.ok) {
|
|
427
|
-
if (response.status === 502) {
|
|
428
|
-
if (retries < 3) {
|
|
429
|
-
console.log("RETRYING CK", retries + 1);
|
|
430
|
-
return isCopilotKitEndpoint(url, retries + 1);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
return false;
|
|
434
|
-
}
|
|
435
|
-
const data = await response.json();
|
|
436
|
-
if (data.agents && data.actions) {
|
|
437
|
-
return true;
|
|
438
|
-
}
|
|
439
|
-
return false;
|
|
440
|
-
}
|
|
441
|
-
async function isCrewAIEndpoint(url) {
|
|
442
|
-
return url.toLowerCase().includes("crew");
|
|
443
|
-
}
|
|
444
|
-
async function isMCPEndpoint(_url) {
|
|
445
|
-
return true;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
// src/services/tunnel.service.ts
|
|
449
|
-
import axios from "axios";
|
|
450
|
-
import localtunnel from "localtunnel";
|
|
451
|
-
var TunnelService = class {
|
|
452
|
-
META_DATA_URL = "https://metadata-cdn.copilotkit.ai/cloud.config.json";
|
|
453
|
-
async create(options) {
|
|
454
|
-
const metadata = await this.getMetaData();
|
|
455
|
-
return localtunnel({
|
|
456
|
-
...options,
|
|
457
|
-
host: metadata.tunnelHost
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
async getMetaData() {
|
|
461
|
-
const response = await axios.get(this.META_DATA_URL);
|
|
462
|
-
return response.data;
|
|
463
|
-
}
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
// src/commands/base-command.ts
|
|
467
|
-
import { Command } from "@oclif/core";
|
|
468
|
-
import Sentry, { consoleIntegration } from "@sentry/node";
|
|
469
|
-
|
|
470
|
-
// src/utils/version.ts
|
|
471
|
-
var LIB_VERSION = "1.54.0";
|
|
472
|
-
|
|
473
|
-
// src/commands/base-command.ts
|
|
474
|
-
import chalk2 from "chalk";
|
|
475
|
-
var BaseCommand = class extends Command {
|
|
476
|
-
async init() {
|
|
477
|
-
await this.checkCLIVersion();
|
|
478
|
-
if (process.env.SENTRY_DISABLED === "true") {
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
Sentry.init({
|
|
482
|
-
dsn: process.env.SENTRY_DSN || "https://1eea15d32e2eacb0456a77db5e39aeeb@o4507288195170304.ingest.us.sentry.io/4508581448581120",
|
|
483
|
-
integrations: [consoleIntegration()],
|
|
484
|
-
// Tracing
|
|
485
|
-
tracesSampleRate: 1
|
|
486
|
-
// Capture 100% of the transactions
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
async catch(err) {
|
|
490
|
-
if (process.env.SENTRY_DISABLED !== "true") {
|
|
491
|
-
Sentry.captureException(err);
|
|
492
|
-
}
|
|
493
|
-
const message = err?.message ?? "Unknown error";
|
|
494
|
-
this.log("\n" + chalk2.red(message) + "\n");
|
|
495
|
-
const exitCode = err?.oclif?.exit ?? 1;
|
|
496
|
-
this.exit(exitCode);
|
|
497
|
-
}
|
|
498
|
-
async finally() {
|
|
499
|
-
if (process.env.SENTRY_DISABLED === "true") {
|
|
500
|
-
return;
|
|
501
|
-
}
|
|
502
|
-
Sentry.close();
|
|
503
|
-
}
|
|
504
|
-
async run() {
|
|
505
|
-
}
|
|
506
|
-
async checkCLIVersion() {
|
|
507
|
-
try {
|
|
508
|
-
const response = await fetch(`${COPILOT_CLOUD_BASE_URL}/api/healthz`);
|
|
509
|
-
const data = await response.json();
|
|
510
|
-
const cloudVersion = data.cliVersion;
|
|
511
|
-
if (!cloudVersion || cloudVersion === LIB_VERSION) {
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
} catch {
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
async gracefulError(message) {
|
|
518
|
-
this.log("\n" + chalk2.red(message));
|
|
519
|
-
process.exit(1);
|
|
520
|
-
}
|
|
521
|
-
};
|
|
522
|
-
|
|
523
|
-
// src/commands/dev.ts
|
|
524
|
-
var DEFAULT_CLOUD_BASE_URL = "https://cloud.copilotkit.ai";
|
|
525
|
-
var CLOUD_BASE_URL = process.env.COPILOT_CLOUD_BASE_URL ?? DEFAULT_CLOUD_BASE_URL;
|
|
526
|
-
var Dev = class _Dev extends BaseCommand {
|
|
527
|
-
constructor(argv, config, authService = new AuthService(), tunnelService = new TunnelService()) {
|
|
528
|
-
super(argv, config);
|
|
529
|
-
this.authService = authService;
|
|
530
|
-
this.tunnelService = tunnelService;
|
|
531
|
-
}
|
|
532
|
-
static flags = {
|
|
533
|
-
port: Flags.string({ description: "port", required: true }),
|
|
534
|
-
project: Flags.string({
|
|
535
|
-
description: "project ID (can be found in the Copilot Cloud dashboard)"
|
|
536
|
-
})
|
|
537
|
-
};
|
|
538
|
-
static description = "Start local development for a CopilotKit project";
|
|
539
|
-
static examples = [
|
|
540
|
-
"<%= config.bin %> <%= command.id %> --port 8000 --project proj_mv3laowus0lz11kklo57bdr6"
|
|
541
|
-
];
|
|
542
|
-
trpcClient = null;
|
|
543
|
-
copilotCloudTunnelId = null;
|
|
544
|
-
async pingTunnelRecursively() {
|
|
545
|
-
if (!this.copilotCloudTunnelId) {
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
try {
|
|
549
|
-
await this.trpcClient.pingLocalTunnel.query({
|
|
550
|
-
localTunnelId: this.copilotCloudTunnelId
|
|
551
|
-
});
|
|
552
|
-
} catch (error) {
|
|
553
|
-
if (error?.data?.code === "NOT_FOUND") {
|
|
554
|
-
this.gracefulError(error.message);
|
|
555
|
-
} else {
|
|
556
|
-
this.gracefulError(
|
|
557
|
-
"Failed to ping tunnel. The connection may have been lost."
|
|
558
|
-
);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
562
|
-
await this.pingTunnelRecursively();
|
|
563
|
-
}
|
|
564
|
-
async run() {
|
|
565
|
-
const { flags } = await this.parse(_Dev);
|
|
566
|
-
const { cliToken, organization, user } = await this.authService.requireLogin(this, "general");
|
|
567
|
-
const analytics = new AnalyticsService({
|
|
568
|
-
userId: user.id,
|
|
569
|
-
organizationId: organization.id,
|
|
570
|
-
email: user.email
|
|
571
|
-
});
|
|
572
|
-
this.trpcClient = createTRPCClient(cliToken);
|
|
573
|
-
const availableProjects = await this.trpcClient.listOrgProjects.query({
|
|
574
|
-
orgId: organization.id
|
|
575
|
-
});
|
|
576
|
-
let selectedProjectId = null;
|
|
577
|
-
if (flags.project) {
|
|
578
|
-
if (!availableProjects.some((project) => project.id === flags.project)) {
|
|
579
|
-
this.log(chalk3.red(`Project with ID ${flags.project} not found`));
|
|
580
|
-
process.exit(1);
|
|
581
|
-
}
|
|
582
|
-
selectedProjectId = flags.project;
|
|
583
|
-
this.log(chalk3.green(`\u2705 Selected project ${selectedProjectId}`));
|
|
584
|
-
} else {
|
|
585
|
-
const { projectId } = await inquirer2.prompt([
|
|
586
|
-
{
|
|
587
|
-
name: "projectId",
|
|
588
|
-
type: "list",
|
|
589
|
-
message: "Select a project",
|
|
590
|
-
choices: availableProjects.map((project) => ({
|
|
591
|
-
value: project.id,
|
|
592
|
-
name: `${project.name} (ID: ${project.id})${availableProjects.length === 1 ? " (press Enter to confirm)" : ""}`
|
|
593
|
-
}))
|
|
594
|
-
}
|
|
595
|
-
]);
|
|
596
|
-
selectedProjectId = projectId;
|
|
597
|
-
}
|
|
598
|
-
const { type: remoteEndpointType } = await detectRemoteEndpointType(
|
|
599
|
-
`http://localhost:${flags.port}`
|
|
600
|
-
);
|
|
601
|
-
if (remoteEndpointType === "Invalid" /* Invalid */) {
|
|
602
|
-
return this.gracefulError(
|
|
603
|
-
`Invalid remote endpoint. Please ensure you are running a compatible endpoint at port ${flags.port} and try again.`
|
|
604
|
-
);
|
|
605
|
-
}
|
|
606
|
-
const humanReadableRemoteEndpointType = getHumanReadableEndpointType(remoteEndpointType);
|
|
607
|
-
await analytics.track({
|
|
608
|
-
event: "cli.dev.initiatied",
|
|
609
|
-
properties: {
|
|
610
|
-
port: flags.port,
|
|
611
|
-
projectId: selectedProjectId,
|
|
612
|
-
endpointType: remoteEndpointType
|
|
613
|
-
}
|
|
614
|
-
});
|
|
615
|
-
this.log(
|
|
616
|
-
chalk3.green(`\u2705 ${humanReadableRemoteEndpointType} endpoint detected`)
|
|
617
|
-
);
|
|
618
|
-
const spinner = ora2("Creating tunnel...\n").start();
|
|
619
|
-
const tunnelId = createId();
|
|
620
|
-
const setupTunnel = this.setupTunnel({
|
|
621
|
-
tunnelId,
|
|
622
|
-
port: parseInt(flags.port),
|
|
623
|
-
subdomain: createId(),
|
|
624
|
-
onSuccess: async ({ url, id }) => {
|
|
625
|
-
this.log("\nTunnel Information:\n");
|
|
626
|
-
this.log(`${chalk3.bold.cyan("\u2022 Tunnel URL: ")} ${chalk3.white(url)}`);
|
|
627
|
-
this.log(
|
|
628
|
-
`${chalk3.bold.cyan("\u2022 Endpoint Type: ")} ${chalk3.white(humanReadableRemoteEndpointType)}`
|
|
629
|
-
);
|
|
630
|
-
this.log(
|
|
631
|
-
`${chalk3.bold.cyan("\u2022 Project: ")} ${chalk3.white(`${CLOUD_BASE_URL}/projects/${selectedProjectId}`)}`
|
|
632
|
-
);
|
|
633
|
-
this.log(chalk3.yellow("\nPress Ctrl+C to stop the tunnel"));
|
|
634
|
-
this.log("\n");
|
|
635
|
-
spinner.text = "Linking local tunnel to Copilot Cloud...";
|
|
636
|
-
const { localTunnelId } = await this.trpcClient.reportRemoteEndpointLocalTunnel.mutate({
|
|
637
|
-
tunnelId: id,
|
|
638
|
-
projectId: selectedProjectId,
|
|
639
|
-
endpointType: remoteEndpointType === "CopilotKit" /* CopilotKit */ ? "CopilotKit" : "LangGraphCloud",
|
|
640
|
-
tunnelUrl: url,
|
|
641
|
-
port: parseInt(flags.port)
|
|
642
|
-
});
|
|
643
|
-
this.copilotCloudTunnelId = localTunnelId;
|
|
644
|
-
await analytics.track({
|
|
645
|
-
event: "cli.dev.tunnel.created",
|
|
646
|
-
properties: {
|
|
647
|
-
tunnelId: localTunnelId,
|
|
648
|
-
port: flags.port,
|
|
649
|
-
projectId: selectedProjectId,
|
|
650
|
-
endpointType: remoteEndpointType
|
|
651
|
-
}
|
|
652
|
-
});
|
|
653
|
-
spinner.color = "green";
|
|
654
|
-
spinner.text = "\u{1F680} Local tunnel is live and linked to Copilot Cloud!\n";
|
|
655
|
-
spinner.succeed();
|
|
656
|
-
await this.pingTunnelRecursively();
|
|
657
|
-
},
|
|
658
|
-
onTunnelClose: async ({ id }) => {
|
|
659
|
-
if (this.copilotCloudTunnelId) {
|
|
660
|
-
await analytics.track({
|
|
661
|
-
event: "cli.dev.tunnel.closed",
|
|
662
|
-
properties: {
|
|
663
|
-
tunnelId: id
|
|
664
|
-
}
|
|
665
|
-
});
|
|
666
|
-
await this.trpcClient.deleteLocalTunnel.mutate({
|
|
667
|
-
localTunnelId: this.copilotCloudTunnelId
|
|
668
|
-
});
|
|
669
|
-
this.copilotCloudTunnelId = null;
|
|
670
|
-
}
|
|
671
|
-
},
|
|
672
|
-
spinner
|
|
673
|
-
});
|
|
674
|
-
await Promise.all([setupTunnel]);
|
|
675
|
-
}
|
|
676
|
-
async setupTunnel({
|
|
677
|
-
port,
|
|
678
|
-
subdomain,
|
|
679
|
-
onSuccess,
|
|
680
|
-
onTunnelClose,
|
|
681
|
-
spinner,
|
|
682
|
-
tunnelId
|
|
683
|
-
}) {
|
|
684
|
-
const TUNNEL_TIMEOUT = 15e3;
|
|
685
|
-
const CONNECTION_TEST_TIMEOUT = 5e3;
|
|
686
|
-
spinner.text = `Testing connection to localhost:${port}...`;
|
|
687
|
-
try {
|
|
688
|
-
const testResponse = await Promise.race([
|
|
689
|
-
fetch(`http://localhost:${port}`, { method: "HEAD" }),
|
|
690
|
-
new Promise(
|
|
691
|
-
(_, reject) => setTimeout(
|
|
692
|
-
() => reject(new Error("Connection timeout")),
|
|
693
|
-
CONNECTION_TEST_TIMEOUT
|
|
694
|
-
)
|
|
695
|
-
)
|
|
696
|
-
]);
|
|
697
|
-
} catch (error) {
|
|
698
|
-
spinner.fail();
|
|
699
|
-
return this.gracefulError(
|
|
700
|
-
`Cannot connect to localhost:${port}. Please ensure your application is running on port ${port} and try again.`
|
|
701
|
-
);
|
|
702
|
-
}
|
|
703
|
-
spinner.text = "Creating tunnel...";
|
|
704
|
-
try {
|
|
705
|
-
const tunnel = await Promise.race([
|
|
706
|
-
this.tunnelService.create({
|
|
707
|
-
port,
|
|
708
|
-
subdomain: tunnelId
|
|
709
|
-
}),
|
|
710
|
-
new Promise(
|
|
711
|
-
(_, reject) => setTimeout(
|
|
712
|
-
() => reject(new Error("Tunnel creation timeout")),
|
|
713
|
-
TUNNEL_TIMEOUT
|
|
714
|
-
)
|
|
715
|
-
)
|
|
716
|
-
]);
|
|
717
|
-
tunnel.on("request", (info) => {
|
|
718
|
-
this.log(
|
|
719
|
-
`${chalk3.green("\u279C")} ${chalk3.white((/* @__PURE__ */ new Date()).toISOString())} - ${info.method} ${info.path}`
|
|
720
|
-
);
|
|
721
|
-
});
|
|
722
|
-
tunnel.on("error", (err) => {
|
|
723
|
-
this.gracefulError(chalk3.red(`Tunnel error: ${err.message}`));
|
|
724
|
-
});
|
|
725
|
-
tunnel.on("close", async () => {
|
|
726
|
-
this.log(chalk3.yellow("\nTunnel closed"));
|
|
727
|
-
await onTunnelClose({ id: tunnelId });
|
|
728
|
-
process.exit(0);
|
|
729
|
-
});
|
|
730
|
-
await Promise.all([
|
|
731
|
-
new Promise(() => {
|
|
732
|
-
process.on("SIGINT", async () => {
|
|
733
|
-
this.log("\nShutting down tunnel...");
|
|
734
|
-
await onTunnelClose({ id: tunnelId });
|
|
735
|
-
tunnel.close();
|
|
736
|
-
process.exit(0);
|
|
737
|
-
});
|
|
738
|
-
process.on("SIGTERM", async () => {
|
|
739
|
-
this.log("\nShutting down tunnel...");
|
|
740
|
-
await onTunnelClose({ id: tunnelId });
|
|
741
|
-
tunnel.close();
|
|
742
|
-
process.exit(0);
|
|
743
|
-
});
|
|
744
|
-
}),
|
|
745
|
-
onSuccess({ url: tunnel.url, id: tunnelId })
|
|
746
|
-
]);
|
|
747
|
-
} catch (error) {
|
|
748
|
-
spinner.fail();
|
|
749
|
-
if (error.message === "Tunnel creation timeout") {
|
|
750
|
-
return this.gracefulError(
|
|
751
|
-
`Unable to establish tunnel connection after ${TUNNEL_TIMEOUT / 1e3} seconds.
|
|
752
|
-
|
|
753
|
-
This usually means:
|
|
754
|
-
\u2022 Network connectivity issues
|
|
755
|
-
\u2022 Tunnel service is temporarily unavailable
|
|
756
|
-
\u2022 Firewall blocking outbound connections
|
|
757
|
-
|
|
758
|
-
Please try:
|
|
759
|
-
1. Check your internet connection
|
|
760
|
-
2. Try again in a few moments
|
|
761
|
-
`
|
|
762
|
-
);
|
|
763
|
-
} else if (error.message === "Connection timeout") {
|
|
764
|
-
return this.gracefulError(
|
|
765
|
-
`Cannot connect to localhost:${port}. Please ensure your application is running on port ${port} and try again.`
|
|
766
|
-
);
|
|
767
|
-
} else {
|
|
768
|
-
return this.gracefulError(`Failed to create tunnel: ${error.message}`);
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
};
|
|
773
|
-
export {
|
|
774
|
-
Dev as default
|
|
775
|
-
};
|
|
776
|
-
//# sourceMappingURL=dev.js.map
|