copilotkit 0.0.25 → 0.0.27
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/commands/base-command.js +1 -1
- package/dist/commands/base-command.js.map +1 -1
- package/dist/commands/dev.js +1 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/init.js +329 -102
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/logout.js.map +1 -1
- package/dist/lib/init/index.d.ts +4 -3
- package/dist/lib/init/index.js +243 -59
- package/dist/lib/init/index.js.map +1 -1
- package/dist/lib/init/questions.d.ts +1 -0
- package/dist/lib/init/questions.js +198 -35
- package/dist/lib/init/questions.js.map +1 -1
- package/dist/lib/init/scaffold/agent.d.ts +1 -0
- package/dist/lib/init/scaffold/agent.js +1 -1
- package/dist/lib/init/scaffold/agent.js.map +1 -1
- package/dist/lib/init/scaffold/crew-inputs.js +1 -1
- package/dist/lib/init/scaffold/crew-inputs.js.map +1 -1
- package/dist/lib/init/scaffold/env.d.ts +1 -0
- package/dist/lib/init/scaffold/env.js +5 -2
- package/dist/lib/init/scaffold/env.js.map +1 -1
- package/dist/lib/init/scaffold/index.d.ts +1 -0
- package/dist/lib/init/scaffold/index.js +133 -32
- package/dist/lib/init/scaffold/index.js.map +1 -1
- package/dist/lib/init/scaffold/langgraph-assistants.js +1 -1
- package/dist/lib/init/scaffold/langgraph-assistants.js.map +1 -1
- package/dist/lib/init/scaffold/packages.d.ts +1 -0
- package/dist/lib/init/scaffold/shadcn.d.ts +1 -0
- package/dist/lib/init/scaffold/shadcn.js +126 -28
- package/dist/lib/init/scaffold/shadcn.js.map +1 -1
- package/dist/lib/init/types/index.d.ts +2 -1
- package/dist/lib/init/types/index.js +114 -8
- package/dist/lib/init/types/index.js.map +1 -1
- package/dist/lib/init/types/questions.d.ts +164 -36
- package/dist/lib/init/types/questions.js +112 -6
- package/dist/lib/init/types/questions.js.map +1 -1
- package/dist/lib/init/types/templates.d.ts +1 -1
- package/dist/lib/init/types/templates.js +3 -3
- package/dist/lib/init/types/templates.js.map +1 -1
- package/dist/utils/version.d.ts +1 -1
- package/dist/utils/version.js +1 -1
- package/dist/utils/version.js.map +1 -1
- package/oclif.manifest.json +4 -7
- package/package.json +1 -1
package/dist/commands/init.js
CHANGED
|
@@ -222,7 +222,7 @@ import { Command } from "@oclif/core";
|
|
|
222
222
|
import Sentry, { consoleIntegration } from "@sentry/node";
|
|
223
223
|
|
|
224
224
|
// src/utils/version.ts
|
|
225
|
-
var LIB_VERSION = "0.0.
|
|
225
|
+
var LIB_VERSION = "0.0.27";
|
|
226
226
|
|
|
227
227
|
// src/commands/base-command.ts
|
|
228
228
|
import chalk2 from "chalk";
|
|
@@ -273,17 +273,110 @@ var BaseCommand = class extends Command {
|
|
|
273
273
|
};
|
|
274
274
|
|
|
275
275
|
// src/lib/init/types/questions.ts
|
|
276
|
+
import { z } from "zod";
|
|
276
277
|
import { Flags } from "@oclif/core";
|
|
277
|
-
var AGENT_FRAMEWORKS = ["CrewAI", "LangGraph"
|
|
278
|
+
var AGENT_FRAMEWORKS = ["CrewAI", "LangGraph"];
|
|
278
279
|
var CREW_TYPES = ["Crews", "Flows"];
|
|
279
280
|
var CHAT_COMPONENTS = ["CopilotChat", "CopilotSidebar", "Headless", "CopilotPopup"];
|
|
280
|
-
var LANGGRAPH_AGENTS = ["Python Starter", "TypeScript Starter"
|
|
281
|
-
var CREW_FLOW_TEMPLATES = ["Starter"
|
|
281
|
+
var LANGGRAPH_AGENTS = ["Python Starter", "TypeScript Starter"];
|
|
282
|
+
var CREW_FLOW_TEMPLATES = ["Starter"];
|
|
283
|
+
var YES_NO = ["Yes", "No"];
|
|
284
|
+
var sanitizers = {
|
|
285
|
+
// Remove trailing slash from URLs
|
|
286
|
+
url: (value) => {
|
|
287
|
+
if (!value) return value;
|
|
288
|
+
return value.trim().replace(/\/+$/, "");
|
|
289
|
+
},
|
|
290
|
+
// Trim whitespace from strings
|
|
291
|
+
trim: (value) => {
|
|
292
|
+
if (!value) return value;
|
|
293
|
+
return value.trim();
|
|
294
|
+
},
|
|
295
|
+
// Lowercase strings
|
|
296
|
+
lowercase: (value) => {
|
|
297
|
+
if (!value) return value;
|
|
298
|
+
return value.toLowerCase().trim();
|
|
299
|
+
},
|
|
300
|
+
// Clean API keys (remove whitespace)
|
|
301
|
+
apiKey: (value) => {
|
|
302
|
+
if (!value) return value;
|
|
303
|
+
return value.trim().replace(/\s/g, "");
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
var AgentFrameworkSchema = z.enum(AGENT_FRAMEWORKS);
|
|
307
|
+
var CrewTypeSchema = z.enum(CREW_TYPES);
|
|
308
|
+
var ChatComponentSchema = z.enum(CHAT_COMPONENTS);
|
|
309
|
+
var LangGraphAgentSchema = z.enum(LANGGRAPH_AGENTS);
|
|
310
|
+
var CrewFlowTemplateSchema = z.enum(CREW_FLOW_TEMPLATES);
|
|
311
|
+
var YesNoSchema = z.enum(YES_NO);
|
|
312
|
+
var UrlSchema = z.preprocess(
|
|
313
|
+
(val) => sanitizers.url(String(val)),
|
|
314
|
+
z.string().url("Please enter a valid URL").min(1, "URL is required")
|
|
315
|
+
);
|
|
316
|
+
var TokenSchema = z.preprocess(
|
|
317
|
+
(val) => sanitizers.trim(String(val)),
|
|
318
|
+
z.string().min(1, "Token is required")
|
|
319
|
+
);
|
|
320
|
+
var ApiKeySchema = z.preprocess(
|
|
321
|
+
(val) => sanitizers.apiKey(String(val)),
|
|
322
|
+
z.string().min(1, "API key is required")
|
|
323
|
+
);
|
|
324
|
+
var NameSchema = z.preprocess(
|
|
325
|
+
(val) => sanitizers.trim(String(val)),
|
|
326
|
+
z.string().min(1, "Name is required")
|
|
327
|
+
);
|
|
328
|
+
var ConfigSchema = z.object({
|
|
329
|
+
// Core fields
|
|
330
|
+
copilotKitVersion: z.string().optional(),
|
|
331
|
+
agentFramework: AgentFrameworkSchema,
|
|
332
|
+
chatUi: ChatComponentSchema.optional(),
|
|
333
|
+
// Yes/No fields
|
|
334
|
+
alreadyDeployed: YesNoSchema.optional(),
|
|
335
|
+
fastApiEnabled: YesNoSchema.optional(),
|
|
336
|
+
useCopilotCloud: YesNoSchema.optional(),
|
|
337
|
+
// LangGraph specific fields
|
|
338
|
+
langGraphAgent: LangGraphAgentSchema.optional(),
|
|
339
|
+
langGraphPlatform: YesNoSchema.optional(),
|
|
340
|
+
langGraphPlatformUrl: UrlSchema.optional(),
|
|
341
|
+
langGraphRemoteEndpointURL: UrlSchema.optional(),
|
|
342
|
+
// CrewAI specific fields
|
|
343
|
+
crewType: CrewTypeSchema.optional(),
|
|
344
|
+
crewName: NameSchema.optional(),
|
|
345
|
+
crewUrl: UrlSchema.optional(),
|
|
346
|
+
crewBearerToken: TokenSchema.optional(),
|
|
347
|
+
crewFlowAgent: CrewFlowTemplateSchema.optional(),
|
|
348
|
+
// API keys and tokens
|
|
349
|
+
copilotCloudPublicApiKey: z.string().optional(),
|
|
350
|
+
langSmithApiKey: ApiKeySchema.optional(),
|
|
351
|
+
llmToken: ApiKeySchema.optional()
|
|
352
|
+
}).refine(
|
|
353
|
+
(data) => {
|
|
354
|
+
if (data.agentFramework === "CrewAI" && data.crewType === "Crews") {
|
|
355
|
+
return !!data.crewUrl && !!data.crewBearerToken;
|
|
356
|
+
}
|
|
357
|
+
return true;
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
message: "Crew URL and bearer token are required for CrewAI Crews",
|
|
361
|
+
path: ["crewUrl", "crewBearerToken"]
|
|
362
|
+
}
|
|
363
|
+
).refine(
|
|
364
|
+
(data) => {
|
|
365
|
+
if (data.agentFramework === "LangGraph" && data.alreadyDeployed === "Yes" && data.langGraphPlatform === "Yes") {
|
|
366
|
+
return !!data.langGraphPlatformUrl && !!data.langSmithApiKey;
|
|
367
|
+
}
|
|
368
|
+
return true;
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
message: "LangGraph Platform URL and LangSmith API key are required",
|
|
372
|
+
path: ["langGraphPlatformUrl", "langSmithApiKey"]
|
|
373
|
+
}
|
|
374
|
+
);
|
|
282
375
|
var ConfigFlags = {
|
|
283
376
|
copilotKitVersion: Flags.string({ description: "CopilotKit version to use (e.g. 1.7.0)" }),
|
|
284
377
|
agentFramework: Flags.string({ description: "Agent framework to power your copilot", options: AGENT_FRAMEWORKS }),
|
|
285
|
-
fastApiEnabled: Flags.string({ description: "Use FastAPI to serve your agent locally", options:
|
|
286
|
-
useCopilotCloud: Flags.string({ description: "Use Copilot Cloud for production-ready hosting", options:
|
|
378
|
+
fastApiEnabled: Flags.string({ description: "Use FastAPI to serve your agent locally", options: YES_NO }),
|
|
379
|
+
useCopilotCloud: Flags.string({ description: "Use Copilot Cloud for production-ready hosting", options: YES_NO }),
|
|
287
380
|
chatUi: Flags.string({ description: "Chat UI component to add to your app", options: CHAT_COMPONENTS }),
|
|
288
381
|
langGraphAgent: Flags.string({ description: "LangGraph agent template to use", options: LANGGRAPH_AGENTS }),
|
|
289
382
|
crewType: Flags.string({ description: "CrewAI implementation type", options: CREW_TYPES }),
|
|
@@ -296,14 +389,14 @@ var ConfigFlags = {
|
|
|
296
389
|
};
|
|
297
390
|
|
|
298
391
|
// src/lib/init/types/templates.ts
|
|
299
|
-
var BASE_URL = "
|
|
392
|
+
var BASE_URL = "http://localhost:3002/r";
|
|
300
393
|
var templateMapping = {
|
|
301
|
-
"
|
|
394
|
+
"LangGraphPlatformRuntime": `${BASE_URL}/langgraph-platform-starter.json`,
|
|
302
395
|
"RemoteEndpoint": `${BASE_URL}/remote-endpoint-starter.json`,
|
|
303
396
|
"CrewEnterprise": [
|
|
304
397
|
`${BASE_URL}/coagents-crew-starter.json`
|
|
305
398
|
],
|
|
306
|
-
"LangGraphGeneric": `${BASE_URL}/generic-lg-starter.json`,
|
|
399
|
+
"LangGraphGeneric": `${BASE_URL}/generic-lg-starter-with-cloud.json`,
|
|
307
400
|
"CrewFlowsStarter": [
|
|
308
401
|
`${BASE_URL}/coagents-starter-ui.json`,
|
|
309
402
|
`${BASE_URL}/agent-layout.json`,
|
|
@@ -320,13 +413,34 @@ var templateMapping = {
|
|
|
320
413
|
};
|
|
321
414
|
|
|
322
415
|
// src/lib/init/questions.ts
|
|
416
|
+
var validateUrl = (input) => {
|
|
417
|
+
try {
|
|
418
|
+
const sanitized = sanitizers.url(input);
|
|
419
|
+
const result = UrlSchema.safeParse(sanitized);
|
|
420
|
+
if (result.success) return true;
|
|
421
|
+
return result.error.errors[0]?.message || "Invalid URL format";
|
|
422
|
+
} catch (error) {
|
|
423
|
+
return "Invalid URL format";
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
var validateRequired = (input) => {
|
|
427
|
+
return sanitizers.trim(input) ? true : "This field is required";
|
|
428
|
+
};
|
|
323
429
|
var questions = [
|
|
324
430
|
// Core setup questions - always shown first
|
|
325
431
|
{
|
|
326
432
|
type: "select",
|
|
327
433
|
name: "agentFramework",
|
|
328
434
|
message: "\u{1F916} Choose your AI framework:",
|
|
329
|
-
choices: Array.from(AGENT_FRAMEWORKS)
|
|
435
|
+
choices: Array.from(AGENT_FRAMEWORKS),
|
|
436
|
+
validate: (input) => {
|
|
437
|
+
try {
|
|
438
|
+
AgentFrameworkSchema.parse(input);
|
|
439
|
+
return true;
|
|
440
|
+
} catch (error) {
|
|
441
|
+
return "Please select a valid framework";
|
|
442
|
+
}
|
|
443
|
+
}
|
|
330
444
|
},
|
|
331
445
|
// CrewAI specific questions - shown when CrewAI selected
|
|
332
446
|
{
|
|
@@ -334,7 +448,15 @@ var questions = [
|
|
|
334
448
|
name: "crewType",
|
|
335
449
|
message: "\u{1F465} What kind of CrewAI implementation would you like to use?",
|
|
336
450
|
choices: Array.from(CREW_TYPES),
|
|
337
|
-
when: (answers) => answers.agentFramework === "CrewAI"
|
|
451
|
+
when: (answers) => answers.agentFramework === "CrewAI",
|
|
452
|
+
validate: (input) => {
|
|
453
|
+
try {
|
|
454
|
+
CrewTypeSchema.parse(input);
|
|
455
|
+
return true;
|
|
456
|
+
} catch (error) {
|
|
457
|
+
return "Please select a valid crew type";
|
|
458
|
+
}
|
|
459
|
+
}
|
|
338
460
|
},
|
|
339
461
|
// CrewAI Crews specific questions - shown when CrewAI Crews selected
|
|
340
462
|
{
|
|
@@ -342,20 +464,26 @@ var questions = [
|
|
|
342
464
|
name: "crewName",
|
|
343
465
|
message: "\u{1F465} What would you like to name your crew? (can be anything)",
|
|
344
466
|
when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Crews",
|
|
345
|
-
default: "MyCopilotCrew"
|
|
467
|
+
default: "MyCopilotCrew",
|
|
468
|
+
validate: validateRequired,
|
|
469
|
+
sanitize: sanitizers.trim
|
|
346
470
|
},
|
|
347
471
|
{
|
|
348
472
|
type: "input",
|
|
349
473
|
name: "crewUrl",
|
|
350
|
-
message: "\u{1F517} Enter your Crew's URL:",
|
|
351
|
-
when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Crews"
|
|
474
|
+
message: "\u{1F517} Enter your Crew's Enterprise URL (more info at https://app.crewai.com):",
|
|
475
|
+
when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Crews",
|
|
476
|
+
validate: validateUrl,
|
|
477
|
+
sanitize: sanitizers.url
|
|
352
478
|
},
|
|
353
479
|
{
|
|
354
480
|
type: "input",
|
|
355
481
|
name: "crewBearerToken",
|
|
356
482
|
message: "\u{1F511} Enter your Crew's bearer token:",
|
|
357
483
|
when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Crews",
|
|
358
|
-
sensitive: true
|
|
484
|
+
sensitive: true,
|
|
485
|
+
validate: validateRequired,
|
|
486
|
+
sanitize: sanitizers.trim
|
|
359
487
|
},
|
|
360
488
|
// CrewAI Flows specific questions - shown when CrewAI Flows selected
|
|
361
489
|
{
|
|
@@ -370,26 +498,49 @@ var questions = [
|
|
|
370
498
|
type: "yes/no",
|
|
371
499
|
name: "alreadyDeployed",
|
|
372
500
|
message: "\u{1F680} Is your LangGraph agent already deployed?",
|
|
373
|
-
when: (answers) => answers.agentFramework === "LangGraph"
|
|
501
|
+
when: (answers) => answers.agentFramework === "LangGraph",
|
|
502
|
+
validate: (input) => {
|
|
503
|
+
try {
|
|
504
|
+
YesNoSchema.parse(input);
|
|
505
|
+
return true;
|
|
506
|
+
} catch (error) {
|
|
507
|
+
return "Please select Yes or No";
|
|
508
|
+
}
|
|
509
|
+
}
|
|
374
510
|
},
|
|
375
511
|
{
|
|
376
512
|
type: "yes/no",
|
|
377
513
|
name: "langGraphPlatform",
|
|
378
|
-
message: "\u{1F99C}\u{1F517} Is it hosted with LangGraph Platform (
|
|
379
|
-
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes"
|
|
514
|
+
message: "\u{1F99C}\u{1F517} Is it hosted with LangGraph Platform (either self-hosted or in LangSmith)?",
|
|
515
|
+
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes",
|
|
516
|
+
validate: (input) => {
|
|
517
|
+
try {
|
|
518
|
+
YesNoSchema.parse(input);
|
|
519
|
+
return true;
|
|
520
|
+
} catch (error) {
|
|
521
|
+
return "Please select Yes or No";
|
|
522
|
+
}
|
|
523
|
+
}
|
|
380
524
|
},
|
|
381
525
|
{
|
|
382
526
|
type: "input",
|
|
383
527
|
name: "langGraphPlatformUrl",
|
|
384
528
|
message: "\u{1F99C}\u{1F517} Enter your LangGraph platform URL:",
|
|
385
|
-
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes" && answers.langGraphPlatform === "Yes"
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
type: "input",
|
|
389
|
-
name: "langGraphRemoteEndpointURL",
|
|
390
|
-
message: "\u{1F50C} Enter your LangGraph endpoint URL:",
|
|
391
|
-
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes" && answers.langGraphPlatform === "No"
|
|
529
|
+
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes" && answers.langGraphPlatform === "Yes",
|
|
530
|
+
validate: validateUrl,
|
|
531
|
+
sanitize: sanitizers.url
|
|
392
532
|
},
|
|
533
|
+
// {
|
|
534
|
+
// type: 'input',
|
|
535
|
+
// name: 'langGraphRemoteEndpointURL',
|
|
536
|
+
// message: '🔌 Enter your LangGraph endpoint URL:',
|
|
537
|
+
// when: (answers) =>
|
|
538
|
+
// answers.agentFramework === 'LangGraph' &&
|
|
539
|
+
// answers.alreadyDeployed === 'Yes' &&
|
|
540
|
+
// answers.langGraphPlatform === 'No',
|
|
541
|
+
// validate: validateUrl,
|
|
542
|
+
// sanitize: sanitizers.url
|
|
543
|
+
// },
|
|
393
544
|
{
|
|
394
545
|
type: "select",
|
|
395
546
|
name: "langGraphAgent",
|
|
@@ -402,14 +553,24 @@ var questions = [
|
|
|
402
553
|
name: "langSmithApiKey",
|
|
403
554
|
message: "\u{1F99C}\u{1F517} Enter your LangSmith API key (required by LangGraph Platform) :",
|
|
404
555
|
when: (answers) => answers.agentFramework === "LangGraph" && answers.langGraphPlatform === "Yes",
|
|
405
|
-
sensitive: true
|
|
556
|
+
sensitive: true,
|
|
557
|
+
validate: validateRequired,
|
|
558
|
+
sanitize: sanitizers.apiKey
|
|
406
559
|
},
|
|
407
560
|
// Deployment options
|
|
408
561
|
{
|
|
409
562
|
type: "yes/no",
|
|
410
563
|
name: "useCopilotCloud",
|
|
411
564
|
message: "\u{1FA81} Deploy with Copilot Cloud? (recommended for production)",
|
|
412
|
-
when: (answers) => !(answers.agentFramework === "CrewAI" && answers.crewType === "Crews") && answers.crewType !== "Flows" && answers.alreadyDeployed === "Yes"
|
|
565
|
+
when: (answers) => !(answers.agentFramework === "CrewAI" && answers.crewType === "Crews") && answers.crewType !== "Flows" && answers.alreadyDeployed === "Yes" && answers.langGraphPlatform !== "No",
|
|
566
|
+
validate: (input) => {
|
|
567
|
+
try {
|
|
568
|
+
YesNoSchema.parse(input);
|
|
569
|
+
return true;
|
|
570
|
+
} catch (error) {
|
|
571
|
+
return "Please select Yes or No";
|
|
572
|
+
}
|
|
573
|
+
}
|
|
413
574
|
},
|
|
414
575
|
// {
|
|
415
576
|
// type: 'yes/no',
|
|
@@ -422,20 +583,22 @@ var questions = [
|
|
|
422
583
|
// answers.useCopilotCloud !== 'Yes',
|
|
423
584
|
// },
|
|
424
585
|
// UI components - always shown last
|
|
425
|
-
{
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
},
|
|
586
|
+
// {
|
|
587
|
+
// type: 'select',
|
|
588
|
+
// name: 'chatUi',
|
|
589
|
+
// message: '💬 Select a UI component for your copilot:',
|
|
590
|
+
// choices: Array.from(CHAT_COMPONENTS),
|
|
591
|
+
// default: 'CopilotChat',
|
|
592
|
+
// when: (answers) => answers.agentFramework === 'None',
|
|
593
|
+
// },
|
|
433
594
|
{
|
|
434
595
|
type: "input",
|
|
435
596
|
name: "llmToken",
|
|
436
597
|
message: "\u{1F511} Enter your OpenAI API key (required for agent functionality):",
|
|
437
598
|
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "No" || answers.agentFramework === "CrewAI" && answers.crewType === "Flows",
|
|
438
|
-
sensitive: true
|
|
599
|
+
sensitive: true,
|
|
600
|
+
validate: validateRequired,
|
|
601
|
+
sanitize: sanitizers.apiKey
|
|
439
602
|
}
|
|
440
603
|
];
|
|
441
604
|
|
|
@@ -444,28 +607,33 @@ import spawn from "cross-spawn";
|
|
|
444
607
|
async function scaffoldShadCN(userAnswers) {
|
|
445
608
|
try {
|
|
446
609
|
const components = [];
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
} else if (userAnswers.crewFlowAgent) {
|
|
460
|
-
components.push(...templateMapping.CrewFlowsStarter);
|
|
461
|
-
} else {
|
|
462
|
-
components.push(templateMapping.RemoteEndpoint);
|
|
610
|
+
switch (userAnswers.agentFramework) {
|
|
611
|
+
case "LangGraph":
|
|
612
|
+
if (userAnswers.langGraphAgent) {
|
|
613
|
+
components.push(...templateMapping.LangGraphStarter);
|
|
614
|
+
} else {
|
|
615
|
+
components.push(templateMapping.LangGraphGeneric);
|
|
616
|
+
if (userAnswers.useCopilotCloud !== "Yes") {
|
|
617
|
+
if (userAnswers.langGraphPlatform === "Yes") {
|
|
618
|
+
components.push(templateMapping.LangGraphPlatformRuntime);
|
|
619
|
+
} else {
|
|
620
|
+
components.push(templateMapping.RemoteEndpoint);
|
|
621
|
+
}
|
|
463
622
|
}
|
|
464
|
-
|
|
465
|
-
|
|
623
|
+
}
|
|
624
|
+
break;
|
|
625
|
+
case "CrewAI":
|
|
626
|
+
if (userAnswers.crewType === "Crews") {
|
|
627
|
+
components.push(...templateMapping.CrewEnterprise);
|
|
628
|
+
} else if (userAnswers.crewFlowAgent) {
|
|
629
|
+
components.push(...templateMapping.CrewFlowsStarter);
|
|
630
|
+
} else {
|
|
466
631
|
components.push(templateMapping.RemoteEndpoint);
|
|
467
|
-
|
|
468
|
-
|
|
632
|
+
}
|
|
633
|
+
break;
|
|
634
|
+
default:
|
|
635
|
+
components.push(templateMapping.RemoteEndpoint);
|
|
636
|
+
break;
|
|
469
637
|
}
|
|
470
638
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
471
639
|
try {
|
|
@@ -492,7 +660,7 @@ import fs from "fs";
|
|
|
492
660
|
async function getLangGraphAgents(url, langSmithApiKey) {
|
|
493
661
|
try {
|
|
494
662
|
const response = await fetch(
|
|
495
|
-
`${url}/assistants/search`,
|
|
663
|
+
`${url.trim().replace(/\/$/, "")}/assistants/search`,
|
|
496
664
|
{
|
|
497
665
|
method: "POST",
|
|
498
666
|
headers: {
|
|
@@ -537,13 +705,16 @@ async function scaffoldEnv(flags, userAnswers) {
|
|
|
537
705
|
newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=${userAnswers.crewName}
|
|
538
706
|
`;
|
|
539
707
|
}
|
|
540
|
-
if (userAnswers.langGraphAgent
|
|
708
|
+
if (userAnswers.langGraphAgent) {
|
|
541
709
|
newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=sample_agent
|
|
542
710
|
`;
|
|
543
711
|
newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=http://localhost:8123
|
|
544
712
|
`;
|
|
545
713
|
} else if (userAnswers.langGraphPlatform === "Yes" && userAnswers.useCopilotCloud === "No") {
|
|
546
714
|
newEnvValues += `LANGGRAPH_DEPLOYMENT_URL=${userAnswers.langGraphPlatformUrl}
|
|
715
|
+
`;
|
|
716
|
+
} else if (userAnswers.langGraphRemoteEndpointURL) {
|
|
717
|
+
newEnvValues += `COPILOTKIT_REMOTE_ENDPOINT=${userAnswers.langGraphRemoteEndpointURL}
|
|
547
718
|
`;
|
|
548
719
|
}
|
|
549
720
|
if (flags.runtimeUrl) {
|
|
@@ -681,7 +852,7 @@ import chalk5 from "chalk";
|
|
|
681
852
|
import path3 from "path";
|
|
682
853
|
import fs3 from "fs";
|
|
683
854
|
async function scaffoldAgent(userAnswers) {
|
|
684
|
-
if (userAnswers.agentFramework === "
|
|
855
|
+
if (userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Crews" || userAnswers.agentFramework === "LangGraph" && !userAnswers.langGraphAgent) {
|
|
685
856
|
return;
|
|
686
857
|
}
|
|
687
858
|
const spinner = ora3({
|
|
@@ -780,7 +951,7 @@ async function addCrewInputs(url, token) {
|
|
|
780
951
|
}
|
|
781
952
|
}
|
|
782
953
|
async function getCrewInputs(url, token) {
|
|
783
|
-
const response = await fetch(`${url}/inputs`, {
|
|
954
|
+
const response = await fetch(`${url.trim()}/inputs`, {
|
|
784
955
|
headers: {
|
|
785
956
|
Authorization: `Bearer ${token}`
|
|
786
957
|
}
|
|
@@ -837,7 +1008,8 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
837
1008
|
name: q.name,
|
|
838
1009
|
message: q.message,
|
|
839
1010
|
when: q.when,
|
|
840
|
-
default: q.default
|
|
1011
|
+
default: q.default,
|
|
1012
|
+
validate: q.validate
|
|
841
1013
|
};
|
|
842
1014
|
switch (q.type) {
|
|
843
1015
|
case "yes/no":
|
|
@@ -857,12 +1029,37 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
857
1029
|
return {
|
|
858
1030
|
...baseQuestion,
|
|
859
1031
|
type: q.sensitive ? "password" : "input",
|
|
860
|
-
mask: q.sensitive ? "*" : void 0
|
|
1032
|
+
mask: q.sensitive ? "*" : void 0,
|
|
1033
|
+
// Add sanitization filter for input fields
|
|
1034
|
+
filter: q.sanitize ? (input) => q.sanitize(input) : void 0
|
|
861
1035
|
};
|
|
862
1036
|
}
|
|
863
1037
|
});
|
|
864
1038
|
const answers = await inquirer3.prompt(inquirerQuestions);
|
|
865
|
-
|
|
1039
|
+
if (answers.langGraphPlatform === "No") {
|
|
1040
|
+
this.log("\nCurrently the CLI only supports scaffolding LangGraph Platform agents. Use our quickstart guide to get started:\n");
|
|
1041
|
+
this.log(chalk6.blue("https://docs.copilotkit.ai/coagents/quickstart/langgraph"));
|
|
1042
|
+
process.exit(0);
|
|
1043
|
+
}
|
|
1044
|
+
try {
|
|
1045
|
+
const spinner = ora5({ text: "Validating configuration...", color: "green" }).start();
|
|
1046
|
+
const validatedConfig = ConfigSchema.parse(answers);
|
|
1047
|
+
spinner.succeed(`\u{1F50D} Configuration validated successfully`);
|
|
1048
|
+
return validatedConfig;
|
|
1049
|
+
} catch (error) {
|
|
1050
|
+
const spinner = ora5({ text: "Validation failed...", color: "red" }).start();
|
|
1051
|
+
if (error.errors) {
|
|
1052
|
+
const formattedErrors = error.errors.map(
|
|
1053
|
+
(err) => `- ${err.path.join(".")}: ${err.message}`
|
|
1054
|
+
).join("\n");
|
|
1055
|
+
spinner.fail(chalk6.red("Configuration validation failed:"));
|
|
1056
|
+
console.error(chalk6.red(formattedErrors));
|
|
1057
|
+
process.exit(1);
|
|
1058
|
+
}
|
|
1059
|
+
spinner.fail(chalk6.red("Unexpected validation error:"));
|
|
1060
|
+
console.error(chalk6.red(error.message || "Unknown error"));
|
|
1061
|
+
process.exit(1);
|
|
1062
|
+
}
|
|
866
1063
|
}
|
|
867
1064
|
async setupCloud(flags, userAnswers) {
|
|
868
1065
|
const { cliToken, organization } = await this.authService.requireLogin(this);
|
|
@@ -891,24 +1088,46 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
891
1088
|
selectedProjectId = projectId;
|
|
892
1089
|
}
|
|
893
1090
|
const copilotCloudPublicApiKey = await this.trpcClient.getCopilotCloudPublicApiKey.query({ projectId: selectedProjectId });
|
|
894
|
-
|
|
1091
|
+
try {
|
|
1092
|
+
const sanitizedConfig = {
|
|
1093
|
+
...userAnswers,
|
|
1094
|
+
copilotCloudPublicApiKey: copilotCloudPublicApiKey?.key,
|
|
1095
|
+
crewUrl: userAnswers.crewUrl ? sanitizers.url(userAnswers.crewUrl) : void 0,
|
|
1096
|
+
langGraphPlatformUrl: userAnswers.langGraphPlatformUrl ? sanitizers.url(userAnswers.langGraphPlatformUrl) : void 0,
|
|
1097
|
+
langGraphRemoteEndpointURL: userAnswers.langGraphRemoteEndpointURL ? sanitizers.url(userAnswers.langGraphRemoteEndpointURL) : void 0,
|
|
1098
|
+
crewBearerToken: userAnswers.crewBearerToken ? sanitizers.apiKey(userAnswers.crewBearerToken) : void 0,
|
|
1099
|
+
langSmithApiKey: userAnswers.langSmithApiKey ? sanitizers.apiKey(userAnswers.langSmithApiKey) : void 0,
|
|
1100
|
+
llmToken: userAnswers.llmToken ? sanitizers.apiKey(userAnswers.llmToken) : void 0
|
|
1101
|
+
};
|
|
1102
|
+
const updatedConfig = ConfigSchema.parse(sanitizedConfig);
|
|
1103
|
+
Object.assign(userAnswers, updatedConfig);
|
|
1104
|
+
} catch (error) {
|
|
1105
|
+
this.log(chalk6.red(`Failed to update configuration with Copilot Cloud API key: ${error.message}`));
|
|
1106
|
+
}
|
|
895
1107
|
if (userAnswers.crewUrl && userAnswers.crewName && userAnswers.crewBearerToken) {
|
|
896
1108
|
const crewSpinner = ora5({
|
|
897
1109
|
text: chalk6("\u{1F465} Adding Crew to Copilot Cloud..."),
|
|
898
1110
|
color: "cyan"
|
|
899
1111
|
}).start();
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
projectId: selectedProjectId,
|
|
903
|
-
config: {
|
|
1112
|
+
try {
|
|
1113
|
+
await this.trpcClient.createRemoteEndpoint.mutate({
|
|
904
1114
|
type: "CrewAI",
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
1115
|
+
projectId: selectedProjectId,
|
|
1116
|
+
config: {
|
|
1117
|
+
type: "CrewAI",
|
|
1118
|
+
url: userAnswers.crewUrl,
|
|
1119
|
+
// Already sanitized
|
|
1120
|
+
agentName: userAnswers.crewName,
|
|
1121
|
+
agentDescription: "A helpful Crew",
|
|
1122
|
+
crewApiBearerToken: userAnswers.crewBearerToken
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1125
|
+
crewSpinner.succeed(chalk6("\u{1F465} Crew added to Copilot Cloud"));
|
|
1126
|
+
} catch (error) {
|
|
1127
|
+
crewSpinner.fail(chalk6("\u{1F465} Failed to add Crew to Copilot Cloud"));
|
|
1128
|
+
console.error(error);
|
|
1129
|
+
process.exit(1);
|
|
1130
|
+
}
|
|
912
1131
|
}
|
|
913
1132
|
if (userAnswers.agentFramework === "LangGraph" && userAnswers.useCopilotCloud === "Yes" && userAnswers.alreadyDeployed === "Yes") {
|
|
914
1133
|
const langGraphSpinner = ora5({
|
|
@@ -926,6 +1145,7 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
926
1145
|
projectId: selectedProjectId,
|
|
927
1146
|
config: {
|
|
928
1147
|
deploymentUrl: userAnswers.langGraphPlatformUrl,
|
|
1148
|
+
// Already sanitized
|
|
929
1149
|
langsmithApiKey: userAnswers.langSmithApiKey,
|
|
930
1150
|
agents: []
|
|
931
1151
|
}
|
|
@@ -943,6 +1163,7 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
943
1163
|
config: {
|
|
944
1164
|
type: "CopilotKit",
|
|
945
1165
|
url: userAnswers.langGraphRemoteEndpointURL
|
|
1166
|
+
// Already sanitized
|
|
946
1167
|
}
|
|
947
1168
|
});
|
|
948
1169
|
langGraphSpinner.succeed(chalk6("\u{1F99C}\u{1F517} LangGraph remote endpoint created"));
|
|
@@ -954,38 +1175,44 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
954
1175
|
}
|
|
955
1176
|
}
|
|
956
1177
|
validateProjectCompatibility(flags) {
|
|
957
|
-
const
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1178
|
+
const spinner = ora5("Checking Next.js project compatibility...").start();
|
|
1179
|
+
try {
|
|
1180
|
+
const projectPath = path5.resolve(process.cwd(), flags.dir);
|
|
1181
|
+
if (!fs5.existsSync(projectPath)) {
|
|
1182
|
+
spinner.fail(`Directory ${flags.dir} does not exist`);
|
|
1183
|
+
throw new Error(`Please provide a valid Next.js project directory.`);
|
|
1184
|
+
}
|
|
1185
|
+
const packageJsonPath = path5.join(projectPath, "package.json");
|
|
1186
|
+
if (!fs5.existsSync(packageJsonPath)) {
|
|
1187
|
+
spinner.fail(`No package.json found in ${projectPath}`);
|
|
1188
|
+
throw new Error(`Please provide a valid Next.js project with a package.json file.`);
|
|
1189
|
+
}
|
|
1190
|
+
const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath, "utf8"));
|
|
1191
|
+
if (!packageJson.dependencies?.next && !packageJson.devDependencies?.next) {
|
|
1192
|
+
spinner.fail(`Not a Next.js project`);
|
|
1193
|
+
throw new Error(`Directory ${projectPath} does not appear to be a Next.js project. Make sure it has next in dependencies.`);
|
|
1194
|
+
}
|
|
1195
|
+
spinner.succeed(`\u{1F53C} Valid Next.js project detected at ${projectPath}`);
|
|
1196
|
+
return true;
|
|
1197
|
+
} catch (error) {
|
|
1198
|
+
if (!spinner.isSpinning) {
|
|
1199
|
+
this.log(chalk6.red(error.message));
|
|
1200
|
+
} else {
|
|
1201
|
+
spinner.fail(chalk6.red(error.message));
|
|
1202
|
+
}
|
|
970
1203
|
process.exit(1);
|
|
971
1204
|
}
|
|
972
|
-
this.log(chalk6.green(`Valid Next.js project detected
|
|
973
|
-
`));
|
|
974
|
-
return true;
|
|
975
1205
|
}
|
|
976
1206
|
finalSummary(userAnswers) {
|
|
977
1207
|
let agentDevInstructions = "";
|
|
978
1208
|
let agentType = "";
|
|
979
1209
|
let agentSetupMessage = "";
|
|
980
|
-
if (userAnswers.agentFramework
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
agentSetupMessage = `We've scaffolded a ${chalk6.cyan(userAnswers.crewFlowAgent || "CrewAI")} agent in the ${chalk6.cyan("./agent")} directory.`;
|
|
987
|
-
agentDevInstructions = "poetry install && poetry run demo";
|
|
988
|
-
}
|
|
1210
|
+
if (userAnswers.agentFramework === "CrewAI") {
|
|
1211
|
+
agentType = "CrewAI";
|
|
1212
|
+
if (userAnswers.crewType === "Crews") {
|
|
1213
|
+
agentSetupMessage = `Using your Crew from ${chalk6.cyan(userAnswers.crewUrl || "the provided URL")}.`;
|
|
1214
|
+
} else if (userAnswers.crewType === "Flows") {
|
|
1215
|
+
agentSetupMessage = `We've scaffolded a ${chalk6.cyan(userAnswers.crewFlowAgent || "CrewAI")} agent in the ${chalk6.cyan("./agent")} directory.`;
|
|
989
1216
|
}
|
|
990
1217
|
}
|
|
991
1218
|
switch (userAnswers.agentFramework) {
|
|
@@ -993,7 +1220,7 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
993
1220
|
switch (userAnswers.langGraphAgent) {
|
|
994
1221
|
case "Python Starter":
|
|
995
1222
|
agentSetupMessage = `We've scaffolded a ${chalk6.cyan(userAnswers.langGraphAgent || "LangGraph")} agent in the ${chalk6.cyan("./agent")} directory.`;
|
|
996
|
-
agentDevInstructions = "poetry install && npx @langchain/langgraph-cli dev --port 8123";
|
|
1223
|
+
agentDevInstructions = "poetry lock && poetry install && npx @langchain/langgraph-cli dev --port 8123";
|
|
997
1224
|
break;
|
|
998
1225
|
case "TypeScript Starter":
|
|
999
1226
|
agentSetupMessage = `We've scaffolded a ${chalk6.cyan(userAnswers.langGraphAgent || "LangGraph")} agent in the ${chalk6.cyan("./agent")} directory.`;
|
|
@@ -1025,7 +1252,7 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1025
1252
|
this.log(` - Start your Next.js app: ${chalk6.gray("$")} ${chalk6.cyan("npm run dev")}`);
|
|
1026
1253
|
if (agentDevInstructions) this.log(` - Start your agent: ${chalk6.gray("$")} ${chalk6.cyan(`cd agent && ${agentDevInstructions}`)}`);
|
|
1027
1254
|
this.log(` - Navigate to ${chalk6.blue("http://localhost:3000/copilotkit")}`);
|
|
1028
|
-
this.log(` - Talk to your
|
|
1255
|
+
this.log(` - Talk to your agent.`);
|
|
1029
1256
|
this.log(` - Read the docs: ${chalk6.blue("https://docs.copilotkit.ai")}`);
|
|
1030
1257
|
this.log(chalk6.magenta("\nEnjoy building with CopilotKit \u{1FA81}\n"));
|
|
1031
1258
|
}
|