turnstone/app/services
pyr0ball 8849f3aa22 fix(hypothesizer): extract first JSON array to handle reasoning model double-output
Reasoning models (e.g. foundation-sec-8b) emit valid JSON then repeat it
inside a markdown fence block. json.loads() fails on the combined text.

extract_first_json_array() scans for the first '[' and walks to its
matching ']' with proper string/escape/nesting handling, then returns
just that slice. Combined with strip_json_fences(), this handles all
observed output patterns:
  - bare JSON array (standard models)
  - fenced JSON array (fence-wrapping models)
  - bare array followed by fenced repeat (reasoning models)
2026-05-25 21:01:14 -07:00
..
diagnose fix(hypothesizer): extract first JSON array to handle reasoning model double-output 2026-05-25 21:01:14 -07:00
__init__.py feat: initial Turnstone POC — ingest, FTS search, MCP server 2026-05-08 12:12:34 -07:00
blocklist.py fix(blocklist): get_candidate for O(1) push/unblock, 400 on malformed device_names JSON 2026-05-15 21:19:02 -07:00
embeddings.py refactor: extract embeddings service layer — decouple context embedder from Ollama 2026-05-25 11:01:25 -07:00
incidents.py refactor: rename ingest → glean throughout codebase 2026-05-20 23:02:55 -07:00
llm.py feat: inject environment context into diagnose pipeline and LLM prompt 2026-05-13 16:29:26 -07:00
models.py refactor: rename ingest → glean throughout codebase 2026-05-20 23:02:55 -07:00
pihole.py feat(blocklist): 6 REST endpoints + Pi-hole settings fields 2026-05-15 21:15:09 -07:00
search.py refactor: rename ingest → glean throughout codebase 2026-05-20 23:02:55 -07:00