| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- #!/usr/bin/env python3
- """
- Gateway CLI - 命令行工具
- 可以直接在终端运行的 A2A IM 工具。
- 使用示例:
- # 发送消息
- gateway-cli send --to agent-001 --message "Hello"
- # 查询在线 Agent
- gateway-cli list
- # 查询 Agent 状态
- gateway-cli status agent-001
- """
- import asyncio
- import json
- import sys
- from typing import Optional
- import click
- from gateway.client.python import tools
- @click.group()
- @click.option('--gateway-url', default='http://localhost:8001',
- envvar='GATEWAY_URL',
- help='Gateway 地址 (默认: http://localhost:8001)')
- @click.pass_context
- def cli(ctx, gateway_url):
- """Gateway CLI - A2A IM 命令行工具"""
- ctx.ensure_object(dict)
- ctx.obj['gateway_url'] = gateway_url
- @cli.command()
- @click.option('--from', 'from_agent', required=True, help='发送方 Agent ID')
- @click.option('--to', 'to_agent', required=True, help='接收方 Agent ID')
- @click.option('--message', '-m', required=True, help='消息内容')
- @click.option('--conversation-id', '-c', help='对话 ID (可选)')
- @click.pass_context
- def send(ctx, from_agent, to_agent, message, conversation_id):
- """发送消息到其他 Agent"""
- async def _send():
- result = await tools.send_message(
- gateway_url=ctx.obj['gateway_url'],
- from_agent_id=from_agent,
- to_agent_id=to_agent,
- message=message,
- conversation_id=conversation_id
- )
- click.echo(json.dumps(result, indent=2, ensure_ascii=False))
- asyncio.run(_send())
- @cli.command()
- @click.option('--type', 'agent_type', help='过滤 Agent 类型')
- @click.pass_context
- def list(ctx, agent_type):
- """查询在线 Agent 列表"""
- async def _list():
- agents = await tools.list_online_agents(
- gateway_url=ctx.obj['gateway_url'],
- agent_type=agent_type
- )
- if not agents:
- click.echo("没有找到在线 Agent")
- return
- click.echo(f"找到 {len(agents)} 个在线 Agent:\n")
- for agent in agents:
- click.echo(f"🟢 {agent['agent_name']} ({agent['agent_id']})")
- if agent.get('capabilities'):
- click.echo(f" 能力: {', '.join(agent['capabilities'])}")
- if agent.get('description'):
- click.echo(f" 描述: {agent['description']}")
- click.echo()
- asyncio.run(_list())
- @cli.command()
- @click.argument('agent_id')
- @click.pass_context
- def status(ctx, agent_id):
- """查询 Agent 在线状态"""
- async def _status():
- result = await tools.get_agent_status(
- gateway_url=ctx.obj['gateway_url'],
- agent_id=agent_id
- )
- status = result.get('status', 'unknown')
- icon = '🟢' if status == 'online' else '⚪'
- click.echo(f"{icon} {agent_id}")
- click.echo(f"状态: {status}")
- if result.get('last_seen'):
- click.echo(f"最后在线: {result['last_seen']}")
- asyncio.run(_status())
- @cli.command()
- @click.option('--id', 'agent_id', required=True, help='Agent ID')
- @click.option('--name', 'agent_name', required=True, help='Agent 名称')
- @click.option('--type', 'agent_type', help='Agent 类型')
- @click.option('--capabilities', '-c', multiple=True, help='Agent 能力 (可多次指定)')
- @click.option('--description', '-d', help='Agent 描述')
- @click.pass_context
- def register(ctx, agent_id, agent_name, agent_type, capabilities, description):
- """注册 Agent 到 Gateway (保持连接)"""
- async def _register():
- click.echo(f"正在注册 Agent: {agent_id}...")
- client = await tools.register_agent(
- gateway_url=ctx.obj['gateway_url'],
- agent_id=agent_id,
- agent_name=agent_name,
- agent_type=agent_type,
- capabilities=list(capabilities) if capabilities else [],
- description=description
- )
- click.echo(f"✅ Agent 已注册: {agent_id}")
- click.echo("按 Ctrl+C 断开连接")
- try:
- # 保持连接
- while True:
- await asyncio.sleep(1)
- except KeyboardInterrupt:
- click.echo("\n正在断开连接...")
- await client.disconnect()
- click.echo("已断开连接")
- asyncio.run(_register())
- if __name__ == '__main__':
- cli()
|