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
|
|
@ -109,6 +109,7 @@ def _slim_project(project: dict) -> dict:
|
|||
"name": project["name"],
|
||||
"path": project["path"],
|
||||
"tech_stack": project.get("tech_stack"),
|
||||
"language": project.get("language", "ru"),
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -209,4 +210,13 @@ def format_prompt(context: dict, role: str, prompt_template: str | None = None)
|
|||
sections.append(prev if isinstance(prev, str) else json.dumps(prev, ensure_ascii=False))
|
||||
sections.append("")
|
||||
|
||||
# Language instruction — always last so it's fresh in context
|
||||
proj = context.get("project")
|
||||
language = proj.get("language", "ru") if proj else "ru"
|
||||
_LANG_NAMES = {"ru": "Russian", "en": "English", "es": "Spanish", "de": "German", "fr": "French"}
|
||||
lang_name = _LANG_NAMES.get(language, language)
|
||||
sections.append(f"## Language")
|
||||
sections.append(f"ALWAYS respond in {lang_name}. All summaries, analysis, comments, and recommendations must be in {lang_name}.")
|
||||
sections.append("")
|
||||
|
||||
return "\n".join(sections)
|
||||
|
|
|
|||
11
core/db.py
11
core/db.py
|
|
@ -20,6 +20,7 @@ CREATE TABLE IF NOT EXISTS projects (
|
|||
pm_prompt TEXT,
|
||||
claude_md_path TEXT,
|
||||
forgejo_repo TEXT,
|
||||
language TEXT DEFAULT 'ru',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
|
|
@ -163,10 +164,20 @@ def get_connection(db_path: Path = DB_PATH) -> sqlite3.Connection:
|
|||
return conn
|
||||
|
||||
|
||||
def _migrate(conn: sqlite3.Connection):
|
||||
"""Run migrations for existing databases."""
|
||||
# Check if language column exists on projects
|
||||
cols = {r[1] for r in conn.execute("PRAGMA table_info(projects)").fetchall()}
|
||||
if "language" not in cols:
|
||||
conn.execute("ALTER TABLE projects ADD COLUMN language TEXT DEFAULT 'ru'")
|
||||
conn.commit()
|
||||
|
||||
|
||||
def init_db(db_path: Path = DB_PATH) -> sqlite3.Connection:
|
||||
conn = get_connection(db_path)
|
||||
conn.executescript(SCHEMA)
|
||||
conn.commit()
|
||||
_migrate(conn)
|
||||
return conn
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -50,14 +50,15 @@ def create_project(
|
|||
pm_prompt: str | None = None,
|
||||
claude_md_path: str | None = None,
|
||||
forgejo_repo: str | None = None,
|
||||
language: str = "ru",
|
||||
) -> dict:
|
||||
"""Create a new project and return it as dict."""
|
||||
conn.execute(
|
||||
"""INSERT INTO projects (id, name, path, tech_stack, status, priority,
|
||||
pm_prompt, claude_md_path, forgejo_repo)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""",
|
||||
pm_prompt, claude_md_path, forgejo_repo, language)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
|
||||
(id, name, path, _json_encode(tech_stack), status, priority,
|
||||
pm_prompt, claude_md_path, forgejo_repo),
|
||||
pm_prompt, claude_md_path, forgejo_repo, language),
|
||||
)
|
||||
conn.commit()
|
||||
return get_project(conn, id)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue