Extract parse_azure_url from graphiti_backend into utils/llm_client so all
services (oasis_profile_generator, simulation_config_generator, graphiti_backend,
LLMClient) strip the /chat/completions suffix and api-version before passing
base_url to the OpenAI SDK, fixing 404 errors when the full Azure endpoint URL
is set in LLM_BASE_URL.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous fix applied _flatten_attributes too broadly, breaking graphiti's
internal ExtractedEntities validation (lists were converted to strings).
Instead, monkey-patch only _extract_entity_attributes — the exact function
that returns entity attribute dicts to node.attributes before Neo4j write.
Lists of primitives are preserved; only dict-valued attributes are flattened.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Graphiti's attribute extraction LLM sometimes returns values wrapped in
nested dicts ({"value": "CTTI"}) instead of plain strings. Neo4j rejects
these with TypeError: "Property values can only be of primitive types".
Fix: after _AzureGenericClient gets the LLM response, validate it through
the Pydantic response_model and call _flatten_attributes() so every value
reaching Neo4j is a scalar. Also add _flatten_attributes() helper.
UI: exclude 'summary' from the Properties section of the node detail panel
since it already appears in the dedicated Summary section below.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Revert default limits back to 10 edges and 12 entities (10 specific + 2
fallback), matching Zep Cloud's maximum. Expose ONTOLOGY_MAX_ENTITY_TYPES
and ONTOLOGY_MAX_EDGE_TYPES in Config so operators can override without
touching code. Prompts now inject the live values at request time.
Also replace Chinese comments in .env.example with English equivalents.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ontology_generator: increase entity limit to 20 (18 specific + 2 fallback),
edge types to 20 (12-20 requested); bump max_tokens to 8192
- ontology_generator: fallback type names (Person/Organization) now resolved
via i18n so Catalan gets Persona/Organització
- locales: add ontologyFallback* keys to en/zh/es/ca
- graph_builder: pass entity/edge attributes to non-Zep set_ontology (were discarded)
- graphiti_backend: _make_model builds real Pydantic fields per attribute
- graphiti_backend: _build_extraction_instructions includes per-entity attribute
hints so the LLM knows which fields to extract
- graphiti_backend: add_batch retries up to 3x on "node not found" race condition
with exponential backoff (2s, 4s) before propagating the error
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Dockerfile installs graphiti optional extras so any GRAPH_BACKEND works at runtime
- container-app.bicep adds graphBackend, neo4jUri/User/Password and llmProvider params
- 2-build-deploy.sh validates graph backend config and passes all new vars to Bicep
- config.sh.example documents new variables with inline guidance
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add commented sections for the new pluggable graph backend and Gemini
LLM provider options so users know what variables are available.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When LLM_PROVIDER=gemini, LLMClient automatically uses the Google AI Studio
OpenAI-compatible endpoint instead of requiring manual base_url configuration.
An explicit base_url argument still takes precedence.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace hardcoded English strings (GENERATED ENTITY TYPES, ATTRIBUTES,
EXAMPLES, etc.) and the Uploading message with i18n keys.
Add corresponding translations to all 4 locale files (ca/en/zh/es).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Translate all Chinese comments, docstrings, log messages, error messages,
and LLM prompt text to English across the entire backend codebase.
Locale translation files (locales/*.json) are unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
gunicorn was declared in pyproject.toml but missing from uv.lock,
so `uv sync --frozen` in the Dockerfile never installed it and the
container crashed with 'no such file or directory' on startup.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Simplifies infrastructure: ACR + Container Apps Environment only.
Log Analytics can be added later if observability is needed.
Update INSTALL.md accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add locales/es.json with 646 keys (neutral Spanish, based on upstream PR #510)
- Add locales/ca.json with 646 keys (standard Catalan, full translation)
- Add README-ES.md and README-CA.md with complete project documentation
- Update locales/languages.json with ca entry and llmInstruction
- Update README.md language switcher links
Both locales integrate automatically with the existing i18n architecture:
UI labels, progress messages, console logs, and LLM prompt instructions
all respect the user's selected language end-to-end.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add sans-serif font for English left-pane (status, workflow sections)
- Shorten English workflow step descriptions
- Reduce English report title font-size from 36px to 28px
- Use sans-serif font for English titles, descriptions and navbar
- Shorten English hero text to avoid overflow
- Fix :global() scoped CSS issue that was setting root font-size to 3.5rem
- Use separate unscoped style block for html[lang] selectors
Background threads (graph building, simulation prep, report generation,
profile generation) now inherit the requesting user's locale preference.
Previously these fell back to 'zh' because Flask request context was
unavailable in spawned threads.