langmart-gateway-type3 3.0.41 → 3.0.43

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.
@@ -3,27 +3,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MarketplaceTools = void 0;
6
+ exports.RegistryTools = void 0;
7
7
  const debug_utils_1 = require("./debug-utils");
8
8
  /**
9
- * Marketplace Tools - Built-in MCP Tools for LangMart Self-Hosted Gateway CLI
9
+ * Registry Tools - Built-in MCP Tools for LangMart Self-Hosted Gateway CLI
10
10
  *
11
- * Provides AI assistant with tools to manage marketplace connections,
11
+ * Provides AI assistant with tools to manage registry connections,
12
12
  * providers, and models through natural language conversation.
13
13
  *
14
- * These tools call LangMart Marketplace API endpoints.
14
+ * These tools call LangMart Registry API endpoints.
15
15
  */
16
16
  const axios_1 = __importDefault(require("axios"));
17
- class MarketplaceTools {
18
- constructor(marketplaceUrl, apiKey, managementUrl = 'http://localhost:8083', keyVault) {
17
+ class RegistryTools {
18
+ constructor(registryUrl, apiKey, managementUrl = 'http://localhost:8083', keyVault) {
19
19
  this.connectionMap = new Map(); // sequence number → UUID mapping
20
20
  this.providerMap = new Map(); // sequence number → UUID mapping
21
- this.marketplaceUrl = marketplaceUrl;
21
+ this.registryUrl = registryUrl;
22
22
  this.apiKey = apiKey;
23
23
  this.managementUrl = managementUrl;
24
24
  this.keyVault = keyVault;
25
25
  this.client = axios_1.default.create({
26
- baseURL: marketplaceUrl,
26
+ baseURL: registryUrl,
27
27
  timeout: 30000,
28
28
  maxRedirects: 0, // Don't follow redirects
29
29
  validateStatus: (status) => status < 500, // Accept any non-5xx response
@@ -32,16 +32,16 @@ class MarketplaceTools {
32
32
  'Content-Type': 'application/json'
33
33
  }
34
34
  });
35
- (0, debug_utils_1.debugLog)(`[MarketplaceTools] Initialized with baseURL: ${marketplaceUrl}`);
35
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Initialized with baseURL: ${registryUrl}`);
36
36
  }
37
- static getInstance(marketplaceUrl, apiKey, managementUrl, keyVault) {
38
- if (!MarketplaceTools.instance && marketplaceUrl && apiKey && keyVault) {
39
- MarketplaceTools.instance = new MarketplaceTools(marketplaceUrl, apiKey, managementUrl || 'http://localhost:8083', keyVault);
37
+ static getInstance(registryUrl, apiKey, managementUrl, keyVault) {
38
+ if (!RegistryTools.instance && registryUrl && apiKey && keyVault) {
39
+ RegistryTools.instance = new RegistryTools(registryUrl, apiKey, managementUrl || 'http://localhost:8083', keyVault);
40
40
  }
41
- if (!MarketplaceTools.instance) {
42
- throw new Error('MarketplaceTools not initialized. Provide marketplaceUrl, apiKey, and keyVault.');
41
+ if (!RegistryTools.instance) {
42
+ throw new Error('RegistryTools not initialized. Provide registryUrl, apiKey, and keyVault.');
43
43
  }
44
- return MarketplaceTools.instance;
44
+ return RegistryTools.instance;
45
45
  }
46
46
  /**
47
47
  * Get tool definitions for AI
@@ -51,8 +51,8 @@ class MarketplaceTools {
51
51
  {
52
52
  type: 'function',
53
53
  function: {
54
- name: 'marketplace.connections.list',
55
- description: 'List all user connections from the marketplace. Shows provider, endpoint type, gateway type (Managed/Self-hosted), and status for each connection. Connections are numbered [1], [2], [3], etc. in order of creation. No parameters required - call this tool directly when user asks to list, show, or see connections. You can use the connection numbers in subsequent tool calls (e.g., marketplace.connections.test with connection_id "1").',
54
+ name: 'registry_connections_list',
55
+ description: 'List all user connections from the registry. Shows provider, endpoint type, gateway type (Managed/Self-hosted), and status for each connection. Connections are numbered [1], [2], [3], etc. in order of creation. No parameters required - call this tool directly when user asks to list, show, or see connections. You can use the connection numbers in subsequent tool calls (e.g., registry_connections_test with connection_id "1").',
56
56
  parameters: {
57
57
  type: 'object',
58
58
  properties: {},
@@ -63,8 +63,8 @@ class MarketplaceTools {
63
63
  {
64
64
  type: 'function',
65
65
  function: {
66
- name: 'marketplace.connections.add',
67
- description: 'Add a new connection to the marketplace. Creates a connection to an LLM provider (OpenAI, Anthropic, Groq, Ollama, etc.) with specified API key and gateway type. The endpoint_type (protocol translator) is automatically determined from the provider - do NOT ask the user for it. Ask the user for: display name, provider name (must match a provider from marketplace.providers.list), API key, endpoint URL, and gateway type. Marketplace-Managed Compute (Type 2): marketplace stores encrypted API keys and manages gateway - convenient but requires trust. Provider API must be accessible from marketplace network (cloud). Self-Hosted Compute (Type 3): you run local gateway and store API keys in local vault - full control over credentials. Provider API must be accessible from YOUR network (can access localhost/private IPs). Both types work with ANY provider. IMPORTANT: After adding the connection, show the tool result directly to the user with the connection details and ask what they want to do next (test, discover models, update, or remove). DO NOT automatically call marketplace.providers.list or marketplace.models.discover - let the user decide.',
66
+ name: 'registry_connections_add',
67
+ description: 'Add a new connection to the registry. Creates a connection to an LLM provider (OpenAI, Anthropic, Groq, Ollama, etc.) with specified API key and gateway type. The endpoint_type (protocol translator) is automatically determined from the provider - do NOT ask the user for it. Ask the user for: display name, provider name (must match a provider from registry_providers_list), API key, endpoint URL, and gateway type. Registry-Managed Compute (Type 2): registry stores encrypted API keys and manages gateway - convenient but requires trust. Provider API must be accessible from registry network (cloud). Self-Hosted Compute (Type 3): you run local gateway and store API keys in local vault - full control over credentials. Provider API must be accessible from YOUR network (can access localhost/private IPs). Both types work with ANY provider. IMPORTANT: After adding the connection, show the tool result directly to the user with the connection details and ask what they want to do next (test, discover models, update, or remove). DO NOT automatically call registry_providers_list or registry_models_discover - let the user decide.',
68
68
  parameters: {
69
69
  type: 'object',
70
70
  properties: {
@@ -74,7 +74,7 @@ class MarketplaceTools {
74
74
  },
75
75
  provider_name: {
76
76
  type: 'string',
77
- description: 'Provider key from marketplace.providers.list: "anthropic", "openai", "groq", "google", "ollama", etc. IMPORTANT: Use marketplace.providers.list first to see available providers and their keys.'
77
+ description: 'Provider key from registry_providers_list: "anthropic", "openai", "groq", "google", "ollama", etc. IMPORTANT: Use registry_providers_list first to see available providers and their keys.'
78
78
  },
79
79
  endpoint_url: {
80
80
  type: 'string',
@@ -86,7 +86,7 @@ class MarketplaceTools {
86
86
  },
87
87
  gateway_type: {
88
88
  type: 'number',
89
- description: 'Gateway type: 2 (Marketplace-Managed Compute - marketplace stores API keys, provider must be reachable from marketplace network), 3 (Self-Hosted Compute - you store API keys locally, provider must be reachable from YOUR network, can access localhost). Both work with ANY provider (OpenAI, Anthropic, Groq, Ollama, etc.)'
89
+ description: 'Gateway type: 2 (Registry-Managed Compute - registry stores API keys, provider must be reachable from registry network), 3 (Self-Hosted Compute - you store API keys locally, provider must be reachable from YOUR network, can access localhost). Both work with ANY provider (OpenAI, Anthropic, Groq, Ollama, etc.)'
90
90
  }
91
91
  },
92
92
  required: ['name', 'provider_name', 'endpoint_url', 'api_key', 'gateway_type']
@@ -96,8 +96,8 @@ class MarketplaceTools {
96
96
  {
97
97
  type: 'function',
98
98
  function: {
99
- name: 'marketplace.connections.remove',
100
- description: 'Remove a connection from the marketplace (soft delete). IMPORTANT: You can use EITHER a sequence number (1, 2, 3) OR a UUID. If the user says "remove 1" or "remove connection 1", use connection_id: "1" - the tool will automatically resolve it. If the user does not provide any identifier, ask which connection they want to remove.',
99
+ name: 'registry_connections_remove',
100
+ description: 'Remove a connection from the registry (soft delete). IMPORTANT: You can use EITHER a sequence number (1, 2, 3) OR a UUID. If the user says "remove 1" or "remove connection 1", use connection_id: "1" - the tool will automatically resolve it. If the user does not provide any identifier, ask which connection they want to remove.',
101
101
  parameters: {
102
102
  type: 'object',
103
103
  properties: {
@@ -113,8 +113,8 @@ class MarketplaceTools {
113
113
  {
114
114
  type: 'function',
115
115
  function: {
116
- name: 'marketplace.connections.test',
117
- description: 'Test a connection to verify API key and endpoint are working. Works for BOTH Marketplace-Managed Compute and Self-Hosted Compute connections. For Self-Hosted connections, the test is automatically routed to your local gateway instance. IMPORTANT: You can use EITHER a sequence number (1, 2, 3) OR a UUID. If the user says "test 1" or "test connection 1", use connection_id: "1" - the tool will automatically resolve it. If user provides just "test connection" without any number, ask which connection they want to test.',
116
+ name: 'registry_connections_test',
117
+ description: 'Test a connection to verify API key and endpoint are working. Works for BOTH Registry-Managed Compute and Self-Hosted Compute connections. For Self-Hosted connections, the test is automatically routed to your local gateway instance. IMPORTANT: You can use EITHER a sequence number (1, 2, 3) OR a UUID. If the user says "test 1" or "test connection 1", use connection_id: "1" - the tool will automatically resolve it. If user provides just "test connection" without any number, ask which connection they want to test.',
118
118
  parameters: {
119
119
  type: 'object',
120
120
  properties: {
@@ -130,7 +130,7 @@ class MarketplaceTools {
130
130
  {
131
131
  type: 'function',
132
132
  function: {
133
- name: 'marketplace.connections.updateKey',
133
+ name: 'registry_connections_update_key',
134
134
  description: 'Update the API key for an existing connection. IMPORTANT: You can use EITHER a sequence number (1, 2, 3) OR a UUID for the connection. If the user says "update key for connection 1", use connection_id: "1" - the tool will automatically resolve it. Always ask the user for the new API key if not provided.',
135
135
  parameters: {
136
136
  type: 'object',
@@ -151,8 +151,8 @@ class MarketplaceTools {
151
151
  {
152
152
  type: 'function',
153
153
  function: {
154
- name: 'marketplace.providers.list',
155
- description: 'List all available LLM providers in the marketplace. Shows provider names, base URLs, and active status. No parameters required - call this tool directly when user asks to list, show, or see available providers. IMPORTANT: After displaying the provider list, ALWAYS ask the user: "Would you like to add a connection to any of these providers?" Explain that they will need: (1) Provider API key from the provider, (2) Display name for the connection, (3) Gateway type: Marketplace-Managed Compute (provider must be internet-accessible from marketplace) or Self-Hosted Compute (provider can be on your local network, including localhost). Then use marketplace.connections.add to create the connection. Wait for user response.',
154
+ name: 'registry_providers_list',
155
+ description: 'List all available LLM providers in the registry. Shows provider names, base URLs, and active status. No parameters required - call this tool directly when user asks to list, show, or see available providers. IMPORTANT: After displaying the provider list, ALWAYS ask the user: "Would you like to add a connection to any of these providers?" Explain that they will need: (1) Provider API key from the provider, (2) Display name for the connection, (3) Gateway type: Registry-Managed Compute (provider must be internet-accessible from registry) or Self-Hosted Compute (provider can be on your local network, including localhost). Then use registry_connections_add to create the connection. Wait for user response.',
156
156
  parameters: {
157
157
  type: 'object',
158
158
  properties: {},
@@ -163,14 +163,14 @@ class MarketplaceTools {
163
163
  {
164
164
  type: 'function',
165
165
  function: {
166
- name: 'marketplace.models.discover',
167
- description: 'Discover and store models from a provider. Fetches available models from the provider API and adds them to the marketplace. IMPORTANT: This requires detailed provider information. If the user wants to discover models from an existing connection, first call marketplace.connections.list to get the connection details (provider, endpoint_url, endpoint_type, gateway_type), then ask the user for their API key. If user wants to discover from a new provider, ask them for: provider name, API key, endpoint URL, endpoint type, and gateway type (2 for Marketplace-Managed Compute - provider must be internet-accessible, 3 for Self-Hosted Compute - provider can be on local network).',
166
+ name: 'registry_models_discover',
167
+ description: 'Discover and store models from a provider. Fetches available models from the provider API and adds them to the registry. IMPORTANT: This requires detailed provider information. If the user wants to discover models from an existing connection, first call registry_connections_list to get the connection details (provider, endpoint_url, endpoint_type, gateway_type), then ask the user for their API key. If user wants to discover from a new provider, ask them for: provider name, API key, endpoint URL, endpoint type, and gateway type (2 for Registry-Managed Compute - provider must be internet-accessible, 3 for Self-Hosted Compute - provider can be on local network).',
168
168
  parameters: {
169
169
  type: 'object',
170
170
  properties: {
171
171
  provider: {
172
172
  type: 'string',
173
- description: 'Provider key (e.g., "groq", "openai", "anthropic"). Use marketplace.providers.list to see available providers.'
173
+ description: 'Provider key (e.g., "groq", "openai", "anthropic"). Use registry_providers_list to see available providers.'
174
174
  },
175
175
  apiKey: {
176
176
  type: 'string',
@@ -178,7 +178,7 @@ class MarketplaceTools {
178
178
  },
179
179
  gatewayType: {
180
180
  type: 'number',
181
- description: 'Gateway type: 2 (Marketplace-Managed Compute - provider must be internet-accessible from marketplace), 3 (Self-Hosted Compute - provider can be on local network, localhost accessible). Both work with ANY provider.'
181
+ description: 'Gateway type: 2 (Registry-Managed Compute - provider must be internet-accessible from registry), 3 (Self-Hosted Compute - provider can be on local network, localhost accessible). Both work with ANY provider.'
182
182
  },
183
183
  endpointUrl: {
184
184
  type: 'string',
@@ -196,7 +196,7 @@ class MarketplaceTools {
196
196
  {
197
197
  type: 'function',
198
198
  function: {
199
- name: 'marketplace.models.list',
199
+ name: 'registry_models_list',
200
200
  description: 'List and filter available models for the user with pagination. Shows model names, providers, context windows, pricing, and capabilities. Supports filtering by publication status (public/private), price range, provider, keyword search, capabilities, and context window.\n\n**Filter behavior (same as UI tab filter):**\n- Space-separated keywords use AND condition (all must match)\n- Matches against model_id and model_name\n- Example: "groq llama" matches models containing BOTH "groq" AND "llama"\n\nUse filters when user asks for specific model types (e.g., "cheap models", "vision models", "Groq models", "published models", "private models", "models with 100k+ context"). Pagination defaults to 10 models per page - use offset to get next pages. HELPFUL TIP: After showing models, explain that they can use these models for chat by selecting them with Tab or /model command.',
201
201
  parameters: {
202
202
  type: 'object',
@@ -215,11 +215,11 @@ class MarketplaceTools {
215
215
  },
216
216
  access_level: {
217
217
  type: 'string',
218
- description: 'Filter by publication status. Options: "public" (published models available to all marketplace users), "private" (unpublished models only visible to owner). Omit to see all models (both public and private). Example: use "public" to list only published models.'
218
+ description: 'Filter by publication status. Options: "public" (published models available to all registry users), "private" (unpublished models only visible to owner). Omit to see all models (both public and private). Example: use "public" to list only published models.'
219
219
  },
220
220
  provider: {
221
221
  type: 'string',
222
- description: 'Filter by provider name (case-insensitive). Example: "groq", "openai", "anthropic", "google". Use marketplace.providers.list to see available providers.'
222
+ description: 'Filter by provider name (case-insensitive). Example: "groq", "openai", "anthropic", "google". Use registry_providers_list to see available providers.'
223
223
  },
224
224
  max_input_price: {
225
225
  type: 'number',
@@ -269,14 +269,14 @@ class MarketplaceTools {
269
269
  {
270
270
  type: 'function',
271
271
  function: {
272
- name: 'marketplace.models.updateCapabilities',
272
+ name: 'registry_models_update_capabilities',
273
273
  description: 'Update capability flags for a model. Allows setting vision support, reasoning capability, tool/function calling, image generation, video generation, audio processing, and embedding capabilities. Use when user wants to update or configure what their model can do. Each capability is a boolean flag. IMPORTANT: Only the model owner can update capabilities.',
274
274
  parameters: {
275
275
  type: 'object',
276
276
  properties: {
277
277
  model_id: {
278
278
  type: 'string',
279
- description: 'Model ID (e.g., "groq/llama-3.3-70b-versatile"). Use marketplace.models.list to get model IDs.'
279
+ description: 'Model ID (e.g., "groq/llama-3.3-70b-versatile"). Use registry_models_list to get model IDs.'
280
280
  },
281
281
  supports_vision: {
282
282
  type: 'boolean',
@@ -314,14 +314,14 @@ class MarketplaceTools {
314
314
  {
315
315
  type: 'function',
316
316
  function: {
317
- name: 'marketplace.models.get',
317
+ name: 'registry_models_get',
318
318
  description: 'Get detailed information about a specific model including pricing and capabilities. Returns model name, display name, provider, context window, input/output pricing per million tokens, and all capability flags (vision, reasoning, tool_use, etc.). Use when user asks for details about a specific model, its price, or what it can do.',
319
319
  parameters: {
320
320
  type: 'object',
321
321
  properties: {
322
322
  model_id: {
323
323
  type: 'string',
324
- description: 'Model identifier (e.g., "groq/llama-3.3-70b-versatile", "google/gemini-2.5-flash"). Use marketplace.models.list to find available model IDs.'
324
+ description: 'Model identifier (e.g., "groq/llama-3.3-70b-versatile", "google/gemini-2.5-flash"). Use registry_models_list to find available model IDs.'
325
325
  }
326
326
  },
327
327
  required: ['model_id']
@@ -331,7 +331,7 @@ class MarketplaceTools {
331
331
  {
332
332
  type: 'function',
333
333
  function: {
334
- name: 'marketplace.requestLogs.list',
334
+ name: 'registry_request_logs_list',
335
335
  description: 'Query user\'s request logs with pagination and filtering. Shows recent API requests including method, endpoint, status code, model used, IP address, and timestamp. Use this to debug issues, view usage history, or find specific requests. Each log has an x-request-id for tracking. Supports filtering by status code, endpoint path, and model name. Call when user asks to see logs, requests, history, or wants to debug an issue.',
336
336
  parameters: {
337
337
  type: 'object',
@@ -364,14 +364,14 @@ class MarketplaceTools {
364
364
  {
365
365
  type: 'function',
366
366
  function: {
367
- name: 'marketplace.requestLogs.get',
368
- description: 'Get detailed log entry by ID including full request/response bodies, headers, status codes, and timing information. Useful for debugging specific failed requests. The log ID can be found from requestLogs.list or from the x-request-id response header. Sensitive data (API keys, auth tokens) are automatically redacted. Body content is truncated by default for readability - use show_full_body to see complete content.',
367
+ name: 'registry_request_logs_get',
368
+ description: 'Get detailed log entry by ID including full request/response bodies, headers, status codes, and timing information. Useful for debugging specific failed requests. The log ID can be found from request_logs_list or from the x-request-id response header. Sensitive data (API keys, auth tokens) are automatically redacted. Body content is truncated by default for readability - use show_full_body to see complete content.',
369
369
  parameters: {
370
370
  type: 'object',
371
371
  properties: {
372
372
  log_id: {
373
373
  type: 'string',
374
- description: 'Log ID (UUID) from requestLogs.list or x-request-id header'
374
+ description: 'Log ID (UUID) from request_logs_list or x-request-id header'
375
375
  },
376
376
  show_full_body: {
377
377
  type: 'boolean',
@@ -385,7 +385,7 @@ class MarketplaceTools {
385
385
  {
386
386
  type: 'function',
387
387
  function: {
388
- name: 'marketplace.requestLogs.stats',
388
+ name: 'registry_request_logs_stats',
389
389
  description: 'Get aggregated statistics about user\'s API usage. Shows total requests, success rate, top models used, top endpoints, and daily request counts. Use this for usage analytics, monitoring, or understanding request patterns. No parameters required.',
390
390
  parameters: {
391
391
  type: 'object',
@@ -406,7 +406,7 @@ class MarketplaceTools {
406
406
  {
407
407
  type: 'function',
408
408
  function: {
409
- name: 'marketplace.vault.status',
409
+ name: 'registry_vault_status',
410
410
  description: 'Get comprehensive vault status showing LocalVault (persistent encrypted storage) and KeyVault (in-memory protection). Returns pre-formatted text with box-drawing characters. IMPORTANT: Display the output exactly as received - do not summarize or reformat. Use when user asks about vault, credentials, or security.',
411
411
  parameters: {
412
412
  type: 'object',
@@ -418,7 +418,7 @@ class MarketplaceTools {
418
418
  {
419
419
  type: 'function',
420
420
  function: {
421
- name: 'marketplace.vault.localvault',
421
+ name: 'registry_vault_localvault',
422
422
  description: 'List all credentials in LocalVault (persistent encrypted storage at ~/.langmart/keystore.enc). Returns pre-formatted text. IMPORTANT: Display output exactly as received - do not summarize. Use when user asks about stored credentials.',
423
423
  parameters: {
424
424
  type: 'object',
@@ -430,7 +430,7 @@ class MarketplaceTools {
430
430
  {
431
431
  type: 'function',
432
432
  function: {
433
- name: 'marketplace.vault.keyvault',
433
+ name: 'registry_vault_keyvault',
434
434
  description: 'Show KeyVault status (in-memory chat protection that redacts API keys from LLM messages). Returns pre-formatted text. IMPORTANT: Display output exactly as received. Use when user asks about key protection or redaction.',
435
435
  parameters: {
436
436
  type: 'object',
@@ -442,8 +442,8 @@ class MarketplaceTools {
442
442
  {
443
443
  type: 'function',
444
444
  function: {
445
- name: 'marketplace.connections.quota.manage',
446
- description: 'Set or update sales quota limits for a connection. Quota applies to ALL models under the connection and tracks total consumption (owner usage + published model sales). Daily quota resets at midnight UTC, monthly resets on 1st. When quota exceeded, all models auto-disable. Can enable/disable enforcement. Use connection_id from marketplace.connections.list.',
445
+ name: 'registry_connections_quota_manage',
446
+ description: 'Set or update sales quota limits for a connection. Quota applies to ALL models under the connection and tracks total consumption (owner usage + published model sales). Daily quota resets at midnight UTC, monthly resets on 1st. When quota exceeded, all models auto-disable. Can enable/disable enforcement. Use connection_id from registry_connections_list.',
447
447
  parameters: {
448
448
  type: 'object',
449
449
  properties: {
@@ -471,8 +471,8 @@ class MarketplaceTools {
471
471
  {
472
472
  type: 'function',
473
473
  function: {
474
- name: 'marketplace.connections.quota.get',
475
- description: 'Get current quota status and usage for a specific connection. Shows daily/monthly limits, current consumption, percentage used, quota exceeded status, affected models count, and usage history (last 30 days). Use connection_id from marketplace.connections.list.',
474
+ name: 'registry_connections_quota_get',
475
+ description: 'Get current quota status and usage for a specific connection. Shows daily/monthly limits, current consumption, percentage used, quota exceeded status, affected models count, and usage history (last 30 days). Use connection_id from registry_connections_list.',
476
476
  parameters: {
477
477
  type: 'object',
478
478
  properties: {
@@ -488,7 +488,7 @@ class MarketplaceTools {
488
488
  {
489
489
  type: 'function',
490
490
  function: {
491
- name: 'marketplace.connections.quota.list',
491
+ name: 'registry_connections_quota_list',
492
492
  description: 'List quota status for all connections owned by the user. Shows quota settings, current usage, and enforcement status for each connection. Useful for getting an overview of quota usage across all provider connections.',
493
493
  parameters: {
494
494
  type: 'object',
@@ -500,14 +500,14 @@ class MarketplaceTools {
500
500
  {
501
501
  type: 'function',
502
502
  function: {
503
- name: 'marketplace.models.updatePricing',
504
- description: 'Update pricing for one or multiple models using filter-based selection. Supports both single model updates and bulk operations.\n\n**TWO PRICING METHODS:**\n1. Exact Price: Set specific prices with input_tokens_per_1k and output_tokens_per_1k\n2. Percentage Adjustment: Increase/decrease current prices by percentage\n\n**TWO TARGET MODES:**\n1. Single Model: Provide model_id to update one model\n2. Bulk Mode: Provide filter (space-separated keywords) to update multiple models using AND-condition matching\n\n**PERCENTAGE EXAMPLES:**\n- "increase all groq models by 10%" → filter="groq", increase_percentage=10\n- "decrease all llama models by 15%" → filter="llama", decrease_percentage=15\n- "increase my published models by 20%" → filter="", source_access_level="public", increase_percentage=20\n- "increase all image models by 10%" → filter="image", increase_percentage=10\n\n**BULK UPDATE WORKFLOW:**\n- Default (auto_confirm: false): Shows matched models, asks for confirmation\n- With auto_confirm: true: Immediately updates all matched models\n- Use source_access_level to pre-filter by publication status\n\n**ENHANCED FILTER LOGIC:**\n- Space-separated keywords use AND condition (all must match)\n- Matches against model_id, model_name, provider name, AND capabilities\n- Capability keywords: image, vision, tool, reasoning, audio, video, embedding\n- Example: "groq llama" matches models with BOTH keywords\n- Example: "image" matches all models with vision or image generation capability\n- Example: "google tool" matches Google models with tool use capability\n\nOnly model owners can update pricing. Use marketplace.models.list to find model IDs.',
503
+ name: 'registry_models_update_pricing',
504
+ description: 'Update pricing for one or multiple models using filter-based selection. Supports both single model updates and bulk operations.\n\n**TWO PRICING METHODS:**\n1. Exact Price: Set specific prices with input_tokens_per_1k and output_tokens_per_1k\n2. Percentage Adjustment: Increase/decrease current prices by percentage\n\n**TWO TARGET MODES:**\n1. Single Model: Provide model_id to update one model\n2. Bulk Mode: Provide filter (space-separated keywords) to update multiple models using AND-condition matching\n\n**PERCENTAGE EXAMPLES:**\n- "increase all groq models by 10%" → filter="groq", increase_percentage=10\n- "decrease all llama models by 15%" → filter="llama", decrease_percentage=15\n- "increase my published models by 20%" → filter="", source_access_level="public", increase_percentage=20\n- "increase all image models by 10%" → filter="image", increase_percentage=10\n\n**BULK UPDATE WORKFLOW:**\n- Default (auto_confirm: false): Shows matched models, asks for confirmation\n- With auto_confirm: true: Immediately updates all matched models\n- Use source_access_level to pre-filter by publication status\n\n**ENHANCED FILTER LOGIC:**\n- Space-separated keywords use AND condition (all must match)\n- Matches against model_id, model_name, provider name, AND capabilities\n- Capability keywords: image, vision, tool, reasoning, audio, video, embedding\n- Example: "groq llama" matches models with BOTH keywords\n- Example: "image" matches all models with vision or image generation capability\n- Example: "google tool" matches Google models with tool use capability\n\nOnly model owners can update pricing. Use registry_models_list to find model IDs.',
505
505
  parameters: {
506
506
  type: 'object',
507
507
  properties: {
508
508
  model_id: {
509
509
  type: 'string',
510
- description: 'Single model UUID from marketplace.models.list (the id field, NOT model_id field). Mutually exclusive with filter. Use for single model updates.'
510
+ description: 'Single model UUID from registry_models_list (the id field, NOT model_id field). Mutually exclusive with filter. Use for single model updates.'
511
511
  },
512
512
  filter: {
513
513
  type: 'string',
@@ -554,36 +554,109 @@ class MarketplaceTools {
554
554
  {
555
555
  type: 'function',
556
556
  function: {
557
- name: 'marketplace.models.publish',
558
- description: 'Publish or unpublish models by setting access level. Supports BOTH single model (by UUID) and bulk operations (by filter).\n\n**Two modes:**\n1. Single model: Provide `model_id` (UUID from marketplace.models.list)\n2. Bulk operation: Provide `filter` (space-separated keywords, same as UI filter)\n\n**IMPORTANT - Automatic filtering logic:**\n- When unpublishing (`access_level: "private"`): Automatically searches only your PUBLIC models\n- When publishing (`access_level: "public"`): Automatically searches only your PRIVATE models\n- When disabling (`access_level: "disabled"`): Searches all your models\n\n**Filter behavior:**\n- Space-separated keywords use AND condition (all must match)\n- Matches against model_id and model_name\n- Example: "groq llama" matches models containing BOTH "groq" AND "llama"\n\n**Confirmation:**\n- `auto_confirm: false` (default): Shows matched models, asks user to confirm\n- `auto_confirm: true`: Immediately updates all matched models\n\n**Access levels:**\n- "public": Available to all users in marketplace (publish)\n- "private": Only owner can use (delist/unpublish)\n- "disabled": Not available to anyone',
557
+ name: 'registry_models_update_billing',
558
+ description: 'Update billing settings for organization models (org admin only). Sets how model usage costs are handled within the organization.\n\n**Billing modes:**\n- "org_pays": Organization pays for all usage (members use for free)\n- "member_pays": Members pay from their own credits (org can set fee %)\n\n**Org fee:**\n- Only applies when billing_mode is "member_pays"\n- Percentage (0-100) added to model cost as org fee\n- Example: 10 = 10% fee on top of model cost\n\n**Pricing (optional):**\n- Override default model pricing if needed\n- Set input_per_1k and output_per_1k in USD\n\n**Requirements:**\n- Must be org admin or owner\n- Model must be organization-level (not private/public)',
559
559
  parameters: {
560
560
  type: 'object',
561
561
  properties: {
562
562
  model_id: {
563
563
  type: 'string',
564
- description: 'Single model UUID from marketplace.models.list (the "id" field). Use this for single model update. Mutually exclusive with filter. Format: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"'
564
+ description: 'Model UUID from registry_models_list (the "id" field). Required.'
565
565
  },
566
- filter: {
566
+ billing_mode: {
567
567
  type: 'string',
568
- description: 'Filter keywords for bulk operation (space-separated, AND condition). Example: "groq llama" matches models with BOTH keywords. Mutually exclusive with model_id. IMPORTANT: Tool automatically filters by correct source access level (public models when unpublishing, private models when publishing).'
568
+ enum: ['org_pays', 'member_pays'],
569
+ description: 'How usage costs are handled: "org_pays" (org covers all costs) or "member_pays" (member pays from their credits)'
569
570
  },
570
- access_level: {
571
+ org_fee_percentage: {
572
+ type: 'number',
573
+ description: 'Fee percentage for member_pays mode (0-100). Ignored for org_pays mode.'
574
+ },
575
+ input_per_1k: {
576
+ type: 'number',
577
+ description: 'Optional: Override price per 1000 input tokens in USD'
578
+ },
579
+ output_per_1k: {
580
+ type: 'number',
581
+ description: 'Optional: Override price per 1000 output tokens in USD'
582
+ }
583
+ },
584
+ required: ['model_id', 'billing_mode']
585
+ }
586
+ }
587
+ },
588
+ {
589
+ type: 'function',
590
+ function: {
591
+ name: 'registry_models_update_visibility',
592
+ description: 'Update visibility for organization models (org admin only). Controls whether org members can see and use the model.\n\n**Visibility:**\n- true: Model is visible and usable by org members\n- false: Model is hidden from org members (admin can still see)\n\n**Requirements:**\n- Must be org admin or owner\n- Model must be organization-level (not private/public)\n\n**Note:** For individual (private) models, owners always have full access. This tool is only for org admins to control org-wide model visibility.',
593
+ parameters: {
594
+ type: 'object',
595
+ properties: {
596
+ model_id: {
571
597
  type: 'string',
572
- description: 'Target access level: "public" (publish to marketplace), "private" (delist/unpublish), "disabled" (completely unavailable)',
573
- enum: ['public', 'private', 'disabled']
598
+ description: 'Model UUID from registry_models_list (the "id" field). Required.'
574
599
  },
575
- auto_confirm: {
600
+ is_available: {
576
601
  type: 'boolean',
577
- description: 'If true, skip confirmation and immediately update all matched models. If false (default), show matched models and ask user to confirm first. Default: false',
578
- default: false
579
- },
580
- source_access_level: {
602
+ description: 'true = visible to org members, false = hidden from org members'
603
+ }
604
+ },
605
+ required: ['model_id', 'is_available']
606
+ }
607
+ }
608
+ },
609
+ // ========================================================================
610
+ // WORKFLOW QUERY TOOLS - For agents to query workflow execution state
611
+ // ========================================================================
612
+ {
613
+ type: 'function',
614
+ function: {
615
+ name: 'workflow_get_status',
616
+ description: 'Get the overall status of a workflow execution by trace ID. Returns the workflow name, overall status (pending/running/completed/failed), start time, completion time, and progress summary. Use this to check if the workflow is still running or has completed.',
617
+ parameters: {
618
+ type: 'object',
619
+ properties: {
620
+ trace_id: {
621
+ type: 'string',
622
+ description: 'The trace ID of the workflow execution. This is provided in your system prompt as "Trace ID".'
623
+ }
624
+ },
625
+ required: ['trace_id']
626
+ }
627
+ }
628
+ },
629
+ {
630
+ type: 'function',
631
+ function: {
632
+ name: 'workflow_list_instances',
633
+ description: 'List all agent instances in a workflow execution. Shows each agent\'s name, role (START/AGENT/END), execution order, status, and any error messages. Use this to see what other agents are in your workflow and their current status.',
634
+ parameters: {
635
+ type: 'object',
636
+ properties: {
637
+ trace_id: {
638
+ type: 'string',
639
+ description: 'The trace ID of the workflow execution. This is provided in your system prompt as "Trace ID".'
640
+ }
641
+ },
642
+ required: ['trace_id']
643
+ }
644
+ }
645
+ },
646
+ {
647
+ type: 'function',
648
+ function: {
649
+ name: 'workflow_get_instance_output',
650
+ description: 'Get the output from a specific agent instance in the workflow. Returns the agent\'s response/output from its most recent session. Use this to retrieve results from agents that have already completed.',
651
+ parameters: {
652
+ type: 'object',
653
+ properties: {
654
+ instance_id: {
581
655
  type: 'string',
582
- description: 'OPTIONAL: Override automatic source filtering. Leave empty to use automatic logic (recommended). Only use if you need to override default behavior.',
583
- enum: ['public', 'private', 'disabled']
656
+ description: 'The instance ID of the agent. Get instance IDs from workflow_list_instances.'
584
657
  }
585
658
  },
586
- required: ['access_level']
659
+ required: ['instance_id']
587
660
  }
588
661
  }
589
662
  }
@@ -610,53 +683,62 @@ class MarketplaceTools {
610
683
  return tools.map(formatTool).join('\n\n');
611
684
  }
612
685
  /**
613
- * Execute a marketplace tool
686
+ * Execute a registry tool
614
687
  */
615
688
  async executeTool(toolName, args) {
616
689
  try {
617
690
  switch (toolName) {
618
- case 'marketplace.connections.list':
691
+ case 'registry_connections_list':
619
692
  return await this.listConnections();
620
- case 'marketplace.connections.add':
693
+ case 'registry_connections_add':
621
694
  return await this.addConnection(args);
622
- case 'marketplace.connections.remove':
695
+ case 'registry_connections_remove':
623
696
  return await this.removeConnection(args.connection_id);
624
- case 'marketplace.connections.test':
697
+ case 'registry_connections_test':
625
698
  return await this.testConnection(args.connection_id);
626
- case 'marketplace.connections.updateKey':
699
+ case 'registry_connections_update_key':
627
700
  return await this.updateConnectionKey(args.connection_id, args.api_key);
628
- case 'marketplace.providers.list':
701
+ case 'registry_providers_list':
629
702
  return await this.listProviders();
630
- case 'marketplace.models.discover':
703
+ case 'registry_models_discover':
631
704
  return await this.discoverModels(args);
632
- case 'marketplace.models.list':
705
+ case 'registry_models_list':
633
706
  return await this.listModels(args);
634
- case 'marketplace.models.updateCapabilities':
707
+ case 'registry_models_update_capabilities':
635
708
  return await this.updateModelCapabilities(args);
636
- case 'marketplace.models.get':
709
+ case 'registry_models_get':
637
710
  return await this.getModelInfo(args.model_id);
638
- case 'marketplace.requestLogs.list':
711
+ case 'registry_request_logs_list':
639
712
  return await this.listRequestLogs(args);
640
- case 'marketplace.requestLogs.get':
713
+ case 'registry_request_logs_get':
641
714
  return await this.getRequestLog(args.log_id, args.show_full_body);
642
- case 'marketplace.requestLogs.stats':
715
+ case 'registry_request_logs_stats':
643
716
  return await this.getRequestLogStats(args);
644
- case 'marketplace.vault.status':
717
+ case 'registry_vault_status':
645
718
  return await this.getVaultStatus();
646
- case 'marketplace.vault.localvault':
719
+ case 'registry_vault_localvault':
647
720
  return await this.getLocalVaultList();
648
- case 'marketplace.vault.keyvault':
721
+ case 'registry_vault_keyvault':
649
722
  return await this.getKeyVaultStatus();
650
- case 'marketplace.connections.quota.manage':
723
+ case 'registry_connections_quota_manage':
651
724
  return await this.manageConnectionQuota(args);
652
- case 'marketplace.connections.quota.get':
725
+ case 'registry_connections_quota_get':
653
726
  return await this.getConnectionQuota(args.connection_id);
654
- case 'marketplace.connections.quota.list':
727
+ case 'registry_connections_quota_list':
655
728
  return await this.listConnectionQuotas();
656
- case 'marketplace.models.updatePricing':
729
+ case 'registry_models_update_pricing':
657
730
  return await this.updateModelPricing(args);
658
- case 'marketplace.models.publish':
659
- return await this.publishModel(args);
731
+ case 'registry_models_update_billing':
732
+ return await this.updateModelBilling(args);
733
+ case 'registry_models_update_visibility':
734
+ return await this.updateModelVisibility(args);
735
+ // Workflow query tools
736
+ case 'workflow_get_status':
737
+ return await this.getWorkflowStatus(args.trace_id);
738
+ case 'workflow_list_instances':
739
+ return await this.listWorkflowInstances(args.trace_id);
740
+ case 'workflow_get_instance_output':
741
+ return await this.getInstanceOutput(args.instance_id);
660
742
  default:
661
743
  return {
662
744
  success: false,
@@ -707,15 +789,15 @@ class MarketplaceTools {
707
789
  // ========================================================================
708
790
  async listConnections() {
709
791
  try {
710
- (0, debug_utils_1.debugLog)(`[MarketplaceTools] Listing connections from: ${this.marketplaceUrl}/api/connections`);
792
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Listing connections from: ${this.registryUrl}/api/connections`);
711
793
  const response = await this.client.get('/api/connections');
712
- (0, debug_utils_1.debugLog)(`[MarketplaceTools] List response status: ${response.status}`);
713
- (0, debug_utils_1.debugLog)(`[MarketplaceTools] List response data keys:`, Object.keys(response.data || {}));
794
+ (0, debug_utils_1.debugLog)(`[RegistryTools] List response status: ${response.status}`);
795
+ (0, debug_utils_1.debugLog)(`[RegistryTools] List response data keys:`, Object.keys(response.data || {}));
714
796
  const connections = response.data.connections || [];
715
797
  if (connections.length === 0) {
716
798
  return {
717
799
  success: true,
718
- output: 'No connections found. Use marketplace.connections.add to create one.'
800
+ output: 'No connections found. Use registry.connections.add to create one.'
719
801
  };
720
802
  }
721
803
  // Sort by created_at to maintain consistent ordering
@@ -747,9 +829,9 @@ class MarketplaceTools {
747
829
  ` ➕ Add a New Connection\n` +
748
830
  ` Create connection to LLM provider (OpenAI, Groq, etc.)\n\n` +
749
831
  ` 🔍 Discover Models\n` +
750
- ` Fetch available models from provider API and add to marketplace\n\n` +
832
+ ` Fetch available models from provider API and add to registry\n\n` +
751
833
  ` 🔑 Update API Key\n` +
752
- ` Change API key for existing connection (Marketplace-Managed only)\n\n` +
834
+ ` Change API key for existing connection (Registry-Managed only)\n\n` +
753
835
  ` 📊 Manage Quota\n` +
754
836
  ` Set usage limits for connection (daily/monthly spending caps)\n\n` +
755
837
  ` 📈 View Quota Status\n` +
@@ -759,23 +841,23 @@ class MarketplaceTools {
759
841
  ` 🧪 Test Connection\n` +
760
842
  ` Verify connection works by discovering models\n\n` +
761
843
  ` 🗑️ Delete Connection\n` +
762
- ` Remove connection and all its models from marketplace\n\n` +
844
+ ` Remove connection and all its models from registry\n\n` +
763
845
  `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`
764
846
  };
765
847
  }
766
848
  catch (error) {
767
- console.error(`[MarketplaceTools] List connections error:`);
768
- console.error(`[MarketplaceTools] Error code:`, error.code);
769
- console.error(`[MarketplaceTools] Error message:`, error.message);
770
- console.error(`[MarketplaceTools] Response status:`, error.response?.status);
771
- console.error(`[MarketplaceTools] Response data:`, error.response?.data);
849
+ console.error(`[RegistryTools] List connections error:`);
850
+ console.error(`[RegistryTools] Error code:`, error.code);
851
+ console.error(`[RegistryTools] Error message:`, error.message);
852
+ console.error(`[RegistryTools] Response status:`, error.response?.status);
853
+ console.error(`[RegistryTools] Response data:`, error.response?.data);
772
854
  // Socket hang up / connection reset errors
773
855
  if (error.code === 'ECONNRESET' || error.code === 'EPIPE' ||
774
856
  error.message?.toLowerCase().includes('socket hang up')) {
775
857
  return {
776
858
  success: false,
777
859
  error: `🔌 Connection lost while listing connections\n\n` +
778
- `The marketplace API connection was interrupted.\n` +
860
+ `The registry API connection was interrupted.\n` +
779
861
  `This may happen if:\n` +
780
862
  ` • The gateway is restarting\n` +
781
863
  ` • Network is unstable\n` +
@@ -796,7 +878,7 @@ class MarketplaceTools {
796
878
  const response = await this.client.post('/api/connections', args);
797
879
  const conn = response.data.connection;
798
880
  // Build detailed connection info
799
- const gatewayTypeLabel = conn.gateway_type === 2 ? 'Marketplace-Managed Compute' : 'Self-Hosted Compute';
881
+ const gatewayTypeLabel = conn.gateway_type === 2 ? 'Registry-Managed Compute' : 'Self-Hosted Compute';
800
882
  return {
801
883
  success: true,
802
884
  output: `✅ Connection added successfully!\n\n` +
@@ -813,13 +895,13 @@ class MarketplaceTools {
813
895
  `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n` +
814
896
  `💡 What would you like to do next?\n\n` +
815
897
  ` 1️⃣ Test this connection\n` +
816
- ` Use: marketplace.connections.test\n\n` +
898
+ ` Use: registry.connections.test\n\n` +
817
899
  ` 2️⃣ Discover available models\n` +
818
- ` Use: marketplace.models.discover\n\n` +
900
+ ` Use: registry.models.discover\n\n` +
819
901
  ` 3️⃣ Update the API key\n` +
820
- ` Use: marketplace.connections.updateKey\n\n` +
902
+ ` Use: registry.connections.updateKey\n\n` +
821
903
  ` 4️⃣ Remove this connection\n` +
822
- ` Use: marketplace.connections.remove\n\n` +
904
+ ` Use: registry.connections.remove\n\n` +
823
905
  `IMPORTANT: Show this output to the user and ask what they'd like to do next. DO NOT automatically call other tools.`
824
906
  };
825
907
  }
@@ -852,11 +934,11 @@ class MarketplaceTools {
852
934
  // Resolve sequence number to UUID if needed
853
935
  const resolvedId = this.resolveConnectionId(connectionId);
854
936
  const testUrl = `/api/connections/${resolvedId}/test`;
855
- (0, debug_utils_1.debugLog)(`[MarketplaceTools] Testing connection: ${connectionId} (resolved to: ${resolvedId})`);
856
- (0, debug_utils_1.debugLog)(`[MarketplaceTools] Full URL: ${this.marketplaceUrl}${testUrl}`);
937
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Testing connection: ${connectionId} (resolved to: ${resolvedId})`);
938
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Full URL: ${this.registryUrl}${testUrl}`);
857
939
  const response = await this.client.post(testUrl);
858
- (0, debug_utils_1.debugLog)(`[MarketplaceTools] Response status: ${response.status}`);
859
- (0, debug_utils_1.debugLog)(`[MarketplaceTools] Response data:`, response.data);
940
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Response status: ${response.status}`);
941
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Response data:`, response.data);
860
942
  const data = response.data;
861
943
  // Check for non-2xx responses (axios doesn't throw for < 500)
862
944
  if (response.status >= 400 || data.success === false) {
@@ -866,7 +948,7 @@ class MarketplaceTools {
866
948
  success: false,
867
949
  error: `❌ Connection not found\n\n` +
868
950
  `Connection: ${connectionId} (resolved to: ${resolvedId})\n\n` +
869
- `💡 Use marketplace.connections.list to see available connections.`
951
+ `💡 Use registry.connections.list to see available connections.`
870
952
  };
871
953
  }
872
954
  // Handle other 4xx errors using the standardized error format
@@ -890,7 +972,7 @@ class MarketplaceTools {
890
972
  `Status: ${errorData.status} (Authentication Failed)\n` +
891
973
  (errorData.details ? `Details: ${errorData.details}\n` : '') +
892
974
  `\n💡 Check your API key and update it if needed using:\n` +
893
- ` marketplace.connections.updateKey`
975
+ ` registry.connections.updateKey`
894
976
  };
895
977
  }
896
978
  if (errorData.code === 'type3_gateway_unavailable') {
@@ -930,18 +1012,18 @@ class MarketplaceTools {
930
1012
  };
931
1013
  }
932
1014
  catch (error) {
933
- console.error(`[MarketplaceTools] Test connection error for ${connectionId}:`);
934
- console.error(`[MarketplaceTools] Error code:`, error.code);
935
- console.error(`[MarketplaceTools] Error message:`, error.message);
936
- console.error(`[MarketplaceTools] Response status:`, error.response?.status);
937
- console.error(`[MarketplaceTools] Response data:`, error.response?.data);
1015
+ console.error(`[RegistryTools] Test connection error for ${connectionId}:`);
1016
+ console.error(`[RegistryTools] Error code:`, error.code);
1017
+ console.error(`[RegistryTools] Error message:`, error.message);
1018
+ console.error(`[RegistryTools] Response status:`, error.response?.status);
1019
+ console.error(`[RegistryTools] Response data:`, error.response?.data);
938
1020
  // Socket hang up / connection reset errors
939
1021
  if (error.code === 'ECONNRESET' || error.code === 'EPIPE' ||
940
1022
  error.message?.toLowerCase().includes('socket hang up')) {
941
1023
  return {
942
1024
  success: false,
943
1025
  error: `🔌 Connection lost during test\n\n` +
944
- `The marketplace API connection was interrupted.\n` +
1026
+ `The registry API connection was interrupted.\n` +
945
1027
  `This may happen if:\n` +
946
1028
  ` • The gateway is restarting\n` +
947
1029
  ` • Network is unstable\n` +
@@ -955,9 +1037,9 @@ class MarketplaceTools {
955
1037
  if (error.code === 'ECONNREFUSED') {
956
1038
  return {
957
1039
  success: false,
958
- error: `🔌 Cannot connect to marketplace API\n\n` +
959
- `The marketplace API is not reachable at ${this.marketplaceUrl}\n\n` +
960
- `💡 Ensure the LangMart Marketplace is running on the correct port.`
1040
+ error: `🔌 Cannot connect to registry API\n\n` +
1041
+ `The registry API is not reachable at ${this.registryUrl}\n\n` +
1042
+ `💡 Ensure the LangMart Registry is running on the correct port.`
961
1043
  };
962
1044
  }
963
1045
  // Generic error fallback
@@ -994,7 +1076,7 @@ class MarketplaceTools {
994
1076
  if (providers.length === 0) {
995
1077
  return {
996
1078
  success: true,
997
- output: 'No providers found in marketplace.'
1079
+ output: 'No providers found in registry.'
998
1080
  };
999
1081
  }
1000
1082
  const output = providers.map((p, idx) => `${idx + 1}. ${p.name} (${p.key})\n` +
@@ -1039,7 +1121,7 @@ class MarketplaceTools {
1039
1121
  `Stored: ${data.stored} models\n` +
1040
1122
  `Failed: ${data.failed} models\n` +
1041
1123
  `Source: ${data.source}\n\n` +
1042
- `Use marketplace.models.list to see all available models.`
1124
+ `Use registry.models.list to see all available models.`
1043
1125
  };
1044
1126
  }
1045
1127
  catch (error) {
@@ -1064,7 +1146,7 @@ class MarketplaceTools {
1064
1146
  if (models.length === 0) {
1065
1147
  return {
1066
1148
  success: true,
1067
- output: 'No models found. Use marketplace.models.discover to discover models from your connections.'
1149
+ output: 'No models found. Use registry.models.discover to discover models from your connections.'
1068
1150
  };
1069
1151
  }
1070
1152
  // Pagination parameters
@@ -1264,7 +1346,7 @@ class MarketplaceTools {
1264
1346
  output: `No models match the specified filters.\n\n` +
1265
1347
  `Active Filters:\n ${activeFilters.join('\n ')}\n` +
1266
1348
  `Sorted By: ${sortLabel}\n\n` +
1267
- `Try relaxing the filters or use marketplace.models.discover to add more models.`
1349
+ `Try relaxing the filters or use registry.models.discover to add more models.`
1268
1350
  };
1269
1351
  }
1270
1352
  // Apply pagination
@@ -1381,7 +1463,7 @@ class MarketplaceTools {
1381
1463
  if (error.response?.status === 404) {
1382
1464
  return {
1383
1465
  success: false,
1384
- error: `Model "${modelId}" not found. Use marketplace.models.list to see available models.`
1466
+ error: `Model "${modelId}" not found. Use registry.models.list to see available models.`
1385
1467
  };
1386
1468
  }
1387
1469
  return {
@@ -1753,7 +1835,7 @@ class MarketplaceTools {
1753
1835
  const provider = providers[i];
1754
1836
  if (provider.connection_id === '__gateway_auth__') {
1755
1837
  lines.push(` ${i + 1}. 🔐 Gateway Authentication`);
1756
- lines.push(` Type: Marketplace API Key`);
1838
+ lines.push(` Type: Registry API Key`);
1757
1839
  lines.push(` Status: ✅ Encrypted & Stored`);
1758
1840
  }
1759
1841
  else {
@@ -1766,7 +1848,7 @@ class MarketplaceTools {
1766
1848
  }
1767
1849
  if (provider.gateway_type) {
1768
1850
  const gatewayName = provider.gateway_type === 2
1769
- ? 'Marketplace-Managed Compute'
1851
+ ? 'Registry-Managed Compute'
1770
1852
  : 'Self-Hosted Compute';
1771
1853
  lines.push(` Gateway: ${gatewayName}`);
1772
1854
  }
@@ -1860,8 +1942,8 @@ class MarketplaceTools {
1860
1942
  const provider = providers[i];
1861
1943
  if (provider.connection_id === '__gateway_auth__') {
1862
1944
  lines.push(` ${i + 1}. 🔐 Gateway Authentication`);
1863
- lines.push(` Type: Marketplace API Key`);
1864
- lines.push(` Purpose: Authenticate with marketplace`);
1945
+ lines.push(` Type: Registry API Key`);
1946
+ lines.push(` Purpose: Authenticate with registry`);
1865
1947
  lines.push(` Status: ✅ Encrypted & Stored`);
1866
1948
  }
1867
1949
  else {
@@ -1874,7 +1956,7 @@ class MarketplaceTools {
1874
1956
  }
1875
1957
  if (provider.gateway_type) {
1876
1958
  const gatewayName = provider.gateway_type === 2
1877
- ? 'Marketplace-Managed Compute'
1959
+ ? 'Registry-Managed Compute'
1878
1960
  : 'Self-Hosted Compute';
1879
1961
  lines.push(` Gateway: ${gatewayName}`);
1880
1962
  }
@@ -2151,7 +2233,7 @@ class MarketplaceTools {
2151
2233
  if (connections.length === 0) {
2152
2234
  return {
2153
2235
  success: true,
2154
- output: 'No connections found. Use marketplace.connections.add to create one.'
2236
+ output: 'No connections found. Use registry.connections.add to create one.'
2155
2237
  };
2156
2238
  }
2157
2239
  // Sort by created_at to maintain consistent ordering
@@ -2199,7 +2281,7 @@ class MarketplaceTools {
2199
2281
  }
2200
2282
  }
2201
2283
  output += `\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
2202
- output += `💡 Use marketplace.connections.quota.get to see detailed history for a specific connection\n`;
2284
+ output += `💡 Use registry.connections.quota.get to see detailed history for a specific connection\n`;
2203
2285
  output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`;
2204
2286
  return {
2205
2287
  success: true,
@@ -2802,7 +2884,7 @@ class MarketplaceTools {
2802
2884
  switch (access_level) {
2803
2885
  case 'public':
2804
2886
  statusEmoji = '🌍';
2805
- accessDescription = 'Public - Available to all marketplace users';
2887
+ accessDescription = 'Public - Available to all registry users';
2806
2888
  break;
2807
2889
  case 'private':
2808
2890
  statusEmoji = '🔒';
@@ -2825,7 +2907,7 @@ class MarketplaceTools {
2825
2907
  ` Description: ${accessDescription}\n\n` +
2826
2908
  `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n` +
2827
2909
  (access_level === 'organization'
2828
- ? `ℹ️ Your model is now listed in the marketplace and available for\n` +
2910
+ ? `ℹ️ Your model is now listed in the registry and available for\n` +
2829
2911
  ` other users to consume. You'll earn revenue when others use it.\n\n`
2830
2912
  : access_level === 'private'
2831
2913
  ? `ℹ️ Your model is now private and only accessible to you.\n\n`
@@ -2840,7 +2922,346 @@ class MarketplaceTools {
2840
2922
  };
2841
2923
  }
2842
2924
  }
2925
+ /**
2926
+ * Update billing settings for organization models (org admin only)
2927
+ * Calls /api/admin/models/:id/billing
2928
+ */
2929
+ async updateModelBilling(args) {
2930
+ try {
2931
+ const { model_id, billing_mode, org_fee_percentage, input_per_1k, output_per_1k } = args;
2932
+ if (!model_id) {
2933
+ return {
2934
+ success: false,
2935
+ error: 'model_id is required'
2936
+ };
2937
+ }
2938
+ if (!billing_mode || !['org_pays', 'member_pays'].includes(billing_mode)) {
2939
+ return {
2940
+ success: false,
2941
+ error: 'billing_mode is required and must be "org_pays" or "member_pays"'
2942
+ };
2943
+ }
2944
+ // Build request body
2945
+ const body = {
2946
+ billing_mode
2947
+ };
2948
+ if (org_fee_percentage !== undefined) {
2949
+ body.org_fee_percentage = org_fee_percentage;
2950
+ }
2951
+ if (input_per_1k !== undefined) {
2952
+ body.price_per_1k_input_tokens = input_per_1k;
2953
+ }
2954
+ if (output_per_1k !== undefined) {
2955
+ body.price_per_1k_output_tokens = output_per_1k;
2956
+ }
2957
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Updating billing for model: ${model_id}`, body);
2958
+ const response = await this.client.patch(`/api/admin/models/${encodeURIComponent(model_id)}/billing`, body);
2959
+ if (!response.data.success) {
2960
+ return {
2961
+ success: false,
2962
+ error: response.data.error?.message || 'Failed to update billing settings'
2963
+ };
2964
+ }
2965
+ const result = response.data.data;
2966
+ // Format output
2967
+ const billingModeLabel = result.billing.mode === 'org_pays'
2968
+ ? '🏢 Organization Pays'
2969
+ : '👤 Member Pays';
2970
+ let output = `✅ Billing settings updated successfully!\n\n` +
2971
+ `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
2972
+ `💰 Model Billing Settings:\n` +
2973
+ `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
2974
+ ` Model ID: ${result.model_id}\n\n` +
2975
+ ` Billing Mode: ${billingModeLabel}\n`;
2976
+ if (result.billing.mode === 'member_pays' && result.billing.org_fee_percentage > 0) {
2977
+ output += ` Org Fee: ${result.billing.org_fee_percentage}%\n`;
2978
+ }
2979
+ if (result.pricing) {
2980
+ output += `\n Pricing:\n` +
2981
+ ` Input: $${result.pricing.input_per_1k.toFixed(6)}/1K tokens\n` +
2982
+ ` Output: $${result.pricing.output_per_1k.toFixed(6)}/1K tokens\n`;
2983
+ }
2984
+ output += `\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n` +
2985
+ `Updated: ${new Date(result.updated_at).toLocaleString()}`;
2986
+ return {
2987
+ success: true,
2988
+ output
2989
+ };
2990
+ }
2991
+ catch (error) {
2992
+ // Handle specific error codes
2993
+ const errorCode = error.response?.data?.error?.code;
2994
+ const errorMsg = error.response?.data?.error?.message || error.message;
2995
+ if (errorCode === 'ADMIN_MODEL_004') {
2996
+ return {
2997
+ success: false,
2998
+ error: 'This tool only works on organization-level models. For private models, owners already have full access.'
2999
+ };
3000
+ }
3001
+ if (errorCode === 'ADMIN_MODEL_006' || errorCode === 'ADMIN_MODEL_005') {
3002
+ return {
3003
+ success: false,
3004
+ error: 'Only organization admins and owners can update billing settings.'
3005
+ };
3006
+ }
3007
+ return {
3008
+ success: false,
3009
+ error: errorMsg
3010
+ };
3011
+ }
3012
+ }
3013
+ /**
3014
+ * Update visibility for organization models (org admin only)
3015
+ * Calls /api/admin/models/:id/visibility
3016
+ */
3017
+ async updateModelVisibility(args) {
3018
+ try {
3019
+ const { model_id, is_available } = args;
3020
+ if (!model_id) {
3021
+ return {
3022
+ success: false,
3023
+ error: 'model_id is required'
3024
+ };
3025
+ }
3026
+ if (typeof is_available !== 'boolean') {
3027
+ return {
3028
+ success: false,
3029
+ error: 'is_available is required and must be true or false'
3030
+ };
3031
+ }
3032
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Updating visibility for model: ${model_id} to ${is_available}`);
3033
+ const response = await this.client.patch(`/api/admin/models/${encodeURIComponent(model_id)}/visibility`, {
3034
+ is_available
3035
+ });
3036
+ if (!response.data.success) {
3037
+ return {
3038
+ success: false,
3039
+ error: response.data.error?.message || 'Failed to update visibility'
3040
+ };
3041
+ }
3042
+ const result = response.data.data;
3043
+ // Format output
3044
+ const visibilityLabel = result.is_available
3045
+ ? '👁️ Visible - Org members can see and use this model'
3046
+ : '🙈 Hidden - Only org admins can see this model';
3047
+ const output = `✅ Visibility updated successfully!\n\n` +
3048
+ `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
3049
+ `👁️ Model Visibility Settings:\n` +
3050
+ `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
3051
+ ` Model ID: ${result.model_id}\n\n` +
3052
+ ` Visibility: ${visibilityLabel}\n\n` +
3053
+ `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n` +
3054
+ `Updated: ${new Date(result.updated_at).toLocaleString()}`;
3055
+ return {
3056
+ success: true,
3057
+ output
3058
+ };
3059
+ }
3060
+ catch (error) {
3061
+ // Handle specific error codes
3062
+ const errorCode = error.response?.data?.error?.code;
3063
+ const errorMsg = error.response?.data?.error?.message || error.message;
3064
+ if (errorCode === 'ADMIN_MODEL_VIS_003') {
3065
+ return {
3066
+ success: false,
3067
+ error: 'This tool only works on organization-level models. For private models, owners always have full access and visibility.'
3068
+ };
3069
+ }
3070
+ if (errorCode === 'ADMIN_MODEL_VIS_005' || errorCode === 'ADMIN_MODEL_VIS_004') {
3071
+ return {
3072
+ success: false,
3073
+ error: 'Only organization admins and owners can update model visibility.'
3074
+ };
3075
+ }
3076
+ return {
3077
+ success: false,
3078
+ error: errorMsg
3079
+ };
3080
+ }
3081
+ }
3082
+ // ========================================================================
3083
+ // WORKFLOW QUERY TOOL IMPLEMENTATIONS
3084
+ // ========================================================================
3085
+ /**
3086
+ * Get overall status of a workflow execution
3087
+ */
3088
+ async getWorkflowStatus(traceId) {
3089
+ try {
3090
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Getting workflow status for trace: ${traceId}`);
3091
+ const response = await this.client.get(`/api/agents/executions/${traceId}/trace`);
3092
+ if (!response.data.success) {
3093
+ return {
3094
+ success: false,
3095
+ error: response.data.error || 'Failed to get workflow status'
3096
+ };
3097
+ }
3098
+ const { workflowName, status, startedAt, completedAt, instances } = response.data;
3099
+ // Calculate progress
3100
+ const total = instances?.length || 0;
3101
+ const completed = instances?.filter((i) => i.status === 'completed').length || 0;
3102
+ const failed = instances?.filter((i) => i.status === 'failed').length || 0;
3103
+ const running = instances?.filter((i) => i.status === 'active' || i.status === 'running').length || 0;
3104
+ let statusEmoji = '⏳';
3105
+ if (status === 'completed')
3106
+ statusEmoji = '✅';
3107
+ else if (status === 'failed')
3108
+ statusEmoji = '❌';
3109
+ else if (status === 'running')
3110
+ statusEmoji = '🔄';
3111
+ let output = `${statusEmoji} Workflow Execution Status\n`;
3112
+ output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n`;
3113
+ output += ` Workflow: ${workflowName || 'Unnamed Workflow'}\n`;
3114
+ output += ` Trace ID: ${traceId}\n`;
3115
+ output += ` Status: ${status?.toUpperCase() || 'UNKNOWN'}\n\n`;
3116
+ output += ` Progress: ${completed}/${total} agents completed\n`;
3117
+ if (running > 0)
3118
+ output += ` Running: ${running} agent(s)\n`;
3119
+ if (failed > 0)
3120
+ output += ` Failed: ${failed} agent(s)\n`;
3121
+ output += `\n`;
3122
+ if (startedAt)
3123
+ output += ` Started: ${new Date(startedAt).toLocaleString()}\n`;
3124
+ if (completedAt)
3125
+ output += ` Completed: ${new Date(completedAt).toLocaleString()}\n`;
3126
+ return {
3127
+ success: true,
3128
+ output
3129
+ };
3130
+ }
3131
+ catch (error) {
3132
+ return {
3133
+ success: false,
3134
+ error: error.response?.data?.error || error.message
3135
+ };
3136
+ }
3137
+ }
3138
+ /**
3139
+ * List all instances in a workflow execution
3140
+ */
3141
+ async listWorkflowInstances(traceId) {
3142
+ try {
3143
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Listing workflow instances for trace: ${traceId}`);
3144
+ const response = await this.client.get(`/api/agents/executions/${traceId}/trace`);
3145
+ if (!response.data.success) {
3146
+ return {
3147
+ success: false,
3148
+ error: response.data.error || 'Failed to list workflow instances'
3149
+ };
3150
+ }
3151
+ const { workflowName, instances } = response.data;
3152
+ if (!instances || instances.length === 0) {
3153
+ return {
3154
+ success: true,
3155
+ output: 'No instances found for this workflow execution.'
3156
+ };
3157
+ }
3158
+ let output = `📋 Workflow Instances\n`;
3159
+ output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
3160
+ output += ` Workflow: ${workflowName || 'Unnamed Workflow'}\n`;
3161
+ output += ` Total Agents: ${instances.length}\n\n`;
3162
+ for (const instance of instances) {
3163
+ let statusEmoji = '⏳';
3164
+ if (instance.status === 'completed')
3165
+ statusEmoji = '✅';
3166
+ else if (instance.status === 'failed')
3167
+ statusEmoji = '❌';
3168
+ else if (instance.status === 'active' || instance.status === 'running')
3169
+ statusEmoji = '🔄';
3170
+ let roleEmoji = '🤖';
3171
+ if (instance.nodeType === 'START')
3172
+ roleEmoji = '🚀';
3173
+ else if (instance.nodeType === 'END')
3174
+ roleEmoji = '🏁';
3175
+ output += `${roleEmoji} [${instance.executionOrder}] ${instance.definitionName || instance.name}\n`;
3176
+ output += ` ID: ${instance.id}\n`;
3177
+ output += ` Role: ${instance.nodeType}\n`;
3178
+ output += ` Status: ${statusEmoji} ${instance.status?.toUpperCase() || 'PENDING'}\n`;
3179
+ if (instance.errorMessage) {
3180
+ output += ` Error: ${instance.errorMessage}\n`;
3181
+ }
3182
+ output += `\n`;
3183
+ }
3184
+ return {
3185
+ success: true,
3186
+ output
3187
+ };
3188
+ }
3189
+ catch (error) {
3190
+ return {
3191
+ success: false,
3192
+ error: error.response?.data?.error || error.message
3193
+ };
3194
+ }
3195
+ }
3196
+ /**
3197
+ * Get output from a specific agent instance
3198
+ */
3199
+ async getInstanceOutput(instanceId) {
3200
+ try {
3201
+ (0, debug_utils_1.debugLog)(`[RegistryTools] Getting instance output for: ${instanceId}`);
3202
+ // Get the instance trace which includes sessions
3203
+ const traceResponse = await this.client.get(`/api/agents/instances/${instanceId}/trace`);
3204
+ if (!traceResponse.data?.success) {
3205
+ return {
3206
+ success: false,
3207
+ error: traceResponse.data?.error || 'Instance not found'
3208
+ };
3209
+ }
3210
+ const instance = traceResponse.data.instance;
3211
+ const sessions = traceResponse.data.sessions || [];
3212
+ if (sessions.length === 0) {
3213
+ return {
3214
+ success: true,
3215
+ output: `📦 Instance Output\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
3216
+ ` Instance: ${instance.name || instanceId}\n` +
3217
+ ` Status: No sessions found - agent has not run yet.\n`
3218
+ };
3219
+ }
3220
+ const latestSession = sessions[0];
3221
+ let statusEmoji = '⏳';
3222
+ if (latestSession.status === 'completed')
3223
+ statusEmoji = '✅';
3224
+ else if (latestSession.status === 'failed')
3225
+ statusEmoji = '❌';
3226
+ else if (latestSession.status === 'active')
3227
+ statusEmoji = '🔄';
3228
+ let output = `📦 Instance Output\n`;
3229
+ output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n`;
3230
+ output += ` Instance: ${instance.name || instanceId}\n`;
3231
+ output += ` Definition: ${instance.definition_name || 'Unknown'}\n`;
3232
+ output += ` Status: ${statusEmoji} ${latestSession.status?.toUpperCase() || 'UNKNOWN'}\n\n`;
3233
+ if (latestSession.error_message) {
3234
+ output += ` ❌ Error: ${latestSession.error_message}\n\n`;
3235
+ }
3236
+ // Try to get the assistant's response from the session
3237
+ if (latestSession.response) {
3238
+ output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
3239
+ output += `Response:\n`;
3240
+ output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n`;
3241
+ output += latestSession.response;
3242
+ }
3243
+ else if (latestSession.metadata?.output) {
3244
+ output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
3245
+ output += `Output:\n`;
3246
+ output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n`;
3247
+ output += JSON.stringify(latestSession.metadata.output, null, 2);
3248
+ }
3249
+ else {
3250
+ output += ` No output available yet.\n`;
3251
+ }
3252
+ return {
3253
+ success: true,
3254
+ output
3255
+ };
3256
+ }
3257
+ catch (error) {
3258
+ return {
3259
+ success: false,
3260
+ error: error.response?.data?.error || error.message
3261
+ };
3262
+ }
3263
+ }
2843
3264
  }
2844
- exports.MarketplaceTools = MarketplaceTools;
2845
- MarketplaceTools.instance = null;
2846
- //# sourceMappingURL=marketplace-tools.js.map
3265
+ exports.RegistryTools = RegistryTools;
3266
+ RegistryTools.instance = null;
3267
+ //# sourceMappingURL=registry-tools.js.map