@orchagent/cli 0.3.86 → 0.3.88
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/agent-keys.js +21 -7
- package/dist/commands/agents.js +60 -5
- package/dist/commands/config.js +4 -0
- package/dist/commands/delete.js +2 -2
- package/dist/commands/dev.js +226 -0
- package/dist/commands/diff.js +418 -0
- package/dist/commands/estimate.js +105 -0
- package/dist/commands/fork.js +11 -1
- package/dist/commands/health.js +226 -0
- package/dist/commands/index.js +14 -0
- package/dist/commands/info.js +75 -0
- package/dist/commands/init.js +729 -38
- package/dist/commands/metrics.js +137 -0
- package/dist/commands/publish.js +237 -21
- package/dist/commands/replay.js +198 -0
- package/dist/commands/run.js +272 -28
- package/dist/commands/schedule.js +11 -6
- package/dist/commands/test.js +68 -1
- package/dist/commands/trace.js +311 -0
- package/dist/lib/api.js +29 -4
- package/dist/lib/batch-publish.js +223 -0
- package/dist/lib/dev-server.js +425 -0
- package/dist/lib/doctor/checks/environment.js +1 -1
- package/dist/lib/key-store.js +121 -0
- package/dist/lib/spinner.js +50 -0
- package/dist/lib/test-mock-runner.js +334 -0
- package/dist/lib/update-notifier.js +1 -1
- package/package.json +1 -1
- package/src/resources/__pycache__/agent_runner.cpython-311.pyc +0 -0
- package/src/resources/__pycache__/agent_runner.cpython-312.pyc +0 -0
- package/src/resources/__pycache__/test_agent_runner_mocks.cpython-311-pytest-9.0.2.pyc +0 -0
- package/src/resources/__pycache__/test_agent_runner_mocks.cpython-312-pytest-8.4.2.pyc +0 -0
- package/src/resources/agent_runner.py +29 -2
- package/src/resources/test_agent_runner_mocks.py +290 -0
package/dist/commands/init.js
CHANGED
|
@@ -393,8 +393,385 @@ DISCORD_CHANNEL_IDS=
|
|
|
393
393
|
# MODEL=claude-sonnet-4-5-20250929
|
|
394
394
|
# MAX_TOKENS=1024
|
|
395
395
|
`;
|
|
396
|
+
// ---------------------------------------------------------------------------
|
|
397
|
+
// Orchestration templates: fan-out, pipeline, map-reduce
|
|
398
|
+
// ---------------------------------------------------------------------------
|
|
399
|
+
const FANOUT_MAIN_PY = `"""
|
|
400
|
+
orchagent fan-out orchestrator.
|
|
401
|
+
|
|
402
|
+
Calls multiple agents in parallel, combines their results.
|
|
403
|
+
|
|
404
|
+
Usage:
|
|
405
|
+
echo '{"task": "analyze this"}' | python main.py
|
|
406
|
+
"""
|
|
407
|
+
|
|
408
|
+
import asyncio
|
|
409
|
+
import json
|
|
410
|
+
import sys
|
|
411
|
+
|
|
412
|
+
from orchagent import AgentClient
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
async def run():
|
|
416
|
+
raw = sys.stdin.read()
|
|
417
|
+
try:
|
|
418
|
+
data = json.loads(raw) if raw.strip() else {}
|
|
419
|
+
except json.JSONDecodeError:
|
|
420
|
+
print(json.dumps({"error": "Invalid JSON input"}))
|
|
421
|
+
sys.exit(1)
|
|
422
|
+
|
|
423
|
+
task = data.get("task", "")
|
|
424
|
+
client = AgentClient()
|
|
425
|
+
|
|
426
|
+
# Fan-out: call all agents in parallel
|
|
427
|
+
# Replace these with your actual dependencies (must match manifest.dependencies)
|
|
428
|
+
agent_a, agent_b, agent_c = await asyncio.gather(
|
|
429
|
+
client.call("org/agent-a@v1", {"task": task}),
|
|
430
|
+
client.call("org/agent-b@v1", {"task": task}),
|
|
431
|
+
client.call("org/agent-c@v1", {"task": task}),
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
# Combine results
|
|
435
|
+
print(json.dumps({
|
|
436
|
+
"results": [agent_a, agent_b, agent_c],
|
|
437
|
+
"summary": f"Collected results from 3 agents",
|
|
438
|
+
"success": True,
|
|
439
|
+
}))
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
if __name__ == "__main__":
|
|
443
|
+
asyncio.run(run())
|
|
444
|
+
`;
|
|
445
|
+
const FANOUT_MAIN_JS = `/**
|
|
446
|
+
* orchagent fan-out orchestrator.
|
|
447
|
+
*
|
|
448
|
+
* Calls multiple agents in parallel, combines their results.
|
|
449
|
+
*
|
|
450
|
+
* Usage:
|
|
451
|
+
* echo '{"task": "analyze this"}' | node main.js
|
|
452
|
+
*/
|
|
453
|
+
|
|
454
|
+
const fs = require('fs');
|
|
455
|
+
const { AgentClient } = require('orchagent-sdk');
|
|
456
|
+
|
|
457
|
+
async function main() {
|
|
458
|
+
const raw = fs.readFileSync('/dev/stdin', 'utf-8');
|
|
459
|
+
let data;
|
|
460
|
+
try {
|
|
461
|
+
data = raw.trim() ? JSON.parse(raw) : {};
|
|
462
|
+
} catch {
|
|
463
|
+
console.log(JSON.stringify({ error: 'Invalid JSON input' }));
|
|
464
|
+
process.exit(1);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const task = data.task || '';
|
|
468
|
+
const client = new AgentClient();
|
|
469
|
+
|
|
470
|
+
// Fan-out: call all agents in parallel
|
|
471
|
+
// Replace these with your actual dependencies (must match manifest.dependencies)
|
|
472
|
+
const [agentA, agentB, agentC] = await Promise.all([
|
|
473
|
+
client.call('org/agent-a@v1', { task }),
|
|
474
|
+
client.call('org/agent-b@v1', { task }),
|
|
475
|
+
client.call('org/agent-c@v1', { task }),
|
|
476
|
+
]);
|
|
477
|
+
|
|
478
|
+
console.log(JSON.stringify({
|
|
479
|
+
results: [agentA, agentB, agentC],
|
|
480
|
+
summary: 'Collected results from 3 agents',
|
|
481
|
+
success: true,
|
|
482
|
+
}));
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
main().catch(err => {
|
|
486
|
+
console.error(err);
|
|
487
|
+
process.exit(1);
|
|
488
|
+
});
|
|
489
|
+
`;
|
|
490
|
+
const PIPELINE_MAIN_PY = `"""
|
|
491
|
+
orchagent pipeline orchestrator.
|
|
492
|
+
|
|
493
|
+
Calls agents sequentially — each step's output feeds into the next.
|
|
494
|
+
|
|
495
|
+
Usage:
|
|
496
|
+
echo '{"task": "process this data"}' | python main.py
|
|
497
|
+
"""
|
|
498
|
+
|
|
499
|
+
import asyncio
|
|
500
|
+
import json
|
|
501
|
+
import sys
|
|
502
|
+
|
|
503
|
+
from orchagent import AgentClient
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
async def run():
|
|
507
|
+
raw = sys.stdin.read()
|
|
508
|
+
try:
|
|
509
|
+
data = json.loads(raw) if raw.strip() else {}
|
|
510
|
+
except json.JSONDecodeError:
|
|
511
|
+
print(json.dumps({"error": "Invalid JSON input"}))
|
|
512
|
+
sys.exit(1)
|
|
513
|
+
|
|
514
|
+
task = data.get("task", "")
|
|
515
|
+
client = AgentClient()
|
|
516
|
+
|
|
517
|
+
# Pipeline: each step feeds into the next
|
|
518
|
+
# Replace these with your actual dependencies (must match manifest.dependencies)
|
|
519
|
+
step1 = await client.call("org/parser@v1", {"input": task})
|
|
520
|
+
step2 = await client.call("org/analyzer@v1", {"input": step1})
|
|
521
|
+
step3 = await client.call("org/reporter@v1", {"input": step2})
|
|
522
|
+
|
|
523
|
+
print(json.dumps({
|
|
524
|
+
"result": step3,
|
|
525
|
+
"steps_completed": 3,
|
|
526
|
+
"success": True,
|
|
527
|
+
}))
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
if __name__ == "__main__":
|
|
531
|
+
asyncio.run(run())
|
|
532
|
+
`;
|
|
533
|
+
const PIPELINE_MAIN_JS = `/**
|
|
534
|
+
* orchagent pipeline orchestrator.
|
|
535
|
+
*
|
|
536
|
+
* Calls agents sequentially — each step's output feeds into the next.
|
|
537
|
+
*
|
|
538
|
+
* Usage:
|
|
539
|
+
* echo '{"task": "process this data"}' | node main.js
|
|
540
|
+
*/
|
|
541
|
+
|
|
542
|
+
const fs = require('fs');
|
|
543
|
+
const { AgentClient } = require('orchagent-sdk');
|
|
544
|
+
|
|
545
|
+
async function main() {
|
|
546
|
+
const raw = fs.readFileSync('/dev/stdin', 'utf-8');
|
|
547
|
+
let data;
|
|
548
|
+
try {
|
|
549
|
+
data = raw.trim() ? JSON.parse(raw) : {};
|
|
550
|
+
} catch {
|
|
551
|
+
console.log(JSON.stringify({ error: 'Invalid JSON input' }));
|
|
552
|
+
process.exit(1);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
const task = data.task || '';
|
|
556
|
+
const client = new AgentClient();
|
|
557
|
+
|
|
558
|
+
// Pipeline: each step feeds into the next
|
|
559
|
+
// Replace these with your actual dependencies (must match manifest.dependencies)
|
|
560
|
+
const step1 = await client.call('org/parser@v1', { input: task });
|
|
561
|
+
const step2 = await client.call('org/analyzer@v1', { input: step1 });
|
|
562
|
+
const step3 = await client.call('org/reporter@v1', { input: step2 });
|
|
563
|
+
|
|
564
|
+
console.log(JSON.stringify({
|
|
565
|
+
result: step3,
|
|
566
|
+
steps_completed: 3,
|
|
567
|
+
success: true,
|
|
568
|
+
}));
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
main().catch(err => {
|
|
572
|
+
console.error(err);
|
|
573
|
+
process.exit(1);
|
|
574
|
+
});
|
|
575
|
+
`;
|
|
576
|
+
const MAPREDUCE_MAIN_PY = `"""
|
|
577
|
+
orchagent map-reduce orchestrator.
|
|
578
|
+
|
|
579
|
+
Splits input into chunks, processes each in parallel (map), then aggregates (reduce).
|
|
580
|
+
|
|
581
|
+
Usage:
|
|
582
|
+
echo '{"items": ["item1", "item2", "item3"]}' | python main.py
|
|
583
|
+
"""
|
|
584
|
+
|
|
585
|
+
import asyncio
|
|
586
|
+
import json
|
|
587
|
+
import sys
|
|
588
|
+
|
|
589
|
+
from orchagent import AgentClient
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
async def run():
|
|
593
|
+
raw = sys.stdin.read()
|
|
594
|
+
try:
|
|
595
|
+
data = json.loads(raw) if raw.strip() else {}
|
|
596
|
+
except json.JSONDecodeError:
|
|
597
|
+
print(json.dumps({"error": "Invalid JSON input"}))
|
|
598
|
+
sys.exit(1)
|
|
599
|
+
|
|
600
|
+
items = data.get("items", [])
|
|
601
|
+
if not items:
|
|
602
|
+
print(json.dumps({"error": "No items to process", "success": False}))
|
|
603
|
+
sys.exit(1)
|
|
604
|
+
|
|
605
|
+
client = AgentClient()
|
|
606
|
+
|
|
607
|
+
# Map: process each item in parallel
|
|
608
|
+
# Replace with your actual dependency (must match manifest.dependencies)
|
|
609
|
+
mapped = await asyncio.gather(
|
|
610
|
+
*[client.call("org/processor@v1", {"item": item}) for item in items]
|
|
611
|
+
)
|
|
612
|
+
|
|
613
|
+
# Reduce: aggregate results into a single output
|
|
614
|
+
# Replace with your actual dependency (must match manifest.dependencies)
|
|
615
|
+
reduced = await client.call("org/aggregator@v1", {"results": mapped})
|
|
616
|
+
|
|
617
|
+
print(json.dumps({
|
|
618
|
+
"result": reduced,
|
|
619
|
+
"items_processed": len(items),
|
|
620
|
+
"success": True,
|
|
621
|
+
}))
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
if __name__ == "__main__":
|
|
625
|
+
asyncio.run(run())
|
|
626
|
+
`;
|
|
627
|
+
const MAPREDUCE_MAIN_JS = `/**
|
|
628
|
+
* orchagent map-reduce orchestrator.
|
|
629
|
+
*
|
|
630
|
+
* Splits input into chunks, processes each in parallel (map), then aggregates (reduce).
|
|
631
|
+
*
|
|
632
|
+
* Usage:
|
|
633
|
+
* echo '{"items": ["item1", "item2", "item3"]}' | node main.js
|
|
634
|
+
*/
|
|
635
|
+
|
|
636
|
+
const fs = require('fs');
|
|
637
|
+
const { AgentClient } = require('orchagent-sdk');
|
|
638
|
+
|
|
639
|
+
async function main() {
|
|
640
|
+
const raw = fs.readFileSync('/dev/stdin', 'utf-8');
|
|
641
|
+
let data;
|
|
642
|
+
try {
|
|
643
|
+
data = raw.trim() ? JSON.parse(raw) : {};
|
|
644
|
+
} catch {
|
|
645
|
+
console.log(JSON.stringify({ error: 'Invalid JSON input' }));
|
|
646
|
+
process.exit(1);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
const items = data.items || [];
|
|
650
|
+
if (!items.length) {
|
|
651
|
+
console.log(JSON.stringify({ error: 'No items to process', success: false }));
|
|
652
|
+
process.exit(1);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
const client = new AgentClient();
|
|
656
|
+
|
|
657
|
+
// Map: process each item in parallel
|
|
658
|
+
// Replace with your actual dependency (must match manifest.dependencies)
|
|
659
|
+
const mapped = await Promise.all(
|
|
660
|
+
items.map(item => client.call('org/processor@v1', { item }))
|
|
661
|
+
);
|
|
662
|
+
|
|
663
|
+
// Reduce: aggregate results into a single output
|
|
664
|
+
// Replace with your actual dependency (must match manifest.dependencies)
|
|
665
|
+
const reduced = await client.call('org/aggregator@v1', { results: mapped });
|
|
666
|
+
|
|
667
|
+
console.log(JSON.stringify({
|
|
668
|
+
result: reduced,
|
|
669
|
+
items_processed: items.length,
|
|
670
|
+
success: true,
|
|
671
|
+
}));
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
main().catch(err => {
|
|
675
|
+
console.error(err);
|
|
676
|
+
process.exit(1);
|
|
677
|
+
});
|
|
678
|
+
`;
|
|
679
|
+
const FANOUT_SCHEMA = `{
|
|
680
|
+
"input": {
|
|
681
|
+
"type": "object",
|
|
682
|
+
"properties": {
|
|
683
|
+
"task": {
|
|
684
|
+
"type": "string",
|
|
685
|
+
"description": "The task to fan out to all agents"
|
|
686
|
+
}
|
|
687
|
+
},
|
|
688
|
+
"required": ["task"]
|
|
689
|
+
},
|
|
690
|
+
"output": {
|
|
691
|
+
"type": "object",
|
|
692
|
+
"properties": {
|
|
693
|
+
"results": {
|
|
694
|
+
"type": "array",
|
|
695
|
+
"description": "Results from each agent"
|
|
696
|
+
},
|
|
697
|
+
"summary": {
|
|
698
|
+
"type": "string",
|
|
699
|
+
"description": "Summary of combined results"
|
|
700
|
+
},
|
|
701
|
+
"success": {
|
|
702
|
+
"type": "boolean",
|
|
703
|
+
"description": "Whether all agents completed successfully"
|
|
704
|
+
}
|
|
705
|
+
},
|
|
706
|
+
"required": ["results", "success"]
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
`;
|
|
710
|
+
const PIPELINE_SCHEMA = `{
|
|
711
|
+
"input": {
|
|
712
|
+
"type": "object",
|
|
713
|
+
"properties": {
|
|
714
|
+
"task": {
|
|
715
|
+
"type": "string",
|
|
716
|
+
"description": "The input to feed into the pipeline"
|
|
717
|
+
}
|
|
718
|
+
},
|
|
719
|
+
"required": ["task"]
|
|
720
|
+
},
|
|
721
|
+
"output": {
|
|
722
|
+
"type": "object",
|
|
723
|
+
"properties": {
|
|
724
|
+
"result": {
|
|
725
|
+
"type": "object",
|
|
726
|
+
"description": "Final output from the last pipeline step"
|
|
727
|
+
},
|
|
728
|
+
"steps_completed": {
|
|
729
|
+
"type": "integer",
|
|
730
|
+
"description": "Number of pipeline steps completed"
|
|
731
|
+
},
|
|
732
|
+
"success": {
|
|
733
|
+
"type": "boolean",
|
|
734
|
+
"description": "Whether the pipeline completed successfully"
|
|
735
|
+
}
|
|
736
|
+
},
|
|
737
|
+
"required": ["result", "success"]
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
`;
|
|
741
|
+
const MAPREDUCE_SCHEMA = `{
|
|
742
|
+
"input": {
|
|
743
|
+
"type": "object",
|
|
744
|
+
"properties": {
|
|
745
|
+
"items": {
|
|
746
|
+
"type": "array",
|
|
747
|
+
"items": { "type": "string" },
|
|
748
|
+
"description": "Items to process in parallel"
|
|
749
|
+
}
|
|
750
|
+
},
|
|
751
|
+
"required": ["items"]
|
|
752
|
+
},
|
|
753
|
+
"output": {
|
|
754
|
+
"type": "object",
|
|
755
|
+
"properties": {
|
|
756
|
+
"result": {
|
|
757
|
+
"type": "object",
|
|
758
|
+
"description": "Aggregated result from all processed items"
|
|
759
|
+
},
|
|
760
|
+
"items_processed": {
|
|
761
|
+
"type": "integer",
|
|
762
|
+
"description": "Number of items processed"
|
|
763
|
+
},
|
|
764
|
+
"success": {
|
|
765
|
+
"type": "boolean",
|
|
766
|
+
"description": "Whether all items were processed successfully"
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
"required": ["result", "success"]
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
`;
|
|
396
773
|
const AGENT_BUILDER_HINT = `\n Tip: orch skill install orchagent-public/agent-builder — gives your AI the full platform builder reference\n`;
|
|
397
|
-
function readmeTemplate(agentName, flavor) {
|
|
774
|
+
function readmeTemplate(agentName, flavor, type) {
|
|
398
775
|
if (flavor === 'support_agent') {
|
|
399
776
|
return `# ${agentName}
|
|
400
777
|
|
|
@@ -556,14 +933,11 @@ Edit \`main.js\` to customize:
|
|
|
556
933
|
| \`MAX_TOKENS\` | No | Max response tokens (default: 1024) |
|
|
557
934
|
`;
|
|
558
935
|
}
|
|
559
|
-
const
|
|
560
|
-
const
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
const localExample = flavor === 'code_runtime'
|
|
565
|
-
? `orchagent run ${agentName} --local --data '{"input": "Hello world"}'`
|
|
566
|
-
: `orchagent run ${agentName} --local --data '{"${inputField}": "Hello world"}'`;
|
|
936
|
+
const usesTask = flavor === 'managed_loop' || flavor === 'orchestrator' || type === 'agent';
|
|
937
|
+
const inputField = usesTask ? 'task' : 'input';
|
|
938
|
+
const inputDescription = usesTask ? 'The task to perform' : 'The input to process';
|
|
939
|
+
const cloudExample = `orchagent run ${agentName} --data '{"${inputField}": "Hello world"}'`;
|
|
940
|
+
const localExample = `orchagent run ${agentName} --local --data '{"${inputField}": "Hello world"}'`;
|
|
567
941
|
let readme = `# ${agentName}
|
|
568
942
|
|
|
569
943
|
A brief description of what this agent does.
|
|
@@ -605,10 +979,185 @@ This orchestrator calls other agents. Update \`manifest.dependencies\` in \`orch
|
|
|
605
979
|
| Dependency | Version | Description |
|
|
606
980
|
|------------|---------|-------------|
|
|
607
981
|
| \`org/agent-name\` | v1 | TODO: describe what this agent does |
|
|
982
|
+
`;
|
|
983
|
+
}
|
|
984
|
+
if (flavor === 'fan_out') {
|
|
985
|
+
readme += `
|
|
986
|
+
## Pattern: Fan-Out
|
|
987
|
+
|
|
988
|
+
This orchestrator calls multiple agents **in parallel** and combines their results. Use this when you have independent tasks that can run concurrently.
|
|
989
|
+
|
|
990
|
+
\`\`\`
|
|
991
|
+
Input ──┬──> Agent A ──┐
|
|
992
|
+
├──> Agent B ──┼──> Combined Results
|
|
993
|
+
└──> Agent C ──┘
|
|
994
|
+
\`\`\`
|
|
995
|
+
|
|
996
|
+
## Dependencies
|
|
997
|
+
|
|
998
|
+
Update \`manifest.dependencies\` in \`orchagent.json\` with your actual agents.
|
|
999
|
+
|
|
1000
|
+
**Publish order:** Publish dependency agents first, then this orchestrator.
|
|
1001
|
+
|
|
1002
|
+
| Dependency | Version | Description |
|
|
1003
|
+
|------------|---------|-------------|
|
|
1004
|
+
| \`org/agent-a\` | v1 | TODO: describe |
|
|
1005
|
+
| \`org/agent-b\` | v1 | TODO: describe |
|
|
1006
|
+
| \`org/agent-c\` | v1 | TODO: describe |
|
|
1007
|
+
`;
|
|
1008
|
+
}
|
|
1009
|
+
if (flavor === 'pipeline') {
|
|
1010
|
+
readme += `
|
|
1011
|
+
## Pattern: Pipeline
|
|
1012
|
+
|
|
1013
|
+
This orchestrator calls agents **sequentially** — each step's output feeds into the next. Use this when data must flow through ordered processing stages.
|
|
1014
|
+
|
|
1015
|
+
\`\`\`
|
|
1016
|
+
Input ──> Parser ──> Analyzer ──> Reporter ──> Output
|
|
1017
|
+
\`\`\`
|
|
1018
|
+
|
|
1019
|
+
## Dependencies
|
|
1020
|
+
|
|
1021
|
+
Update \`manifest.dependencies\` in \`orchagent.json\` with your actual agents.
|
|
1022
|
+
|
|
1023
|
+
**Publish order:** Publish dependency agents first, then this orchestrator.
|
|
1024
|
+
|
|
1025
|
+
| Dependency | Version | Description |
|
|
1026
|
+
|------------|---------|-------------|
|
|
1027
|
+
| \`org/parser\` | v1 | TODO: describe |
|
|
1028
|
+
| \`org/analyzer\` | v1 | TODO: describe |
|
|
1029
|
+
| \`org/reporter\` | v1 | TODO: describe |
|
|
1030
|
+
`;
|
|
1031
|
+
}
|
|
1032
|
+
if (flavor === 'map_reduce') {
|
|
1033
|
+
readme += `
|
|
1034
|
+
## Pattern: Map-Reduce
|
|
1035
|
+
|
|
1036
|
+
This orchestrator **splits input** into items, processes each in **parallel** (map), then **aggregates** the results (reduce).
|
|
1037
|
+
|
|
1038
|
+
\`\`\`
|
|
1039
|
+
Items ──┬──> Processor (item 1) ──┐
|
|
1040
|
+
├──> Processor (item 2) ──┼──> Aggregator ──> Output
|
|
1041
|
+
└──> Processor (item N) ──┘
|
|
1042
|
+
\`\`\`
|
|
1043
|
+
|
|
1044
|
+
## Dependencies
|
|
1045
|
+
|
|
1046
|
+
Update \`manifest.dependencies\` in \`orchagent.json\` with your actual agents.
|
|
1047
|
+
|
|
1048
|
+
**Publish order:** Publish dependency agents first, then this orchestrator.
|
|
1049
|
+
|
|
1050
|
+
| Dependency | Version | Description |
|
|
1051
|
+
|------------|---------|-------------|
|
|
1052
|
+
| \`org/processor\` | v1 | Processes individual items |
|
|
1053
|
+
| \`org/aggregator\` | v1 | Combines processed results |
|
|
608
1054
|
`;
|
|
609
1055
|
}
|
|
610
1056
|
return readme;
|
|
611
1057
|
}
|
|
1058
|
+
const AGENT_CODE_TEMPLATE_PY = `"""
|
|
1059
|
+
orchagent agent entrypoint.
|
|
1060
|
+
|
|
1061
|
+
Reads JSON input from stdin, processes the task, and writes JSON output to stdout.
|
|
1062
|
+
This is a code-runtime agent — you control the logic and can call any LLM provider.
|
|
1063
|
+
|
|
1064
|
+
Usage:
|
|
1065
|
+
echo '{"task": "summarize this text"}' | python main.py
|
|
1066
|
+
"""
|
|
1067
|
+
|
|
1068
|
+
import json
|
|
1069
|
+
import sys
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
def main():
|
|
1073
|
+
# Read JSON input from stdin
|
|
1074
|
+
raw = sys.stdin.read()
|
|
1075
|
+
try:
|
|
1076
|
+
data = json.loads(raw) if raw.strip() else {}
|
|
1077
|
+
except json.JSONDecodeError:
|
|
1078
|
+
print(json.dumps({"error": "Invalid JSON input", "success": False}))
|
|
1079
|
+
sys.exit(1)
|
|
1080
|
+
|
|
1081
|
+
task = data.get("task", "")
|
|
1082
|
+
|
|
1083
|
+
# --- Your agent logic here ---
|
|
1084
|
+
# This is a code-runtime agent. You write the logic — call any LLM provider,
|
|
1085
|
+
# use any library, chain multiple steps, etc.
|
|
1086
|
+
#
|
|
1087
|
+
# Example (Anthropic):
|
|
1088
|
+
# pip install anthropic
|
|
1089
|
+
# import anthropic
|
|
1090
|
+
# client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY from env
|
|
1091
|
+
# response = client.messages.create(model="claude-sonnet-4-5-20250929", ...)
|
|
1092
|
+
#
|
|
1093
|
+
# Example (OpenAI):
|
|
1094
|
+
# pip install openai
|
|
1095
|
+
# import openai
|
|
1096
|
+
# client = openai.OpenAI() # reads OPENAI_API_KEY from env
|
|
1097
|
+
# response = client.chat.completions.create(model="gpt-4o", ...)
|
|
1098
|
+
#
|
|
1099
|
+
# To use workspace secrets, add them to "required_secrets" in orchagent.json:
|
|
1100
|
+
# "required_secrets": ["ANTHROPIC_API_KEY"]
|
|
1101
|
+
# Then access via: os.environ["ANTHROPIC_API_KEY"]
|
|
1102
|
+
result = f"Received task: {task}"
|
|
1103
|
+
# --- End your logic ---
|
|
1104
|
+
|
|
1105
|
+
# Write JSON output to stdout
|
|
1106
|
+
print(json.dumps({"result": result, "success": True}))
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
if __name__ == "__main__":
|
|
1110
|
+
main()
|
|
1111
|
+
`;
|
|
1112
|
+
const AGENT_CODE_TEMPLATE_JS = `/**
|
|
1113
|
+
* orchagent agent entrypoint.
|
|
1114
|
+
*
|
|
1115
|
+
* Reads JSON input from stdin, processes the task, and writes JSON output to stdout.
|
|
1116
|
+
* This is a code-runtime agent — you control the logic and can call any LLM provider.
|
|
1117
|
+
*
|
|
1118
|
+
* Usage:
|
|
1119
|
+
* echo '{"task": "summarize this text"}' | node main.js
|
|
1120
|
+
*/
|
|
1121
|
+
|
|
1122
|
+
const fs = require('fs');
|
|
1123
|
+
|
|
1124
|
+
function main() {
|
|
1125
|
+
const raw = fs.readFileSync('/dev/stdin', 'utf-8');
|
|
1126
|
+
let data;
|
|
1127
|
+
try {
|
|
1128
|
+
data = raw.trim() ? JSON.parse(raw) : {};
|
|
1129
|
+
} catch {
|
|
1130
|
+
console.log(JSON.stringify({ error: 'Invalid JSON input', success: false }));
|
|
1131
|
+
process.exit(1);
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
const task = data.task || '';
|
|
1135
|
+
|
|
1136
|
+
// --- Your agent logic here ---
|
|
1137
|
+
// This is a code-runtime agent. You write the logic — call any LLM provider,
|
|
1138
|
+
// use any library, chain multiple steps, etc.
|
|
1139
|
+
//
|
|
1140
|
+
// Example (Anthropic):
|
|
1141
|
+
// npm install @anthropic-ai/sdk
|
|
1142
|
+
// const Anthropic = require('@anthropic-ai/sdk');
|
|
1143
|
+
// const client = new Anthropic(); // reads ANTHROPIC_API_KEY from env
|
|
1144
|
+
//
|
|
1145
|
+
// Example (OpenAI):
|
|
1146
|
+
// npm install openai
|
|
1147
|
+
// const OpenAI = require('openai');
|
|
1148
|
+
// const client = new OpenAI(); // reads OPENAI_API_KEY from env
|
|
1149
|
+
//
|
|
1150
|
+
// To use workspace secrets, add them to "required_secrets" in orchagent.json:
|
|
1151
|
+
// "required_secrets": ["ANTHROPIC_API_KEY"]
|
|
1152
|
+
// Then access via: process.env.ANTHROPIC_API_KEY
|
|
1153
|
+
const result = \`Received task: \${task}\`;
|
|
1154
|
+
// --- End your logic ---
|
|
1155
|
+
|
|
1156
|
+
console.log(JSON.stringify({ result, success: true }));
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
main();
|
|
1160
|
+
`;
|
|
612
1161
|
const AGENT_PROMPT_TEMPLATE = `You are a helpful AI agent.
|
|
613
1162
|
|
|
614
1163
|
Given the input, complete the task step by step.
|
|
@@ -939,7 +1488,7 @@ function resolveInitFlavor(typeOption) {
|
|
|
939
1488
|
return { type: 'prompt', flavor: 'direct_llm' };
|
|
940
1489
|
}
|
|
941
1490
|
if (normalized === 'agent' || normalized === 'agentic') {
|
|
942
|
-
return { type: 'agent', flavor: '
|
|
1491
|
+
return { type: 'agent', flavor: 'code_runtime' };
|
|
943
1492
|
}
|
|
944
1493
|
if (normalized === 'tool' || normalized === 'code') {
|
|
945
1494
|
return { type: 'tool', flavor: 'code_runtime' };
|
|
@@ -955,7 +1504,8 @@ function registerInitCommand(program) {
|
|
|
955
1504
|
.option('--orchestrator', 'Create an orchestrator agent with dependency scaffolding and SDK boilerplate')
|
|
956
1505
|
.option('--run-mode <mode>', 'Run mode for agents: on_demand or always_on', 'on_demand')
|
|
957
1506
|
.option('--language <lang>', 'Language: python or javascript (default: python)', 'python')
|
|
958
|
-
.option('--
|
|
1507
|
+
.option('--loop', 'Use platform-managed LLM loop instead of code runtime (requires --type agent)')
|
|
1508
|
+
.option('--template <name>', 'Start from a template (available: fan-out, pipeline, map-reduce, support-agent, discord, discord-js, github-weekly-summary)')
|
|
959
1509
|
.action(async (name, options) => {
|
|
960
1510
|
const cwd = process.cwd();
|
|
961
1511
|
let runMode = (options.runMode || 'on_demand').trim().toLowerCase();
|
|
@@ -969,25 +1519,18 @@ function registerInitCommand(program) {
|
|
|
969
1519
|
}
|
|
970
1520
|
initMode = { type: 'agent', flavor: 'orchestrator' };
|
|
971
1521
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
throw new errors_1.CliError('JavaScript agent-type agents are not yet supported. Use --type tool for JavaScript agents.');
|
|
981
|
-
}
|
|
982
|
-
// JS orchestrators are now supported via the orchagent-sdk npm package
|
|
983
|
-
// Block --language for types that don't create runtime files
|
|
984
|
-
if (isJavaScript && (initMode.type === 'prompt' || initMode.type === 'skill')) {
|
|
985
|
-
throw new errors_1.CliError(`The --language flag has no effect for ${initMode.type} types (no runtime files are created). ` +
|
|
986
|
-
'Use --type tool or --type agent to create a project with runtime scaffolding.');
|
|
1522
|
+
if (options.loop) {
|
|
1523
|
+
if (options.orchestrator) {
|
|
1524
|
+
throw new errors_1.CliError('Cannot use --loop with --orchestrator. Orchestrators use code runtime with SDK calls.');
|
|
1525
|
+
}
|
|
1526
|
+
if (initMode.type !== 'agent') {
|
|
1527
|
+
throw new errors_1.CliError('The --loop flag requires --type agent. It enables platform-managed LLM loop execution.');
|
|
1528
|
+
}
|
|
1529
|
+
initMode = { type: 'agent', flavor: 'managed_loop' };
|
|
987
1530
|
}
|
|
988
1531
|
if (options.template) {
|
|
989
1532
|
const template = options.template.trim().toLowerCase();
|
|
990
|
-
const validTemplates = ['support-agent', 'discord', 'discord-js', 'github-weekly-summary'];
|
|
1533
|
+
const validTemplates = ['fan-out', 'pipeline', 'map-reduce', 'support-agent', 'discord', 'discord-js', 'github-weekly-summary'];
|
|
991
1534
|
if (!validTemplates.includes(template)) {
|
|
992
1535
|
throw new errors_1.CliError(`Unknown --template '${template}'. Available templates: ${validTemplates.join(', ')}`);
|
|
993
1536
|
}
|
|
@@ -997,7 +1540,16 @@ function registerInitCommand(program) {
|
|
|
997
1540
|
if (initMode.type === 'skill') {
|
|
998
1541
|
throw new errors_1.CliError('Cannot use --template with --type skill.');
|
|
999
1542
|
}
|
|
1000
|
-
if (template === '
|
|
1543
|
+
if (template === 'fan-out') {
|
|
1544
|
+
initMode = { type: 'agent', flavor: 'fan_out' };
|
|
1545
|
+
}
|
|
1546
|
+
else if (template === 'pipeline') {
|
|
1547
|
+
initMode = { type: 'agent', flavor: 'pipeline' };
|
|
1548
|
+
}
|
|
1549
|
+
else if (template === 'map-reduce') {
|
|
1550
|
+
initMode = { type: 'agent', flavor: 'map_reduce' };
|
|
1551
|
+
}
|
|
1552
|
+
else if (template === 'support-agent') {
|
|
1001
1553
|
initMode = { type: 'agent', flavor: 'support_agent' };
|
|
1002
1554
|
runMode = 'always_on';
|
|
1003
1555
|
}
|
|
@@ -1013,6 +1565,22 @@ function registerInitCommand(program) {
|
|
|
1013
1565
|
initMode = { type: 'agent', flavor: 'github_weekly_summary' };
|
|
1014
1566
|
}
|
|
1015
1567
|
}
|
|
1568
|
+
// Validate --language option
|
|
1569
|
+
const language = (options.language || 'python').trim().toLowerCase();
|
|
1570
|
+
if (!['python', 'javascript', 'js', 'typescript', 'ts'].includes(language)) {
|
|
1571
|
+
throw new errors_1.CliError(`Invalid --language '${options.language}'. Use 'python' or 'javascript'.`);
|
|
1572
|
+
}
|
|
1573
|
+
const isJavaScript = ['javascript', 'js', 'typescript', 'ts'].includes(language);
|
|
1574
|
+
// Block unsupported JS flavors
|
|
1575
|
+
if (isJavaScript && initMode.flavor === 'managed_loop') {
|
|
1576
|
+
throw new errors_1.CliError('JavaScript is not supported for --loop (managed loop). Use --type agent without --loop for a code-runtime agent.');
|
|
1577
|
+
}
|
|
1578
|
+
// JS orchestrators are now supported via the orchagent-sdk npm package
|
|
1579
|
+
// Block --language for types that don't create runtime files
|
|
1580
|
+
if (isJavaScript && (initMode.type === 'prompt' || initMode.type === 'skill')) {
|
|
1581
|
+
throw new errors_1.CliError(`The --language flag has no effect for ${initMode.type} types (no runtime files are created). ` +
|
|
1582
|
+
'Use --type tool or --type agent to create a project with runtime scaffolding.');
|
|
1583
|
+
}
|
|
1016
1584
|
// When a name is provided, create a subdirectory for the project
|
|
1017
1585
|
const targetDir = name ? path_1.default.join(cwd, name) : cwd;
|
|
1018
1586
|
const agentName = name || path_1.default.basename(cwd);
|
|
@@ -1230,6 +1798,121 @@ function registerInitCommand(program) {
|
|
|
1230
1798
|
process.stdout.write(AGENT_BUILDER_HINT);
|
|
1231
1799
|
return;
|
|
1232
1800
|
}
|
|
1801
|
+
// Handle orchestration templates (fan-out, pipeline, map-reduce)
|
|
1802
|
+
if (initMode.flavor === 'fan_out' || initMode.flavor === 'pipeline' || initMode.flavor === 'map_reduce') {
|
|
1803
|
+
const manifestPath = path_1.default.join(targetDir, 'orchagent.json');
|
|
1804
|
+
try {
|
|
1805
|
+
await promises_1.default.access(manifestPath);
|
|
1806
|
+
throw new errors_1.CliError(`Already initialized (orchagent.json exists in ${name ? name + '/' : 'current directory'})`);
|
|
1807
|
+
}
|
|
1808
|
+
catch (err) {
|
|
1809
|
+
if (err.code !== 'ENOENT') {
|
|
1810
|
+
throw err;
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
// Build dependencies based on template
|
|
1814
|
+
let dependencies;
|
|
1815
|
+
let mainPy;
|
|
1816
|
+
let mainJs;
|
|
1817
|
+
let schema;
|
|
1818
|
+
let templateLabel;
|
|
1819
|
+
let maxHops;
|
|
1820
|
+
if (initMode.flavor === 'fan_out') {
|
|
1821
|
+
dependencies = [
|
|
1822
|
+
{ id: 'org/agent-a', version: 'v1' },
|
|
1823
|
+
{ id: 'org/agent-b', version: 'v1' },
|
|
1824
|
+
{ id: 'org/agent-c', version: 'v1' },
|
|
1825
|
+
];
|
|
1826
|
+
mainPy = FANOUT_MAIN_PY;
|
|
1827
|
+
mainJs = FANOUT_MAIN_JS;
|
|
1828
|
+
schema = FANOUT_SCHEMA;
|
|
1829
|
+
templateLabel = 'fan-out';
|
|
1830
|
+
maxHops = 2;
|
|
1831
|
+
}
|
|
1832
|
+
else if (initMode.flavor === 'pipeline') {
|
|
1833
|
+
dependencies = [
|
|
1834
|
+
{ id: 'org/parser', version: 'v1' },
|
|
1835
|
+
{ id: 'org/analyzer', version: 'v1' },
|
|
1836
|
+
{ id: 'org/reporter', version: 'v1' },
|
|
1837
|
+
];
|
|
1838
|
+
mainPy = PIPELINE_MAIN_PY;
|
|
1839
|
+
mainJs = PIPELINE_MAIN_JS;
|
|
1840
|
+
schema = PIPELINE_SCHEMA;
|
|
1841
|
+
templateLabel = 'pipeline';
|
|
1842
|
+
maxHops = 2;
|
|
1843
|
+
}
|
|
1844
|
+
else {
|
|
1845
|
+
dependencies = [
|
|
1846
|
+
{ id: 'org/processor', version: 'v1' },
|
|
1847
|
+
{ id: 'org/aggregator', version: 'v1' },
|
|
1848
|
+
];
|
|
1849
|
+
mainPy = MAPREDUCE_MAIN_PY;
|
|
1850
|
+
mainJs = MAPREDUCE_MAIN_JS;
|
|
1851
|
+
schema = MAPREDUCE_SCHEMA;
|
|
1852
|
+
templateLabel = 'map-reduce';
|
|
1853
|
+
maxHops = 2;
|
|
1854
|
+
}
|
|
1855
|
+
const manifest = {
|
|
1856
|
+
name: agentName,
|
|
1857
|
+
type: 'agent',
|
|
1858
|
+
description: `A ${templateLabel} orchestrator agent`,
|
|
1859
|
+
run_mode: runMode,
|
|
1860
|
+
runtime: { command: isJavaScript ? 'node main.js' : 'python main.py' },
|
|
1861
|
+
manifest: {
|
|
1862
|
+
manifest_version: 1,
|
|
1863
|
+
dependencies,
|
|
1864
|
+
max_hops: maxHops,
|
|
1865
|
+
timeout_ms: 120000,
|
|
1866
|
+
per_call_downstream_cap: 50,
|
|
1867
|
+
},
|
|
1868
|
+
required_secrets: [],
|
|
1869
|
+
};
|
|
1870
|
+
if (isJavaScript) {
|
|
1871
|
+
manifest.entrypoint = 'main.js';
|
|
1872
|
+
}
|
|
1873
|
+
await promises_1.default.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
1874
|
+
if (isJavaScript) {
|
|
1875
|
+
await promises_1.default.writeFile(path_1.default.join(targetDir, 'main.js'), mainJs);
|
|
1876
|
+
await promises_1.default.writeFile(path_1.default.join(targetDir, 'package.json'), ORCHESTRATOR_PACKAGE_JSON);
|
|
1877
|
+
}
|
|
1878
|
+
else {
|
|
1879
|
+
await promises_1.default.writeFile(path_1.default.join(targetDir, 'main.py'), mainPy);
|
|
1880
|
+
await promises_1.default.writeFile(path_1.default.join(targetDir, 'requirements.txt'), ORCHESTRATOR_REQUIREMENTS);
|
|
1881
|
+
}
|
|
1882
|
+
await promises_1.default.writeFile(path_1.default.join(targetDir, 'schema.json'), schema);
|
|
1883
|
+
await promises_1.default.writeFile(path_1.default.join(targetDir, 'README.md'), readmeTemplate(agentName, initMode.flavor));
|
|
1884
|
+
const prefix = name ? name + '/' : '';
|
|
1885
|
+
process.stdout.write(`Initialized ${templateLabel} orchestrator "${agentName}" in ${targetDir}\n`);
|
|
1886
|
+
process.stdout.write(`\nFiles created:\n`);
|
|
1887
|
+
process.stdout.write(` ${prefix}orchagent.json - Agent configuration (${templateLabel} pattern)\n`);
|
|
1888
|
+
if (isJavaScript) {
|
|
1889
|
+
process.stdout.write(` ${prefix}main.js - ${templateLabel} orchestrator entrypoint\n`);
|
|
1890
|
+
process.stdout.write(` ${prefix}package.json - npm dependencies (orchagent-sdk)\n`);
|
|
1891
|
+
}
|
|
1892
|
+
else {
|
|
1893
|
+
process.stdout.write(` ${prefix}main.py - ${templateLabel} orchestrator entrypoint\n`);
|
|
1894
|
+
process.stdout.write(` ${prefix}requirements.txt - Python dependencies (orchagent-sdk)\n`);
|
|
1895
|
+
}
|
|
1896
|
+
process.stdout.write(` ${prefix}schema.json - Input/output schemas\n`);
|
|
1897
|
+
process.stdout.write(` ${prefix}README.md - Agent documentation\n`);
|
|
1898
|
+
process.stdout.write(` Run mode: ${runMode}\n`);
|
|
1899
|
+
process.stdout.write(` Execution: code_runtime (${templateLabel})\n`);
|
|
1900
|
+
process.stdout.write(`\nNext steps:\n`);
|
|
1901
|
+
const stepNum = name ? 2 : 1;
|
|
1902
|
+
if (name) {
|
|
1903
|
+
process.stdout.write(` 1. cd ${name}\n`);
|
|
1904
|
+
}
|
|
1905
|
+
process.stdout.write(` ${stepNum}. Update manifest.dependencies in orchagent.json with your actual agents\n`);
|
|
1906
|
+
if (isJavaScript) {
|
|
1907
|
+
process.stdout.write(` ${stepNum + 1}. Edit main.js with your orchestration logic\n`);
|
|
1908
|
+
}
|
|
1909
|
+
else {
|
|
1910
|
+
process.stdout.write(` ${stepNum + 1}. Edit main.py with your orchestration logic\n`);
|
|
1911
|
+
}
|
|
1912
|
+
process.stdout.write(` ${stepNum + 2}. Publish dependency agents first, then: orchagent publish\n`);
|
|
1913
|
+
process.stdout.write(AGENT_BUILDER_HINT);
|
|
1914
|
+
return;
|
|
1915
|
+
}
|
|
1233
1916
|
const manifestPath = path_1.default.join(targetDir, 'orchagent.json');
|
|
1234
1917
|
const promptPath = path_1.default.join(targetDir, 'prompt.md');
|
|
1235
1918
|
const schemaPath = path_1.default.join(targetDir, 'schema.json');
|
|
@@ -1270,8 +1953,8 @@ function registerInitCommand(program) {
|
|
|
1270
1953
|
manifest.required_secrets = [];
|
|
1271
1954
|
}
|
|
1272
1955
|
else if (initMode.flavor === 'managed_loop') {
|
|
1273
|
-
manifest.description = 'An AI agent with tool use';
|
|
1274
|
-
manifest.supported_providers = ['
|
|
1956
|
+
manifest.description = 'An AI agent with tool use (managed loop)';
|
|
1957
|
+
manifest.supported_providers = ['any'];
|
|
1275
1958
|
manifest.loop = { max_turns: 25 };
|
|
1276
1959
|
manifest.required_secrets = [];
|
|
1277
1960
|
}
|
|
@@ -1283,7 +1966,7 @@ function registerInitCommand(program) {
|
|
|
1283
1966
|
manifest.tags = ['discord', 'always-on'];
|
|
1284
1967
|
}
|
|
1285
1968
|
else if (initMode.flavor === 'code_runtime') {
|
|
1286
|
-
manifest.description = 'A code-runtime
|
|
1969
|
+
manifest.description = initMode.type === 'agent' ? 'An AI agent' : 'A code-runtime tool';
|
|
1287
1970
|
if (isJavaScript) {
|
|
1288
1971
|
manifest.runtime = { command: 'node main.js' };
|
|
1289
1972
|
manifest.entrypoint = 'main.js';
|
|
@@ -1314,8 +1997,11 @@ function registerInitCommand(program) {
|
|
|
1314
1997
|
await promises_1.default.writeFile(envExamplePath, DISCORD_ENV_EXAMPLE);
|
|
1315
1998
|
}
|
|
1316
1999
|
else if (initMode.flavor === 'code_runtime') {
|
|
2000
|
+
const isAgent = initMode.type === 'agent';
|
|
1317
2001
|
if (isJavaScript) {
|
|
1318
|
-
|
|
2002
|
+
const template = runMode === 'always_on' ? ALWAYS_ON_TEMPLATE_JS
|
|
2003
|
+
: isAgent ? AGENT_CODE_TEMPLATE_JS : CODE_TEMPLATE_JS;
|
|
2004
|
+
await promises_1.default.writeFile(path_1.default.join(targetDir, 'main.js'), template);
|
|
1319
2005
|
await promises_1.default.writeFile(path_1.default.join(targetDir, 'package.json'), JSON.stringify({
|
|
1320
2006
|
name: agentName,
|
|
1321
2007
|
private: true,
|
|
@@ -1324,9 +2010,11 @@ function registerInitCommand(program) {
|
|
|
1324
2010
|
}, null, 2) + '\n');
|
|
1325
2011
|
}
|
|
1326
2012
|
else {
|
|
1327
|
-
|
|
2013
|
+
const template = runMode === 'always_on' ? ALWAYS_ON_TEMPLATE_PY
|
|
2014
|
+
: isAgent ? AGENT_CODE_TEMPLATE_PY : CODE_TEMPLATE_PY;
|
|
2015
|
+
await promises_1.default.writeFile(path_1.default.join(targetDir, 'main.py'), template);
|
|
1328
2016
|
}
|
|
1329
|
-
await promises_1.default.writeFile(schemaPath, SCHEMA_TEMPLATE);
|
|
2017
|
+
await promises_1.default.writeFile(schemaPath, isAgent ? AGENT_SCHEMA_TEMPLATE : SCHEMA_TEMPLATE);
|
|
1330
2018
|
}
|
|
1331
2019
|
else if (initMode.flavor === 'managed_loop') {
|
|
1332
2020
|
await promises_1.default.writeFile(promptPath, AGENT_PROMPT_TEMPLATE);
|
|
@@ -1338,7 +2026,7 @@ function registerInitCommand(program) {
|
|
|
1338
2026
|
}
|
|
1339
2027
|
// Create README
|
|
1340
2028
|
const readmePath = path_1.default.join(targetDir, 'README.md');
|
|
1341
|
-
await promises_1.default.writeFile(readmePath, readmeTemplate(agentName, initMode.flavor || 'direct_llm'));
|
|
2029
|
+
await promises_1.default.writeFile(readmePath, readmeTemplate(agentName, initMode.flavor || 'direct_llm', initMode.type));
|
|
1342
2030
|
process.stdout.write(`Initialized agent "${agentName}" in ${targetDir}\n`);
|
|
1343
2031
|
process.stdout.write(`\nFiles created:\n`);
|
|
1344
2032
|
const prefix = name ? name + '/' : '';
|
|
@@ -1359,7 +2047,8 @@ function registerInitCommand(program) {
|
|
|
1359
2047
|
process.stdout.write(` ${prefix}.env.example - Environment variables template\n`);
|
|
1360
2048
|
}
|
|
1361
2049
|
else if (initMode.flavor === 'code_runtime') {
|
|
1362
|
-
const entrypointDesc = runMode === 'always_on' ? 'Always-on HTTP server'
|
|
2050
|
+
const entrypointDesc = runMode === 'always_on' ? 'Always-on HTTP server'
|
|
2051
|
+
: initMode.type === 'agent' ? 'Agent entrypoint (your code)' : 'Tool entrypoint (stdin/stdout JSON)';
|
|
1363
2052
|
if (isJavaScript) {
|
|
1364
2053
|
process.stdout.write(` ${prefix}main.js - ${entrypointDesc}\n`);
|
|
1365
2054
|
process.stdout.write(` ${prefix}package.json - npm dependencies\n`);
|
|
@@ -1417,15 +2106,17 @@ function registerInitCommand(program) {
|
|
|
1417
2106
|
process.stdout.write(` ${stepNum + 3}. Deploy: orch service deploy\n`);
|
|
1418
2107
|
}
|
|
1419
2108
|
else if (isJavaScript) {
|
|
2109
|
+
const inputField = initMode.type === 'agent' ? 'task' : 'input';
|
|
1420
2110
|
process.stdout.write(` ${stepNum}. Edit main.js with your agent logic\n`);
|
|
1421
2111
|
process.stdout.write(` ${stepNum + 1}. Edit schema.json with your input/output schemas\n`);
|
|
1422
|
-
process.stdout.write(` ${stepNum + 2}. Test: echo '{"
|
|
2112
|
+
process.stdout.write(` ${stepNum + 2}. Test: echo '{"${inputField}": "test"}' | node main.js\n`);
|
|
1423
2113
|
process.stdout.write(` ${stepNum + 3}. Run: orchagent publish\n`);
|
|
1424
2114
|
}
|
|
1425
2115
|
else {
|
|
2116
|
+
const inputField = initMode.type === 'agent' ? 'task' : 'input';
|
|
1426
2117
|
process.stdout.write(` ${stepNum}. Edit main.py with your agent logic\n`);
|
|
1427
2118
|
process.stdout.write(` ${stepNum + 1}. Edit schema.json with your input/output schemas\n`);
|
|
1428
|
-
process.stdout.write(` ${stepNum + 2}. Test: echo '{"
|
|
2119
|
+
process.stdout.write(` ${stepNum + 2}. Test: echo '{"${inputField}": "test"}' | python main.py\n`);
|
|
1429
2120
|
process.stdout.write(` ${stepNum + 3}. Run: orchagent publish\n`);
|
|
1430
2121
|
}
|
|
1431
2122
|
}
|