When the LLM returns ontology attributes as plain strings instead of
dicts, set_ontology() crashes with "TypeError: string indices must be
integers, not 'str'" at attr_def["name"].
Two-layer fix:
1. ontology_generator.py: normalize string attrs to {"name", "type",
"description"} dicts during validation, so downstream code always
receives well-formed structures.
2. graph_builder.py: add isinstance guard as a safety net in
set_ontology() for both entity and edge attribute loops.
Co-Authored-By: Octopus <liyuan851277048@icloud.com>
When the LLM generates a <tool_call> block followed by a self-generated
<tool_result> block in the same response, the fake result must be stripped
before appending to message history. The real tool result will be injected
separately by the system.
This fixes a React Hallucination bug where models could fabricate tool
results that didn't actually come from tool invocations.
The API retrieval layer hardcoded reddit as the default platform in 11+ locations. When a Twitter-only simulation was run, all data retrieval APIs silently returned empty results because they looked for reddit_simulation.db which did not exist. This commit reads the simulation enable_twitter/enable_reddit config to determine the correct default platform.
Fixes#150
Previously, the frontend only checked for 'completed' and 'stopped'
status to stop polling. When the simulation process exited with an
error (runner_status === 'failed'), polling continued indefinitely.
This commit adds handling for the 'failed' status:
- Stop polling when runner_status is 'failed'
- Display error message in the log
- Update UI status to 'error'
- Add i18n translations for simFailed key
fetch_all_nodes already had a max_items guard (default 2000) but
fetch_all_edges had no such safeguard, allowing unbounded memory growth
on graphs with large numbers of edges.
Add _MAX_EDGES = 5000 constant and mirror the same loop-guard pattern
from fetch_all_nodes: cap the result list, emit a warning log, and
break pagination once the limit is reached.
Upgrade the transitive Python dependency NLTK from 3.9.2 to 3.10.0 to address CVE-2025-14009. The contributor title said 3.9.3, but the reviewed lockfile resolves 3.10.0.
HistoryDatabase.vue formatDate() derived the day from UTC
(new Date(dateStr).toISOString().slice(0, 10)) while the sibling
formatTime() uses local hours/minutes. The backend sends naive-local
timestamps (datetime.now().isoformat()), so for any non-UTC client the
two disagree by up to a day -- e.g. for the project's UTC+8 audience a
record created 00:00-08:00 local shows the previous day's date next to
the current time. Derive the date from local components so it matches
the time shown.
The Shanda sponsor logo's alt text was `666ghj%2MiroFish | Shanda`,
missing the `F` from the URL-encoded `/`. Every other badge in both
READMEs uses the correct `666ghj%2FMiroFish`. Bring this one in line
with the rest.
- Add return type annotation (list[str]) to Config.validate()
- Add type annotations (msg: str, -> None) to logger convenience functions
- Add FileParser.is_supported() classmethod for checking file format support
The filter was meant to skip the message just pushed by the caller, but
it matches by content, so a repeated message like "tell me more" also
removes the previous turn from the history sent to the backend.
DEBUG defaults to True (FLASK_DEBUG env var is 'True' unless overridden) and the server binds to 0.0.0.0. When debug mode is active, Flask enables the Werkzeug interactive debugger, which allows arbitrary Python code execution via the browser-accessible debugger console if an exception is triggered. Combined with the public bind address this creates a remote code execution vector on any deployment that forgets to set FLASK_DEBUG=False.
Affected files: config.py
Signed-off-by: ChinhLee <76194645+chinhkrb113@users.noreply.github.com>