Skip to content

Prompt assembly merges tool definitions discovered via readRealmFile#5485

Open
lukemelia wants to merge 3 commits into
cs-12045-readrealmfile-file-meta-for-mdfrom
cs-12046-prompt-merges-discovered-tool-definitions
Open

Prompt assembly merges tool definitions discovered via readRealmFile#5485
lukemelia wants to merge 3 commits into
cs-12045-readrealmfile-file-meta-for-mdfrom
cs-12046-prompt-merges-discovered-tool-definitions

Conversation

@lukemelia

Copy link
Copy Markdown
Contributor

Linear: CS-12046

Stacked on #5484 (readRealmFile file-meta reads) — the pull model's prompt-injection leg. Tools discovered by reading a skill file become callable on the model's next generation, sourced from room events — the same event-sourcing every other prompt input uses, so it's replay-correct and inspectable.

Behavior

  • Fulfillment (read-realm-file-fulfillment.ts): each read skill's usable tool entries — those with a well-formed, index-stamped LLM definition — are embedded on the read's command-result event as data.discoveredTools, each tagged with sourceSkillUrl (the execution leg verifies calls against the declaring skill's indexed frontmatter). Entries without a definition (a skill indexed before schema enrichment) are dropped. attachedFiles is untouched — the attachment-download path and timeline rendering see exactly the event shape they saw before, and tool-less reads publish byte-identical data.
  • getTools (runtime-common/ai/prompt.ts) gains a third source: it scans tool-result events for data.discoveredTools and merges the definitions into the tool map first, so an enabled skill's uploaded definition or a message-context tool with the same functionName wins on conflict. A skill read many times contributes only its latest read's definitions — wholesale, so a tool the skill no longer declares disappears. A skill listed in disabledSkillCards contributes none.
  • Event type: DiscoveredToolDefinition on ToolResultWithOutputContent.data (matrix-event.gts), riding the existing data JSON-stringify/parse wire path (sendMatrixEvent / constructHistory).

Testing

ai-bot suite (240 passing; the 2 failures are the pre-existing locking tests needing a CI-provisioned Postgres role):

  • fulfillment: a skill read embeds stamped definitions tagged with the skill URL and drops unstamped entries; tool-less reads carry no discoveredTools key.
  • getTools: discovered tools are offered on later turns; the latest read of a skill wins wholesale; a disabled skill contributes nothing; a skill both enabled and read yields one definition with the uploaded one winning; definitions round-trip the encode/decode path via constructHistory.

🤖 Generated with Claude Code

Tools discovered by reading a skill file become available to the model on
the next generation, sourced from room events like every other prompt
input — replay-correct and inspectable.

The readRealmFile fulfillment embeds each read skill's usable (schema-
stamped) tool entries on the result event as data.discoveredTools, each
tagged with the source skill URL so the execution leg can verify calls
against the declaring skill's indexed frontmatter. Entries without a
well-formed definition are dropped; tool-less reads publish exactly the
same event shape as before, and attachedFiles is untouched so the
attachment-download path and timeline rendering are unchanged.

getTools gains a third source: tool-result events' discoveredTools, merged
into the tool map before the enabled-skill and message-context sources so
those win on functionName conflict. A skill read many times contributes
only its latest read's definitions (the file may have changed between
reads), and a skill disabled in room state contributes none.

CS-12046

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends prompt assembly so that tool definitions discovered via readRealmFile (from skill markdown file-meta frontmatter) are persisted on tool-result events and then merged into getTools on subsequent turns, making the behavior fully event-sourced and replayable from room history.

Changes:

  • Embed index-stamped tool definitions from readRealmFile results as data.discoveredTools on tool-result events (tagged with sourceSkillUrl).
  • Teach getTools to scan tool-result events for discoveredTools and merge them into the tool map ahead of uploaded skill tools and message-context tools.
  • Add ai-bot tests covering fulfillment embedding/dropping, precedence/wholesale replacement rules, disabled-skill filtering, and JSON encode/decode round-trip.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/runtime-common/ai/prompt.ts Adds discoveredTools as a third getTools source and defines conflict/precedence behavior.
packages/base/matrix-event.gts Introduces DiscoveredToolDefinition and adds data.discoveredTools to tool-result event payload typing.
packages/ai-bot/lib/read-realm-file-fulfillment.ts Extracts usable stamped tool definitions from read results and publishes them on tool-result events (without changing attachment shape).
packages/ai-bot/tests/read-realm-file-fulfillment-test.ts Tests that fulfillment embeds stamped definitions and omits the key for tool-less reads.
packages/ai-bot/tests/prompt-construction-test.ts Tests getTools discovery behavior, precedence, disabled-skill behavior, and encode/decode round-trip via constructHistory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/runtime-common/ai/prompt.ts
Comment thread packages/runtime-common/ai/prompt.ts
@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Host Test Results

    1 files      1 suites   2h 58m 24s ⏱️
3 470 tests 3 455 ✅ 15 💤 0 ❌
3 489 runs  3 474 ✅ 15 💤 0 ❌

Results for commit 33223d5.

Realm Server Test Results

    1 files      1 suites   11m 27s ⏱️
1 816 tests 1 816 ✅ 0 💤 0 ❌
1 895 runs  1 895 ✅ 0 💤 0 ❌

Results for commit 33223d5.

Only the bot publishes readRealmFile results, so discovered definitions on
anyone else's tool-result event are ignored; and an entry only counts when
its definition is a well-formed function tool (type plus function.name),
not just any object with a nested name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A failed or invalid readRealmFile result is not evidence the skill was
fetched, so its discoveredTools claim is ignored.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lukemelia lukemelia requested review from a team and jurgenwerk July 13, 2026 21:00
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.

3 participants