History

Preview the connections.list item in the connection edit sheet (#1746)

The "What agents see" preview rendered a `- \`<prefix>\` — <description>` inventory line. That line left the execute description in #1230, 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 next to the description. Render the `connections.list` item (name, identityLabel, description) in the preview, say in the sheet copy that both fields are agent-visible, and note that the callable name stays fixed at connect time.

Sergiy Dybskiy committed 2 months ago

Commit 9dff4e81 parent b83999f3 files · +42 −25Browse files

Unified · Split

3 files
  1. .changeset/connection-edit-sheet-agent-preview.md +9 −0
  2. packages/core/sdk/src/connection.ts +4 −4
  3. packages/react/src/components/metadata-edit-sheet.tsx +29 −21
.changeset/connection-edit-sheet-agent-preview.md+9−0
@@ -0,0 +1,9 @@
1---
2"@executor-js/react": patch
3---
4
5**The connection edit sheet now previews what agents actually read**
6
7The "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.
8
9The 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.
packages/core/sdk/src/connection.ts+4−4
@@ -31,11 +31,11 @@ export interface Connection { · 30 unmodified lines
31 /** Callable handle `tools.<integration>.<owner>.<connection>`. Append `.<tool>`31 /** Callable handle `tools.<integration>.<owner>.<connection>`. Append `.<tool>`
32 * to reach one of its tools. */32 * to reach one of its tools. */
33 readonly address: ConnectionAddress;33 readonly address: ConnectionAddress;
34 /** Optional human label (which account). Not load-bearing. */34 /** Optional human label (which account). Not load-bearing for routing, but
35 * agent-visible through `connections.list`. */
35 readonly identityLabel?: string | null;36 readonly identityLabel?: string | null;
36 /** User-curated description of what this connection is for. Agent-visible:37 /** User-curated description of what this connection is for. Agent-visible
37 * surfaces next to the connection's prefix in the execute-tool inventory38 * through `connections.list`, so it is the place to give agents context a
38 * and in `connections.list`, so it is the place to give agents context a
39 * spec can't (e.g. "the staging CRM — reads only"). */39 * spec can't (e.g. "the staging CRM — reads only"). */
40 readonly description?: string | null;40 readonly description?: string | null;
41 /** Epoch ms when an OAuth access token expires; null/absent for static creds. */41 /** Epoch ms when an OAuth access token expires; null/absent for static creds. */
packages/react/src/components/metadata-edit-sheet.tsx+29−21
@@ -25,16 +25,24 @@ import { Textarea } from "./textarea"; · 24 unmodified lines
25// ---------------------------------------------------------------------------25// ---------------------------------------------------------------------------
26// Metadata edit sheets — the user-curated, AGENT-VISIBLE metadata for an26// Metadata edit sheets — the user-curated, AGENT-VISIBLE metadata for an
27// integration and for a connection. The point of the sheet (vs. an inline27// integration and for a connection. The point of the sheet (vs. an inline
28// input) is the preview: it shows the exact inventory line an agent reads, so28// input) is the preview: it shows the record an agent reads, so editing a
29// editing the description is editing what the model sees.29// field is editing what the model sees.
30// ---------------------------------------------------------------------------30// ---------------------------------------------------------------------------
31 31
32/** The connection's callable prefix under `tools.`: the path an agent reaches32/** The `connections.list` item an agent reads for this connection, reduced to
33 * this connection's tools through (`tools.<prefix>.<tool>`). The execute tool's33 * the fields the sheet edits. The callable name is fixed at connect time and
34 * inventory now lists integrations, not per-connection prefixes. */34 * is not editable here; only the label and description are. */
35const connectionPrefix = (connection: Connection): string => {35const connectionListItemPreview = (input: {
36 const address = String(connection.address);36 readonly name: string;
37 return address.startsWith("tools.") ? address.slice("tools.".length) : address;37 readonly identityLabel: string;
38 readonly description: string;
39}): string => {
40 const fields = [
41 `name: ${JSON.stringify(input.name)}`,
42 ...(input.identityLabel ? [`identityLabel: ${JSON.stringify(input.identityLabel)}`] : []),
43 ...(input.description ? [`description: ${JSON.stringify(input.description)}`] : []),
44 ];
45 return `{ ${fields.join(", ")}, ... }`;
38};46};
39 47
40function AgentPreview(props: { readonly label: string; readonly line: string }) {48function AgentPreview(props: { readonly label: string; readonly line: string }) {
@@ -88,8 +96,13 @@ export function ConnectionEditSheet(props: { · 47 unmodified lines
88 props.onOpenChange(false);96 props.onOpenChange(false);
89 };97 };
90 98
91 const previewDescription = description.trim().split("\n", 1)[0];99 const previewLine = connection
92 const prefix = connection ? connectionPrefix(connection) : "";100 ? connectionListItemPreview({
101 name: String(connection.name),
102 identityLabel: identityLabel.trim(),
103 description: description.trim(),
104 })
105 : "";
93 106
94 return (107 return (
95 <Sheet open={connection !== null} onOpenChange={props.onOpenChange}>108 <Sheet open={connection !== null} onOpenChange={props.onOpenChange}>
@@ -97,8 +110,9 @@ export function ConnectionEditSheet(props: { · 1 unmodified line
97 <SheetHeader>110 <SheetHeader>
98 <SheetTitle>Edit connection</SheetTitle>111 <SheetTitle>Edit connection</SheetTitle>
99 <SheetDescription>112 <SheetDescription>
100 The description is agent-visible: it rides this connection's prefix in the tool113 Both fields are agent-visible: agents read them from <code>connections.list</code> when
101 inventory, so it is the place to say what this credential reaches and how to use it.114 they pick an account, so this is the place to say which account this is and what it is
115 for.
102 </SheetDescription>116 </SheetDescription>
103 </SheetHeader>117 </SheetHeader>
104 118
@@ -128,18 +142,12 @@ export function ConnectionEditSheet(props: { · 23 unmodified lines
128 disabled={saving}142 disabled={saving}
129 />143 />
130 <p className="text-xs text-muted-foreground">144 <p className="text-xs text-muted-foreground">
131 Display-only; shown in the accounts list instead of the connection name.145 Shown in the accounts list instead of the connection name. Agents see it too, but the
146 callable name stays as it was at connect time.
132 </p>147 </p>
133 </div>148 </div>
134 149
135 {connection ? (150 {connection ? <AgentPreview label="What agents see" line={previewLine} /> : null}
136 <AgentPreview
137 label="What agents see"
138 line={
139 previewDescription ? `- \`${prefix}\` — ${previewDescription}` : `- \`${prefix}\``
140 }
141 />
142 ) : null}
143 </div>151 </div>
144 152
145 <SheetFooter>153 <SheetFooter>