11#!/usr/bin/env node
2- import { readFile } from "node:fs/promises" ;
2+ import { readFile , writeFile } from "node:fs/promises" ;
3+ import { fileURLToPath } from "node:url" ;
34import { Command } from "commander" ;
45import { RuntimeService , type AgentDispatchConfig } from "@agentdispatch/core" ;
56import { AgentDispatchClient } from "@agentdispatch/sdk" ;
67import { SqliteTaskStore } from "@agentdispatch/store-sqlite" ;
78import { AwsAgentCoreAdapter } from "@agentdispatch/adapter-aws-agentcore" ;
89
9- const program = new Command ( ) ;
10-
11- program . name ( "agentdispatch" ) . description ( "Provider-neutral agent task dispatcher" ) . version ( "0.1.0" ) ;
12-
13- program
14- . command ( "run" )
15- . requiredOption ( "--provider <provider>" )
16- . requiredOption ( "--account-profile <name>" )
17- . requiredOption ( "--capability <capability>" )
18- . requiredOption ( "--task-type <type>" )
19- . option ( "--target-mode <mode>" , "Target mode" , "session" )
20- . option ( "--instruction <text>" )
21- . option ( "--command <command>" )
22- . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" )
23- . action ( async ( options ) => {
24- const client = await createClient ( options . config ) ;
25- const handle = await client . dispatchTask ( {
26- provider : options . provider ,
27- accountProfile : options . accountProfile ,
28- capability : options . capability ,
29- taskType : options . taskType ,
30- target : { mode : options . targetMode } ,
31- input : { instruction : options . instruction , command : options . command }
10+ export function buildProgram ( output : Pick < Console , "log" | "error" > = console ) : Command {
11+ const program = new Command ( ) ;
12+
13+ program . name ( "agentdispatch" ) . description ( "Provider-neutral agent task dispatcher" ) . version ( "0.1.0" ) ;
14+
15+ program
16+ . command ( "init" )
17+ . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" )
18+ . option ( "--runtime-arn <arn>" , "Existing AWS AgentCore runtime ARN" , "arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/example" )
19+ . option ( "--region <region>" , "AWS region" , "us-west-2" )
20+ . action ( async ( options ) => {
21+ const config = sampleConfig ( options . region , options . runtimeArn ) ;
22+ await writeFile ( options . config , `${ JSON . stringify ( config , null , 2 ) } \n` ) ;
23+ output . log ( `Wrote ${ options . config } ` ) ;
3224 } ) ;
33- console . log ( JSON . stringify ( handle , null , 2 ) ) ;
34- } ) ;
3525
36- program . command ( "status" ) . argument ( "<taskId>" ) . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" ) . action ( async ( taskId , options ) => {
37- console . log ( JSON . stringify ( await ( await createClient ( options . config ) ) . getTaskStatus ( taskId ) , null , 2 ) ) ;
38- } ) ;
26+ program
27+ . command ( "providers" )
28+ . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" )
29+ . action ( async ( options ) => {
30+ output . log ( JSON . stringify ( ( await createClient ( options . config ) ) . listProviders ( ) , null , 2 ) ) ;
31+ } ) ;
3932
40- program . command ( "logs" ) . argument ( "<taskId>" ) . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" ) . action ( async ( taskId , options ) => {
41- const logs = await ( await createClient ( options . config ) ) . getTaskLogs ( taskId ) ;
42- process . stdout . write ( logs . data ) ;
43- } ) ;
33+ program
34+ . command ( "capabilities" )
35+ . option ( "--provider <provider>" )
36+ . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" )
37+ . action ( async ( options ) => {
38+ output . log ( JSON . stringify ( ( await createClient ( options . config ) ) . listCapabilities ( options . provider ) , null , 2 ) ) ;
39+ } ) ;
4440
45- program . command ( "result" ) . argument ( "<taskId>" ) . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" ) . action ( async ( taskId , options ) => {
46- console . log ( JSON . stringify ( await ( await createClient ( options . config ) ) . getTaskResult ( taskId ) , null , 2 ) ) ;
47- } ) ;
41+ program
42+ . command ( "accounts" )
43+ . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" )
44+ . action ( async ( options ) => {
45+ output . log ( JSON . stringify ( ( await createClient ( options . config ) ) . listAccountProfiles ( ) , null , 2 ) ) ;
46+ } ) ;
4847
49- program . command ( "cancel" ) . argument ( "<taskId>" ) . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" ) . action ( async ( taskId , options ) => {
50- console . log ( JSON . stringify ( await ( await createClient ( options . config ) ) . cancelTask ( taskId ) , null , 2 ) ) ;
51- } ) ;
48+ program
49+ . command ( "run" )
50+ . requiredOption ( "--provider <provider>" )
51+ . requiredOption ( "--account-profile <name>" )
52+ . requiredOption ( "--capability <capability>" )
53+ . requiredOption ( "--task-type <type>" )
54+ . option ( "--target-mode <mode>" , "Target mode" , "session" )
55+ . option ( "--instruction <text>" )
56+ . option ( "--command <command>" )
57+ . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" )
58+ . action ( async ( options ) => {
59+ const client = await createClient ( options . config ) ;
60+ const handle = await client . dispatchTask ( {
61+ provider : options . provider ,
62+ accountProfile : options . accountProfile ,
63+ capability : options . capability ,
64+ taskType : options . taskType ,
65+ target : { mode : options . targetMode } ,
66+ input : { instruction : options . instruction , command : options . command }
67+ } ) ;
68+ output . log ( JSON . stringify ( handle , null , 2 ) ) ;
69+ } ) ;
5270
53- void program . parseAsync ( ) ;
71+ program . command ( "status" ) . argument ( "<taskId>" ) . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" ) . action ( async ( taskId , options ) => {
72+ output . log ( JSON . stringify ( await ( await createClient ( options . config ) ) . getTaskStatus ( taskId ) , null , 2 ) ) ;
73+ } ) ;
74+
75+ program . command ( "logs" ) . argument ( "<taskId>" ) . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" ) . action ( async ( taskId , options ) => {
76+ const logs = await ( await createClient ( options . config ) ) . getTaskLogs ( taskId ) ;
77+ output . log ( logs . data ) ;
78+ } ) ;
5479
55- async function createClient ( configPath : string ) : Promise < AgentDispatchClient > {
80+ program . command ( "result" ) . argument ( "<taskId>" ) . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" ) . action ( async ( taskId , options ) => {
81+ output . log ( JSON . stringify ( await ( await createClient ( options . config ) ) . getTaskResult ( taskId ) , null , 2 ) ) ;
82+ } ) ;
83+
84+ program . command ( "cancel" ) . argument ( "<taskId>" ) . option ( "--config <path>" , "Config file" , "agentdispatch.config.json" ) . action ( async ( taskId , options ) => {
85+ output . log ( JSON . stringify ( await ( await createClient ( options . config ) ) . cancelTask ( taskId ) , null , 2 ) ) ;
86+ } ) ;
87+
88+ return program ;
89+ }
90+
91+ export async function createClient ( configPath : string ) : Promise < AgentDispatchClient > {
5692 const config = await loadConfig ( configPath ) ;
5793 const stateDir = config . stateDir ?? ".agentdispatch" ;
5894 const store = new SqliteTaskStore ( { stateDir } ) ;
@@ -73,7 +109,42 @@ async function createClient(configPath: string): Promise<AgentDispatchClient> {
73109 return new AgentDispatchClient ( new RuntimeService ( { config, store, adapters } ) ) ;
74110}
75111
76- async function loadConfig ( path : string ) : Promise < AgentDispatchConfig > {
112+ export async function loadConfig ( path : string ) : Promise < AgentDispatchConfig > {
77113 const raw = await readFile ( path , "utf8" ) ;
78114 return JSON . parse ( raw ) as AgentDispatchConfig ;
79115}
116+
117+ export function sampleConfig ( region : string , runtimeArn : string ) : AgentDispatchConfig {
118+ return {
119+ stateDir : ".agentdispatch" ,
120+ accounts : {
121+ "dev-aws" : {
122+ provider : "aws" ,
123+ region,
124+ credentialSource : "aws-sdk-default"
125+ }
126+ } ,
127+ backends : {
128+ "aws-agentcore" : {
129+ provider : "aws" ,
130+ capability : "agent-runtime" ,
131+ adapter : "aws-agentcore" ,
132+ account : "dev-aws" ,
133+ details : {
134+ runtimeArn,
135+ qualifier : "DEFAULT"
136+ }
137+ }
138+ } ,
139+ defaults : {
140+ provider : "aws" ,
141+ accountProfile : "dev-aws" ,
142+ capability : "agent-runtime" ,
143+ backend : "aws-agentcore"
144+ }
145+ } ;
146+ }
147+
148+ if ( process . argv [ 1 ] && fileURLToPath ( import . meta. url ) === process . argv [ 1 ] ) {
149+ void buildProgram ( ) . parseAsync ( ) ;
150+ }
0 commit comments