agent-relay-server 0.67.1 → 0.68.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/docs/openapi.json +1 -1
  2. package/package.json +2 -2
  3. package/public/assets/{MessageBubble-CgL7SMC9.js → MessageBubble-DPcJxTJj.js} +2 -2
  4. package/public/assets/{MessageBubble-CgL7SMC9.js.map → MessageBubble-DPcJxTJj.js.map} +1 -1
  5. package/public/assets/{PlanGraphPanel-C9M1YUH3.js → PlanGraphPanel-BYmE8ldg.js} +2 -2
  6. package/public/assets/{PlanGraphPanel-C9M1YUH3.js.map → PlanGraphPanel-BYmE8ldg.js.map} +1 -1
  7. package/public/assets/{activity-C0ki3CXN.js → activity-BzU196gP.js} +2 -2
  8. package/public/assets/{activity-C0ki3CXN.js.map → activity-BzU196gP.js.map} +1 -1
  9. package/public/assets/agent-profiles-CQuoP8Nr.js +2 -0
  10. package/public/assets/agent-profiles-CQuoP8Nr.js.map +1 -0
  11. package/public/assets/{agents-DVTyhojU.js → agents-qH6q44nK.js} +2 -2
  12. package/public/assets/{agents-DVTyhojU.js.map → agents-qH6q44nK.js.map} +1 -1
  13. package/public/assets/{analytics-D6ffu1ji.js → analytics-EJH9GFID.js} +2 -2
  14. package/public/assets/{analytics-D6ffu1ji.js.map → analytics-EJH9GFID.js.map} +1 -1
  15. package/public/assets/{automation-CKLQvSB-.js → automation-Dahmxg07.js} +2 -2
  16. package/public/assets/{automation-CKLQvSB-.js.map → automation-Dahmxg07.js.map} +1 -1
  17. package/public/assets/{branch-state-badge-DrwCnoKR.js → branch-state-badge-C7H8HY22.js} +2 -2
  18. package/public/assets/{branch-state-badge-DrwCnoKR.js.map → branch-state-badge-C7H8HY22.js.map} +1 -1
  19. package/public/assets/{channels-BuqbbyaO.js → channels-VhlwES_A.js} +2 -2
  20. package/public/assets/{channels-BuqbbyaO.js.map → channels-VhlwES_A.js.map} +1 -1
  21. package/public/assets/{chat-XM7zLIrJ.js → chat-DJqvtoFT.js} +2 -2
  22. package/public/assets/{chat-XM7zLIrJ.js.map → chat-DJqvtoFT.js.map} +1 -1
  23. package/public/assets/{connectors-_LpoKQNb.js → connectors-C03pRoXx.js} +2 -2
  24. package/public/assets/{connectors-_LpoKQNb.js.map → connectors-C03pRoXx.js.map} +1 -1
  25. package/public/assets/{formatted-body-impl-BOtgnE2e.js → formatted-body-impl-DhvR8Z-A.js} +2 -2
  26. package/public/assets/{formatted-body-impl-BOtgnE2e.js.map → formatted-body-impl-DhvR8Z-A.js.map} +1 -1
  27. package/public/assets/index-Dh7NjR-l.css +2 -0
  28. package/public/assets/{index-CARLLWss.js → index-VGRP16ua.js} +6 -6
  29. package/public/assets/index-VGRP16ua.js.map +1 -0
  30. package/public/assets/{insights-BuhwfZK_.js → insights-v9noub5E.js} +2 -2
  31. package/public/assets/{insights-BuhwfZK_.js.map → insights-v9noub5E.js.map} +1 -1
  32. package/public/assets/{integrations-DCyxAv8c.js → integrations-BEa3ArUw.js} +2 -2
  33. package/public/assets/{integrations-DCyxAv8c.js.map → integrations-BEa3ArUw.js.map} +1 -1
  34. package/public/assets/{maintenance-FVXyLhl7.js → maintenance-DyRfVkhp.js} +2 -2
  35. package/public/assets/{maintenance-FVXyLhl7.js.map → maintenance-DyRfVkhp.js.map} +1 -1
  36. package/public/assets/{managed-agents-CaeHrwda.js → managed-agents-BSdMoBgG.js} +2 -2
  37. package/public/assets/{managed-agents-CaeHrwda.js.map → managed-agents-BSdMoBgG.js.map} +1 -1
  38. package/public/assets/{markdown-preview-impl-Brm7jSxL.js → markdown-preview-impl-DidsrMmn.js} +2 -2
  39. package/public/assets/{markdown-preview-impl-Brm7jSxL.js.map → markdown-preview-impl-DidsrMmn.js.map} +1 -1
  40. package/public/assets/{memory-Drj5wn76.js → memory-DM8muGVW.js} +2 -2
  41. package/public/assets/{memory-Drj5wn76.js.map → memory-DM8muGVW.js.map} +1 -1
  42. package/public/assets/{messages-CSSnT5X4.js → messages-BqjAkcBF.js} +2 -2
  43. package/public/assets/{messages-CSSnT5X4.js.map → messages-BqjAkcBF.js.map} +1 -1
  44. package/public/assets/{orchestrators-FdF1O-b_.js → orchestrators-C_mjUDZg.js} +2 -2
  45. package/public/assets/{orchestrators-FdF1O-b_.js.map → orchestrators-C_mjUDZg.js.map} +1 -1
  46. package/public/assets/{overview-tqzRF2zO.js → overview-Cpu2plX-.js} +2 -2
  47. package/public/assets/{overview-tqzRF2zO.js.map → overview-Cpu2plX-.js.map} +1 -1
  48. package/public/assets/{pairs-CJiBSa2o.js → pairs--8_0A0lq.js} +2 -2
  49. package/public/assets/{pairs-CJiBSa2o.js.map → pairs--8_0A0lq.js.map} +1 -1
  50. package/public/assets/{projects-DtJmrhI0.js → projects-nCww9PG1.js} +2 -2
  51. package/public/assets/{projects-DtJmrhI0.js.map → projects-nCww9PG1.js.map} +1 -1
  52. package/public/assets/{security-CItvWUwq.js → security-CwgoEvJT.js} +2 -2
  53. package/public/assets/{security-CItvWUwq.js.map → security-CwgoEvJT.js.map} +1 -1
  54. package/public/assets/{select-CXen1oFN.js → select-Bhx6zSZr.js} +2 -2
  55. package/public/assets/{select-CXen1oFN.js.map → select-Bhx6zSZr.js.map} +1 -1
  56. package/public/assets/{settings-Dm2NtIMK.js → settings-BNQBnKXg.js} +2 -2
  57. package/public/assets/{settings-Dm2NtIMK.js.map → settings-BNQBnKXg.js.map} +1 -1
  58. package/public/assets/store-BB-YW24l.js +9 -0
  59. package/public/assets/store-BB-YW24l.js.map +1 -0
  60. package/public/assets/{tasks-DbyJbQLo.js → tasks-C5Kv18N7.js} +2 -2
  61. package/public/assets/{tasks-DbyJbQLo.js.map → tasks-C5Kv18N7.js.map} +1 -1
  62. package/public/assets/{teams-BtjasnAN.js → teams-D_Ttv7qD.js} +2 -2
  63. package/public/assets/{teams-BtjasnAN.js.map → teams-D_Ttv7qD.js.map} +1 -1
  64. package/public/assets/{terminal-viewer-impl-CbVuN1vi.js → terminal-viewer-impl-5y8v9jNx.js} +2 -2
  65. package/public/assets/{terminal-viewer-impl-CbVuN1vi.js.map → terminal-viewer-impl-5y8v9jNx.js.map} +1 -1
  66. package/public/assets/{work-queue-MP7UUAx7.js → work-queue-BB7bYLIK.js} +2 -2
  67. package/public/assets/{work-queue-MP7UUAx7.js.map → work-queue-BB7bYLIK.js.map} +1 -1
  68. package/public/assets/{workspaces-Bu4uVUcu.js → workspaces-CrtAeVnv.js} +2 -2
  69. package/public/assets/{workspaces-Bu4uVUcu.js.map → workspaces-CrtAeVnv.js.map} +1 -1
  70. package/public/index.html +3 -3
  71. package/runner/src/adapter.ts +11 -0
  72. package/src/agent-card-projection.ts +28 -0
  73. package/src/automations/dispatch.ts +2 -2
  74. package/src/bus.ts +5 -1
  75. package/src/config-store.ts +9 -3
  76. package/src/db/agent-search.ts +22 -8
  77. package/src/db/index.ts +1 -0
  78. package/src/db/migrations.ts +17 -0
  79. package/src/db/provisioning-registry.ts +278 -0
  80. package/src/db/schema.ts +16 -0
  81. package/src/managed-policy.ts +2 -1
  82. package/src/mcp/tools-messaging.ts +72 -3
  83. package/src/project-instructions.ts +41 -1
  84. package/src/routes/agent-sessions.ts +2 -2
  85. package/src/services/spawn-agent.ts +13 -17
  86. package/src/sse.ts +3 -4
  87. package/public/assets/agent-profiles-1Nx8ROA_.js +0 -2
  88. package/public/assets/agent-profiles-1Nx8ROA_.js.map +0 -1
  89. package/public/assets/index-CARLLWss.js.map +0 -1
  90. package/public/assets/index-eCpWfoCA.css +0 -2
  91. package/public/assets/store-BeKcuJ2q.js +0 -9
  92. package/public/assets/store-BeKcuJ2q.js.map +0 -1
@@ -25,14 +25,14 @@
25
25
  // deliberately out of scope here — this slice converges the two external TRANSPORTS.
26
26
  import type { SpawnProvider } from "agent-relay-sdk";
27
27
  import { errMessage, stringValue } from "agent-relay-sdk";
28
- import { countLiveSpawnedAgents, createActivityEvent, ensureTeam, getAgent, listAgents, resolveProjectForCwd, setAgentTeam, ValidationError } from "../db";
28
+ import { countLiveSpawnedAgents, createActivityEvent, ensureTeam, getAgent, listAgents, resolveProjectForCwd, setAgentTeam, ValidationError, withResolvedProvisioning } from "../db";
29
29
  import { createCommand } from "../commands-db";
30
30
  import { emitCommandEvent } from "../command-events";
31
31
  import { buildSpawnCommand, generateSpawnRequestId, resolveSpawnModelParams } from "../spawn-command";
32
32
  import { runnerRuntimeTokenEnv } from "../runtime-tokens";
33
33
  import { selectSpawnOrchestrator } from "../spawn-targets";
34
34
  import { getAgentProfile } from "../config-store";
35
- import { composeProjectInstructions, type ProjectInstructionPolicy } from "../project-instructions";
35
+ import { composeSpawnInstructions, type ProjectInstructionPolicy } from "../project-instructions";
36
36
  import { autoSeedProjectForCwd } from "./project";
37
37
  import { hasComponentScope, isComponentAuthorizedFor } from "../security";
38
38
  import { isPathWithinBase } from "../utils";
@@ -169,7 +169,7 @@ export async function spawnAgent(input: SpawnAgentInput, ctx: AuthContext): Prom
169
169
  // Resolve + validate the named agent profile server-side (was HTTP-only; the MCP path passed
170
170
  // the name through unvalidated). Both transports now 404 on an unknown profile and ship the
171
171
  // resolved value to the orchestrator.
172
- const agentProfile = input.profile ? getAgentProfile(input.profile)?.value : undefined;
172
+ const agentProfile = withResolvedProvisioning(input.profile ? getAgentProfile(input.profile)?.value : undefined, input.provider);
173
173
  if (input.profile && !agentProfile) throw new McpNotFoundError("agent profile not found");
174
174
 
175
175
  // --- THE GATE (uniform across transports) ---------------------------------
@@ -218,21 +218,17 @@ export async function spawnAgent(input: SpawnAgentInput, ctx: AuthContext): Prom
218
218
  if (!callerProject) console.warn(`project auto-seed skipped for ${resolvedCwd}: ${errMessage(err)}`);
219
219
  }
220
220
 
221
- // #409 + #463 — one composition home for the prompt material handed to providers.
222
- // Precedence is: project preamble, profile system, profile append entries, then
223
- // transient caller/fork context. Spawns without profile/project material stay
221
+ // #409 + #463 + #557 the instruction-sources half of the launch-assembly contract.
222
+ // composeSpawnInstructions is the single home that composes the prompt material handed to
223
+ // providers (project preamble profile system → profile append → caller/fork context) and
224
+ // carries the #559 scoped-knowledge seam. Spawns without profile/project material stay
224
225
  // byte-identical to the caller-provided systemPromptAppend.
225
- const appendBlocks: string[] = [];
226
- if (input.projectInstructions && callerProject) {
227
- const block = composeProjectInstructions(callerProject, {
228
- ...(input.projectInstructions.policy ? { policy: input.projectInstructions.policy } : {}),
229
- });
230
- if (block.trim()) appendBlocks.push(block);
231
- }
232
- if (agentProfile?.instructions.system?.trim()) appendBlocks.push(agentProfile.instructions.system);
233
- appendBlocks.push(...(agentProfile?.instructions.append.filter((entry) => entry.trim()) ?? []));
234
- if (input.systemPromptAppend?.trim()) appendBlocks.push(input.systemPromptAppend);
235
- const systemPromptAppend = appendBlocks.length ? appendBlocks.join("\n\n") : input.systemPromptAppend;
226
+ const systemPromptAppend = composeSpawnInstructions({
227
+ ...(callerProject ? { callerProject } : {}),
228
+ ...(input.projectInstructions ? { projectInstructions: input.projectInstructions } : {}),
229
+ ...(agentProfile ? { profile: agentProfile } : {}),
230
+ ...(input.systemPromptAppend ? { callerSystemPromptAppend: input.systemPromptAppend } : {}),
231
+ });
236
232
 
237
233
  // Child runner token. `agentInitiated` (set whenever an agent is the caller) forces a
238
234
  // non-spawn-capable child (no grandchildren); `spawnedBy` stamps authoritative lineage the
package/src/sse.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { getAgent, getOrchestrator, matchingDeliveryAgents, onWorkspaceChange } from "./db";
2
- import { attachBranchState } from "./agent-branch-state";
3
- import { attachIssueRepo } from "./agent-issue-repo";
2
+ import { projectAgentStatusData } from "./agent-card-projection";
4
3
  import { emitRelayEvent, subscribeRelayEvents, type RelayEvent } from "./events";
5
4
  import { messageMatchesAgent, targetMatchesAgent } from "./agent-ref";
6
5
  import type { ActivityEvent, AgentCard, Message, RelayNotification, Task } from "./types";
@@ -109,8 +108,8 @@ export function emitNewMessage(msg: Message) {
109
108
  export function emitAgentStatus(agentId: string) {
110
109
  const agent = getAgent(agentId);
111
110
  // Enrich with the branch-state badge fields (#236) and the resolved issueRepo (#533) so
112
- // the dashboard's live agent updates carry the same projection as GET /api/agents.
113
- const data = agent ? attachIssueRepo(attachBranchState(agent)) : { id: agentId, status: "offline" };
111
+ // the dashboard's live agent updates carry the same projection as GET /api/agents (#560).
112
+ const data = projectAgentStatusData(agentId, agent);
114
113
  emitRelayEvent({ type: "agent.status", source: "server", subject: agentId, data: data as unknown as Record<string, unknown> });
115
114
  const notification = agent ? notificationForAgentStatus(agent) : undefined;
116
115
  if (notification) emitNotificationCreated(notification);
@@ -1,2 +0,0 @@
1
- import{Bn as e,R as t,Rt as n,V as r,Yt as i,f as a,m as o}from"./lucide-react-BbMYCUlW.js";import{t as s}from"./store-BeKcuJ2q.js";import{t as c}from"./badge-C6NJQ60B.js";import{t as l}from"./button-DD2CCM3t.js";var u=e(),d={host:`text-emerald-400 bg-emerald-500/10`,minimal:`text-amber-400 bg-amber-500/10`,isolated:`text-red-400 bg-red-500/10`};function f({relay:e}){return(0,u.jsx)(`div`,{className:`flex items-center gap-1`,children:[{key:`ctx`,on:e.context},{key:`skl`,on:e.skills},{key:`plg`,on:e.plugins},{key:`stl`,on:e.statusLine}].map(e=>(0,u.jsx)(`span`,{className:`inline-block h-1.5 w-1.5 rounded-full ${e.on?`bg-emerald-400`:`bg-muted-foreground/30`}`,title:`${e.key}: ${e.on?`on`:`off`}`},e.key))})}function p({profile:e}){let t=s(e=>e.openProfileModal),a=s(e=>e.deleteProfile),p=e.builtIn===!0;return(0,u.jsxs)(`div`,{className:`group flex flex-col gap-3 rounded-lg border border-border bg-card p-4`,children:[(0,u.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,u.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,u.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,u.jsx)(`span`,{className:`font-mono text-sm font-medium`,children:e.name}),p&&(0,u.jsx)(c,{variant:`secondary`,className:`text-[10px]`,children:`Built-in`})]}),e.description&&(0,u.jsx)(`p`,{className:`mt-0.5 text-xs text-muted-foreground line-clamp-2`,children:e.description})]}),(0,u.jsxs)(`div`,{className:`flex shrink-0 items-center gap-0.5 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity`,children:[(0,u.jsx)(l,{variant:`ghost`,size:`icon-sm`,className:`h-7 w-7`,title:`View`,onClick:()=>t(`view`,e),children:(0,u.jsx)(n,{className:`h-3.5 w-3.5`})}),!p&&(0,u.jsx)(l,{variant:`ghost`,size:`icon-sm`,className:`h-7 w-7`,title:`Edit`,onClick:()=>t(`edit`,e),children:(0,u.jsx)(r,{className:`h-3.5 w-3.5`})}),(0,u.jsx)(l,{variant:`ghost`,size:`icon-sm`,className:`h-7 w-7`,title:`Duplicate`,onClick:()=>t(`duplicate`,e),children:(0,u.jsx)(i,{className:`h-3.5 w-3.5`})}),!p&&(0,u.jsx)(l,{variant:`ghost`,size:`icon-sm`,className:`h-7 w-7 text-destructive`,title:`Delete`,onClick:()=>a(e.name),children:(0,u.jsx)(o,{className:`h-3.5 w-3.5`})})]})]}),(0,u.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5 text-[10px]`,children:[(0,u.jsx)(c,{variant:`outline`,className:d[e.base]||``,children:e.base}),(0,u.jsx)(c,{variant:`outline`,children:e.provider||`any`}),(0,u.jsxs)(c,{variant:`outline`,children:[`fs: `,e.permissions.filesystem]}),e.permissions.mode&&(0,u.jsx)(c,{variant:`outline`,children:e.permissions.mode})]}),(0,u.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-1 text-[10px] text-muted-foreground`,children:[(0,u.jsxs)(`span`,{className:`flex items-center gap-1`,children:[`Relay `,(0,u.jsx)(f,{relay:e.relay})]}),(0,u.jsxs)(`span`,{children:[`MCP: `,e.mcp.mode]}),(0,u.jsxs)(`span`,{children:[`Hooks: `,e.hooks.mode]}),e.instructions.globalInstructions===`ignore`&&(0,u.jsx)(`span`,{className:`text-amber-400`,children:`global: ignore`}),Object.keys(e.env||{}).length>0&&(0,u.jsxs)(`span`,{children:[Object.keys(e.env).length,` env vars`]})]})]})}function m(){let e=s(e=>e.agentProfiles),n=s(e=>e.openProfileModal),r=e.filter(e=>e.builtIn),i=e.filter(e=>!e.builtIn);return(0,u.jsxs)(`div`,{className:`space-y-4`,children:[(0,u.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,u.jsxs)(`div`,{className:`flex items-center gap-2 text-lg font-semibold`,children:[(0,u.jsx)(a,{className:`h-5 w-5 text-primary`}),`Agent Profiles`]}),(0,u.jsx)(c,{variant:`outline`,children:e.length}),(0,u.jsx)(`div`,{className:`flex-1`}),(0,u.jsxs)(l,{size:`sm`,className:`gap-1`,onClick:()=>n(`create`),children:[(0,u.jsx)(t,{className:`h-3.5 w-3.5`}),`Create Profile`]})]}),r.length>0&&(0,u.jsxs)(`div`,{children:[(0,u.jsx)(`h3`,{className:`mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`Built-in`}),(0,u.jsx)(`div`,{className:`grid gap-3 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3`,children:r.map(e=>(0,u.jsx)(p,{profile:e},e.name))})]}),i.length>0&&(0,u.jsxs)(`div`,{children:[(0,u.jsx)(`h3`,{className:`mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:`Custom`}),(0,u.jsx)(`div`,{className:`grid gap-3 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3`,children:i.map(e=>(0,u.jsx)(p,{profile:e},e.name))})]}),e.length===0&&(0,u.jsx)(`div`,{className:`py-12 text-center text-sm text-muted-foreground`,children:`No agent profiles found. Create one to configure agent behavior.`})]})}export{m as AgentProfilesView};
2
- //# sourceMappingURL=agent-profiles-1Nx8ROA_.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agent-profiles-1Nx8ROA_.js","names":[],"sources":["../../dashboard/src/components/views/agent-profiles.tsx"],"sourcesContent":["import { useRelayStore } from '@/store'\nimport { Button } from '@/components/ui/button'\nimport { Badge } from '@/components/ui/badge'\nimport { Copy, Eye, Pencil, Plus, Trash2, UserCog } from 'lucide-react'\nimport type { AgentProfile } from '@/types'\n\nconst BASE_COLORS: Record<string, string> = {\n host: 'text-emerald-400 bg-emerald-500/10',\n minimal: 'text-amber-400 bg-amber-500/10',\n isolated: 'text-red-400 bg-red-500/10',\n}\n\nfunction RelayDots({ relay }: { relay: AgentProfile['relay'] }) {\n const items = [\n { key: 'ctx', on: relay.context },\n { key: 'skl', on: relay.skills },\n { key: 'plg', on: relay.plugins },\n { key: 'stl', on: relay.statusLine },\n ]\n return (\n <div className=\"flex items-center gap-1\">\n {items.map((item) => (\n <span key={item.key} className={`inline-block h-1.5 w-1.5 rounded-full ${item.on ? 'bg-emerald-400' : 'bg-muted-foreground/30'}`} title={`${item.key}: ${item.on ? 'on' : 'off'}`} />\n ))}\n </div>\n )\n}\n\nfunction ProfileCard({ profile }: { profile: AgentProfile }) {\n const openProfileModal = useRelayStore((s) => s.openProfileModal)\n const deleteProfile = useRelayStore((s) => s.deleteProfile)\n const isBuiltIn = profile.builtIn === true\n\n return (\n <div className=\"group flex flex-col gap-3 rounded-lg border border-border bg-card p-4\">\n <div className=\"flex items-start gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-mono text-sm font-medium\">{profile.name}</span>\n {isBuiltIn && <Badge variant=\"secondary\" className=\"text-[10px]\">Built-in</Badge>}\n </div>\n {profile.description && (\n <p className=\"mt-0.5 text-xs text-muted-foreground line-clamp-2\">{profile.description}</p>\n )}\n </div>\n <div className=\"flex shrink-0 items-center gap-0.5 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity\">\n <Button variant=\"ghost\" size=\"icon-sm\" className=\"h-7 w-7\" title=\"View\" onClick={() => openProfileModal('view', profile)}>\n <Eye className=\"h-3.5 w-3.5\" />\n </Button>\n {!isBuiltIn && (\n <Button variant=\"ghost\" size=\"icon-sm\" className=\"h-7 w-7\" title=\"Edit\" onClick={() => openProfileModal('edit', profile)}>\n <Pencil className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n <Button variant=\"ghost\" size=\"icon-sm\" className=\"h-7 w-7\" title=\"Duplicate\" onClick={() => openProfileModal('duplicate', profile)}>\n <Copy className=\"h-3.5 w-3.5\" />\n </Button>\n {!isBuiltIn && (\n <Button variant=\"ghost\" size=\"icon-sm\" className=\"h-7 w-7 text-destructive\" title=\"Delete\" onClick={() => deleteProfile(profile.name)}>\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-1.5 text-[10px]\">\n <Badge variant=\"outline\" className={BASE_COLORS[profile.base] || ''}>{profile.base}</Badge>\n <Badge variant=\"outline\">{profile.provider || 'any'}</Badge>\n <Badge variant=\"outline\">fs: {profile.permissions.filesystem}</Badge>\n {profile.permissions.mode && <Badge variant=\"outline\">{profile.permissions.mode}</Badge>}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-[10px] text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n Relay <RelayDots relay={profile.relay} />\n </span>\n <span>MCP: {profile.mcp.mode}</span>\n <span>Hooks: {profile.hooks.mode}</span>\n {profile.instructions.globalInstructions === 'ignore' && <span className=\"text-amber-400\">global: ignore</span>}\n {Object.keys(profile.env || {}).length > 0 && <span>{Object.keys(profile.env).length} env vars</span>}\n </div>\n </div>\n )\n}\n\nexport function AgentProfilesView() {\n const profiles = useRelayStore((s) => s.agentProfiles)\n const openProfileModal = useRelayStore((s) => s.openProfileModal)\n\n const builtIn = profiles.filter((p) => p.builtIn)\n const custom = profiles.filter((p) => !p.builtIn)\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"flex items-center gap-2 text-lg font-semibold\">\n <UserCog className=\"h-5 w-5 text-primary\" />\n Agent Profiles\n </div>\n <Badge variant=\"outline\">{profiles.length}</Badge>\n <div className=\"flex-1\" />\n <Button size=\"sm\" className=\"gap-1\" onClick={() => openProfileModal('create')}>\n <Plus className=\"h-3.5 w-3.5\" />\n Create Profile\n </Button>\n </div>\n\n {builtIn.length > 0 && (\n <div>\n <h3 className=\"mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wider\">Built-in</h3>\n <div className=\"grid gap-3 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\">\n {builtIn.map((p) => <ProfileCard key={p.name} profile={p} />)}\n </div>\n </div>\n )}\n\n {custom.length > 0 && (\n <div>\n <h3 className=\"mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wider\">Custom</h3>\n <div className=\"grid gap-3 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\">\n {custom.map((p) => <ProfileCard key={p.name} profile={p} />)}\n </div>\n </div>\n )}\n\n {profiles.length === 0 && (\n <div className=\"py-12 text-center text-sm text-muted-foreground\">\n No agent profiles found. Create one to configure agent behavior.\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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"}