@agents-at-scale/ark 0.1.53 → 0.1.55

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 (115) hide show
  1. package/dist/commands/export/index.js +6 -4
  2. package/dist/commands/generate/generators/agent.js +2 -0
  3. package/dist/commands/generate/generators/marketplace.js +2 -0
  4. package/dist/commands/generate/generators/mcpserver.js +2 -0
  5. package/dist/commands/generate/generators/project.js +9 -2
  6. package/dist/commands/generate/generators/query.js +2 -0
  7. package/dist/commands/generate/generators/team.js +2 -0
  8. package/dist/commands/generate/templateDiscovery.js +1 -0
  9. package/dist/commands/generate/templateEngine.js +1 -3
  10. package/dist/commands/import/index.js +1 -1
  11. package/dist/commands/install/index.js +2 -1
  12. package/dist/commands/models/kubernetes/manifest-builder.js +27 -10
  13. package/dist/commands/models/providers/azure.d.ts +10 -7
  14. package/dist/commands/models/providers/azure.js +83 -21
  15. package/dist/commands/uninstall/index.js +1 -1
  16. package/dist/components/ChatUI.js +17 -16
  17. package/dist/components/statusChecker.js +3 -3
  18. package/dist/lib/arkApiClient.js +11 -9
  19. package/dist/lib/arkApiProxy.js +1 -0
  20. package/dist/lib/arkServiceProxy.js +5 -1
  21. package/dist/lib/chatClient.js +9 -0
  22. package/dist/lib/config.js +8 -3
  23. package/dist/lib/errors.js +3 -0
  24. package/dist/ui/asyncOperations/connectingToArk.js +2 -2
  25. package/package.json +16 -12
  26. package/dist/arkServices.spec.d.ts +0 -1
  27. package/dist/arkServices.spec.js +0 -138
  28. package/dist/commands/agents/index.spec.d.ts +0 -1
  29. package/dist/commands/agents/index.spec.js +0 -67
  30. package/dist/commands/cluster/get.spec.d.ts +0 -1
  31. package/dist/commands/cluster/get.spec.js +0 -92
  32. package/dist/commands/cluster/index.spec.d.ts +0 -1
  33. package/dist/commands/cluster/index.spec.js +0 -24
  34. package/dist/commands/completion/index.spec.d.ts +0 -1
  35. package/dist/commands/completion/index.spec.js +0 -34
  36. package/dist/commands/config/index.spec.d.ts +0 -1
  37. package/dist/commands/config/index.spec.js +0 -78
  38. package/dist/commands/evaluation/index.spec.d.ts +0 -1
  39. package/dist/commands/evaluation/index.spec.js +0 -161
  40. package/dist/commands/export/index.spec.d.ts +0 -1
  41. package/dist/commands/export/index.spec.js +0 -145
  42. package/dist/commands/import/index.spec.d.ts +0 -1
  43. package/dist/commands/import/index.spec.js +0 -46
  44. package/dist/commands/install/index.spec.d.ts +0 -1
  45. package/dist/commands/install/index.spec.js +0 -286
  46. package/dist/commands/marketplace/index.spec.d.ts +0 -1
  47. package/dist/commands/marketplace/index.spec.js +0 -88
  48. package/dist/commands/memory/index.spec.d.ts +0 -1
  49. package/dist/commands/memory/index.spec.js +0 -124
  50. package/dist/commands/models/create.spec.d.ts +0 -1
  51. package/dist/commands/models/create.spec.js +0 -167
  52. package/dist/commands/models/index.spec.d.ts +0 -1
  53. package/dist/commands/models/index.spec.js +0 -96
  54. package/dist/commands/models/providers/azure.spec.d.ts +0 -1
  55. package/dist/commands/models/providers/azure.spec.js +0 -232
  56. package/dist/commands/models/providers/bedrock.spec.d.ts +0 -1
  57. package/dist/commands/models/providers/bedrock.spec.js +0 -241
  58. package/dist/commands/models/providers/openai.spec.d.ts +0 -1
  59. package/dist/commands/models/providers/openai.spec.js +0 -180
  60. package/dist/commands/queries/delete.spec.d.ts +0 -1
  61. package/dist/commands/queries/delete.spec.js +0 -74
  62. package/dist/commands/queries/index.spec.d.ts +0 -1
  63. package/dist/commands/queries/index.spec.js +0 -167
  64. package/dist/commands/queries/list.spec.d.ts +0 -1
  65. package/dist/commands/queries/list.spec.js +0 -170
  66. package/dist/commands/queries/validation.spec.d.ts +0 -1
  67. package/dist/commands/queries/validation.spec.js +0 -27
  68. package/dist/commands/query/index.spec.d.ts +0 -1
  69. package/dist/commands/query/index.spec.js +0 -104
  70. package/dist/commands/targets/index.spec.d.ts +0 -1
  71. package/dist/commands/targets/index.spec.js +0 -154
  72. package/dist/commands/teams/index.spec.d.ts +0 -1
  73. package/dist/commands/teams/index.spec.js +0 -70
  74. package/dist/commands/tools/index.spec.d.ts +0 -1
  75. package/dist/commands/tools/index.spec.js +0 -70
  76. package/dist/commands/uninstall/index.spec.d.ts +0 -1
  77. package/dist/commands/uninstall/index.spec.js +0 -125
  78. package/dist/lib/arkServiceProxy.spec.d.ts +0 -1
  79. package/dist/lib/arkServiceProxy.spec.js +0 -100
  80. package/dist/lib/arkStatus.spec.d.ts +0 -1
  81. package/dist/lib/arkStatus.spec.js +0 -49
  82. package/dist/lib/chatClient.spec.d.ts +0 -1
  83. package/dist/lib/chatClient.spec.js +0 -108
  84. package/dist/lib/cluster.spec.d.ts +0 -1
  85. package/dist/lib/cluster.spec.js +0 -338
  86. package/dist/lib/commands.spec.d.ts +0 -1
  87. package/dist/lib/commands.spec.js +0 -146
  88. package/dist/lib/config.spec.d.ts +0 -1
  89. package/dist/lib/config.spec.js +0 -202
  90. package/dist/lib/duration.spec.d.ts +0 -1
  91. package/dist/lib/duration.spec.js +0 -13
  92. package/dist/lib/errors.spec.d.ts +0 -1
  93. package/dist/lib/errors.spec.js +0 -221
  94. package/dist/lib/executeQuery.spec.d.ts +0 -1
  95. package/dist/lib/executeQuery.spec.js +0 -325
  96. package/dist/lib/kubectl.spec.d.ts +0 -1
  97. package/dist/lib/kubectl.spec.js +0 -192
  98. package/dist/lib/marketplaceFetcher.spec.d.ts +0 -1
  99. package/dist/lib/marketplaceFetcher.spec.js +0 -225
  100. package/dist/lib/nextSteps.spec.d.ts +0 -1
  101. package/dist/lib/nextSteps.spec.js +0 -59
  102. package/dist/lib/output.spec.d.ts +0 -1
  103. package/dist/lib/output.spec.js +0 -123
  104. package/dist/lib/startup.spec.d.ts +0 -1
  105. package/dist/lib/startup.spec.js +0 -152
  106. package/dist/lib/stdin.spec.d.ts +0 -1
  107. package/dist/lib/stdin.spec.js +0 -82
  108. package/dist/lib/timeout.spec.d.ts +0 -1
  109. package/dist/lib/timeout.spec.js +0 -14
  110. package/dist/lib/waitForReady.spec.d.ts +0 -1
  111. package/dist/lib/waitForReady.spec.js +0 -104
  112. package/dist/marketplaceServices.spec.d.ts +0 -1
  113. package/dist/marketplaceServices.spec.js +0 -74
  114. package/dist/ui/statusFormatter.spec.d.ts +0 -1
  115. package/dist/ui/statusFormatter.spec.js +0 -58
@@ -19,8 +19,8 @@ async function exportResources(options, config) {
19
19
  try {
20
20
  const allResourceTypes = config.defaultExportTypes || RESOURCE_ORDER;
21
21
  const outputPath = options.output || 'ark-export.yaml';
22
- let resourceTypes = options.types
23
- ? (options.types.split(','))
22
+ const resourceTypes = options.types
23
+ ? options.types.split(',')
24
24
  : allResourceTypes;
25
25
  // ensure that we get resources in the correct order; e.g. agents before teams that use the agents
26
26
  resourceTypes.sort((a, b) => {
@@ -37,7 +37,7 @@ async function exportResources(options, config) {
37
37
  output.info(`fetching ${resourceType}...`);
38
38
  const resources = await listResources(resourceType, {
39
39
  namespace: options.namespace,
40
- labels: options.labels
40
+ labels: options.labels,
41
41
  });
42
42
  const resourceCount = resources.length;
43
43
  if (resources.length > 0) {
@@ -50,7 +50,9 @@ async function exportResources(options, config) {
50
50
  output.warning('no resources found to export');
51
51
  return;
52
52
  }
53
- const yamlContent = allResources.map((resource) => yaml.stringify(resource)).join("\n---\n");
53
+ const yamlContent = allResources
54
+ .map((resource) => yaml.stringify(resource))
55
+ .join('\n---\n');
54
56
  await fs.writeFile(outputPath, yamlContent, 'utf-8');
55
57
  output.success(`exported ${allResourceCount} resources to ${outputPath}`);
56
58
  }
@@ -19,6 +19,8 @@ export function createAgentGenerator() {
19
19
  };
20
20
  }
21
21
  class AgentGenerator {
22
+ templateDiscovery;
23
+ templateEngine;
22
24
  constructor() {
23
25
  this.templateDiscovery = new TemplateDiscovery();
24
26
  this.templateEngine = new TemplateEngine();
@@ -17,6 +17,8 @@ export function createMarketplaceGenerator() {
17
17
  };
18
18
  }
19
19
  class MarketplaceGenerator {
20
+ templateDiscovery;
21
+ templateEngine;
20
22
  constructor() {
21
23
  this.templateDiscovery = new TemplateDiscovery();
22
24
  this.templateEngine = new TemplateEngine();
@@ -16,6 +16,8 @@ export function createMcpServerGenerator() {
16
16
  };
17
17
  }
18
18
  class McpServerGenerator {
19
+ templateDiscovery;
20
+ templateEngine;
19
21
  constructor() {
20
22
  this.templateDiscovery = new TemplateDiscovery();
21
23
  this.templateEngine = new TemplateEngine();
@@ -21,6 +21,9 @@ export function createProjectGenerator() {
21
21
  };
22
22
  }
23
23
  class ProjectGenerator {
24
+ templateDiscovery;
25
+ templateEngine;
26
+ samplesPath;
24
27
  constructor() {
25
28
  this.templateDiscovery = new TemplateDiscovery();
26
29
  this.templateEngine = new TemplateEngine();
@@ -727,7 +730,9 @@ Generated with ARK CLI generator`;
727
730
  },
728
731
  ];
729
732
  if (config.projectType === 'empty') {
730
- steps.push({ desc: 'Add YAML files to agents/, teams/, queries/ directories' }, { desc: 'Use either the default model already in models/ or a configuration template from samples/models/ of ARK repository' }, { desc: 'Edit .env file to set your API keys' }, { desc: 'Deploy your project', cmd: 'devspace dev' });
733
+ steps.push({ desc: 'Add YAML files to agents/, teams/, queries/ directories' }, {
734
+ desc: 'Use either the default model already in models/ or a configuration template from samples/models/ of ARK repository',
735
+ }, { desc: 'Edit .env file to set your API keys' }, { desc: 'Deploy your project', cmd: 'devspace dev' });
731
736
  }
732
737
  else if (config.selectedModels && config.selectedModels !== 'none') {
733
738
  steps.push({ desc: 'Edit .env file to set your API keys' }, { desc: 'Load environment variables', cmd: 'source .env' }, { desc: 'Deploy your project', cmd: 'devspace dev' }, {
@@ -736,7 +741,9 @@ Generated with ARK CLI generator`;
736
741
  });
737
742
  }
738
743
  else {
739
- steps.push({ desc: 'Use either the default model already in models/ or a configuration template from samples/models/ of ARK repository' }, { desc: 'Edit .env file to set your API keys' }, { desc: 'Deploy your project', cmd: 'devspace dev' });
744
+ steps.push({
745
+ desc: 'Use either the default model already in models/ or a configuration template from samples/models/ of ARK repository',
746
+ }, { desc: 'Edit .env file to set your API keys' }, { desc: 'Deploy your project', cmd: 'devspace dev' });
740
747
  }
741
748
  console.log(chalk.magenta.bold('🚀 NEXT STEPS:\n'));
742
749
  let stepNumber = 1;
@@ -19,6 +19,8 @@ export function createQueryGenerator() {
19
19
  };
20
20
  }
21
21
  class QueryGenerator {
22
+ templateDiscovery;
23
+ templateEngine;
22
24
  constructor() {
23
25
  this.templateDiscovery = new TemplateDiscovery();
24
26
  this.templateEngine = new TemplateEngine();
@@ -18,6 +18,8 @@ export function createTeamGenerator() {
18
18
  };
19
19
  }
20
20
  class TeamGenerator {
21
+ templateDiscovery;
22
+ templateEngine;
21
23
  constructor() {
22
24
  this.templateDiscovery = new TemplateDiscovery();
23
25
  this.templateEngine = new TemplateEngine();
@@ -2,6 +2,7 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  export class TemplateDiscovery {
5
+ templatesPath;
5
6
  constructor() {
6
7
  // Get the path to the templates directory
7
8
  // This handles both development and production scenarios
@@ -4,9 +4,7 @@ import chalk from 'chalk';
4
4
  import { SecurityUtils } from '../../lib/security.js';
5
5
  import { TemplateError } from '../../lib/errors.js';
6
6
  export class TemplateEngine {
7
- constructor() {
8
- this.variables = {};
9
- }
7
+ variables = {};
10
8
  /**
11
9
  * Set template variables for substitution
12
10
  */
@@ -5,7 +5,7 @@ async function importResources(filepath) {
5
5
  try {
6
6
  output.info(`importing ark resources from ${filepath}...`);
7
7
  const args = ['create', '-f', filepath];
8
- const result = await execa('kubectl', args, {
8
+ await execa('kubectl', args, {
9
9
  stdio: 'pipe',
10
10
  });
11
11
  output.success(`imported resources from ${filepath}`);
@@ -40,6 +40,7 @@ async function checkAndCleanFailedRelease(releaseName, namespace, verbose = fals
40
40
  }
41
41
  }
42
42
  catch {
43
+ // Ignore errors - prerequisite may not exist
43
44
  }
44
45
  }
45
46
  async function installService(service, verbose = false) {
@@ -170,7 +171,7 @@ export async function installArk(config, serviceName, options = {}) {
170
171
  checked: Boolean(service.enabled),
171
172
  })),
172
173
  ];
173
- let selectedComponents = [];
174
+ let selectedComponents;
174
175
  try {
175
176
  const answers = await inquirer.prompt([
176
177
  {
@@ -1,5 +1,6 @@
1
1
  // Kubernetes model manifest builder
2
2
  export class KubernetesModelManifestBuilder {
3
+ modelName;
3
4
  constructor(modelName) {
4
5
  this.modelName = modelName;
5
6
  }
@@ -23,24 +24,40 @@ export class KubernetesModelManifestBuilder {
23
24
  }
24
25
  buildProviderConfig(config) {
25
26
  if (config.type === 'azure') {
26
- return {
27
- azure: {
27
+ const azureConfig = config;
28
+ const azure = {
29
+ baseUrl: { value: azureConfig.baseUrl },
30
+ apiVersion: { value: azureConfig.apiVersion },
31
+ };
32
+ const authMethod = azureConfig.authMethod ?? 'apiKey';
33
+ if (authMethod === 'apiKey') {
34
+ azure.auth = {
28
35
  apiKey: {
29
36
  valueFrom: {
30
37
  secretKeyRef: {
31
- name: config.secretName,
38
+ name: azureConfig.secretName || 'azure-openai-secret',
32
39
  key: 'api-key',
33
40
  },
34
41
  },
35
42
  },
36
- baseUrl: {
37
- value: config.baseUrl,
38
- },
39
- apiVersion: {
40
- value: config.apiVersion,
43
+ };
44
+ }
45
+ else if (authMethod === 'managedIdentity') {
46
+ azure.auth = {
47
+ managedIdentity: azureConfig.clientId ?
48
+ { clientId: { value: azureConfig.clientId } }
49
+ : {},
50
+ };
51
+ }
52
+ else if (authMethod === 'workloadIdentity') {
53
+ azure.auth = {
54
+ workloadIdentity: {
55
+ clientId: { value: azureConfig.clientId },
56
+ tenantId: { value: azureConfig.tenantId },
41
57
  },
42
- },
43
- };
58
+ };
59
+ }
60
+ return { azure };
44
61
  }
45
62
  if (config.type === 'bedrock') {
46
63
  return this.buildBedrockConfig(config);
@@ -1,12 +1,16 @@
1
1
  import { BaseProviderConfig, BaseCollectorOptions, ProviderConfigCollector } from './types.js';
2
+ export type AzureAuthMethod = 'apiKey' | 'managedIdentity' | 'workloadIdentity';
2
3
  /**
3
4
  * Configuration for Azure OpenAI models.
4
5
  */
5
6
  export interface AzureConfig extends BaseProviderConfig {
6
7
  type: 'azure';
7
8
  baseUrl: string;
8
- apiKey: string;
9
9
  apiVersion: string;
10
+ authMethod?: AzureAuthMethod;
11
+ apiKey?: string;
12
+ clientId?: string;
13
+ tenantId?: string;
10
14
  }
11
15
  /**
12
16
  * Options specific to Azure collector.
@@ -15,16 +19,15 @@ export interface AzureCollectorOptions extends BaseCollectorOptions {
15
19
  baseUrl?: string;
16
20
  apiKey?: string;
17
21
  apiVersion?: string;
22
+ authMethod?: AzureAuthMethod;
23
+ clientId?: string;
24
+ tenantId?: string;
18
25
  }
19
26
  /**
20
27
  * Configuration collector for Azure OpenAI models.
21
28
  *
22
- * Collects the necessary configuration to connect to Azure OpenAI Service:
23
- * - baseUrl: The Azure OpenAI endpoint URL (e.g., https://<resource>.openai.azure.com)
24
- * - apiVersion: The API version to use (defaults to 2024-12-01-preview)
25
- * - apiKey: The authentication key for the Azure OpenAI resource
26
- *
27
- * Values can be provided via command-line options or will be prompted interactively.
29
+ * Supports API Key, Managed Identity (AKS), and Workload Identity auth.
30
+ * Values can be provided via command-line options or prompted interactively.
28
31
  */
29
32
  export declare class AzureConfigCollector implements ProviderConfigCollector {
30
33
  collectConfig(options: BaseCollectorOptions): Promise<AzureConfig>;
@@ -2,12 +2,8 @@ import inquirer from 'inquirer';
2
2
  /**
3
3
  * Configuration collector for Azure OpenAI models.
4
4
  *
5
- * Collects the necessary configuration to connect to Azure OpenAI Service:
6
- * - baseUrl: The Azure OpenAI endpoint URL (e.g., https://<resource>.openai.azure.com)
7
- * - apiVersion: The API version to use (defaults to 2024-12-01-preview)
8
- * - apiKey: The authentication key for the Azure OpenAI resource
9
- *
10
- * Values can be provided via command-line options or will be prompted interactively.
5
+ * Supports API Key, Managed Identity (AKS), and Workload Identity auth.
6
+ * Values can be provided via command-line options or prompted interactively.
11
7
  */
12
8
  export class AzureConfigCollector {
13
9
  async collectConfig(options) {
@@ -50,33 +46,99 @@ export class AzureConfigCollector {
50
46
  ]);
51
47
  apiVersion = answer.apiVersion;
52
48
  }
53
- let apiKey = azureOptions.apiKey;
54
- if (!apiKey) {
49
+ let authMethod = azureOptions.authMethod;
50
+ if (!authMethod && azureOptions.apiKey) {
51
+ authMethod = 'apiKey';
52
+ }
53
+ if (!authMethod) {
55
54
  const answer = await inquirer.prompt([
56
55
  {
57
- type: 'password',
58
- name: 'apiKey',
59
- message: 'API key:',
60
- mask: '*',
61
- validate: (input) => {
62
- if (!input)
63
- return 'API key is required';
64
- return true;
65
- },
56
+ type: 'list',
57
+ name: 'authMethod',
58
+ message: 'Authentication:',
59
+ choices: [
60
+ { name: 'API Key', value: 'apiKey' },
61
+ { name: 'Managed Identity (AKS)', value: 'managedIdentity' },
62
+ { name: 'Workload Identity', value: 'workloadIdentity' },
63
+ ],
66
64
  },
67
65
  ]);
68
- apiKey = answer.apiKey;
66
+ authMethod = answer.authMethod;
67
+ }
68
+ let apiKey;
69
+ let clientId;
70
+ let tenantId;
71
+ if (authMethod === 'apiKey') {
72
+ apiKey = azureOptions.apiKey;
73
+ if (!apiKey) {
74
+ const answer = await inquirer.prompt([
75
+ {
76
+ type: 'password',
77
+ name: 'apiKey',
78
+ message: 'API key:',
79
+ mask: '*',
80
+ validate: (input) => {
81
+ if (!input)
82
+ return 'API key is required';
83
+ return true;
84
+ },
85
+ },
86
+ ]);
87
+ apiKey = answer.apiKey;
88
+ }
89
+ if (!apiKey) {
90
+ throw new Error('API key is required');
91
+ }
69
92
  }
70
- if (!apiKey) {
71
- throw new Error('API key is required');
93
+ else if (authMethod === 'managedIdentity') {
94
+ clientId = azureOptions.clientId;
95
+ if (!clientId) {
96
+ const answer = await inquirer.prompt([
97
+ {
98
+ type: 'input',
99
+ name: 'clientId',
100
+ message: 'Managed Identity Client ID (optional for system-assigned):',
101
+ },
102
+ ]);
103
+ clientId = answer.clientId || undefined;
104
+ }
105
+ }
106
+ else if (authMethod === 'workloadIdentity') {
107
+ clientId = azureOptions.clientId;
108
+ tenantId = azureOptions.tenantId;
109
+ if (!clientId) {
110
+ const answer = await inquirer.prompt([
111
+ {
112
+ type: 'input',
113
+ name: 'clientId',
114
+ message: 'Workload Identity Client ID:',
115
+ validate: (input) => input ? true : 'Client ID is required for Workload Identity',
116
+ },
117
+ ]);
118
+ clientId = answer.clientId;
119
+ }
120
+ if (!tenantId) {
121
+ const answer = await inquirer.prompt([
122
+ {
123
+ type: 'input',
124
+ name: 'tenantId',
125
+ message: 'Azure Tenant ID:',
126
+ validate: (input) => input ? true : 'Tenant ID is required for Workload Identity',
127
+ },
128
+ ]);
129
+ tenantId = answer.tenantId;
130
+ }
72
131
  }
73
132
  return {
74
133
  type: 'azure',
75
134
  modelValue: options.model,
76
135
  secretName: '',
77
136
  baseUrl,
78
- apiKey,
79
137
  apiVersion,
138
+ authMethod,
139
+ apiKey,
140
+ clientId,
141
+ tenantId,
80
142
  };
81
143
  }
82
144
  }
@@ -88,7 +88,7 @@ async function uninstallArk(config, serviceName, options = {}) {
88
88
  const services = getInstallableServices();
89
89
  const serviceEntries = Object.entries(services).reverse();
90
90
  for (const [, service] of serviceEntries) {
91
- let shouldUninstall = false;
91
+ let shouldUninstall;
92
92
  try {
93
93
  // Ask for confirmation
94
94
  shouldUninstall =
@@ -410,31 +410,32 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
410
410
  // Create abort controller for this request
411
411
  const controller = new AbortController();
412
412
  setAbortController(controller);
413
- // Convert messages to format expected by OpenAI API - only include user and agent messages
414
413
  const apiMessages = messages
415
414
  .filter((msg) => msg.type === 'user' || msg.type === 'agent' || msg.type === 'team')
416
- .map((msg) => {
415
+ .flatMap((msg) => {
417
416
  if (msg.type === 'user') {
418
- return {
419
- role: 'user',
420
- content: msg.content,
421
- };
417
+ return [
418
+ {
419
+ role: 'user',
420
+ content: msg.content,
421
+ },
422
+ ];
422
423
  }
423
424
  else if (msg.type === 'agent') {
424
- return {
425
- role: 'assistant',
426
- content: msg.content,
427
- };
425
+ return [
426
+ {
427
+ role: 'assistant',
428
+ content: msg.content,
429
+ },
430
+ ];
428
431
  }
429
432
  else if (msg.type === 'team') {
430
- // For teams, concatenate all member responses
431
- const content = msg.members.map((m) => m.content).join(' ');
432
- return {
433
+ return msg.members.map((m) => ({
433
434
  role: 'assistant',
434
- content: content || '',
435
- };
435
+ content: m.content || '',
436
+ }));
436
437
  }
437
- return { role: 'user', content: '' };
438
+ return [];
438
439
  });
439
440
  // Add the new user message
440
441
  apiMessages.push({
@@ -24,7 +24,7 @@ export const getKubectlVersion = () => ({
24
24
  throw new Error('kubectl version output missing clientVersion field');
25
25
  }
26
26
  catch (e) {
27
- throw new Error(`Failed to parse kubectl version JSON: ${e instanceof Error ? e.message : 'Unknown error'}`);
27
+ throw new Error(`Failed to parse kubectl version JSON: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e });
28
28
  }
29
29
  },
30
30
  });
@@ -72,7 +72,7 @@ export class StatusChecker {
72
72
  return config.versionExtract(stdout);
73
73
  }
74
74
  catch (error) {
75
- throw new Error(`Failed to get ${config.command} version: ${error instanceof Error ? error.message : 'Unknown error'}`);
75
+ throw new Error(`Failed to get ${config.command} version: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
76
76
  }
77
77
  }
78
78
  /**
@@ -341,7 +341,7 @@ export class StatusChecker {
341
341
  clusterAccess = true;
342
342
  }
343
343
  catch {
344
- clusterAccess = false;
344
+ // clusterAccess remains false
345
345
  }
346
346
  // Get cluster info if accessible
347
347
  let clusterInfo;
@@ -1,5 +1,7 @@
1
1
  import OpenAI from 'openai';
2
2
  export class ArkApiClient {
3
+ openai;
4
+ baseUrl;
3
5
  constructor(arkApiUrl) {
4
6
  this.baseUrl = arkApiUrl;
5
7
  this.openai = new OpenAI({
@@ -29,7 +31,7 @@ export class ArkApiClient {
29
31
  return targets;
30
32
  }
31
33
  catch (error) {
32
- throw new Error(`Failed to get query targets: ${error instanceof Error ? error.message : 'Unknown error'}`);
34
+ throw new Error(`Failed to get query targets: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
33
35
  }
34
36
  }
35
37
  async getAgents() {
@@ -42,7 +44,7 @@ export class ArkApiClient {
42
44
  return data.items || [];
43
45
  }
44
46
  catch (error) {
45
- throw new Error(`Failed to get agents: ${error instanceof Error ? error.message : 'Unknown error'}`);
47
+ throw new Error(`Failed to get agents: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
46
48
  }
47
49
  }
48
50
  async getModels() {
@@ -55,7 +57,7 @@ export class ArkApiClient {
55
57
  return data.items || [];
56
58
  }
57
59
  catch (error) {
58
- throw new Error(`Failed to get models: ${error instanceof Error ? error.message : 'Unknown error'}`);
60
+ throw new Error(`Failed to get models: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
59
61
  }
60
62
  }
61
63
  async getTools() {
@@ -68,7 +70,7 @@ export class ArkApiClient {
68
70
  return data.items || [];
69
71
  }
70
72
  catch (error) {
71
- throw new Error(`Failed to get tools: ${error instanceof Error ? error.message : 'Unknown error'}`);
73
+ throw new Error(`Failed to get tools: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
72
74
  }
73
75
  }
74
76
  async getTeams() {
@@ -81,7 +83,7 @@ export class ArkApiClient {
81
83
  return data.items || [];
82
84
  }
83
85
  catch (error) {
84
- throw new Error(`Failed to get teams: ${error instanceof Error ? error.message : 'Unknown error'}`);
86
+ throw new Error(`Failed to get teams: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
85
87
  }
86
88
  }
87
89
  async getSessions() {
@@ -94,7 +96,7 @@ export class ArkApiClient {
94
96
  return data.items || [];
95
97
  }
96
98
  catch (error) {
97
- throw new Error(`Failed to get sessions: ${error instanceof Error ? error.message : 'Unknown error'}`);
99
+ throw new Error(`Failed to get sessions: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
98
100
  }
99
101
  }
100
102
  async deleteSession(sessionId) {
@@ -108,7 +110,7 @@ export class ArkApiClient {
108
110
  return await response.json();
109
111
  }
110
112
  catch (error) {
111
- throw new Error(`Failed to delete session: ${error instanceof Error ? error.message : 'Unknown error'}`);
113
+ throw new Error(`Failed to delete session: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
112
114
  }
113
115
  }
114
116
  async deleteQueryMessages(sessionId, queryId) {
@@ -122,7 +124,7 @@ export class ArkApiClient {
122
124
  return await response.json();
123
125
  }
124
126
  catch (error) {
125
- throw new Error(`Failed to delete query messages: ${error instanceof Error ? error.message : 'Unknown error'}`);
127
+ throw new Error(`Failed to delete query messages: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
126
128
  }
127
129
  }
128
130
  async deleteAllSessions() {
@@ -136,7 +138,7 @@ export class ArkApiClient {
136
138
  return await response.json();
137
139
  }
138
140
  catch (error) {
139
- throw new Error(`Failed to delete all sessions: ${error instanceof Error ? error.message : 'Unknown error'}`);
141
+ throw new Error(`Failed to delete all sessions: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
140
142
  }
141
143
  }
142
144
  async createChatCompletion(params) {
@@ -2,6 +2,7 @@ import { ArkApiClient } from './arkApiClient.js';
2
2
  import { ArkServiceProxy } from './arkServiceProxy.js';
3
3
  import { arkServices } from '../arkServices.js';
4
4
  export class ArkApiProxy {
5
+ serviceProxy;
5
6
  constructor(localPort, reusePortForwards = false) {
6
7
  const arkApiService = arkServices['ark-api'];
7
8
  this.serviceProxy = new ArkServiceProxy(arkApiService, localPort, reusePortForwards);
@@ -3,9 +3,13 @@ import find from 'find-process';
3
3
  import Debug from 'debug';
4
4
  const debug = Debug('ark:service-proxy');
5
5
  export class ArkServiceProxy {
6
+ reusePortForwards;
7
+ kubectlProcess;
8
+ localPort;
9
+ isReady = false;
10
+ service;
6
11
  constructor(service, localPort, reusePortForwards = false) {
7
12
  this.reusePortForwards = reusePortForwards;
8
- this.isReady = false;
9
13
  this.service = service;
10
14
  this.localPort =
11
15
  localPort || service.k8sPortForwardLocalPort || this.getRandomPort();
@@ -1,5 +1,6 @@
1
1
  import { QUERY_ANNOTATIONS } from './constants.js';
2
2
  export class ChatClient {
3
+ arkApiClient;
3
4
  constructor(arkApiClient) {
4
5
  this.arkApiClient = arkApiClient;
5
6
  }
@@ -57,6 +58,14 @@ export class ChatClient {
57
58
  if (onChunk) {
58
59
  onChunk(content, undefined, arkMetadata);
59
60
  }
61
+ if (!fullResponse &&
62
+ arkMetadata?.completedQuery?.status?.response?.content) {
63
+ const responseContent = arkMetadata.completedQuery.status.response.content;
64
+ fullResponse = responseContent;
65
+ if (onChunk) {
66
+ onChunk(responseContent, undefined, arkMetadata);
67
+ }
68
+ }
60
69
  // Handle tool calls
61
70
  if (delta?.tool_calls) {
62
71
  for (const toolCallDelta of delta.tool_calls) {
@@ -33,7 +33,9 @@ export function loadConfig() {
33
33
  }
34
34
  catch (e) {
35
35
  const message = e instanceof Error ? e.message : 'Unknown error';
36
- throw new Error(`Invalid YAML in ${userConfigPath}: ${message}`);
36
+ throw new Error(`Invalid YAML in ${userConfigPath}: ${message}`, {
37
+ cause: e,
38
+ });
37
39
  }
38
40
  }
39
41
  // Load project config from current directory
@@ -45,7 +47,9 @@ export function loadConfig() {
45
47
  }
46
48
  catch (e) {
47
49
  const message = e instanceof Error ? e.message : 'Unknown error';
48
- throw new Error(`Invalid YAML in ${projectConfigPath}: ${message}`);
50
+ throw new Error(`Invalid YAML in ${projectConfigPath}: ${message}`, {
51
+ cause: e,
52
+ });
49
53
  }
50
54
  }
51
55
  // Apply environment variable overrides
@@ -106,7 +110,8 @@ function mergeConfig(target, source) {
106
110
  target.services.reusePortForwards = source.services.reusePortForwards;
107
111
  }
108
112
  for (const [serviceName, overrides] of Object.entries(source.services)) {
109
- if (serviceName !== 'reusePortForwards' && typeof overrides === 'object') {
113
+ if (serviceName !== 'reusePortForwards' &&
114
+ typeof overrides === 'object') {
110
115
  target.services[serviceName] = {
111
116
  ...target.services[serviceName],
112
117
  ...overrides,
@@ -24,6 +24,9 @@ export var ErrorCode;
24
24
  ErrorCode["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
25
25
  })(ErrorCode || (ErrorCode = {}));
26
26
  export class ArkError extends Error {
27
+ code;
28
+ details;
29
+ suggestions;
27
30
  constructor(message, code = ErrorCode.UNKNOWN_ERROR, details, suggestions) {
28
31
  super(message);
29
32
  this.name = 'ArkError';