Repository navigation
refactor(ai): remove unused metadata fields - #61018
Conversation
There was a problem hiding this comment.
The change looks sound to me. I found no remaining readers of the removed fields in packages/ai or packages/core. The kept MediaPart.metadata and SystemPart.metadata are still read where expected. A stored Message whose message and text part carry the old metadata still decodes, with the extra keys dropped. The changed tests pass, and typecheck:tsc is clean in ai, core and plugin.
Public API (breaking for @opencode/ai users and plugins):
Message.metadata: removedTextPart.metadata: removed (core no longer writesmetadata.attachmentto it)ToolCallPart.metadata,ToolResultPart.metadata,ReasoningPart.metadata: removedToolDefinition.metadata: removedLLMRequest.metadataand themetadatarequest input: removedMediaPart.metadata: kept, but core no longer writesdescriptioninto it
Plugins get these objects through SessionRequest.messages, which the session request, context and compaction hooks expose. A plugin that read message.metadata (session metadata or agents) or metadata.attachment on text parts now gets undefined. TypeScript callers that set these fields get a compile error. Old stored data still decodes.
No other concerns.
5719409 to
abfde36
Compare
There was a problem hiding this comment.
This push only rebases the change onto newer dev; the patch is identical to the one I reviewed. The new code from dev doesn't read any of the removed fields. typecheck:tsc is clean in ai, core and plugin, and the changed tests pass.
The public API impact is the same as before. metadata is removed from Message, TextPart, ToolCallPart, ToolResultPart, ReasoningPart, ToolDefinition and LLMRequest. This breaks plugins and SDK callers that set or read those fields. Old stored data still decodes.
No new concerns.
abfde36 to
baf7901
Compare
There was a problem hiding this comment.
This push only rebases the change onto newer dev; the patch is identical to the one I reviewed. typecheck:tsc is still clean in ai, core and plugin, and the changed tests pass.
The public API impact is the same as before. metadata is removed from Message, TextPart, ToolCallPart, ToolResultPart, ReasoningPart, ToolDefinition and LLMRequest. This breaks plugins and SDK callers that set or read those fields. Old stored data still decodes.
No new concerns.
…penCode 2.2.6) (#1350) ## Problem On OpenCode 2.2.6, scheduled Mission wakes no longer start their passage. Upstream anomalyco/opencode#61018 removed the `metadata` copy from the LLM messages plugins see in session context hooks. CodeNomad classified wakes from `metadata.schedule` on that projection, so a 2.2.6 wake looked inconsistent: the drain failed with `schedule-carrier-wake` and the passage was never admitted. ## Fix The context projection still carries each native message `id`, and the stored native message still carries `metadata.schedule`. Wake classification now resolves user-role context IDs through the existing bounded native message reader and classifies the authoritative stored records by type and status, ignoring projected metadata. Resolved records are reused for the candidate proof, so a wake row is read once. Classification and recovery reads have separate read and byte budgets, and exceeding a bound surfaces a coverage error instead of dropping the wake. Placement, mapping, deterministic identities, source-byte fences, RPC checks and CAS/high-water behavior are unchanged. The minimum stays 2.2.3. The canonical authority and bounds contract is in `dev-docs/MISSIONS_NATIVE_SCHEDULE_TRANSPORT.md`. Native facts, checked on isolated CLIs: | CLI | Context message ID | Context `metadata.schedule` | Stored `metadata.schedule` | |---|---|---|---| | 2.2.3 | kept | present | present | | 2.2.5 | kept | present | present | | 2.2.6 | kept | absent | present | ## Tests - Unit coverage for metadata-free and conflicting projections, notices, compactions, invalid native records, a context of 128 wake entries, eight recovery reads and independent byte budgets. - `tests-runtime-contracts` gains a native context/storage check and the cold scheduled-Mission product check on minimum and latest, and uploads the fixtures' receipts and failure diagnostics when a step fails. The schedule fixtures read the actual CLI version instead of a hardcoded 2.2.3, poll for the PID-matching ready registration, and set the `at` time after activation, just before Play. The cold wait allows 120 s (leader-lease recovery exceeds 45 s on dev too). - On 2.2.6, an `origin/dev` snapshot fails the cold product check (`schedule-carrier-wake`); this branch passes `at` and `in` with the exact CI command (product step: 102 s on 2.2.3, 208 s on 2.2.6). - Foundation fixtures pass on 2.2.3 and 2.2.6 (3 CAS applications, cold recovery, no provider requests); an earlier revision also passed them on 2.2.5. Server Missions suites: 1,406 passed. Server/UI typechecks and native bundle builds pass. The full runtime-contract sequence passes locally on 2.2.3 (15 min) and 2.2.6 (23 min 26 s, against the job's 25-minute timeout). ## Known limitation `experimental.part_rows` (off by default) stores assistant parts in `session_part`, which CodeNomad's history, search, outline, gallery and pruning readers do not read. Documented in `dev-docs/SESSION_HISTORY_QUERIES.md`, not addressed here.
Problem
@opencode/aihad a free-formmetadatabag on almost every message type. Most of them were never read by the package or anything else. Core copied its own session metadata into some of them, but nothing read it back.Change
Removed the
metadatafields nothing reads, and the writes that fed them.Message.metadataTextPart.metadataToolCallPart.metadataToolResultPart.metadataToolResultPart.makeReasoningPart.metadataToolDefinition.metadataLLMRequest.metadataSystemPart.metadataMediaPart.metadatafile_id, citations, title, context, transformations)descriptioninto itStored native compaction windows that contain the removed fields still decode. The extra keys are dropped.
Breaking change
@opencode/aiis published, and plugins receiveMessageand part objects through session hooks. Code that sets or reads the removed fields needs to drop them.Out of scope
MediaPart.metadatato a typed provider option.Verification
bun testinpackages/ai(2013 passed, 0 failed)bun run script/test.tsinpackages/core(7188 passed; 3 shell tests fail the same way ondevlocally)bun run typecheck:tscinpackages/aiandpackages/corebun run checkfrom repo root (35/35)Added by the opencode bot (AI-generated).
Public API: removes
metadatafrom @opencode/ai Message, TextPart, ToolCallPart, ToolResultPart, ReasoningPart, ToolDefinition and LLMRequest (breaking for plugins and SDK callers that set or read it)