Graphiti's OpenAIClient routes "simpler" extraction prompts to
ModelSize.small, falling back to a hard-coded `gpt-4.1-nano` when no
small_model is configured. Against Qwen/Dashscope (and other OpenAI-SDK
endpoints that don't host that model) this surfaces as a 404 mid-graph
build, even when LLM_MODEL_NAME points at a working model.
Add LLM_SMALL_MODEL_NAME (defaults to LLM_MODEL_NAME) and pass it through
the Graphiti LLMConfig so the small slot is always populated with a
model the configured endpoint actually serves.
Closes#37
Graphiti's default cross-encoder hard-codes the OpenAI gpt-4.1-nano model
and depends on OpenAI-specific logprobs/logit_bias, so the adapter has
been injecting a no-op _PassthroughReranker just to keep search code
paths working. Search results consumed by SearchResult, InsightForge,
Panorama, and Interview were therefore returned in Graphiti's RRF order
with no real reranking signal.
Add an Ollama-backed CrossEncoderClient that scores passages through a
local chat model via the OpenAI-compatible /v1 surface and wire it into
_get_graphiti() behind a RERANKER_PROVIDER switch (default: ollama).
Construction is side-effect-free and the rank() method never raises:
per-passage parse failures degrade to a deterministic low score, and a
whole-call failure falls back to passthrough order with a single WARNING
log so Flask keeps serving when Ollama is unreachable. Setting
RERANKER_PROVIDER=none preserves the legacy passthrough for CI and slim
containers that cannot pull the model.
Closes#39
Two coupled changes that together restore non-empty post-migration graph
builds and remove the silent "succeeded but empty" outcome.
Root cause: Config defaulted EMBEDDING_MODEL to OpenAI text-embedding-3-small
(1536 dim), but Graphiti's Neo4j vector index is 1024 dim. With the
documented Dashscope LLM default, EMBEDDING_API_KEY/EMBEDDING_BASE_URL
fell back to LLM_*, producing either a 4xx (since #29 propagates as
Task.FAILED) or a write that landed metadata but no entities.
Changes:
- Flip Config defaults to local Ollama (mxbai-embed-large, 1024 dim,
http://localhost:11434/v1). Override semantics unchanged: explicit
EMBEDDING_* env vars continue to win, so existing OpenAI/Gemini setups
are not affected.
- Gate _build_graph_worker on a non-zero entity-node count before
complete_task. Mirrors the existing _recover_stuck_projects rule;
surfaces any residual silent failure as Task.FAILED with the new
progress.emptyGraphFailure locale key, instead of marking the project
GRAPH_COMPLETED on an empty graph.
- Update README, CLAUDE.md, and docker-compose.yml comments to reflect
Ollama as the active default and OpenAI/Gemini as commented fallbacks.
- The matching .env.example diff is recorded in
.kiro/specs/graph-build-empty-fix/HANDOFF.md for manual operator apply
(file is hook-protected from the assistant).
Spec: .kiro/specs/graph-build-empty-fix/
Closes#37
Adds a Neo4j service to docker-compose so `docker compose up -d` works
on a clean checkout, and unhardcodes Graphiti's LLM/embedder so the
documented default provider (Qwen via Dashscope) actually works.
- docker-compose: neo4j:5-community service with cypher-shell
healthcheck, named volumes, and `depends_on: service_healthy` on the
app container; in-Docker NEO4J_URI override leaves the host-mode
default untouched.
- Config: new GRAPHITI_LLM_PROVIDER (openai|gemini, default openai) plus
optional EMBEDDING_API_KEY / EMBEDDING_BASE_URL that fall back to the
chat LLM credentials.
- graphiti_adapter: provider switch inside the singleton factory with
lazy per-provider imports; Gemini path is preserved exactly. The
no-op `_GeminiReranker` becomes a provider-agnostic
`_PassthroughReranker`, still injected explicitly so Graphiti does
not fall back to its OpenAI-only default reranker.
- Drop the ignored `reranker=` kwarg from `_GraphNamespace.search` and
the misleading callers in `zep_tools.py` and
`oasis_profile_generator.py`.
- Refresh `.env.example` to mirror the README env section.
Spec, requirements, and design under
`.kiro/specs/graphiti-neo4j-finalize/`.
Closes#1
Replaces the paid, rate-limited Zep Cloud service with Graphiti (graphiti-core
0.11.6) backed by a local Neo4j instance — free, unlimited, and self-hosted.
Key changes:
- Add GraphitiAdapter: drop-in Zep-compatible wrapper around Graphiti with a
persistent event-loop thread to avoid asyncio/Neo4j driver conflicts
- Switch LLM client to native GeminiClient + GeminiEmbedder (text-embedding-004
fails on Gemini compat endpoint; use google-genai SDK directly)
- Add _GeminiReranker passthrough replacing OpenAIRerankerClient (which
hardcodes gpt-4.1-nano and uses logprobs unsupported by Gemini)
- Fix Cypher queries: use s.uuid/t.uuid for edge source/target instead of
r.source_node_uuid (null property in Graphiti's schema)
- Add ontology-based entity type classifier (_classify_entity_type) so nodes
get colored by type in the D3 graph visualization instead of all being Entity
- Apply classifier in ZepEntityReader so filter_defined_entities finds entities
(previously 0 personas loaded because all labels were ['Entity'])
- Add startup recovery: auto-mark graph_building projects as graph_completed
on backend restart if Neo4j already has their data
- Add resume capability to graph build: skip already-processed episodes after
a restart (断点续传)
- Add non-blocking graph data cache with background refresh in graph.py
- Add EMBEDDING_MODEL config (default: gemini-embedding-001 for Gemini users)
- Add CLAUDE.md with project architecture and dev commands
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Introduced the Report Agent module to facilitate the automatic generation of simulation analysis reports using LangChain and Zep, following the ReACT model.
- Added functionality for report outline planning, segmented content generation, and user interaction through a dialogue interface.
- Implemented new API endpoints for report generation, status checking, and retrieval, enhancing the overall reporting capabilities.
- Updated README.md to include detailed instructions on the new report generation features and API usage.
- Enhanced the project structure to accommodate the new report management functionalities, including report storage and retrieval mechanisms.
- Added support for a `max_rounds` parameter in simulation API, allowing users to limit the number of simulation rounds, improving control over simulation duration.
- Updated README.md to reflect the new `max_rounds` parameter and its usage in simulation requests.
- Enhanced error handling for `max_rounds` input validation to ensure it is a positive integer.
- Modified simulation runner and related scripts to incorporate `max_rounds` functionality, ensuring consistent application across Twitter and Reddit simulations.
- Improved logging to indicate when the number of rounds is truncated due to the `max_rounds` setting, enhancing traceability during simulation execution.
- Updated README.md to include new simulation scripts and configuration details for OASIS, including API retry mechanisms and environment variable settings.
- Added simulation management and configuration generation services to streamline the simulation process across Twitter and Reddit platforms.
- Introduced new API routes for simulation-related operations, including entity retrieval and simulation status management.
- Implemented a robust retry mechanism for external API calls to improve system stability.
- Enhanced task management model to include detailed progress tracking.
- Added logging capabilities for action tracking during simulations.
- Included new scripts for running parallel simulations and testing profile formats.