feat(engine): declare per-harness content-block support and reject unsupported input - #515
feat(engine): declare per-harness content-block support and reject unsupported input#515Zerlight wants to merge 10 commits into
Conversation
|
Your Claude subscription has hit its usage limit. It resets at 11:30am (UTC). Re-trigger Pullfrog after the reset, or add an Add repo secret → · Model settings → · Setup docs → · Ask in Discord →
|
Greptile SummaryThis PR introduces per-harness attachment capabilities, typed attachment refusals, attachment-reference admission, durable reference projection, and last-hop prompt materialization.
Confidence Score: 4/5The PR should not merge until direct inline prompts enforce the advertised per-harness image-count limit; readonly-file conversion should also be completed or withheld. A reachable Files Needing Attention: packages/host/engine/src/attachment/admit.ts, packages/host/engine/src/attachment/materializer.ts
|
| Filename | Overview |
|---|---|
| packages/foundation/schema/src/model/attachment.ts | Defines attachment capability limits, open representation values, host intersections, and attachment URI helpers. |
| packages/foundation/schema/src/model/agent/input.ts | Adds the per-agent attachment capability matrix and effective host/adapter intersection. |
| packages/host/engine/src/attachment/admit.ts | Adds stored-reference and inline-content admission, but the reachable inline path does not enforce the declared image-count limit. |
| packages/host/engine/src/attachment/materializer.ts | Materializes inline images and readonly hardlinks, although readonly blocks cannot yet cross the final ContentBlock conversion. |
| packages/host/engine/src/session/lifecycle-service.ts | Integrates attachment admission before intent persistence and materialization before adapter dispatch. |
| packages/host/engine/src/session/session-input-dispatcher.ts | Applies inline capability checks and supports separate echo and materialized adapter inputs. |
| packages/host/engine/src/conversation/turn-service.ts | Projects durable attachment references into byte-free conversation resource links. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
C[Client prompt] --> G{Input path}
G -->|turn.submit| A[Load and admit attachment refs]
G -->|agent.input| I[Validate inline blocks]
A --> P[Persist prompt refs]
P --> M[Materialize stored bytes]
I --> D[Session dispatcher]
M --> D
D --> B[Agent adapter]
P --> R[conversation.read projection]
R --> L[resource_link without bytes]
B --> X[Run ends]
X --> K[Clean materialized files]
Reviews (1): Last reviewed commit: "fix(engine): project the attachment kind..." | Re-trigger Greptile
071ef0e to
9448836
Compare
There was a problem hiding this comment.
Greptile has paused reviews on this repository — it used its 100 free open-source review credits for this billing period. Reviews resume automatically on September 23. To continue before then, an organization admin can keep reviews running past the free credits — those bill as normal usage.
|
Your Claude subscription has hit its usage limit. It resets at 11:30am (UTC). Re-trigger Pullfrog after the reset, or add an Add repo secret → · Model settings → · Setup docs → · Ask in Discord →
|
…e undeclared blocks
A closed enum inside capabilities-update makes the whole agent.event frame invalid-payload for a peer that has not learned a newer representation, dropping the session's capability stream. Kinds were already open; representations now match, and the host intersection drops what it cannot materialize.
…t caps Admit deduped ids before accounting while the materializer converts one block per ref, so a repeated ref escaped the 12 MiB aggregate: 500 refs to one 8 MiB image admitted at '8 MiB, 1 image' and materialized 4 GiB. The caps now bound what actually leaves the store. A projected attachment: link is also refused by name instead of as a file attachment.
A prompt may name one attachment twice in a run, and the destination is content-addressed, so an existing hardlink is already the same bytes; EEXIST was failing the turn as a filesystem error. Cleanup failures no longer vanish into a bare noop.
Both shipped resource_link renderers prefer title over name, so carrying the kind there labelled every attachment chip 'image' instead of its filename. The projection assertions also sat behind an early return that let them skip silently.
9448836 to
255e72d
Compare
|
Your Claude subscription has hit its usage limit. It resets at 11:30am (UTC). Re-trigger Pullfrog after the reset, or add an Add repo secret → · Model settings → · Setup docs → · Ask in Discord →
|
|
Review round on this PR (Greptile, two inline threads), both fixed on the top of the stack in a8c1bb4: legacy |

Summary
Phase 3 of CODE-627 — Conversation turn graph & immutable attachment store. Linear: https://linear.app/arcbox/issue/CODE-625/featengine-declare-per-harness-content-block-support-and-reject
Stack: #514 ← this PR (
ruocheng/code-625, baseruocheng/code-636) ← #516. Merge bottom-up; this PR's diff is only its own commits.AttachmentCapabilityper harness (effective = host limits ∩ adapter declaration) with typedunsupported_attachmentrefusals at the admit step, before anything is persisted, and thePreparedPromptmaterializer — the only place bytes leave the store — producing inline images or read-only file projections per declared representation. Admitted refs are persisted and projected without bytes.Commits
Verification
Every commit passed
pnpm check:ciandpnpm testat its own tip; the stack tip (1d942a62; the same tree as the originally gated73fc5ff2plus the two review fixes below on 628/629) is atpnpm check:ci0 errors,pnpm test3408 passed / 1 skipped. Adversarial reviewers (one per axis, isolated read-only worktrees) reviewed the branch; each P1/P2 was reproduced with a failing test or a probe step before its fix — the round-by-round record is in the Linear issue's comments.Checklist
pnpm check:ciandpnpm testboth pass (no Rust changes)AGENTS.mdand module docs in this branch)