Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/connection-edit-sheet-agent-preview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@executor-js/react": patch
---

**The connection edit sheet now previews what agents actually read**

The "What agents see" preview in the connection edit sheet rendered a `- \`<prefix>\` — <description>`inventory line. That line left the`execute`tool description when the inventory was slimmed to bare integration slugs, so the preview showed text no agent reads. The account label was also marked "Display-only", but`connections.list` returns it to agents alongside the description.

The preview now mirrors the `connections.list` item for the connection (`name`, `identityLabel`, `description`), and the sheet copy says that both fields are agent-visible while the callable name stays as it was at connect time.
8 changes: 4 additions & 4 deletions packages/core/sdk/src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ export interface Connection {
/** Callable handle `tools.<integration>.<owner>.<connection>`. Append `.<tool>`
* to reach one of its tools. */
readonly address: ConnectionAddress;
/** Optional human label (which account). Not load-bearing. */
/** Optional human label (which account). Not load-bearing for routing, but
* agent-visible through `connections.list`. */
readonly identityLabel?: string | null;
/** User-curated description of what this connection is for. Agent-visible:
* surfaces next to the connection's prefix in the execute-tool inventory
* and in `connections.list`, so it is the place to give agents context a
/** User-curated description of what this connection is for. Agent-visible
* through `connections.list`, so it is the place to give agents context a
* spec can't (e.g. "the staging CRM — reads only"). */
readonly description?: string | null;
/** Epoch ms when an OAuth access token expires; null/absent for static creds. */
Expand Down
50 changes: 29 additions & 21 deletions packages/react/src/components/metadata-edit-sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,24 @@ import { Textarea } from "./textarea";
// ---------------------------------------------------------------------------
// Metadata edit sheets — the user-curated, AGENT-VISIBLE metadata for an
// integration and for a connection. The point of the sheet (vs. an inline
// input) is the preview: it shows the exact inventory line an agent reads, so
// editing the description is editing what the model sees.
// input) is the preview: it shows the record an agent reads, so editing a
// field is editing what the model sees.
// ---------------------------------------------------------------------------

/** The connection's callable prefix under `tools.`: the path an agent reaches
* this connection's tools through (`tools.<prefix>.<tool>`). The execute tool's
* inventory now lists integrations, not per-connection prefixes. */
const connectionPrefix = (connection: Connection): string => {
const address = String(connection.address);
return address.startsWith("tools.") ? address.slice("tools.".length) : address;
/** The `connections.list` item an agent reads for this connection, reduced to
* the fields the sheet edits. The callable name is fixed at connect time and
* is not editable here; only the label and description are. */
const connectionListItemPreview = (input: {
readonly name: string;
readonly identityLabel: string;
readonly description: string;
}): string => {
const fields = [
`name: ${JSON.stringify(input.name)}`,
...(input.identityLabel ? [`identityLabel: ${JSON.stringify(input.identityLabel)}`] : []),
...(input.description ? [`description: ${JSON.stringify(input.description)}`] : []),
];
return `{ ${fields.join(", ")}, ... }`;
};

function AgentPreview(props: { readonly label: string; readonly line: string }) {
Expand Down Expand Up @@ -88,17 +96,23 @@ export function ConnectionEditSheet(props: {
props.onOpenChange(false);
};

const previewDescription = description.trim().split("\n", 1)[0];
const prefix = connection ? connectionPrefix(connection) : "";
const previewLine = connection
? connectionListItemPreview({
name: String(connection.name),
identityLabel: identityLabel.trim(),
description: description.trim(),
})
: "";

return (
<Sheet open={connection !== null} onOpenChange={props.onOpenChange}>
<SheetContent side="right">
<SheetHeader>
<SheetTitle>Edit connection</SheetTitle>
<SheetDescription>
The description is agent-visible: it rides this connection's prefix in the tool
inventory, so it is the place to say what this credential reaches and how to use it.
Both fields are agent-visible: agents read them from <code>connections.list</code> when
they pick an account, so this is the place to say which account this is and what it is
for.
</SheetDescription>
</SheetHeader>

Expand Down Expand Up @@ -128,18 +142,12 @@ export function ConnectionEditSheet(props: {
disabled={saving}
/>
<p className="text-xs text-muted-foreground">
Display-only; shown in the accounts list instead of the connection name.
Shown in the accounts list instead of the connection name. Agents see it too, but the
callable name stays as it was at connect time.
</p>
</div>

{connection ? (
<AgentPreview
label="What agents see"
line={
previewDescription ? `- \`${prefix}\` — ${previewDescription}` : `- \`${prefix}\``
}
/>
) : null}
{connection ? <AgentPreview label="What agents see" line={previewLine} /> : null}
</div>

<SheetFooter>
Expand Down
Loading