@orchagent/cli 0.3.63 → 0.3.64

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.
@@ -86,15 +86,15 @@ if __name__ == "__main__":
86
86
  main()
87
87
  `;
88
88
  function readmeTemplate(agentName, flavor) {
89
- const inputField = flavor === 'managed_loop' ? 'task' : 'input';
90
- const inputDescription = flavor === 'managed_loop' ? 'The task to perform' : 'The input to process';
89
+ const inputField = flavor === 'managed_loop' || flavor === 'orchestrator' ? 'task' : 'input';
90
+ const inputDescription = flavor === 'managed_loop' || flavor === 'orchestrator' ? 'The task to perform' : 'The input to process';
91
91
  const cloudExample = flavor === 'code_runtime'
92
92
  ? `orchagent run ${agentName} --data '{"input": "Hello world"}'`
93
93
  : `orchagent run ${agentName} --data '{"${inputField}": "Hello world"}'`;
94
94
  const localExample = flavor === 'code_runtime'
95
95
  ? `orchagent run ${agentName} --local --data '{"input": "Hello world"}'`
96
96
  : `orchagent run ${agentName} --local --data '{"${inputField}": "Hello world"}'`;
97
- return `# ${agentName}
97
+ let readme = `# ${agentName}
98
98
 
99
99
  A brief description of what this agent does.
100
100
 
@@ -124,6 +124,20 @@ ${localExample}
124
124
  |-------|------|-------------|
125
125
  | \`result\` | string | The agent's response |
126
126
  `;
127
+ if (flavor === 'orchestrator') {
128
+ readme += `
129
+ ## Dependencies
130
+
131
+ This orchestrator calls other agents. Update \`manifest.dependencies\` in \`orchagent.json\` with your actual dependencies.
132
+
133
+ **Publish order:** Publish dependency agents first, then this orchestrator.
134
+
135
+ | Dependency | Version | Description |
136
+ |------------|---------|-------------|
137
+ | \`org/agent-name\` | v1 | TODO: describe what this agent does |
138
+ `;
139
+ }
140
+ return readme;
127
141
  }
128
142
  const AGENT_PROMPT_TEMPLATE = `You are a helpful AI agent.
129
143
 
@@ -157,6 +171,65 @@ const AGENT_SCHEMA_TEMPLATE = `{
157
171
  }
158
172
  }
159
173
  `;
174
+ const ORCHESTRATOR_MAIN_PY = `"""
175
+ orchagent orchestrator entrypoint.
176
+
177
+ Reads JSON input from stdin, calls dependency agents via the orchagent SDK,
178
+ and writes JSON output to stdout.
179
+
180
+ Usage:
181
+ echo '{"task": "do something"}' | python main.py
182
+ """
183
+
184
+ import asyncio
185
+ import json
186
+ import sys
187
+
188
+ from orchagent import AgentClient
189
+
190
+
191
+ def main():
192
+ # Read JSON input from stdin
193
+ raw = sys.stdin.read()
194
+ try:
195
+ data = json.loads(raw) if raw.strip() else {}
196
+ except json.JSONDecodeError:
197
+ print(json.dumps({"error": "Invalid JSON input"}))
198
+ sys.exit(1)
199
+
200
+ task = data.get("task", "")
201
+
202
+ # --- Your orchestration logic here ---
203
+ # The AgentClient reads ORCHAGENT_SERVICE_KEY from the environment automatically.
204
+ # Do NOT add ORCHAGENT_SERVICE_KEY to required_secrets — the gateway injects it.
205
+ client = AgentClient()
206
+
207
+ # Call a dependency agent (must be listed in manifest.dependencies)
208
+ result = asyncio.run(
209
+ client.call("org/agent-name@v1", {"input": task})
210
+ )
211
+
212
+ # You can chain multiple calls, run them in parallel, or add conditional logic:
213
+ #
214
+ # Sequential:
215
+ # result2 = asyncio.run(client.call("org/another-agent@v1", {"input": result}))
216
+ #
217
+ # Parallel:
218
+ # r1, r2 = asyncio.run(asyncio.gather(
219
+ # client.call("org/agent-a@v1", {"input": task}),
220
+ # client.call("org/agent-b@v1", {"input": task}),
221
+ # ))
222
+ # --- End orchestration logic ---
223
+
224
+ # Write JSON output to stdout
225
+ print(json.dumps({"result": result, "success": True}))
226
+
227
+
228
+ if __name__ == "__main__":
229
+ main()
230
+ `;
231
+ const ORCHESTRATOR_REQUIREMENTS = `orchagent-sdk>=0.1.0
232
+ `;
160
233
  const SKILL_TEMPLATE = `---
161
234
  name: my-skill
162
235
  description: When to use this skill
@@ -189,6 +262,7 @@ function registerInitCommand(program) {
189
262
  .description('Initialize a new agent project')
190
263
  .argument('[name]', 'Agent name (default: current directory name)')
191
264
  .option('--type <type>', 'Type: prompt, tool, agent, or skill (legacy aliases: agentic, code)', 'prompt')
265
+ .option('--orchestrator', 'Create an orchestrator agent with dependency scaffolding and SDK boilerplate')
192
266
  .option('--run-mode <mode>', 'Run mode for agents: on_demand or always_on', 'on_demand')
193
267
  .action(async (name, options) => {
194
268
  const cwd = process.cwd();
@@ -196,7 +270,13 @@ function registerInitCommand(program) {
196
270
  if (!['on_demand', 'always_on'].includes(runMode)) {
197
271
  throw new errors_1.CliError("Invalid --run-mode. Use 'on_demand' or 'always_on'.");
198
272
  }
199
- const initMode = resolveInitFlavor(options.type);
273
+ let initMode = resolveInitFlavor(options.type);
274
+ if (options.orchestrator) {
275
+ if (initMode.type === 'skill') {
276
+ throw new errors_1.CliError('Cannot use --orchestrator with --type skill. Orchestrators are agent-type agents that call other agents.');
277
+ }
278
+ initMode = { type: 'agent', flavor: 'orchestrator' };
279
+ }
200
280
  // When a name is provided, create a subdirectory for the project
201
281
  const targetDir = name ? path_1.default.join(cwd, name) : cwd;
202
282
  const agentName = name || path_1.default.basename(cwd);
@@ -247,7 +327,7 @@ function registerInitCommand(program) {
247
327
  throw err;
248
328
  }
249
329
  }
250
- if (initMode.flavor !== 'code_runtime' && runMode === 'always_on') {
330
+ if (initMode.flavor !== 'code_runtime' && initMode.flavor !== 'orchestrator' && runMode === 'always_on') {
251
331
  throw new errors_1.CliError("run_mode=always_on requires runtime.command in orchagent.json (e.g. \"runtime\": { \"command\": \"python main.py\" }). Use --type tool for code-runtime agents.");
252
332
  }
253
333
  // Create manifest and type-specific files
@@ -255,7 +335,19 @@ function registerInitCommand(program) {
255
335
  manifest.name = agentName;
256
336
  manifest.type = initMode.type;
257
337
  manifest.run_mode = runMode;
258
- if (initMode.flavor === 'managed_loop') {
338
+ if (initMode.flavor === 'orchestrator') {
339
+ manifest.description = 'An orchestrator agent that coordinates other agents';
340
+ manifest.runtime = { command: 'python main.py' };
341
+ manifest.manifest = {
342
+ manifest_version: 1,
343
+ dependencies: [{ id: 'org/agent-name', version: 'v1' }],
344
+ max_hops: 3,
345
+ timeout_ms: 120000,
346
+ per_call_downstream_cap: 50,
347
+ };
348
+ manifest.required_secrets = [];
349
+ }
350
+ else if (initMode.flavor === 'managed_loop') {
259
351
  manifest.description = 'An AI agent with tool use';
260
352
  manifest.supported_providers = ['anthropic'];
261
353
  manifest.loop = { max_turns: 25 };
@@ -267,7 +359,14 @@ function registerInitCommand(program) {
267
359
  manifest.required_secrets = [];
268
360
  }
269
361
  await promises_1.default.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
270
- if (initMode.flavor === 'code_runtime') {
362
+ if (initMode.flavor === 'orchestrator') {
363
+ const entrypointPath = path_1.default.join(targetDir, 'main.py');
364
+ const requirementsPath = path_1.default.join(targetDir, 'requirements.txt');
365
+ await promises_1.default.writeFile(entrypointPath, ORCHESTRATOR_MAIN_PY);
366
+ await promises_1.default.writeFile(requirementsPath, ORCHESTRATOR_REQUIREMENTS);
367
+ await promises_1.default.writeFile(schemaPath, AGENT_SCHEMA_TEMPLATE);
368
+ }
369
+ else if (initMode.flavor === 'code_runtime') {
271
370
  const entrypointPath = path_1.default.join(targetDir, 'main.py');
272
371
  await promises_1.default.writeFile(entrypointPath, CODE_TEMPLATE_PY);
273
372
  await promises_1.default.writeFile(schemaPath, SCHEMA_TEMPLATE);
@@ -286,19 +385,32 @@ function registerInitCommand(program) {
286
385
  process.stdout.write(`Initialized agent "${agentName}" in ${targetDir}\n`);
287
386
  process.stdout.write(`\nFiles created:\n`);
288
387
  const prefix = name ? name + '/' : '';
289
- process.stdout.write(` ${prefix}orchagent.json - Agent configuration\n`);
290
- if (initMode.flavor === 'code_runtime') {
291
- process.stdout.write(` ${prefix}main.py - Agent entrypoint (stdin/stdout JSON)\n`);
388
+ process.stdout.write(` ${prefix}orchagent.json - Agent configuration\n`);
389
+ if (initMode.flavor === 'orchestrator') {
390
+ process.stdout.write(` ${prefix}main.py - Orchestrator entrypoint (SDK calls)\n`);
391
+ process.stdout.write(` ${prefix}requirements.txt - Python dependencies (orchagent-sdk)\n`);
392
+ }
393
+ else if (initMode.flavor === 'code_runtime') {
394
+ process.stdout.write(` ${prefix}main.py - Agent entrypoint (stdin/stdout JSON)\n`);
292
395
  }
293
396
  else {
294
- process.stdout.write(` ${prefix}prompt.md - Prompt template\n`);
397
+ process.stdout.write(` ${prefix}prompt.md - Prompt template\n`);
295
398
  }
296
- process.stdout.write(` ${prefix}schema.json - Input/output schemas\n`);
297
- process.stdout.write(` ${prefix}README.md - Agent documentation\n`);
399
+ process.stdout.write(` ${prefix}schema.json - Input/output schemas\n`);
400
+ process.stdout.write(` ${prefix}README.md - Agent documentation\n`);
298
401
  process.stdout.write(` Run mode: ${runMode}\n`);
299
- process.stdout.write(` Execution: ${initMode.flavor}\n`);
402
+ process.stdout.write(` Execution: ${initMode.flavor === 'orchestrator' ? 'code_runtime (orchestrator)' : initMode.flavor}\n`);
300
403
  process.stdout.write(`\nNext steps:\n`);
301
- if (initMode.flavor === 'code_runtime') {
404
+ if (initMode.flavor === 'orchestrator') {
405
+ const stepNum = name ? 2 : 1;
406
+ if (name) {
407
+ process.stdout.write(` 1. cd ${name}\n`);
408
+ }
409
+ process.stdout.write(` ${stepNum}. Update manifest.dependencies in orchagent.json with your actual agents\n`);
410
+ process.stdout.write(` ${stepNum + 1}. Edit main.py with your orchestration logic\n`);
411
+ process.stdout.write(` ${stepNum + 2}. Publish dependency agents first, then: orchagent publish\n`);
412
+ }
413
+ else if (initMode.flavor === 'code_runtime') {
302
414
  const stepNum = name ? 2 : 1;
303
415
  if (name) {
304
416
  process.stdout.write(` 1. cd ${name}\n`);
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.extractTemplateVariables = extractTemplateVariables;
7
7
  exports.deriveInputSchema = deriveInputSchema;
8
8
  exports.scanUndeclaredEnvVars = scanUndeclaredEnvVars;
9
+ exports.checkDependencies = checkDependencies;
9
10
  exports.registerPublishCommand = registerPublishCommand;
10
11
  const promises_1 = __importDefault(require("fs/promises"));
11
12
  const path_1 = __importDefault(require("path"));
@@ -15,7 +16,6 @@ const chalk_1 = __importDefault(require("chalk"));
15
16
  const config_1 = require("../lib/config");
16
17
  const api_1 = require("../lib/api");
17
18
  const errors_1 = require("../lib/errors");
18
- const api_2 = require("../lib/api");
19
19
  const analytics_1 = require("../lib/analytics");
20
20
  const bundle_1 = require("../lib/bundle");
21
21
  /**
@@ -270,6 +270,56 @@ function commandForEntrypoint(entrypoint) {
270
270
  }
271
271
  return `python ${entrypoint}`;
272
272
  }
273
+ /**
274
+ * Check if manifest dependencies are published and callable.
275
+ * Best-effort: network errors cause the check to be silently skipped
276
+ * (returns empty array) to avoid false alarms.
277
+ */
278
+ async function checkDependencies(config, dependencies, publishingOrgSlug, workspaceId) {
279
+ // Pre-fetch user's agents if any deps are in the same org (one API call)
280
+ let myAgents = null;
281
+ const hasSameOrgDeps = dependencies.some(d => {
282
+ const [org] = d.id.split('/');
283
+ return org === publishingOrgSlug;
284
+ });
285
+ if (hasSameOrgDeps) {
286
+ try {
287
+ const headers = {};
288
+ if (workspaceId)
289
+ headers['X-Workspace-Id'] = workspaceId;
290
+ myAgents = await (0, api_1.request)(config, 'GET', '/agents', { headers });
291
+ }
292
+ catch {
293
+ return []; // Can't reach API — skip check entirely
294
+ }
295
+ }
296
+ return Promise.all(dependencies.map(async (dep) => {
297
+ const parts = dep.id.split('/');
298
+ const ref = `${dep.id}@${dep.version}`;
299
+ if (parts.length !== 2)
300
+ return { ref, status: 'not_found' };
301
+ const [depOrg, depName] = parts;
302
+ // Same org: check against pre-fetched agent list
303
+ if (depOrg === publishingOrgSlug && myAgents) {
304
+ const match = myAgents.find(a => a.name === depName && a.version === dep.version);
305
+ if (!match)
306
+ return { ref, status: 'not_found' };
307
+ return { ref, status: match.callable ? 'found_callable' : 'found_not_callable' };
308
+ }
309
+ // Different org: try public endpoint
310
+ try {
311
+ const agent = await (0, api_1.getPublicAgent)(config, depOrg, depName, dep.version);
312
+ return { ref, status: agent.callable ? 'found_callable' : 'found_not_callable' };
313
+ }
314
+ catch (err) {
315
+ if (err?.status === 404) {
316
+ return { ref, status: 'not_found' };
317
+ }
318
+ // Network/unexpected error — don't false alarm
319
+ return { ref, status: 'found_callable' };
320
+ }
321
+ }));
322
+ }
273
323
  function registerPublishCommand(program) {
274
324
  program
275
325
  .command('publish')
@@ -287,18 +337,33 @@ function registerPublishCommand(program) {
287
337
  : undefined;
288
338
  const config = await (0, config_1.getResolvedConfig)({}, options.profile);
289
339
  const cwd = process.cwd();
340
+ // Resolve workspace context — if `orch workspace use` was called, publish
341
+ // to that workspace instead of the personal org (F-5)
342
+ const configFile = await (0, config_1.loadConfig)();
343
+ let workspaceId;
344
+ if (configFile.workspace) {
345
+ const { workspaces } = await (0, api_1.request)(config, 'GET', '/workspaces');
346
+ const ws = workspaces.find(w => w.slug === configFile.workspace);
347
+ if (!ws) {
348
+ throw new errors_1.CliError(`Workspace '${configFile.workspace}' not found. Run \`orch workspace list\` to see available workspaces.`);
349
+ }
350
+ workspaceId = ws.id;
351
+ }
290
352
  // Check for SKILL.md first (skills take precedence)
291
353
  const skillMdPath = path_1.default.join(cwd, 'SKILL.md');
292
354
  const skillData = await parseSkillMd(skillMdPath);
293
355
  if (skillData) {
294
356
  // Publish as a skill (server auto-assigns version)
295
- const org = await (0, api_1.getOrg)(config);
357
+ const org = await (0, api_1.getOrg)(config, workspaceId);
358
+ if (workspaceId && !options.dryRun) {
359
+ process.stdout.write(`Workspace: ${org.slug}\n`);
360
+ }
296
361
  // SC-05: Collect all files in the skill directory for multi-file support
297
362
  const skillFiles = await collectSkillFiles(cwd);
298
363
  const hasMultipleFiles = skillFiles.length > 1;
299
364
  // Handle dry-run for skills
300
365
  if (options.dryRun) {
301
- const preview = await (0, api_1.previewAgentVersion)(config, skillData.frontmatter.name);
366
+ const preview = await (0, api_1.previewAgentVersion)(config, skillData.frontmatter.name, workspaceId);
302
367
  const skillBodyBytes = Buffer.byteLength(skillData.body, 'utf-8');
303
368
  const totalFilesSize = skillFiles.reduce((sum, f) => sum + f.size, 0);
304
369
  const versionInfo = preview.existing_versions.length > 0
@@ -315,6 +380,9 @@ function registerPublishCommand(program) {
315
380
  process.stderr.write('\nSkill Preview:\n');
316
381
  process.stderr.write(` Name: ${skillData.frontmatter.name}\n`);
317
382
  process.stderr.write(` Type: skill\n`);
383
+ if (workspaceId) {
384
+ process.stderr.write(` Workspace: ${org.slug}\n`);
385
+ }
318
386
  process.stderr.write(` Version: ${versionInfo}\n`);
319
387
  process.stderr.write(` Visibility: private\n`);
320
388
  process.stderr.write(` Providers: any\n`);
@@ -345,7 +413,7 @@ function registerPublishCommand(program) {
345
413
  // SC-05: Include all skill files for UI preview
346
414
  skill_files: hasMultipleFiles ? skillFiles : undefined,
347
415
  allow_local_download: options.localDownload || false,
348
- });
416
+ }, workspaceId);
349
417
  const skillVersion = skillResult.agent?.version || 'v1';
350
418
  const skillAgentId = skillResult.agent?.id;
351
419
  await (0, analytics_1.track)('cli_publish', { agent_type: 'skill', multi_file: hasMultipleFiles });
@@ -574,8 +642,11 @@ function registerPublishCommand(program) {
574
642
  if (options.docker && executionEngine !== 'code_runtime') {
575
643
  throw new errors_1.CliError('--docker is only supported for code runtime agents');
576
644
  }
577
- // Get org info
578
- const org = await (0, api_1.getOrg)(config);
645
+ // Get org info (workspace-aware — returns workspace org if workspace is active)
646
+ const org = await (0, api_1.getOrg)(config, workspaceId);
647
+ if (workspaceId && !options.dryRun) {
648
+ process.stdout.write(`Workspace: ${org.slug}\n`);
649
+ }
579
650
  // Default to 'any' provider if not specified
580
651
  const supportedProviders = manifest.supported_providers || ['any'];
581
652
  // Detect SDK compatibility for code runtime agents
@@ -586,9 +657,33 @@ function registerPublishCommand(program) {
586
657
  process.stdout.write(`SDK detected - agent will be marked as Local Ready\n`);
587
658
  }
588
659
  }
660
+ // Check if manifest dependencies are published and callable (F-9b).
661
+ // Runs for both dry-run and normal publish so users catch issues early.
662
+ const manifestDeps = manifest.manifest?.dependencies;
663
+ if (manifestDeps?.length) {
664
+ const depResults = await checkDependencies(config, manifestDeps, org.slug, workspaceId);
665
+ const notFound = depResults.filter(r => r.status === 'not_found');
666
+ const notCallable = depResults.filter(r => r.status === 'found_not_callable');
667
+ if (notFound.length > 0) {
668
+ process.stderr.write(chalk_1.default.yellow(`\n⚠ Unpublished dependencies:\n`));
669
+ for (const dep of notFound) {
670
+ process.stderr.write(chalk_1.default.yellow(` - ${dep.ref}\n`));
671
+ }
672
+ process.stderr.write(`\n These agents must be published before this orchestrator can call them.\n` +
673
+ ` Publish each dependency first, then re-run this publish.\n\n`);
674
+ }
675
+ if (notCallable.length > 0) {
676
+ process.stderr.write(chalk_1.default.yellow(`\n⚠ Dependencies not marked as callable:\n`));
677
+ for (const dep of notCallable) {
678
+ process.stderr.write(chalk_1.default.yellow(` - ${dep.ref}\n`));
679
+ }
680
+ process.stderr.write(`\n Agents must have callable: true in orchagent.json to be invoked\n` +
681
+ ` by orchestrators. Update and republish each dependency.\n\n`);
682
+ }
683
+ }
589
684
  // Handle dry-run for agents
590
685
  if (options.dryRun) {
591
- const preview = await (0, api_1.previewAgentVersion)(config, manifest.name);
686
+ const preview = await (0, api_1.previewAgentVersion)(config, manifest.name, workspaceId);
592
687
  const versionInfo = preview.existing_versions.length > 0
593
688
  ? `${preview.next_version} (new version, ${preview.existing_versions[preview.existing_versions.length - 1]} exists)`
594
689
  : `${preview.next_version} (first version)`;
@@ -641,6 +736,9 @@ function registerPublishCommand(program) {
641
736
  process.stderr.write('\nAgent Preview:\n');
642
737
  process.stderr.write(` Name: ${manifest.name}\n`);
643
738
  process.stderr.write(` Type: ${canonicalType}\n`);
739
+ if (workspaceId) {
740
+ process.stderr.write(` Workspace: ${org.slug}\n`);
741
+ }
644
742
  process.stderr.write(` Run mode: ${runMode}\n`);
645
743
  process.stderr.write(` Engine: ${executionEngine}${shouldUploadBundle ? ' (hosted)' : ''}\n`);
646
744
  process.stderr.write(` Callable: ${callable ? 'enabled' : 'disabled'}\n`);
@@ -719,11 +817,11 @@ function registerPublishCommand(program) {
719
817
  default_skills: skillsFromFlag || manifest.default_skills,
720
818
  skills_locked: manifest.skills_locked || options.skillsLocked || undefined,
721
819
  allow_local_download: options.localDownload || false,
722
- });
820
+ }, workspaceId);
723
821
  }
724
822
  catch (err) {
725
823
  // Improve SECURITY_BLOCKED error display
726
- if (err instanceof api_2.ApiError && err.status === 422) {
824
+ if (err instanceof api_1.ApiError && err.status === 422) {
727
825
  const payload = err.payload;
728
826
  const errorCode = payload?.error?.code;
729
827
  if (errorCode === 'SECURITY_BLOCKED') {
@@ -855,6 +953,22 @@ function registerPublishCommand(program) {
855
953
  process.stdout.write(`\nService key (save this - shown only once):\n`);
856
954
  process.stdout.write(` ${result.service_key}\n`);
857
955
  }
956
+ // Show next-step CLI command based on run mode
957
+ const runRef = `${org.slug}/${manifest.name}`;
958
+ if (runMode === 'always_on') {
959
+ process.stdout.write(`\nDeploy as service:\n`);
960
+ process.stdout.write(` orch service deploy ${runRef}\n`);
961
+ }
962
+ else {
963
+ const schemaProps = inputSchema && typeof inputSchema === 'object' && 'properties' in inputSchema
964
+ ? Object.keys(inputSchema.properties).slice(0, 3)
965
+ : null;
966
+ const exampleFields = schemaProps?.length
967
+ ? schemaProps.map(k => `"${k}": "..."`).join(', ')
968
+ : '"input": "..."';
969
+ process.stdout.write(`\nRun with CLI:\n`);
970
+ process.stdout.write(` orch run ${runRef} --data '{${exampleFields}}'\n`);
971
+ }
858
972
  process.stdout.write(`\nAPI endpoint:\n`);
859
973
  process.stdout.write(` POST ${config.apiUrl}/${org.slug}/${manifest.name}/${assignedVersion}/run\n`);
860
974
  if (shouldUploadBundle) {
package/dist/lib/api.js CHANGED
@@ -275,8 +275,11 @@ async function publicRequest(config, path) {
275
275
  }
276
276
  return (await response.json());
277
277
  }
278
- async function getOrg(config) {
279
- return request(config, 'GET', '/org');
278
+ async function getOrg(config, workspaceId) {
279
+ const headers = {};
280
+ if (workspaceId)
281
+ headers['X-Workspace-Id'] = workspaceId;
282
+ return request(config, 'GET', '/org', { headers });
280
283
  }
281
284
  async function updateOrg(config, payload) {
282
285
  return request(config, 'PATCH', '/org', {
@@ -290,10 +293,13 @@ async function getPublicAgent(config, org, agent, version) {
290
293
  async function listMyAgents(config) {
291
294
  return request(config, 'GET', '/agents');
292
295
  }
293
- async function createAgent(config, data) {
296
+ async function createAgent(config, data, workspaceId) {
297
+ const headers = { 'Content-Type': 'application/json' };
298
+ if (workspaceId)
299
+ headers['X-Workspace-Id'] = workspaceId;
294
300
  return request(config, 'POST', '/agents', {
295
301
  body: JSON.stringify(data),
296
- headers: { 'Content-Type': 'application/json' },
302
+ headers,
297
303
  });
298
304
  }
299
305
  async function fetchLlmKeys(config) {
@@ -446,8 +452,11 @@ async function transferAgent(config, agentId, data) {
446
452
  /**
447
453
  * Preview the next version number for an agent.
448
454
  */
449
- async function previewAgentVersion(config, agentName) {
450
- return request(config, 'GET', `/agents/preview?name=${encodeURIComponent(agentName)}`);
455
+ async function previewAgentVersion(config, agentName, workspaceId) {
456
+ const headers = {};
457
+ if (workspaceId)
458
+ headers['X-Workspace-Id'] = workspaceId;
459
+ return request(config, 'GET', `/agents/preview?name=${encodeURIComponent(agentName)}`, { headers });
451
460
  }
452
461
  /**
453
462
  * Report a skill installation to the backend.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchagent/cli",
3
- "version": "0.3.63",
3
+ "version": "0.3.64",
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>",