@voybio/ace-swarm 2.4.0 → 2.4.2

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +502 -56
  3. package/assets/.agents/ACE/agent-qa/instructions.md +11 -0
  4. package/assets/agent-state/MODULES/schemas/RUNTIME_TOOL_SPEC_REGISTRY.schema.json +43 -0
  5. package/assets/agent-state/runtime-tool-specs.json +70 -2
  6. package/assets/instructions/ACE_Coder.instructions.md +13 -0
  7. package/assets/instructions/ACE_UI.instructions.md +11 -0
  8. package/dist/ace-context.js +70 -11
  9. package/dist/ace-internal-tools.d.ts +3 -1
  10. package/dist/ace-internal-tools.js +10 -2
  11. package/dist/agent-runtime/role-adapters.d.ts +18 -1
  12. package/dist/agent-runtime/role-adapters.js +49 -5
  13. package/dist/astgrep-index.d.ts +48 -0
  14. package/dist/astgrep-index.js +126 -1
  15. package/dist/cli.js +487 -17
  16. package/dist/discovery-runtime-wrappers.d.ts +108 -0
  17. package/dist/discovery-runtime-wrappers.js +615 -0
  18. package/dist/helpers/bootstrap.js +1 -1
  19. package/dist/helpers/constants.d.ts +4 -2
  20. package/dist/helpers/constants.js +8 -0
  21. package/dist/helpers/path-utils.d.ts +8 -1
  22. package/dist/helpers/path-utils.js +27 -8
  23. package/dist/helpers/store-resolution.js +7 -3
  24. package/dist/hermes/bridge-protocol.d.ts +41 -0
  25. package/dist/hermes/bridge-protocol.js +70 -0
  26. package/dist/hermes/launch-profile.d.ts +19 -0
  27. package/dist/hermes/launch-profile.js +81 -0
  28. package/dist/hermes/session-manager.d.ts +42 -0
  29. package/dist/hermes/session-manager.js +187 -0
  30. package/dist/job-scheduler.js +30 -4
  31. package/dist/json-sanitizer.d.ts +16 -0
  32. package/dist/json-sanitizer.js +26 -0
  33. package/dist/local-model-policy.d.ts +27 -0
  34. package/dist/local-model-policy.js +84 -0
  35. package/dist/local-model-runtime.d.ts +17 -0
  36. package/dist/local-model-runtime.js +77 -20
  37. package/dist/model-bridge.d.ts +6 -1
  38. package/dist/model-bridge.js +338 -21
  39. package/dist/orchestrator-supervisor.d.ts +42 -0
  40. package/dist/orchestrator-supervisor.js +110 -3
  41. package/dist/plan-proposal.d.ts +115 -0
  42. package/dist/plan-proposal.js +1073 -0
  43. package/dist/runtime-executor.d.ts +6 -1
  44. package/dist/runtime-executor.js +72 -5
  45. package/dist/runtime-tool-specs.d.ts +19 -1
  46. package/dist/runtime-tool-specs.js +67 -26
  47. package/dist/schemas.js +30 -1
  48. package/dist/server.d.ts +3 -0
  49. package/dist/server.js +73 -4
  50. package/dist/shared.d.ts +1 -0
  51. package/dist/shared.js +2 -0
  52. package/dist/store/bootstrap-store.d.ts +1 -0
  53. package/dist/store/bootstrap-store.js +8 -2
  54. package/dist/store/materializers/vericify-projector.js +3 -0
  55. package/dist/store/repositories/local-model-runtime-repository.d.ts +13 -1
  56. package/dist/store/repositories/local-model-runtime-repository.js +4 -1
  57. package/dist/store/repositories/vericify-repository.d.ts +1 -1
  58. package/dist/tools-agent.d.ts +20 -0
  59. package/dist/tools-agent.js +544 -29
  60. package/dist/tools-discovery.js +135 -0
  61. package/dist/tools-files.js +768 -66
  62. package/dist/tools-framework.js +80 -61
  63. package/dist/tools.d.ts +4 -1
  64. package/dist/tools.js +35 -13
  65. package/dist/tui/chat.d.ts +8 -0
  66. package/dist/tui/chat.js +74 -0
  67. package/dist/tui/index.d.ts +7 -0
  68. package/dist/tui/index.js +45 -2
  69. package/dist/tui/layout.d.ts +1 -0
  70. package/dist/tui/layout.js +4 -1
  71. package/dist/tui/ollama.d.ts +8 -1
  72. package/dist/tui/ollama.js +53 -12
  73. package/dist/tui/openai-compatible.d.ts +13 -0
  74. package/dist/tui/openai-compatible.js +305 -5
  75. package/dist/tui/provider-discovery.d.ts +1 -0
  76. package/dist/tui/provider-discovery.js +50 -24
  77. package/dist/vericify-bridge.d.ts +4 -1
  78. package/dist/vericify-bridge.js +3 -0
  79. package/package.json +2 -1
  80. package/scripts/hermes_bridge_worker.py +136 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voybio/ace-swarm",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "ACE Framework MCP server and CLI — single-file ACEPACK state, local-model serving, agent orchestration, and host compliance enforcement.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,6 +21,7 @@
21
21
  "files": [
22
22
  "dist/**/*.js",
23
23
  "dist/**/*.d.ts",
24
+ "scripts/hermes_bridge_worker.py",
24
25
  "assets",
25
26
  "README.md",
26
27
  "CHANGELOG.md"
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env python3
2
+ """ACE-owned Hermes bridge worker.
3
+
4
+ The worker reads one JSON request from stdin and writes newline-delimited
5
+ bridge events to stdout. All Hermes stdout chatter is redirected to stderr so
6
+ ACE never has to guess whether an unframed line is assistant text or authority.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import contextlib
12
+ import json
13
+ import os
14
+ import sys
15
+ import traceback
16
+ from pathlib import Path
17
+ from typing import Any
18
+
19
+
20
+ ORIGINAL_STDOUT = sys.stdout
21
+
22
+
23
+ def emit(event: dict[str, Any]) -> None:
24
+ ORIGINAL_STDOUT.write(json.dumps(event, ensure_ascii=False, separators=(",", ":")) + "\n")
25
+ ORIGINAL_STDOUT.flush()
26
+
27
+
28
+ def load_request() -> dict[str, Any]:
29
+ raw = sys.stdin.read()
30
+ if not raw.strip():
31
+ raise ValueError("empty bridge request")
32
+ parsed = json.loads(raw)
33
+ if not isinstance(parsed, dict):
34
+ raise ValueError("bridge request must be a JSON object")
35
+ return parsed
36
+
37
+
38
+ def provider_for_hermes(provider: str) -> str:
39
+ if provider in {"llama.cpp", "ollama"}:
40
+ return "openai"
41
+ return provider
42
+
43
+
44
+ def base_url_for_hermes(provider: str, base_url: Any) -> str:
45
+ raw = str(base_url or "").rstrip("/")
46
+ if provider == "ollama" and raw and not raw.endswith("/v1"):
47
+ return f"{raw}/v1"
48
+ return raw
49
+
50
+
51
+ def main() -> int:
52
+ try:
53
+ request = load_request()
54
+ hermes_root = Path(request["hermes_root"]).resolve()
55
+ sys.path.insert(0, str(hermes_root))
56
+
57
+ session_id = str(request["session_id"])
58
+ turn_id = str(request.get("turn_id") or session_id)
59
+ emit({"type": "session_open", "session_id": session_id, "turn_id": turn_id})
60
+
61
+ with contextlib.redirect_stdout(sys.stderr):
62
+ from run_agent import AIAgent # type: ignore
63
+
64
+ def status_callback(kind: str, message: str) -> None:
65
+ emit({"type": "status" if kind == "lifecycle" else "status", "session_id": session_id, "turn_id": turn_id, "kind": kind, "message": str(message)})
66
+
67
+ def delta_callback(text: str) -> None:
68
+ emit({"type": "delta", "session_id": session_id, "turn_id": turn_id, "text": str(text)})
69
+
70
+ def reasoning_callback(text: str) -> None:
71
+ emit({"type": "reasoning", "session_id": session_id, "turn_id": turn_id, "text": str(text)})
72
+
73
+ def interim_callback(text: str, **kwargs: Any) -> None:
74
+ emit({"type": "assistant_interim", "session_id": session_id, "turn_id": turn_id, "text": str(text), **kwargs})
75
+
76
+ def thinking_callback(text: str) -> None:
77
+ emit({"type": "reasoning", "session_id": session_id, "turn_id": turn_id, "text": str(text)})
78
+
79
+ def tool_start_callback(tool_name: str, *args: Any, **kwargs: Any) -> None:
80
+ emit({"type": "tool_start", "session_id": session_id, "turn_id": turn_id, "tool": str(tool_name), "input": kwargs.get("args") or (args[0] if args else {})})
81
+
82
+ def tool_progress_callback(tool_name: str, message: str = "", *args: Any, **kwargs: Any) -> None:
83
+ emit({"type": "tool_progress", "session_id": session_id, "turn_id": turn_id, "tool": str(tool_name), "message": str(message), **kwargs})
84
+
85
+ def tool_complete_callback(tool_name: str, result: Any = None, *args: Any, **kwargs: Any) -> None:
86
+ emit({"type": "tool_complete", "session_id": session_id, "turn_id": turn_id, "tool": str(tool_name), "result": result, **kwargs})
87
+
88
+ agent = AIAgent(
89
+ base_url=base_url_for_hermes(str(request.get("provider") or ""), request.get("base_url")),
90
+ api_key=str(request.get("api_key") or "no-key-required"),
91
+ provider=provider_for_hermes(str(request.get("provider") or "")),
92
+ model=str(request.get("model") or ""),
93
+ max_iterations=int(request.get("max_turns") or 6),
94
+ enabled_toolsets=["mcp-ace_shadow"],
95
+ disabled_toolsets=["terminal", "filesystem", "web", "vision", "creative", "reasoning"],
96
+ quiet_mode=True,
97
+ verbose_logging=False,
98
+ ephemeral_system_prompt=str(request.get("system_prompt") or ""),
99
+ session_id=session_id,
100
+ platform="ace",
101
+ skip_context_files=True,
102
+ skip_memory=True,
103
+ status_callback=status_callback,
104
+ stream_delta_callback=delta_callback,
105
+ reasoning_callback=reasoning_callback,
106
+ thinking_callback=thinking_callback,
107
+ interim_assistant_callback=interim_callback,
108
+ tool_start_callback=tool_start_callback,
109
+ tool_progress_callback=tool_progress_callback,
110
+ tool_complete_callback=tool_complete_callback,
111
+ )
112
+ emit({"type": "turn_run", "session_id": session_id, "turn_id": turn_id})
113
+ result = agent.run_conversation(str(request.get("task") or ""), task_id=turn_id)
114
+
115
+ final = result.get("final_response") if isinstance(result, dict) else str(result)
116
+ emit({
117
+ "type": "final",
118
+ "session_id": session_id,
119
+ "turn_id": turn_id,
120
+ "text": final or "",
121
+ "completed": bool(result.get("completed", True)) if isinstance(result, dict) else True,
122
+ "turns": int(result.get("api_calls", 1) or 1) if isinstance(result, dict) else 1,
123
+ })
124
+ emit({"type": "session_close", "session_id": session_id, "turn_id": turn_id})
125
+ return 0
126
+ except Exception as exc:
127
+ emit({
128
+ "type": "error",
129
+ "message": str(exc),
130
+ "traceback": traceback.format_exc(limit=8),
131
+ })
132
+ return 1
133
+
134
+
135
+ if __name__ == "__main__":
136
+ raise SystemExit(main())