@orchagent/cli 0.3.99 → 0.3.100

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.
@@ -28,7 +28,7 @@ async function resolveAgentId(config, ref) {
28
28
  }
29
29
  // Use the latest version
30
30
  const latest = matching.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())[0];
31
- return { agent: latest, agentId: latest.id, orgSlug: latest.org_slug ?? resolvedOrg ?? '' };
31
+ return { agent: latest, agentId: latest.id, orgSlug: latest.org_slug ?? resolvedOrg ?? '', workspaceId };
32
32
  }
33
33
  function registerAgentKeysCommand(program) {
34
34
  const agentKeys = program
@@ -42,8 +42,8 @@ function registerAgentKeysCommand(program) {
42
42
  if (!config.apiKey) {
43
43
  throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
44
44
  }
45
- const { agent, agentId, orgSlug } = await resolveAgentId(config, ref);
46
- const result = await (0, api_1.listAgentKeys)(config, agentId);
45
+ const { agent, agentId, orgSlug, workspaceId } = await resolveAgentId(config, ref);
46
+ const result = await (0, api_1.listAgentKeys)(config, agentId, workspaceId);
47
47
  // Load locally-saved keys for this agent
48
48
  const localKeys = await (0, key_store_1.loadServiceKeys)(orgSlug, agent.name);
49
49
  const localPrefixes = new Set(localKeys.map(k => k.prefix));
@@ -76,8 +76,8 @@ function registerAgentKeysCommand(program) {
76
76
  if (!config.apiKey) {
77
77
  throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
78
78
  }
79
- const { agent, orgSlug } = await resolveAgentId(config, ref);
80
- const result = await (0, api_1.createAgentKey)(config, agent.id);
79
+ const { agent, orgSlug, workspaceId } = await resolveAgentId(config, ref);
80
+ const result = await (0, api_1.createAgentKey)(config, agent.id, workspaceId);
81
81
  process.stdout.write(`\nNew service key for ${agent.name}:\n\n`);
82
82
  process.stdout.write(` ${result.key}\n\n`);
83
83
  try {
@@ -96,8 +96,8 @@ function registerAgentKeysCommand(program) {
96
96
  if (!config.apiKey) {
97
97
  throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
98
98
  }
99
- const { agent, agentId } = await resolveAgentId(config, ref);
100
- await (0, api_1.deleteAgentKey)(config, agentId, keyId);
99
+ const { agent, agentId, workspaceId } = await resolveAgentId(config, ref);
100
+ await (0, api_1.deleteAgentKey)(config, agentId, keyId, workspaceId);
101
101
  process.stdout.write(`Deleted key ${keyId} from ${agent.name}.\n`);
102
102
  });
103
103
  }
@@ -43,9 +43,10 @@ function registerEstimateCommand(program) {
43
43
  process.exit(1);
44
44
  }
45
45
  const { agent, version } = parsed;
46
+ const workspaceId = await (0, api_1.resolveWorkspaceIdForOrg)(config, org);
46
47
  let data;
47
48
  try {
48
- data = await (0, api_1.getAgentCostEstimate)(config, org, agent, version);
49
+ data = await (0, api_1.getAgentCostEstimate)(config, org, agent, version, workspaceId);
49
50
  }
50
51
  catch (err) {
51
52
  if (err instanceof api_1.ApiError && err.status === 404) {
@@ -412,7 +412,8 @@ import asyncio
412
412
  import json
413
413
  import sys
414
414
 
415
- from orchagent import AgentClient
415
+ # pip install orchagent-sdk (package name)
416
+ from orchagent import AgentClient # module name
416
417
 
417
418
 
418
419
  async def run():
@@ -503,7 +504,8 @@ import asyncio
503
504
  import json
504
505
  import sys
505
506
 
506
- from orchagent import AgentClient
507
+ # pip install orchagent-sdk (package name)
508
+ from orchagent import AgentClient # module name
507
509
 
508
510
 
509
511
  async def run():
@@ -589,7 +591,8 @@ import asyncio
589
591
  import json
590
592
  import sys
591
593
 
592
- from orchagent import AgentClient
594
+ # pip install orchagent-sdk (package name)
595
+ from orchagent import AgentClient # module name
593
596
 
594
597
 
595
598
  async def run():
@@ -1207,7 +1210,8 @@ import asyncio
1207
1210
  import json
1208
1211
  import sys
1209
1212
 
1210
- from orchagent import AgentClient
1213
+ # pip install orchagent-sdk (package name)
1214
+ from orchagent import AgentClient # module name
1211
1215
 
1212
1216
 
1213
1217
  def main():
@@ -292,7 +292,7 @@ function buildManifest(data) {
292
292
  return manifest;
293
293
  }
294
294
  // ─── Bundle Download + Extraction ───────────────────────────────────────────
295
- async function downloadBundle(config, org, agent, version, agentId) {
295
+ async function downloadBundle(config, org, agent, version, agentId, workspaceId) {
296
296
  try {
297
297
  return await (0, api_1.downloadCodeBundle)(config, org, agent, version);
298
298
  }
@@ -305,7 +305,7 @@ async function downloadBundle(config, org, agent, version, agentId) {
305
305
  }
306
306
  if (config.apiKey && agentId) {
307
307
  try {
308
- return await (0, api_1.downloadCodeBundleAuthenticated)(config, agentId);
308
+ return await (0, api_1.downloadCodeBundleAuthenticated)(config, agentId, workspaceId);
309
309
  }
310
310
  catch (err) {
311
311
  if (!(err instanceof api_1.ApiError) || err.status !== 404)
@@ -411,7 +411,7 @@ Examples:
411
411
  // and exit-code 1.
412
412
  if (engine === 'code_runtime' && data.has_bundle) {
413
413
  write('Downloading code bundle...\n');
414
- const bundle = await downloadBundle(config, org, data.name, data.version, data.agentId);
414
+ const bundle = await downloadBundle(config, org, data.name, data.version, data.agentId, workspaceId);
415
415
  if (bundle) {
416
416
  const tempDir = path_1.default.join(os_1.default.tmpdir(), `orchagent-pull-${Date.now()}`);
417
417
  const zipPath = path_1.default.join(tempDir, 'bundle.zip');
@@ -656,7 +656,7 @@ async function downloadAgent(config, org, agent, version, workspaceId) {
656
656
  entrypoint: targetAgent.entrypoint,
657
657
  };
658
658
  }
659
- async function downloadBundleWithFallback(config, org, agentName, version, agentId) {
659
+ async function downloadBundleWithFallback(config, org, agentName, version, agentId, workspaceId) {
660
660
  try {
661
661
  return await (0, api_1.downloadCodeBundle)(config, org, agentName, version);
662
662
  }
@@ -667,7 +667,7 @@ async function downloadBundleWithFallback(config, org, agentName, version, agent
667
667
  if (!config.apiKey || !agentId) {
668
668
  throw new api_1.ApiError(`Bundle for '${org}/${agentName}@${version}' not found`, 404);
669
669
  }
670
- return await (0, api_1.downloadCodeBundleAuthenticated)(config, agentId);
670
+ return await (0, api_1.downloadCodeBundleAuthenticated)(config, agentId, workspaceId);
671
671
  }
672
672
  async function checkDependencies(config, dependencies) {
673
673
  const results = [];
@@ -738,7 +738,7 @@ async function downloadSkillDependency(config, ref, defaultOrg) {
738
738
  const skillData = await (0, api_1.publicRequest)(config, `/public/agents/${org}/${parsed.skill}/${parsed.version}/download`);
739
739
  await saveAgentLocally(org, parsed.skill, skillData);
740
740
  }
741
- async function downloadDependenciesRecursively(config, depStatuses, visited = new Set()) {
741
+ async function downloadDependenciesRecursively(config, depStatuses, visited = new Set(), workspaceId) {
742
742
  for (const status of depStatuses) {
743
743
  if (!status.downloadable || !status.agentData)
744
744
  continue;
@@ -750,7 +750,7 @@ async function downloadDependenciesRecursively(config, depStatuses, visited = ne
750
750
  await (0, spinner_1.withSpinner)(`Downloading dependency: ${depRef}...`, async () => {
751
751
  await saveAgentLocally(org, agent, status.agentData);
752
752
  if (status.agentData.has_bundle) {
753
- await saveBundleLocally(config, org, agent, status.dep.version, status.agentData.id);
753
+ await saveBundleLocally(config, org, agent, status.dep.version, status.agentData.id, workspaceId);
754
754
  }
755
755
  if (resolveExecutionEngine(status.agentData) === 'code_runtime' && (status.agentData.source_url || status.agentData.pip_package)) {
756
756
  await installTool(status.agentData);
@@ -767,7 +767,7 @@ async function downloadDependenciesRecursively(config, depStatuses, visited = ne
767
767
  }
768
768
  if (status.agentData.dependencies && status.agentData.dependencies.length > 0) {
769
769
  const nestedStatuses = await checkDependencies(config, status.agentData.dependencies);
770
- await downloadDependenciesRecursively(config, nestedStatuses, visited);
770
+ await downloadDependenciesRecursively(config, nestedStatuses, visited, workspaceId);
771
771
  }
772
772
  }
773
773
  }
@@ -1168,7 +1168,7 @@ async function unzipBundle(zipPath, destDir) {
1168
1168
  });
1169
1169
  });
1170
1170
  }
1171
- async function executeBundleAgent(config, org, agentName, version, agentData, args, inputOption) {
1171
+ async function executeBundleAgent(config, org, agentName, version, agentData, args, inputOption, workspaceId) {
1172
1172
  const userCwd = process.cwd();
1173
1173
  const tempDir = path_1.default.join(os_1.default.tmpdir(), `orchagent-${agentName}-${Date.now()}`);
1174
1174
  await promises_1.default.mkdir(tempDir, { recursive: true });
@@ -1176,7 +1176,7 @@ async function executeBundleAgent(config, org, agentName, version, agentData, ar
1176
1176
  const extractDir = path_1.default.join(tempDir, 'agent');
1177
1177
  try {
1178
1178
  const bundleBuffer = await (0, spinner_1.withSpinner)(`Downloading ${org}/${agentName}@${version} bundle...`, async () => {
1179
- const buffer = await downloadBundleWithFallback(config, org, agentName, version, agentData.id);
1179
+ const buffer = await downloadBundleWithFallback(config, org, agentName, version, agentData.id, workspaceId);
1180
1180
  await promises_1.default.writeFile(bundleZip, buffer);
1181
1181
  return buffer;
1182
1182
  }, { successText: (buf) => `Downloaded bundle (${buf.length} bytes)` });
@@ -1391,7 +1391,7 @@ async function saveAgentLocally(org, agent, agentData) {
1391
1391
  }
1392
1392
  return agentDir;
1393
1393
  }
1394
- async function saveBundleLocally(config, org, agent, version, agentId) {
1394
+ async function saveBundleLocally(config, org, agent, version, agentId, workspaceId) {
1395
1395
  const agentDir = path_1.default.join(AGENTS_DIR, org, agent);
1396
1396
  const bundleDir = path_1.default.join(agentDir, 'bundle');
1397
1397
  const metaPath = path_1.default.join(agentDir, 'agent.json');
@@ -1411,7 +1411,7 @@ async function saveBundleLocally(config, org, agent, version, agentId) {
1411
1411
  catch {
1412
1412
  // Metadata doesn't exist, need to download
1413
1413
  }
1414
- const bundleBuffer = await (0, spinner_1.withSpinner)(`Downloading bundle for ${org}/${agent}@${version}...`, async () => downloadBundleWithFallback(config, org, agent, version, agentId), { successText: `Downloaded bundle for ${org}/${agent}@${version}` });
1414
+ const bundleBuffer = await (0, spinner_1.withSpinner)(`Downloading bundle for ${org}/${agent}@${version}...`, async () => downloadBundleWithFallback(config, org, agent, version, agentId, workspaceId), { successText: `Downloaded bundle for ${org}/${agent}@${version}` });
1415
1415
  const tempZip = path_1.default.join(os_1.default.tmpdir(), `bundle-${Date.now()}.zip`);
1416
1416
  await promises_1.default.writeFile(tempZip, bundleBuffer);
1417
1417
  try {
@@ -2764,7 +2764,7 @@ async function executeLocal(agentRef, args, options) {
2764
2764
  process.stderr.write(` orch run ${org}/${parsed.agent}@${parsed.version} --data '{...}'\n\n`);
2765
2765
  process.exit(0);
2766
2766
  }
2767
- await downloadDependenciesRecursively(resolved, depStatuses);
2767
+ await downloadDependenciesRecursively(resolved, depStatuses, new Set(), workspaceId);
2768
2768
  }
2769
2769
  // Check if user is overriding locked skills
2770
2770
  const agentSkillsLocked = agentData.skills_locked;
@@ -2806,7 +2806,7 @@ async function executeLocal(agentRef, args, options) {
2806
2806
  });
2807
2807
  bundleInput = injected.body;
2808
2808
  }
2809
- await executeBundleAgent(resolved, org, parsed.agent, parsed.version, agentData, args, bundleInput);
2809
+ await executeBundleAgent(resolved, org, parsed.agent, parsed.version, agentData, args, bundleInput, workspaceId);
2810
2810
  return;
2811
2811
  }
2812
2812
  if (agentData.run_command && (agentData.source_url || agentData.pip_package)) {
@@ -196,6 +196,8 @@ Examples:
196
196
  throw new errors_1.CliError('Missing org. Use org/agent or set default org.');
197
197
  }
198
198
  const agentId = `${org}/${parsed.agent}/${parsed.version}`;
199
+ // Resolve workspace context for the target org
200
+ const workspaceId = await (0, api_1.resolveWorkspaceIdForOrg)(resolved, org);
199
201
  // Detect LLM key for the scan
200
202
  let llmKey;
201
203
  let llmProvider;
@@ -208,7 +210,13 @@ Examples:
208
210
  llmProvider = options.provider;
209
211
  }
210
212
  else {
211
- const detected = await (0, llm_1.detectLlmKey)(['any'], resolved);
213
+ // Respect --provider preference when detecting local keys
214
+ let providersToCheck = ['any'];
215
+ if (options.provider) {
216
+ (0, llm_1.validateProvider)(options.provider);
217
+ providersToCheck = [options.provider];
218
+ }
219
+ const detected = await (0, llm_1.detectLlmKey)(providersToCheck, resolved);
212
220
  if (detected) {
213
221
  llmKey = detected.key;
214
222
  llmProvider = detected.provider;
@@ -236,6 +244,9 @@ Examples:
236
244
  'Content-Type': 'application/json',
237
245
  Authorization: `Bearer ${resolved.apiKey}`,
238
246
  };
247
+ if (workspaceId) {
248
+ headers['X-Workspace-Id'] = workspaceId;
249
+ }
239
250
  if (llmKey) {
240
251
  headers['X-LLM-API-Key'] = llmKey;
241
252
  }
@@ -3,6 +3,7 @@ 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.NO_LLM_KEY_FIXTURE_MESSAGE = void 0;
6
7
  exports.registerTestCommand = registerTestCommand;
7
8
  const promises_1 = __importDefault(require("fs/promises"));
8
9
  const path_1 = __importDefault(require("path"));
@@ -18,6 +19,15 @@ const config_1 = require("../lib/config");
18
19
  const llm_1 = require("../lib/llm");
19
20
  const bundle_1 = require("../lib/bundle");
20
21
  const test_mock_runner_1 = require("../lib/test-mock-runner");
22
+ // ─── Constants ────────────────────────────────────────────────────────────────
23
+ exports.NO_LLM_KEY_FIXTURE_MESSAGE = 'No LLM API key found for fixture tests.\n\n' +
24
+ 'Fixture tests run locally on your machine and cannot access workspace vault keys.\n' +
25
+ 'Set a local environment variable:\n\n' +
26
+ ' export OPENAI_API_KEY=sk-...\n' +
27
+ ' export ANTHROPIC_API_KEY=sk-ant-...\n' +
28
+ ' export GEMINI_API_KEY=AI...\n\n' +
29
+ 'Or add it to a .env file in your agent directory.\n\n' +
30
+ 'To run with vault keys instead, use: orch run --cloud';
21
31
  // ─── Utility functions ───────────────────────────────────────────────────────
22
32
  function validateFixture(data, fixturePath) {
23
33
  const fileName = path_1.default.basename(fixturePath);
@@ -511,11 +521,10 @@ async function runPromptFixtureTests(agentDir, fixtures, verbose, config) {
511
521
  catch {
512
522
  // Schema is optional
513
523
  }
514
- // Detect LLM key
524
+ // Detect LLM key — fixture tests run locally, so vault keys can't be used
515
525
  const detected = await (0, llm_1.detectLlmKey)(['any'], config);
516
526
  if (!detected) {
517
- throw new errors_1.CliError('No LLM key found for fixture tests.\n' +
518
- 'Set an environment variable (e.g., OPENAI_API_KEY) or run `orch secrets set <PROVIDER>_API_KEY <key>`');
527
+ throw new errors_1.CliError(exports.NO_LLM_KEY_FIXTURE_MESSAGE);
519
528
  }
520
529
  const { provider, key, model: serverModel } = detected;
521
530
  const model = serverModel ?? (0, llm_1.getDefaultModel)(provider);
@@ -27,7 +27,9 @@ function registerTreeCommand(program) {
27
27
  throw new errors_1.CliError('Missing org. Use org/agent format or set default org.');
28
28
  }
29
29
  const { agent, version } = parsed;
30
- const tree = await (0, api_1.request)(config, 'GET', `/agents/${org}/${agent}/${version}/tree`);
30
+ // Resolve workspace context for team workspaces
31
+ const workspaceId = await (0, api_1.resolveWorkspaceIdForOrg)(config, org);
32
+ const tree = await (0, api_1.request)(config, 'GET', `/agents/${org}/${agent}/${version}/tree`, ...(workspaceId ? [{ headers: { 'X-Workspace-Id': workspaceId } }] : []));
31
33
  if (options.json) {
32
34
  console.log(JSON.stringify(tree, null, 2));
33
35
  return;
package/dist/lib/api.js CHANGED
@@ -284,8 +284,14 @@ async function updateOrg(config, payload) {
284
284
  async function getPublicAgent(config, org, agent, version) {
285
285
  return publicRequest(config, `/public/agents/${org}/${agent}/${version}`);
286
286
  }
287
- async function getAgentCostEstimate(config, org, agent, version) {
288
- return publicRequest(config, `/public/agents/${org}/${agent}/${version}/cost-estimate`);
287
+ async function getAgentCostEstimate(config, org, agent, version, workspaceId) {
288
+ const path = `/public/agents/${org}/${agent}/${version}/cost-estimate`;
289
+ if (workspaceId && config.apiKey) {
290
+ return request(config, 'GET', path, {
291
+ headers: { 'X-Workspace-Id': workspaceId },
292
+ });
293
+ }
294
+ return publicRequest(config, path);
289
295
  }
290
296
  async function listMyAgents(config, workspaceId) {
291
297
  const headers = {};
@@ -402,15 +408,16 @@ async function resolveWorkspaceIdForOrg(config, orgSlug) {
402
408
  /**
403
409
  * Download a tool bundle for a private agent using authenticated endpoint.
404
410
  */
405
- async function downloadCodeBundleAuthenticated(config, agentId) {
411
+ async function downloadCodeBundleAuthenticated(config, agentId, workspaceId) {
406
412
  if (!config.apiKey) {
407
413
  throw new ApiError('Missing API key for authenticated bundle download', 401);
408
414
  }
409
- const response = await safeFetch(`${config.apiUrl.replace(/\/$/, '')}/agents/${agentId}/bundle`, {
410
- headers: {
411
- Authorization: `Bearer ${config.apiKey}`,
412
- },
413
- });
415
+ const headers = {
416
+ Authorization: `Bearer ${config.apiKey}`,
417
+ };
418
+ if (workspaceId)
419
+ headers['X-Workspace-Id'] = workspaceId;
420
+ const response = await safeFetch(`${config.apiUrl.replace(/\/$/, '')}/agents/${agentId}/bundle`, { headers });
414
421
  if (!response.ok) {
415
422
  const text = await response.text();
416
423
  let message = response.statusText;
@@ -548,12 +555,21 @@ async function setWorkspaceDefaultEnvironment(config, workspaceId, environmentId
548
555
  headers: { 'Content-Type': 'application/json' },
549
556
  });
550
557
  }
551
- async function listAgentKeys(config, agentId) {
552
- return request(config, 'GET', `/agents/${agentId}/keys`);
558
+ async function listAgentKeys(config, agentId, workspaceId) {
559
+ const headers = {};
560
+ if (workspaceId)
561
+ headers['X-Workspace-Id'] = workspaceId;
562
+ return request(config, 'GET', `/agents/${agentId}/keys`, { headers });
553
563
  }
554
- async function createAgentKey(config, agentId) {
555
- return request(config, 'POST', `/agents/${agentId}/keys`);
564
+ async function createAgentKey(config, agentId, workspaceId) {
565
+ const headers = {};
566
+ if (workspaceId)
567
+ headers['X-Workspace-Id'] = workspaceId;
568
+ return request(config, 'POST', `/agents/${agentId}/keys`, { headers });
556
569
  }
557
- async function deleteAgentKey(config, agentId, keyId) {
558
- return request(config, 'DELETE', `/agents/${agentId}/keys/${keyId}`);
570
+ async function deleteAgentKey(config, agentId, keyId, workspaceId) {
571
+ const headers = {};
572
+ if (workspaceId)
573
+ headers['X-Workspace-Id'] = workspaceId;
574
+ return request(config, 'DELETE', `/agents/${agentId}/keys/${keyId}`, { headers });
559
575
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchagent/cli",
3
- "version": "0.3.99",
3
+ "version": "0.3.100",
4
4
  "description": "Command-line interface for orchagent — deploy and run AI agents for your team",
5
5
  "license": "MIT",
6
6
  "author": "orchagent <hello@orchagent.io>",