1"""

2 AgentOS CLI — Command-line interface for agent management.

3

4 v1.14.5: Full-featured CLI for init, run, deploy, list, and config management.

5"""

6

7 import argparse

8 import asyncio

9 import json

10 import logging

11 import os

12 import sys

13 from pathlib import Path

14 from typing import Optional

15

16 logger = logging.getLogger(__name__)

17

18

19 def main():

20 parser = argparse.ArgumentParser(

21 prog="agentos",

22 description="AgentOS — Production Multi-Agent Framework CLI",

23 )

24 sub = parser.add_subparsers(dest="command", required=True)

25

26 # ---- init ----

27 p_init = sub.add_parser("init", help="Initialize a new agent project")

28 p_init.add_argument("name", help="Project name")

29 p_init.add_argument("--template", "-t", default="default",

30 choices=["default", "chat", "research", "coding", "pipeline"],

31 help="Project template")

32 p_init.add_argument("--dir", "-d", default=".", help="Target directory")

33

34 # ---- run ----

35 p_run = sub.add_parser("run", help="Run an agent or workflow")

36 p_run.add_argument("target", help="Agent config file (.yaml) or workflow file")

37 p_run.add_argument("--prompt", "-p", help="Prompt to send to agent")

38 p_run.add_argument("--stream", "-s", action="store_true", help="Stream output")

39 p_run.add_argument("--model", "-m", help="Override model")

40

41 # ---- deploy ----

42 p_deploy = sub.add_parser("deploy", help="Deploy agent to cluster")

43 p_deploy.add_argument("config", help="Agent config file")

44 p_deploy.add_argument("--workers", "-w", type=int, default=1, help="Number of workers")

45 p_deploy.add_argument("--ray", action="store_true", help="Deploy via Ray cluster")

46

47 # ---- list ----

48 p_list = sub.add_parser("list", help="List running agents")

49 p_list.add_argument("--format", "-f", choices=["table", "json"], default="table")

50

51 # ---- marketplace ----

52 p_market = sub.add_parser("marketplace", help="Agent marketplace commands")

53 m_sub = p_market.add_subparsers(dest="market_cmd", required=True)

54 m_sub.add_parser("search", help="Search marketplace").add_argument("query", nargs="?", default="")

55 m_sub.add_parser("install", help="Install a template").add_argument("template_id")

56 m_sub.add_parser("featured", help="Show featured templates")

57

58 # ---- config ----

59 p_config = sub.add_parser("config", help="Manage agent configuration")

60 c_sub = p_config.add_subparsers(dest="config_cmd", required=True)

61 c_sub.add_parser("show", help="Show current config")

62 c_sub.add_parser("set", help="Set a config value").add_argument("key")

63 c_sub.add_parser("list-models", help="List available models")

64

65 # ---- serve (API) ----

66 p_serve = sub.add_parser("serve", help="Start AgentOS API server")

67 p_serve.add_argument("--host", default="0.0.0.0", help="Host to bind")

68 p_serve.add_argument("--port", "-p", type=int, default=8000, help="Port")

69 p_serve.add_argument("--reload", action="store_true", help="Auto-reload on changes")

70

71 # ---- version ----

72 sub.add_parser("version", help="Show version")

73

74 args = parser.parse_args()

75 handler = CLIHandler()

76

77 if args.command == "init":

78 handler.cmd_init(args)

79 elif args.command == "run":

80 asyncio.run(handler.cmd_run(args))

81 elif args.command == "deploy":

82 asyncio.run(handler.cmd_deploy(args))

83 elif args.command == "list":

84 asyncio.run(handler.cmd_list(args))

85 elif args.command == "marketplace":

86 asyncio.run(handler.cmd_marketplace(args))

87 elif args.command == "config":

88 handler.cmd_config(args)

89 elif args.command == "serve":

90 handler.cmd_serve(args)

91 elif args.command == "version":

92 handler.cmd_version()

93

94

95 class CLIHandler:

96 def cmd_init(self, args):

97 target = Path(args.dir).resolve() / args.name

98 target.mkdir(parents=True, exist_ok=True)

99

100 templates = {

101 "default": {

102 "agent.yaml": "name: {name}\ntype: default\nmodel: gpt-4o\n",

103 "main.py": (

104 "from agentos import Agent, OpenAIModel\n\n"

105 "agent = Agent(\n"

106 " model=OpenAIModel('gpt-4o'),\n"

107 " system_prompt='You are a helpful assistant.',\n"

108 ")\n\n"

109 "async def main():\n"

110 " result = await agent.run('Hello!')\n"

111 " print(result)\n\n"

112 "if __name__ == '__main__':\n"

113 " import asyncio\n"

114 " asyncio.run(main())\n"

115 ),

116 },

117 "chat": {

118 "agent.yaml": "name: {name}\ntype: chat\nmodel: gpt-4o\nmemory: enabled\n",

119 "main.py": (

120 "from agentos import Agent, OpenAIModel\n"

121 "from agentos.memory.consolidation import ReflectionEngine\n\n"

122 "agent = Agent(\n"

123 " model=OpenAIModel('gpt-4o'),\n"

124 " memory=ReflectionEngine(),\n"

125 ")\n"

126 ),

127 },

128 "research": {

129 "agent.yaml": "name: {name}\ntype: research\nmodel: gpt-4o\ntools: [web_search, arxiv]\n",

130 "main.py": (

131 "from agentos import Agent, Swarm\n\n"

132 "researcher = Agent(model='gpt-4o', name='Researcher')\n"

133 "writer = Agent(model='gpt-4o', name='Writer')\n"

134 "swarm = Swarm(agents=[researcher, writer])\n"

135 ),

136 },

137 "coding": {

138 "agent.yaml": "name: {name}\ntype: coding\nmodel: claude-3-opus\n",

139 },

140 "pipeline": {

141 "agent.yaml": "name: {name}\ntype: pipeline\nworkflow: workflow.yaml\n",

142 "workflow.yaml": (

143 "name: {name}-pipeline\n"

144 "version: '1.0'\n"

145 "steps:\n"

146 " - id: process\n"

147 " type: task\n"

148 " agent: default\n"

149 " task: 'Process input'\n"

150 ),

151 },

152 }

153

154 tmpl = templates.get(args.template, templates["default"])

155 for filename, content in tmpl.items():

156 formatted = content.format(name=args.name)

157 (target / filename).write_text(formatted)

158

159 print(f"✓ Created {args.template} project '{args.name}' at {target}")

160 print(f" cd {target} && agentos run agent.yaml -p 'Hello!'")

161

162 async def cmd_run(self, args):

163 target = Path(args.target)

164 if not target.exists():

165 print(f"Error: '{target}' not found")

166 sys.exit(1)

167

168 try:

169 from agentos import Agent

170 import yaml

171

172 if target.suffix in (".yaml", ".yml"):

173 config = yaml.safe_load(target.read_text())

174 agent = Agent.from_config(config)

175 else:

176 # Workflow file

177 from agentos.workflow import WorkflowParser, WorkflowEngine

178 wf = WorkflowParser.parse_file(target)

179 ctx = await WorkflowEngine().execute(wf)

180 print(json.dumps(ctx.variables, indent=2, default=str))

181 return

182

183 prompt = args.prompt or "Tell me about yourself."

184 if args.stream:

185 async for chunk in agent.stream(prompt):

186 print(chunk, end="", flush=True)

187 print()

188 else:

189 result = await agent.run(prompt)

190 print(result)

191

192 except Exception as e:

193 print(f"Error: {e}", file=sys.stderr)

194 sys.exit(1)

195

196 async def cmd_deploy(self, args):

197 config_path = Path(args.config)

198 if not config_path.exists():

199 print(f"Error: config '{config_path}' not found")

200 sys.exit(1)

201

202 if args.ray:

203 from agentos.orchestration.distributed import RayAgentActor, PlacementStrategy

204 import ray

205 ray.init()

206 actor = RayAgentActor.options(num_cpus=args.workers).remote(config_path)

207 print(f"✓ Deployed {args.workers} workers to Ray cluster")

208 else:

209 print(f"✓ Deploying {args.workers} workers via local mode")

210 print(" (Install 'ray' for distributed deployment)")

211

212 async def cmd_list(self, args):

213 try:

214 from agentos.protocols.registry import AgentRegistry

215 registry = AgentRegistry()

216 agents = await registry.list_agents()

217

218 if args.format == "json":

219 print(json.dumps([a.__dict__ for a in agents], indent=2, default=str))

220 else:

221 if not agents:

222 print("No agents registered.")

223 return

224 print(f"{'ID':20} {'Capabilities':30} {'Status'}")

225 print("-" * 65)

226 for a in agents:

227 caps = ", ".join(a.capabilities[:3])

228 print(f"{a.agent_id:20} {caps:30} {'online' if a.healthy else 'offline'}")

229 except Exception as e:

230 print("No running agents found. Start an agent first with 'agentos serve' or 'agentos run'.")

231

232 async def cmd_marketplace(self, args):

233 from agentos.marketplace import MarketplaceManager, MarketSearchQuery

234 manager = MarketplaceManager()

235

236 if args.market_cmd == "search":

237 results = await manager.search(MarketSearchQuery(keywords=args.query or ""))

238 if not results:

239 print("No templates found.")

240 return

241 for r in results[:10]:

242 print(f" {r.template.name:30} ★{r.template.rating:.1f} {r.template.description[:60]}")

243 elif args.market_cmd == "install":

244 path = await manager.install(args.template_id)

245 print(f"✓ Installed to {path}")

246 elif args.market_cmd == "featured":

247 featured = await manager.get_featured(10)

248 for tpl in featured:

249 print(f" {tpl.name:30} {tpl.downloads:>6} downloads ★{tpl.rating:.1f}")

250

251 def cmd_config(self, args):

252 config_dir = Path.home() / ".agentos"

253 config_dir.mkdir(exist_ok=True)

254 config_file = config_dir / "config.json"

255

256 if args.config_cmd == "show":

257 if config_file.exists():

258 print(config_file.read_text())

259 else:

260 print(json.dumps({"model": "gpt-4o", "workspace": str(Path.home() / "agentos")}, indent=2))

261 elif args.config_cmd == "set":

262 key, _, value = args.key.partition("=")

263 if not value:

264 print("Usage: agentos config set KEY=VALUE")

265 return

266 cfg = json.loads(config_file.read_text()) if config_file.exists() else {}

267 cfg[key] = value

268 config_file.write_text(json.dumps(cfg, indent=2))

269 print(f"✓ Set {key}={value}")

270 elif args.config_cmd == "list-models":

271 models = ["gpt-4o", "gpt-4-turbo", "claude-3-opus", "claude-3-sonnet",

272 "gemini-1.5-pro", "llama-3-70b", "mixtral-8x7b"]

273 for m in models:

274 print(f" {m}")

275

276 def cmd_serve(self, args):

277 print(f"Starting AgentOS API server on http://{args.host}:{args.port}")

278 print("API docs: http://{args.host}:{args.port}/docs")

279 try:

280 from agentos.api.server import serve

281 import uvicorn

282 uvicorn.run("agentos.api.server:app", host=args.host, port=args.port, reload=args.reload)

283 except ImportError:

284 print("Install API dependencies: pip install nexus-agentos[api]")

285 print("Module 'agentos.api.server' not available yet — running stub.")

286 import http.server

287 server = http.server.HTTPServer(

288 (args.host, args.port),

289 lambda *a: None,

290 )

291 print(f" Stub server on {args.host}:{args.port}")

292 try:

293 server.serve_forever()

294 except KeyboardInterrupt:

295 print("\nShutting down...")

296

297 def cmd_version(self):

298 from agentos import __version__

299 print(f"AgentOS v{__version__}")

300

301

302 if __name__ == "__main__":

303 main()