trinity-agent 0.6.2__tar.gz → 0.6.4__tar.gz

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 (116) hide show
  1. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/PKG-INFO +1 -1
  2. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/pyproject.toml +1 -1
  3. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/__init__.py +1 -1
  4. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/agents/claude_agent.py +70 -2
  5. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/config.py +21 -0
  6. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/tui/session.py +13 -1
  7. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/uv.lock +1 -1
  8. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/.gitignore +0 -0
  9. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/LICENSE +0 -0
  10. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/README.en.md +0 -0
  11. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/README.md +0 -0
  12. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/checkpoint.md +0 -0
  13. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/phase-6-plan.md +0 -0
  14. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/plans/2026-06-02-prompt-compression.md +0 -0
  15. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/plans/2026-06-02-token-analytics.md +0 -0
  16. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/plans/2026-06-02-token-optimization-phase7b.md +0 -0
  17. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/plans/2026-06-02-tui-overhaul.md +0 -0
  18. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/reference-architecture.md +0 -0
  19. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/test-results/phase-1-T.md +0 -0
  20. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/test-results/phase-2-T.md +0 -0
  21. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/test-results/phase-3-T.md +0 -0
  22. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/test-results/phase-4-T.md +0 -0
  23. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/test-results/phase-5-T.md +0 -0
  24. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/test-results/phase-6-T.md +0 -0
  25. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/test-results/phase-7-T.md +0 -0
  26. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/docs/test-results/phase-9-T.md +0 -0
  27. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/__main__.py +0 -0
  28. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/agents/__init__.py +0 -0
  29. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/agents/base.py +0 -0
  30. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/agents/codex_agent.py +0 -0
  31. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/agents/factory.py +0 -0
  32. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/agents/gemini_agent.py +0 -0
  33. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/agents/response_cleaner.py +0 -0
  34. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/cli.py +0 -0
  35. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/completion/__init__.py +0 -0
  36. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/completion/base.py +0 -0
  37. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/completion/hook.py +0 -0
  38. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/completion/idle.py +0 -0
  39. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/completion/prompt.py +0 -0
  40. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/context/__init__.py +0 -0
  41. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/context/analytics.py +0 -0
  42. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/context/budget.py +0 -0
  43. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/context/compressor.py +0 -0
  44. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/context/monitor.py +0 -0
  45. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/context/rotator.py +0 -0
  46. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/context/shared.py +0 -0
  47. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/deliberation/__init__.py +0 -0
  48. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/deliberation/consensus.py +0 -0
  49. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/deliberation/distributor.py +0 -0
  50. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/deliberation/protocol.py +0 -0
  51. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/error_handler.py +0 -0
  52. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/health/__init__.py +0 -0
  53. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/health/checker.py +0 -0
  54. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/i18n.py +0 -0
  55. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/logging.py +0 -0
  56. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/models.py +0 -0
  57. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/orchestrator.py +0 -0
  58. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/retry.py +0 -0
  59. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/setup/__init__.py +0 -0
  60. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/setup/detector.py +0 -0
  61. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/setup/wizard.py +0 -0
  62. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/tmux/__init__.py +0 -0
  63. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/tmux/layout.py +0 -0
  64. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/tmux/pane.py +0 -0
  65. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/tmux/session.py +0 -0
  66. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/tui/__init__.py +0 -0
  67. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/tui/app.py +0 -0
  68. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/tui/events.py +0 -0
  69. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/tui/prompt.py +0 -0
  70. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/tui/theme.py +0 -0
  71. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/workspace/__init__.py +0 -0
  72. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/workspace/isolation.py +0 -0
  73. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/src/trinity/workspace/managed_home.py +0 -0
  74. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/templates/trinity.config.example +0 -0
  75. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/conftest.py +0 -0
  76. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_agent_factory.py +0 -0
  77. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_analytics.py +0 -0
  78. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_budget.py +0 -0
  79. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_claude_agent.py +0 -0
  80. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_cli.py +0 -0
  81. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_cli_detector.py +0 -0
  82. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_cli_v2.py +0 -0
  83. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_codex_agent.py +0 -0
  84. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_completion.py +0 -0
  85. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_compressor.py +0 -0
  86. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_config.py +0 -0
  87. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_consensus_v2.py +0 -0
  88. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_context_monitor.py +0 -0
  89. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_deliberation.py +0 -0
  90. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_e2e.py +0 -0
  91. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_error_handling.py +0 -0
  92. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_gemini_agent.py +0 -0
  93. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_health_checker.py +0 -0
  94. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_i18n.py +0 -0
  95. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_interactive_claude.py +0 -0
  96. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_logging.py +0 -0
  97. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_managed_home.py +0 -0
  98. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_models.py +0 -0
  99. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_multi_provider.py +0 -0
  100. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_orchestrator.py +0 -0
  101. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_protocol.py +0 -0
  102. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_protocol_compression.py +0 -0
  103. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_protocol_v2.py +0 -0
  104. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_response_cleaner.py +0 -0
  105. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_retry.py +0 -0
  106. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_session_handoff.py +0 -0
  107. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_session_rotator.py +0 -0
  108. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_setup_wizard.py +0 -0
  109. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_shared_context.py +0 -0
  110. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_tmux.py +0 -0
  111. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_tmux_integration.py +0 -0
  112. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_tmux_layout.py +0 -0
  113. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_tui.py +0 -0
  114. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_tui_prompt.py +0 -0
  115. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_tui_session.py +0 -0
  116. {trinity_agent-0.6.2 → trinity_agent-0.6.4}/tests/test_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trinity-agent
3
- Version: 0.6.2
3
+ Version: 0.6.4
4
4
  Summary: Three minds, one context — Multi-agent AI orchestrator for Claude Code, Codex, and Gemini CLI.
5
5
  Project-URL: Homepage, https://github.com/hongdangmoo49/Trinity
6
6
  Project-URL: Repository, https://github.com/hongdangmoo49/Trinity
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "trinity-agent"
7
- version = "0.6.2"
7
+ version = "0.6.4"
8
8
  description = "Three minds, one context — Multi-agent AI orchestrator for Claude Code, Codex, and Gemini CLI."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,3 +1,3 @@
1
1
  """Trinity — Three minds, one context."""
2
2
 
3
- __version__ = "0.6.2"
3
+ __version__ = "0.6.4"
@@ -282,8 +282,8 @@ class InteractiveClaudeAgent(AgentWrapper):
282
282
  result = await self._send_and_wait_for_response(full_prompt, timeout)
283
283
  elapsed = time.time() - start_time
284
284
 
285
- # Extract response text (strip what we sent)
286
- response_text = self._extract_response(result.output)
285
+ # Extract response: re-capture FULL pane to use absolute line boundary
286
+ response_text = self._extract_response_from_pane()
287
287
 
288
288
  # Parse token usage if possible — accumulate across calls
289
289
  parsed = self._parse_usage_from_output(result.output)
@@ -367,6 +367,74 @@ class InteractiveClaudeAgent(AgentWrapper):
367
367
  )
368
368
  return result
369
369
 
370
+ def _extract_response_from_pane(self) -> str:
371
+ """Extract response by re-capturing the full pane after completion.
372
+
373
+ Uses _last_response_start_line (absolute line count captured before
374
+ sending) to precisely slice the response region from the pane.
375
+ Falls back to substring matching if the boundary is outside the
376
+ visible window.
377
+ """
378
+ import re
379
+ from trinity.agents.response_cleaner import ResponseCleaner
380
+
381
+ prompt_re = re.compile(r"^[>❯$]\s*$")
382
+
383
+ # Re-capture the full pane scrollback
384
+ if self._pane:
385
+ all_lines = self._pane.capture(lines=-9999)
386
+ else:
387
+ return ""
388
+
389
+ total = len(all_lines)
390
+
391
+ # Strategy 1: Absolute line boundary
392
+ if self._last_response_start_line > 0 and total > self._last_response_start_line:
393
+ response_lines = all_lines[self._last_response_start_line:]
394
+
395
+ # Skip the prompt echo — find where sent text ends
396
+ if self._sent_text:
397
+ sent_first_line = self._sent_text.split("\n")[0][:50]
398
+ echo_ended = False
399
+ cleaned_echo = []
400
+ for line in response_lines:
401
+ if not echo_ended:
402
+ if sent_first_line in line:
403
+ echo_ended = True
404
+ continue
405
+ cleaned_echo.append(line)
406
+ if cleaned_echo:
407
+ response_lines = cleaned_echo
408
+ else:
409
+ # Strategy 2: Last-occurrence substring match
410
+ last_match = -1
411
+ if self._sent_text:
412
+ sent_first = self._sent_text.split("\n")[0][:50]
413
+ for i, line in enumerate(all_lines):
414
+ if sent_first in line:
415
+ last_match = i
416
+ if last_match >= 0:
417
+ response_lines = all_lines[last_match + 1:]
418
+ else:
419
+ # Strategy 3: Fallback — last lines
420
+ response_lines = all_lines[-50:]
421
+ logger.warning(
422
+ "[%s] No prompt boundary found (%d lines), using last 50",
423
+ self.name, total,
424
+ )
425
+
426
+ # Strip trailing prompt characters
427
+ cleaned = []
428
+ for line in reversed(response_lines):
429
+ if prompt_re.match(line.strip()):
430
+ continue
431
+ cleaned.append(line)
432
+ cleaned.reverse()
433
+
434
+ text = "\n".join(cleaned).strip()
435
+ text = ResponseCleaner.clean(text) if text else ""
436
+ return text if text else ""
437
+
370
438
  def _extract_response(self, raw_output: str) -> str:
371
439
  """Extract the agent's response from the raw pane output.
372
440
 
@@ -101,6 +101,11 @@ class TrinityConfig:
101
101
  health = data.get("health", {})
102
102
  logging_conf = data.get("logging", {})
103
103
 
104
+ # Detect language: explicit lang field, or infer from role prompts
105
+ lang = general.get("lang", None)
106
+ if lang is None:
107
+ lang = cls._detect_lang_from_agents(data.get("agents", {}))
108
+
104
109
  agents = {}
105
110
  for name, agent_data in data.get("agents", {}).items():
106
111
  agents[name] = AgentSpec(
@@ -234,3 +239,19 @@ class TrinityConfig:
234
239
 
235
240
  path.parent.mkdir(parents=True, exist_ok=True)
236
241
  path.write_text("\n".join(lines), encoding="utf-8")
242
+
243
+ @staticmethod
244
+ def _detect_lang_from_agents(agents_data: dict) -> str:
245
+ """Detect language from existing role prompts.
246
+
247
+ If any role prompt contains Korean characters (hangul), return "ko".
248
+ Otherwise return "en". This handles configs created before the
249
+ lang field was added.
250
+ """
251
+ import re
252
+ hangul = re.compile(r"[ㄱ-ㆎ가-힣]")
253
+ for agent_data in agents_data.values():
254
+ role = agent_data.get("role_prompt", "")
255
+ if hangul.search(role):
256
+ return "ko"
257
+ return "en"
@@ -332,10 +332,18 @@ class InteractiveSession:
332
332
  result = self._run_with_live(orchestrator, prompt)
333
333
  except KeyboardInterrupt:
334
334
  self.console.print("\n[yellow]Deliberation interrupted.[/yellow]")
335
+ self.tui.reset_agents()
335
336
  return
336
337
  except Exception as e:
337
338
  self.console.print(f"[red]Error: {e}[/red]")
338
339
  logger.exception("Deliberation failed")
340
+ self.tui.reset_agents()
341
+ return
342
+
343
+ # Guard: result may be None if deliberation timed out or was interrupted
344
+ if result is None:
345
+ self.console.print("[yellow]Deliberation did not complete in time.[/yellow]")
346
+ self.tui.reset_agents()
339
347
  return
340
348
 
341
349
  # Update TUI with result
@@ -441,7 +449,11 @@ class InteractiveSession:
441
449
  if error_holder[0]:
442
450
  raise error_holder[0]
443
451
 
444
- return result_holder[0] # type: ignore[return-value]
452
+ result = result_holder[0]
453
+ if result is None:
454
+ logger.warning("Deliberation thread completed but produced no result")
455
+
456
+ return result # type: ignore[return-value]
445
457
 
446
458
  # ─── Display ────────────────────────────────────────────────────────
447
459
 
@@ -346,7 +346,7 @@ wheels = [
346
346
 
347
347
  [[package]]
348
348
  name = "trinity-agent"
349
- version = "0.6.1"
349
+ version = "0.6.3"
350
350
  source = { editable = "." }
351
351
  dependencies = [
352
352
  { name = "click" },
File without changes
File without changes
File without changes