agentram 0.1.29 → 0.1.30
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/agentram/cli.py +77 -23
- package/package.json +1 -1
package/agentram/cli.py
CHANGED
|
@@ -475,9 +475,11 @@ def run_textual_tui(context: McpContext) -> bool:
|
|
|
475
475
|
def __init__(self, mcp_context: McpContext) -> None:
|
|
476
476
|
super().__init__()
|
|
477
477
|
self.context = mcp_context
|
|
478
|
-
self.messages: list[str] = []
|
|
479
|
-
self.busy = False
|
|
480
|
-
self.
|
|
478
|
+
self.messages: list[str] = []
|
|
479
|
+
self.busy = False
|
|
480
|
+
self.prompt_queue: list[str] = []
|
|
481
|
+
self.processing_task: asyncio.Task[None] | None = None
|
|
482
|
+
self.suggestions: list[str] = []
|
|
481
483
|
self.setup_done = False
|
|
482
484
|
self.prompt_history: list[str] = []
|
|
483
485
|
self.history_index: int | None = None
|
|
@@ -769,23 +771,37 @@ def run_textual_tui(context: McpContext) -> bool:
|
|
|
769
771
|
self.chat.clear()
|
|
770
772
|
self.chat.write("system > Chat cleared.")
|
|
771
773
|
return
|
|
772
|
-
if self.busy:
|
|
773
|
-
self.
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
self.
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
self.
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
774
|
+
if self.busy:
|
|
775
|
+
self.prompt_queue.append(text)
|
|
776
|
+
self.chat.write(f"agentram > queued #{len(self.prompt_queue)}")
|
|
777
|
+
return
|
|
778
|
+
self.prompt_queue.append(text)
|
|
779
|
+
self.processing_task = asyncio.create_task(self.process_prompt_queue())
|
|
780
|
+
|
|
781
|
+
async def process_prompt_queue(self) -> None:
|
|
782
|
+
if self.busy:
|
|
783
|
+
return
|
|
784
|
+
self.busy = True
|
|
785
|
+
try:
|
|
786
|
+
while self.prompt_queue:
|
|
787
|
+
text = self.prompt_queue.pop(0)
|
|
788
|
+
pending = len(self.prompt_queue)
|
|
789
|
+
suffix = f" ({pending} queued)" if pending else ""
|
|
790
|
+
self.chat.write(f"agentram > thinking...{suffix}")
|
|
791
|
+
try:
|
|
792
|
+
response = await asyncio.to_thread(handle_chat_input, self.context, text, self.messages)
|
|
793
|
+
except Exception as error: # noqa: BLE001 - TUI boundary
|
|
794
|
+
response = f"error: {error}"
|
|
795
|
+
if response == "__clear__":
|
|
796
|
+
self.chat.clear()
|
|
797
|
+
self.chat.write("system > Chat cleared.")
|
|
798
|
+
elif response:
|
|
799
|
+
self.chat.write("agentram > " + response)
|
|
800
|
+
self.refresh_sidebar()
|
|
801
|
+
finally:
|
|
802
|
+
self.busy = False
|
|
803
|
+
self.processing_task = None
|
|
804
|
+
self.query_one("#input", Input).focus()
|
|
789
805
|
|
|
790
806
|
AgentRAMTextualApp(context).run()
|
|
791
807
|
return True
|
|
@@ -1188,7 +1204,7 @@ def supervisor_workflow_text(context: McpContext, prompt: str) -> str:
|
|
|
1188
1204
|
main_agent = agents.get("main")
|
|
1189
1205
|
small_agent = agents.get("small")
|
|
1190
1206
|
memory_context = retrieve_text(context, prompt, task_id="codex", limit=8)
|
|
1191
|
-
route = classify_agent_runtime_route(context, prompt)
|
|
1207
|
+
route = classify_agent_runtime_route(context, prompt, main_agent)
|
|
1192
1208
|
intent = str(route.get("intent", "chat"))
|
|
1193
1209
|
outputs: dict[str, str] = {}
|
|
1194
1210
|
|
|
@@ -1252,7 +1268,28 @@ def supervisor_workflow_text(context: McpContext, prompt: str) -> str:
|
|
|
1252
1268
|
]
|
|
1253
1269
|
)
|
|
1254
1270
|
|
|
1255
|
-
def classify_agent_runtime_route(context: McpContext, prompt: str) -> dict[str, object]:
|
|
1271
|
+
def classify_agent_runtime_route(context: McpContext, prompt: str, main_agent: AgentModelEndpoint | None = None) -> dict[str, object]:
|
|
1272
|
+
if main_agent:
|
|
1273
|
+
try:
|
|
1274
|
+
response = call_agent_endpoint(main_agent, build_agent_runtime_router_prompt(prompt))
|
|
1275
|
+
data = json.loads(extract_json_object(response))
|
|
1276
|
+
intent = str(data.get("intent", "")).strip().lower()
|
|
1277
|
+
if intent in {"planning", "execution", "memory", "chat"}:
|
|
1278
|
+
return {
|
|
1279
|
+
"intent": intent,
|
|
1280
|
+
"confidence": float(data.get("confidence", 0.75)),
|
|
1281
|
+
"reason": str(data.get("reason", "main-agent router")),
|
|
1282
|
+
"source": "main-agent",
|
|
1283
|
+
}
|
|
1284
|
+
except Exception as error: # noqa: BLE001 - router boundary
|
|
1285
|
+
fallback = heuristic_agent_runtime_route(prompt)
|
|
1286
|
+
fallback["source"] = "heuristic"
|
|
1287
|
+
fallback["router_error"] = str(error)
|
|
1288
|
+
return fallback
|
|
1289
|
+
|
|
1290
|
+
return heuristic_agent_runtime_route(prompt)
|
|
1291
|
+
|
|
1292
|
+
def heuristic_agent_runtime_route(prompt: str) -> dict[str, object]:
|
|
1256
1293
|
lower = prompt.lower()
|
|
1257
1294
|
execute_words = [
|
|
1258
1295
|
"bắt đầu làm", "bat dau lam", "làm đi", "lam di", "tiến hành", "tien hanh", "thực hiện", "thuc hien",
|
|
@@ -1263,12 +1300,29 @@ def classify_agent_runtime_route(context: McpContext, prompt: str) -> dict[str,
|
|
|
1263
1300
|
return {"intent": "execution", "confidence": 0.9, "source": "heuristic"}
|
|
1264
1301
|
if any(word in lower for word in plan_words):
|
|
1265
1302
|
return {"intent": "planning", "confidence": 0.85, "source": "heuristic"}
|
|
1266
|
-
decision =
|
|
1303
|
+
decision = heuristic_intent(prompt)
|
|
1267
1304
|
intent = str(decision.get("intent", "chat"))
|
|
1268
1305
|
if intent == "coding":
|
|
1269
1306
|
decision["intent"] = "execution"
|
|
1307
|
+
decision["source"] = "heuristic"
|
|
1270
1308
|
return decision
|
|
1271
1309
|
|
|
1310
|
+
def build_agent_runtime_router_prompt(prompt: str) -> str:
|
|
1311
|
+
return "\n".join(
|
|
1312
|
+
[
|
|
1313
|
+
"You are AgentRAM orchestration router using the main agent model.",
|
|
1314
|
+
"Classify which agent should handle the user prompt. Do not edit files. Do not run tools. Return only JSON.",
|
|
1315
|
+
"Schema: {\"intent\":\"planning|execution|memory|chat\",\"confidence\":0.0,\"reason\":\"short\"}",
|
|
1316
|
+
"planning = user asks to plan, design, set roadmap, discuss goal, no execution yet.",
|
|
1317
|
+
"execution = user approves plan, says start/do it, or asks coding/refactor/fix/test/file work.",
|
|
1318
|
+
"memory = user asks to remember/save/note a decision/fact.",
|
|
1319
|
+
"chat = normal conversation.",
|
|
1320
|
+
"Nếu user prompt bằng tiếng Việt, reason dùng tiếng Việt.",
|
|
1321
|
+
"User prompt:",
|
|
1322
|
+
prompt,
|
|
1323
|
+
]
|
|
1324
|
+
)
|
|
1325
|
+
|
|
1272
1326
|
def runtime_execution_plan(context: McpContext, supervisor: AgentModelEndpoint | None, prompt: str, memory_context: str, route: dict[str, object]) -> str:
|
|
1273
1327
|
state = context.goal_store.load().context_block()
|
|
1274
1328
|
if state:
|