Skip to content

Agent-driven setup guide, compat command, and setup diagnostics - #31

Merged
Mtrya merged 3 commits into
mainfrom
install-ai-setup
Jul 28, 2026
Merged

Agent-driven setup guide, compat command, and setup diagnostics#31
Mtrya merged 3 commits into
mainfrom
install-ai-setup

Conversation

@Mtrya

@Mtrya Mtrya commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Closes #29.

What

  • INSTALL_AI.md (new): an interview-driven setup decision tree for coding agents — "Read INSTALL_AI.md and help me configure kimi-bridge" now works end to end. External-first policy: generic upstream setup (uv, Kimi Code install/auth, bot creation) hands off to official documentation links with checkpoints; the tree hardcodes only what upstream docs can't say — the exact Feishu scopes/events/callbacks + publish step, per-platform ID discovery via a placeholder-allowlist bootstrap, the doctor output vocabulary, and bridge-specific failure branches (auth, downgrade-after-newer-state, compat verdicts).
  • kimi-bridge compat: reports whether an installed or given Kimi Code version is tested with this bridge, which other bridge releases tested it, or that it's newer/older than everything tested. Backed by a new packaged compatibility-map.json (bridge-release → tested versions), seeded from git history; each release appends one record.
  • Telegram ID discovery: the adapter now logs non-allowlisted sender IDs with copy-paste guidance, matching Feishu and QQ — no more silent drops, no third-party ID bots needed.
  • Clean startup failures: auth/config/state failures render as one kimi-bridge: … line instead of a traceback; the auth message covers both /login OAuth and own-provider config.toml setups.
  • Doctor unknown-keys WARN: WARN config: unknown configuration keys ignored: … catches config typos that were silently ignored.
  • Docs: README quick start now leads with the agent-driven path and slims Architecture/Security to key points (details moved to docs/); CONFIGURATION.md's dense platform credential paragraphs point at INSTALL_AI.md; INSTALL.md is positioned as the human happy path.

Validation

  • uv run pytest -q — 350 passed
  • uv run ruff check . — clean
  • uv build — wheel contains both supported-kimi-code-versions.json and compatibility-map.json
  • Isolated uv tool install from the built wheel: --version, --help, compat (supported / newer / older / no-kimi paths, exit codes 0/1), and non-starting doctor all verified, then uninstalled
  • All external links in INSTALL_AI.md spot-checked (the compatibility-map raw URL resolves once this merges)

Summary by Sourcery

Add an agent-focused installation playbook, a Kimi Code compatibility reporting command, and clearer diagnostics around configuration, authentication, and startup failures.

New Features:

  • Introduce INSTALL_AI.md as an interview-driven setup guide for agents assisting with kimi-bridge installation and configuration.
  • Add a kimi-bridge compat subcommand and compatibility map resource to report which Kimi Code versions are tested with each bridge release.

Enhancements:

  • Load and validate an append-only compatibility history (compatibility-map.json) to classify Kimi Code versions across bridge releases.
  • Improve startup failure handling to print concise, single-line error messages for auth and state errors instead of full tracebacks, while keeping KeyboardInterrupt as a clean exit.
  • Warn on unknown configuration keys discovered in the TOML config and surface them through the doctor command without failing the run.
  • Log non-allowlisted Telegram senders with their numeric user ID and allowlist guidance to simplify ID discovery.
  • Refine documentation to emphasize the agent-driven setup path, reposition INSTALL.md as the human happy path, and reference the new agent guide and compatibility tooling from architecture and configuration docs.

Tests:

  • Extend test coverage for the new compat command, compatibility map parsing/classification, startup error handling paths, doctor warnings for unknown config keys, and Telegram non-allowlisted sender logging.

Summary by CodeRabbit

  • New Features

    • Added a compat command to report Kimi Code version compatibility.
    • Added an agent-guided installation and configuration playbook.
    • Added compatibility checks for installed or specified Kimi Code versions.
  • Bug Fixes

    • Configuration diagnostics now warn about unknown settings without failing.
    • Telegram now logs rejected messages with the sender’s user ID.
    • Authentication errors provide clearer login and installation guidance.
  • Documentation

    • Updated setup, architecture, configuration, and operational guidance for compatibility checks and platform configuration.

- Add INSTALL_AI.md: an interview-driven setup decision tree for coding
  agents, with external-first handoffs to official docs and hardcoded
  bridge-specific requirements (Feishu scopes/events/publish, per-platform
  ID discovery, doctor vocabulary, smoke-test contract).
- Add 'kimi-bridge compat' subcommand backed by a packaged
  compatibility-map.json recording which Kimi Code versions each bridge
  release tested.
- Telegram adapter now logs non-allowlisted sender IDs with copy-paste
  guidance, matching Feishu and QQ.
- Startup failures (auth, config, state) render as one clean line
  instead of a traceback; the auth message covers both /login OAuth and
  own-provider configuration.
- Doctor warns on unknown configuration keys instead of silently
  ignoring typos.
- Slim README quick start around the agent-driven path; move platform
  credential walkthroughs from CONFIGURATION.md into INSTALL_AI.md.

Closes #29
@sourcery-ai

sourcery-ai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds an agent-focused INSTALL_AI guide and reorganizes docs, introduces a new kimi-bridge compat CLI command backed by a packaged compatibility map, improves startup failure handling and configuration diagnostics, and enhances Telegram allowlist logging and Kimi server auth messaging.

Sequence diagram for the new kimi-bridge compat command

sequenceDiagram
    actor User
    participant CLI as kimi_bridge_main
    participant Compat as _run_compat
    participant Probe as _probe_kimi_code_version
    participant Kimi as kimi_executable
    participant Classifier as classify_bridge_compatibility

    User->>CLI: kimi-bridge compat [--kimi-code VERSION]
    CLI->>Compat: _run_compat(kimi_code)
    Compat->>Compat: _current_map_entry()
    Compat->>User: print tested versions for current bridge
    alt version argument provided
        Compat->>Compat: version = kimi_code
    else auto-detect version
        Compat->>Probe: _probe_kimi_code_version()
        Probe->>Kimi: kimi --version
        Kimi-->>Probe: stdout (version)
        Probe-->>Compat: normalized version or None
    end
    alt version is None
        Compat->>User: print full COMPATIBILITY_MAP
        Compat-->>CLI: exit 0
    else version detected
        Compat->>Classifier: classify_bridge_compatibility(version,current_bridge)
        Classifier-->>Compat: BridgeCompatibility(support,releases)
        alt SUPPORTED_BY_CURRENT_BRIDGE
            Compat->>User: print supported-by-current message
            Compat-->>CLI: exit 0
        else SUPPORTED_BY_OTHER_RELEASES
            Compat->>User: print supported-by-other-releases message
            Compat-->>CLI: exit 1
        else UNTESTED_OLDER_THAN_ALL
            Compat->>User: print untested-older-than-all message
            Compat-->>CLI: exit 1
        else UNTESTED_NEWER_THAN_ALL
            Compat->>User: print untested-newer-than-all message
            Compat-->>CLI: exit 1
        end
    end
Loading

File-Level Changes

Change Details Files
Introduce a compatibility map model and API for classifying Kimi Code versions across bridge releases, and load it from a packaged JSON resource.
  • Add COMPATIBILITY_MAP_RESOURCE, dataclasses for compatibility entries/verdicts, and a BridgeSupport enum.
  • Implement _parse_compatibility_map with strict schema, sorting, and uniqueness validation, and _load_compatibility_map that reads compatibility-map.json from package data.
  • Expose COMPATIBILITY_MAP at module import time and add classify_bridge_compatibility to compute support verdicts for a given Kimi Code version.
src/kimi_bridge/compatibility.py
tests/test_compatibility.py
src/kimi_bridge/compatibility-map.json
pyproject.toml
AGENTS.md
docs/ARCHITECTURE.md
Add a compat subcommand to the CLI that reports tested Kimi Code versions for bridge releases and classifies an installed or given Kimi Code version against the compatibility map.
  • Extend __main__ argument parsing with a compat subcommand and optional --kimi-code argument.
  • Implement _probe_kimi_code_version to locate kimi on PATH and parse its --version output without leaking it to stdout.
  • Add _current_map_entry and _run_compat helpers to print the current release’s tested versions, optionally dump the full compatibility map, and exit 0/1 based on support, including malformed-version handling.
  • Wire main() to dispatch to compat and add tests for supported/unsupported/newer/older/malformed cases and for probing behavior.
src/kimi_bridge/__main__.py
tests/test_main.py
src/kimi_bridge/compatibility.py
tests/test_compatibility.py
Clean up startup failure handling so expected auth/config/state errors print one concise line instead of a traceback while preserving KeyboardInterrupt semantics.
  • Import KimiServerError and catch (KimiServerError, ValueError, TypeError) in main(), printing kimi-bridge: <message> to stderr and exiting 1.
  • Ensure KeyboardInterrupt still exits with status code 0 and no traceback.
  • Add tests covering authentication failure rendering, generic state errors without tracebacks, and KeyboardInterrupt behavior.
src/kimi_bridge/__main__.py
tests/test_main.py
Improve Kimi server authentication error messaging to cover both /login and config-file based setups with an explicit link to official Kimi Code docs.
  • Update _read_startup_credentials in the supervisor to detect auth errors and raise KimiServerAuthenticationError with neutral guidance mentioning /login, ~/.kimi-code/config.toml, and KIMI_CODE_INSTALL_URL.
  • Add a supervisor test that simulates an auth failure and asserts the new message content.
src/kimi_bridge/kimi_server/supervisor.py
tests/test_kimi_server.py
Add config-typo detection and surface unknown configuration keys as warnings in doctor while keeping runtime behavior unchanged.
  • Introduce _KNOWN_TOP_LEVEL_KEYS and _KNOWN_SUB_KEYS plus an unknown_config_keys helper that returns dotted names of unrecognized config keys, including nested adapter keys.
  • Extend doctor._check_config to parse raw TOML, call unknown_config_keys, and insert a WARNING config check when unknown keys are present.
  • Document unknown-key warnings in CONFIGURATION.md and add a doctor test exercising the warning without failing the overall run.
src/kimi_bridge/config.py
src/kimi_bridge/doctor.py
tests/test_doctor.py
docs/CONFIGURATION.md
Enhance Telegram adapter behavior by logging non-allowlisted senders with actionable guidance instead of silently dropping them.
  • Track whether an inbound event is a message or callback query and compute a human-readable event_kind.
  • When a user ID is not in allowed_users, emit a WARNING on the Telegram logger including the event kind, numeric user ID, and [telegram].allowed_users guidance before ignoring the message.
  • Add tests that verify the warning is logged once and that only allowlisted messages reach the handler.
src/kimi_bridge/platforms/telegram.py
tests/test_telegram.py
docs/CONFIGURATION.md
Add an agent-oriented installation guide and reorient existing docs toward the new agent-driven path while slimming the README.
  • Create INSTALL_AI.md, a detailed decision-tree playbook for agents performing setup, covering preflight checks, platform selection, credentials, doctor, smoke tests, and rollback.
  • Rewrite README quick start to point first to the agent-driven INSTALL_AI flow, present a shorter manual skeleton, and reference INSTALL.md and CONFIGURATION.md for full details.
  • Position INSTALL.md as the human happy-path runbook and update links/descriptions in README, CONFIGURATION.md, ARCHITECTURE.md, and AGENTS.md to mention the compatibility map and compat command where relevant.
INSTALL_AI.md
README.md
INSTALL.md
docs/CONFIGURATION.md
docs/ARCHITECTURE.md
AGENTS.md

Assessment against linked issues

Issue Objective Addressed Explanation
#29 Create INSTALL_AI.md as a comprehensive, agent-driven setup decision tree (detect-first traversal, explicit branches and outcomes, external-first links for upstream steps, covering preflight, install/upgrade, platform choice, settings, credentials, doctor, smoke test, persistence, and rollback, and addressing the listed gaps).
#29 Refactor existing human-facing documentation so that INSTALL.md becomes a concise happy-path runbook, with other docs (README, CONFIGURATION, ARCHITECTURE, etc.) slimmed or cross-referenced to avoid duplication and to point humans and agents to INSTALL_AI.md as the agent-native entrypoint.
#29 Introduce and document supporting tooling and diagnostics that the decision tree relies on, including a Kimi Code compatibility reverse-lookup command (kimi-bridge compat backed by a packaged compatibility map), clearer and cleaner startup/authentication failures, doctor warnings for unknown configuration keys, and bridge-assisted Telegram user ID discovery via logs.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Mtrya, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0d9dde32-8b16-41fd-9a1c-c9f001c385d2

📥 Commits

Reviewing files that changed from the base of the PR and between 08be3c7 and 1ff7b55.

📒 Files selected for processing (10)
  • INSTALL_AI.md
  • README.md
  • src/kimi_bridge/__main__.py
  • src/kimi_bridge/compatibility.py
  • src/kimi_bridge/config.py
  • src/kimi_bridge/doctor.py
  • tests/test_compatibility.py
  • tests/test_config.py
  • tests/test_main.py
  • tests/test_telegram.py
📝 Walkthrough

Walkthrough

The changes add an agent-oriented installation playbook, document compatibility history, introduce the compat CLI command, warn about unknown configuration keys, improve authentication guidance, and log rejected Telegram sender identities.

Changes

Installation and setup

Layer / File(s) Summary
Agent-driven installation workflow
INSTALL_AI.md, INSTALL.md, README.md, docs/CONFIGURATION.md
Adds interview-driven preflight, installation, platform credentials, doctor, smoke-test, persistence, and rollback guidance, while routing human and platform-specific setup documentation accordingly.

Compatibility and diagnostics

Layer / File(s) Summary
Compatibility manifest and CLI
src/kimi_bridge/compatibility-map.json, src/kimi_bridge/compatibility.py, src/kimi_bridge/__main__.py, pyproject.toml, tests/test_compatibility.py, tests/test_main.py
Adds validated bridge-release compatibility history, package inclusion, version classification, executable probing, and the compat command with CLI tests.
Unknown configuration diagnostics
src/kimi_bridge/config.py, src/kimi_bridge/doctor.py, docs/CONFIGURATION.md, tests/test_doctor.py
Detects unsupported TOML keys and reports them as warnings without failing diagnosis.

Runtime feedback

Layer / File(s) Summary
Authentication and allowlist feedback
src/kimi_bridge/kimi_server/supervisor.py, src/kimi_bridge/platforms/telegram.py, tests/test_kimi_server.py, tests/test_telegram.py
Expands startup authentication guidance and logs event type and user ID for rejected Telegram senders.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant CLI as compat CLI
  participant Kimi as kimi executable
  participant Classifier as compatibility classifier
  Operator->>CLI: run compat
  CLI->>Kimi: probe version when needed
  CLI->>Classifier: classify detected or supplied version
  Classifier-->>CLI: return support verdict
  CLI-->>Operator: print compatibility result
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Several code changes—compat command, compatibility map, Telegram logging, and doctor/startup diagnostics—go beyond the docs-only scope of #29. Split the feature work into separate PRs or link the missing implementation issues; keep this PR focused on INSTALL_AI.md, INSTALL.md, and related docs.
Docstring Coverage ⚠️ Warning Docstring coverage is 12.77% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and captures the main additions: agent-driven setup docs, compat command, and diagnostics.
Linked Issues check ✅ Passed The PR adds INSTALL_AI.md, trims INSTALL.md, and adds the agent-oriented setup flow and documentation required by #29.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch install-ai-setup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 security issue, 5 other issues, and left some high level feedback:

Security issues:

  • Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. (link)

General comments:

  • In __main__.py, catching broad ValueError and TypeError for all run() failures risks masking programming errors; consider narrowing this to domain-specific exception types (e.g., a dedicated state/config error) so unexpected bugs still surface with tracebacks.
  • The doctor config check re-opens and parses the TOML with tomllib solely to compute unknown_config_keys, even though load_config has already processed it; consider threading through the raw dict (or extending load_config) to avoid double parsing and keep unknown-key detection aligned with the loader.
  • Because COMPATIBILITY_MAP is loaded at import time and _parse_compatibility_map raises RuntimeError on any schema or content issue, a corrupted compatibility-map.json will prevent all commands from running; you might want to load this lazily or degrade more gracefully with a targeted error message when the compat functionality is actually used.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `__main__.py`, catching broad `ValueError` and `TypeError` for all `run()` failures risks masking programming errors; consider narrowing this to domain-specific exception types (e.g., a dedicated state/config error) so unexpected bugs still surface with tracebacks.
- The doctor config check re-opens and parses the TOML with `tomllib` solely to compute `unknown_config_keys`, even though `load_config` has already processed it; consider threading through the raw dict (or extending `load_config`) to avoid double parsing and keep unknown-key detection aligned with the loader.
- Because `COMPATIBILITY_MAP` is loaded at import time and `_parse_compatibility_map` raises `RuntimeError` on any schema or content issue, a corrupted `compatibility-map.json` will prevent all commands from running; you might want to load this lazily or degrade more gracefully with a targeted error message when the compat functionality is actually used.

## Individual Comments

### Comment 1
<location path="src/kimi_bridge/compatibility.py" line_range="261-266" />
<code_context>
+        return BridgeCompatibility(
+            BridgeSupport.SUPPORTED_BY_OTHER_RELEASES, others
+        )
+    tested_keys = [
+        kimi_code_version_sort_key(version)
+        for entry in entries
+        for version in entry.kimi_code
+    ]
+    if kimi_code_version_sort_key(normalized) < min(tested_keys):
+        return BridgeCompatibility(BridgeSupport.UNTESTED_OLDER_THAN_ALL)
+    return BridgeCompatibility(BridgeSupport.UNTESTED_NEWER_THAN_ALL)
</code_context>
<issue_to_address>
**issue (bug_risk):** Classification of untested versions treats any version ≥ min(tested) as 'newer than all', which mislabels versions between min and max of the tested range.

Because we only compare against `min(tested_keys)`, any normalized version not in `tested_keys` but ≥ the minimum is treated as `UNTESTED_NEWER_THAN_ALL`. This means a gap in the tested range (e.g., tested 1.0 and 3.0, untested 2.0) is incorrectly described as newer than all tested versions.

Please compute both `min_key` and `max_key` and handle three ranges explicitly:
- `< min_key``UNTESTED_OLDER_THAN_ALL`
- `> max_key``UNTESTED_NEWER_THAN_ALL`
- `min_key <= key <= max_key` but not present → explicitly choose and document the intended classification (possibly a separate state).
</issue_to_address>

### Comment 2
<location path="src/kimi_bridge/__main__.py" line_range="275-277" />
<code_context>
+        f"{', '.join(current.kimi_code)}"
+    )
+    version = kimi_code if kimi_code is not None else _probe_kimi_code_version()
+    if version is None:
+        print("kimi executable not found on PATH; full compatibility map:")
+        for entry in COMPATIBILITY_MAP:
+            print(f"  kimi-bridge {entry.bridge}: {', '.join(entry.kimi_code)}")
+        return 0
</code_context>
<issue_to_address>
**suggestion (bug_risk):** The message for `version is None` always blames a missing executable, even when detection failed for other reasons.

Since `version` is `None` both when `shutil.which` fails and when `_probe_kimi_code_version` fails for other reasons (non-zero exit code, parse errors, etc.), this message misattributes all failures to a missing executable.

Consider either distinguishing these cases (e.g., have `_probe_kimi_code_version` signal parse/runtime failures explicitly or return richer info so `_run_compat` knows whether `which` succeeded), or at least using a neutral message like “could not detect Kimi Code version; full compatibility map:” to avoid misleading users.

```suggestion
    version = kimi_code if kimi_code is not None else _probe_kimi_code_version()
    if version is None:
        print("could not detect Kimi Code version; full compatibility map:")
```
</issue_to_address>

### Comment 3
<location path="tests/test_compatibility.py" line_range="196-205" />
<code_context>
+    assert verdict.releases == ("0.1.0",)
+
+
+def test_classifier_distinguishes_untested_direction() -> None:
+    newer = classify_bridge_compatibility("0.30.0", releases=_FAKE_RELEASES)
+    older = classify_bridge_compatibility("0.27.0", releases=_FAKE_RELEASES)
+
+    assert newer.support is BridgeSupport.UNTESTED_NEWER_THAN_ALL
+    assert older.support is BridgeSupport.UNTESTED_OLDER_THAN_ALL
+
+
+def test_classifier_rejects_malformed_versions() -> None:
+    with pytest.raises(ValueError, match="malformed"):
+        classify_bridge_compatibility("not-a-version", releases=_FAKE_RELEASES)
</code_context>
<issue_to_address>
**suggestion (testing):** Add tests for `classify_bridge_compatibility` when the compatibility map is empty and when `current_bridge` overrides the default current entry.

Two remaining branches aren’t covered: the `RuntimeError("Kimi compatibility map has no releases")` guard when `releases` is empty, and use of the `current_bridge` parameter to override the default “current” entry. Please add a test that calls `classify_bridge_compatibility(..., releases=())` and asserts the `RuntimeError`, and another that sets `current_bridge` to the first entry in `_FAKE_RELEASES` to exercise that path and fully cover the classifier’s control flow.
</issue_to_address>

### Comment 4
<location path="tests/test_telegram.py" line_range="611-620" />
<code_context>
+async def test_non_allowlisted_sender_is_logged_with_user_id(
</code_context>
<issue_to_address>
**suggestion (testing):** Consider adding coverage for the callback-query path of the non-allowlisted Telegram user logging.

Right now this only exercises the message path. Since `_message_identity` now uses `event_kind = "callback query" if sender is not None else "message"`, please also cover the callback-query path (either via parametrization or a separate test using a callback update) so the log message remains validated for both event kinds.

Suggested implementation:

```python
@pytest.mark.parametrize("event_kind", ["message", "callback_query"])
async def test_non_allowlisted_sender_is_logged_with_user_id(
    caplog: pytest.LogCaptureFixture,
    event_kind: str,
) -> None:
    received: list[InboundMessage] = []
    api = FakeTelegramAPI()

    async def on_message(_adapter: Any, message: InboundMessage) -> None:
        received.append(message)

    caplog.set_level(logging.WARNING, logger="kimi_bridge.platforms.telegram")
    adapter = await _start_adapter(api, on_message=on_message)

```

Inside `test_non_allowlisted_sender_is_logged_with_user_id`, after `adapter = await _start_adapter(...)`:

1. Replace the existing logic that currently only sends a **message** from a non-allowlisted user with a branch on `event_kind`:
   - When `event_kind == "message"`: keep the current behavior (e.g. using your existing helper or `FakeTelegramAPI` call that sends a `message` update from a non-allowlisted user), and assert that the warning log contains `event_kind="message"` (or the exact string you expect from `_message_identity`).
   - When `event_kind == "callback_query"`: construct and send a **callback query** update from a non-allowlisted user (using the same user id used in the message path). This should exercise `_message_identity`’s `"callback query"` branch. Then assert that the warning log contains the same user id and `event_kind="callback query"` (or the exact phrase `_message_identity` logs for callback queries).
2. Use the same logging assertion style already present in this test (e.g. `caplog.records` or `caplog.text`) so that both parameterized cases validate the log message format and content for their respective event kinds.
3. If you have existing helpers in this file for building callback updates (e.g. a factory function or `FakeTelegramAPI` method used in other tests), reuse them here to keep the test consistent with the rest of the suite.
</issue_to_address>

### Comment 5
<location path="README.md" line_range="32" />
<code_context>
 ## Quick start

-Install and authenticate official [Kimi Code](https://moonshotai.github.io/kimi-code/en/guides/getting-started), then install [uv](https://docs.astral.sh/uv/getting-started/installation/) and kimi-bridge:
+The easiest path: open any CLI agent and say — *"Read https://github.com/Mtrya/kimi-bridge/INSTALL_AI.md and help me configure kimi-bridge."* The agent interviews you and runs the setup end to end.

-```bash
</code_context>
<issue_to_address>
**issue (bug_risk):** GitHub URL likely missing `/blob/main/` and will 404 as written.

Please update this to a valid GitHub file URL (for example, `https://github.com/Mtrya/kimi-bridge/blob/main/INSTALL_AI.md`) so that users who open it in a browser reach the INSTALL_AI.md guide directly.
</issue_to_address>

### Comment 6
<location path="src/kimi_bridge/__main__.py" line_range="242-251" />
<code_context>
        completed = subprocess.run(
            [path, "--version"],
            check=False,
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL,
            text=True,
            encoding="utf-8",
            errors="replace",
            timeout=15,
        )
</code_context>
<issue_to_address>
**security (python.lang.security.audit.dangerous-subprocess-use-audit):** Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

*Source: opengrep*
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/kimi_bridge/compatibility.py Outdated
Comment thread src/kimi_bridge/__main__.py Outdated
Comment thread tests/test_compatibility.py
Comment thread tests/test_telegram.py
Comment thread README.md Outdated
Comment thread src/kimi_bridge/__main__.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (2)
src/kimi_bridge/__main__.py (1)

262-266: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Silent "not found → use latest" fallback in both bridge-lookup helpers. _current_map_entry() and classify_bridge_compatibility's current_bridge resolution both use next(..., <last entry>), so an unmatched bridge identifier is silently treated as the latest release instead of surfacing the mismatch. For _current_map_entry() specifically, if __version__ is bumped before compatibility-map.json gets its corresponding release record (per the "each release appends one record" process in AGENTS.md), kimi-bridge compat would silently print and classify against the previous release's tested-versions list as if it were the currently running bridge's own history — misleading whoever runs compat during that window.

  • src/kimi_bridge/__main__.py#L262-L266: raise/log instead of silently defaulting to COMPATIBILITY_MAP[-1] when no entry's bridge matches __version__ (e.g. warn in _run_compat's output that the running version isn't in the map yet).
  • src/kimi_bridge/compatibility.py#L232-L250: raise (e.g. ValueError/RuntimeError) instead of silently defaulting to entries[-1] when a caller-supplied current_bridge matches no entry.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/kimi_bridge/__main__.py` around lines 262 - 266, Replace the silent
latest-entry fallbacks in both bridge lookups: in src/kimi_bridge/__main__.py
lines 262-266, make _current_map_entry() raise or surface a clear warning
through _run_compat when __version__ is absent from COMPATIBILITY_MAP; in
src/kimi_bridge/compatibility.py lines 232-250, make
classify_bridge_compatibility raise an appropriate error when current_bridge
matches no entry instead of using entries[-1].
pyproject.toml (1)

66-66: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

Remove the unnecessary compatibility-map.json force-include.

src/kimi_bridge/compatibility-map.json is tracked and not ignored; hatch build treats /reference as an exception, and the other JSON data file is packaged the same way in pyproject.toml.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pyproject.toml` at line 66, Remove the unnecessary force-include entry for
src/kimi_bridge/compatibility-map.json from the pyproject.toml configuration,
leaving the existing package-data handling and other JSON entries unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@INSTALL_AI.md`:
- Around line 5-15: Rewrite the public guidance in “How to use this file” to
remove references to an internal mental model, node IDs, branches, file
mechanics, and other orchestration metadata. Preserve the user-facing setup
behaviors and outcomes while expressing them as normal documentation, and move
any required planning details to a non-published internal location.
- Around line 83-85: Update the I3 downgrade-abort instructions to resolve the
active bridge installation method, including pipx fallback, and the configured
config, state, and workspace paths before performing cleanup. Instruct users to
restore or delete the state file at the resolved state_path for the active
instance, then rerun that installation’s matching doctor; report the exact paths
and files removed, while preserving the note that config.toml credentials remain
untouched.
- Around line 152-154: Update the doctor-output guidance for
DoctorReport.render() to describe whitespace-tolerant status parsing rather than
requiring literal prefixes such as “ERROR config:”. Document that check entries
may repeat, including config before config permissions, and instruct consumers
to detect blocking errors from rendered status values while preserving the rule
that only ERROR results fail the run.
- Around line 61-62: Update the Telegram and QQ probe instructions in
INSTALL_AI.md to use bounded HTTPS requests, including a timeout for the QQ
egress-IP lookup. Distinguish transport/reachability failures from non-2xx HTTP
responses: only connection or TLS failures should be reported as network
unsupported, while reachable endpoints with HTTP errors must be reported
separately. Preserve the existing user guidance and whitelist workflow.

In `@README.md`:
- Line 32: Update the quick-start instruction in README.md to reference
INSTALL_AI.md using the normalized local Markdown link shape
[INSTALL_AI.md](INSTALL_AI.md), replacing the root GitHub URL while preserving
the surrounding agent prompt.

In `@src/kimi_bridge/compatibility.py`:
- Around line 261-268: Update classify_bridge_compatibility() to distinguish
normalized versions that fall between tested releases: compare against both
min(tested_keys) and max(tested_keys), and avoid returning
UNTESTED_NEWER_THAN_ALL unless the version exceeds max(tested_keys). Add or use
an in-between compatibility verdict for versions between tested bounds,
preserving the existing older-than-all behavior.

In `@src/kimi_bridge/config.py`:
- Around line 46-58: Update unknown_config_keys to accept Mapping[str, object]
instead of dict, and check nested values with isinstance(value, Mapping) rather
than dict. Import Mapping from the appropriate typing or collections.abc module
so key, value, and nested-table types remain statically explicit.

In `@src/kimi_bridge/doctor.py`:
- Around line 179-190: Update _check_config() to parse the configuration only
once within its existing handled try boundary, then reuse that same raw document
for unknown_config_keys(). Remove the later path.open/tomllib.load read so
validation and the unknown-key warning use the identical snapshot while
preserving existing error handling.

---

Nitpick comments:
In `@pyproject.toml`:
- Line 66: Remove the unnecessary force-include entry for
src/kimi_bridge/compatibility-map.json from the pyproject.toml configuration,
leaving the existing package-data handling and other JSON entries unchanged.

In `@src/kimi_bridge/__main__.py`:
- Around line 262-266: Replace the silent latest-entry fallbacks in both bridge
lookups: in src/kimi_bridge/__main__.py lines 262-266, make _current_map_entry()
raise or surface a clear warning through _run_compat when __version__ is absent
from COMPATIBILITY_MAP; in src/kimi_bridge/compatibility.py lines 232-250, make
classify_bridge_compatibility raise an appropriate error when current_bridge
matches no entry instead of using entries[-1].
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dbe6bd31-c5d6-4038-bd51-fdc5ab038f40

📥 Commits

Reviewing files that changed from the base of the PR and between 638581f and 08be3c7.

📒 Files selected for processing (19)
  • AGENTS.md
  • INSTALL.md
  • INSTALL_AI.md
  • README.md
  • docs/ARCHITECTURE.md
  • docs/CONFIGURATION.md
  • pyproject.toml
  • src/kimi_bridge/__main__.py
  • src/kimi_bridge/compatibility-map.json
  • src/kimi_bridge/compatibility.py
  • src/kimi_bridge/config.py
  • src/kimi_bridge/doctor.py
  • src/kimi_bridge/kimi_server/supervisor.py
  • src/kimi_bridge/platforms/telegram.py
  • tests/test_compatibility.py
  • tests/test_doctor.py
  • tests/test_kimi_server.py
  • tests/test_main.py
  • tests/test_telegram.py

Comment thread INSTALL_AI.md
Comment thread INSTALL_AI.md Outdated
Comment thread INSTALL_AI.md Outdated
Comment thread INSTALL_AI.md Outdated
Comment thread README.md Outdated
Comment thread src/kimi_bridge/compatibility.py Outdated
Comment thread src/kimi_bridge/config.py Outdated
Comment thread src/kimi_bridge/doctor.py Outdated
Mtrya added 2 commits July 29, 2026 00:36
- classify untested versions inside the tested range explicitly instead
  of mislabeling them newer-than-all; neutral message when Kimi Code
  version detection fails for reasons other than a missing executable.
- INSTALL_AI.md: distinguish transport failures from HTTP statuses in
  the Telegram/QQ network probes (bounded HTTPS requests); rollback
  resolves the active tool manager and configured paths; doctor parsing
  guidance is whitespace-tolerant and notes repeated check entries.
- README: fix the INSTALL_AI.md GitHub URL to the /blob/main/ form.
- _check_config parses the TOML document a single time inside its
  handled boundary and reuses that snapshot for both validation and the
  unknown-keys warning; load_config keeps its signature and delegates
  to _load_config_from_raw.
- unknown_config_keys accepts Mapping[str, object] and matches nested
  tables with isinstance(Mapping).
@Mtrya
Mtrya merged commit 4268bb4 into main Jul 28, 2026
10 of 11 checks passed
@Mtrya
Mtrya deleted the install-ai-setup branch July 28, 2026 16:42
@Mtrya Mtrya mentioned this pull request Jul 28, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Jul 29, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rework installation docs into an agent-native setup tree (INSTALL_AI.md)

1 participant