Skip to content

WIP: fix refresh extension not working#2170

Open
NKoech123 wants to merge 1 commit into
mainfrom
ai_main_21c4f7f91cd44797a402
Open

WIP: fix refresh extension not working#2170
NKoech123 wants to merge 1 commit into
mainfrom
ai_main_21c4f7f91cd44797a402

Conversation

@NKoech123

@NKoech123 NKoech123 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds two new agent actions, extension-data-set and extension-data-get, that let the agent directly read and write an extension's tool_data store without going through the iframe bridge or raw SQL.

Problem

Agents had no reliable way to refresh data used by an extension (e.g. a dashboard) from the agent side. The only path was routing through the sandboxed iframe bridge or raw SQL, which is not accessible/safe for agent-driven updates, making it impossible for the agent to seed or refresh data that an extension reads via extensionData.get() at render time.

Solution

Introduce two dedicated actions that wrap access-controlled reads/writes to the tool_data table, allowing an agent to fetch fresh data from providers and persist it directly for an extension to pick up on next load.

Key Changes

  • Added extension-data-set action: upserts an item into an extension's data store (tool_data), enforcing editor access, a 1MB payload size limit, and scope (user or org) handling with Postgres/SQLite-compatible upsert conflict clauses.
  • Added extension-data-get action: reads a single item or lists items from an extension's data store, enforcing viewer access, with support for user, org, or all scope filtering and a configurable result limit.
  • Both actions call ensureExtensionsTables() before executing and use resolveAccess to enforce permission checks tied to the extension.
  • Updated SKILL.md documentation to describe the new agent-side extension data access pattern, including guidance that this is the correct path for agent-driven dashboard refreshes.

Edit in Builder  Preview


To clone this PR locally use the Github CLI with command gh pr checkout 2170

You can tag me at @BuilderIO for anything you want me to fix or change

@builder-io-integration builder-io-integration Bot changed the title Update from the Builder.io agent Add agent-side actions to read/write extension data Jul 15, 2026
@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@NKoech123 NKoech123 changed the title Add agent-side actions to read/write extension data WIP: fix refresh extension not working Jul 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Here's a visual recap of what changed:

Visual recap

Open the full interactive recap

@builder-io-integration builder-io-integration Bot 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.

Builder reviewed your changes and found 2 potential issues 🔴

Review Details

Code Review Summary

PR #2170 adds two agent-facing actions for extension tool_data: an access-controlled upsert and a scoped read/list operation, plus guidance in the extensions skill. The implementation uses parameterized SQL, ensures the extension tables exist, enforces editor/viewer access, caps individual writes at 1 MiB, and supports both PostgreSQL and SQLite conflict syntax. The overall architecture is appropriate and avoids exposing raw SQL or iframe bridge details to the agent.

Risk level: High, because this change introduces security-sensitive scoped reads and persistent data mutation.

Key Findings

  • 🔴 HIGHextension-data-get does not reject scope="org" when no organization context exists; it queries using an empty organization id instead of failing closed.
  • 🟡 MEDIUM — List responses are limited by row count but not aggregate size, so 1,000 individually valid 1 MiB values can create an excessively large agent result and exhaust serialization/context resources.

🧪 Browser testing: Skipped — PR only modifies backend action wiring and agent documentation, with no user-facing UI changes.

: `AND scope = 'user' AND lower(owner_email) = ?`;
const scopeArgs =
scope === "org"
? [orgId ?? ""]

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.

🔴 Reject organization reads without organization context

When scope="org", this path passes orgId ?? "" to SQL without first requiring an organization context. Fail closed as extension-data-set does; otherwise org-scoped reads from a non-org context can silently query an invalid scope and may expose rows if empty/null organization identifiers exist.

Additional Info
Found by one code-review agent; matches the existing validation pattern in extension-data-set and extension routes.

Fix in Builder

Comment on lines +952 to +957
return {
extensionId,
collection,
scope,
count: result.rows?.length ?? 0,
items: result.rows ?? [],

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.

🟡 Bound list responses by aggregate size

The list operation caps rows at 1,000 but has no aggregate response-size limit, while each stored value may be up to 1 MiB. A populated collection can therefore produce a very large agent tool result, exhausting serialization or model context resources; add a byte/character cap or return a bounded, explicitly truncated result.

Additional Info
Found by one code-review agent; based on the 1 MiB per-item write limit and 1,000-item read limit.

Fix in Builder

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.

2 participants