@agents-at-scale/ark 0.1.55 → 0.1.56

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 (36) hide show
  1. package/dist/arkServices.js +14 -0
  2. package/dist/commands/completion/index.js +9 -6
  3. package/dist/commands/export/index.js +0 -1
  4. package/dist/commands/generate/generators/team.js +0 -1
  5. package/dist/commands/install/index.js +33 -30
  6. package/dist/commands/marketplace/index.js +18 -3
  7. package/dist/commands/models/create.js +1 -0
  8. package/dist/commands/models/kubernetes/manifest-builder.js +22 -0
  9. package/dist/commands/models/providers/anthropic.d.ts +15 -0
  10. package/dist/commands/models/providers/anthropic.js +72 -0
  11. package/dist/commands/models/providers/factory.js +3 -0
  12. package/dist/commands/models/providers/index.d.ts +3 -4
  13. package/dist/commands/models/providers/index.js +1 -0
  14. package/dist/commands/uninstall/index.js +8 -2
  15. package/dist/components/ChatUI.js +4 -17
  16. package/dist/index.js +0 -2
  17. package/dist/lib/arkApiClient.d.ts +14 -4
  18. package/dist/lib/arkApiClient.js +51 -34
  19. package/dist/lib/chatClient.d.ts +4 -6
  20. package/dist/lib/chatClient.js +136 -102
  21. package/dist/lib/errors.d.ts +0 -1
  22. package/dist/lib/errors.js +0 -1
  23. package/dist/lib/marketplaceFetcher.d.ts +1 -0
  24. package/dist/lib/marketplaceFetcher.js +17 -0
  25. package/dist/lib/types.d.ts +0 -38
  26. package/dist/marketplaceServices.d.ts +6 -1
  27. package/dist/marketplaceServices.js +19 -3
  28. package/dist/types/arkService.d.ts +1 -0
  29. package/dist/types/marketplace.d.ts +1 -1
  30. package/package.json +5 -3
  31. package/templates/marketplace/marketplace.json.example +2 -2
  32. package/templates/tool/uv.lock +794 -95
  33. package/dist/commands/evaluation/index.d.ts +0 -3
  34. package/dist/commands/evaluation/index.js +0 -60
  35. package/dist/lib/executeEvaluation.d.ts +0 -16
  36. package/dist/lib/executeEvaluation.js +0 -155
@@ -66,6 +66,7 @@ const defaultArkServices = {
66
66
  helmReleaseName: 'ark-controller',
67
67
  description: 'Core Ark controller for managing AI resources',
68
68
  enabled: true,
69
+ mandatory: true,
69
70
  category: 'core',
70
71
  namespace: 'ark-system',
71
72
  chartPath: `${REGISTRY_BASE}/ark-controller:${CHART_VERSION}`,
@@ -73,11 +74,24 @@ const defaultArkServices = {
73
74
  k8sDeploymentName: 'ark-controller',
74
75
  k8sDevDeploymentName: 'ark-controller-devspace',
75
76
  },
77
+ 'ark-completions': {
78
+ name: 'ark-completions',
79
+ helmReleaseName: 'ark-completions',
80
+ description: 'Completions execution engine for Ark queries',
81
+ enabled: true,
82
+ mandatory: true,
83
+ category: 'core',
84
+ namespace: 'ark-system',
85
+ chartPath: `${REGISTRY_BASE}/ark-completions:${CHART_VERSION}`,
86
+ installArgs: ['--create-namespace'],
87
+ k8sDeploymentName: 'ark-completions',
88
+ },
76
89
  'ark-tenant': {
77
90
  name: 'ark-tenant',
78
91
  helmReleaseName: 'ark-tenant',
79
92
  description: 'Tenant provisioning with RBAC and resource quotas',
80
93
  enabled: true,
94
+ mandatory: true,
81
95
  category: 'core',
82
96
  chartPath: `${REGISTRY_BASE}/ark-tenant:${CHART_VERSION}`,
83
97
  installArgs: [],
@@ -28,7 +28,7 @@ _ark_completion() {
28
28
 
29
29
  case \${COMP_CWORD} in
30
30
  1)
31
- opts="agents chat cluster completion config dashboard docs evaluation export generate import install marketplace memory models queries query routes status targets teams tools uninstall help"
31
+ opts="agents chat cluster completion config dashboard docs export generate import install marketplace memory models queries query routes status targets teams tools uninstall help"
32
32
  COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
33
33
  return 0
34
34
  ;;
@@ -90,12 +90,12 @@ _ark_completion() {
90
90
  return 0
91
91
  ;;
92
92
  install)
93
- opts="marketplace/services/phoenix marketplace/services/langfuse marketplace/agents/noah"
93
+ opts="marketplace/services/phoenix marketplace/services/langfuse marketplace/agents/noah marketplace/executors/langchain marketplace/executors/claude-agent-sdk"
94
94
  COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
95
95
  return 0
96
96
  ;;
97
97
  uninstall)
98
- opts="marketplace/services/phoenix marketplace/services/langfuse marketplace/agents/noah"
98
+ opts="marketplace/services/phoenix marketplace/services/langfuse marketplace/agents/noah marketplace/executors/langchain marketplace/executors/claude-agent-sdk"
99
99
  COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
100
100
  return 0
101
101
  ;;
@@ -160,7 +160,6 @@ _ark() {
160
160
  'config[Configuration management]' \\
161
161
  'dashboard[Open ARK dashboard]' \\
162
162
  'docs[Open ARK documentation]' \\
163
- 'evaluation[Execute evaluations against evaluators]' \\
164
163
  'export[Export ARK resources to a file]' \\
165
164
  'generate[Generate ARK resources]' \\
166
165
  'import[Import ARK resources from a file]' \\
@@ -244,12 +243,16 @@ _ark() {
244
243
  install)
245
244
  _values 'services to install' \\
246
245
  'marketplace/services/phoenix[Phoenix observability platform]' \\
247
- 'marketplace/services/langfuse[Langfuse LLM analytics]'
246
+ 'marketplace/services/langfuse[Langfuse LLM analytics]' \\
247
+ 'marketplace/executors/langchain[LangChain execution engine]' \\
248
+ 'marketplace/executors/claude-agent-sdk[Claude Agent SDK executor]'
248
249
  ;;
249
250
  uninstall)
250
251
  _values 'services to uninstall' \\
251
252
  'marketplace/services/phoenix[Phoenix observability platform]' \\
252
- 'marketplace/services/langfuse[Langfuse LLM analytics]'
253
+ 'marketplace/services/langfuse[Langfuse LLM analytics]' \\
254
+ 'marketplace/executors/langchain[LangChain execution engine]' \\
255
+ 'marketplace/executors/claude-agent-sdk[Claude Agent SDK executor]'
253
256
  ;;
254
257
  chat)
255
258
  # Get available targets dynamically
@@ -11,7 +11,6 @@ const RESOURCE_ORDER = [
11
11
  'models',
12
12
  'agents',
13
13
  'teams',
14
- 'evaluators',
15
14
  'mcpservers',
16
15
  'a2aservers',
17
16
  ];
@@ -91,7 +91,6 @@ class TeamGenerator {
91
91
  choices: [
92
92
  { name: 'Sequential - Agents execute in order', value: 'sequential' },
93
93
  { name: 'Round Robin - Agents take turns', value: 'round-robin' },
94
- { name: 'Graph - Custom workflow with dependencies', value: 'graph' },
95
94
  {
96
95
  name: 'Selector - AI chooses the next agent (can add graph constraints)',
97
96
  value: 'selector',
@@ -5,7 +5,7 @@ import inquirer from 'inquirer';
5
5
  import { showNoClusterError } from '../../lib/startup.js';
6
6
  import output from '../../lib/output.js';
7
7
  import { getInstallableServices, arkDependencies, arkServices, } from '../../arkServices.js';
8
- import { isMarketplaceService, getMarketplaceItem, getAllMarketplaceServices, getAllMarketplaceAgents, } from '../../marketplaceServices.js';
8
+ import { isMarketplaceService, getMarketplaceItem, getAllMarketplaceServices, getAllMarketplaceAgents, getAllMarketplaceExecutors, } from '../../marketplaceServices.js';
9
9
  import { printNextSteps } from '../../lib/nextSteps.js';
10
10
  import ora from 'ora';
11
11
  import { waitForServicesReady, } from '../../lib/waitForReady.js';
@@ -95,7 +95,13 @@ export async function installArk(config, serviceName, options = {}) {
95
95
  output.info(` marketplace/agents/${name}`);
96
96
  }
97
97
  }
98
- if (!marketplaceServices && !marketplaceAgents) {
98
+ const marketplaceExecutors = await getAllMarketplaceExecutors();
99
+ if (marketplaceExecutors) {
100
+ for (const name of Object.keys(marketplaceExecutors)) {
101
+ output.info(` marketplace/executors/${name}`);
102
+ }
103
+ }
104
+ if (!marketplaceServices && !marketplaceAgents && !marketplaceExecutors) {
99
105
  output.warning('Marketplace unavailable');
100
106
  }
101
107
  process.exit(1);
@@ -137,39 +143,35 @@ export async function installArk(config, serviceName, options = {}) {
137
143
  }
138
144
  // If not using -y flag, show checklist interface
139
145
  if (!options.yes) {
140
- console.log(chalk.cyan.bold('\nSelect components to install:'));
141
- console.log(chalk.gray('Use arrow keys to navigate, space to toggle, enter to confirm\n'));
142
- // Build choices for the checkbox prompt
143
146
  const coreServices = Object.values(arkServices)
144
147
  .filter((s) => s.category === 'core')
145
148
  .sort((a, b) => a.name.localeCompare(b.name));
146
149
  const otherServices = Object.values(arkServices)
147
150
  .filter((s) => s.category === 'service')
148
151
  .sort((a, b) => a.name.localeCompare(b.name));
149
- const allChoices = [
150
- new inquirer.Separator(chalk.bold('──── Dependencies ────')),
151
- {
152
- name: `cert-manager ${chalk.gray('- Certificate management')}`,
153
- value: 'cert-manager',
154
- checked: true,
155
- },
156
- {
157
- name: `gateway-api ${chalk.gray('- Gateway API CRDs')}`,
158
- value: 'gateway-api',
159
- checked: true,
160
- },
161
- new inquirer.Separator(chalk.bold('──── Ark Core ────')),
162
- ...coreServices.map((service) => ({
152
+ const mandatoryServiceNames = [...coreServices, ...otherServices]
153
+ .filter((s) => s.mandatory)
154
+ .map((s) => s.helmReleaseName);
155
+ console.log(chalk.cyan.bold('\nSelect components to install:'));
156
+ console.log(chalk.gray('Use arrow keys to navigate, space to toggle, enter to confirm\n'));
157
+ const formatServiceChoice = (service) => {
158
+ if (service.mandatory) {
159
+ return new inquirer.Separator(`${chalk.dim.green('◉')} ${chalk.dim(`${service.name} - ${service.description}`)}`);
160
+ }
161
+ return {
163
162
  name: `${service.name} ${chalk.gray(`- ${service.description}`)}`,
164
163
  value: service.helmReleaseName,
165
164
  checked: Boolean(service.enabled),
166
- })),
165
+ };
166
+ };
167
+ const allChoices = [
168
+ new inquirer.Separator(chalk.bold('──── Dependencies ────')),
169
+ new inquirer.Separator(`${chalk.dim.green('◉')} ${chalk.dim('cert-manager - Certificate management')}`),
170
+ new inquirer.Separator(`${chalk.dim.green('◉')} ${chalk.dim('gateway-api - Gateway API CRDs')}`),
171
+ new inquirer.Separator(chalk.bold('──── Ark Core ────')),
172
+ ...coreServices.map(formatServiceChoice),
167
173
  new inquirer.Separator(chalk.bold('──── Ark Services ────')),
168
- ...otherServices.map((service) => ({
169
- name: `${service.name} ${chalk.gray(`- ${service.description}`)}`,
170
- value: service.helmReleaseName,
171
- checked: Boolean(service.enabled),
172
- })),
174
+ ...otherServices.map(formatServiceChoice),
173
175
  ];
174
176
  let selectedComponents;
175
177
  try {
@@ -182,11 +184,12 @@ export async function installArk(config, serviceName, options = {}) {
182
184
  pageSize: 15,
183
185
  },
184
186
  ]);
185
- selectedComponents = answers.components;
186
- if (selectedComponents.length === 0) {
187
- output.warning('No components selected. Exiting.');
188
- process.exit(0);
189
- }
187
+ selectedComponents = [
188
+ 'cert-manager',
189
+ 'gateway-api',
190
+ ...mandatoryServiceNames,
191
+ ...answers.components,
192
+ ];
190
193
  }
191
194
  catch (error) {
192
195
  // Handle Ctrl-C gracefully
@@ -1,7 +1,7 @@
1
1
  import { Command } from 'commander';
2
2
  import chalk from 'chalk';
3
3
  import { getMarketplaceRepoUrl, getMarketplaceRegistry, } from '../../lib/config.js';
4
- import { getAllMarketplaceServices, getAllMarketplaceAgents, } from '../../marketplaceServices.js';
4
+ import { getAllMarketplaceServices, getAllMarketplaceAgents, getAllMarketplaceExecutors, } from '../../marketplaceServices.js';
5
5
  import { fetchMarketplaceManifest } from '../../lib/marketplaceFetcher.js';
6
6
  function createMarketplaceCommand(_config) {
7
7
  const repoUrl = getMarketplaceRepoUrl();
@@ -18,19 +18,21 @@ Registry: ${chalk.cyan(registry.replace('oci://', ''))}
18
18
  `)
19
19
  .addHelpText('after', `
20
20
  ${chalk.cyan('Examples:')}
21
- ${chalk.yellow('ark marketplace list')} # List available services and agents
21
+ ${chalk.yellow('ark marketplace list')} # List available marketplace items
22
22
  ${chalk.yellow('ark install marketplace/services/phoenix')} # Install Phoenix service
23
23
  ${chalk.yellow('ark install marketplace/agents/noah')} # Install Noah agent
24
+ ${chalk.yellow('ark install marketplace/executors/langchain')} # Install LangChain executor
24
25
  ${chalk.yellow('ark uninstall marketplace/services/phoenix')} # Uninstall Phoenix
25
26
  `);
26
27
  // List command
27
28
  const list = new Command('list');
28
29
  list
29
30
  .alias('ls')
30
- .description('List available marketplace services and agents')
31
+ .description('List available marketplace items')
31
32
  .action(async () => {
32
33
  const services = await getAllMarketplaceServices();
33
34
  const agents = await getAllMarketplaceAgents();
35
+ const executors = await getAllMarketplaceExecutors();
34
36
  const manifest = await fetchMarketplaceManifest();
35
37
  console.log(chalk.blue('\n🏪 ARK Marketplace\n'));
36
38
  if (!manifest) {
@@ -68,6 +70,19 @@ ${chalk.cyan('Examples:')}
68
70
  console.log();
69
71
  }
70
72
  }
73
+ if (executors && Object.keys(executors).length > 0) {
74
+ console.log(chalk.bold('Executors:'));
75
+ console.log(chalk.gray('Install with: ark install marketplace/executors/<name>\n'));
76
+ for (const [key, executor] of Object.entries(executors)) {
77
+ const icon = '⚙️';
78
+ const executorName = `marketplace/executors/${key.padEnd(12)}`;
79
+ const executorDesc = executor.description;
80
+ console.log(`${icon} ${chalk.green(executorName)} ${chalk.gray(executorDesc)}`);
81
+ const namespaceInfo = `namespace: ${executor.namespace || 'default'}`;
82
+ console.log(` ${chalk.dim(namespaceInfo)}`);
83
+ console.log();
84
+ }
85
+ }
71
86
  console.log(chalk.cyan(`Repository: ${repoUrl}`));
72
87
  console.log(chalk.cyan(`Registry: ${registry}`));
73
88
  console.log();
@@ -59,6 +59,7 @@ export async function createModel(modelName, options = {}) {
59
59
  choices: [
60
60
  { name: 'Azure OpenAI', value: 'azure' },
61
61
  { name: 'OpenAI', value: 'openai' },
62
+ { name: 'Anthropic', value: 'anthropic' },
62
63
  { name: 'AWS Bedrock', value: 'bedrock' },
63
64
  ],
64
65
  default: 'azure',
@@ -79,6 +79,28 @@ export class KubernetesModelManifestBuilder {
79
79
  },
80
80
  };
81
81
  }
82
+ if (config.type === 'anthropic') {
83
+ const anthropicConfig = config;
84
+ const anthropic = {
85
+ apiKey: {
86
+ valueFrom: {
87
+ secretKeyRef: {
88
+ name: config.secretName,
89
+ key: 'api-key',
90
+ },
91
+ },
92
+ },
93
+ baseUrl: {
94
+ value: anthropicConfig.baseUrl,
95
+ },
96
+ };
97
+ if (anthropicConfig.version) {
98
+ anthropic.version = {
99
+ value: anthropicConfig.version,
100
+ };
101
+ }
102
+ return { anthropic };
103
+ }
82
104
  throw new Error(`Unknown provider type: ${config.type}`);
83
105
  }
84
106
  buildBedrockConfig(config) {
@@ -0,0 +1,15 @@
1
+ import { BaseProviderConfig, BaseCollectorOptions, ProviderConfigCollector } from './types.js';
2
+ export interface AnthropicConfig extends BaseProviderConfig {
3
+ type: 'anthropic';
4
+ baseUrl: string;
5
+ apiKey: string;
6
+ version?: string;
7
+ }
8
+ export interface AnthropicCollectorOptions extends BaseCollectorOptions {
9
+ baseUrl?: string;
10
+ apiKey?: string;
11
+ version?: string;
12
+ }
13
+ export declare class AnthropicConfigCollector implements ProviderConfigCollector {
14
+ collectConfig(options: BaseCollectorOptions): Promise<AnthropicConfig>;
15
+ }
@@ -0,0 +1,72 @@
1
+ import inquirer from 'inquirer';
2
+ export class AnthropicConfigCollector {
3
+ async collectConfig(options) {
4
+ const anthropicOptions = options;
5
+ let baseUrl = anthropicOptions.baseUrl;
6
+ if (!baseUrl) {
7
+ const answer = await inquirer.prompt([
8
+ {
9
+ type: 'input',
10
+ name: 'baseUrl',
11
+ message: 'base URL:',
12
+ validate: (input) => {
13
+ if (!input)
14
+ return 'base URL is required';
15
+ try {
16
+ new URL(input);
17
+ return true;
18
+ }
19
+ catch {
20
+ return 'please enter a valid URL';
21
+ }
22
+ },
23
+ },
24
+ ]);
25
+ baseUrl = answer.baseUrl;
26
+ }
27
+ if (!baseUrl) {
28
+ throw new Error('base URL is required');
29
+ }
30
+ baseUrl = baseUrl.replace(/\/$/, '');
31
+ let apiKey = anthropicOptions.apiKey;
32
+ if (!apiKey) {
33
+ const answer = await inquirer.prompt([
34
+ {
35
+ type: 'password',
36
+ name: 'apiKey',
37
+ message: 'API key:',
38
+ mask: '*',
39
+ validate: (input) => {
40
+ if (!input)
41
+ return 'API key is required';
42
+ return true;
43
+ },
44
+ },
45
+ ]);
46
+ apiKey = answer.apiKey;
47
+ }
48
+ if (!apiKey) {
49
+ throw new Error('API key is required');
50
+ }
51
+ let version = anthropicOptions.version;
52
+ if (!version) {
53
+ const answer = await inquirer.prompt([
54
+ {
55
+ type: 'input',
56
+ name: 'version',
57
+ message: 'anthropic version:',
58
+ default: '2023-06-01',
59
+ },
60
+ ]);
61
+ version = answer.version;
62
+ }
63
+ return {
64
+ type: 'anthropic',
65
+ modelValue: options.model,
66
+ secretName: '',
67
+ baseUrl,
68
+ apiKey,
69
+ ...(version ? { version } : {}),
70
+ };
71
+ }
72
+ }
@@ -1,6 +1,7 @@
1
1
  import { OpenAIConfigCollector } from './openai.js';
2
2
  import { AzureConfigCollector } from './azure.js';
3
3
  import { BedrockConfigCollector } from './bedrock.js';
4
+ import { AnthropicConfigCollector } from './anthropic.js';
4
5
  /**
5
6
  * Factory for creating provider-specific configuration collectors.
6
7
  *
@@ -24,6 +25,8 @@ export class ProviderConfigCollectorFactory {
24
25
  return new AzureConfigCollector();
25
26
  case 'bedrock':
26
27
  return new BedrockConfigCollector();
28
+ case 'anthropic':
29
+ return new AnthropicConfigCollector();
27
30
  default:
28
31
  throw new Error(`Unknown provider type: ${type}`);
29
32
  }
@@ -7,11 +7,10 @@ export { BaseProviderConfig, BaseCollectorOptions, ProviderConfigCollector, } fr
7
7
  export { OpenAIConfig, OpenAICollectorOptions, OpenAIConfigCollector, } from './openai.js';
8
8
  export { AzureConfig, AzureCollectorOptions, AzureConfigCollector, } from './azure.js';
9
9
  export { BedrockConfig, BedrockCollectorOptions, BedrockConfigCollector, } from './bedrock.js';
10
+ export { AnthropicConfig, AnthropicCollectorOptions, AnthropicConfigCollector, } from './anthropic.js';
10
11
  export { ProviderConfigCollectorFactory } from './factory.js';
11
12
  import { OpenAIConfig } from './openai.js';
12
13
  import { AzureConfig } from './azure.js';
13
14
  import { BedrockConfig } from './bedrock.js';
14
- /**
15
- * Union type of all supported provider configurations.
16
- */
17
- export type ProviderConfig = OpenAIConfig | AzureConfig | BedrockConfig;
15
+ import { AnthropicConfig } from './anthropic.js';
16
+ export type ProviderConfig = OpenAIConfig | AzureConfig | BedrockConfig | AnthropicConfig;
@@ -6,4 +6,5 @@
6
6
  export { OpenAIConfigCollector, } from './openai.js';
7
7
  export { AzureConfigCollector, } from './azure.js';
8
8
  export { BedrockConfigCollector, } from './bedrock.js';
9
+ export { AnthropicConfigCollector, } from './anthropic.js';
9
10
  export { ProviderConfigCollectorFactory } from './factory.js';
@@ -5,7 +5,7 @@ import inquirer from 'inquirer';
5
5
  import { showNoClusterError } from '../../lib/startup.js';
6
6
  import output from '../../lib/output.js';
7
7
  import { getInstallableServices } from '../../arkServices.js';
8
- import { isMarketplaceService, getMarketplaceItem, getAllMarketplaceServices, getAllMarketplaceAgents, } from '../../marketplaceServices.js';
8
+ import { isMarketplaceService, getMarketplaceItem, getAllMarketplaceServices, getAllMarketplaceAgents, getAllMarketplaceExecutors, } from '../../marketplaceServices.js';
9
9
  async function uninstallService(service, verbose = false) {
10
10
  const helmArgs = ['uninstall', service.helmReleaseName, '--ignore-not-found'];
11
11
  // Only add namespace flag if service has explicit namespace
@@ -44,7 +44,13 @@ async function uninstallArk(config, serviceName, options = {}) {
44
44
  output.info(` marketplace/agents/${name}`);
45
45
  }
46
46
  }
47
- if (!marketplaceServices && !marketplaceAgents) {
47
+ const marketplaceExecutors = await getAllMarketplaceExecutors();
48
+ if (marketplaceExecutors) {
49
+ for (const name of Object.keys(marketplaceExecutors)) {
50
+ output.info(` marketplace/executors/${name}`);
51
+ }
52
+ }
53
+ if (!marketplaceServices && !marketplaceAgents && !marketplaceExecutors) {
48
54
  output.warning('Marketplace unavailable');
49
55
  }
50
56
  process.exit(1);
@@ -6,7 +6,6 @@ import * as React from 'react';
6
6
  import { marked } from 'marked';
7
7
  // @ts-ignore - no types available
8
8
  import TerminalRenderer from 'marked-terminal';
9
- import { APIError } from 'openai';
10
9
  import { TargetSelector } from '../ui/TargetSelector.js';
11
10
  import { useAsyncOperation, AsyncOperationStatus } from './AsyncOperation.js';
12
11
  import { createConnectingToArkOperation } from '../ui/asyncOperations/connectingToArk.js';
@@ -470,9 +469,9 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
470
469
  const fullResponse = await chatClientRef.current.sendMessage(target.id, apiMessages, { ...chatConfig, a2aContextId: a2aContextIdRef.current }, (chunk, toolCalls, arkMetadata) => {
471
470
  // Extract A2A context ID from response
472
471
  // Chat TUI always queries a single target, so contextId is in response
473
- if (arkMetadata?.completedQuery?.status?.response?.a2a?.contextId) {
474
- a2aContextIdRef.current =
475
- arkMetadata.completedQuery.status.response.a2a.contextId;
472
+ const completed = arkMetadata?.completedQuery;
473
+ if (completed?.status?.response?.a2a?.contextId) {
474
+ a2aContextIdRef.current = completed.status.response.a2a.contextId;
476
475
  }
477
476
  // Update message progressively as chunks arrive
478
477
  setMessages((prev) => {
@@ -558,21 +557,9 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
558
557
  return;
559
558
  }
560
559
  let errorMessage = 'Failed to send message';
561
- // OpenAI SDK errors include response body in .error property
562
- if (err instanceof APIError) {
563
- if (err.error && typeof err.error === 'object') {
564
- const errorObj = err.error;
565
- errorMessage = errorObj.message || JSON.stringify(err.error, null, 2);
566
- }
567
- else {
568
- errorMessage = err.message;
569
- }
570
- }
571
- // Standard JavaScript errors
572
- else if (err instanceof Error) {
560
+ if (err instanceof Error) {
573
561
  errorMessage = err.message;
574
562
  }
575
- // String errors from throw statements
576
563
  else if (typeof err === 'string') {
577
564
  errorMessage = err;
578
565
  }
package/dist/index.js CHANGED
@@ -13,7 +13,6 @@ import { createClusterCommand } from './commands/cluster/index.js';
13
13
  import { createCompletionCommand } from './commands/completion/index.js';
14
14
  import { createDashboardCommand } from './commands/dashboard/index.js';
15
15
  import { createDocsCommand } from './commands/docs/index.js';
16
- import { createEvaluationCommand } from './commands/evaluation/index.js';
17
16
  import { createExportCommand } from './commands/export/index.js';
18
17
  import { createGenerateCommand } from './commands/generate/index.js';
19
18
  import { createImportCommand } from './commands/import/index.js';
@@ -49,7 +48,6 @@ async function main() {
49
48
  program.addCommand(createCompletionCommand(config));
50
49
  program.addCommand(createDashboardCommand(config));
51
50
  program.addCommand(createDocsCommand(config));
52
- program.addCommand(createEvaluationCommand(config));
53
51
  program.addCommand(createExportCommand(config));
54
52
  program.addCommand(createGenerateCommand(config));
55
53
  program.addCommand(createImportCommand(config));
@@ -1,4 +1,3 @@
1
- import OpenAI from 'openai';
2
1
  export interface QueryTarget {
3
2
  id: string;
4
3
  name: string;
@@ -38,7 +37,6 @@ export interface Team {
38
37
  status?: string;
39
38
  }
40
39
  export declare class ArkApiClient {
41
- private openai;
42
40
  private baseUrl;
43
41
  constructor(arkApiUrl: string);
44
42
  getBaseUrl(): string;
@@ -51,6 +49,18 @@ export declare class ArkApiClient {
51
49
  deleteSession(sessionId: string): Promise<any>;
52
50
  deleteQueryMessages(sessionId: string, queryId: string): Promise<any>;
53
51
  deleteAllSessions(): Promise<any>;
54
- createChatCompletion(params: OpenAI.Chat.Completions.ChatCompletionCreateParams): Promise<OpenAI.Chat.Completions.ChatCompletion>;
55
- createChatCompletionStream(params: OpenAI.Chat.Completions.ChatCompletionCreateParams): AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>;
52
+ createQuery(params: {
53
+ input: string;
54
+ target: {
55
+ type: string;
56
+ name: string;
57
+ };
58
+ sessionId?: string;
59
+ conversationId?: string;
60
+ timeout?: string;
61
+ metadata?: {
62
+ annotations?: Record<string, string>;
63
+ };
64
+ }): Promise<Record<string, unknown>>;
65
+ getQuery(queryName: string): Promise<Record<string, unknown>>;
56
66
  }
@@ -1,33 +1,39 @@
1
- import OpenAI from 'openai';
2
1
  export class ArkApiClient {
3
- openai;
4
2
  baseUrl;
5
3
  constructor(arkApiUrl) {
6
4
  this.baseUrl = arkApiUrl;
7
- this.openai = new OpenAI({
8
- baseURL: `${arkApiUrl}/openai/v1`,
9
- apiKey: 'dummy', // ark-api doesn't require an API key
10
- dangerouslyAllowBrowser: false,
11
- maxRetries: 0, // Disable automatic retries for query errors
12
- });
13
5
  }
14
6
  getBaseUrl() {
15
7
  return this.baseUrl;
16
8
  }
17
9
  async getQueryTargets() {
18
10
  try {
19
- const models = await this.openai.models.list();
20
- const targets = models.data.map((model) => {
21
- const parts = model.id.split('/');
22
- const type = parts[0] || 'model';
23
- const name = parts.slice(1).join('/') || model.id;
24
- return {
25
- id: model.id,
26
- name,
27
- type,
28
- description: model.id,
29
- };
30
- });
11
+ const targets = [];
12
+ const endpoints = [
13
+ { type: 'agent', path: '/v1/agents' },
14
+ { type: 'model', path: '/v1/models' },
15
+ { type: 'team', path: '/v1/teams' },
16
+ { type: 'tool', path: '/v1/tools' },
17
+ ];
18
+ for (const ep of endpoints) {
19
+ try {
20
+ const response = await fetch(`${this.baseUrl}${ep.path}`);
21
+ if (response.ok) {
22
+ const data = (await response.json());
23
+ for (const item of data.items || []) {
24
+ targets.push({
25
+ id: `${ep.type}/${item.name}`,
26
+ name: item.name,
27
+ type: ep.type,
28
+ description: item.description || item.name,
29
+ });
30
+ }
31
+ }
32
+ }
33
+ catch {
34
+ // Skip unavailable resource types
35
+ }
36
+ }
31
37
  return targets;
32
38
  }
33
39
  catch (error) {
@@ -141,21 +147,32 @@ export class ArkApiClient {
141
147
  throw new Error(`Failed to delete all sessions: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
142
148
  }
143
149
  }
144
- async createChatCompletion(params) {
145
- return (await this.openai.chat.completions.create({
146
- ...params,
147
- stream: false,
148
- }));
149
- }
150
- async *createChatCompletionStream(params) {
151
- // Errors from OpenAI SDK will automatically propagate with proper error messages
152
- // and kill the CLI, so no try/catch needed here
153
- const stream = await this.openai.chat.completions.create({
154
- ...params,
155
- stream: true,
150
+ async createQuery(params) {
151
+ const response = await fetch(`${this.baseUrl}/v1/queries/`, {
152
+ method: 'POST',
153
+ headers: { 'Content-Type': 'application/json' },
154
+ body: JSON.stringify({
155
+ name: `cli-query-${Date.now()}`,
156
+ type: 'user',
157
+ input: params.input,
158
+ target: params.target,
159
+ sessionId: params.sessionId,
160
+ conversationId: params.conversationId,
161
+ timeout: params.timeout,
162
+ ...(params.metadata ? { metadata: params.metadata } : {}),
163
+ }),
156
164
  });
157
- for await (const chunk of stream) {
158
- yield chunk;
165
+ if (!response.ok) {
166
+ const text = await response.text();
167
+ throw new Error(`Query creation failed (${response.status}): ${text}`);
168
+ }
169
+ return (await response.json());
170
+ }
171
+ async getQuery(queryName) {
172
+ const response = await fetch(`${this.baseUrl}/v1/queries/${queryName}`);
173
+ if (!response.ok) {
174
+ throw new Error(`Failed to get query: ${response.status}`);
159
175
  }
176
+ return (await response.json());
160
177
  }
161
178
  }