cocoindex-code 0.2.38__tar.gz → 0.2.39__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.
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/PKG-INFO +1 -1
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/_version.py +2 -2
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/client.py +40 -3
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/protocol.py +9 -1
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/.gitignore +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/LICENSE +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/README.md +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/pyproject.toml +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/__init__.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/__main__.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/_daemon_paths.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/chunking.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/cli.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/daemon.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/embedder_defaults.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/embedder_params.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/file_walk.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/grep.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/indexer.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/litellm_embedder.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/project.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/query.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/schema.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/server.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/settings.py +0 -0
- {cocoindex_code-0.2.38 → cocoindex_code-0.2.39}/src/cocoindex_code/shared.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cocoindex-code
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.39
|
|
4
4
|
Summary: MCP server for indexing and querying codebases using CocoIndex
|
|
5
5
|
Project-URL: Homepage, https://github.com/cocoindex-io/cocoindex-code
|
|
6
6
|
Project-URL: Repository, https://github.com/cocoindex-io/cocoindex-code
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
21
|
+
__version__ = version = '0.2.39'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 39)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -18,6 +18,8 @@ from multiprocessing.connection import Client, Connection
|
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
from typing import NamedTuple
|
|
20
20
|
|
|
21
|
+
import msgspec
|
|
22
|
+
|
|
21
23
|
from ._daemon_paths import (
|
|
22
24
|
connection_family,
|
|
23
25
|
daemon_log_path,
|
|
@@ -158,6 +160,16 @@ def _connect_and_handshake() -> Connection:
|
|
|
158
160
|
if _daemon_ensured and not e.resp.ok:
|
|
159
161
|
raise
|
|
160
162
|
stop_daemon()
|
|
163
|
+
except DaemonProtocolError:
|
|
164
|
+
# The reply didn't even decode — a daemon whose wire protocol
|
|
165
|
+
# drifted beyond what the version-mismatch path can express (e.g.
|
|
166
|
+
# still running a pre-upgrade binary). Same treatment as a version
|
|
167
|
+
# mismatch: restart it below; once a matching daemon was already
|
|
168
|
+
# ensured this cannot legitimately happen, so fail fast instead of
|
|
169
|
+
# looping on restarts.
|
|
170
|
+
if _daemon_ensured:
|
|
171
|
+
raise
|
|
172
|
+
stop_daemon()
|
|
161
173
|
except (ConnectionRefusedError, OSError):
|
|
162
174
|
# No daemon answered. Normal on the first call of this process (start
|
|
163
175
|
# one below). If we had already ensured one, decide crash vs graceful
|
|
@@ -238,7 +250,15 @@ def _raw_connect_and_handshake() -> _HandshakeResult:
|
|
|
238
250
|
conn.close()
|
|
239
251
|
raise ConnectionRefusedError(f"Handshake failed: {e}") from e
|
|
240
252
|
|
|
241
|
-
|
|
253
|
+
try:
|
|
254
|
+
resp = decode_response(data)
|
|
255
|
+
except msgspec.DecodeError as e:
|
|
256
|
+
# The daemon speaks an incompatible wire protocol — e.g. a stale
|
|
257
|
+
# pre-upgrade daemon whose handshake reply no longer matches this
|
|
258
|
+
# client's schema. Must not escape as a raw decode error: the caller
|
|
259
|
+
# handles DaemonProtocolError by restarting the daemon (issue #237).
|
|
260
|
+
conn.close()
|
|
261
|
+
raise DaemonProtocolError(f"Undecodable handshake reply from daemon: {e}") from e
|
|
242
262
|
if isinstance(resp, ErrorResponse):
|
|
243
263
|
conn.close()
|
|
244
264
|
raise RuntimeError(f"Daemon error: {resp.message}")
|
|
@@ -274,6 +294,19 @@ class DaemonVersionError(RuntimeError):
|
|
|
274
294
|
super().__init__(message)
|
|
275
295
|
|
|
276
296
|
|
|
297
|
+
class DaemonProtocolError(RuntimeError):
|
|
298
|
+
"""Raised when the daemon's handshake reply cannot be decoded at all.
|
|
299
|
+
|
|
300
|
+
A version-mismatched daemon normally reports itself via ``resp.ok`` being
|
|
301
|
+
False (→ ``DaemonVersionError``), but that requires its reply to decode
|
|
302
|
+
against this client's schema. When even decoding fails, the daemon is
|
|
303
|
+
from a version whose wire protocol drifted too far — handled the same
|
|
304
|
+
way: restart on first contact, fail fast once a matching daemon was
|
|
305
|
+
already ensured. Subclasses RuntimeError so broad daemon-failure handlers
|
|
306
|
+
(e.g. in ``stop_daemon``) cover it.
|
|
307
|
+
"""
|
|
308
|
+
|
|
309
|
+
|
|
277
310
|
class DaemonStartError(RuntimeError):
|
|
278
311
|
"""Raised when the daemon process fails to start.
|
|
279
312
|
|
|
@@ -427,7 +460,7 @@ def send_heartbeat() -> bool:
|
|
|
427
460
|
"""
|
|
428
461
|
try:
|
|
429
462
|
conn, _resp = _raw_connect_and_handshake()
|
|
430
|
-
except (ConnectionRefusedError, DaemonVersionError, OSError):
|
|
463
|
+
except (ConnectionRefusedError, DaemonVersionError, DaemonProtocolError, OSError):
|
|
431
464
|
return False
|
|
432
465
|
try:
|
|
433
466
|
conn.send_bytes(encode_request(HeartbeatRequest()))
|
|
@@ -608,7 +641,11 @@ def stop_daemon() -> None:
|
|
|
608
641
|
conn.recv_bytes()
|
|
609
642
|
finally:
|
|
610
643
|
conn.close()
|
|
611
|
-
except (ConnectionRefusedError, OSError, RuntimeError, DaemonVersionError):
|
|
644
|
+
except (ConnectionRefusedError, OSError, RuntimeError, DaemonVersionError, DaemonProtocolError):
|
|
645
|
+
# A version-mismatched or protocol-incompatible daemon refuses the
|
|
646
|
+
# handshake, so the graceful StopRequest is impossible — fall through
|
|
647
|
+
# to the SIGTERM escalation below, which must never be skipped just
|
|
648
|
+
# because the daemon speaks a different protocol (issue #237).
|
|
612
649
|
pass
|
|
613
650
|
|
|
614
651
|
if _wait_for_daemon_exit(timeout=3.0):
|
|
@@ -79,13 +79,21 @@ Request = (
|
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
class HandshakeResponse(_msgspec.Struct, tag="handshake"):
|
|
82
|
+
# The handshake is the one message exchanged between *mismatched*
|
|
83
|
+
# client/daemon versions — it is how a mismatch gets detected in the
|
|
84
|
+
# first place. Every field added after a release MUST have a default:
|
|
85
|
+
# a required field makes an older daemon's reply undecodable, which
|
|
86
|
+
# breaks the restart-on-mismatch path and bricks every command
|
|
87
|
+
# (issue #237).
|
|
82
88
|
ok: bool
|
|
83
89
|
daemon_version: str
|
|
84
90
|
# The daemon's process id. The client remembers it so that, when the
|
|
85
91
|
# daemon later vanishes, the graceful-exit marker (written on shutdown
|
|
86
92
|
# with the same pid) can be matched race-free against the exact process
|
|
87
93
|
# the client was talking to — distinguishing a graceful exit from a crash.
|
|
88
|
-
|
|
94
|
+
# None only when decoding the reply of a pre-0.2.38 daemon, whose
|
|
95
|
+
# handshake never satisfies ``ok`` and version checks anyway.
|
|
96
|
+
pid: int | None = None
|
|
89
97
|
global_settings_mtime_us: int | None = None
|
|
90
98
|
# Non-fatal daemon-side warnings surfaced to the client on every handshake.
|
|
91
99
|
# The client dedupes and prints them to stderr (see client._print_handshake_warnings).
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|