@orchagent/cli 0.2.8 → 0.2.9
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.
- package/dist/commands/run.js +99 -3
- package/package.json +1 -1
package/dist/commands/run.js
CHANGED
|
@@ -48,6 +48,13 @@ const output_1 = require("../lib/output");
|
|
|
48
48
|
const llm_1 = require("../lib/llm");
|
|
49
49
|
const DEFAULT_VERSION = 'latest';
|
|
50
50
|
const AGENTS_DIR = path_1.default.join(os_1.default.homedir(), '.orchagent', 'agents');
|
|
51
|
+
// Local execution environment variables
|
|
52
|
+
const LOCAL_EXECUTION_ENV = 'ORCHAGENT_LOCAL_EXECUTION';
|
|
53
|
+
const AGENTS_DIR_ENV = 'ORCHAGENT_AGENTS_DIR';
|
|
54
|
+
const CALL_CHAIN_ENV = 'ORCHAGENT_CALL_CHAIN';
|
|
55
|
+
const DEADLINE_MS_ENV = 'ORCHAGENT_DEADLINE_MS';
|
|
56
|
+
const MAX_HOPS_ENV = 'ORCHAGENT_MAX_HOPS';
|
|
57
|
+
const DOWNSTREAM_REMAINING_ENV = 'ORCHAGENT_DOWNSTREAM_REMAINING';
|
|
51
58
|
function parseAgentRef(value) {
|
|
52
59
|
const [ref, versionPart] = value.split('@');
|
|
53
60
|
const version = versionPart?.trim() || DEFAULT_VERSION;
|
|
@@ -70,7 +77,7 @@ async function checkDependencies(config, dependencies) {
|
|
|
70
77
|
const [org, agent] = dep.id.split('/');
|
|
71
78
|
try {
|
|
72
79
|
const agentData = await downloadAgent(config, org, agent, dep.version);
|
|
73
|
-
const downloadable = !!(agentData.source_url || agentData.pip_package || agentData.type === 'prompt');
|
|
80
|
+
const downloadable = !!(agentData.source_url || agentData.pip_package || agentData.has_bundle || agentData.type === 'prompt');
|
|
74
81
|
results.push({ dep, downloadable, agentData });
|
|
75
82
|
}
|
|
76
83
|
catch {
|
|
@@ -117,6 +124,12 @@ async function promptUserForDeps(depStatuses) {
|
|
|
117
124
|
});
|
|
118
125
|
});
|
|
119
126
|
}
|
|
127
|
+
async function downloadSkillDependency(config, ref, defaultOrg) {
|
|
128
|
+
const parsed = parseSkillRef(ref);
|
|
129
|
+
const org = parsed.org ?? defaultOrg;
|
|
130
|
+
const skillData = await (0, api_1.publicRequest)(config, `/public/agents/${org}/${parsed.skill}/${parsed.version}/download`);
|
|
131
|
+
await saveAgentLocally(org, parsed.skill, skillData);
|
|
132
|
+
}
|
|
120
133
|
async function downloadDependenciesRecursively(config, depStatuses, visited = new Set()) {
|
|
121
134
|
for (const status of depStatuses) {
|
|
122
135
|
if (!status.downloadable || !status.agentData)
|
|
@@ -127,12 +140,27 @@ async function downloadDependenciesRecursively(config, depStatuses, visited = ne
|
|
|
127
140
|
visited.add(depRef);
|
|
128
141
|
const [org, agent] = status.dep.id.split('/');
|
|
129
142
|
process.stderr.write(`\nDownloading dependency: ${depRef}...\n`);
|
|
130
|
-
// Save the dependency locally
|
|
143
|
+
// Save the dependency metadata locally
|
|
131
144
|
await saveAgentLocally(org, agent, status.agentData);
|
|
132
|
-
//
|
|
145
|
+
// For bundle-based agents, also extract the bundle
|
|
146
|
+
if (status.agentData.has_bundle) {
|
|
147
|
+
await saveBundleLocally(config, org, agent, status.dep.version);
|
|
148
|
+
}
|
|
149
|
+
// Install if it's a pip/source code agent
|
|
133
150
|
if (status.agentData.type === 'code' && (status.agentData.source_url || status.agentData.pip_package)) {
|
|
134
151
|
await installCodeAgent(status.agentData);
|
|
135
152
|
}
|
|
153
|
+
// Download default skills
|
|
154
|
+
const defaultSkills = status.agentData.default_skills || [];
|
|
155
|
+
for (const skillRef of defaultSkills) {
|
|
156
|
+
try {
|
|
157
|
+
await downloadSkillDependency(config, skillRef, org);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Skill download failed - not critical, continue
|
|
161
|
+
process.stderr.write(` Warning: Failed to download skill ${skillRef}\n`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
136
164
|
// Recursively download its dependencies
|
|
137
165
|
if (status.agentData.dependencies && status.agentData.dependencies.length > 0) {
|
|
138
166
|
const nestedStatuses = await checkDependencies(config, status.agentData.dependencies);
|
|
@@ -393,9 +421,32 @@ async function executeBundleAgent(config, org, agentName, version, agentData, ar
|
|
|
393
421
|
}
|
|
394
422
|
// Run the entrypoint with input via stdin
|
|
395
423
|
process.stderr.write(`\nRunning: python3 ${entrypoint}\n\n`);
|
|
424
|
+
// Pass auth credentials to subprocess for orchestrator agents calling sub-agents
|
|
425
|
+
const subprocessEnv = { ...process.env };
|
|
426
|
+
if (config.apiKey) {
|
|
427
|
+
subprocessEnv.ORCHAGENT_SERVICE_KEY = config.apiKey;
|
|
428
|
+
subprocessEnv.ORCHAGENT_API_URL = config.apiUrl;
|
|
429
|
+
}
|
|
430
|
+
// For orchestrator agents with dependencies, enable local execution mode
|
|
431
|
+
if (agentData.dependencies && agentData.dependencies.length > 0) {
|
|
432
|
+
subprocessEnv[LOCAL_EXECUTION_ENV] = 'true';
|
|
433
|
+
subprocessEnv[AGENTS_DIR_ENV] = AGENTS_DIR;
|
|
434
|
+
// Initialize call chain with this agent
|
|
435
|
+
const agentRef = `${org}/${agentName}@${version}`;
|
|
436
|
+
subprocessEnv[CALL_CHAIN_ENV] = agentRef;
|
|
437
|
+
// Set deadline from manifest timeout (default 120s)
|
|
438
|
+
const manifest = agentData;
|
|
439
|
+
const timeoutMs = manifest.manifest?.timeout_ms || 120000;
|
|
440
|
+
subprocessEnv[DEADLINE_MS_ENV] = String(Date.now() + timeoutMs);
|
|
441
|
+
// Set max hops from manifest (default 10)
|
|
442
|
+
subprocessEnv[MAX_HOPS_ENV] = String(manifest.manifest?.max_hops || 10);
|
|
443
|
+
// Set downstream cap
|
|
444
|
+
subprocessEnv[DOWNSTREAM_REMAINING_ENV] = String(manifest.manifest?.per_call_downstream_cap || 100);
|
|
445
|
+
}
|
|
396
446
|
const proc = (0, child_process_1.spawn)('python3', [entrypointPath], {
|
|
397
447
|
cwd: extractDir,
|
|
398
448
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
449
|
+
env: subprocessEnv,
|
|
399
450
|
});
|
|
400
451
|
// Send input JSON via stdin
|
|
401
452
|
proc.stdin.write(inputJson);
|
|
@@ -484,6 +535,51 @@ async function saveAgentLocally(org, agent, agentData) {
|
|
|
484
535
|
}
|
|
485
536
|
return agentDir;
|
|
486
537
|
}
|
|
538
|
+
async function saveBundleLocally(config, org, agent, version) {
|
|
539
|
+
const agentDir = path_1.default.join(AGENTS_DIR, org, agent);
|
|
540
|
+
const bundleDir = path_1.default.join(agentDir, 'bundle');
|
|
541
|
+
// Check if already extracted with same version
|
|
542
|
+
const metaPath = path_1.default.join(agentDir, 'agent.json');
|
|
543
|
+
try {
|
|
544
|
+
const existingMeta = await promises_1.default.readFile(metaPath, 'utf-8');
|
|
545
|
+
const existing = JSON.parse(existingMeta);
|
|
546
|
+
if (existing.version === version) {
|
|
547
|
+
// Check if bundle dir exists
|
|
548
|
+
try {
|
|
549
|
+
await promises_1.default.access(bundleDir);
|
|
550
|
+
return bundleDir; // Already cached
|
|
551
|
+
}
|
|
552
|
+
catch {
|
|
553
|
+
// Bundle dir doesn't exist, need to extract
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
catch {
|
|
558
|
+
// Metadata doesn't exist, need to download
|
|
559
|
+
}
|
|
560
|
+
// Download and extract bundle
|
|
561
|
+
process.stderr.write(`Downloading bundle for ${org}/${agent}@${version}...\n`);
|
|
562
|
+
const bundleBuffer = await (0, api_1.downloadCodeBundle)(config, org, agent, version);
|
|
563
|
+
const tempZip = path_1.default.join(os_1.default.tmpdir(), `bundle-${Date.now()}.zip`);
|
|
564
|
+
await promises_1.default.writeFile(tempZip, bundleBuffer);
|
|
565
|
+
// Clean and recreate bundle directory
|
|
566
|
+
try {
|
|
567
|
+
await promises_1.default.rm(bundleDir, { recursive: true, force: true });
|
|
568
|
+
}
|
|
569
|
+
catch {
|
|
570
|
+
// Directory might not exist
|
|
571
|
+
}
|
|
572
|
+
await promises_1.default.mkdir(bundleDir, { recursive: true });
|
|
573
|
+
await unzipBundle(tempZip, bundleDir);
|
|
574
|
+
// Clean up temp file
|
|
575
|
+
try {
|
|
576
|
+
await promises_1.default.rm(tempZip);
|
|
577
|
+
}
|
|
578
|
+
catch {
|
|
579
|
+
// Ignore cleanup errors
|
|
580
|
+
}
|
|
581
|
+
return bundleDir;
|
|
582
|
+
}
|
|
487
583
|
function registerRunCommand(program) {
|
|
488
584
|
program
|
|
489
585
|
.command('run <agent> [args...]')
|