@agents-at-scale/ark 0.1.52 → 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 (116) hide show
  1. package/dist/arkServices.js +11 -7
  2. package/dist/commands/export/index.js +6 -4
  3. package/dist/commands/generate/generators/agent.js +2 -0
  4. package/dist/commands/generate/generators/marketplace.js +2 -0
  5. package/dist/commands/generate/generators/mcpserver.js +2 -0
  6. package/dist/commands/generate/generators/project.js +9 -2
  7. package/dist/commands/generate/generators/query.js +2 -0
  8. package/dist/commands/generate/generators/team.js +2 -0
  9. package/dist/commands/generate/templateDiscovery.js +1 -0
  10. package/dist/commands/generate/templateEngine.js +1 -3
  11. package/dist/commands/import/index.js +1 -1
  12. package/dist/commands/install/index.js +2 -1
  13. package/dist/commands/models/kubernetes/manifest-builder.js +27 -10
  14. package/dist/commands/models/providers/azure.d.ts +10 -7
  15. package/dist/commands/models/providers/azure.js +83 -21
  16. package/dist/commands/uninstall/index.js +1 -1
  17. package/dist/components/ChatUI.js +17 -16
  18. package/dist/components/statusChecker.js +3 -3
  19. package/dist/lib/arkApiClient.js +11 -9
  20. package/dist/lib/arkApiProxy.js +1 -0
  21. package/dist/lib/arkServiceProxy.js +5 -1
  22. package/dist/lib/chatClient.js +9 -0
  23. package/dist/lib/config.js +8 -3
  24. package/dist/lib/errors.js +3 -0
  25. package/dist/ui/asyncOperations/connectingToArk.js +2 -2
  26. package/package.json +17 -13
  27. package/dist/arkServices.spec.d.ts +0 -1
  28. package/dist/arkServices.spec.js +0 -138
  29. package/dist/commands/agents/index.spec.d.ts +0 -1
  30. package/dist/commands/agents/index.spec.js +0 -67
  31. package/dist/commands/cluster/get.spec.d.ts +0 -1
  32. package/dist/commands/cluster/get.spec.js +0 -92
  33. package/dist/commands/cluster/index.spec.d.ts +0 -1
  34. package/dist/commands/cluster/index.spec.js +0 -24
  35. package/dist/commands/completion/index.spec.d.ts +0 -1
  36. package/dist/commands/completion/index.spec.js +0 -34
  37. package/dist/commands/config/index.spec.d.ts +0 -1
  38. package/dist/commands/config/index.spec.js +0 -78
  39. package/dist/commands/evaluation/index.spec.d.ts +0 -1
  40. package/dist/commands/evaluation/index.spec.js +0 -161
  41. package/dist/commands/export/index.spec.d.ts +0 -1
  42. package/dist/commands/export/index.spec.js +0 -145
  43. package/dist/commands/import/index.spec.d.ts +0 -1
  44. package/dist/commands/import/index.spec.js +0 -46
  45. package/dist/commands/install/index.spec.d.ts +0 -1
  46. package/dist/commands/install/index.spec.js +0 -286
  47. package/dist/commands/marketplace/index.spec.d.ts +0 -1
  48. package/dist/commands/marketplace/index.spec.js +0 -88
  49. package/dist/commands/memory/index.spec.d.ts +0 -1
  50. package/dist/commands/memory/index.spec.js +0 -124
  51. package/dist/commands/models/create.spec.d.ts +0 -1
  52. package/dist/commands/models/create.spec.js +0 -167
  53. package/dist/commands/models/index.spec.d.ts +0 -1
  54. package/dist/commands/models/index.spec.js +0 -96
  55. package/dist/commands/models/providers/azure.spec.d.ts +0 -1
  56. package/dist/commands/models/providers/azure.spec.js +0 -232
  57. package/dist/commands/models/providers/bedrock.spec.d.ts +0 -1
  58. package/dist/commands/models/providers/bedrock.spec.js +0 -241
  59. package/dist/commands/models/providers/openai.spec.d.ts +0 -1
  60. package/dist/commands/models/providers/openai.spec.js +0 -180
  61. package/dist/commands/queries/delete.spec.d.ts +0 -1
  62. package/dist/commands/queries/delete.spec.js +0 -74
  63. package/dist/commands/queries/index.spec.d.ts +0 -1
  64. package/dist/commands/queries/index.spec.js +0 -167
  65. package/dist/commands/queries/list.spec.d.ts +0 -1
  66. package/dist/commands/queries/list.spec.js +0 -170
  67. package/dist/commands/queries/validation.spec.d.ts +0 -1
  68. package/dist/commands/queries/validation.spec.js +0 -27
  69. package/dist/commands/query/index.spec.d.ts +0 -1
  70. package/dist/commands/query/index.spec.js +0 -104
  71. package/dist/commands/targets/index.spec.d.ts +0 -1
  72. package/dist/commands/targets/index.spec.js +0 -154
  73. package/dist/commands/teams/index.spec.d.ts +0 -1
  74. package/dist/commands/teams/index.spec.js +0 -70
  75. package/dist/commands/tools/index.spec.d.ts +0 -1
  76. package/dist/commands/tools/index.spec.js +0 -70
  77. package/dist/commands/uninstall/index.spec.d.ts +0 -1
  78. package/dist/commands/uninstall/index.spec.js +0 -125
  79. package/dist/lib/arkServiceProxy.spec.d.ts +0 -1
  80. package/dist/lib/arkServiceProxy.spec.js +0 -100
  81. package/dist/lib/arkStatus.spec.d.ts +0 -1
  82. package/dist/lib/arkStatus.spec.js +0 -49
  83. package/dist/lib/chatClient.spec.d.ts +0 -1
  84. package/dist/lib/chatClient.spec.js +0 -108
  85. package/dist/lib/cluster.spec.d.ts +0 -1
  86. package/dist/lib/cluster.spec.js +0 -338
  87. package/dist/lib/commands.spec.d.ts +0 -1
  88. package/dist/lib/commands.spec.js +0 -146
  89. package/dist/lib/config.spec.d.ts +0 -1
  90. package/dist/lib/config.spec.js +0 -202
  91. package/dist/lib/duration.spec.d.ts +0 -1
  92. package/dist/lib/duration.spec.js +0 -13
  93. package/dist/lib/errors.spec.d.ts +0 -1
  94. package/dist/lib/errors.spec.js +0 -221
  95. package/dist/lib/executeQuery.spec.d.ts +0 -1
  96. package/dist/lib/executeQuery.spec.js +0 -325
  97. package/dist/lib/kubectl.spec.d.ts +0 -1
  98. package/dist/lib/kubectl.spec.js +0 -192
  99. package/dist/lib/marketplaceFetcher.spec.d.ts +0 -1
  100. package/dist/lib/marketplaceFetcher.spec.js +0 -225
  101. package/dist/lib/nextSteps.spec.d.ts +0 -1
  102. package/dist/lib/nextSteps.spec.js +0 -59
  103. package/dist/lib/output.spec.d.ts +0 -1
  104. package/dist/lib/output.spec.js +0 -123
  105. package/dist/lib/startup.spec.d.ts +0 -1
  106. package/dist/lib/startup.spec.js +0 -152
  107. package/dist/lib/stdin.spec.d.ts +0 -1
  108. package/dist/lib/stdin.spec.js +0 -82
  109. package/dist/lib/timeout.spec.d.ts +0 -1
  110. package/dist/lib/timeout.spec.js +0 -14
  111. package/dist/lib/waitForReady.spec.d.ts +0 -1
  112. package/dist/lib/waitForReady.spec.js +0 -104
  113. package/dist/marketplaceServices.spec.d.ts +0 -1
  114. package/dist/marketplaceServices.spec.js +0 -74
  115. package/dist/ui/statusFormatter.spec.d.ts +0 -1
  116. package/dist/ui/statusFormatter.spec.js +0 -58
@@ -2,7 +2,11 @@
2
2
  * Centralized ARK service definitions used by both install and status commands
3
3
  */
4
4
  import { loadConfig, getMarketplaceRegistry } from './lib/config.js';
5
+ import { createRequire } from 'module';
6
+ const require = createRequire(import.meta.url);
7
+ const packageJson = require('../package.json');
5
8
  const REGISTRY_BASE = 'oci://ghcr.io/mckinsey/agents-at-scale-ark/charts';
9
+ const CHART_VERSION = `${packageJson.version}`;
6
10
  /**
7
11
  * Dependencies that should be installed before ARK services
8
12
  * Note: Dependencies will be installed in the order they are defined here
@@ -64,7 +68,7 @@ const defaultArkServices = {
64
68
  enabled: true,
65
69
  category: 'core',
66
70
  namespace: 'ark-system',
67
- chartPath: `${REGISTRY_BASE}/ark-controller`,
71
+ chartPath: `${REGISTRY_BASE}/ark-controller:${CHART_VERSION}`,
68
72
  installArgs: ['--create-namespace', '--set', 'rbac.enable=true'],
69
73
  k8sDeploymentName: 'ark-controller',
70
74
  k8sDevDeploymentName: 'ark-controller-devspace',
@@ -75,7 +79,7 @@ const defaultArkServices = {
75
79
  description: 'Tenant provisioning with RBAC and resource quotas',
76
80
  enabled: true,
77
81
  category: 'core',
78
- chartPath: `${REGISTRY_BASE}/ark-tenant`,
82
+ chartPath: `${REGISTRY_BASE}/ark-tenant:${CHART_VERSION}`,
79
83
  installArgs: [],
80
84
  },
81
85
  'ark-api': {
@@ -84,7 +88,7 @@ const defaultArkServices = {
84
88
  description: 'API layer for interacting with Ark resources',
85
89
  enabled: true,
86
90
  category: 'service',
87
- chartPath: `${REGISTRY_BASE}/ark-api`,
91
+ chartPath: `${REGISTRY_BASE}/ark-api:${CHART_VERSION}`,
88
92
  installArgs: [],
89
93
  k8sServiceName: 'ark-api',
90
94
  k8sServicePort: 80,
@@ -99,7 +103,7 @@ const defaultArkServices = {
99
103
  enabled: true,
100
104
  category: 'service',
101
105
  // namespace: undefined - uses current context namespace
102
- chartPath: `${REGISTRY_BASE}/ark-dashboard`,
106
+ chartPath: `${REGISTRY_BASE}/ark-dashboard:${CHART_VERSION}`,
103
107
  installArgs: [],
104
108
  k8sServiceName: 'ark-dashboard',
105
109
  k8sServicePort: 3000,
@@ -114,7 +118,7 @@ const defaultArkServices = {
114
118
  enabled: true,
115
119
  category: 'service',
116
120
  // namespace: undefined - uses current context namespace
117
- chartPath: `${REGISTRY_BASE}/ark-mcp`,
121
+ chartPath: `${REGISTRY_BASE}/ark-mcp:${CHART_VERSION}`,
118
122
  installArgs: [],
119
123
  k8sDeploymentName: 'ark-mcp',
120
124
  k8sDevDeploymentName: 'ark-mcp-devspace',
@@ -128,7 +132,7 @@ const defaultArkServices = {
128
132
  description: 'In-memory storage service with streaming support for Ark queries',
129
133
  enabled: true,
130
134
  category: 'service',
131
- chartPath: `${REGISTRY_BASE}/ark-broker`,
135
+ chartPath: `${REGISTRY_BASE}/ark-broker:${CHART_VERSION}`,
132
136
  installArgs: [],
133
137
  prerequisiteUninstalls: [{ releaseName: 'ark-cluster-memory' }],
134
138
  k8sDeploymentName: 'ark-broker',
@@ -156,7 +160,7 @@ const defaultArkServices = {
156
160
  enabled: false, // Disabled - not needed for most users
157
161
  category: 'service',
158
162
  namespace: 'ark-system',
159
- chartPath: `${REGISTRY_BASE}/localhost-gateway`,
163
+ chartPath: `${REGISTRY_BASE}/localhost-gateway:${CHART_VERSION}`,
160
164
  installArgs: [],
161
165
  },
162
166
  noah: {
@@ -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);