@arbor-education/agent-view-frontend 0.2.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.
package/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # Agent View Frontend
2
+
3
+ React components to support the development of the Agentic MATs initiative.
4
+
5
+ The UI is designed to work against the **AI agent service** — not only the local mock
6
+ server. `AgentMonitorKanban` is self-contained: give it a `jwt`, optional `headers`, and
7
+ a `baseUrl` (plus optional per-operation URL props), and it fetches agents and definitions, loads
8
+ checklists and resources, creates agents, and streams chat via the bundled **AI service
9
+ SDK** (`AgentServiceClient`) against `/api/v1/agents/*`. The demo ships with presets for
10
+ mock, local (`localhost:8001`), and staging backends; see
11
+ [Wiring the UI to the AI service](#wiring-the-ui-to-the-ai-service).
12
+
13
+ ---
14
+
15
+ ## Setup
16
+
17
+ **Requirements:** Node.js and Yarn.
18
+
19
+ ```bash
20
+ yarn install
21
+ make demo-with-mock
22
+ ```
23
+
24
+ Open **http://localhost:4174/**. The demo starts in **Backend** mode and loads agents from the local mock agent service automatically.
25
+
26
+ To run the demo UI only (no backend — use **Debug options** to switch to Mock data, Sparse, or Empty):
27
+
28
+ ```bash
29
+ make demo
30
+ ```
31
+
32
+ Or run the mock server and demo in separate terminals:
33
+
34
+ ```bash
35
+ # Terminal 1
36
+ make mock-server
37
+
38
+ # Terminal 2
39
+ make demo
40
+ ```
41
+
42
+ If you change mock-server code, restart it so the demo picks up API changes.
43
+
44
+ Use **Debug options** in the toolbar to switch backends:
45
+
46
+ | Preset | Service URL | Notes |
47
+ |---|---|---|
48
+ | **Mock server** | `/api/ai-agent-service` | Local seed data via the demo proxy. Bearer token optional. |
49
+ | **Local AI service** | `http://localhost:8001` | Real AI agent service on your machine. Bearer token required. |
50
+ | **Staging AI service** | `https://ai-agent-service.qa.arbor.engineering` | QA environment. Bearer token required. |
51
+
52
+ You can also paste any service origin into the **Service URL** field (the SDK appends
53
+ `/api/v1/agents/…` automatically).
54
+
55
+ You can also configure the demo without opening the debug panel:
56
+
57
+ ```bash
58
+ # Via URL query params (token is stripped from the address bar after load)
59
+ http://localhost:4174/?serviceUrl=http://localhost:3001&token=your-bearer-token
60
+
61
+ # Via environment variables
62
+ VITE_AGENT_SERVICE_URL=https://ai-agent-service.qa.arbor.engineering \
63
+ VITE_AGENT_SERVICE_TOKEN=your-bearer-token \
64
+ make demo
65
+ ```
66
+
67
+ | Variable | Default | Purpose |
68
+ |---|---|---|
69
+ | `MOCK_SERVER_PORT` | `3001` | Port for the mock agent service |
70
+ | `VITE_AGENT_SERVICE_PROXY_TARGET` | `http://localhost:3001` | Where the demo proxies `/api/ai-agent-service` |
71
+ | `VITE_AGENT_SERVICE_URL` | `/api/ai-agent-service` | Initial service URL for the demo (overridable in Debug options) |
72
+ | `VITE_AGENT_SERVICE_TOKEN` | _(empty)_ | Initial bearer token for the demo |
73
+
74
+ To hit QA instead of the local mock server:
75
+
76
+ ```bash
77
+ VITE_AGENT_SERVICE_PROXY_TARGET=https://ai-agent-service.qa.arbor.engineering make demo
78
+ ```
79
+
80
+ ---
81
+
82
+ ## Scripts
83
+
84
+ | Command | What it does |
85
+ |---|---|
86
+ | `yarn demo` / `make demo` | Start the demo app with hot reload |
87
+ | `yarn demo:with-mock` / `make demo-with-mock` | Start mock server + demo together |
88
+ | `yarn mock-server` / `make mock-server` | Start the local AI agent service mock server |
89
+ | `yarn dev` / `make dev` | Alias for `demo` |
90
+ | `yarn build` / `make build` | Library build → `dist/` |
91
+ | `yarn test` / `make test` | Run Vitest test suite |
92
+ | `yarn test:watch` / `make test-watch` | Vitest in watch mode |
93
+ | `yarn check-types` / `make typecheck` | TypeScript check (no emit) |
94
+ | `yarn lint` / `make lint` | ESLint check for TS/TSX |
95
+ | `yarn lint:fix` | ESLint with auto-fix |
96
+ | `yarn style-lint` / `make style-lint` | Stylelint check for SCSS |
97
+ | `make check` | typecheck + lint + style-lint + test + build |
98
+ | `make clean` | Remove `dist` and Vite cache |
99
+
100
+ ---
101
+
102
+ ## Wiring the UI to the AI service
103
+
104
+ `AgentMonitorKanban` owns all AI service orchestration internally. Give it the
105
+ credentials and endpoint URLs and it does the rest — listing agents/definitions,
106
+ loading checklists and resources, creating agents, and streaming chat.
107
+
108
+ **In the demo** — open **Debug options**, pick **Local AI service** or **Staging AI
109
+ service**, paste a bearer token, and click **Reload board**. The demo resolves the
110
+ Service URL field into `baseUrl`; see [`demo/App.tsx`](demo/App.tsx) (and the URL
111
+ helpers in [`demo/backendApi.ts`](demo/backendApi.ts)).
112
+
113
+ **In your app** — pass `jwt`, optional `headers`, and the endpoint URLs:
114
+
115
+ ```tsx
116
+ import { AgentMonitorKanban } from 'agent-view-frontend';
117
+ import 'agent-view-frontend/style.css';
118
+ import '@arbor-education/design-system.components/dist/index.css';
119
+
120
+ <AgentMonitorKanban
121
+ jwt={jwt}
122
+ headers={{ 'X-Arbor-Application': 'agent-view' }}
123
+ // Required. Service origin — the SDK appends `/api/v1/<route>`.
124
+ baseUrl="https://ai-agent-service.qa.arbor.engineering"
125
+ // Optional per-operation overrides (full URLs). Parameterised routes
126
+ // substitute the `:invocationId` placeholder, e.g.:
127
+ // agentChecklistUrl="https://…/agents/:invocationId/checklist"
128
+ />;
129
+ ```
130
+
131
+ Each URL is a separate prop. The optional per-operation overrides
132
+ (`agentDefinitionsUrl`, `agentsUrl`, `agentUrl`, `agentChecklistUrl`,
133
+ `agentResourcesUrl`, `agentChatUrl`) each fall back to `baseUrl` +
134
+ `/api/v1` + the route when omitted. See the [AI service SDK](#ai-service-sdk) section
135
+ for the underlying client, which you can also use directly.
136
+
137
+ ---
138
+
139
+ ## NPM usage
140
+
141
+ Install the package and its peer dependencies:
142
+
143
+ ```bash
144
+ yarn add agent-view-frontend @arbor-education/design-system.components react react-dom
145
+ ```
146
+
147
+ Import the component and styles:
148
+
149
+ ```tsx
150
+ import { AgentMonitorKanban } from 'agent-view-frontend';
151
+ import 'agent-view-frontend/style.css';
152
+ import '@arbor-education/design-system.components/dist/index.css';
153
+
154
+ function Page() {
155
+ return <AgentMonitorKanban baseUrl="/api/ai-agent-service" />;
156
+ }
157
+ ```
158
+
159
+ ---
160
+
161
+ ## AI service SDK
162
+
163
+ The package ships a framework-agnostic client for the AI agent service
164
+ `/api/v1/agents/*` endpoints (works against the local mock server or the real AI service).
165
+
166
+ ```ts
167
+ import {
168
+ AgentServiceClient,
169
+ createHttpChatConnectorFactory,
170
+ mapApiAgent,
171
+ mapApiChecklistResponse,
172
+ } from 'agent-view-frontend';
173
+
174
+ const client = new AgentServiceClient({
175
+ baseUrl: '/api/ai-agent-service', // or 'http://localhost:3001'
176
+ token: jwt, // Bearer token; "Bearer " prefix optional
177
+ });
178
+
179
+ // List / detail (mapped into the UI's Agent + checklist shapes)
180
+ const agents = (await client.listAgents()).map(mapApiAgent);
181
+ const detail = await client.getAgent(invocationId);
182
+ const checklist = mapApiChecklistResponse(invocationId, detail);
183
+
184
+ // Lifecycle
185
+ await client.createAgent('school_trip_agents');
186
+ await client.cancelAgent(agentId);
187
+ await client.archiveAgent(agentId);
188
+
189
+ // Streaming chat (SSE)
190
+ const connectorFor = createHttpChatConnectorFactory(client);
191
+ const connector = connectorFor(agents[0]);
192
+ const reply = await connector.sendMessage('What have you done so far?');
193
+ ```
194
+
195
+ `AgentServiceClient` also accepts `headers` (merged into every request) and per-operation
196
+ `urls` overrides — the same options `AgentMonitorKanban` forwards from its `headers` and
197
+ `urls` props.
198
+
199
+ `client.chat(agentId, request, { onEvent })` resolves with the final SSE event
200
+ and invokes `onEvent` per frame. Non-2xx responses and `event: error` frames
201
+ throw an `AgentServiceError` carrying `status` and the parsed `detail`.
202
+
203
+ The demo wires **Mock**, **Local**, and **Staging** backends through this SDK — see
204
+ [`demo/backendApi.ts`](demo/backendApi.ts) and
205
+ [Wiring the UI to the AI service](#wiring-the-ui-to-the-ai-service).
package/dist/index.cjs ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),o=require("react"),P=require("classnames"),d=require("@arbor-education/design-system.components"),se=require("@arbor-education/ask-arbor-chat-panel"),v={"generating-a-response":"generating-a-response",hitl:"hitl",complete:"complete",failed:"failed"},N={"generating-a-response":"generating-a-response",hitl:"hitl",complete:"complete",failed:"failed"},b={briefing:"briefing",running:"running",stopped:"stopped",complete:"complete"},W={agent:"agent",user:"user",system:"system"},Z={MIS_RECORD:"MIS_RECORD",FILE:"FILE",WORKFLOW:"WORKFLOW",LINK:"LINK"},je={cancelled:"cancelled",archived:"archived"},ve={in_progress:"in_progress",requires_attention:"requires_attention",available:"available"},$={[N.complete]:{label:"Complete",icon:"circle-check",color:"var(--color-semantic-success-600)"},[N.failed]:{label:"Failed",icon:"circle-x",color:"var(--color-semantic-destructive-600)"},[N.hitl]:{label:"Requires attention",icon:"triangle-alert",color:"var(--color-semantic-warning-600)"},[N["generating-a-response"]]:{label:"Generating a response",icon:"loader",color:"var(--color-brand-600)"}},he={[v["generating-a-response"]]:{status:v["generating-a-response"],title:"Active",dotColour:"green",statusIcon:{name:$["generating-a-response"].icon,color:$["generating-a-response"].color,spin:!0}},[v.hitl]:{status:v.hitl,title:"Requires attention",dotColour:"orange",statusIcon:{name:$.hitl.icon,color:$.hitl.color}},[v.complete]:{status:v.complete,title:"Complete",dotColour:"green",dotModifier:"grey-dark",statusIcon:{name:$.complete.icon,color:$.complete.color}},[v.failed]:{status:v.failed,title:"Failed",dotColour:"salmon",statusIcon:{name:$.failed.icon,color:$.failed.color}}},et=[v["generating-a-response"],v.hitl],tt=[v.complete,v.failed],nt="m4",st="1",Pe="msg-opening",we="Unable to load agent tasks. Please try again.",at="Unable to load the resources for this agent",rt="Something went wrong. Please try again.",Me="Unable to load agents. Please try again.",ee="Loading tasks…",be="Loading agents…",ot="Task",it="What recent actions have you taken?",ct={[b.briefing]:"Briefing",[b.running]:"Working",[b.stopped]:"Stopped",[b.complete]:"Complete"},lt=[v["generating-a-response"],v.hitl,v.complete,v.failed],dt={[v["generating-a-response"]]:"Agents currently working on tasks for you.",[v.hitl]:"Agents that need your input before they can continue.",[v.complete]:"Agents that have finished their work.",[v.failed]:"Agents that failed or were stopped."},gt=()=>n.jsxs("svg",{className:"agent-view__empty-illustration",viewBox:"0 0 360 240",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-label":"Preview of the agents board layout",children:[n.jsx("rect",{x:"0",y:"0",width:"360",height:"240",rx:"12",fill:"var(--color-grey-100)"}),n.jsx("rect",{x:"16",y:"16",width:"100",height:"208",rx:"8",fill:"var(--card-default-color-background)",stroke:"var(--card-default-color-border)"}),n.jsx("rect",{x:"130",y:"16",width:"100",height:"208",rx:"8",fill:"var(--card-default-color-background)",stroke:"var(--card-default-color-border)"}),n.jsx("rect",{x:"244",y:"16",width:"100",height:"100",rx:"8",fill:"var(--card-default-color-background)",stroke:"var(--card-default-color-border)"}),n.jsx("rect",{x:"244",y:"124",width:"100",height:"100",rx:"8",fill:"var(--card-default-color-background)",stroke:"var(--card-default-color-border)"}),n.jsx("rect",{x:"28",y:"52",width:"76",height:"36",rx:"6",fill:"var(--color-grey-050)"}),n.jsx("rect",{x:"28",y:"96",width:"76",height:"36",rx:"6",fill:"var(--color-grey-050)"}),n.jsx("rect",{x:"142",y:"52",width:"76",height:"36",rx:"6",fill:"var(--color-semantic-warning-050)"}),n.jsx("circle",{cx:"40",cy:"70",r:"4",fill:"var(--color-brand-600)"}),n.jsx("circle",{cx:"40",cy:"114",r:"4",fill:"var(--color-brand-600)"}),n.jsx("circle",{cx:"154",cy:"70",r:"4",fill:"var(--color-semantic-warning-600)"}),n.jsx("circle",{cx:"256",cy:"52",r:"4",fill:"var(--color-grey-400)"}),n.jsx("circle",{cx:"256",cy:"160",r:"4",fill:"var(--color-semantic-destructive-500)"})]}),ut=({status:e})=>{const t=he[e];return t.statusIcon?n.jsx(d.Icon,{name:t.statusIcon.name,size:16,color:t.statusIcon.color,screenReaderText:t.title}):n.jsx(d.Dot,{colour:t.dotColour,label:t.title})},pt=()=>n.jsxs("section",{className:"agent-view__empty","aria-label":"About the agents board",children:[n.jsxs("div",{className:"agent-view__empty-content",children:[n.jsx(d.Heading,{level:4,children:"Your agents board"}),n.jsx("p",{className:"agent-view__empty-lead",children:"When you start an agent, it appears here so you can track progress at a glance. Agents move between columns as their status changes."}),n.jsx("ul",{className:"agent-view__empty-columns",children:lt.map(e=>{const t=he[e];return n.jsxs("li",{className:"agent-view__empty-column",children:[n.jsx("span",{className:"agent-view__empty-column-indicator",children:n.jsx(ut,{status:e})}),n.jsxs("span",{className:"agent-view__empty-column-text",children:[n.jsx("span",{className:"agent-view__empty-column-title",children:t.title}),n.jsx("span",{className:"agent-view__empty-column-description",children:dt[e]})]})]},e)})}),n.jsxs("p",{className:"agent-view__empty-hint",children:["Use ",n.jsx("strong",{children:"Start an agent"})," above to begin."]})]}),n.jsx("div",{className:"agent-view__empty-visual",children:n.jsx(gt,{})})]}),ht=(e,t)=>({...e,...t.length>0?{children:t}:{}}),Le=e=>{const t=[],a=[];for(const s of e){const r=s.children?Le(s.children):{needsInput:[],tasks:[]};if(t.push(...r.needsInput),s.status===N.hitl){t.push({...s,children:void 0});continue}a.push(ht(s,r.tasks))}return{needsInput:t,tasks:a}},_t=e=>e.map((t,a)=>({item:t,index:a})).sort((t,a)=>{const s=t.item.status===N.hitl,r=a.item.status===N.hitl;return s!==r?s?-1:1:t.index-a.index}).map(({item:t})=>t),mt=({checklist:e})=>e.length===0?n.jsx("p",{className:"agent-view__progress-empty",children:"No tasks to display."}):n.jsx("ul",{className:"agent-view__progress-list","aria-label":"Agent tasks",children:_t(e).map(t=>{const a=$[t.status];return n.jsxs("li",{className:P("agent-view__progress-item",`agent-view__progress-item--${t.status.replace(/_/g,"-")}`),children:[n.jsx(d.Icon,{name:a.icon,size:16,color:a.color,screenReaderText:`${a.label}:`,className:P({"agent-view__progress-icon--spinning":t.status===N["generating-a-response"]})}),n.jsxs("div",{className:"agent-view__progress-item-content",children:[n.jsx("span",{className:"agent-view__progress-label",children:t.task}),t.status!==N.complete&&n.jsx("span",{className:"agent-view__progress-description",children:t.description})]})]},t.task)})}),ft=({prompts:e,classNamePrefix:t="agent-workspace",onSelect:a})=>e.length===0?null:n.jsx("div",{className:`${t}__chips`,children:e.map(s=>n.jsx("button",{type:"button",className:`${t}__chip`,onClick:()=>a(s),children:s},s))});class vt{constructor(t,a){this.connector=t,this.canSend=a.canSend,this.onTurn=a.onTurn,this.onAwaitingChange=a.onAwaitingChange}get canRate(){return!1}get canLoadHistory(){return!1}get canListInteractions(){return!1}get canSendNotification(){return!1}get ratingPopupUrls(){return{}}async sendMessage(t){var a,s;if(!this.canSend())return null;(a=this.onAwaitingChange)==null||a.call(this,!0);try{const r=await this.connector.sendMessage(t.userMessage);return this.onTurn(r),{id:r.message.id,text:r.message.text,type:se.CHAT_RESPONSE_TYPE_AGENT,...r.message.followUpPrompts?{followUpPrompts:r.message.followUpPrompts}:{}}}catch{return{id:`error-${Date.now()}`,text:rt,type:se.CHAT_RESPONSE_TYPE_ERROR}}finally{(s=this.onAwaitingChange)==null||s.call(this,!1)}}async loadHistory(t){return null}async listInteractions(){return null}async rateMessage(t){}async sendNotification(t){return!1}}const wt=({connector:e,phase:t,chatHistory:a,chatSessionKey:s,startQuery:r,clarificationMessage:i,onTurn:c,onAwaitingChange:g,onClarificationPrompt:w,onDismissClarification:u})=>{const p=o.useMemo(()=>new vt(e,{canSend:()=>t===b.running,onTurn:c,onAwaitingChange:g}),[e,t,c,g]),m=t!==b.running,x=t===b.running;return n.jsxs("section",{className:"agent-workspace__panel agent-workspace__panel--chat","aria-label":"Chat",children:[i&&n.jsxs("div",{className:"agent-workspace__clarification",role:"region","aria-label":"Agent question",children:[n.jsx("p",{className:"agent-workspace__clarification-text",children:i.text}),i.followUpPrompts&&n.jsx(ft,{prompts:i.followUpPrompts,onSelect:w}),n.jsx("button",{type:"button",className:"agent-workspace__clarification-dismiss",onClick:u,children:"Dismiss"})]}),n.jsx("div",{className:"agent-workspace__ask-arbor",children:n.jsx(se.ChatPanel,{connector:p,chatHistory:a,startQuery:r,lockConversation:m,enableUpload:!0,speechEnabled:x,speechLanguage:"en-GB",speechSubmissionDelay:1e3,slashMenuItems:[],menuContent:[],introHeading:"Message your agent",introBody:"Ask questions, share trip details, or paste a link. The agent will update the checklist as it works.",placeholder:x?"Message the agent, paste a link, or attach a file…":"The agent is not accepting messages."},s)}),t===b.stopped&&n.jsxs("div",{className:"agent-workspace__notice",role:"status",children:[n.jsx(d.Icon,{name:"circle-alert",size:16,color:"var(--color-semantic-warning-600)"}),n.jsx("span",{children:"You stopped the agent. Its progress is saved in the checklist on the left."})]}),t===b.complete&&n.jsxs("div",{className:"agent-workspace__notice",role:"status",children:[n.jsx(d.Icon,{name:"party-popper",size:16,color:"var(--color-semantic-success-600)"}),n.jsx("span",{children:"The agent has finished."})]})]})},Ue=({item:e,depth:t,canRequestInput:a,onAttentionItemClick:s})=>{const r=$[e.status],i=e.status.replace(/_/g,"-"),c=e.status===N.hitl&&a&&s,g=n.jsxs("div",{className:"agent-workspace__task-row",children:[n.jsx(d.Icon,{name:r.icon,size:16,color:r.color,screenReaderText:`${r.label}:`,className:P({"agent-workspace__task-icon--spinning":e.status===N["generating-a-response"]})}),n.jsxs("div",{className:"agent-workspace__task-content",children:[n.jsx("span",{className:"agent-workspace__task-label",children:e.task}),e.status!==N.complete&&e.description&&n.jsx("span",{className:"agent-workspace__task-description",children:e.description})]})]});return n.jsxs("li",{className:P("agent-workspace__task",`agent-workspace__task--${i}`,{"agent-workspace__task--child":t>0}),children:[c?n.jsx("button",{type:"button",className:"agent-workspace__task-button","aria-label":`Provide input for ${e.task}`,onClick:()=>s(e),children:g}):g,e.children&&e.children.length>0&&n.jsx("ul",{className:"agent-workspace__task-children",children:e.children.map(w=>n.jsx(Ue,{item:w,depth:t+1,canRequestInput:a,onAttentionItemClick:s},w.task))})]})},Ce=({items:e,ariaLabel:t,canRequestInput:a,onAttentionItemClick:s})=>n.jsx("ul",{className:"agent-workspace__task-list","aria-label":t,children:e.map(r=>n.jsx(Ue,{item:r,depth:0,canRequestInput:a,onAttentionItemClick:s},r.task))}),xt=({checklist:e,isLoading:t,error:a,phase:s,canRequestInput:r,onStop:i,onAttentionItemClick:c})=>{const g=o.useMemo(()=>e?Le(e):null,[e]);return n.jsxs("section",{className:"agent-workspace__panel agent-workspace__panel--checklist","aria-label":"Checklist",children:[n.jsxs("div",{className:"agent-workspace__panel-header",children:[n.jsx(d.Heading,{level:4,children:"Checklist"}),s===b.running&&n.jsx(d.Button,{variant:"secondary-destructive",size:"S",iconLeftName:"circle-x",iconLeftScreenReaderText:"Stop",onClick:i,children:"Stop agent"})]}),n.jsxs("div",{className:"agent-workspace__panel-body","aria-live":"polite",children:[t&&n.jsxs("div",{className:"agent-workspace__loading",children:[n.jsx(d.Icon,{name:"loader",size:16,color:"var(--color-brand-600)",className:"agent-workspace__task-icon--spinning",screenReaderText:ee}),n.jsx("span",{children:ee})]}),!t&&a&&n.jsx("p",{className:"agent-workspace__error",role:"alert",children:a}),!t&&!a&&g&&n.jsxs(n.Fragment,{children:[g.needsInput.length>0&&n.jsxs("div",{className:"agent-workspace__task-group",children:[n.jsx("p",{className:"agent-workspace__task-group-label",children:"Needs your input"}),n.jsx(Ce,{items:g.needsInput,ariaLabel:"Tasks needing your input",canRequestInput:r,onAttentionItemClick:c})]}),g.tasks.length>0&&n.jsxs("div",{className:P("agent-workspace__task-group",{"agent-workspace__task-group--following":g.needsInput.length>0}),children:[g.needsInput.length>0&&n.jsx("p",{className:"agent-workspace__task-group-label",children:"Other tasks"}),n.jsx(Ce,{items:g.tasks,ariaLabel:"Agent tasks",canRequestInput:r,onAttentionItemClick:c})]})]}),!t&&!a&&(!g||g.needsInput.length===0&&g.tasks.length===0)&&n.jsx("p",{className:"agent-workspace__empty",children:s===b.briefing?"Tasks will appear here once the agent starts.":"No tasks to display."})]})]})},kt={[Z.MIS_RECORD]:{icon:"table",label:"Arbor MIS",color:"var(--color-brand-600)"},[Z.FILE]:{icon:"file",label:"File",color:"var(--color-semantic-caution-800)"},[Z.WORKFLOW]:{icon:"list-tree",label:"Workflow",color:"var(--color-semantic-warning-700)"},[Z.LINK]:{icon:"link",label:"Link",color:"var(--color-semantic-info-700)"}},At=({resources:e,isLoading:t=!1,error:a=null})=>n.jsxs("section",{className:"agent-workspace__panel agent-workspace__panel--documents","aria-label":"Resources",children:[n.jsxs("div",{className:"agent-workspace__panel-header",children:[n.jsx(d.Heading,{level:4,children:"Resources"}),n.jsx("span",{className:"agent-workspace__panel-count",children:e.length})]}),n.jsxs("div",{className:"agent-workspace__panel-body","aria-live":"polite",children:[t&&n.jsxs("div",{className:"agent-workspace__loading",children:[n.jsx(d.Icon,{name:"loader",size:16,color:"var(--color-brand-600)",className:"agent-workspace__task-icon--spinning",screenReaderText:"Loading resources"}),n.jsx("span",{children:"Loading resources…"})]}),!t&&a&&n.jsx("p",{className:"agent-workspace__error",role:"alert",children:a}),!t&&!a&&e.length>0&&n.jsx("ul",{className:"agent-workspace__resource-list","aria-label":"Agent resources",children:e.map(s=>{const r=kt[s.type];return n.jsx("li",{className:"agent-workspace__resource",children:n.jsxs("a",{className:"agent-workspace__resource-card",href:s.uri,target:"_blank",rel:"noreferrer",children:[n.jsx("span",{className:`agent-workspace__resource-icon agent-workspace__resource-icon--${s.type.toLowerCase()}`,children:n.jsx(d.Icon,{name:r.icon,size:16,color:r.color,screenReaderText:`${r.label}:`})}),n.jsxs("span",{className:"agent-workspace__resource-content",children:[n.jsxs("span",{className:"agent-workspace__resource-top",children:[n.jsx("span",{className:"agent-workspace__resource-name",children:s.name}),n.jsx("span",{className:`agent-workspace__resource-badge agent-workspace__resource-badge--${s.type.toLowerCase()}`,children:r.label})]}),s.description&&n.jsx("span",{className:"agent-workspace__resource-description",children:s.description})]}),n.jsx(d.Icon,{name:"external-link",size:12,color:"var(--color-grey-500)",screenReaderText:"Opens in a new tab",className:"agent-workspace__resource-open"})]})},`${s.type}-${s.uri}`)})}),!t&&!a&&e.length===0&&n.jsx("p",{className:"agent-workspace__empty",children:"No resources yet."})]})]}),St=["I'll get the details and come back to you","Skip this for now"],yt=e=>{var a;const t=(a=e.prompt)!=null&&a.trim()?e.prompt.trim():`I need a bit more from you on "${e.task}". ${e.description} What can you tell me?`;return{id:`clarification-${Date.now()}`,author:W.agent,text:t,followUpPrompts:e.clarificationPrompts??St}},ce=e=>({id:e.id,text:e.text,type:e.author===W.user?se.CHAT_RESPONSE_TYPE_USER:e.author===W.system?se.CHAT_RESPONSE_TYPE_INFO:se.CHAT_RESPONSE_TYPE_AGENT,...e.followUpPrompts?{followUpPrompts:e.followUpPrompts}:{}}),Nt=(e,t)=>{const a=e.hasRunBefore?t||"This trip":e.tripName.trim()||"A new trip",s=e.destination?` to ${e.destination}`:"",r=e.hasRunBefore?" It has run before.":"";return`${a}${s}.${r}`.trim()},jt=e=>{switch(e){case v.failed:return b.stopped;case v.complete:return b.complete;default:return b.running}},Ee=(e,t)=>{t([ce(e)])},$e=({agent:e,open:t,onClose:a,initialBrief:s,initialPhase:r,initialChecklist:i,fetchAgentChecklist:c,fetchAgentResources:g,connector:w})=>{const u=o.useRef(w),[p,m]=o.useState(r??(s?b.running:jt(e.status))),[x,T]=o.useState([]),[I,k]=o.useState(0),[M,y]=o.useState(),[L,D]=o.useState(null),[H,ae]=o.useState([]),[Q,J]=o.useState(!1),[A,j]=o.useState(null),[O,F]=o.useState(i??null),[G,B]=o.useState(!1),[R,re]=o.useState(null),[_e,V]=o.useState(!1),[q,me]=o.useState(!1),[z,fe]=o.useState(!1),K=o.useRef(!1);o.useEffect(()=>{u.current=w},[w]),o.useEffect(()=>{K.current=!1,T([]),k(h=>h+1)},[e.invocation_id]),o.useEffect(()=>{if(!t||s||K.current)return;const h=u.current.bootstrapConversation;if(!h){Ee(u.current.openingMessage(),T);return}K.current=!0;let S=!1;return V(!0),(async()=>{try{const X=await h.call(u.current);if(S)return;T(X.map(ce))}catch{S||Ee(u.current.openingMessage(),T)}finally{S||V(!1)}})(),()=>{S=!0}},[t,s,e.invocation_id,w]);const Y=o.useCallback(h=>{h.checklist&&F(h.checklist),h.phase&&m(h.phase)},[]);o.useEffect(()=>{var h,S;!t||s||i&&i.length>0&&((S=(h=u.current).seedChecklist)==null||S.call(h,i))},[t,s,i]),o.useEffect(()=>{if(!t||s||!c)return;let h=!1;return B(!(i!=null&&i.length)),re(null),(async()=>{var S,X;try{const oe=await c(e.invocation_id);if(h)return;i!=null&&i.length||(F(oe.checklist),(X=(S=u.current).seedChecklist)==null||X.call(S,oe.checklist))}catch{!h&&!(i!=null&&i.length)&&re(we)}finally{h||B(!1)}})(),()=>{h=!0}},[t,e.invocation_id,s,i,c]),o.useEffect(()=>{if(!t||!g)return;let h=!1;return J(!0),j(null),(async()=>{try{const S=await g(e.invocation_id);h||ae(S)}catch{h||j(at)}finally{h||J(!1)}})(),()=>{h=!0}},[t,e.invocation_id,g]),o.useEffect(()=>{if(!t||!s||K.current)return;K.current=!0;const h={id:`user-brief-${Date.now()}`,author:W.user,text:Nt(s,e.invocation_name)};(async()=>{const S=await u.current.start(s);T([ce(u.current.openingMessage()),ce(h),ce(S.message)]),S.checklist&&F(S.checklist),m(S.phase??b.running)})()},[t,s,e.invocation_name]);const de=o.useCallback(h=>{D(yt(h))},[]),ge=o.useCallback(h=>{D(null),y(h),k(S=>S+1)},[]),ue=o.useCallback(async()=>{await u.current.stop(),m(b.stopped)},[]),pe=O;return n.jsxs(d.Modal,{open:t,closeHandler:a,hideCloseButton:!0,className:"agent-workspace",children:[n.jsxs(d.Modal.Header,{className:"agent-workspace__header",children:[n.jsxs("div",{className:"agent-workspace__header-title",children:[n.jsx("span",{className:"agent-workspace__header-avatar","aria-hidden":"true",children:n.jsx(d.Icon,{name:"ask-arbor",size:24})}),n.jsx(d.Modal.Title,{children:e.invocation_name}),n.jsx("span",{className:P("agent-workspace__phase",`agent-workspace__phase--${p}`),children:ct[p]})]}),n.jsxs("div",{className:"agent-workspace__header-actions",children:[n.jsx(d.Button,{variant:"tertiary",size:"S",iconLeftName:"clipboard-list",iconLeftScreenReaderText:"Toggle checklist","aria-pressed":!z,onClick:()=>fe(h=>!h),children:"Checklist"}),n.jsx(d.Button,{variant:"tertiary",size:"S",iconLeftName:"files",iconLeftScreenReaderText:"Toggle resources","aria-pressed":!q,onClick:()=>me(h=>!h),children:"Resources"}),n.jsx(d.Button,{variant:"secondary",size:"S",iconLeftName:"x",iconLeftScreenReaderText:"Close",onClick:a,children:"Close"})]})]}),n.jsxs(d.Modal.Body,{className:P("agent-workspace__body",{"agent-workspace__body--no-left":z,"agent-workspace__body--no-right":q}),children:[!z&&n.jsx(xt,{checklist:pe,isLoading:G,error:R,phase:p,canRequestInput:p===b.running&&!_e,onStop:()=>void ue(),onAttentionItemClick:de}),n.jsx(wt,{connector:u.current,phase:p,chatHistory:x,chatSessionKey:I,startQuery:M,clarificationMessage:L,onTurn:Y,onAwaitingChange:V,onClarificationPrompt:ge,onDismissClarification:()=>D(null)}),!q&&n.jsx(At,{resources:H,isLoading:Q,error:A})]})]})},De=({open:e,onClose:t,onStart:a,agentDefinitions:s})=>{const r=s[0],[i,c]=o.useState(r),[g,w]=o.useState(""),[u,p]=o.useState(!1),[m,x]=o.useState(null),T=[...s].sort((y,L)=>y.agent_intent.localeCompare(L.agent_intent)).map(y=>({value:y.ref,label:y.agent_intent}));o.useEffect(()=>{e&&(c(r),w(""),p(!1),x(null))},[e,r]);const I=i!==void 0&&g.trim().length>0,k=o.useCallback(y=>{const L=s.find(D=>D.ref===y[0]);L&&c(L)},[s]),M=o.useCallback(async()=>{if(!(!i||!I||u)){p(!0),x(null);try{await a({definition:i,invocationName:g.trim()})}catch(y){x(y instanceof Error?y.message:"Unable to start the agent.")}finally{p(!1)}}},[I,i,g,u,a]);return!i||s.length===0?null:n.jsxs(d.Modal,{open:e,closeHandler:t,className:"new-agent",children:[n.jsx(d.Modal.Header,{className:"new-agent__header",children:n.jsxs("div",{className:"new-agent__header-title",children:[n.jsx("span",{className:"new-agent__header-avatar","aria-hidden":"true",children:n.jsx(d.Icon,{name:"ask-arbor",size:24})}),n.jsx(d.Modal.Title,{children:"Start an agent"})]})}),n.jsx(d.Modal.Body,{className:"new-agent__body",children:n.jsxs("form",{className:"new-agent__form","aria-label":"Start an agent",onSubmit:y=>{y.preventDefault(),I&&!u&&M()},children:[n.jsxs("div",{className:"new-agent__type-field",children:[n.jsx("label",{className:"new-agent__type-label",htmlFor:"new-agent-type",children:"What would you like your agent to do?"}),n.jsx(d.SelectDropdown,{id:"new-agent-type",placeholder:"Choose an intent",options:T,selectedValues:[i.ref],onSelectionChange:k}),n.jsx("p",{className:"new-agent__type-description",children:i.description})]}),n.jsxs("div",{className:"new-agent__type-field",children:[n.jsx("label",{className:"new-agent__type-label",htmlFor:"new-agent-invocation-name",children:"Name"}),n.jsx(d.TextInput,{id:"new-agent-invocation-name",value:g,placeholder:"e.g. Test with memory3",onChange:y=>w(y.target.value)})]}),m?n.jsx("p",{className:"new-agent__error",role:"alert",children:m}):null,n.jsx("div",{className:"new-agent__actions",children:n.jsx(d.Button,{type:"submit",variant:"primary",disabled:!I||u,iconLeftName:u?"loader":"sparkles",iconLeftScreenReaderText:u?"Starting":void 0,children:u?"Starting…":"Start"})})]})})]})};class te extends Error{constructor(t,a,s){super(s??`Agent service request failed (${t})`),this.name="AgentServiceError",this.status=t,this.detail=a}}const bt="/api/v1",C={agentDefinitions:"/agent-definitions",agents:"/agents",tripOptions:"/trip-options",demoDataset:"/demo/dataset"},E={GET:"GET",POST:"POST"},Ct={error:"error"},Et={user:"user"},ne={acceptJson:"application/json",acceptEventStream:"text/event-stream",contentTypeJson:"application/json",arborApplicationUrl:"X-Arbor-Application-Url"},Tt=/:invocationId\b/g,It=e=>e.trim().replace(/^Bearer\s+/i,""),Rt=e=>e.endsWith("/")?e.slice(0,-1):e;class He{constructor(t){var s;this.baseUrl=Rt(t.baseUrl);const a=(s=t.token)==null?void 0:s.trim();this.token=a?It(a):void 0,this.customHeaders=t.headers,this.urls=t.urls??{},this.fetchImpl=t.fetch??globalThis.fetch.bind(globalThis)}setHeaders(t){this.customHeaders=t}async listAgentDefinitions(){return(await this.request(E.GET,this.resolveUrl("agentDefinitions",C.agentDefinitions))).agent_definitions??[]}getAgentDefinition(t){return this.request(E.GET,this.apiUrl(`${C.agentDefinitions}/${encodeURIComponent(t)}`))}listTripOptions(){return this.request(E.GET,this.apiUrl(C.tripOptions))}getDataset(){return this.request(E.GET,this.apiUrl(C.demoDataset))}setDataset(t){return this.request(E.POST,this.apiUrl(C.demoDataset),{dataset:t})}listAgents(t={}){const a=new URLSearchParams;t.status&&a.set("status",t.status),t.agentDefinitionRef&&a.set("agent_definition_ref",t.agentDefinitionRef);const s=a.toString()?`?${a.toString()}`:"";return this.request(E.GET,`${this.resolveUrl("agents",C.agents)}${s}`)}createAgent(t,a={}){var c,g;const s={agent_definition_ref:t},r=(c=a.invocationName)==null?void 0:c.trim(),i=(g=a.agentIntent)==null?void 0:g.trim();return r&&(s.invocation_name=r),i&&(s.agent_intent=i),this.request(E.POST,this.resolveUrl("agents",C.agents),s)}getAgent(t){return this.request(E.GET,this.resolveUrl("agent",`${C.agents}/${encodeURIComponent(t)}`,t))}getAgentChecklist(t){return this.request(E.GET,this.resolveUrl("agentChecklist",`${C.agents}/${encodeURIComponent(t)}/checklist`,t))}getAgentResources(t){return this.request(E.GET,this.resolveUrl("agentResources",`${C.agents}/${encodeURIComponent(t)}/resources`,t))}getAgentContext(t){return this.request(E.GET,this.apiUrl(`${C.agents}/${encodeURIComponent(t)}/context`))}cancelAgent(t){return this.request(E.POST,this.apiUrl(`${C.agents}/${encodeURIComponent(t)}/cancel`))}archiveAgent(t){return this.request(E.POST,this.apiUrl(`${C.agents}/${encodeURIComponent(t)}/archive`))}async chat(t,a,s={}){const r=await this.fetchImpl(this.resolveUrl("agentChat",`${C.agents}/${encodeURIComponent(t)}/chat`,t),{method:E.POST,headers:{...this.customHeaders,...this.authHeaders(),Accept:ne.acceptEventStream,"Content-Type":ne.contentTypeJson},body:JSON.stringify(a),signal:s.signal});if(!r.ok)throw await this.toError(r);if(!r.body)throw new te(r.status,null,"Chat response contained no stream body");return this.consumeSse(r.body,s.onEvent)}authHeaders(){return this.token?{Authorization:`Bearer ${this.token}`}:{}}apiUrl(t){return`${this.baseUrl}${bt}${t}`}resolveUrl(t,a,s){const r=this.urls[t];return r?s?r.replace(Tt,encodeURIComponent(s)):r:this.apiUrl(a)}async request(t,a,s){const r=await this.fetchImpl(a,{method:t,headers:{...this.customHeaders,...this.authHeaders(),Accept:ne.acceptJson,...s===void 0?{}:{"Content-Type":ne.contentTypeJson}},...s===void 0?{}:{body:JSON.stringify(s)}});if(!r.ok)throw await this.toError(r);if(r.status!==204)return await r.json()}async toError(t){let a=null;try{a=await t.json()}catch{}return new te(t.status,a,`Agent service request failed (${t.status} ${t.statusText})`)}async consumeSse(t,a){const s=t.getReader(),r=new TextDecoder;let i="",c;const g=w=>{const{event:u,data:p}=Ot(w);if(p===null)return;if(u===Ct.error){const x=Te(p);throw new te(502,x,(x==null?void 0:x.message)??"Chat stream error")}const m=Te(p);m&&(c=m,a==null||a(m))};for(;;){const{done:w,value:u}=await s.read();if(w)break;i+=r.decode(u,{stream:!0});const p=i.split(`
2
+
3
+ `);i=p.pop()??"";for(const m of p)g(m)}if(i.trim()&&g(i),!c)throw new te(502,null,"Chat stream ended without any events");return c}}const Ot=e=>{let t=null;const a=[];for(const s of e.split(`
4
+ `)){const r=s.trimEnd();r.startsWith("event:")?t=r.slice(6).trim():r.startsWith("data:")&&a.push(r.slice(5).trim())}return{event:t,data:a.length>0?a.join(`
5
+ `):null}},Te=e=>{try{return JSON.parse(e)}catch{return}},Pt={id:Pe,author:W.agent,text:"I'm connected to this agent. Ask me how it's progressing, or send an instruction and I’ll act on it."};let Ie=0;const Re=e=>(Ie+=1,`${e}-${Date.now()}-${Ie}`),Mt=e=>{const t=e.destination?` to ${e.destination}`:"";return`Let's get started on ${e.tripName.trim()||e.destination.trim()||"this task"}${t}. What will you do first?`};class Fe{constructor(t,a,s={}){this.seededChecklist=[],this.client=t,this.agentId=a,this.opening=s.openingMessage??Pt,this.model=s.model,this.bootstrapPrompt=s.bootstrapPrompt??it}openingMessage(){return this.opening}async bootstrapConversation(t=this.bootstrapPrompt){const a=t.trim();if(!a)return[this.opening];const s={id:Re("msg-user"),author:W.user,text:a},r=await this.exchange(a);return[s,r.message]}async start(t){return{...await this.exchange(Mt(t)),phase:b.running}}sendMessage(t){return this.exchange(t)}async stop(){}seedChecklist(t){this.seededChecklist=t}async exchange(t){var i;const a=[{role:Et.user,content:t}],s=await this.client.chat(this.agentId,{messages:a,...this.chatId?{chat_id:this.chatId}:{},...this.model?{model:this.model}:{},moderation_enabled:!0,meta:{feature_id:"agent_view",source:"agent_view_frontend"}});return this.chatId=s.chat_id,{message:{id:s.event_id||Re("msg-agent"),author:W.agent,text:s.message.content,...(i=s.follow_up_prompts)!=null&&i.length?{followUpPrompts:s.follow_up_prompts}:{}}}}}const Be=(e,t)=>a=>{var s;return new Fe(e,a.invocation_id,{model:t==null?void 0:t.model,bootstrapPrompt:t==null?void 0:t.bootstrapPrompt,openingMessage:((s=t==null?void 0:t.resolveOpeningMessage)==null?void 0:s.call(t,a))??(t==null?void 0:t.openingMessage)})},Ge=e=>{switch(e){case je.cancelled:return v.failed;case je.archived:return v.complete;case v.hitl:case v.complete:case v.failed:case v["generating-a-response"]:return e;default:return v["generating-a-response"]}},qe=e=>{switch(e){case ve.requires_attention:return N.hitl;case ve.in_progress:case ve.available:return N["generating-a-response"];case N.failed:case N.complete:case N.hitl:case N["generating-a-response"]:return e;default:return N["generating-a-response"]}},ze=e=>({ref:e.name,display_name:e.display_name,agent_intent:e.agent_intent??e.display_name,description:e.description}),Lt=e=>({id:e.id,name:e.name,...e.has_run_before?{hasRunBefore:e.has_run_before}:{}}),Ut=new Set(Object.values(Z)),$t=e=>e&&Ut.has(e)?e:Z.LINK,Ke=e=>({uri:e.uri??"",type:$t(e.type),name:e.name??"",description:e.description??""}),We=e=>(Array.isArray(e)?e:e.resources??[]).map(Ke),xe=e=>{var a;const t=e.invocation_id??e.id;return{id:e.id,invocation_id:t,agent_definition_ref:e.agent_definition_ref,...e.agent_intent?{agent_intent:e.agent_intent}:{},invocation_name:((a=e.invocation_name)==null?void 0:a.trim())||e.agent_definition_ref,application_id:e.application_id,...e.application_name?{application_name:e.application_name}:{},created_by:e.created_by,status:Ge(e.status),context_ref:e.context_ref??null,checklist_ref:e.checklist_ref??null}},Ae=e=>{var t;return{task:e.task??e.name??e.label??ot,status:qe(e.status),description:e.description??"",...e.prompt?{prompt:e.prompt}:{},...(t=e.follow_up_prompts)!=null&&t.length?{clarificationPrompts:e.follow_up_prompts}:{}}},Dt=e=>Array.isArray(e)?e:e.checklist_items??e.checklist??e.items??[],Je=(e,t,a)=>{var i;const s=!Array.isArray(t)&&(t.opening_message||(i=t.opening_follow_up_prompts)!=null&&i.length)?t:a,r=s?le(s):void 0;return{invocation_id:e,checklist:Dt(t).map(Ae),...r?{openingMessage:r}:{}}},Ht=(e,t)=>{const a=le(t);return{invocation_id:t.invocation_id??e,checklist:(t.checklist_items??[]).map(Ae),...a?{openingMessage:a}:{}}},le=e=>{var a,s;const t=(a=e.opening_message)==null?void 0:a.trim();if(t)return{id:Pe,author:W.agent,text:t,...(s=e.opening_follow_up_prompts)!=null&&s.length?{followUpPrompts:e.opening_follow_up_prompts}:{}}},Ft=e=>e instanceof te?e.message:e instanceof TypeError?"Network error while contacting the agent service.":e instanceof Error&&e.message?e.message:Me,Bt=e=>{const t={};for(const a of e){const s=le(a);if(!s)continue;const r=a.invocation_id??a.id;t[r]=s,t[a.id]=s}return t},Gt=e=>JSON.stringify(e),Ve=e=>{const{jwt:t,headers:a,urls:s}=e,r=JSON.stringify(a??{}),i=Gt(s),c=o.useMemo(()=>{const{baseUrl:A,...j}=s;return new He({baseUrl:A,token:t,headers:a,urls:j})},[t,i]);o.useLayoutEffect(()=>{c.setHeaders(a)},[c,r]);const[g,w]=o.useState([]),[u,p]=o.useState([]),[m,x]=o.useState({}),[T,I]=o.useState("loading"),[k,M]=o.useState(null),[y,L]=o.useState(0);o.useEffect(()=>{let A=!1;return I("loading"),M(null),(async()=>{try{const[j,O]=await Promise.all([c.listAgents(),c.listAgentDefinitions()]);if(A)return;w(j.map(xe)),p(O.map(ze)),x(Bt(j)),I("idle")}catch(j){if(A)return;w([]),p([]),x({}),I("error"),M(Ft(j))}})(),()=>{A=!0}},[c,y]);const D=o.useCallback(()=>{L(A=>A+1)},[]),H=o.useCallback(async A=>{const[j,O]=await Promise.all([c.getAgentChecklist(A),c.getAgent(A).catch(()=>null)]);return Je(A,j,O??void 0)},[c]),ae=o.useCallback(async A=>{const j=await c.getAgentResources(A);return We(j)},[c]),Q=o.useCallback(async({definition:A,invocationName:j})=>{const O=await c.createAgent(A.ref,{invocationName:j}),F=await c.getAgent(O.id),G=xe(F),B=le(F);return w(R=>[G,...R]),B&&x(R=>({...R,[G.invocation_id]:B,[G.id]:B})),G},[c]),J=o.useMemo(()=>Be(c,{resolveOpeningMessage:A=>m[A.invocation_id]??m[A.id]}),[c,m]);return{agents:g,agentDefinitions:u,loadState:T,loadError:k,reload:D,fetchAgentChecklist:H,fetchAgentResources:ae,createAgent:Q,chatConnector:J}},qt=e=>e!==void 0&&e.some(t=>t.status===N.hitl),zt=(e,t)=>qt(t)?v.hitl:e.status,Kt=({column:e,label:t})=>e.statusIcon?n.jsx("span",{className:"agent-view__status-indicator",children:n.jsx(d.Icon,{name:e.statusIcon.name,size:16,color:e.statusIcon.color,className:P({"agent-view__progress-icon--spinning":e.statusIcon.spin}),screenReaderText:t})}):n.jsx("span",{className:P("agent-view__dot",{[`agent-view__dot--${e.dotModifier}`]:e.dotModifier}),children:n.jsx(d.Dot,{colour:e.dotColour,label:t})}),Wt=({agent:e,agentName:t,column:a,isExpanded:s,isLoading:r,checklist:i,error:c,onToggle:g,onViewAgent:w})=>{const{id:u,invocation_name:p}=e,m=`agent-card-${u}-header`,x=`agent-card-${u}-progress`;return n.jsx("li",{className:P("agent-view__card",{"agent-view__card--expanded":s}),children:n.jsxs(d.Card,{spacing:"dense",children:[n.jsx("button",{type:"button",className:"agent-view__card-toggle","aria-expanded":s,"aria-controls":x,"aria-label":p,id:m,onClick:()=>g(u),children:n.jsxs("div",{className:"agent-view__card-content",children:[n.jsx(Kt,{column:a}),n.jsx("span",{className:"agent-view__card-invocation-name",children:p}),n.jsx("span",{className:"agent-view__card-agent-name",children:t}),n.jsx(d.Icon,{name:s?"chevron-up":"chevron-down",size:16,className:"agent-view__card-chevron"})]})}),s&&n.jsxs("div",{id:x,"aria-labelledby":m,className:"agent-view__card-progress",children:[r&&n.jsxs("div",{className:"agent-view__progress-loading","aria-live":"polite",children:[n.jsx(d.Icon,{name:"loader",size:16,color:"var(--color-brand-600)",className:"agent-view__progress-icon--spinning",screenReaderText:ee}),n.jsx("span",{children:ee})]}),!r&&c&&n.jsx("p",{className:"agent-view__progress-error",role:"alert",children:c}),!r&&!c&&i!==null&&n.jsx(mt,{checklist:i}),!r&&!c&&i===null&&n.jsxs("div",{className:"agent-view__progress-loading","aria-live":"polite",children:[n.jsx(d.Icon,{name:"loader",size:16,color:"var(--color-brand-600)",className:"agent-view__progress-icon--spinning",screenReaderText:ee}),n.jsx("span",{children:ee})]}),n.jsx("div",{className:"agent-view__card-actions",children:n.jsx(d.Button,{variant:"secondary",size:"S",onClick:()=>w==null?void 0:w(e),children:"View agent"})})]})]})})},Oe=({column:e,agents:t,expandedAgentId:a,loadingAgentId:s,checklistByInvocationId:r,errorByAgentId:i,definitionNameByRef:c,onToggleAgent:g,onViewAgent:w,isSplit:u=!1})=>n.jsxs("section",{className:P("agent-view__column",{"agent-view__column--split":u}),"aria-label":e.title,children:[n.jsxs("div",{className:"agent-view__column-header",children:[n.jsx(d.Heading,{level:4,children:e.title}),n.jsx("span",{className:"agent-view__column-count",children:t.length})]}),n.jsx("ul",{className:"agent-view__card-list",children:t.map(p=>n.jsx(Wt,{agent:p,agentName:ke(p,c),column:e,isExpanded:a===p.id,isLoading:s===p.id,checklist:r[p.invocation_id]??null,error:i[p.id]??null,onToggle:g,onViewAgent:w},p.id))})]}),ke=(e,t)=>t.get(e.agent_definition_ref)??e.agent_definition_ref.replace(/_/g," "),Jt=({jwt:e,headers:t,baseUrl:a,agentDefinitionsUrl:s,agentsUrl:r,agentUrl:i,agentChecklistUrl:c,agentResourcesUrl:g,agentChatUrl:w,institutions:u})=>{var Ne;const p=o.useMemo(()=>({baseUrl:a,...s?{agentDefinitions:s}:{},...r?{agents:r}:{},...i?{agent:i}:{},...c?{agentChecklist:c}:{},...g?{agentResources:g}:{},...w?{agentChat:w}:{}}),[a,s,r,i,c,g,w]),[m,x]=o.useState(null),T=m?(Ne=u==null?void 0:u.find(l=>l.applicationId===m.application_id))==null?void 0:Ne.applicationUrl:void 0,I=o.useMemo(()=>{const l={...t??{}};return T?l[ne.arborApplicationUrl]=T:delete l[ne.arborApplicationUrl],l},[t,T]),{agents:k,agentDefinitions:M,loadState:y,loadError:L,reload:D,fetchAgentChecklist:H,fetchAgentResources:ae,createAgent:Q,chatConnector:J}=Ve({jwt:e,headers:I,urls:p}),[A,j]=o.useState(!1),[O,F]=o.useState(null),[G,B]=o.useState(null),[R,re]=o.useState({}),[_e,V]=o.useState({}),[q,me]=o.useState([]),[z,fe]=o.useState([]),K=o.useMemo(()=>{const l=new Set(k.map(_=>_.application_id)),f=new Map((u??[]).map(_=>[_.applicationId,_.name]));return[...l].sort((_,U)=>(f.get(_)??_).localeCompare(f.get(U)??U)).map(_=>({value:_,label:f.get(_)??_}))},[k,u]),Y=o.useMemo(()=>new Map(M.map(l=>[l.ref,l.display_name])),[M]),de=o.useMemo(()=>[...new Set(k.map(f=>ke(f,Y)))].sort((f,_)=>f.localeCompare(_)).map(f=>({value:f,label:f})),[k,Y]),ge=o.useMemo(()=>k.filter(l=>!(q.length>0&&!q.includes(l.application_id)||z.length>0&&!z.includes(ke(l,Y)))),[k,Y,z,q]),ue=K.length>1,pe=de.length>1,h=ue||pe;o.useEffect(()=>{if(k.length===0)return;let l=!1;return(async()=>{const f=await Promise.allSettled(k.map(async _=>{const U=await H(_.invocation_id);return{agentId:_.id,invocationId:_.invocation_id,checklist:U.checklist}}));l||(re(_=>{const U={..._};for(const ie of f)ie.status==="fulfilled"&&(U[ie.value.invocationId]=ie.value.checklist);return U}),V(_=>{const U={..._};return f.forEach((ie,Ze)=>{ie.status==="rejected"&&(U[k[Ze].id]=we)}),U}))})(),()=>{l=!0}},[k,H]);const S=o.useCallback(async l=>{if(!R[l.invocation_id]){B(l.id),V(f=>{const _={...f};return delete _[l.id],_});try{const f=await H(l.invocation_id);re(_=>({..._,[l.invocation_id]:f.checklist}))}catch{V(f=>({...f,[l.id]:we}))}finally{B(f=>f===l.id?null:f)}}},[H,R]),X=o.useCallback(l=>{if(O===l){F(null);return}const f=k.find(({id:_})=>_===l);f&&(F(l),S(f))},[k,O,S]),oe=o.useMemo(()=>{const l={};for(const f of ge){const _=zt(f,R[f.invocation_id]);(l[_]??(l[_]=[])).push(f)}return l},[ge,R]),Ye=o.useCallback(l=>{x(l)},[]),Qe=o.useCallback(async l=>{const f=await Q(l);x(f),j(!1)},[Q]),Xe=o.useCallback(()=>{x(null)},[]),Se=o.useMemo(()=>m?J(m):void 0,[J,m]),ye={expandedAgentId:O,loadingAgentId:G,checklistByInvocationId:R,errorByAgentId:_e,definitionNameByRef:Y,onToggleAgent:X,onViewAgent:Ye};return n.jsxs("div",{className:"agent-view-frontend agent-view",children:[n.jsxs("div",{className:"agent-view__header",children:[n.jsx(d.Heading,{level:1,children:"Agents"}),n.jsx(d.Button,{variant:"primary",size:"S",iconLeftName:"sparkles",iconLeftScreenReaderText:"Start an agent",onClick:()=>j(!0),children:"Start an agent"})]}),k.length>0&&h&&n.jsxs("div",{className:"agent-view__filters",children:[ue&&n.jsxs("div",{className:"agent-view__filter",children:[n.jsx("label",{className:"agent-view__filter-label",htmlFor:"agent-view-institution-filter",children:"Institution"}),n.jsx(d.Combobox,{id:"agent-view-institution-filter",triggerVariant:"button",multiple:!0,searchType:"substring",placeholder:"All institutions",options:K,value:q,onValueChange:me,showSelectionCountBadge:!0,showClearAll:!0,clearAllLabel:"Clear institutions"})]}),pe&&n.jsxs("div",{className:"agent-view__filter",children:[n.jsx("label",{className:"agent-view__filter-label",htmlFor:"agent-view-agent-filter",children:"Agent"}),n.jsx(d.Combobox,{id:"agent-view-agent-filter",triggerVariant:"button",multiple:!0,searchType:"substring",placeholder:"All agents",options:de,value:z,onValueChange:fe,showSelectionCountBadge:!0,showClearAll:!0,clearAllLabel:"Clear agents"})]})]}),y==="error"?n.jsxs("div",{className:"agent-view__state agent-view__state--error",role:"alert",children:[n.jsx(d.Icon,{name:"triangle-alert",size:24,color:"var(--color-semantic-destructive-600)"}),n.jsx("p",{className:"agent-view__state-message",children:L??Me}),n.jsx(d.Button,{variant:"secondary",size:"S",onClick:D,children:"Try again"})]}):y==="loading"&&k.length===0?n.jsxs("div",{className:"agent-view__state","aria-live":"polite",children:[n.jsx(d.Icon,{name:"loader",size:24,color:"var(--color-brand-600)",className:"agent-view__progress-icon--spinning",screenReaderText:be}),n.jsx("p",{className:"agent-view__state-message",children:be})]}):k.length===0?n.jsx(pt,{}):n.jsxs("div",{className:"agent-view__board",children:[et.map(l=>n.jsx(Oe,{column:he[l],agents:oe[l]??[],...ye},l)),n.jsx("div",{className:"agent-view__split-column",children:tt.map(l=>n.jsx(Oe,{column:he[l],agents:oe[l]??[],isSplit:!0,...ye},l))})]}),m&&Se&&n.jsx($e,{agent:m,open:!0,initialChecklist:R[m.invocation_id]??null,fetchAgentChecklist:H,fetchAgentResources:ae,onClose:Xe,connector:Se},m.id),n.jsx(De,{open:A,onClose:()=>j(!1),onStart:Qe,agentDefinitions:M})]})},Vt=(e,t)=>{const a=Date.now(),s=t.trim()||e.agent_intent;return{id:`agent-${a}`,invocation_id:`inv-${a}`,agent_definition_ref:e.ref,agent_intent:e.agent_intent,invocation_name:s,application_id:nt,created_by:st,status:v["generating-a-response"],context_ref:null,checklist_ref:null}};exports.AgentMonitorKanban=Jt;exports.AgentServiceClient=He;exports.AgentServiceError=te;exports.AgentView=$e;exports.HttpChatConnector=Fe;exports.NewAgentModal=De;exports.buildAgentFromDefinition=Vt;exports.createHttpChatConnectorFactory=Be;exports.mapApiAgent=xe;exports.mapApiAgentDefinition=ze;exports.mapApiAgentStatus=Ge;exports.mapApiChecklistEndpointResponse=Je;exports.mapApiChecklistItem=Ae;exports.mapApiChecklistResponse=Ht;exports.mapApiChecklistStatus=qe;exports.mapApiOpeningMessage=le;exports.mapApiResource=Ke;exports.mapApiResourcesEndpointResponse=We;exports.mapApiTripOption=Lt;exports.useAgentService=Ve;