@inkeep/agents-cli 0.21.0 → 0.22.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.
Files changed (2) hide show
  1. package/dist/index.js +390 -86
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -78,18 +78,29 @@ var init_models = __esm({
78
78
  "use strict";
79
79
  init_esm_shims();
80
80
  ANTHROPIC_MODELS = {
81
+ CLAUDE_OPUS_4_1: "anthropic/claude-opus-4-1",
81
82
  CLAUDE_OPUS_4_1_20250805: "anthropic/claude-opus-4-1-20250805",
83
+ CLAUDE_SONNET_4_5: "anthropic/claude-sonnet-4-5",
82
84
  CLAUDE_SONNET_4_5_20250929: "anthropic/claude-sonnet-4-5-20250929",
85
+ CLAUDE_SONNET_4: "anthropic/claude-sonnet-4",
83
86
  CLAUDE_SONNET_4_20250514: "anthropic/claude-sonnet-4-20250514",
87
+ CLAUDE_3_5_SONNET: "anthropic/claude-3-5-sonnet",
84
88
  CLAUDE_3_5_SONNET_20241022: "anthropic/claude-3-5-sonnet-20241022",
89
+ CLAUDE_3_5_HAIKU: "anthropic/claude-3-5-haiku",
85
90
  CLAUDE_3_5_HAIKU_20241022: "anthropic/claude-3-5-haiku-20241022"
86
91
  };
87
92
  OPENAI_MODELS = {
93
+ GPT_5: "openai/gpt-5",
88
94
  GPT_5_20250807: "openai/gpt-5-2025-08-07",
95
+ GPT_5_MINI: "openai/gpt-5-mini",
89
96
  GPT_5_MINI_20250807: "openai/gpt-5-mini-2025-08-07",
97
+ GPT_5_NANO: "openai/gpt-5-nano",
90
98
  GPT_5_NANO_20250807: "openai/gpt-5-nano-2025-08-07",
99
+ GPT_4_1: "openai/gpt-4.1",
91
100
  GPT_4_1_20250414: "openai/gpt-4.1-2025-04-14",
101
+ GPT_4_1_MINI: "openai/gpt-4.1-mini",
92
102
  GPT_4_1_MINI_20250414: "openai/gpt-4.1-mini-2025-04-14",
103
+ GPT_4_1_NANO: "openai/gpt-4.1-nano",
93
104
  GPT_4_1_NANO_20250414: "openai/gpt-4.1-nano-2025-04-14"
94
105
  };
95
106
  GOOGLE_MODELS = {
@@ -1607,11 +1618,8 @@ var init_schema = __esm({
1607
1618
  {
1608
1619
  ...tenantScoped,
1609
1620
  ...uiProperties,
1610
- // Project-level default model settings that can be inherited by agents
1611
1621
  models: text("models", { mode: "json" }).$type(),
1612
- // Project-level stopWhen configuration that can be inherited by agents
1613
1622
  stopWhen: text("stop_when", { mode: "json" }).$type(),
1614
- // Project-level sandbox configuration for function execution
1615
1623
  sandboxConfig: text("sandbox_config", { mode: "json" }).$type(),
1616
1624
  ...timestamps
1617
1625
  },
@@ -1644,9 +1652,7 @@ var init_schema = __esm({
1644
1652
  "context_configs",
1645
1653
  {
1646
1654
  ...agentScoped,
1647
- // Developer-defined Zod schema for validating incoming request context
1648
1655
  headersSchema: blob("headers_schema", { mode: "json" }).$type(),
1649
- // Object mapping template keys to fetch definitions that use request context data
1650
1656
  contextVariables: blob("context_variables", { mode: "json" }).$type(),
1651
1657
  ...timestamps
1652
1658
  },
@@ -1663,15 +1669,11 @@ var init_schema = __esm({
1663
1669
  "context_cache",
1664
1670
  {
1665
1671
  ...projectScoped,
1666
- // Always scoped to conversation for complete data isolation
1667
1672
  conversationId: text("conversation_id").notNull(),
1668
- // Reference to the context config and specific fetch definition
1669
1673
  contextConfigId: text("context_config_id").notNull(),
1670
1674
  contextVariableKey: text("context_variable_key").notNull(),
1671
1675
  value: blob("value", { mode: "json" }).$type().notNull(),
1672
- // Request hash for cache invalidation based on context changes
1673
1676
  requestHash: text("request_hash"),
1674
- // Metadata for monitoring and debugging
1675
1677
  fetchedAt: text("fetched_at").notNull(),
1676
1678
  fetchSource: text("fetch_source"),
1677
1679
  fetchDurationMs: integer("fetch_duration_ms"),
@@ -1718,9 +1720,7 @@ var init_schema = __esm({
1718
1720
  {
1719
1721
  ...agentScoped,
1720
1722
  sourceSubAgentId: text("source_sub_agent_id").notNull(),
1721
- // For internal relationships
1722
1723
  targetSubAgentId: text("target_sub_agent_id"),
1723
- // For external relationships
1724
1724
  externalSubAgentId: text("external_sub_agent_id"),
1725
1725
  relationType: text("relation_type"),
1726
1726
  ...timestamps
@@ -1889,9 +1889,7 @@ var init_schema = __esm({
1889
1889
  config: blob("config", { mode: "json" }).$type().notNull(),
1890
1890
  credentialReferenceId: text("credential_reference_id"),
1891
1891
  headers: blob("headers", { mode: "json" }).$type(),
1892
- // Image URL for custom tool icon (supports regular URLs and base64 encoded images)
1893
1892
  imageUrl: text("image_url"),
1894
- // Server capabilities and status (only for MCP tools)
1895
1893
  capabilities: blob("capabilities", { mode: "json" }).$type(),
1896
1894
  lastError: text("last_error"),
1897
1895
  ...timestamps
@@ -1921,7 +1919,6 @@ var init_schema = __esm({
1921
1919
  foreignColumns: [agents.tenantId, agents.projectId, agents.id],
1922
1920
  name: "function_tools_agent_fk"
1923
1921
  }).onDelete("cascade"),
1924
- // Foreign key constraint to functions table
1925
1922
  foreignKey({
1926
1923
  columns: [table.tenantId, table.projectId, table.functionId],
1927
1924
  foreignColumns: [functions.tenantId, functions.projectId, functions.id],
@@ -1979,13 +1976,11 @@ var init_schema = __esm({
1979
1976
  },
1980
1977
  (table) => [
1981
1978
  primaryKey({ columns: [table.tenantId, table.projectId, table.agentId, table.id] }),
1982
- // Foreign key constraint to sub_agents table
1983
1979
  foreignKey({
1984
1980
  columns: [table.tenantId, table.projectId, table.agentId, table.subAgentId],
1985
1981
  foreignColumns: [subAgents.tenantId, subAgents.projectId, subAgents.agentId, subAgents.id],
1986
1982
  name: "sub_agent_function_tool_relations_sub_agent_fk"
1987
1983
  }).onDelete("cascade"),
1988
- // Foreign key constraint to functionTools table
1989
1984
  foreignKey({
1990
1985
  columns: [table.tenantId, table.projectId, table.agentId, table.functionToolId],
1991
1986
  foreignColumns: [
@@ -2023,26 +2018,18 @@ var init_schema = __esm({
2023
2018
  {
2024
2019
  ...projectScoped,
2025
2020
  conversationId: text("conversation_id").notNull(),
2026
- // Role mapping: user, agent, system (unified for both formats)
2027
2021
  role: text("role").notNull(),
2028
- // Agent sender/recipient tracking (nullable - only populated when relevant)
2029
2022
  fromSubAgentId: text("from_sub_agent_id"),
2030
2023
  toSubAgentId: text("to_sub_agent_id"),
2031
- // External agent sender tracking
2032
2024
  fromExternalAgentId: text("from_external_sub_agent_id"),
2033
- // External agent recipient tracking
2034
2025
  toExternalAgentId: text("to_external_sub_agent_id"),
2035
- // Message content stored as JSON to support both formats
2036
2026
  content: blob("content", { mode: "json" }).$type().notNull(),
2037
- // Message classification and filtering
2038
2027
  visibility: text("visibility").notNull().default("user-facing"),
2039
2028
  messageType: text("message_type").notNull().default("chat"),
2040
2029
  taskId: text("task_id"),
2041
2030
  parentMessageId: text("parent_message_id"),
2042
- // A2A specific fields
2043
2031
  a2aTaskId: text("a2a_task_id"),
2044
2032
  a2aSessionId: text("a2a_session_id"),
2045
- // Metadata for extensions
2046
2033
  metadata: blob("metadata", { mode: "json" }).$type(),
2047
2034
  ...timestamps
2048
2035
  },
@@ -2059,17 +2046,14 @@ var init_schema = __esm({
2059
2046
  "ledger_artifacts",
2060
2047
  {
2061
2048
  ...projectScoped,
2062
- // Links
2063
2049
  taskId: text("task_id").notNull(),
2064
2050
  toolCallId: text("tool_call_id"),
2065
2051
  contextId: text("context_id").notNull(),
2066
- // Core Artifact fields
2067
2052
  type: text("type").notNull().default("source"),
2068
2053
  name: text("name"),
2069
2054
  description: text("description"),
2070
2055
  parts: blob("parts", { mode: "json" }).$type(),
2071
2056
  metadata: blob("metadata", { mode: "json" }).$type(),
2072
- // Extra ledger information (not part of the Artifact spec – kept optional)
2073
2057
  summary: text("summary"),
2074
2058
  mime: blob("mime", { mode: "json" }).$type(),
2075
2059
  visibility: text("visibility").default("context"),
@@ -234104,10 +234088,10 @@ function maskSensitiveConfig(config) {
234104
234088
  if (!config) return config;
234105
234089
  const masked = { ...config };
234106
234090
  if (masked.agentsManageApiKey) {
234107
- masked.agentsManageApiKey = "***" + masked.agentsManageApiKey.slice(-4);
234091
+ masked.agentsManageApiKey = `***${masked.agentsManageApiKey.slice(-4)}`;
234108
234092
  }
234109
234093
  if (masked.agentsRunApiKey) {
234110
- masked.agentsRunApiKey = "***" + masked.agentsRunApiKey.slice(-4);
234094
+ masked.agentsRunApiKey = `***${masked.agentsRunApiKey.slice(-4)}`;
234111
234095
  }
234112
234096
  return masked;
234113
234097
  }
@@ -234551,6 +234535,9 @@ function isJsonSchemaPath(path3) {
234551
234535
  if (path3.includes("dataComponents") && path3.endsWith("props")) {
234552
234536
  return true;
234553
234537
  }
234538
+ if (path3.includes("statusComponents") && path3.endsWith("detailsSchema")) {
234539
+ return true;
234540
+ }
234554
234541
  return false;
234555
234542
  }
234556
234543
  function updateTracker(tracker, placeholder, value) {
@@ -234629,7 +234616,7 @@ function restorePlaceholders(generatedCode, replacements) {
234629
234616
  const sortedPlaceholders = Object.keys(replacements).sort((a, b2) => b2.length - a.length);
234630
234617
  for (const placeholder of sortedPlaceholders) {
234631
234618
  let originalValue = replacements[placeholder];
234632
- originalValue = originalValue.replace(/`/g, "\\`");
234619
+ originalValue = originalValue.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
234633
234620
  const escapedPlaceholder = placeholder.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
234634
234621
  const regex = new RegExp(escapedPlaceholder, "g");
234635
234622
  restoredCode = restoredCode.replace(regex, originalValue);
@@ -234669,6 +234656,7 @@ __export(pull_llm_generate_exports, {
234669
234656
  generateDataComponentFile: () => generateDataComponentFile,
234670
234657
  generateEnvironmentFiles: () => generateEnvironmentFiles,
234671
234658
  generateIndexFile: () => generateIndexFile,
234659
+ generateStatusComponentFile: () => generateStatusComponentFile,
234672
234660
  generateTextWithPlaceholders: () => generateTextWithPlaceholders,
234673
234661
  generateToolFile: () => generateToolFile,
234674
234662
  generateTypeScriptFileWithLLM: () => generateTypeScriptFileWithLLM,
@@ -234834,22 +234822,48 @@ ${NAMING_CONVENTION_RULES}
234834
234822
  ${IMPORT_INSTRUCTIONS}
234835
234823
 
234836
234824
  REQUIREMENTS:
234837
- 1. Import { agent, subAgent } from '@inkeep/agents-sdk'
234825
+ 1. IMPORTS (CRITICAL):
234826
+ - ALWAYS import { agent, subAgent } from '@inkeep/agents-sdk'
234827
+ - ALWAYS import { z } from 'zod' when using ANY Zod schemas (responseSchema, headersSchema, etc.)
234828
+ - ALWAYS import { contextConfig, fetchDefinition, headers } from '@inkeep/agents-core' when agent has contextConfig
234829
+ - Import status components from '../status-components/' when needed
234838
234830
  2. Define each agent using the agent() function following the type definitions provided above
234839
234831
  3. Create the agent using agent() with proper structure
234840
234832
  - IMPORTANT: If description is null, undefined, or empty string, omit the description field entirely
234841
- 4. CRITICAL: For multi-line strings (especially prompts), ALWAYS use template literals with backticks:
234842
- - Single-line strings: use regular quotes 'short string'
234843
- - Multi-line strings: MUST use template literals starting and ending with backticks
234833
+ 4. CRITICAL: Template Literals vs Raw Code:
234834
+ - For STRING VALUES: ALWAYS use template literals with backticks: \`string content\`
234835
+ - This includes: prompt, description, query, url, method, body, defaultValue, etc.
234836
+ - This prevents TypeScript syntax errors with apostrophes (user's, don't, etc.)
234844
234837
  - IMPORTANT: ANY placeholder that starts with < and ends with > MUST be wrapped in template literals (backticks)
234845
- - Placeholders contain multi-line content and require template literals
234846
- - This prevents TypeScript syntax errors with newlines and special characters
234847
- - you must import { z } from 'zod' if you are using zod schemas in the agent file.
234848
- - you must import { headers } from '@inkeep/agents-core' and use it to create the headers schema if you are using headers in a contextConfig.
234838
+ - For object keys: use quotes only for keys with hyphens ('Content-Type'), omit for simple identifiers (Authorization)
234839
+
234840
+ EXCEPTION - Schema Fields (NO template literals):
234841
+ - headersSchema: z.object({ ... }) (raw Zod code, NOT a string)
234842
+ - responseSchema: z.object({ ... }) (raw Zod code, NOT a string)
234843
+ - These are TypeScript expressions, not string values
234844
+
234845
+ Examples:
234846
+ \u2705 prompt: \`You are a helpful assistant.\` (string value, use backticks)
234847
+ \u2705 query: \`query GetData { field }\` (string value, use backticks)
234848
+ \u2705 responseSchema: z.object({ name: z.string() }) (Zod code, NO backticks)
234849
+ \u2705 headersSchema: z.object({ 'inkeep_api_key': z.string() }) (Zod code, NO backticks)
234850
+ \u274C responseSchema: \`z.object({ name: z.string() })\` (WRONG - don't wrap Zod in backticks)
234851
+
234849
234852
  - convert template literals to use the appropriate headers schema or context config toTemplate method. a template literal is a substring that starts with {{ and ends with }}.
234850
234853
  - if you see a template literal with {{headers.}}, convert it to use the headers schema toTemplate method.
234851
234854
  - if you see a template literal with {{contextVariableKey.field_name}}, convert it to use the context config toTemplate method.
234852
- 6. If you are writing zod schemas make them clean. For example if you see z.union([z.string(), z.null()]) write it as z.string().nullable()
234855
+ 5. For contextConfig (CRITICAL):
234856
+ - NEVER use plain objects for contextConfig
234857
+ - ALWAYS use helper functions: headers(), fetchDefinition(), contextConfig()
234858
+ - Create separate const variables for each helper before the agent definition
234859
+ - Pattern: const myHeaders = headers({ schema: z.object({ api_key: z.string() }) });
234860
+ - Pattern: const myFetch = fetchDefinition({ id: '...', fetchConfig: {...}, responseSchema: z.object({...}) });
234861
+ - Pattern: const myContext = contextConfig({ headers: myHeaders, contextVariables: { data: myFetch } });
234862
+ - Then use: export const myAgent = agent({ contextConfig: myContext });
234863
+ - Use myHeaders.toTemplate('key_name') for header interpolation in fetch configs
234864
+ - Use myContext.toTemplate('variable.field') for context variable interpolation
234865
+
234866
+ 7. If you are writing zod schemas make them clean. For example if you see z.union([z.string(), z.null()]) write it as z.string().nullable()
234853
234867
 
234854
234868
  PLACEHOLDER HANDLING EXAMPLES:
234855
234869
  // CORRECT - Placeholder wrapped in template literals:
@@ -234864,6 +234878,8 @@ import { contextConfig, fetchDefinition, headers } from '@inkeep/agents-core';
234864
234878
  import { userProfile } from '../data-components/user-profile';
234865
234879
  import { searchTool } from '../tools/search-tool';
234866
234880
  import { weatherTool } from '../tools/weather-tool';
234881
+ import { toolSummary } from '../status-components/tool-summary';
234882
+ import { progressStatus } from '../status-components/progress-status';
234867
234883
  import { z } from 'zod';
234868
234884
 
234869
234885
  const supportAgentHeaders = headers({
@@ -234928,7 +234944,16 @@ export const supportAgent = agent({
234928
234944
  name: 'Support Agent',
234929
234945
  description: 'Multi-agent support system', // Only include if description has a value
234930
234946
  defaultSubAgent: routerAgent,
234931
- subAgents: () => [routerAgent, qaAgent]
234947
+ subAgents: () => [routerAgent, qaAgent],
234948
+ models: {
234949
+ base: { model: 'gpt-4' },
234950
+ summarizer: { model: 'gpt-4' },
234951
+ },
234952
+ statusUpdates: {
234953
+ numEvents: 3,
234954
+ timeInSeconds: 15,
234955
+ statusComponents: [toolSummary.config, progressStatus.config],
234956
+ },
234932
234957
  });
234933
234958
 
234934
234959
  Generate ONLY the TypeScript code without any markdown or explanations.`;
@@ -235212,6 +235237,75 @@ Generate ONLY the TypeScript code without any markdown or explanations.`;
235212
235237
  });
235213
235238
  writeFileSync3(outputPath, cleanGeneratedCode(text2));
235214
235239
  }
235240
+ async function generateStatusComponentFile(componentData, componentId, outputPath, modelSettings) {
235241
+ const model = createModel(modelSettings);
235242
+ const promptTemplate = `Generate a TypeScript file for an Inkeep status component.
235243
+
235244
+ STATUS COMPONENT DATA:
235245
+ {{DATA}}
235246
+
235247
+ COMPONENT ID: ${componentId}
235248
+
235249
+ ${getTypeDefinitions()}
235250
+
235251
+ ${NAMING_CONVENTION_RULES}
235252
+
235253
+ ${IMPORT_INSTRUCTIONS}
235254
+
235255
+ REQUIREMENTS:
235256
+ 1. Import statusComponent from '@inkeep/agents-sdk'
235257
+ 2. Import z from 'zod' for schema definitions
235258
+ 3. Create the status component using statusComponent()
235259
+ 4. Export following naming convention rules (camelCase version of ID)
235260
+ 5. Use 'type' field as the identifier (like 'tool_summary')
235261
+ 6. CRITICAL: All imports must be alphabetically sorted to comply with Biome linting
235262
+ 7. If you are writing zod schemas make them clean. For example if you see z.union([z.string(), z.null()]) write it as z.string().nullable()
235263
+ 8. The statusComponent() function handles conversion to .config automatically
235264
+
235265
+ EXAMPLE:
235266
+ import { statusComponent } from '@inkeep/agents-sdk';
235267
+ import { z } from 'zod';
235268
+
235269
+ export const toolSummary = statusComponent({
235270
+ type: 'tool_summary',
235271
+ description: 'Summary of tool calls and their purpose',
235272
+ detailsSchema: z.object({
235273
+ tool_name: z.string().describe('Name of tool used'),
235274
+ summary: z.string().describe('What was discovered or accomplished'),
235275
+ }),
235276
+ });
235277
+
235278
+ EXAMPLE WITH HYPHEN TYPE:
235279
+ import { statusComponent } from '@inkeep/agents-sdk';
235280
+ import { z } from 'zod';
235281
+
235282
+ // Component type 'search-progress' becomes export name 'searchProgress'
235283
+ export const searchProgress = statusComponent({
235284
+ type: 'search-progress',
235285
+ description: 'Progress of search operation',
235286
+ detailsSchema: z.object({
235287
+ query: z.string().describe('Search query being executed'),
235288
+ results_found: z.number().describe('Number of results found'),
235289
+ time_elapsed: z.number().optional().describe('Time elapsed in milliseconds'),
235290
+ }),
235291
+ });
235292
+
235293
+ EXAMPLE WITHOUT DETAILS SCHEMA:
235294
+ import { statusComponent } from '@inkeep/agents-sdk';
235295
+
235296
+ export const simpleStatus = statusComponent({
235297
+ type: 'simple_status',
235298
+ description: 'A simple status with no additional details',
235299
+ });
235300
+
235301
+ Generate ONLY the TypeScript code without any markdown or explanations.`;
235302
+ const text2 = await generateTextWithPlaceholders(model, componentData, promptTemplate, {
235303
+ temperature: 0.1,
235304
+ maxOutputTokens: 4e3,
235305
+ abortSignal: AbortSignal.timeout(6e4)
235306
+ });
235307
+ writeFileSync3(outputPath, cleanGeneratedCode(text2));
235308
+ }
235215
235309
  async function generateEnvironmentFiles(environmentsDir, credentials, environment = "development") {
235216
235310
  const generateCredentialCode = (cred) => {
235217
235311
  const params = [
@@ -235658,6 +235752,18 @@ function collectAllEntities(projectData) {
235658
235752
  entities.push({ id: compId, type: "artifactComponent" });
235659
235753
  }
235660
235754
  }
235755
+ if (projectData.agents) {
235756
+ for (const [_agentId, agentData] of Object.entries(projectData.agents)) {
235757
+ const agentObj = agentData;
235758
+ if (agentObj.statusUpdates?.statusComponents) {
235759
+ for (const statusComp of agentObj.statusUpdates.statusComponents) {
235760
+ if (statusComp.type) {
235761
+ entities.push({ id: statusComp.type, type: "statusComponent" });
235762
+ }
235763
+ }
235764
+ }
235765
+ }
235766
+ }
235661
235767
  if (projectData.credentialReferences) {
235662
235768
  for (const credId of Object.keys(projectData.credentialReferences)) {
235663
235769
  entities.push({ id: credId, type: "credential" });
@@ -235677,6 +235783,7 @@ var init_variable_name_registry = __esm({
235677
235783
  // Usually no suffix needed
235678
235784
  dataComponentSuffix: null,
235679
235785
  artifactComponentSuffix: null,
235786
+ statusComponentSuffix: null,
235680
235787
  credentialSuffix: null
235681
235788
  };
235682
235789
  VariableNameGenerator = class {
@@ -235690,6 +235797,7 @@ var init_variable_name_registry = __esm({
235690
235797
  tools: /* @__PURE__ */ new Map(),
235691
235798
  dataComponents: /* @__PURE__ */ new Map(),
235692
235799
  artifactComponents: /* @__PURE__ */ new Map(),
235800
+ statusComponents: /* @__PURE__ */ new Map(),
235693
235801
  credentials: /* @__PURE__ */ new Map(),
235694
235802
  usedNames: /* @__PURE__ */ new Map()
235695
235803
  };
@@ -235801,6 +235909,8 @@ var init_variable_name_registry = __esm({
235801
235909
  return this.conventions.dataComponentSuffix || "";
235802
235910
  case "artifactComponent":
235803
235911
  return this.conventions.artifactComponentSuffix || "";
235912
+ case "statusComponent":
235913
+ return this.conventions.statusComponentSuffix || "";
235804
235914
  case "credential":
235805
235915
  return this.conventions.credentialSuffix || "";
235806
235916
  default:
@@ -235822,6 +235932,8 @@ var init_variable_name_registry = __esm({
235822
235932
  return this.registry.dataComponents;
235823
235933
  case "artifactComponent":
235824
235934
  return this.registry.artifactComponents;
235935
+ case "statusComponent":
235936
+ return this.registry.statusComponents;
235825
235937
  case "credential":
235826
235938
  return this.registry.credentials;
235827
235939
  default:
@@ -236136,6 +236248,7 @@ function displayPlanSummary(plan) {
236136
236248
  tool: [],
236137
236249
  dataComponent: [],
236138
236250
  artifactComponent: [],
236251
+ statusComponent: [],
236139
236252
  environment: []
236140
236253
  };
236141
236254
  for (const file of plan.files) {
@@ -236188,6 +236301,15 @@ function displayPlanSummary(plan) {
236188
236301
  }
236189
236302
  }
236190
236303
  }
236304
+ if (filesByType.statusComponent.length > 0) {
236305
+ console.log(chalk7.gray("\n Status Components:"));
236306
+ for (const file of filesByType.statusComponent) {
236307
+ console.log(chalk7.gray(` \u2022 ${file.path}`));
236308
+ for (const entity of file.entities) {
236309
+ console.log(chalk7.gray(` - ${entity.variableName}`));
236310
+ }
236311
+ }
236312
+ }
236191
236313
  if (filesByType.environment.length > 0) {
236192
236314
  console.log(chalk7.gray("\n Environments:"));
236193
236315
  for (const file of filesByType.environment) {
@@ -236209,7 +236331,9 @@ function displayPatternSummary(patterns) {
236209
236331
  console.log(chalk7.gray(` \u2022 Agent suffix: "${patterns.namingConventions.agentSuffix}"`));
236210
236332
  console.log(chalk7.gray(` \u2022 SubAgent suffix: "${patterns.namingConventions.subAgentSuffix}"`));
236211
236333
  if (patterns.examples.mappings && patterns.examples.mappings.length > 0) {
236212
- console.log(chalk7.gray(` Found ${patterns.examples.mappings.length} existing variable mappings`));
236334
+ console.log(
236335
+ chalk7.gray(` Found ${patterns.examples.mappings.length} existing variable mappings`)
236336
+ );
236213
236337
  }
236214
236338
  }
236215
236339
  function displayRecommendedPattern() {
@@ -236316,10 +236440,7 @@ async function generatePlan(projectData, patterns, modelSettings, createModel2)
236316
236440
  nameGenerator.generateVariableName(entity.id, entity.type);
236317
236441
  }
236318
236442
  const model = createModel2(modelSettings);
236319
- const promptTemplate = createPlanningPromptTemplate(
236320
- nameGenerator.getRegistry(),
236321
- allEntities
236322
- );
236443
+ const promptTemplate = createPlanningPromptTemplate(nameGenerator.getRegistry(), allEntities);
236323
236444
  const promptData = {
236324
236445
  projectData,
236325
236446
  patterns
@@ -236369,28 +236490,42 @@ CRITICAL RULES:
236369
236490
  1. TOOL TYPES - VERY IMPORTANT:
236370
236491
  - **Function Tools** (type: "function"): ALWAYS define INLINE within agent files using "inlineContent" array
236371
236492
  - **MCP Tools** (type: "mcp"): Create separate files in tools/ directory
236372
- - VALID FILE TYPES: Only use these exact types: "agent", "tool", "dataComponent", "artifactComponent", "environment", "index"
236493
+ - VALID FILE TYPES: Only use these exact types: "agent", "tool", "dataComponent", "artifactComponent", "statusComponent", "environment", "index"
236373
236494
  - NEVER create file type "functionTool" - function tools go in "inlineContent" of agent files
236374
236495
 
236375
- 2. File Structure:
236496
+ 2. STATUS COMPONENTS - VERY IMPORTANT:
236497
+ - **Status Components**: ALWAYS create separate files in status-components/ directory
236498
+ - Status components are found in agent.statusUpdates.statusComponents array
236499
+ - Each status component should get its own file
236500
+ - Agents must import status components from status-components/ directory
236501
+ - Status components are NEVER inlined in agent files
236502
+
236503
+ 3. File Structure:
236376
236504
  - If patterns show "toolsLocation": "inline", ALL tools should be in "inlineContent" of agent files
236377
236505
  - If patterns show "toolsLocation": "separate", MCP tools get separate files, function tools still inline
236378
236506
  - Follow the detected file naming convention (kebab-case, camelCase, or snake_case)
236379
236507
 
236380
- 3. Variable Names:
236508
+ 4. Variable Names:
236381
236509
  - MUST use the exact variable names from the mappings above
236382
236510
  - If ID "weather" is used by both agent and subAgent, they will have different variable names
236383
236511
  - Do NOT generate new variable names - use what's provided
236384
236512
 
236385
- 4. File Placement:
236513
+ 5. File Placement:
236386
236514
  - agents/ directory: Agent files (with function tools in "inlineContent")
236387
236515
  - tools/ directory: MCP tool files only
236388
236516
  - data-components/ directory: Data component files
236389
236517
  - artifact-components/ directory: Artifact component files
236518
+ - status-components/ directory: Status component files
236390
236519
  - environments/ directory: Environment/credential files
236391
236520
  - index.ts: Main project file
236392
236521
 
236393
- 5. Dependencies:
236522
+ 6. File Paths (CRITICAL):
236523
+ - Paths MUST be relative to the project root directory
236524
+ - DO NOT include the project name in the path
236525
+ - CORRECT: "agents/weather-agent.ts", "tools/inkeep-facts.ts", "status-components/tool-summary.ts"
236526
+ - WRONG: "my-project/agents/weather-agent.ts", "project-name/tools/inkeep-facts.ts"
236527
+
236528
+ 7. Dependencies:
236394
236529
  - Each file should list which variables it needs to import from other files
236395
236530
  - Imports should use relative paths
236396
236531
  - Respect detected import style (named vs default)
@@ -236445,6 +236580,20 @@ OUTPUT FORMAT (JSON):
236445
236580
  "dependencies": [],
236446
236581
  "inlineContent": null
236447
236582
  },
236583
+ {
236584
+ "path": "status-components/tool-summary.ts",
236585
+ "type": "statusComponent",
236586
+ "entities": [
236587
+ {
236588
+ "id": "tool_summary",
236589
+ "variableName": "toolSummary",
236590
+ "entityType": "statusComponent",
236591
+ "exportName": "toolSummary"
236592
+ }
236593
+ ],
236594
+ "dependencies": [],
236595
+ "inlineContent": null
236596
+ },
236448
236597
  {
236449
236598
  "path": "index.ts",
236450
236599
  "type": "index",
@@ -236482,6 +236631,7 @@ function formatVariableMappings(registry2, allEntities) {
236482
236631
  tool: [],
236483
236632
  dataComponent: [],
236484
236633
  artifactComponent: [],
236634
+ statusComponent: [],
236485
236635
  credential: []
236486
236636
  };
236487
236637
  for (const entity of allEntities) {
@@ -236516,6 +236666,8 @@ function getRegistryMap(registry2, entityType) {
236516
236666
  return registry2.dataComponents;
236517
236667
  case "artifactComponent":
236518
236668
  return registry2.artifactComponents;
236669
+ case "statusComponent":
236670
+ return registry2.statusComponents;
236519
236671
  case "credential":
236520
236672
  return registry2.credentials;
236521
236673
  default:
@@ -236598,6 +236750,21 @@ function generateDefaultPlan(registry2) {
236598
236750
  dependencies: []
236599
236751
  });
236600
236752
  }
236753
+ for (const [compId, variableName] of registry2.statusComponents.entries()) {
236754
+ files.push({
236755
+ path: `status-components/${kebabCase(compId)}.ts`,
236756
+ type: "statusComponent",
236757
+ entities: [
236758
+ {
236759
+ id: compId,
236760
+ variableName,
236761
+ entityType: "statusComponent",
236762
+ exportName: variableName
236763
+ }
236764
+ ],
236765
+ dependencies: []
236766
+ });
236767
+ }
236601
236768
  files.push({
236602
236769
  path: "index.ts",
236603
236770
  type: "index",
@@ -236633,14 +236800,18 @@ async function generateFilesFromPlan(plan, projectData, dirs, modelSettings, deb
236633
236800
  (fileInfo, index2) => generateFile(fileInfo, projectData, plan, dirs, modelSettings, debug).then(() => {
236634
236801
  if (debug) {
236635
236802
  const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
236636
- console.log(`[DEBUG] \u2713 Completed ${index2 + 1}/${plan.files.length}: ${fileInfo.path} (${elapsed}s elapsed)`);
236803
+ console.log(
236804
+ `[DEBUG] \u2713 Completed ${index2 + 1}/${plan.files.length}: ${fileInfo.path} (${elapsed}s elapsed)`
236805
+ );
236637
236806
  }
236638
236807
  })
236639
236808
  );
236640
236809
  await Promise.all(tasks2);
236641
236810
  const totalTime = ((Date.now() - startTime) / 1e3).toFixed(1);
236642
236811
  if (debug) {
236643
- console.log(`[DEBUG] All files generated in ${totalTime}s (${plan.files.length} files in parallel)`);
236812
+ console.log(
236813
+ `[DEBUG] All files generated in ${totalTime}s (${plan.files.length} files in parallel)`
236814
+ );
236644
236815
  }
236645
236816
  }
236646
236817
  async function generateFile(fileInfo, projectData, plan, dirs, modelSettings, debug) {
@@ -236678,7 +236849,9 @@ async function generateFile(fileInfo, projectData, plan, dirs, modelSettings, de
236678
236849
  writeFileSync4(outputPath, cleanedCode);
236679
236850
  const totalDuration = ((Date.now() - fileStartTime) / 1e3).toFixed(1);
236680
236851
  if (debug) {
236681
- console.log(`[DEBUG] \u2713 Completed: ${fileInfo.path} (LLM: ${llmDuration}s, Total: ${totalDuration}s)`);
236852
+ console.log(
236853
+ `[DEBUG] \u2713 Completed: ${fileInfo.path} (LLM: ${llmDuration}s, Total: ${totalDuration}s)`
236854
+ );
236682
236855
  }
236683
236856
  } catch (error) {
236684
236857
  console.error(`[ERROR] Failed to generate ${fileInfo.path}:`, error.message);
@@ -236717,6 +236890,21 @@ function extractDataForFile(fileInfo, projectData) {
236717
236890
  }
236718
236891
  return {};
236719
236892
  }
236893
+ case "statusComponent": {
236894
+ const statusType = fileInfo.entities[0]?.id;
236895
+ if (statusType && projectData.agents) {
236896
+ for (const agentData of Object.values(projectData.agents)) {
236897
+ const agent = agentData;
236898
+ if (agent.statusUpdates?.statusComponents) {
236899
+ const found = agent.statusUpdates.statusComponents.find(
236900
+ (sc) => sc.type === statusType
236901
+ );
236902
+ if (found) return found;
236903
+ }
236904
+ }
236905
+ }
236906
+ return {};
236907
+ }
236720
236908
  case "environment":
236721
236909
  return projectData.credentialReferences || {};
236722
236910
  default:
@@ -236772,11 +236960,13 @@ CRITICAL RULES:
236772
236960
  return createDataComponentPrompt(fileData, context, registryInfo, commonInstructions);
236773
236961
  case "artifactComponent":
236774
236962
  return createArtifactComponentPrompt(fileData, context, registryInfo, commonInstructions);
236963
+ case "statusComponent":
236964
+ return createStatusComponentPrompt(fileData, context, registryInfo, commonInstructions);
236775
236965
  default:
236776
236966
  throw new Error(`Unknown file type: ${fileInfo.type}`);
236777
236967
  }
236778
236968
  }
236779
- function createIndexPrompt(projectData, context, registryInfo, commonInstructions) {
236969
+ function createIndexPrompt(_projectData, context, _registryInfo, commonInstructions) {
236780
236970
  const importMappings = generateImportMappings(context.plan);
236781
236971
  return `Generate index.ts for Inkeep project.
236782
236972
 
@@ -236803,7 +236993,7 @@ export const myProject = project({
236803
236993
 
236804
236994
  Generate ONLY the TypeScript code without markdown.`;
236805
236995
  }
236806
- function createAgentPrompt(agentData, context, registryInfo, commonInstructions) {
236996
+ function createAgentPrompt(_agentData, context, _registryInfo, commonInstructions) {
236807
236997
  const inlineTools = context.fileInfo.inlineContent || [];
236808
236998
  const hasInlineTools = inlineTools.length > 0;
236809
236999
  return `Generate TypeScript file for Inkeep agent.
@@ -236857,17 +237047,62 @@ const calculateBMI = functionTool({
236857
237047
  ` : ""}
236858
237048
 
236859
237049
  IMPORTS (CRITICAL - MUST BE FIRST):
236860
- ALWAYS import these from '@inkeep/agents-sdk' at the TOP of the file:
236861
- import { agent, subAgent, functionTool } from '@inkeep/agents-sdk';
237050
+ ALWAYS import these at the TOP of the file:
237051
+ - import { agent, subAgent, functionTool } from '@inkeep/agents-sdk';
237052
+ - import { z } from 'zod'; (REQUIRED when using ANY Zod schemas like responseSchema, headersSchema)
237053
+ - import { contextConfig, fetchDefinition, headers } from '@inkeep/agents-core'; (REQUIRED when agent has contextConfig)
237054
+ - import status components from '../status-components/' when needed
236862
237055
 
236863
237056
  SUBAGENT AND AGENT API (CRITICAL):
236864
237057
  - Use 'canUse' (NOT 'tools') - must be a FUNCTION returning array
236865
237058
  - Use 'canDelegateTo' - must be a FUNCTION returning array
236866
237059
  - Use 'dataComponents' - must be a FUNCTION returning array
236867
237060
  - Use 'subAgents' in agent() - must be a FUNCTION returning array
236868
- - For multi-line strings (like 'prompt'), ALWAYS use template literals (backticks \`...\`)
237061
+
237062
+ CONTEXT CONFIG (CRITICAL - NO PLAIN OBJECTS):
237063
+ - NEVER use plain objects for contextConfig
237064
+ - ALWAYS use helper functions: headers(), fetchDefinition(), contextConfig()
237065
+ - Create separate const variables for each helper before the agent definition
237066
+ - Pattern:
237067
+ const myHeaders = headers({ schema: z.object({ api_key: z.string() }) });
237068
+ const myFetch = fetchDefinition({ id: '...', fetchConfig: {...}, responseSchema: z.object({...}) });
237069
+ const myContext = contextConfig({ headers: myHeaders, contextVariables: { data: myFetch } });
237070
+ export const myAgent = agent({ contextConfig: myContext });
237071
+ - Use myHeaders.toTemplate('key_name') for header values in fetchConfig
237072
+ - Use myContext.toTemplate('variable.field') for prompt interpolation
237073
+
237074
+ STRING LITERALS (CRITICAL - MUST FOLLOW):
237075
+ - For STRING VALUES: ALWAYS use template literals (backticks \`)
237076
+ - This includes: prompt, description, query, url, method, body, defaultValue, etc.
237077
+ - Template literals prevent syntax errors with apostrophes (don't, user's, it's)
237078
+ - For object keys that are identifiers (no hyphens), omit quotes: Authorization not 'Authorization'
237079
+ - For object keys with hyphens, use quotes: 'Content-Type'
237080
+
237081
+ EXCEPTION - Schema Fields (NO template literals):
237082
+ - headersSchema: z.object({ ... }) (raw Zod code, NOT a string)
237083
+ - responseSchema: z.object({ ... }) (raw Zod code, NOT a string)
237084
+ - These are TypeScript expressions, not string values
237085
+
237086
+ CORRECT EXAMPLES:
237087
+ \u2705 prompt: \`You are a helpful assistant.\` (string value)
237088
+ \u2705 query: \`query GetData { field }\` (string value)
237089
+ \u2705 responseSchema: z.object({ name: z.string() }) (Zod code, NO backticks)
237090
+ \u2705 headersSchema: z.object({ 'inkeep_api_key': z.string() }) (Zod code, NO backticks)
237091
+
237092
+ WRONG EXAMPLES:
237093
+ \u274C prompt: 'You are a helpful assistant.' (use backticks not single quotes)
237094
+ \u274C responseSchema: \`z.object({ name: z.string() })\` (don't wrap Zod in backticks)
237095
+
237096
+ STATUS COMPONENTS (CRITICAL):
237097
+ - Status components are ALWAYS imported from '../status-components/' directory
237098
+ - In statusUpdates.statusComponents array, use statusComponent.config to get the config object
237099
+ - NEVER inline status component definitions in the agent file
237100
+ - Example: import { toolSummary } from '../status-components/tool-summary'
237101
+ - Then use: statusComponents: [toolSummary.config]
236869
237102
 
236870
237103
  \u2705 CORRECT:
237104
+ import { toolSummary } from '../status-components/tool-summary';
237105
+
236871
237106
  const weatherSubAgent = subAgent({
236872
237107
  id: 'weather',
236873
237108
  name: 'Weather Sub',
@@ -236884,7 +237119,12 @@ const weatherAgent = agent({
236884
237119
  id: 'weather',
236885
237120
  name: 'Weather Agent',
236886
237121
  defaultSubAgent: weatherSubAgent,
236887
- subAgents: () => [weatherSubAgent] // FUNCTION returning array
237122
+ subAgents: () => [weatherSubAgent], // FUNCTION returning array
237123
+ statusUpdates: {
237124
+ numEvents: 1,
237125
+ timeInSeconds: 1,
237126
+ statusComponents: [toolSummary.config] // Use .config
237127
+ }
236888
237128
  });
236889
237129
 
236890
237130
  \u274C WRONG:
@@ -236893,10 +237133,11 @@ string', // NO - use backticks for multi-line
236893
237133
  tools: [tool1, tool2], // NO - use 'canUse' not 'tools'
236894
237134
  canUse: [tool1, tool2], // NO - must be a function
236895
237135
  subAgents: [weatherSubAgent], // NO - must be a function
237136
+ statusComponents: [{ type: '...', ... }], // NO - import from files
236896
237137
 
236897
237138
  Generate ONLY the TypeScript code without markdown.`;
236898
237139
  }
236899
- function createToolPrompt(toolData, context, registryInfo, commonInstructions) {
237140
+ function createToolPrompt(_toolData, _context, _registryInfo, commonInstructions) {
236900
237141
  return `Generate TypeScript file for Inkeep tool.
236901
237142
 
236902
237143
  TOOL DATA:
@@ -236912,7 +237153,7 @@ REQUIREMENTS:
236912
237153
 
236913
237154
  Generate ONLY the TypeScript code without markdown.`;
236914
237155
  }
236915
- function createDataComponentPrompt(componentData, context, registryInfo, commonInstructions) {
237156
+ function createDataComponentPrompt(_componentData, _context, _registryInfo, commonInstructions) {
236916
237157
  return `Generate TypeScript file for Inkeep data component.
236917
237158
 
236918
237159
  COMPONENT DATA:
@@ -236968,7 +237209,7 @@ REQUIREMENTS:
236968
237209
 
236969
237210
  Generate ONLY the TypeScript code without markdown.`;
236970
237211
  }
236971
- function createArtifactComponentPrompt(componentData, context, registryInfo, commonInstructions) {
237212
+ function createArtifactComponentPrompt(_componentData, _context, _registryInfo, commonInstructions) {
236972
237213
  return `Generate TypeScript file for Inkeep artifact component.
236973
237214
 
236974
237215
  COMPONENT DATA:
@@ -236985,7 +237226,38 @@ REQUIREMENTS:
236985
237226
 
236986
237227
  Generate ONLY the TypeScript code without markdown.`;
236987
237228
  }
236988
- function formatRegistryForFile(fileInfo, registry2) {
237229
+ function createStatusComponentPrompt(_componentData, _context, _registryInfo, commonInstructions) {
237230
+ return `Generate TypeScript file for Inkeep status component.
237231
+
237232
+ COMPONENT DATA:
237233
+ {{DATA}}
237234
+
237235
+ ${commonInstructions}
237236
+
237237
+ REQUIREMENTS:
237238
+ 1. Import statusComponent from '@inkeep/agents-sdk'
237239
+ 2. Import z from 'zod' for schema definitions if detailsSchema is present
237240
+ 3. Use exact variable name from registry
237241
+ 4. Convert any JSON Schema in detailsSchema to Zod schema
237242
+ 5. Use 'type' field as the identifier
237243
+ 6. The statusComponent() function handles .config conversion automatically
237244
+
237245
+ EXAMPLE:
237246
+ import { statusComponent } from '@inkeep/agents-sdk';
237247
+ import { z } from 'zod';
237248
+
237249
+ export const toolSummary = statusComponent({
237250
+ type: 'tool_summary',
237251
+ description: 'Summary of tool calls',
237252
+ detailsSchema: z.object({
237253
+ tool_name: z.string().describe('Name of tool used'),
237254
+ summary: z.string().describe('What was accomplished'),
237255
+ }),
237256
+ });
237257
+
237258
+ Generate ONLY the TypeScript code without markdown.`;
237259
+ }
237260
+ function formatRegistryForFile(fileInfo, _registry) {
236989
237261
  let result = "Entities in this file:\n";
236990
237262
  for (const entity of fileInfo.entities) {
236991
237263
  result += ` - ${entity.entityType} "${entity.id}" \u2192 variable: ${entity.variableName}
@@ -237651,9 +237923,7 @@ async function configGetCommand(key, options) {
237651
237923
  if (!existsSync(configPath)) {
237652
237924
  console.error(chalk2.red("No configuration file found."));
237653
237925
  console.log(
237654
- chalk2.gray(
237655
- 'Run "inkeep init" to create one, or specify a config file with --config'
237656
- )
237926
+ chalk2.gray('Run "inkeep init" to create one, or specify a config file with --config')
237657
237927
  );
237658
237928
  process.exit(1);
237659
237929
  }
@@ -238280,7 +238550,9 @@ async function detectCurrentProject(debug = false) {
238280
238550
  if (typeof value.getId === "function") {
238281
238551
  const projectId = value.getId();
238282
238552
  if (debug) {
238283
- console.log(chalk8.gray(` \u2022 Project detected: ${projectId} (from export: ${exportKey})`));
238553
+ console.log(
238554
+ chalk8.gray(` \u2022 Project detected: ${projectId} (from export: ${exportKey})`)
238555
+ );
238284
238556
  }
238285
238557
  return projectId;
238286
238558
  }
@@ -238298,7 +238570,7 @@ async function detectCurrentProject(debug = false) {
238298
238570
  try {
238299
238571
  const content = readFileSync5(indexPath, "utf-8");
238300
238572
  const projectIdMatch = content.match(/project\s*\(\s*\{\s*id\s*:\s*['"]([^'"]+)['"]/);
238301
- if (projectIdMatch && projectIdMatch[1]) {
238573
+ if (projectIdMatch?.[1]) {
238302
238574
  const projectId = projectIdMatch[1];
238303
238575
  if (debug) {
238304
238576
  console.log(chalk8.gray(` \u2022 Project ID extracted from static parse: ${projectId}`));
@@ -238331,7 +238603,7 @@ async function verifyGeneratedFiles(projectDir, originalProjectData, debug = fal
238331
238603
  errors.push("index.ts does not contain a project() call");
238332
238604
  }
238333
238605
  const projectIdMatch = indexContent.match(/project\s*\(\s*\{\s*id\s*:\s*['"]([^'"]+)['"]/);
238334
- if (projectIdMatch && projectIdMatch[1]) {
238606
+ if (projectIdMatch?.[1]) {
238335
238607
  const extractedProjectId = projectIdMatch[1];
238336
238608
  if (extractedProjectId !== originalProjectData.id) {
238337
238609
  warnings.push(
@@ -238348,31 +238620,36 @@ async function verifyGeneratedFiles(projectDir, originalProjectData, debug = fal
238348
238620
  const agentsDir = join9(projectDir, "agents");
238349
238621
  const expectedAgents = Object.keys(originalProjectData.agents || {});
238350
238622
  for (const agentId of expectedAgents) {
238351
- const agentPath = join9(agentsDir, `${agentId}.ts`);
238623
+ const kebabCaseId = agentId.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
238624
+ const agentPath = join9(agentsDir, `${kebabCaseId}.ts`);
238352
238625
  if (!existsSync8(agentPath)) {
238353
- errors.push(`Agent file not found: agents/${agentId}.ts`);
238626
+ errors.push(`Agent file not found: agents/${kebabCaseId}.ts`);
238354
238627
  } else if (debug) {
238355
- console.log(chalk8.gray(` \u2713 Agent file exists: agents/${agentId}.ts`));
238628
+ console.log(chalk8.gray(` \u2713 Agent file exists: agents/${kebabCaseId}.ts`));
238356
238629
  }
238357
238630
  }
238358
238631
  const toolsDir = join9(projectDir, "tools");
238359
238632
  const expectedTools = Object.keys(originalProjectData.tools || {});
238360
238633
  for (const toolId of expectedTools) {
238361
- const toolPath = join9(toolsDir, `${toolId}.ts`);
238634
+ const kebabCaseId = toolId.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
238635
+ const toolPath = join9(toolsDir, `${kebabCaseId}.ts`);
238362
238636
  if (!existsSync8(toolPath)) {
238363
- errors.push(`Tool file not found: tools/${toolId}.ts`);
238637
+ errors.push(`Tool file not found: tools/${kebabCaseId}.ts`);
238364
238638
  } else if (debug) {
238365
- console.log(chalk8.gray(` \u2713 Tool file exists: tools/${toolId}.ts`));
238639
+ console.log(chalk8.gray(` \u2713 Tool file exists: tools/${kebabCaseId}.ts`));
238366
238640
  }
238367
238641
  }
238368
238642
  const dataComponentsDir = join9(projectDir, "data-components");
238369
238643
  const expectedDataComponents = Object.keys(originalProjectData.dataComponents || {});
238370
238644
  for (const componentId of expectedDataComponents) {
238371
- const componentPath = join9(dataComponentsDir, `${componentId}.ts`);
238645
+ const kebabCaseId = componentId.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
238646
+ const componentPath = join9(dataComponentsDir, `${kebabCaseId}.ts`);
238372
238647
  if (!existsSync8(componentPath)) {
238373
- errors.push(`Data component file not found: data-components/${componentId}.ts`);
238648
+ errors.push(`Data component file not found: data-components/${kebabCaseId}.ts`);
238374
238649
  } else if (debug) {
238375
- console.log(chalk8.gray(` \u2713 Data component file exists: data-components/${componentId}.ts`));
238650
+ console.log(
238651
+ chalk8.gray(` \u2713 Data component file exists: data-components/${kebabCaseId}.ts`)
238652
+ );
238376
238653
  }
238377
238654
  }
238378
238655
  const environmentsDir = join9(projectDir, "environments");
@@ -238398,8 +238675,12 @@ async function verifyGeneratedFiles(projectDir, originalProjectData, debug = fal
238398
238675
  if (debug) {
238399
238676
  console.log(chalk8.gray("\n\u{1F50D} Verification Summary:"));
238400
238677
  console.log(chalk8.gray(` \u2022 index.ts: ${existsSync8(indexPath) ? "\u2713" : "\u2717"}`));
238401
- console.log(chalk8.gray(` \u2022 Agent files: ${expectedAgents.length}/${expectedAgents.length} found`));
238402
- console.log(chalk8.gray(` \u2022 Tool files: ${expectedTools.length}/${expectedTools.length} found`));
238678
+ console.log(
238679
+ chalk8.gray(` \u2022 Agent files: ${expectedAgents.length}/${expectedAgents.length} found`)
238680
+ );
238681
+ console.log(
238682
+ chalk8.gray(` \u2022 Tool files: ${expectedTools.length}/${expectedTools.length} found`)
238683
+ );
238403
238684
  console.log(
238404
238685
  chalk8.gray(
238405
238686
  ` \u2022 Data component files: ${expectedDataComponents.length}/${expectedDataComponents.length} found`
@@ -238455,12 +238736,14 @@ function createProjectStructure(projectDir, projectId, useCurrentDirectory = fal
238455
238736
  const toolsDir = join9(projectRoot, "tools");
238456
238737
  const dataComponentsDir = join9(projectRoot, "data-components");
238457
238738
  const artifactComponentsDir = join9(projectRoot, "artifact-components");
238739
+ const statusComponentsDir = join9(projectRoot, "status-components");
238458
238740
  const environmentsDir = join9(projectRoot, "environments");
238459
238741
  ensureDirectoryExists(projectRoot);
238460
238742
  ensureDirectoryExists(agentsDir);
238461
238743
  ensureDirectoryExists(toolsDir);
238462
238744
  ensureDirectoryExists(dataComponentsDir);
238463
238745
  ensureDirectoryExists(artifactComponentsDir);
238746
+ ensureDirectoryExists(statusComponentsDir);
238464
238747
  ensureDirectoryExists(environmentsDir);
238465
238748
  return {
238466
238749
  projectRoot,
@@ -238468,6 +238751,7 @@ function createProjectStructure(projectDir, projectId, useCurrentDirectory = fal
238468
238751
  toolsDir,
238469
238752
  dataComponentsDir,
238470
238753
  artifactComponentsDir,
238754
+ statusComponentsDir,
238471
238755
  environmentsDir
238472
238756
  };
238473
238757
  }
@@ -238644,6 +238928,11 @@ async function pullProjectCommand(options) {
238644
238928
  }, 0);
238645
238929
  const dataComponentCount = Object.keys(projectData.dataComponents || {}).length;
238646
238930
  const artifactComponentCount = Object.keys(projectData.artifactComponents || {}).length;
238931
+ const statusComponentCount = Object.values(projectData.agents || {}).reduce((total, agent) => {
238932
+ const agentObj = agent;
238933
+ const statusComponents = agentObj.statusUpdates?.statusComponents || [];
238934
+ return total + statusComponents.length;
238935
+ }, 0);
238647
238936
  console.log(chalk8.cyan("\n\u{1F4CA} Project Summary:"));
238648
238937
  console.log(chalk8.gray(` \u2022 Name: ${projectData.name}`));
238649
238938
  console.log(chalk8.gray(` \u2022 Description: ${projectData.description || "No description"}`));
@@ -238656,6 +238945,9 @@ async function pullProjectCommand(options) {
238656
238945
  if (artifactComponentCount > 0) {
238657
238946
  console.log(chalk8.gray(` \u2022 Artifact Components: ${artifactComponentCount}`));
238658
238947
  }
238948
+ if (statusComponentCount > 0) {
238949
+ console.log(chalk8.gray(` \u2022 Status Components: ${statusComponentCount}`));
238950
+ }
238659
238951
  const credentialReferences2 = projectData.credentialReferences || {};
238660
238952
  const credentialCount = Object.keys(credentialReferences2).length;
238661
238953
  if (credentialCount > 0) {
@@ -238754,13 +239046,19 @@ async function pullProjectCommand(options) {
238754
239046
  if (options.debug) {
238755
239047
  console.log(chalk8.gray("\n\u{1F4CD} Plan saved to .inkeep/generation-plan.json"));
238756
239048
  }
239049
+ const statusComponentsCount = Object.values(projectData.agents || {}).reduce((total, agent) => {
239050
+ const agentObj = agent;
239051
+ const statusComponents = agentObj.statusUpdates?.statusComponents || [];
239052
+ return total + statusComponents.length;
239053
+ }, 0);
238757
239054
  const fileCount = {
238758
239055
  agents: Object.keys(projectData.agents || {}).length,
238759
239056
  tools: Object.keys(projectData.tools || {}).length,
238760
239057
  dataComponents: Object.keys(projectData.dataComponents || {}).length,
238761
- artifactComponents: Object.keys(projectData.artifactComponents || {}).length
239058
+ artifactComponents: Object.keys(projectData.artifactComponents || {}).length,
239059
+ statusComponents: statusComponentsCount
238762
239060
  };
238763
- const totalFiles = fileCount.agents + fileCount.tools + fileCount.dataComponents + fileCount.artifactComponents + 5;
239061
+ const totalFiles = fileCount.agents + fileCount.tools + fileCount.dataComponents + fileCount.artifactComponents + fileCount.statusComponents + 5;
238764
239062
  spinner.succeed(`Project files generated (${totalFiles} files created)`);
238765
239063
  spinner.start("Verifying generated files...");
238766
239064
  try {
@@ -238817,6 +239115,9 @@ async function pullProjectCommand(options) {
238817
239115
  if (fileCount.artifactComponents > 0) {
238818
239116
  console.log(chalk8.gray(` \u251C\u2500\u2500 artifact-components/ (${fileCount.artifactComponents} files)`));
238819
239117
  }
239118
+ if (fileCount.statusComponents > 0) {
239119
+ console.log(chalk8.gray(` \u251C\u2500\u2500 status-components/ (${fileCount.statusComponents} files)`));
239120
+ }
238820
239121
  console.log(chalk8.gray(" \u2514\u2500\u2500 environments/ (4 files)"));
238821
239122
  console.log(chalk8.cyan("\n\u{1F4DD} Next steps:"));
238822
239123
  console.log(chalk8.gray(` \u2022 cd ${dirs.projectRoot}`));
@@ -238980,9 +239281,12 @@ async function pushCommand(options) {
238980
239281
  console.log(chalk9.gray(` \u2022 Size: ${JSON.stringify(projectDefinition).length} bytes`));
238981
239282
  const agentCount = Object.keys(projectDefinition.agents || {}).length;
238982
239283
  const toolCount = Object.keys(projectDefinition.tools || {}).length;
238983
- const subAgentCount = Object.values(projectDefinition.agents || {}).reduce((total, agent) => {
238984
- return total + Object.keys(agent.subAgents || {}).length;
238985
- }, 0);
239284
+ const subAgentCount = Object.values(projectDefinition.agents || {}).reduce(
239285
+ (total, agent) => {
239286
+ return total + Object.keys(agent.subAgents || {}).length;
239287
+ },
239288
+ 0
239289
+ );
238986
239290
  console.log(chalk9.cyan("\n\u{1F4CA} Project Data Summary:"));
238987
239291
  console.log(chalk9.gray(` \u2022 Agent: ${agentCount}`));
238988
239292
  console.log(chalk9.gray(` \u2022 Tools: ${toolCount}`));
@@ -239104,7 +239408,7 @@ program.command("chat [agent-id]").description(
239104
239408
  const config = options.config || options.configFilePath;
239105
239409
  await chatCommandEnhanced2(agentId, { ...options, config });
239106
239410
  });
239107
- program.command("list-agent").description("List all available agent for a specific project").requiredOption("--project <project-id>", "Project ID to list agent for").option("--tenant-id <tenant-id>", "Tenant ID").option("--agents-manage-api-url <url>", "Agents manage API URL").option("--config <path>", "Path to configuration file").option("--config-file-path <path>", "Path to configuration file (deprecated, use --config)").action(async (options) => {
239411
+ program.command("list-agent").description("List all available agents for a specific project").requiredOption("--project <project-id>", "Project ID to list agent for").option("--tenant-id <tenant-id>", "Tenant ID").option("--agents-manage-api-url <url>", "Agents manage API URL").option("--config <path>", "Path to configuration file").option("--config-file-path <path>", "Path to configuration file (deprecated, use --config)").action(async (options) => {
239108
239412
  const config = options.config || options.configFilePath;
239109
239413
  await listAgentsCommand({ ...options, config });
239110
239414
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-cli",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Inkeep CLI tool",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -46,8 +46,8 @@
46
46
  "recast": "^0.23.0",
47
47
  "ts-morph": "^26.0.0",
48
48
  "tsx": "^4.20.5",
49
- "@inkeep/agents-core": "^0.21.0",
50
- "@inkeep/agents-sdk": "^0.21.0"
49
+ "@inkeep/agents-core": "^0.22.0",
50
+ "@inkeep/agents-sdk": "^0.22.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/degit": "^2.8.6",