@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
@@ -1,13 +1,12 @@
1
1
  import { ArkApiClient, QueryTarget } from './arkApiClient.js';
2
- import type { Query } from './types.js';
3
2
  export { QueryTarget };
4
3
  export interface ChatConfig {
5
4
  streamingEnabled: boolean;
6
5
  currentTarget?: QueryTarget;
7
- a2aContextId?: string;
8
6
  sessionId?: string;
9
7
  conversationId?: string;
10
8
  queryTimeout?: string;
9
+ a2aContextId?: string;
11
10
  }
12
11
  export interface ToolCall {
13
12
  id: string;
@@ -23,17 +22,16 @@ export interface ArkMetadata {
23
22
  model?: string;
24
23
  query?: string;
25
24
  target?: string;
26
- completedQuery?: Query;
25
+ completedQuery?: Record<string, unknown>;
27
26
  }
28
27
  export declare class ChatClient {
29
28
  private arkApiClient;
30
29
  constructor(arkApiClient: ArkApiClient);
31
30
  getQueryTargets(): Promise<QueryTarget[]>;
32
- /**
33
- * Send a chat completion request
34
- */
35
31
  sendMessage(targetId: string, messages: Array<{
36
32
  role: 'user' | 'assistant' | 'system';
37
33
  content: string;
38
34
  }>, config: ChatConfig, onChunk?: (chunk: string, toolCalls?: ToolCall[], arkMetadata?: ArkMetadata) => void, signal?: AbortSignal): Promise<string>;
35
+ private pollResponse;
36
+ private pollStreamResponse;
39
37
  }
@@ -7,120 +7,154 @@ export class ChatClient {
7
7
  async getQueryTargets() {
8
8
  return await this.arkApiClient.getQueryTargets();
9
9
  }
10
- /**
11
- * Send a chat completion request
12
- */
13
10
  async sendMessage(targetId, messages, config, onChunk, signal) {
14
- const shouldStream = config.streamingEnabled && !!onChunk;
15
- const params = {
16
- model: targetId,
17
- messages: messages,
18
- signal: signal,
19
- };
20
- // Build metadata object - only add if we have something to include
21
- if (config.sessionId ||
22
- config.conversationId ||
23
- config.a2aContextId ||
24
- config.queryTimeout) {
25
- params.metadata = {};
26
- if (config.sessionId) {
27
- params.metadata.sessionId = config.sessionId;
28
- }
29
- if (config.conversationId) {
30
- params.metadata.conversationId = config.conversationId;
31
- }
32
- if (config.queryTimeout) {
33
- params.metadata.timeout = config.queryTimeout;
34
- }
35
- // Add A2A context ID to queryAnnotations (goes to annotations)
36
- if (config.a2aContextId) {
37
- const queryAnnotations = {
38
- [QUERY_ANNOTATIONS.A2A_CONTEXT_ID]: config.a2aContextId,
39
- };
40
- params.metadata.queryAnnotations = JSON.stringify(queryAnnotations);
41
- }
11
+ const parts = targetId.split('/');
12
+ const targetType = parts[0] || 'agent';
13
+ const targetName = parts.slice(1).join('/') || targetId;
14
+ const lastUserMessage = messages.filter(m => m.role === 'user').pop();
15
+ const input = lastUserMessage?.content || '';
16
+ const annotations = {};
17
+ if (config.a2aContextId) {
18
+ annotations[QUERY_ANNOTATIONS.A2A_CONTEXT_ID] = config.a2aContextId;
42
19
  }
43
- if (shouldStream) {
44
- let fullResponse = '';
45
- const toolCallsById = new Map();
46
- const stream = this.arkApiClient.createChatCompletionStream(params);
47
- for await (const chunk of stream) {
48
- if (signal?.aborted) {
49
- break;
20
+ if (config.streamingEnabled && onChunk) {
21
+ annotations['ark.mckinsey.com/streaming-enabled'] = 'true';
22
+ }
23
+ const queryResult = await this.arkApiClient.createQuery({
24
+ input,
25
+ target: { type: targetType, name: targetName },
26
+ sessionId: config.sessionId,
27
+ conversationId: config.conversationId,
28
+ timeout: config.queryTimeout,
29
+ ...(Object.keys(annotations).length > 0
30
+ ? { metadata: { annotations } }
31
+ : {}),
32
+ });
33
+ const queryName = queryResult.name;
34
+ if (!queryName) {
35
+ throw new Error('Query creation did not return a name');
36
+ }
37
+ if (config.streamingEnabled && onChunk) {
38
+ return await this.pollStreamResponse(queryName, onChunk, signal);
39
+ }
40
+ else {
41
+ return await this.pollResponse(queryName, onChunk, signal);
42
+ }
43
+ }
44
+ async pollResponse(queryName, onChunk, signal) {
45
+ while (!signal?.aborted) {
46
+ const query = (await this.arkApiClient.getQuery(queryName));
47
+ const phase = query.status?.phase;
48
+ if (phase === 'done' || phase === 'error' || phase === 'canceled') {
49
+ const content = query.status?.response?.content || '';
50
+ let toolCalls;
51
+ if (query.status?.response?.raw) {
52
+ try {
53
+ const rawMessages = JSON.parse(query.status.response.raw);
54
+ for (const msg of rawMessages) {
55
+ if (msg.tool_calls && msg.tool_calls.length > 0) {
56
+ toolCalls = msg.tool_calls.map(tc => ({
57
+ id: tc.id,
58
+ type: 'function',
59
+ function: tc.function,
60
+ }));
61
+ }
62
+ }
63
+ }
64
+ catch {
65
+ // ignore parse errors
66
+ }
50
67
  }
51
- const delta = chunk.choices?.[0]?.delta;
52
- // Extract ARK metadata if present
53
- const arkMetadata = chunk.ark;
54
- const content = delta?.content || '';
55
- if (content) {
56
- fullResponse += content;
68
+ if (toolCalls && onChunk) {
69
+ onChunk('', toolCalls, undefined);
57
70
  }
58
- if (onChunk) {
59
- onChunk(content, undefined, arkMetadata);
71
+ if (content && onChunk) {
72
+ onChunk(content, undefined, undefined);
60
73
  }
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
- }
74
+ if (phase === 'error') {
75
+ throw new Error(content || 'Query failed');
68
76
  }
69
- // Handle tool calls
70
- if (delta?.tool_calls) {
71
- for (const toolCallDelta of delta.tool_calls) {
72
- const index = toolCallDelta.index;
73
- // Initialize tool call if this is the first chunk for this index
74
- if (!toolCallsById.has(index)) {
75
- toolCallsById.set(index, {
76
- id: toolCallDelta.id || '',
77
- type: toolCallDelta.type || 'function',
78
- function: {
79
- name: toolCallDelta.function?.name || '',
80
- arguments: '',
81
- },
82
- });
83
- }
84
- // Accumulate function arguments
85
- const toolCall = toolCallsById.get(index);
86
- if (toolCallDelta.function?.arguments) {
87
- toolCall.function.arguments += toolCallDelta.function.arguments;
77
+ return content;
78
+ }
79
+ await new Promise(resolve => setTimeout(resolve, 1000));
80
+ }
81
+ return '';
82
+ }
83
+ async pollStreamResponse(queryName, onChunk, signal) {
84
+ const baseUrl = this.arkApiClient.getBaseUrl();
85
+ const response = await fetch(`${baseUrl}/v1/broker/chunks?watch=true&query-id=${queryName}`, { signal });
86
+ if (!response.ok) {
87
+ return await this.pollResponse(queryName, onChunk, signal);
88
+ }
89
+ const reader = response.body?.getReader();
90
+ if (!reader) {
91
+ return await this.pollResponse(queryName, onChunk, signal);
92
+ }
93
+ const decoder = new TextDecoder();
94
+ let buffer = '';
95
+ let fullResponse = '';
96
+ const toolCallsById = new Map();
97
+ try {
98
+ while (true) {
99
+ const { done, value } = await reader.read();
100
+ if (done)
101
+ break;
102
+ buffer += decoder.decode(value, { stream: true });
103
+ const lines = buffer.split('\n\n');
104
+ buffer = lines.pop() || '';
105
+ for (const line of lines) {
106
+ const trimmed = line.trim();
107
+ if (!trimmed || !trimmed.startsWith('data:'))
108
+ continue;
109
+ const data = trimmed.substring(5).trim();
110
+ if (data === '[DONE]')
111
+ continue;
112
+ let chunk;
113
+ try {
114
+ chunk = JSON.parse(data);
115
+ }
116
+ catch {
117
+ continue;
118
+ }
119
+ const arkMetadata = chunk.ark;
120
+ const choices = chunk.choices;
121
+ const delta = choices?.[0]?.delta;
122
+ const content = delta?.content || '';
123
+ if (content) {
124
+ fullResponse += content;
125
+ onChunk(content, undefined, arkMetadata);
126
+ }
127
+ if (delta?.tool_calls) {
128
+ for (const tc of delta.tool_calls) {
129
+ if (!toolCallsById.has(tc.index)) {
130
+ toolCallsById.set(tc.index, {
131
+ id: tc.id || '',
132
+ type: 'function',
133
+ function: { name: tc.function?.name || '', arguments: '' },
134
+ });
135
+ }
136
+ const existing = toolCallsById.get(tc.index);
137
+ if (tc.function?.arguments) {
138
+ existing.function.arguments += tc.function.arguments;
139
+ }
140
+ onChunk('', Array.from(toolCallsById.values()), arkMetadata);
88
141
  }
89
- // Send the current state of all tool calls
90
- if (onChunk) {
91
- const toolCallsArray = Array.from(toolCallsById.values());
92
- onChunk('', toolCallsArray, arkMetadata);
142
+ }
143
+ if (!fullResponse &&
144
+ arkMetadata?.completedQuery) {
145
+ const completed = arkMetadata.completedQuery;
146
+ const responseContent = completed?.status?.response?.content;
147
+ if (responseContent) {
148
+ fullResponse = responseContent;
149
+ onChunk(responseContent, undefined, arkMetadata);
93
150
  }
94
151
  }
95
152
  }
96
153
  }
97
- return fullResponse;
98
154
  }
99
- else {
100
- const response = await this.arkApiClient.createChatCompletion(params);
101
- const message = response.choices[0]?.message;
102
- const content = message?.content || '';
103
- const arkMetadata = response.ark;
104
- // Handle tool calls in non-streaming mode
105
- if (message?.tool_calls && message.tool_calls.length > 0) {
106
- const toolCalls = message.tool_calls.map((tc) => ({
107
- id: tc.id,
108
- type: tc.type || 'function',
109
- function: {
110
- name: tc.function?.name || '',
111
- arguments: tc.function?.arguments || '',
112
- },
113
- }));
114
- // Send tool calls first
115
- if (onChunk) {
116
- onChunk('', toolCalls, arkMetadata);
117
- }
118
- }
119
- // Send content after tool calls
120
- if (content && onChunk) {
121
- onChunk(content, undefined, arkMetadata);
122
- }
123
- return content;
155
+ finally {
156
+ reader.releaseLock();
124
157
  }
158
+ return fullResponse;
125
159
  }
126
160
  }
@@ -6,7 +6,6 @@ export declare const ExitCodes: {
6
6
  readonly CliError: 1;
7
7
  readonly OperationError: 2;
8
8
  readonly Timeout: 3;
9
- readonly EvaluationFailed: 4;
10
9
  };
11
10
  export declare enum ErrorCode {
12
11
  INVALID_INPUT = "INVALID_INPUT",
@@ -8,7 +8,6 @@ export const ExitCodes = {
8
8
  CliError: 1,
9
9
  OperationError: 2,
10
10
  Timeout: 3,
11
- EvaluationFailed: 4,
12
11
  };
13
12
  export var ErrorCode;
14
13
  (function (ErrorCode) {
@@ -4,3 +4,4 @@ export declare function fetchMarketplaceManifest(): Promise<AnthropicMarketplace
4
4
  export declare function mapMarketplaceItemToArkService(item: AnthropicMarketplaceItem, registry?: string): ArkService;
5
5
  export declare function getMarketplaceServicesFromManifest(): Promise<ServiceCollection | null>;
6
6
  export declare function getMarketplaceAgentsFromManifest(): Promise<ServiceCollection | null>;
7
+ export declare function getMarketplaceExecutorsFromManifest(): Promise<ServiceCollection | null>;
@@ -78,3 +78,20 @@ export async function getMarketplaceAgentsFromManifest() {
78
78
  }
79
79
  return Object.keys(agents).length > 0 ? agents : null;
80
80
  }
81
+ export async function getMarketplaceExecutorsFromManifest() {
82
+ const manifest = await fetchMarketplaceManifest();
83
+ if (!manifest || !manifest.items) {
84
+ return null;
85
+ }
86
+ const executors = {};
87
+ for (const item of manifest.items) {
88
+ if (item.ark && item.type === 'executor') {
89
+ const executorName = item.name
90
+ .toLowerCase()
91
+ .replace(/[^a-z0-9-]/g, '-')
92
+ .replace(/^-+|-+$/g, '');
93
+ executors[executorName] = mapMarketplaceItemToArkService(item);
94
+ }
95
+ }
96
+ return Object.keys(executors).length > 0 ? executors : null;
97
+ }
@@ -136,41 +136,3 @@ export interface ClusterInfo {
136
136
  user?: string;
137
137
  namespace?: string;
138
138
  }
139
- export interface EvaluationManifest {
140
- apiVersion: string;
141
- kind: 'Evaluation';
142
- metadata: {
143
- name: string;
144
- };
145
- spec: {
146
- type: 'direct' | 'query';
147
- evaluator: {
148
- name: string;
149
- };
150
- config: {
151
- input?: string;
152
- output?: string;
153
- queryRef?: {
154
- name: string;
155
- };
156
- responseTarget?: {
157
- type: string;
158
- name: string;
159
- };
160
- };
161
- timeout?: string;
162
- ttl?: string;
163
- };
164
- }
165
- export interface EvaluationStatus {
166
- phase?: 'pending' | 'running' | 'done' | 'error';
167
- score?: string;
168
- passed?: boolean;
169
- message?: string;
170
- }
171
- export interface Evaluation {
172
- metadata: {
173
- name: string;
174
- };
175
- status?: EvaluationStatus;
176
- }
@@ -17,7 +17,12 @@ export declare function getAllMarketplaceServices(): Promise<ServiceCollection |
17
17
  */
18
18
  export declare function getAllMarketplaceAgents(): Promise<ServiceCollection | null>;
19
19
  /**
20
- * Get a marketplace item by path (supports both services and agents)
20
+ * Get all marketplace executors, fetching from marketplace.json
21
+ * Returns null if marketplace is unavailable
22
+ */
23
+ export declare function getAllMarketplaceExecutors(): Promise<ServiceCollection | null>;
24
+ /**
25
+ * Get a marketplace item by path (supports services, agents, and executors)
21
26
  * Returns null if marketplace is unavailable
22
27
  */
23
28
  export declare function getMarketplaceItem(path: string): Promise<ArkService | undefined | null>;
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Supports Anthropic Marketplace JSON format for dynamic enumeration
7
7
  */
8
- import { getMarketplaceServicesFromManifest, getMarketplaceAgentsFromManifest, } from './lib/marketplaceFetcher.js';
8
+ import { getMarketplaceServicesFromManifest, getMarketplaceAgentsFromManifest, getMarketplaceExecutorsFromManifest, } from './lib/marketplaceFetcher.js';
9
9
  /**
10
10
  * Get all marketplace services, fetching from marketplace.json
11
11
  * Returns null if marketplace is unavailable
@@ -21,7 +21,14 @@ export async function getAllMarketplaceAgents() {
21
21
  return await getMarketplaceAgentsFromManifest();
22
22
  }
23
23
  /**
24
- * Get a marketplace item by path (supports both services and agents)
24
+ * Get all marketplace executors, fetching from marketplace.json
25
+ * Returns null if marketplace is unavailable
26
+ */
27
+ export async function getAllMarketplaceExecutors() {
28
+ return await getMarketplaceExecutorsFromManifest();
29
+ }
30
+ /**
31
+ * Get a marketplace item by path (supports services, agents, and executors)
25
32
  * Returns null if marketplace is unavailable
26
33
  */
27
34
  export async function getMarketplaceItem(path) {
@@ -41,9 +48,18 @@ export async function getMarketplaceItem(path) {
41
48
  }
42
49
  return agents[name];
43
50
  }
51
+ if (path.startsWith('marketplace/executors/')) {
52
+ const name = path.replace(/^marketplace\/executors\//, '');
53
+ const executors = await getAllMarketplaceExecutors();
54
+ if (!executors) {
55
+ return null;
56
+ }
57
+ return executors[name];
58
+ }
44
59
  return undefined;
45
60
  }
46
61
  export function isMarketplaceService(name) {
47
62
  return (name.startsWith('marketplace/services/') ||
48
- name.startsWith('marketplace/agents/'));
63
+ name.startsWith('marketplace/agents/') ||
64
+ name.startsWith('marketplace/executors/'));
49
65
  }
@@ -7,6 +7,7 @@ export interface ArkService {
7
7
  helmReleaseName: string;
8
8
  description: string;
9
9
  enabled: boolean;
10
+ mandatory?: boolean;
10
11
  category: string;
11
12
  namespace?: string;
12
13
  chartPath?: string;
@@ -2,7 +2,7 @@ export interface AnthropicMarketplaceItem {
2
2
  name: string;
3
3
  displayName?: string;
4
4
  description: string;
5
- type?: 'service' | 'agent';
5
+ type?: 'service' | 'agent' | 'executor';
6
6
  version?: string;
7
7
  author?: string;
8
8
  homepage?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-at-scale/ark",
3
- "version": "0.1.55",
3
+ "version": "0.1.56",
4
4
  "description": "Ark CLI - Interactive terminal interface for ARK agents",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -58,8 +58,8 @@
58
58
  "marked": "^15.0.12",
59
59
  "marked-terminal": "^7.3.0",
60
60
  "open": "^10.2.0",
61
- "openai": "^5.19.1",
62
61
  "ora": "^8.2.0",
62
+ "picomatch": "4.0.4",
63
63
  "react": "^19.1.5",
64
64
  "yaml": "^2.6.1"
65
65
  },
@@ -87,6 +87,8 @@
87
87
  "overrides": {
88
88
  "minimatch": "^10.2.3",
89
89
  "rollup": "4.59.0",
90
- "hono": "^4.12.2"
90
+ "hono": "^4.12.4",
91
+ "@hono/node-server": "^1.19.10",
92
+ "flatted": "^3.4.2"
91
93
  }
92
94
  }
@@ -5,13 +5,13 @@
5
5
  {
6
6
  "name": "phoenix",
7
7
  "displayName": "Phoenix",
8
- "description": "AI/ML observability and evaluation platform with OpenTelemetry integration",
8
+ "description": "AI/ML observability platform with OpenTelemetry integration",
9
9
  "version": "0.1.5",
10
10
  "author": "ARK Marketplace",
11
11
  "homepage": "https://github.com/mckinsey/agents-at-scale-marketplace",
12
12
  "repository": "https://github.com/mckinsey/agents-at-scale-marketplace",
13
13
  "license": "Apache-2.0",
14
- "tags": ["observability", "evaluation", "telemetry", "monitoring"],
14
+ "tags": ["observability", "telemetry", "monitoring"],
15
15
  "category": "observability",
16
16
  "icon": "https://example.com/phoenix-icon.png",
17
17
  "documentation": "https://mckinsey.github.io/agents-at-scale-marketplace/services/phoenix/",