Skip to content

RS-LoCoMo-Full-v3: strict-representable agent step - #145

Merged
fazpu merged 2 commits into
mainfrom
fix/answer-step-strict-schema
Jul 26, 2026
Merged

RS-LoCoMo-Full-v3: strict-representable agent step#145
fazpu merged 2 commits into
mainfrom
fix/answer-step-strict-schema

Conversation

@fazpu

@fazpu fazpu commented Jul 26, 2026

Copy link
Copy Markdown
Member

Problem

The first answer-stage execution against a real provider failed all 8 questions identically:

HTTP 400 (Azure): Invalid schema for response_format 'AnswerAgentStep':
In context=('properties','arguments'), 'additionalProperties' is required
to be supplied and to be false.

AnswerAgentStep.arguments was a free-form dict[str, object]. Strict mode requires every schema object closed — and closing an object with no properties would forbid all content. A free-form object is unrepresentable under strict structured output. The providers that accepted v2's schema were precisely the ones not enforcing strict mode (design §2.4).

Fix, probed live before implementing

Tool arguments travel as arguments_json — one JSON object encoded as a string. A live probe of the exact shape: Azure accepts it, and at temperature 0 gpt-4o-mini immediately showed why the inner parse must be lenient:

"arguments_json":"{\"query\":\"Where did Caroline go?\"}."
                                                        ^ period inside the string

The loop takes the first complete JSON object and records any trailing text on the trace row (arguments_trailing) — syntax noise neither reads as a retrieval failure nor vanishes.

Guard

_strict_json_schema now refuses to send any strict schema containing an open object, failing at build time with a clear message instead of on the first compliant provider in production. A test proves no HTTP happens for an invalid schema. AnswerAgentStep was the only provider-bound model with a free-form dict (DecisionRecord.edit_detail is persistence-only — checked all 15 response_type= call sites).

Protocol

v2 → v3 per the design's own rule (schema + prompt changed). No v2 score ever existed. Design §2.4 gains the two new verified observations (strict enforced only by some providers; string contamination), §7 records the parse rule, D78 carries a dated amendment.

Validation

pyright 0 errors; 585 passed, 310 skipped; ruff clean. New tests: trailing-junk parse with recorded leftover, non-object rejection, answer steps ignoring the field, build-time guard.

Contributor agreement

The first answer-stage execution against a real provider failed all eight
questions identically: Azure, serving gpt-4o-mini, rejected the request with
HTTP 400 — "Invalid schema for response_format 'AnswerAgentStep': in
('properties','arguments'), 'additionalProperties' is required to be supplied
and to be false." AnswerAgentStep.arguments was a free-form dict; pydantic
renders it as an open object; strict mode requires every object closed; and
closing an object with no properties would forbid all content. A free-form
object is therefore unrepresentable under strict structured output. The
providers that accepted v2's schema were the ones not enforcing strict mode at
all (design §2.4).

Tool arguments now travel as arguments_json, one JSON object encoded as a
string. Probing the shape live: Azure accepts the schema, and at temperature 0
gpt-4o-mini immediately demonstrated why the inner parse must be lenient — it
appended a sentence period inside the string, after the closing brace. The loop
takes the first complete JSON object and records any trailing text on the trace
row, so syntax noise neither reads as a retrieval failure nor vanishes.

The adapter now refuses to send a strict schema containing an open object,
failing at build time with a clear message instead of on the first compliant
provider in production. AnswerAgentStep was the only provider-bound model with
a free-form dict (DecisionRecord.edit_detail is persistence-only).

Protocol bumped v2 -> v3 per the design's own rule; no v2 score ever existed.
Design §2.4 gains the two new verified observations, §7 records the parse rule,
and D78 carries a dated amendment.

Validation: pyright 0 errors, 585 passed, ruff clean. New tests: trailing-junk
parse with recorded leftover, non-object rejection, answer steps ignoring the
field, and the guard proving no HTTP happens for an invalid schema.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GKENhTLJg1HqhbdwCmmkbc
@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  src/rememberstack/adapters
  openrouter.py
Project Total  

This report was generated by python-coverage-comment-action

Grok review of the v3 change, all non-blocking, applied anyway: the open-object
guard now raises a dedicated StrictSchemaError so a programmer schema
regression is never mistaken for a flaky model reply by broad except blocks;
parsed_arguments gains parametrized edge cases (empty, whitespace, nesting,
unicode, fragments, non-objects); the WP-8.2 parenthetical now names both D78
amendments instead of only the judge story.

Validation: pyright 0 errors, 586 passed, ruff clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GKENhTLJg1HqhbdwCmmkbc
@fazpu
fazpu merged commit 077bd50 into main Jul 26, 2026
6 checks passed
@fazpu
fazpu deleted the fix/answer-step-strict-schema branch July 26, 2026 10:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant