@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.
- package/CHANGELOG.md +16 -0
- package/README.md +502 -56
- package/assets/.agents/ACE/agent-qa/instructions.md +11 -0
- package/assets/agent-state/MODULES/schemas/RUNTIME_TOOL_SPEC_REGISTRY.schema.json +43 -0
- package/assets/agent-state/runtime-tool-specs.json +70 -2
- package/assets/instructions/ACE_Coder.instructions.md +13 -0
- package/assets/instructions/ACE_UI.instructions.md +11 -0
- package/dist/ace-context.js +70 -11
- package/dist/ace-internal-tools.d.ts +3 -1
- package/dist/ace-internal-tools.js +10 -2
- package/dist/agent-runtime/role-adapters.d.ts +18 -1
- package/dist/agent-runtime/role-adapters.js +49 -5
- package/dist/astgrep-index.d.ts +48 -0
- package/dist/astgrep-index.js +126 -1
- package/dist/cli.js +487 -17
- package/dist/discovery-runtime-wrappers.d.ts +108 -0
- package/dist/discovery-runtime-wrappers.js +615 -0
- package/dist/helpers/bootstrap.js +1 -1
- package/dist/helpers/constants.d.ts +4 -2
- package/dist/helpers/constants.js +8 -0
- package/dist/helpers/path-utils.d.ts +8 -1
- package/dist/helpers/path-utils.js +27 -8
- package/dist/helpers/store-resolution.js +7 -3
- package/dist/hermes/bridge-protocol.d.ts +41 -0
- package/dist/hermes/bridge-protocol.js +70 -0
- package/dist/hermes/launch-profile.d.ts +19 -0
- package/dist/hermes/launch-profile.js +81 -0
- package/dist/hermes/session-manager.d.ts +42 -0
- package/dist/hermes/session-manager.js +187 -0
- package/dist/job-scheduler.js +30 -4
- package/dist/json-sanitizer.d.ts +16 -0
- package/dist/json-sanitizer.js +26 -0
- package/dist/local-model-policy.d.ts +27 -0
- package/dist/local-model-policy.js +84 -0
- package/dist/local-model-runtime.d.ts +17 -0
- package/dist/local-model-runtime.js +77 -20
- package/dist/model-bridge.d.ts +6 -1
- package/dist/model-bridge.js +338 -21
- package/dist/orchestrator-supervisor.d.ts +42 -0
- package/dist/orchestrator-supervisor.js +110 -3
- package/dist/plan-proposal.d.ts +115 -0
- package/dist/plan-proposal.js +1073 -0
- package/dist/runtime-executor.d.ts +6 -1
- package/dist/runtime-executor.js +72 -5
- package/dist/runtime-tool-specs.d.ts +19 -1
- package/dist/runtime-tool-specs.js +67 -26
- package/dist/schemas.js +30 -1
- package/dist/server.d.ts +3 -0
- package/dist/server.js +73 -4
- package/dist/shared.d.ts +1 -0
- package/dist/shared.js +2 -0
- package/dist/store/bootstrap-store.d.ts +1 -0
- package/dist/store/bootstrap-store.js +8 -2
- package/dist/store/materializers/vericify-projector.js +3 -0
- package/dist/store/repositories/local-model-runtime-repository.d.ts +13 -1
- package/dist/store/repositories/local-model-runtime-repository.js +4 -1
- package/dist/store/repositories/vericify-repository.d.ts +1 -1
- package/dist/tools-agent.d.ts +20 -0
- package/dist/tools-agent.js +544 -29
- package/dist/tools-discovery.js +135 -0
- package/dist/tools-files.js +768 -66
- package/dist/tools-framework.js +80 -61
- package/dist/tools.d.ts +4 -1
- package/dist/tools.js +35 -13
- package/dist/tui/chat.d.ts +8 -0
- package/dist/tui/chat.js +74 -0
- package/dist/tui/index.d.ts +7 -0
- package/dist/tui/index.js +45 -2
- package/dist/tui/layout.d.ts +1 -0
- package/dist/tui/layout.js +4 -1
- package/dist/tui/ollama.d.ts +8 -1
- package/dist/tui/ollama.js +53 -12
- package/dist/tui/openai-compatible.d.ts +13 -0
- package/dist/tui/openai-compatible.js +305 -5
- package/dist/tui/provider-discovery.d.ts +1 -0
- package/dist/tui/provider-discovery.js +50 -24
- package/dist/vericify-bridge.d.ts +4 -1
- package/dist/vericify-bridge.js +3 -0
- package/package.json +2 -1
- 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.
|
|
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())
|