Fix output truncation bug, add language support for agent responses
Bug 1 — Output truncation:
_run_claude() was replacing raw stdout with parsed sub-field which
could be a dict (not string). run_agent() then saved dict.__repr__
to DB instead of full JSON. Fixed: _run_claude() always returns
string output; run_agent() ensures string before DB write.
Added tests: full_output_saved_to_db, dict_output_saved_as_json_string.
Bug 2 — Language support:
Added projects.language column (TEXT DEFAULT 'ru').
Auto-migration for existing DBs (ALTER TABLE ADD COLUMN).
context_builder passes language in project context.
format_prompt() appends "## Language\nALWAYS respond in {language}"
at the end of every prompt.
CLI: kin project add --language ru (default: ru).
Tests: language in prompt for ru/en, project creation, context.
112 tests, all passing. ~/.kin/kin.db migrated (vdol: language=ru).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
38c252fc1b
commit
c129cf9d95
7 changed files with 117 additions and 18 deletions
|
|
@ -95,6 +95,48 @@ class TestRunAgent:
|
|||
assert len(logs) == 1
|
||||
assert logs[0]["project_id"] == "vdol"
|
||||
|
||||
@patch("agents.runner.subprocess.run")
|
||||
def test_full_output_saved_to_db(self, mock_run, conn):
|
||||
"""Bug fix: output_summary must contain the FULL output, not truncated."""
|
||||
long_json = json.dumps({
|
||||
"result": json.dumps({
|
||||
"summary": "Security audit complete",
|
||||
"findings": [{"title": f"Finding {i}", "severity": "HIGH"} for i in range(50)],
|
||||
}),
|
||||
})
|
||||
mock = MagicMock()
|
||||
mock.stdout = long_json
|
||||
mock.stderr = ""
|
||||
mock.returncode = 0
|
||||
mock_run.return_value = mock
|
||||
|
||||
run_agent(conn, "security", "VDOL-001", "vdol")
|
||||
|
||||
logs = conn.execute("SELECT output_summary FROM agent_logs WHERE agent_role='security'").fetchall()
|
||||
assert len(logs) == 1
|
||||
output = logs[0]["output_summary"]
|
||||
assert output is not None
|
||||
assert len(output) > 1000 # Must not be truncated
|
||||
# Should contain all 50 findings
|
||||
assert "Finding 49" in output
|
||||
|
||||
@patch("agents.runner.subprocess.run")
|
||||
def test_dict_output_saved_as_json_string(self, mock_run, conn):
|
||||
"""When claude returns structured JSON, it must be saved as string."""
|
||||
mock_run.return_value = _mock_claude_success({
|
||||
"result": {"status": "ok", "files": ["a.py", "b.py"]},
|
||||
})
|
||||
|
||||
result = run_agent(conn, "debugger", "VDOL-001", "vdol")
|
||||
|
||||
# output should be a string (JSON serialized), not a dict
|
||||
assert isinstance(result["raw_output"], str)
|
||||
|
||||
logs = conn.execute("SELECT output_summary FROM agent_logs WHERE agent_role='debugger'").fetchall()
|
||||
saved = logs[0]["output_summary"]
|
||||
assert isinstance(saved, str)
|
||||
assert "a.py" in saved
|
||||
|
||||
@patch("agents.runner.subprocess.run")
|
||||
def test_previous_output_passed(self, mock_run, conn):
|
||||
mock_run.return_value = _mock_claude_success({"result": "tests pass"})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue