|
|
|
|
|
import argparse |
|
import yaml |
|
import time |
|
import threading |
|
import sys |
|
from storage import Storage |
|
|
|
def load_config(path="config.yml"): |
|
try: |
|
with open(path, "r", encoding="utf-8") as f: |
|
return yaml.safe_load(f) |
|
except FileNotFoundError: |
|
print(f"[Error] Config file not found: {path}") |
|
return {} |
|
except yaml.YAMLError as e: |
|
print(f"[Error] Failed to parse YAML config: {e}") |
|
return {} |
|
|
|
def main(): |
|
parser = argparse.ArgumentParser(description="HMP Agent CLI") |
|
parser.add_argument("--config", default="config.yml", help="Путь к конфигурационному файлу") |
|
subparsers = parser.add_subparsers(dest="command") |
|
|
|
|
|
write_parser = subparsers.add_parser("write_entry", help="Добавить запись в когнитивный дневник") |
|
write_parser.add_argument("text") |
|
write_parser.add_argument("--tags", nargs="*", help="Теги (опционально)") |
|
|
|
read_parser = subparsers.add_parser("read_entries", help="Показать последние записи") |
|
read_parser.add_argument("--limit", type=int, default=5) |
|
|
|
search_time_parser = subparsers.add_parser("search_entries_by_time", help="Поиск записей по временному диапазону") |
|
search_time_parser.add_argument("--from_ts", required=True) |
|
search_time_parser.add_argument("--to_ts", required=True) |
|
|
|
|
|
concept_parser = subparsers.add_parser("add_concept", help="Добавить концепт") |
|
concept_parser.add_argument("name") |
|
concept_parser.add_argument("--description", help="Описание (опционально)") |
|
|
|
link_parser = subparsers.add_parser("add_link", help="Добавить связь") |
|
link_parser.add_argument("--from_node", type=int, required=True) |
|
link_parser.add_argument("--to_node", type=int, required=True) |
|
link_parser.add_argument("--relation", required=True) |
|
|
|
expand_parser = subparsers.add_parser("expand_graph", help="Расширить граф от узла с глубиной") |
|
expand_parser.add_argument("--start_id", type=int, required=True) |
|
expand_parser.add_argument("--depth", type=int, default=1) |
|
|
|
args = parser.parse_args() |
|
|
|
|
|
config = load_config(args.config) |
|
storage = Storage(config=config) |
|
|
|
print(f"[Agent] Запущена команда: {args.command}") |
|
|
|
|
|
if args.command == "write_entry": |
|
storage.write_entry(args.text, args.tags) |
|
print("✅ Запись добавлена.") |
|
|
|
elif args.command == "read_entries": |
|
for entry in storage.read_entries(limit=args.limit): |
|
print(f"[{entry[0]}] {entry[1]} | tags: {entry[2]} | ts: {entry[3]}") |
|
|
|
elif args.command == "search_entries_by_time": |
|
results = storage.search_entries_by_time(args.from_ts, args.to_ts) |
|
for e in results: |
|
print(f"[{e[0]}] {e[1]} | tags: {e[2]} | ts: {e[3]}") |
|
|
|
|
|
elif args.command == "add_concept": |
|
cid = storage.add_concept(args.name, args.description) |
|
print(f"✅ Концепт добавлен с ID: {cid}") |
|
|
|
elif args.command == "add_link": |
|
storage.add_link(args.from_node, args.to_node, args.relation) |
|
print("✅ Связь добавлена.") |
|
|
|
elif args.command == "expand_graph": |
|
links = storage.expand_graph(args.start_id, args.depth) |
|
print(f"📐 Подграф (до глубины {args.depth}):") |
|
for src, tgt, rel in links: |
|
print(f"{src} --[{rel}]--> {tgt}") |
|
|
|
else: |
|
parser.print_help() |
|
|
|
storage.close() |
|
|
|
|
|
def run_mcp_agent(config): |
|
print(f"[HMP-MCP] MCP-Agent '{config.get('agent_name', 'unnamed')}' запущен в DHT-режиме") |
|
|
|
bootstrap_path = config.get("bootstrap_file", "bootstrap.txt") |
|
update_interval = config.get("update_interval", 30) |
|
enable_api = config.get("serve_api", True) |
|
|
|
def load_bootstrap(): |
|
try: |
|
with open(bootstrap_path, "r") as f: |
|
return [line.strip() for line in f if line.strip()] |
|
except FileNotFoundError: |
|
print("[Warning] bootstrap.txt не найден. Запуск без исходных узлов.") |
|
return [] |
|
|
|
def update_dht(): |
|
nodes = load_bootstrap() |
|
print(f"[MCP] Найдено {len(nodes)} узлов в bootstrap.txt:") |
|
for node in nodes: |
|
print(f" ↪️ Пинг {node} (заглушка)") |
|
print("[MCP] Обновление DHT завершено.") |
|
|
|
def mcp_loop(): |
|
while True: |
|
update_dht() |
|
time.sleep(update_interval) |
|
|
|
threading.Thread(target=mcp_loop, daemon=True).start() |
|
|
|
if enable_api: |
|
print("[MCP] REST API (заглушка) доступен по адресу http://localhost:8000/") |
|
print(" В будущем: /bootstrap, /status, /reputation/:id и пр.") |
|
|
|
try: |
|
while True: |
|
time.sleep(1) |
|
except KeyboardInterrupt: |
|
print("\n[MCP] MCP-Agent завершает работу.") |
|
|
|
if __name__ == "__main__": |
|
main() |
|
|