feat(llm): add Gemini adapter and process book-1-chapter-05
Add GeminiAdapter calling Google's Generative Language REST API (default model: gemini-2.5-flash). Register "gemini" as third provider in the factory and CLI. Add rate-limit retry with exponential backoff to the pipeline's _call_llm helper. Increase default max_tokens from 2000 to 4096. Process book-1-chapter-05 via Gemini free tier — 1 new entity extracted (necessaries-conveniencies-and-amusements-of-life), 41 existing entities correctly skipped by dedup. Canonical set now at 42 unique entities. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
# Markitect Infrastructure Tasks
|
||||
|
||||
Issues discovered while building the infospace-with-history example.
|
||||
These should be addressed in the markitect infrastructure, then the
|
||||
experiment re-run.
|
||||
All three have been fixed in commit `706981c` and the pipeline script
|
||||
refactored to use the fixed infrastructure directly.
|
||||
|
||||
## 1. Artifact Repository does not store content
|
||||
## 1. Artifact Repository does not store content — RESOLVED
|
||||
|
||||
**File:** `markitect/prompts/resolver/resolver.py`, line 147-148
|
||||
**Issue:** `content = f"[Content of {artifact.name} from {space_id}]"` — the
|
||||
@@ -13,10 +13,11 @@ the SQLiteArtifactRepository stores metadata (digest, name, type) but not
|
||||
the content itself.
|
||||
**Impact:** Consumers must maintain their own content cache alongside the
|
||||
repository, defeating the purpose of centralised artifact storage.
|
||||
**Fix:** Add a `content` column to the artifacts table, or use a separate
|
||||
content-addressable store keyed by digest.
|
||||
**Fix applied:** Added `content` field to `Artifact` model, `content TEXT`
|
||||
column to SQLite schema (with migration for existing DBs), and replaced
|
||||
the resolver placeholder with `artifact.content`.
|
||||
|
||||
## 2. ContentMacro raw_text defaults to empty string
|
||||
## 2. ContentMacro raw_text defaults to empty string — RESOLVED
|
||||
|
||||
**File:** `markitect/prompts/templates/models.py`, line 46
|
||||
**Issue:** `raw_text: str = ""` — when macros are constructed programmatically
|
||||
@@ -24,15 +25,15 @@ content-addressable store keyed by digest.
|
||||
ContextCompiler then calls `str.replace("", resolved.content)` which inserts
|
||||
content between every character, producing multi-gigabyte output.
|
||||
**Impact:** Silent data corruption; compiled prompts become unusable.
|
||||
**Fix:** Either require `raw_text` in the constructor, or derive it
|
||||
automatically from `target` (e.g., `raw_text = f"@{{{target}}}"` if not
|
||||
provided).
|
||||
**Fix applied:** Added `__post_init__` to `ContentMacro` that auto-derives
|
||||
`raw_text = f"@{{{self.target}}}"` when not provided.
|
||||
|
||||
## 3. No TemplateAnalyzer support for @{target} syntax
|
||||
## 3. No TemplateAnalyzer support for @{target} syntax — RESOLVED
|
||||
|
||||
**File:** `markitect/prompts/templates/analyzer.py`
|
||||
**Issue:** The TemplateAnalyzer parses `{{kind:target}}` syntax but the
|
||||
**File:** `markitect/prompts/templates/parser.py`
|
||||
**Issue:** The MacroParser parses `{{kind:target}}` syntax but the
|
||||
templates in this example use the simplified `@{target}` syntax. There's
|
||||
no automatic parsing for this format, requiring manual macro construction.
|
||||
**Fix:** Add `@{target}` as a recognised shorthand syntax in the analyzer,
|
||||
auto-detecting it as `{{require:target}}`.
|
||||
**Fix applied:** Added `SHORTHAND_PATTERN` to `MacroParser` that recognises
|
||||
`@{target}` and maps it to `MacroKind.REQUIRED`. Updated `has_macros()`,
|
||||
`count_macros()`, and `find_macro_positions()` accordingly.
|
||||
|
||||
Reference in New Issue
Block a user