fix(extract): disable tools for digest LLM extraction (no error_max_turns) #120
@@ -82,6 +82,7 @@ async def query(
|
||||
system: str | None = None,
|
||||
model: str | None = None,
|
||||
effort: str | None = None,
|
||||
tools: str | None = None,
|
||||
) -> str:
|
||||
"""Send a prompt to Claude Code headless and return the text response.
|
||||
|
||||
@@ -104,6 +105,12 @@ async def query(
|
||||
effort: Optional effort level (``low``/``medium``/``high``/``xhigh``/
|
||||
``max``). When set, passed as ``--effort``. Pairs with ``model``;
|
||||
an empty string is treated as "unset" (CLI default).
|
||||
tools: Optional available-tools spec, passed as ``--tools``. Pass an
|
||||
empty string (``""``) to disable ALL tools — for pure text→JSON
|
||||
extraction the model has no reason to call a tool, and leaving
|
||||
tools enabled makes it occasionally emit ``stop_reason: tool_use``
|
||||
which trips ``--max-turns 1`` → ``error_max_turns`` and forces a
|
||||
retry (slow). ``None`` leaves the CLI default (all tools).
|
||||
|
||||
Returns:
|
||||
The text response from Claude.
|
||||
@@ -126,6 +133,8 @@ async def query(
|
||||
cmd += ["--model", model]
|
||||
if effort:
|
||||
cmd += ["--effort", effort]
|
||||
if tools is not None: # "" → disable all tools (no tool_use → no max-turns trip)
|
||||
cmd += ["--tools", tools]
|
||||
|
||||
size_info = f"; prompt_len={len(full_prompt):,} chars" if len(full_prompt) > 100_000 else ""
|
||||
last_err = "unknown error"
|
||||
@@ -204,13 +213,15 @@ async def query_json(
|
||||
system: str | None = None,
|
||||
model: str | None = None,
|
||||
effort: str | None = None,
|
||||
tools: str | None = None,
|
||||
) -> dict | list | None:
|
||||
"""Send a prompt and parse the response as JSON.
|
||||
|
||||
Uses parse_llm_json for robust parsing (handles markdown wrapping, truncation).
|
||||
``model``/``effort`` are forwarded to :func:`query` (see its docstring).
|
||||
``model``/``effort``/``tools`` are forwarded to :func:`query` (see its docstring).
|
||||
Pure text→JSON extractors should pass ``tools=""`` to avoid ``error_max_turns``.
|
||||
"""
|
||||
raw = await query(prompt, timeout=timeout, system=system, model=model, effort=effort)
|
||||
raw = await query(prompt, timeout=timeout, system=system, model=model, effort=effort, tools=tools)
|
||||
return parse_llm_json(raw)
|
||||
|
||||
|
||||
|
||||
@@ -101,6 +101,8 @@ async def extract(raw_text: str, model: str | None = None) -> dict:
|
||||
result = await claude_session.query_json(
|
||||
user_msg, system=DIGEST_EXTRACTION_PROMPT,
|
||||
model=(model or config.DIGEST_EXTRACT_MODEL or None),
|
||||
tools="", # pure text→JSON: disable tools so the model never emits
|
||||
# stop_reason=tool_use and trips --max-turns (error_max_turns).
|
||||
)
|
||||
except Exception as e: # surfaced as warning, not swallowed silently (§6)
|
||||
logger.warning("digest_metadata_extractor: query failed: %s", e)
|
||||
|
||||
Reference in New Issue
Block a user