kimi-bridge 0.1.0__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.
- kimi_bridge-0.1.0/.github/workflows/ci.yml +65 -0
- kimi_bridge-0.1.0/.github/workflows/kimi-drift.yml +63 -0
- kimi_bridge-0.1.0/.github/workflows/release.yml +87 -0
- kimi_bridge-0.1.0/.gitignore +8 -0
- kimi_bridge-0.1.0/AGENTS.md +37 -0
- kimi_bridge-0.1.0/INSTALL.md +177 -0
- kimi_bridge-0.1.0/LICENSE +21 -0
- kimi_bridge-0.1.0/PKG-INFO +140 -0
- kimi_bridge-0.1.0/README.md +109 -0
- kimi_bridge-0.1.0/docs/ARCHITECTURE.md +77 -0
- kimi_bridge-0.1.0/docs/COMMANDS.md +83 -0
- kimi_bridge-0.1.0/docs/CONFIGURATION.md +94 -0
- kimi_bridge-0.1.0/docs/kimi-bridge.service +15 -0
- kimi_bridge-0.1.0/pyproject.toml +70 -0
- kimi_bridge-0.1.0/scripts/check_distribution.py +215 -0
- kimi_bridge-0.1.0/scripts/check_docs.py +158 -0
- kimi_bridge-0.1.0/scripts/check_kimi_compatibility.py +110 -0
- kimi_bridge-0.1.0/scripts/check_release.py +78 -0
- kimi_bridge-0.1.0/scripts/smoke_server.py +98 -0
- kimi_bridge-0.1.0/src/kimi_bridge/__init__.py +9 -0
- kimi_bridge-0.1.0/src/kimi_bridge/__main__.py +152 -0
- kimi_bridge-0.1.0/src/kimi_bridge/assets/__init__.py +1 -0
- kimi_bridge-0.1.0/src/kimi_bridge/assets/video-cover.png +0 -0
- kimi_bridge-0.1.0/src/kimi_bridge/compatibility.py +187 -0
- kimi_bridge-0.1.0/src/kimi_bridge/compatibility_check.py +948 -0
- kimi_bridge-0.1.0/src/kimi_bridge/config.py +193 -0
- kimi_bridge-0.1.0/src/kimi_bridge/doctor.py +387 -0
- kimi_bridge-0.1.0/src/kimi_bridge/interactions.py +123 -0
- kimi_bridge-0.1.0/src/kimi_bridge/kimi_server/__init__.py +86 -0
- kimi_bridge-0.1.0/src/kimi_bridge/kimi_server/client.py +1025 -0
- kimi_bridge-0.1.0/src/kimi_bridge/kimi_server/contract.py +954 -0
- kimi_bridge-0.1.0/src/kimi_bridge/kimi_server/contract_validation.py +639 -0
- kimi_bridge-0.1.0/src/kimi_bridge/kimi_server/events.py +42 -0
- kimi_bridge-0.1.0/src/kimi_bridge/kimi_server/probe.py +143 -0
- kimi_bridge-0.1.0/src/kimi_bridge/kimi_server/supervisor.py +440 -0
- kimi_bridge-0.1.0/src/kimi_bridge/kimi_server/types.py +187 -0
- kimi_bridge-0.1.0/src/kimi_bridge/kimi_server/wire.py +294 -0
- kimi_bridge-0.1.0/src/kimi_bridge/platforms/__init__.py +0 -0
- kimi_bridge-0.1.0/src/kimi_bridge/platforms/base.py +114 -0
- kimi_bridge-0.1.0/src/kimi_bridge/platforms/feishu.py +942 -0
- kimi_bridge-0.1.0/src/kimi_bridge/platforms/feishu_cards.py +672 -0
- kimi_bridge-0.1.0/src/kimi_bridge/platforms/telegram.py +1322 -0
- kimi_bridge-0.1.0/src/kimi_bridge/router/__init__.py +5 -0
- kimi_bridge-0.1.0/src/kimi_bridge/router/commands.py +878 -0
- kimi_bridge-0.1.0/src/kimi_bridge/router/core.py +174 -0
- kimi_bridge-0.1.0/src/kimi_bridge/router/files.py +51 -0
- kimi_bridge-0.1.0/src/kimi_bridge/router/formatting.py +330 -0
- kimi_bridge-0.1.0/src/kimi_bridge/router/interactions.py +338 -0
- kimi_bridge-0.1.0/src/kimi_bridge/router/models.py +75 -0
- kimi_bridge-0.1.0/src/kimi_bridge/router/rendering.py +282 -0
- kimi_bridge-0.1.0/src/kimi_bridge/router/sessions.py +310 -0
- kimi_bridge-0.1.0/src/kimi_bridge/state.py +120 -0
- kimi_bridge-0.1.0/src/kimi_bridge/supported-kimi-code-versions.json +7 -0
- kimi_bridge-0.1.0/tests/conftest.py +24 -0
- kimi_bridge-0.1.0/tests/test_compatibility.py +98 -0
- kimi_bridge-0.1.0/tests/test_compatibility_check.py +594 -0
- kimi_bridge-0.1.0/tests/test_config.py +151 -0
- kimi_bridge-0.1.0/tests/test_doctor.py +308 -0
- kimi_bridge-0.1.0/tests/test_feishu.py +1001 -0
- kimi_bridge-0.1.0/tests/test_kimi_server.py +1532 -0
- kimi_bridge-0.1.0/tests/test_main.py +103 -0
- kimi_bridge-0.1.0/tests/test_public_docs.py +48 -0
- kimi_bridge-0.1.0/tests/test_router.py +3037 -0
- kimi_bridge-0.1.0/tests/test_state.py +160 -0
- kimi_bridge-0.1.0/tests/test_telegram.py +1081 -0
- kimi_bridge-0.1.0/tests/test_workflows.py +134 -0
- kimi_bridge-0.1.0/uv.lock +828 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
tests:
|
|
18
|
+
name: Python ${{ matrix.python-version }}
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
strategy:
|
|
21
|
+
fail-fast: false
|
|
22
|
+
matrix:
|
|
23
|
+
python-version: ["3.11", "3.13"]
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
26
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
27
|
+
with:
|
|
28
|
+
python-version: ${{ matrix.python-version }}
|
|
29
|
+
enable-cache: true
|
|
30
|
+
- run: uv sync --locked --all-extras --dev
|
|
31
|
+
- run: uv run --locked pytest -q
|
|
32
|
+
|
|
33
|
+
quality:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
37
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
38
|
+
with:
|
|
39
|
+
python-version: "3.13"
|
|
40
|
+
enable-cache: true
|
|
41
|
+
- run: uv lock --check
|
|
42
|
+
- run: uv sync --locked --all-extras --dev
|
|
43
|
+
- run: uv run --locked ruff check .
|
|
44
|
+
- run: git diff --check
|
|
45
|
+
- run: uv run --locked python scripts/check_docs.py
|
|
46
|
+
- run: uv run --locked python scripts/check_kimi_compatibility.py contract --output /tmp/kimi-contract.json
|
|
47
|
+
|
|
48
|
+
distribution:
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
52
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
53
|
+
with:
|
|
54
|
+
python-version: "3.13"
|
|
55
|
+
enable-cache: true
|
|
56
|
+
- run: uv sync --locked --all-extras --dev
|
|
57
|
+
- run: uv build --no-sources
|
|
58
|
+
- run: uv run --locked twine check dist/*
|
|
59
|
+
- run: uv run --locked python scripts/check_distribution.py --dist-dir dist
|
|
60
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
61
|
+
with:
|
|
62
|
+
name: distributions
|
|
63
|
+
path: dist/
|
|
64
|
+
if-no-files-found: error
|
|
65
|
+
retention-days: 14
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Kimi compatibility
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "17 19 * * *"
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: kimi-code-compatibility
|
|
13
|
+
cancel-in-progress: false
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
canary:
|
|
17
|
+
if: github.ref == 'refs/heads/main'
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
21
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.13"
|
|
24
|
+
enable-cache: true
|
|
25
|
+
- run: uv sync --locked --dev
|
|
26
|
+
- name: Run isolated credential-free canary
|
|
27
|
+
id: canary
|
|
28
|
+
continue-on-error: true
|
|
29
|
+
run: uv run --locked python scripts/check_kimi_compatibility.py check --report "$RUNNER_TEMP/kimi-compatibility/report.json" --artifacts "$RUNNER_TEMP/kimi-compatibility/artifacts"
|
|
30
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
31
|
+
if: always()
|
|
32
|
+
with:
|
|
33
|
+
name: kimi-compatibility-report
|
|
34
|
+
path: ${{ runner.temp }}/kimi-compatibility/
|
|
35
|
+
if-no-files-found: error
|
|
36
|
+
retention-days: 14
|
|
37
|
+
|
|
38
|
+
synchronize:
|
|
39
|
+
needs: canary
|
|
40
|
+
if: always() && needs.canary.result == 'success'
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
permissions:
|
|
43
|
+
actions: write
|
|
44
|
+
contents: write
|
|
45
|
+
issues: write
|
|
46
|
+
pull-requests: write
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
49
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
50
|
+
with:
|
|
51
|
+
python-version: "3.13"
|
|
52
|
+
enable-cache: true
|
|
53
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
54
|
+
with:
|
|
55
|
+
name: kimi-compatibility-report
|
|
56
|
+
path: ${{ runner.temp }}/kimi-compatibility
|
|
57
|
+
- run: uv sync --locked --dev
|
|
58
|
+
- name: Synchronize promotion or rolling drift issue
|
|
59
|
+
env:
|
|
60
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
61
|
+
GITHUB_DEFAULT_BRANCH: main
|
|
62
|
+
GITHUB_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
63
|
+
run: uv run --locked python scripts/check_kimi_compatibility.py sync --report "$RUNNER_TEMP/kimi-compatibility/report.json"
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: release-${{ github.event.release.tag_name }}
|
|
12
|
+
cancel-in-progress: false
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
19
|
+
with:
|
|
20
|
+
ref: ${{ github.event.release.tag_name }}
|
|
21
|
+
fetch-depth: 0
|
|
22
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
23
|
+
with:
|
|
24
|
+
python-version: "3.13"
|
|
25
|
+
enable-cache: true
|
|
26
|
+
- run: uv sync --locked --all-extras --dev
|
|
27
|
+
- name: Verify release identity
|
|
28
|
+
run: uv run --locked python scripts/check_release.py --tag "$GITHUB_REF_NAME" --commit "$GITHUB_SHA"
|
|
29
|
+
- run: uv run --locked pytest -q
|
|
30
|
+
- run: uv run --locked ruff check .
|
|
31
|
+
- run: git diff --check
|
|
32
|
+
- run: uv run --locked python scripts/check_docs.py
|
|
33
|
+
- run: uv build --no-sources
|
|
34
|
+
- run: uv run --locked twine check dist/*
|
|
35
|
+
- run: uv run --locked python scripts/check_distribution.py --dist-dir dist
|
|
36
|
+
- name: Record artifact hashes
|
|
37
|
+
run: sha256sum dist/* > SHA256SUMS
|
|
38
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
39
|
+
with:
|
|
40
|
+
name: release-${{ github.event.release.tag_name }}
|
|
41
|
+
path: |
|
|
42
|
+
dist/
|
|
43
|
+
SHA256SUMS
|
|
44
|
+
if-no-files-found: error
|
|
45
|
+
retention-days: 14
|
|
46
|
+
|
|
47
|
+
release-assets:
|
|
48
|
+
needs: build
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
permissions:
|
|
51
|
+
actions: read
|
|
52
|
+
contents: write
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
55
|
+
with:
|
|
56
|
+
name: release-${{ github.event.release.tag_name }}
|
|
57
|
+
path: release-bundle
|
|
58
|
+
- name: Verify artifact hashes
|
|
59
|
+
working-directory: release-bundle
|
|
60
|
+
run: sha256sum --check SHA256SUMS
|
|
61
|
+
- name: Attach distributions and hashes
|
|
62
|
+
env:
|
|
63
|
+
GH_TOKEN: ${{ github.token }}
|
|
64
|
+
run: gh release upload "$GITHUB_REF_NAME" release-bundle/dist/* release-bundle/SHA256SUMS --clobber --repo "$GITHUB_REPOSITORY"
|
|
65
|
+
|
|
66
|
+
pypi-publish:
|
|
67
|
+
needs: [build, release-assets]
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
environment:
|
|
70
|
+
name: pypi
|
|
71
|
+
url: https://pypi.org/p/kimi-bridge
|
|
72
|
+
permissions:
|
|
73
|
+
actions: read
|
|
74
|
+
id-token: write
|
|
75
|
+
steps:
|
|
76
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
77
|
+
with:
|
|
78
|
+
name: release-${{ github.event.release.tag_name }}
|
|
79
|
+
path: release-bundle
|
|
80
|
+
- name: Verify artifact hashes
|
|
81
|
+
working-directory: release-bundle
|
|
82
|
+
run: sha256sum --check SHA256SUMS
|
|
83
|
+
- uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
|
|
84
|
+
with:
|
|
85
|
+
packages-dir: release-bundle/dist/
|
|
86
|
+
verify-metadata: true
|
|
87
|
+
attestations: true
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidance for AI agents (and humans) working in this repo.
|
|
4
|
+
|
|
5
|
+
## Project state
|
|
6
|
+
|
|
7
|
+
**The managed server client, Feishu bridge, and experimental Telegram adapter are implemented, including interactive approvals/questions, prompt steering, inbound media, semantic outbound files, separately streamed optional thinking, compatibility diagnostics, and credential-free contract monitoring.** Feishu is live-validated; Telegram is fake-tested but not live-validated. The core contracts are platform-neutral, and the runtime intentionally enables one selected adapter per process. Public behavior and architectural requirements live in `docs/ARCHITECTURE.md`, `docs/CONFIGURATION.md`, and `docs/COMMANDS.md`; changing those contracts requires explicit user sign-off and matching documentation in the same change.
|
|
8
|
+
|
|
9
|
+
## Layout
|
|
10
|
+
|
|
11
|
+
- `src/kimi_bridge/kimi_server/` — the ONLY package that talks to kimi-code. Its facade, client, supervisor, types, wire/event helpers, probe, and semantic-contract modules form one boundary; platform adapters, automation, and the router must stay free of kimi-server API details.
|
|
12
|
+
- `src/kimi_bridge/interactions.py` — platform-neutral approval/question prompts, answers, responses, and outcomes.
|
|
13
|
+
- `src/kimi_bridge/router/` — the platform-neutral routing package. `core.py` exposes the single `ChatRouter` facade; command orchestration, session/stream lifecycle, interaction lifecycle, answer/thinking rendering, file authorization, formatting, and private runtime state stay in their focused modules. The package must not construct platform UI payloads or choose native media types.
|
|
14
|
+
- `src/kimi_bridge/platforms/` — one adapter per IM platform, behind the semantic `PlatformAdapter` protocol in `base.py`. Native text/file rendering, uploads, and callback decoding stay inside the platform package.
|
|
15
|
+
- `src/kimi_bridge/platforms/feishu.py` and `feishu_cards.py` — Feishu Markdown posts, native media uploads/messages, card JSON, and callback decoding. Bundled native-rendering assets live below `src/kimi_bridge/assets/` and must be loaded with package resources so wheel installs work.
|
|
16
|
+
- `src/kimi_bridge/platforms/telegram.py` — the handwritten Telegram Bot API transport and adapter. Telegram update dictionaries, multipart uploads, inline keyboards, callback tokens, `ForceReply` wizard state, retry policy, and file downloads stay here.
|
|
17
|
+
- `src/kimi_bridge/state.py` — versioned bridge-owned conversation state. New schema changes require an explicit migration that preserves existing bindings; unknown future versions must still fail loudly.
|
|
18
|
+
- `scripts/check_kimi_compatibility.py` and `.github/workflows/kimi-drift.yml` — credential-free semantic contract checking and quiet supported-version promotion. Protocol knowledge must remain in `kimi_server`; automation consumes its projection.
|
|
19
|
+
|
|
20
|
+
## kimi server API
|
|
21
|
+
|
|
22
|
+
- Tested runtime versions are the immutable `src/kimi_bridge/supported-kimi-code-versions.json` manifest loaded by `compatibility.py`. Unknown official Kimi Code versions warn and attempt the live contract; executable/server version mismatches and legacy Python `kimi-cli` fail. Start the server with `kimi web --no-open --host 127.0.0.1 --port <p>`; it stays in the foreground and prints the bearer token at startup.
|
|
23
|
+
- Specs are served at runtime: `GET /openapi.json` (REST) and `GET /asyncapi.json` (WebSocket). Consult them instead of guessing field names; note the API is 0.x and may shift between kimi-code releases — check `server_version` in `/api/v1/meta`.
|
|
24
|
+
- Stored sessions must be materialized through `GET /api/v1/sessions/{session_id}/status` before each initial or reconnected WebSocket subscription. This lifecycle detail belongs only in the `kimi_server` package.
|
|
25
|
+
- Auth: `Authorization: Bearer <token>` header on REST and WS.
|
|
26
|
+
|
|
27
|
+
## Conventions
|
|
28
|
+
|
|
29
|
+
- Python ≥ 3.11, asyncio throughout, typed (dataclasses / Protocol, `from __future__ import annotations`).
|
|
30
|
+
- Minimal dependencies: core is `httpx` + `websockets` only. Feishu uses the optional `lark-oapi` SDK; Telegram reuses `httpx` and must not gain a framework dependency without an explicit design change.
|
|
31
|
+
- Keep the shared contracts semantic and platform-neutral. Do not introduce a generic UI schema, plugin framework, capability registry, or multi-adapter runtime without a concrete second platform requiring it.
|
|
32
|
+
- Keep public documentation compact and current. Do not expose private credentials, local planning material, ignored reference snapshots, or internal progress terminology in package metadata, docs, workflows, issues, or releases.
|
|
33
|
+
- If a file is gitignored, it's gitignored for a reason — never force-add it.
|
|
34
|
+
|
|
35
|
+
## Testing
|
|
36
|
+
|
|
37
|
+
Unit-test the router against a fake `KimiServerClient` and fake adapters. Router tests assert semantic interactions, path authorization, state migration, and independent stream behavior; platform tests assert native rendering, uploads, and callback decoding. Keep server supervision, REST/WebSocket recovery, Feishu filtering, Telegram Bot API transport, configuration, and state persistence behind fakes in CI; do not require a live Kimi server or real IM credentials. The standalone smoke script is the explicit authenticated live-server check. Distribution changes also require building source and wheel artifacts, checking metadata/license/bundled assets, and exercising isolated core and Feishu-extra `uv tool` installs through non-starting `--help`, `--version`, and `doctor` before uninstalling them.
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Install and operate kimi-bridge
|
|
2
|
+
|
|
3
|
+
This is the starting runbook for both humans and coding agents. An agent should inspect the machine first, explain what it found, and pause at every user decision or credential boundary. Do not claim success until the selected chat adapter has been exercised by its allowlisted user.
|
|
4
|
+
|
|
5
|
+
## 1. Inspect before changing anything
|
|
6
|
+
|
|
7
|
+
Confirm that the host is Linux and inventory existing tools without installing or replacing them:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
uname -s
|
|
11
|
+
python3 --version
|
|
12
|
+
command -v uv || true
|
|
13
|
+
command -v kimi || true
|
|
14
|
+
kimi --version
|
|
15
|
+
kimi --help
|
|
16
|
+
kimi doctor config
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
kimi-bridge requires Linux, Python 3.11 or newer, [uv](https://docs.astral.sh/uv/getting-started/installation/), and authenticated official [Kimi Code](https://moonshotai.github.io/kimi-code/en/guides/getting-started). Official Kimi Code has `web`, `doctor`, and `migrate` commands. The older Python product prints a `kimi, version ...` banner and is incompatible; do not install or retain legacy `kimi-cli` as a workaround. Follow Moonshot AI's current installation or migration guide when Kimi Code is absent or legacy.
|
|
20
|
+
|
|
21
|
+
Ask the user which adapter they want before configuring anything:
|
|
22
|
+
|
|
23
|
+
- Feishu requires an app ID, app secret, and at least one Feishu `open_id` or `user_id`.
|
|
24
|
+
- Experimental Telegram requires a bot token and at least one stable numeric Telegram user ID. Usernames are not authorization identities.
|
|
25
|
+
|
|
26
|
+
Do not ask the user to paste credentials into a repository file. Do not print, log, commit, or echo credentials or real allowlist values. If a secret already exists in a protected environment file or secret manager, transfer it locally without displaying it. Otherwise ask the user to enter it through a private local editor or another secret-safe channel. Avoid commands that leave secrets in shell history.
|
|
27
|
+
|
|
28
|
+
## 2. Install from PyPI
|
|
29
|
+
|
|
30
|
+
For Feishu, install the optional SDK extra:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
uv tool install 'kimi-bridge[feishu]'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
For the experimental Telegram adapter, the core package is sufficient:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv tool install kimi-bridge
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Check the exposed command:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
command -v kimi-bridge
|
|
46
|
+
kimi-bridge --version
|
|
47
|
+
kimi-bridge --help
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If `uv` reports that its tool bin directory is not on `PATH`, run `uv tool update-shell`, then start a fresh shell. Do not replace a working installation merely because its resolved path differs from an example in this guide.
|
|
51
|
+
|
|
52
|
+
## 3. Create protected configuration
|
|
53
|
+
|
|
54
|
+
Create the private configuration directory, then let the user populate the selected adapter's values using the [configuration reference](docs/CONFIGURATION.md):
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
install -d -m 700 ~/.kimi-bridge
|
|
58
|
+
touch ~/.kimi-bridge/config.toml
|
|
59
|
+
chmod 600 ~/.kimi-bridge/config.toml
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Do not place secrets in environment files inside the project. After the file is populated, inspect only its ownership, mode, and redacted structure. Never include its contents in tool output or a diagnostic report.
|
|
63
|
+
|
|
64
|
+
Run the non-starting diagnostic:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
kimi-bridge doctor
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`doctor` loads configuration, checks secret-file permissions and writable paths, fingerprints the `kimi` executable, classifies its version, and runs Kimi's non-starting configuration check. It reports only credential presence and allowlist counts. Warnings return success; blocking errors return nonzero. Resolve every error before continuing and explain any warning rather than suppressing it.
|
|
71
|
+
|
|
72
|
+
## 4. Verify in the foreground
|
|
73
|
+
|
|
74
|
+
Start the bridge from a normal shell:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
kimi-bridge
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Ask the allowlisted user to send `/status`, then send one small prompt and confirm that its reply streams and completes without a duplicate message. Exercise an approval or question if the selected permission mode requires it. Stop with `Ctrl-C` and confirm clean shutdown.
|
|
81
|
+
|
|
82
|
+
For Feishu, do not call the setup complete until direct messages, editable replies, and any configured card callbacks work. For Telegram, state plainly that its adapter remains experimental and was not live-validated by the project unless this installation's own private-chat test actually passed.
|
|
83
|
+
|
|
84
|
+
## 5. Optional per-user systemd service
|
|
85
|
+
|
|
86
|
+
Do not create a service automatically. First ask: “Do you want kimi-bridge to run persistently as your user?” A foreground-only installation is complete if the answer is no.
|
|
87
|
+
|
|
88
|
+
If the user says yes, resolve the actual executable locations before creating anything:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
command -v kimi-bridge
|
|
92
|
+
command -v kimi
|
|
93
|
+
uv tool dir --bin
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The repository includes [a user-unit template](docs/kimi-bridge.service). Its default paths match uv's usual user tool directory and Kimi Code's usual installer directory, but an agent must replace `ExecStart` and the `PATH` entries when the commands above report different absolute paths. Do not put credentials in the unit.
|
|
97
|
+
|
|
98
|
+
After receiving approval to create the service, place the reviewed unit at `~/.config/systemd/user/kimi-bridge.service`, then validate and reload it without starting it:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
install -d -m 700 ~/.config/systemd/user
|
|
102
|
+
install -m 600 docs/kimi-bridge.service ~/.config/systemd/user/kimi-bridge.service
|
|
103
|
+
systemd-analyze --user verify ~/.config/systemd/user/kimi-bridge.service
|
|
104
|
+
systemctl --user daemon-reload
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The copy command assumes a source checkout. For a PyPI-only installation, create the same reviewed unit from the linked template. If `systemd-analyze --user` is unavailable, report that syntax validation remains pending rather than skipping it silently.
|
|
108
|
+
|
|
109
|
+
Pause again and ask for explicit approval before enabling or starting the unit. Only after approval:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
systemctl --user enable --now kimi-bridge.service
|
|
113
|
+
systemctl --user status kimi-bridge.service
|
|
114
|
+
journalctl --user -u kimi-bridge.service --since today
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Review the journal for startup success and confirm it contains no credential values. Repeat the same `/status` and streamed-reply chat check against the service.
|
|
118
|
+
|
|
119
|
+
By default, a user service follows the user's login session. `loginctl enable-linger "$USER"` makes the user manager start at boot and remain available after logout. Treat lingering as a separate user decision because it changes host lifecycle behavior; never enable it silently. Disabling it later uses `loginctl disable-linger "$USER"`.
|
|
120
|
+
|
|
121
|
+
## Operations
|
|
122
|
+
|
|
123
|
+
Inspect and follow logs:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
systemctl --user status kimi-bridge.service
|
|
127
|
+
journalctl --user -u kimi-bridge.service -f
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Restart after an approved configuration change:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
kimi-bridge doctor
|
|
134
|
+
systemctl --user restart kimi-bridge.service
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Upgrade, validate, and restart:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
uv tool upgrade kimi-bridge
|
|
141
|
+
kimi-bridge --version
|
|
142
|
+
kimi-bridge doctor
|
|
143
|
+
systemctl --user restart kimi-bridge.service
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Pin a known release for rollback, retaining the Feishu extra when applicable:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
uv tool install --force 'kimi-bridge[feishu]==0.1.0'
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Use `kimi-bridge==0.1.0` instead for the core installation, then rerun `doctor` and restart the service.
|
|
153
|
+
|
|
154
|
+
Stop and disable the service without deleting user data:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
systemctl --user disable --now kimi-bridge.service
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
After the user confirms removal, delete only `~/.config/systemd/user/kimi-bridge.service`, run `systemctl --user daemon-reload`, and uninstall the tool:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
uv tool uninstall kimi-bridge
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Uninstalling the tool or service must preserve `~/.kimi-bridge/config.toml`, `state.json`, workspaces, inbound files, and Kimi sessions unless the user separately asks to remove those specific paths.
|
|
167
|
+
|
|
168
|
+
## Install from a checkout
|
|
169
|
+
|
|
170
|
+
Contributors can use an isolated tool directly from a trusted checkout:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
uv tool install .
|
|
174
|
+
uv tool install --force '.[feishu]'
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
For development and validation commands, see [README](README.md#development).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mtrya
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kimi-bridge
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Control a local Kimi Code agent from Feishu or Telegram
|
|
5
|
+
Project-URL: Homepage, https://github.com/Mtrya/kimi-bridge
|
|
6
|
+
Project-URL: Repository, https://github.com/Mtrya/kimi-bridge
|
|
7
|
+
Project-URL: Issues, https://github.com/Mtrya/kimi-bridge/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/Mtrya/kimi-bridge#readme
|
|
9
|
+
Project-URL: Changelog, https://github.com/Mtrya/kimi-bridge/releases
|
|
10
|
+
Author: Mtrya
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: agent,chatbot,feishu,kimi-code,telegram
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Framework :: AsyncIO
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Communications :: Chat
|
|
24
|
+
Classifier: Topic :: Software Development :: User Interfaces
|
|
25
|
+
Requires-Python: >=3.11
|
|
26
|
+
Requires-Dist: httpx
|
|
27
|
+
Requires-Dist: websockets
|
|
28
|
+
Provides-Extra: feishu
|
|
29
|
+
Requires-Dist: lark-oapi<2,>=1.7.1; extra == 'feishu'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# kimi-bridge
|
|
33
|
+
|
|
34
|
+
Control a local [Kimi Code](https://github.com/MoonshotAI/kimi-code) agent from an instant-messaging conversation.
|
|
35
|
+
|
|
36
|
+
kimi-bridge supervises Kimi Code's local server, keeps chat-to-session bindings across restarts, streams editable replies, and brings approvals, questions, steering, files, thinking output, and session controls into your chat client.
|
|
37
|
+
|
|
38
|
+
## Support
|
|
39
|
+
|
|
40
|
+
| Surface | Status | Validation |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| Feishu direct messages | Supported | Live-validated end to end |
|
|
43
|
+
| Telegram private chats | Experimental | Fake Bot API tests only; not live-validated |
|
|
44
|
+
| Linux, Python ≥3.11 | Supported | Hosted tests on 3.11 and 3.13 |
|
|
45
|
+
| macOS and Windows | Not currently supported | — |
|
|
46
|
+
|
|
47
|
+
Only one adapter runs in each bridge process. Feishu uses the official `lark-oapi` WebSocket client. Telegram uses a small handwritten `httpx` Bot API transport without a Telegram framework.
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- Durable Kimi session creation, listing, switching, renaming, inspection, compaction, and undo.
|
|
52
|
+
- Edit-in-place answer streaming, router-side chunking, and optional separate thinking output.
|
|
53
|
+
- Interactive approvals and questions with timeout handling and stale-action protection.
|
|
54
|
+
- Busy-turn prompt steering, cancellation, permission modes, model/effort/plan controls, goals, tasks, skills, and read-only MCP inspection.
|
|
55
|
+
- Inbound images and files plus workspace-contained outbound `/send`.
|
|
56
|
+
- Private-chat allowlists, loopback-only Kimi server supervision, and a secret-safe non-starting doctor command.
|
|
57
|
+
|
|
58
|
+
## Quick start
|
|
59
|
+
|
|
60
|
+
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.
|
|
61
|
+
|
|
62
|
+
For Feishu:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
uv tool install 'kimi-bridge[feishu]'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
For the experimental Telegram adapter:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
uv tool install kimi-bridge
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Create `~/.kimi-bridge/config.toml` for one adapter, protect it with `chmod 600`, and validate the installation without starting the server or connecting to chat:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
kimi-bridge doctor
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Then run:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
kimi-bridge
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Start with the [installation runbook](INSTALL.md), especially when asking a coding agent to configure the bridge. The [configuration reference](docs/CONFIGURATION.md) contains complete Feishu and Telegram examples.
|
|
87
|
+
|
|
88
|
+
## Commands
|
|
89
|
+
|
|
90
|
+
Commands cover:
|
|
91
|
+
|
|
92
|
+
- sessions: `/new`, `/sessions`, `/switch`, `/status`, `/title`, `/usage`, `/compact`, `/undo`;
|
|
93
|
+
- control: `/mode`, `/model`, `/effort`, `/plan`, `/goal`, `/stop`;
|
|
94
|
+
- tasks and tools: `/tasks`, `/skills`, `/mcp`;
|
|
95
|
+
- output: `/send`, `/render-thinking`.
|
|
96
|
+
|
|
97
|
+
Use `/help` in chat or read the [command reference](docs/COMMANDS.md) for exact grammar, busy-session behavior, and platform media semantics.
|
|
98
|
+
|
|
99
|
+
## Architecture and security
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
Feishu or experimental Telegram
|
|
103
|
+
│
|
|
104
|
+
▼
|
|
105
|
+
semantic chat router
|
|
106
|
+
│
|
|
107
|
+
▼
|
|
108
|
+
supervised local `kimi web`
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The Kimi client owns all REST, WebSocket, version, and process-lifecycle details. The router owns platform-neutral session and interaction behavior. Each adapter owns its native transport and UI payloads. See [Architecture](docs/ARCHITECTURE.md) for the full boundary.
|
|
112
|
+
|
|
113
|
+
The managed Kimi server binds to loopback and uses its generated bearer token. Chat access is restricted by the selected adapter's allowlist, but kimi-bridge is designed for one trusted operator, not mutually untrusted tenants. A permitted Kimi agent can read, write, and execute within the authority of the host account, so protect both the host and chat credentials.
|
|
114
|
+
|
|
115
|
+
Tested Kimi Code versions are recorded in a packaged compatibility manifest. An unlisted official version emits a loud warning and is attempted against the live contract; legacy Python `kimi-cli`, an unrecognized product, or an executable/server version mismatch fails. Run `kimi-bridge doctor` after every Kimi or bridge upgrade.
|
|
116
|
+
|
|
117
|
+
## Documentation
|
|
118
|
+
|
|
119
|
+
- [Install and operate](INSTALL.md)
|
|
120
|
+
- [Configure](docs/CONFIGURATION.md)
|
|
121
|
+
- [Commands and interactions](docs/COMMANDS.md)
|
|
122
|
+
- [Architecture and compatibility](docs/ARCHITECTURE.md)
|
|
123
|
+
- [Upstream Kimi Code](https://moonshotai.github.io/kimi-code/en/guides/getting-started)
|
|
124
|
+
- [Report an issue](https://github.com/Mtrya/kimi-bridge/issues)
|
|
125
|
+
|
|
126
|
+
## Development
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
uv sync --all-extras --dev
|
|
130
|
+
uv run pytest -q
|
|
131
|
+
uv run ruff check .
|
|
132
|
+
uv run python scripts/check_docs.py
|
|
133
|
+
uv run python scripts/smoke_server.py
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Unit tests use fake Kimi, Feishu, Telegram, WebSocket, state, and process boundaries. The smoke script is the explicit authenticated local-server check; hosted checks use no credentials or inference.
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
[MIT](LICENSE) © 2026 Mtrya
|