8 Commits

Author SHA1 Message Date
Jiangzhou 4372baedfa fix(init): clarify providers, add interactive recovery, fix retry crash (#181) (#184)
Addresses the `ccc init` issues reported in #181:

- Relabel embedding providers so local Ollama is clearly under `litellm`
  ("litellm (100+ providers — cloud APIs & local Ollama)") and
  sentence-transformers is marked as built-in HuggingFace models.
- Reject `ollama/` models inline at the sentence-transformers prompt, before
  anything is written or tested, instead of crashing later.
- On a failed init model check, loop with an interactive "try a different
  model / keep & finish" choice, pre-filling the previous provider and model
  on retry, and print a prominent "Next steps" recovery block.
- Add `ccc doctor -v` to show full tracebacks; by default show the one-line
  error plus a hint to rerun with `-v`.
- Fix the retry crash where a rewritten global_settings.yml made the already
  -ensured daemon report a bogus "version mismatch": restart the daemon on a
  stale-settings handshake even after it was ensured, while still failing fast
  on a genuine mid-session version mismatch. Make DaemonVersionError's message
  reflect the actual cause.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 00:19:44 -07:00
Jiangzhou ee3515fa57 feat: configurable embedder indexing_params/query_params + curated defaults (#150)
Users can now set `indexing_params` and `query_params` under `embedding:` in
`global_settings.yml` to pass extra kwargs to the embedder separately for
indexing vs. query — supporting asymmetric retrieval models (Cohere v3,
Voyage, Nvidia NIM, Gemini, nomic-ai code/text models, Snowflake arctic,
etc.).

- `ccc init` auto-populates these from a curated table of known models and
  prints the applied defaults; unknown models get a commented-out template
  for the accepted keys (`prompt_name` for sentence-transformers;
  `input_type`, `dimensions` for litellm).
- Daemon validates the effective params at startup; invalid keys fail fast
  with a clear error.
- Backward compat: configs for `nomic-ai/CodeRankEmbed` /
  `nomic-ai/nomic-embed-code` that predate this feature keep the previous
  hardcoded `prompt_name=query` behavior, and a one-time handshake warning
  asks users to make the setting explicit. The warning is suppressible by
  any non-None `query_params` (including `{}`).
- `ccc doctor` now tests indexing and query separately so asymmetric
  misconfigurations surface independently.

Drops the legacy `shared.query_prompt_name` module variable and
`_QUERY_PROMPT_MODELS` set; the new resolution path is centralized in
`embedder_params.resolve_embedder_params` and the curated defaults live in
`embedder_defaults._DEFAULT_PARAMS`.

Also enables `litellm.drop_params = True` so provider-specific kwargs that
a particular model doesn't accept are silently dropped instead of failing.
2026-04-24 16:08:20 -07:00
Jiangzhou 92d611968e feat: unified Docker workspace mount with supervised daemon (#135)
* feat: unified Docker workspace mount with supervised daemon

Reshape the Docker experience around a single bind mount and a single
named volume. Global settings live on the host under
$HOME/.cocoindex_code/ (visible and editable); index data and the model
cache persist in one cocoindex-data volume; daemon runtime state stays
on the container's native filesystem.

CLI and MCP output now show host-side paths via a bidirectional
COCOINDEX_CODE_HOST_PATH_MAPPING translator. A shell wrapper that
forwards $PWD (COCOINDEX_CODE_HOST_CWD) lets ccc work from any project
subdirectory on the host.

The daemon tolerates a missing global_settings.yml (starts in
no-settings mode) so ccc init's interactive picker works in Docker on
first run. A supervisor restart loop in the entrypoint, driven by a new
COCOINDEX_CODE_DAEMON_SUPERVISED contract, makes settings-change
auto-restart safe — editing global_settings.yml triggers an in-place
daemon respawn without taking the container down.

Linux ownership alignment via PUID/PGID, gosu privilege drop, and a
coco user baked into the image. Release workflow now publishes to both
Docker Hub (cocoindex/cocoindex-code) and GHCR
(ghcr.io/cocoindex-io/cocoindex-code).

Also:
- Merge cocoindex-db and cocoindex-model-cache into a single volume
- find_parent_with_marker requires .cocoindex_code/settings.yml, so a
  workspace-root global-only dir doesn't trigger nested-init warnings
- New pytest marker `docker_e2e` gates the Docker-backed E2E suite
  (excluded from default pytest runs)

* fix: mypy on Windows for POSIX-only os.getuid/getgid calls
2026-04-14 13:30:50 -07:00
Jiangzhou 3066e02194 feat: handle setting file issues more gracefully (#114) 2026-03-21 10:31:14 -07:00
Jiangzhou 57e7a20dea chore: no longer automatically trigger init by ccc index (#82) 2026-03-16 11:35:21 -07:00
Jiangzhou 3a5935246a chore: minor tweak to comments added to users .gitignore (#80) 2026-03-16 09:31:46 -07:00
Jiangzhou 0b30f16451 feat: assorted improvements for CLI/daemon to be resilient and ergonomic (#72)
* feat: assorted improvements for CLI/daemon to be resilient and ergonomic

* tests: add more e2e tests

* fix: resolve path comparison and LMDB cleanup issues on Windows/3.14t

Three root causes fixed:

1. Path resolution mismatch on Windows: init and auto_init_project used
   unresolved Path.cwd() but find_parent_with_marker/find_project_root
   resolve internally, causing comparison failures and daemon key mismatches.

2. LMDB not released on remove_project: The daemon ProjectRegistry
   dropped the Project from dicts without closing its SQLite connection or
   forcing GC of the Rust LMDB environment. On free-threaded Python (3.14t)
   and Windows, deferred GC kept the LMDB open, causing environment already
   open errors and PermissionErrors when deleting db files.

3. Silent connection close on streaming errors: When update_index async
   iteration failed in the daemon, the connection was closed without sending
   an ErrorResponse, causing the client to get an unhelpful EOFError.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: break LMDB reference chain explicitly and resolve cwd in path filter

On 3.14t (free-threaded Python), gc.collect() alone does not release the
Rust LMDB environment because deferred reference counting keeps
core.Environment alive through App._core_env_app, ContextProvider._core_env,
and Environment._core_env.  Explicitly null these internal references in
Project.close() before gc.collect() so the Rust object is freed promptly.

Also resolve Path.cwd() in resolve_default_path() — on Windows, the
unresolved cwd did not match the resolved project_root, causing
relative_to() to fail and the subdirectory path filter to be skipped.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use double gc.collect() for layered deferred refcount on 3.14t

Revert fragile internal attribute clearing. On free-threaded Python, the
first gc.collect() frees Python wrappers whose Rust Drop implementations
issue further deferred Py_DECREF calls on core.Environment; a second
gc.collect() flushes those and actually drops the LMDB handle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add sleep in tests for LMDB release on free-threaded Python

On 3.14t, deferred reference counting means the Rust LMDB environment
is not released immediately after remove_project + gc.collect(). Add a
1-second sleep in the two tests that reset and re-index, giving the
runtime time to process pending deferred Py_DECREF calls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: restart daemon after reset in tests, increase daemon wait timeout

Instead of sleeping, restart the daemon after reset in the two tests
that re-index after removing databases. This reliably releases the LMDB
environment on all platforms including free-threaded Python (3.14t).

Also increase _wait_for_daemon timeout from 5s to 10s — Windows CI
runners occasionally need longer to start the daemon subprocess.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 23:04:00 -07:00
Jiangzhou 9000f1df7e feat: preliminary implementation for daemon + CLI (#67) 2026-03-14 15:57:26 -07:00