Skip to content

Kilo SQLite source fails to import: schema lacks text/content/message keys #90

Description

@robbe1912

Problem

ctx search --refresh strict --provider kilo and ctx import --provider kilo fail with:

import kilo source ~/.local/share/kilo/kilo.db failed with 1 failure(s);
first failure: line 0: Kilo SQLite database contained no real conversational message rows

This blocks every Kilo session from being indexed, regardless of message size.

Root cause

The Kilo Code VSCode extension stores its history in ~/.local/share/kilo/kilo.db. ctx reads it through KiloSqliteAdapternormalize_opencode_sqlite with OPENCODE_KILO_DIALECT (see crates/ctx-history-capture/src/provider/adapter_impls/sqlite.rs:143 and crates/ctx-history-capture/src/provider/providers/opencode.rs:55). The opencode adapter runs every fetched row through opencode_data_has_real_message_content, which requires the row's data JSON to have a top-level text, content, or message key (crates/ctx-history-capture/src/provider/providers/opencode.rs:708):

data.get("text")
    .or_else(|| data.get("content"))
    .or_else(|| data.pointer("/message/role"))

Kilo's message schema does not use any of those keys. Representative message shapes from a real kilo.db:

  • user message: {"role":"user","time":{...},"summary":{"diffs":[...]},"agent":"code","model":{...},"editorContext":{...}}
  • assistant message: {"role":"assistant","time":{...},"parentID":...,"modelID":...,"providerID":...,"mode":...,"agent":...,"path":...,"cost":...,"tokens":...,"finish":...}

Top-level keys for both shapes are role / time / agent / model (or modelID) / path / cost / tokens / finish / summary / editorContext. No text, content, or message. As a result opencode_data_has_real_message_content returns false for every kilo row, the adapter concludes "no real conversational message rows", and the source import fails.

(Note: Kilo Code is the VSCode extension itself; z.ai is the coding-plan / model provider behind it, not the extension vendor. The kilo.db schema is owned by the extension.)

This is independent of the oversized-row handling that #88 / #89 recently fixed — kilo was already failing on schema grounds before the oversized path could matter.

Reproduction

  1. Install the Kilo Code VSCode extension locally and have at least one conversation.
  2. Run ctx sources --provider kilo → source is detected and reported as available.
  3. Run ctx search "anything" --refresh strict --provider kilo → fails with the error above.
  4. Run ctx import --provider kilo --jsonfailed=1, failures[0].error contains "no real conversational message rows".

Expected behaviour

Kilo messages should import analogously to opencode messages: each message becomes an event keyed by role (user/assistant/...), with payload body assembled from the fields kilo actually uses (summary.diffs for user turns, path/mode/agent for assistant turns, etc.). At minimum the role / time / agent / model fields that exist on every kilo row are enough to produce a searchable event.

Proposed direction

Two reasonable options, both contained to crates/ctx-history-capture/src/provider/providers/opencode.rs:

  1. Extend opencode_data_has_real_message_content / opencode_event_text to recognize kilo's field set when dialect.provider == CaptureProvider::Kilo (or via a dialect flag). Smallest change, keeps the shared opencode pipeline intact.
  2. Add a dedicated normalize_kilo_sqlite mirroring the pattern of the 13 existing per-provider adapters (crates/ctx-history-capture/src/provider/providers/{crush,firebender,goose,...}.rs). Cleaner separation but more code.

The KiloSqliteAdapter is already plumbed (provider, source_format, dialect struct all exist), so either option is mostly local work — no schema migration, no SDK changes.

Validation

A regression test along the lines of native_opencode_imports_read_only_sqlite (crates/ctx-history-capture/src/tests/native_sqlite.rs:5) but using a kilo-shaped fixture (rows with role / time.created / summary.diffs instead of opencode's text / content) would lock the fix in. The existing write_opencode_smoke_db fixture helper can serve as the template.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions