@flexkit/studio 0.2.38 → 0.2.39

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 (74) hide show
  1. package/README.md +76 -7
  2. package/dist/{chat-page-DW3FP4UZ.js → chat-page-2ES466GO.js} +3 -3
  3. package/dist/{chat-page-DW3FP4UZ.js.map → chat-page-2ES466GO.js.map} +1 -1
  4. package/dist/{chunk-JUWAKQPE.js → chunk-7FYOLFHG.js} +3 -3
  5. package/dist/{chunk-JUWAKQPE.js.map → chunk-7FYOLFHG.js.map} +1 -1
  6. package/dist/{chunk-UOTVVZPA.js → chunk-CESG6WQB.js} +3 -3
  7. package/dist/{chunk-UOTVVZPA.js.map → chunk-CESG6WQB.js.map} +1 -1
  8. package/dist/{chunk-DSZJXMN5.js → chunk-DQ2OVNOB.js} +2 -2
  9. package/dist/{chunk-DSZJXMN5.js.map → chunk-DQ2OVNOB.js.map} +1 -1
  10. package/dist/{chunk-IUWDNPMY.js → chunk-DR36N2JC.js} +2 -2
  11. package/dist/{chunk-IUWDNPMY.js.map → chunk-DR36N2JC.js.map} +1 -1
  12. package/dist/{chunk-IJECATW3.js → chunk-DUS2CRB3.js} +2 -2
  13. package/dist/{chunk-IJECATW3.js.map → chunk-DUS2CRB3.js.map} +1 -1
  14. package/dist/{chunk-3GXM5SSM.js → chunk-JJFOUJMQ.js} +3 -3
  15. package/dist/{chunk-3GXM5SSM.js.map → chunk-JJFOUJMQ.js.map} +1 -1
  16. package/dist/{chunk-AQBULUC2.js → chunk-KWE3LHFM.js} +4 -4
  17. package/dist/{chunk-AQBULUC2.js.map → chunk-KWE3LHFM.js.map} +1 -1
  18. package/dist/{chunk-GSKQHFQM.js → chunk-MGCXYA2S.js} +3 -3
  19. package/dist/{chunk-GSKQHFQM.js.map → chunk-MGCXYA2S.js.map} +1 -1
  20. package/dist/{chunk-CCVE7GGO.js → chunk-PR3MTHFM.js} +2 -2
  21. package/dist/{chunk-CCVE7GGO.js.map → chunk-PR3MTHFM.js.map} +1 -1
  22. package/dist/{chunk-32B35YDF.js → chunk-R7EOMV6C.js} +3 -3
  23. package/dist/{chunk-32B35YDF.js.map → chunk-R7EOMV6C.js.map} +1 -1
  24. package/dist/{chunk-GORBKX24.js → chunk-SAVZBVP5.js} +3 -3
  25. package/dist/{chunk-GORBKX24.js.map → chunk-SAVZBVP5.js.map} +1 -1
  26. package/dist/{chunk-6J3ZIVDQ.js → chunk-SGQMQZIW.js} +2 -2
  27. package/dist/{chunk-6J3ZIVDQ.js.map → chunk-SGQMQZIW.js.map} +1 -1
  28. package/dist/{chunk-LMJEP4VR.js → chunk-TOISBMRE.js} +2 -2
  29. package/dist/{chunk-LMJEP4VR.js.map → chunk-TOISBMRE.js.map} +1 -1
  30. package/dist/{chunk-INZZOKRC.js → chunk-TP6QGIJH.js} +3 -3
  31. package/dist/{chunk-INZZOKRC.js.map → chunk-TP6QGIJH.js.map} +1 -1
  32. package/dist/{chunk-377TM7UG.js → chunk-U3PTPLSE.js} +2 -2
  33. package/dist/{chunk-377TM7UG.js.map → chunk-U3PTPLSE.js.map} +1 -1
  34. package/dist/{chunk-4OGLWOO3.js → chunk-VR3LFFJ3.js} +3 -3
  35. package/dist/{chunk-4OGLWOO3.js.map → chunk-VR3LFFJ3.js.map} +1 -1
  36. package/dist/{chunk-WYVXSLB7.js → chunk-WSXNYZQC.js} +2 -2
  37. package/dist/{chunk-WYVXSLB7.js.map → chunk-WSXNYZQC.js.map} +1 -1
  38. package/dist/{chunk-KV4OGH5U.js → chunk-Z7JAN2UW.js} +2 -2
  39. package/dist/{chunk-KV4OGH5U.js.map → chunk-Z7JAN2UW.js.map} +1 -1
  40. package/dist/{entry-G2R3W5NU.js → entry-ZYSQFFEW.js} +2 -2
  41. package/dist/{entry-G2R3W5NU.js.map → entry-ZYSQFFEW.js.map} +1 -1
  42. package/dist/index.js +2 -2
  43. package/dist/{list-IRTUEW55.js → list-4EXGXJZA.js} +2 -2
  44. package/dist/{list-IRTUEW55.js.map → list-4EXGXJZA.js.map} +1 -1
  45. package/dist/{list-LVXMUJHP.js → list-XTC2OYA6.js} +3 -3
  46. package/dist/{list-LVXMUJHP.js.map → list-XTC2OYA6.js.map} +1 -1
  47. package/dist/{pages-HJHR7DFO.js → pages-HW4OCENA.js} +3 -3
  48. package/dist/{pages-HJHR7DFO.js.map → pages-HW4OCENA.js.map} +1 -1
  49. package/dist/{plugin-pages-ZO3TLUYW.js → plugin-pages-CUTCB6NU.js} +2 -2
  50. package/dist/{plugin-pages-ZO3TLUYW.js.map → plugin-pages-CUTCB6NU.js.map} +1 -1
  51. package/dist/{project-selector-OXDEHTJ5.js → project-selector-Z4Q6G6GM.js} +2 -2
  52. package/dist/{project-selector-OXDEHTJ5.js.map → project-selector-Z4Q6G6GM.js.map} +1 -1
  53. package/dist/record-links-DBU5G6ZH.js +2 -0
  54. package/dist/{record-links-SZQUATM6.js.map → record-links-DBU5G6ZH.js.map} +1 -1
  55. package/dist/{root-MMGPZ4ZF.js → root-3Q44ISGQ.js} +3 -3
  56. package/dist/{root-MMGPZ4ZF.js.map → root-3Q44ISGQ.js.map} +1 -1
  57. package/dist/{root-BIUU3CXY.js → root-422O7YX5.js} +3 -3
  58. package/dist/{root-BIUU3CXY.js.map → root-422O7YX5.js.map} +1 -1
  59. package/dist/{root-E4GIVJYA.js → root-7FYWXLI6.js} +3 -3
  60. package/dist/{root-E4GIVJYA.js.map → root-7FYWXLI6.js.map} +1 -1
  61. package/dist/{root-P537YXFS.js → root-7NZPP7IC.js} +2 -2
  62. package/dist/{root-P537YXFS.js.map → root-7NZPP7IC.js.map} +1 -1
  63. package/dist/{root-BRIEXCDH.js → root-Q6SHODPG.js} +2 -2
  64. package/dist/{root-BRIEXCDH.js.map → root-Q6SHODPG.js.map} +1 -1
  65. package/dist/{root-4ATHF5ZZ.js → root-SYRZ3UBN.js} +2 -2
  66. package/dist/{root-4ATHF5ZZ.js.map → root-SYRZ3UBN.js.map} +1 -1
  67. package/dist/{search-57W7MXQ3.js → search-X7F5JZOU.js} +2 -2
  68. package/dist/{search-57W7MXQ3.js.map → search-X7F5JZOU.js.map} +1 -1
  69. package/dist/{skills-pages-LUOBTEAP.js → skills-pages-X3DVZXY5.js} +2 -2
  70. package/dist/{skills-pages-LUOBTEAP.js.map → skills-pages-X3DVZXY5.js.map} +1 -1
  71. package/dist/{source-CJPY5PTU.js → source-43PHAELP.js} +2 -2
  72. package/dist/{source-CJPY5PTU.js.map → source-43PHAELP.js.map} +1 -1
  73. package/package.json +6 -6
  74. package/dist/record-links-SZQUATM6.js +0 -2
package/README.md CHANGED
@@ -13,18 +13,80 @@
13
13
 
14
14
  </div>
15
15
 
16
- **The open-source React platform for building internal tools, PIMs, CRMs, ERPs, and custom business data apps - fast.**
16
+ **The AI operating system for e-commerce.**
17
17
 
18
- ⸻
18
+ Your data, context, workflows and agents in one system. Flexkit connects the tools you already use, learns how your store works, runs it around the clock and gets smarter with every outcome.
19
19
 
20
- Flexkit is a schema-driven, developer-first platform for modeling and managing structured business data.
21
- Define your data model once, sync it, and instantly get a fully-featured admin UI, a GraphQL API on top of a graph database, and a modern Studio where teams can create, explore, and relate business entities with ease.
20
+ This repository holds the open-source parts of Flexkit: the **Studio** (a React app you can mount inside your own app), the **CLI** and the **SDK** for defining your data model and your own agent tools. They are MIT-licensed. The data backend and the agent are hosted by Flexkit.
22
21
 
23
- Build production-ready internal tools, PIMs, CRMs, and complex admin interfaces in a fraction of the time — without sacrificing flexibility or developer control.
22
+ [Website](https://flexkit.io) · [Documentation](https://flexkit.io/docs) · [Discussions](https://github.com/orgs/flexkit-io/discussions)
24
23
 
25
- ## Getting Started
24
+ ## One system, six layers
26
25
 
27
- Visit [https://flexkit.io/docs](https://flexkit.io/docs) to view the full documentation.
26
+ Flexkit holds your business data and the context around it. It picks the right model for each task and runs agents across the tools you already use. Your team sets the limits.
27
+
28
+ | Layer | What it does |
29
+ | --------------- | ------------------------------------------------------------------------------------------------------------------- |
30
+ | **Data** | Your products, orders, customers and suppliers as linked records, so agents see how everything connects. |
31
+ | **Context** | Your documents, written rules and past decisions, so agents cite their sources and work the way your team does. |
32
+ | **Models** | Models from OpenAI, Anthropic, Google and xAI. Flexkit picks one for each task, or you choose your own. |
33
+ | **Agents** | Automations that run on a schedule or a trigger, and ask first before changing what you have not allowed. |
34
+ | **Connections** | Plugins from Shopify and Stripe to Slack and Google Workspace, plus access from Claude, ChatGPT and any MCP client. |
35
+ | **Control** | Roles set what each person can do, spaces set what they can see, and every run leaves a transcript to read. |
36
+
37
+ ## What you get
38
+
39
+ - **Your business, connected.** Flexkit stores your business as a graph of the records you choose (products, orders, customers, suppliers or anything else) with the relationships between them as first-class data. An agent answers by walking that graph, from a low-stock alert to the open orders it affects to the supplier who can refill it.
40
+ - **Keep your systems, connect their data.** Your shop, ERP and CRM stay where they are. Sync what matters to Flexkit through its GraphQL API or a plugin, and Flexkit links it into one record.
41
+ - **It learns how your business works.** Drop in supplier PDFs, return policies and price lists, and the agent reads them and cites the passage. Write your rules once as skills, and every chat and automation follows them. What the team keeps agreeing on becomes shared memory.
42
+ - **Ask anything, get a real answer.** The agent answers from your own records, querying the live data each time. It charts the result, exports it as a file, and changes records once you approve. When it needs a decision, it asks instead of guessing.
43
+ - **Runs your business around the clock.** Anything you would ask twice can run on its own: every morning, when an order comes in, when stock drops, or when another system sends a signal. Results go to Slack or Teams, and changes you have not allowed wait for a yes.
44
+ - **The right model for each job.** A quick model for a lookup, a stronger one for a long run. Choose a model yourself for any chat or automation, and switch the day a better one ships.
45
+ - **Your team stays in control.** Five built-in roles say what someone may do. Spaces say what they may see, down to a single field, and the same rule holds in tables, in chat, in automations, in the API and in AI clients.
46
+
47
+ And everything around it:
48
+
49
+ - **Describe your business, get a data model.** The agent proposes the record types and the links between them; nothing changes until you approve.
50
+ - **One record, every market.** Keep a price, a name or a description per market or language, with a default to fall back on.
51
+ - **A thousand records in one ask.** Reprice a collection or retag a season. Flexkit counts what will change first and runs it in the background once you approve.
52
+ - **Reports you can send.** Ask for a report and get a page or a PDF, with a link that keeps working.
53
+ - **Type it, say it or attach it.** Dictate a question, or drop in a photo, a spreadsheet or a supplier's PDF and ask about what is in it.
54
+
55
+ ## Works where you already work
56
+
57
+ Flexkit runs in the browser, as a desktop app for macOS and Windows, inside your own React app, and inside Claude, ChatGPT, Cursor or any MCP client (signed in with your Flexkit account, with your role and spaces applied).
58
+
59
+ Plugins connect it to **Shopify, Slack, Microsoft Teams, Notion, Stripe** (preview), **Google Workspace** (preview), **Axiom** and **Tinybird**, so the agent can read and act in the tools your team already uses. Developers can add their own tools from code.
60
+
61
+ ## For developers
62
+
63
+ - **The data model in code.** Define it in `flexkit.config.ts` and deploy it from the terminal.
64
+ - **A GraphQL API for everything,** generated from your data model.
65
+ - **Your own tools behind the agent.** Expose server-side functions from your app as tools and code skills.
66
+ - **A CLI** for records, queries, automations, skills, knowledge, plugins, logs, tokens and more. See the [CLI README](https://github.com/flexkit-io/flexkit/tree/main/packages/cli).
67
+
68
+ ### Packages
69
+
70
+ | Package | Description |
71
+ | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
72
+ | [`@flexkit/studio`](https://github.com/flexkit-io/flexkit/tree/main/packages/flexkit-studio) | The Studio: tables, record editing, chat, automations and the rest of the workspace as a React component. |
73
+ | [`@flexkit/schema`](https://github.com/flexkit-io/flexkit/tree/main/packages/schema) | `defineConfig` / `defineEntity` and the serializer that turns `flexkit.config.ts` into the deployable schema. |
74
+ | [`@flexkit/tools`](https://github.com/flexkit-io/flexkit/tree/main/packages/tools) | Define, serve and run custom tools and code skills from your own server. |
75
+ | [`@flexkit/cli`](https://github.com/flexkit-io/flexkit/tree/main/packages/cli) | The `flexkit` command-line interface. |
76
+ | [`@flexkit/agent-protocol`](https://github.com/flexkit-io/flexkit/tree/main/packages/agent-protocol) | Schemas and types shared between the agent platform and the Studio UI. |
77
+
78
+ The [`apps`](https://github.com/flexkit-io/flexkit/tree/main/apps) folder has the desktop app, the hosted Studio, and example host apps for Next.js, Astro and TanStack Start.
79
+
80
+ ## Getting started
81
+
82
+ Visit [flexkit.io/docs](https://flexkit.io/docs) for the full documentation.
83
+
84
+ ```shell
85
+ npm install --global @flexkit/cli
86
+ flexkit login
87
+ flexkit link # link this folder to a project
88
+ flexkit deploy # deploy the schema from flexkit.config.ts
89
+ ```
28
90
 
29
91
  ### Define your schema
30
92
 
@@ -107,6 +169,13 @@ export default defineTools({
107
169
  });
108
170
  ```
109
171
 
172
+ ## Security and data
173
+
174
+ - Business data is hosted in the EU and is never used to train models.
175
+ - Credentials for connected tools are encrypted with AES-256-GCM.
176
+ - Every proposed change leaves an approval record, every automation run a transcript, and every schema deploy a history entry.
177
+ - Export the whole project, records and files, as one archive that re-imports cleanly.
178
+
110
179
  ## Contributing
111
180
 
112
181
  Contributions to Flexkit are welcome and highly appreciated. However, before you jump right into it, we would like you to review our [Contribution Guidelines](/CONTRIBUTING.md) to make sure you have a smooth experience contributing to Flexkit.
@@ -1,4 +1,4 @@
1
- import'./index.css';import {a}from'./chunk-KV4OGH5U.js';import {f as f$2,b,c,g as g$1,a as a$1,e as e$1,d}from'./chunk-CSUHZFEP.js';import {x,A,u,t,H,o,m,l as l$1,n,p,y,r,s,w,v,k as k$1,e as e$3,G,D,B,g as g$2,j,h,f as f$3,z,F,I,E,q}from'./chunk-AQBULUC2.js';import {a as a$2,c as c$2,b as b$2}from'./chunk-ELOJGLAR.js';import'./chunk-QSTWBKPN.js';import {a as a$5,e as e$2,l as l$2,k,d as d$2,h as h$1,g as g$3}from'./chunk-3GXM5SSM.js';import {c as c$4}from'./chunk-L5Z56DDM.js';import {g,f as f$1,a as a$4,d as d$3}from'./chunk-PLCI2RJA.js';import'./chunk-IJECATW3.js';import'./chunk-4ZWQ44NZ.js';import'./chunk-DSLPTDZX.js';import'./chunk-7KLXWCDS.js';import'./chunk-HKN6BX5U.js';import {f,d as d$1}from'./chunk-INZZOKRC.js';import'./chunk-MBBE4RND.js';import'./chunk-5CVDMZUI.js';import {Nb,M,Lb,Ya,Za,$a,Tb,Wb,Ub,Vb,Xb,Yb,_b,$b,ac,Rb,dc,ec,hc,fc,gc,Gc,cc}from'./chunk-RULCANNM.js';import'./chunk-A4DPLZZF.js';import'./chunk-G5N6HEPW.js';import {l}from'./chunk-5JUG4BEF.js';import'./chunk-S7Z6KKIN.js';import'./chunk-U45E5X3H.js';import {b as b$1,c as c$1,e}from'./chunk-N33S7BSG.js';import {a as a$3,c as c$3}from'./chunk-X3SHNHHM.js';import {useRef,useMemo,useState,useEffect,useLayoutEffect,useCallback}from'react';import {LoaderCircle,TriangleAlert,CheckCircle2,CornerDownRightIcon,CheckIcon,CopyIcon,PencilIcon,XIcon}from'lucide-react';import {useParams,useNavigate,useLocation}from'react-router-dom';import le,{useSWRConfig}from'swr';import {jsx,jsxs}from'react/jsx-runtime';var an={hidden:false,used:[]};function Dn(e,t){return t?`${e}:${t}`:e}function _n(e,t){return t.hidden?[]:e.filter(n=>!t.used.includes(n))}function Ln(e,t){return e.used.includes(t)?e:{...e,used:[...e.used,t]}}function Pe(e,t,n,o){let s=Dn(t,o),a=useMemo(()=>d$3(e),[e]),{data:u,mutate:y}=le(g(e).agentProfile(),f$1),M=u?.promptSuggestions?.[s]??an,p=useCallback(g=>{y(async d=>{let{promptSuggestions:c}=await a.savePromptSuggestion({set:s,...g});return {preferredName:d?.preferredName??null,promptSuggestions:c}},{optimisticData:d=>{let c=d?.promptSuggestions?.[s]??an,I="used"in g?Ln(c,g.used):{...c,hidden:true};return {preferredName:d?.preferredName??null,promptSuggestions:{...d?.promptSuggestions,[s]:I}}},rollbackOnError:true,revalidate:false}).catch(()=>{});},[a,s,y]),_=useCallback(g=>p({used:g}),[p]),A=useCallback(()=>p({hide:true}),[p]);return {visible:useMemo(()=>u?_n(n,M):[],[u,n,M]),markUsed:_,hideAll:A}}var zn=1e4,Qn=14,fn={queued:"Getting your store ready\u2026",deploying:"Creating 22 entities for catalog, inventory, orders, customers and marketing\u2026",seeding:"Adding the Aven Living sample store\u2026",completed:"Your store is ready",failed:"The starter could not be applied"};function cn({canSend:e,onPrompt:t,projectId:n}){let{data:o,mutate:s}=le(a$5(n),f$1,{refreshInterval:c=>e$2(c?.starter)?zn:0,revalidateOnFocus:false}),a=o?.starter??null,u=e$2(a),{projectSummaries:y}=f(),M=y.find(c=>c.id===n),p=!M||M.role==="owner",[_,A]=useState(null),[C,g]=useState(false),d=useRef(false);if(useEffect(()=>{u?(d.current=true,l$2({projectId:n})):d.current&&a&&k(a)&&(d.current=false,d$1(n));},[n,u,a]),!a)return null;if(a.state==="failed")return jsxs("div",{className:"fk:mx-auto fk:flex fk:w-full fk:max-w-xl fk:flex-col fk:items-center fk:gap-3 fk:rounded-lg fk:border fk:border-border fk:p-4 fk:text-center fk:text-sm",children:[jsxs("p",{className:"fk:flex fk:items-center fk:gap-2 fk:font-medium",children:[jsx(TriangleAlert,{className:"fk:size-4 fk:text-destructive"}),fn.failed]}),jsxs("p",{className:"fk:text-muted-foreground",children:[_??a.error??"Please try again.",p?null:" Ask the project owner to try again."]}),p?jsxs(c$3,{disabled:C,onClick:()=>{g(true),A(null),d$2(n,{template:a.template,sampleData:a.sampleData}).then(async c=>{if(g(false),!c.ok){A(c.message);return}await s({starter:c.starter},{revalidate:false}),l$2({projectId:n});});},size:"sm",variant:"outline",children:[C?jsx(LoaderCircle,{className:"fk:size-4 fk:animate-spin"}):null,"Try again"]}):null]});if(u){let c=a.state==="seeding"&&a.progress?a.progress:null;return jsxs("div",{"aria-live":"polite",className:"fk:mx-auto fk:flex fk:w-full fk:max-w-xl fk:flex-col fk:items-center fk:gap-3 fk:text-center fk:text-sm fk:text-muted-foreground",children:[jsxs("p",{className:"fk:flex fk:items-center fk:gap-2",children:[jsx(LoaderCircle,{className:"fk:size-4 fk:animate-spin"}),fn[a.state]]}),c?jsx("div",{className:"fk:h-1.5 fk:w-48 fk:overflow-hidden fk:rounded-full fk:bg-muted",children:jsx("div",{className:"fk:h-full fk:bg-primary fk:transition-[width]",style:{width:`${Math.round(c.done/Math.max(1,c.total)*100).toString()}%`}})}):null,jsx("p",{className:"fk:text-xs",children:"This usually takes under a minute. You can already ask the agent anything."})]})}return $n(a.completedAt)?a.sampleData?jsx(Xn,{canSend:e,completedAt:a.completedAt,onPrompt:t,projectId:n}):jsxs("p",{className:"fk:mx-auto fk:flex fk:items-center fk:gap-2 fk:text-sm fk:text-muted-foreground",children:[jsx(CheckCircle2,{className:"fk:size-4 fk:text-emerald-600"}),"The commerce starter is ready. Ask the agent to add your products, or to adapt the schema."]}):null}function Xn({canSend:e,completedAt:t,onPrompt:n,projectId:o}){let s=Pe(o,"sample-store",g$3,t);return s.visible.length===0?null:jsxs("div",{className:"fk:mx-auto fk:flex fk:w-full fk:max-w-2xl fk:flex-col fk:items-center fk:gap-3",children:[jsxs("p",{className:"fk:flex fk:items-center fk:gap-2 fk:text-sm fk:text-muted-foreground",children:[jsx(CheckCircle2,{className:"fk:size-4 fk:text-emerald-600"}),"The Aven Living sample store is ready. Try asking:"]}),jsx(Xe,{canSend:e,onPrompt:n,suggestions:s})]})}function Xe({canSend:e,onPrompt:t,suggestions:n}){return jsxs("div",{className:"fk:flex fk:flex-col fk:items-center fk:gap-2",children:[jsx("div",{className:"fk:flex fk:flex-wrap fk:justify-center fk:gap-2",children:n.visible.map(o=>jsxs("button",{className:"fk:inline-flex fk:max-w-full fk:items-center fk:gap-1.5 fk:rounded-full fk:border fk:border-border/70 fk:bg-muted/40 fk:px-3 fk:py-1.5 fk:text-left fk:text-sm fk:text-muted-foreground fk:transition-colors fk:hover:border-border fk:hover:bg-muted fk:hover:text-foreground fk:disabled:opacity-60 fk:corner-squircle",disabled:!e,onClick:()=>{t(o).then(s=>{s&&n.markUsed(o);});},type:"button",children:[jsx(CornerDownRightIcon,{className:"fk:size-3 fk:shrink-0"}),jsx("span",{children:o})]},o))}),jsxs("button",{className:"fk:inline-flex fk:items-center fk:gap-1 fk:text-xs fk:text-muted-foreground fk:transition-colors fk:hover:text-foreground",onClick:n.hideAll,type:"button",children:[jsx(XIcon,{className:"fk:size-3"}),"Hide suggestions"]})]})}function $n(e){let t=e?Date.parse(e):Number.NaN;return Number.isFinite(t)&&Date.now()-t<Qn*24*60*60*1e3}function gn(e,t){let n=Date.parse(e.createdAt)-Date.parse(t.createdAt);return Number.isFinite(n)&&n!==0?n:e.createdAt!==t.createdAt?e.createdAt<t.createdAt?-1:1:e.id===t.id?0:e.id<t.id?-1:1}function pe(e){return [...new Map(e.map(n=>[n.id,n])).values()].sort(gn)}function we(e,t){if(!t)return e;if(!e)return t;let n=new Set(t.messages.map(a=>a.id)),o=t.messages[t.messages.length-1],s=e.messages.filter(a=>!n.has(a.id)&&(!o||gn(a,o)>0));return s.length===0?t:{...t,messages:pe([...t.messages,...s])}}function jn(e){return e==="pending"||e==="streaming"||e==="awaiting_approval"}function pn(e){return e==="queued"||e==="steering"}function be(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(n.role==="assistant"){if(!jn(n.status))break;return {after:e.slice(t+1),before:e.slice(0,t),live:n}}}return {after:[],before:e,live:null}}function $e(e){return e==="steering"?"Picked up at the next step":e==="queued"?"Sends when this turn ends":null}function mn(e){let t=new Set;for(let n of e)if(!(n.role!=="assistant"||!Array.isArray(n.parts)))for(let o of n.parts){let s=o.type==="data-mid-turn-message"?o.data?.messageId:null;typeof s=="string"&&t.add(s);}return t}function Te(e){return e.find(t=>t.role==="user"&&t.status==="queued"&&t.kind!=="monitor_event")??null}function hn(e){return e.streaming&&!e.hasDraft?"stop":"send"}var nr=6e4,kn=15e3;function rr(e){if(!e)return 0;if(be(e.messages).live||Te(e.messages))return y;if(!e.messages.some(o=>o.role==="assistant"&&o.status==="complete"))return (e.monitors?.length??0)>0?kn:0;let n=new Date(e.chat.lastMessageAt??e.chat.updatedAt).getTime();return Date.now()-n<nr?y:(e.monitors?.length??0)>0?kn:0}function sr(e,t,n){return {chat:{createdAt:n,id:e,lastMessageAt:n,modelId:t,title:null,updatedAt:n},messages:[],pendingApproval:null}}function vn(e,t,n,o,s,a){return e||(t?{chat:t,messages:[],pendingApproval:null}:n||sr(o,s,a))}function Sn(e,t){let n=new Set([t.userMessage.id,t.assistantMessage.id]);return {...e,messages:pe([...e.messages.filter(o=>!n.has(o.id)),t.userMessage,t.assistantMessage])}}function or(e,t){return {...e,messages:pe([...e.messages.filter(n=>n.id!==t.id),t])}}function ar(e,t,n){return t?we(e[t],n):n}function ir(e){return e==="awaiting_approval"?"awaiting_approval":e==="complete"?"success":e==="failed"?"failed":"running"}function qe({attachments:e$1=[],label:t,text:n}){let{textInput:o}=Lb(),[s,a]=useState(false),u=n.trim().length>0;async function y(){await navigator.clipboard.writeText(n),a(true),setTimeout(()=>a(false),1500);}return jsxs("div",{className:"fk:group fk:ml-auto fk:flex fk:w-fit fk:max-w-[70%] fk:flex-col fk:items-end fk:gap-1",children:[jsx(q,{attachments:e$1}),u?jsx("div",{className:"fk:whitespace-pre-wrap fk:rounded-xl fk:bg-muted fk:dark:bg-white/20 fk:px-3.5 fk:py-2 fk:text-base fk:corner-squircle",children:n}):null,t?jsxs("span",{className:"fk:inline-flex fk:items-center fk:gap-1 fk:text-xs fk:text-muted-foreground",children:[jsx(CornerDownRightIcon,{className:"fk:size-3 fk:shrink-0"}),t]}):null,jsxs("div",{className:u?"fk:flex fk:gap-0.5 fk:opacity-0 fk:transition-opacity fk:group-hover:opacity-100":"fk:hidden",children:[jsxs(b$1,{children:[jsx(c$1,{asChild:true,children:jsx(c$3,{"aria-label":"Copy prompt",className:"fk:size-6 fk:text-muted-foreground",size:"icon",variant:"ghost",onClick:()=>{y();},children:s?jsx(CheckIcon,{className:"fk:size-3.5"}):jsx(CopyIcon,{className:"fk:size-3.5"})})}),jsx(e,{children:"Copy"})]}),jsxs(b$1,{children:[jsx(c$1,{asChild:true,children:jsx(c$3,{"aria-label":"Edit prompt",className:"fk:size-6 fk:text-muted-foreground",size:"icon",variant:"ghost",onClick:()=>o.setInput(n),children:jsx(PencilIcon,{className:"fk:size-3.5"})})}),jsx(e,{children:"Edit"})]})]})]})}function xn(e){let n=e.find(o=>o.type==="data-suggested-prompt")?.data?.prompt;return typeof n=="string"&&n.trim()?n:null}function Mn({prompt:e}){let{textInput:t}=Lb();return jsx("div",{className:"fk:flex fk:justify-start",children:jsxs("button",{className:"fk:inline-flex fk:max-w-full fk:items-center fk:gap-1.5 fk:rounded-full fk:border fk:border-border/70 fk:bg-muted/40 fk:px-3 fk:py-1.5 fk:text-left fk:text-sm fk:text-muted-foreground fk:transition-colors fk:hover:border-border fk:hover:bg-muted fk:hover:ext-foreground fk:corner-squircle",title:"Use as your next message",type:"button",onClick:()=>t.setInput(e),children:[jsx(CornerDownRightIcon,{className:"fk:size-3 fk:shrink-0"}),jsx("span",{className:"fk:truncate",children:e})]})})}function lr({api:e,part:t,partIndex:n,parts:o}){return t.type.startsWith("tool-")?t.state==="output-error"?jsx(G,{message:t.errorText??"The tool call failed."}):null:jsx(F,{api:e,part:t,partIndex:n,parts:o})}function An({api:e,message:t,showSuggestion:n=false}){if(t.kind==="monitor_event"){let u=r(t);return u?jsx(s,{data:u,error:t.error}):null}if(t.kind==="plugin_connected"){let u=w(t.parts);return u?jsx(v,{data:u,error:t.error,label:$e(t.status)}):null}if(t.role==="user")return jsx(qe,{attachments:k$1(t.parts),label:$e(t.status),text:t.textContent});let o=(Array.isArray(t.parts)?t.parts:[]).filter(u=>!e$3(u)&&!(u.type.startsWith("tool-")&&u.state!=="output-error")),s$1=o.some(u=>u.type==="data-turn-error"),a=n&&!t.error?xn(o):null;return o.length===0&&!t.error?null:jsxs("div",{className:"fk:w-full fk:min-w-0 fk:space-y-8",children:[o.map((u,y)=>jsx(lr,{api:e,part:u,partIndex:y,parts:o},u.toolCallId??`${t.id}-${y.toString()}`)),t.error&&!s$1?jsx(G,{message:t.error}):null,a?jsx(Mn,{prompt:a}):null]})}function ur({api:e,chatId:t,detail:n,message:o,onMidTurnDelivered:s,onStatusChange:a,onTurnUpdated:u,questionAnsweredSignal:y}){let M=ir(o.status),p=o.workflowRunId?e.getAgentChatStreamUrl(t,o.workflowRunId):"",[_,A]=useState(0),[C,g]=useState(false),[d,c]=useState({}),I$1=useRef(null),{message:x,status:P}=D(p,{decidedApprovals:d,recordStatus:M,resumeToken:_,suppressApprovalPause:C}),K=useMemo(()=>x?[{...x,parts:x.parts.filter(h=>!e$3(h))}]:[],[x]),L=B(K),Y=useRef(u);Y.current=u;let G=useRef(a);G.current=a;let W=useMemo(()=>({answerQuestion:async(h,X)=>{let{question:$}=await e.answerAgentChatQuestion(t,h,X);return g(true),A(ue=>ue+1),Y.current(),$??null},onApprovalDecided:(h,X)=>{h&&X&&X!=="pending"&&c($=>({...$,[h]:X})),!(h&&I$1.current===h)&&(h&&(I$1.current=h),g(true),A($=>$+1),Y.current());}}),[e,t]);useEffect(()=>{A(0),g(false),I$1.current=null,c({});},[o.id]);let m=useRef(y);useEffect(()=>{y!==m.current&&(m.current=y,y?.messageId===o.id&&(g(true),A(h=>h+1)));},[o.id,y]),useEffect(()=>{C&&o.status==="streaming"&&g(false);},[o.status,C]),useEffect(()=>{(P==="finished"||P==="paused")&&Y.current();},[P]);let O=(x?.parts??[]).filter(h=>h.type==="data-mid-turn-message").map(h=>String(h.data?.messageId??"")).join(`
1
+ import'./index.css';import {a}from'./chunk-Z7JAN2UW.js';import {f as f$2,b,c,g as g$1,a as a$1,e as e$1,d}from'./chunk-CSUHZFEP.js';import {x,A,u,t,H,o,m,l as l$1,n,p,y,r,s,w,v,k as k$1,e as e$3,G,D,B,g as g$2,j,h,f as f$3,z,F,I,E,q}from'./chunk-KWE3LHFM.js';import {a as a$2,c as c$2,b as b$2}from'./chunk-ELOJGLAR.js';import'./chunk-QSTWBKPN.js';import {a as a$5,e as e$2,l as l$2,k,d as d$2,h as h$1,g as g$3}from'./chunk-JJFOUJMQ.js';import {c as c$4}from'./chunk-L5Z56DDM.js';import {g,f as f$1,a as a$4,d as d$3}from'./chunk-PLCI2RJA.js';import'./chunk-DUS2CRB3.js';import'./chunk-4ZWQ44NZ.js';import'./chunk-DSLPTDZX.js';import'./chunk-7KLXWCDS.js';import'./chunk-HKN6BX5U.js';import {f,d as d$1}from'./chunk-TP6QGIJH.js';import'./chunk-MBBE4RND.js';import'./chunk-5CVDMZUI.js';import {Nb,M,Lb,Ya,Za,$a,Tb,Wb,Ub,Vb,Xb,Yb,_b,$b,ac,Rb,dc,ec,hc,fc,gc,Gc,cc}from'./chunk-RULCANNM.js';import'./chunk-A4DPLZZF.js';import'./chunk-G5N6HEPW.js';import {l}from'./chunk-5JUG4BEF.js';import'./chunk-S7Z6KKIN.js';import'./chunk-U45E5X3H.js';import {b as b$1,c as c$1,e}from'./chunk-N33S7BSG.js';import {a as a$3,c as c$3}from'./chunk-X3SHNHHM.js';import {useRef,useMemo,useState,useEffect,useLayoutEffect,useCallback}from'react';import {LoaderCircle,TriangleAlert,CheckCircle2,CornerDownRightIcon,CheckIcon,CopyIcon,PencilIcon,XIcon}from'lucide-react';import {useParams,useNavigate,useLocation}from'react-router-dom';import le,{useSWRConfig}from'swr';import {jsx,jsxs}from'react/jsx-runtime';var an={hidden:false,used:[]};function Dn(e,t){return t?`${e}:${t}`:e}function _n(e,t){return t.hidden?[]:e.filter(n=>!t.used.includes(n))}function Ln(e,t){return e.used.includes(t)?e:{...e,used:[...e.used,t]}}function Pe(e,t,n,o){let s=Dn(t,o),a=useMemo(()=>d$3(e),[e]),{data:u,mutate:y}=le(g(e).agentProfile(),f$1),M=u?.promptSuggestions?.[s]??an,p=useCallback(g=>{y(async d=>{let{promptSuggestions:c}=await a.savePromptSuggestion({set:s,...g});return {preferredName:d?.preferredName??null,promptSuggestions:c}},{optimisticData:d=>{let c=d?.promptSuggestions?.[s]??an,I="used"in g?Ln(c,g.used):{...c,hidden:true};return {preferredName:d?.preferredName??null,promptSuggestions:{...d?.promptSuggestions,[s]:I}}},rollbackOnError:true,revalidate:false}).catch(()=>{});},[a,s,y]),_=useCallback(g=>p({used:g}),[p]),A=useCallback(()=>p({hide:true}),[p]);return {visible:useMemo(()=>u?_n(n,M):[],[u,n,M]),markUsed:_,hideAll:A}}var zn=1e4,Qn=14,fn={queued:"Getting your store ready\u2026",deploying:"Creating 22 entities for catalog, inventory, orders, customers and marketing\u2026",seeding:"Adding the Aven Living sample store\u2026",completed:"Your store is ready",failed:"The starter could not be applied"};function cn({canSend:e,onPrompt:t,projectId:n}){let{data:o,mutate:s}=le(a$5(n),f$1,{refreshInterval:c=>e$2(c?.starter)?zn:0,revalidateOnFocus:false}),a=o?.starter??null,u=e$2(a),{projectSummaries:y}=f(),M=y.find(c=>c.id===n),p=!M||M.role==="owner",[_,A]=useState(null),[C,g]=useState(false),d=useRef(false);if(useEffect(()=>{u?(d.current=true,l$2({projectId:n})):d.current&&a&&k(a)&&(d.current=false,d$1(n));},[n,u,a]),!a)return null;if(a.state==="failed")return jsxs("div",{className:"fk:mx-auto fk:flex fk:w-full fk:max-w-xl fk:flex-col fk:items-center fk:gap-3 fk:rounded-lg fk:border fk:border-border fk:p-4 fk:text-center fk:text-sm",children:[jsxs("p",{className:"fk:flex fk:items-center fk:gap-2 fk:font-medium",children:[jsx(TriangleAlert,{className:"fk:size-4 fk:text-destructive"}),fn.failed]}),jsxs("p",{className:"fk:text-muted-foreground",children:[_??a.error??"Please try again.",p?null:" Ask the project owner to try again."]}),p?jsxs(c$3,{disabled:C,onClick:()=>{g(true),A(null),d$2(n,{template:a.template,sampleData:a.sampleData}).then(async c=>{if(g(false),!c.ok){A(c.message);return}await s({starter:c.starter},{revalidate:false}),l$2({projectId:n});});},size:"sm",variant:"outline",children:[C?jsx(LoaderCircle,{className:"fk:size-4 fk:animate-spin"}):null,"Try again"]}):null]});if(u){let c=a.state==="seeding"&&a.progress?a.progress:null;return jsxs("div",{"aria-live":"polite",className:"fk:mx-auto fk:flex fk:w-full fk:max-w-xl fk:flex-col fk:items-center fk:gap-3 fk:text-center fk:text-sm fk:text-muted-foreground",children:[jsxs("p",{className:"fk:flex fk:items-center fk:gap-2",children:[jsx(LoaderCircle,{className:"fk:size-4 fk:animate-spin"}),fn[a.state]]}),c?jsx("div",{className:"fk:h-1.5 fk:w-48 fk:overflow-hidden fk:rounded-full fk:bg-muted",children:jsx("div",{className:"fk:h-full fk:bg-primary fk:transition-[width]",style:{width:`${Math.round(c.done/Math.max(1,c.total)*100).toString()}%`}})}):null,jsx("p",{className:"fk:text-xs",children:"This usually takes under a minute. You can already ask the agent anything."})]})}return $n(a.completedAt)?a.sampleData?jsx(Xn,{canSend:e,completedAt:a.completedAt,onPrompt:t,projectId:n}):jsxs("p",{className:"fk:mx-auto fk:flex fk:items-center fk:gap-2 fk:text-sm fk:text-muted-foreground",children:[jsx(CheckCircle2,{className:"fk:size-4 fk:text-emerald-600"}),"The commerce starter is ready. Ask the agent to add your products, or to adapt the schema."]}):null}function Xn({canSend:e,completedAt:t,onPrompt:n,projectId:o}){let s=Pe(o,"sample-store",g$3,t);return s.visible.length===0?null:jsxs("div",{className:"fk:mx-auto fk:flex fk:w-full fk:max-w-2xl fk:flex-col fk:items-center fk:gap-3",children:[jsxs("p",{className:"fk:flex fk:items-center fk:gap-2 fk:text-sm fk:text-muted-foreground",children:[jsx(CheckCircle2,{className:"fk:size-4 fk:text-emerald-600"}),"The Aven Living sample store is ready. Try asking:"]}),jsx(Xe,{canSend:e,onPrompt:n,suggestions:s})]})}function Xe({canSend:e,onPrompt:t,suggestions:n}){return jsxs("div",{className:"fk:flex fk:flex-col fk:items-center fk:gap-2",children:[jsx("div",{className:"fk:flex fk:flex-wrap fk:justify-center fk:gap-2",children:n.visible.map(o=>jsxs("button",{className:"fk:inline-flex fk:max-w-full fk:items-center fk:gap-1.5 fk:rounded-full fk:border fk:border-border/70 fk:bg-muted/40 fk:px-3 fk:py-1.5 fk:text-left fk:text-sm fk:text-muted-foreground fk:transition-colors fk:hover:border-border fk:hover:bg-muted fk:hover:text-foreground fk:disabled:opacity-60 fk:corner-squircle",disabled:!e,onClick:()=>{t(o).then(s=>{s&&n.markUsed(o);});},type:"button",children:[jsx(CornerDownRightIcon,{className:"fk:size-3 fk:shrink-0"}),jsx("span",{children:o})]},o))}),jsxs("button",{className:"fk:inline-flex fk:items-center fk:gap-1 fk:text-xs fk:text-muted-foreground fk:transition-colors fk:hover:text-foreground",onClick:n.hideAll,type:"button",children:[jsx(XIcon,{className:"fk:size-3"}),"Hide suggestions"]})]})}function $n(e){let t=e?Date.parse(e):Number.NaN;return Number.isFinite(t)&&Date.now()-t<Qn*24*60*60*1e3}function gn(e,t){let n=Date.parse(e.createdAt)-Date.parse(t.createdAt);return Number.isFinite(n)&&n!==0?n:e.createdAt!==t.createdAt?e.createdAt<t.createdAt?-1:1:e.id===t.id?0:e.id<t.id?-1:1}function pe(e){return [...new Map(e.map(n=>[n.id,n])).values()].sort(gn)}function we(e,t){if(!t)return e;if(!e)return t;let n=new Set(t.messages.map(a=>a.id)),o=t.messages[t.messages.length-1],s=e.messages.filter(a=>!n.has(a.id)&&(!o||gn(a,o)>0));return s.length===0?t:{...t,messages:pe([...t.messages,...s])}}function jn(e){return e==="pending"||e==="streaming"||e==="awaiting_approval"}function pn(e){return e==="queued"||e==="steering"}function be(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(n.role==="assistant"){if(!jn(n.status))break;return {after:e.slice(t+1),before:e.slice(0,t),live:n}}}return {after:[],before:e,live:null}}function $e(e){return e==="steering"?"Picked up at the next step":e==="queued"?"Sends when this turn ends":null}function mn(e){let t=new Set;for(let n of e)if(!(n.role!=="assistant"||!Array.isArray(n.parts)))for(let o of n.parts){let s=o.type==="data-mid-turn-message"?o.data?.messageId:null;typeof s=="string"&&t.add(s);}return t}function Te(e){return e.find(t=>t.role==="user"&&t.status==="queued"&&t.kind!=="monitor_event")??null}function hn(e){return e.streaming&&!e.hasDraft?"stop":"send"}var nr=6e4,kn=15e3;function rr(e){if(!e)return 0;if(be(e.messages).live||Te(e.messages))return y;if(!e.messages.some(o=>o.role==="assistant"&&o.status==="complete"))return (e.monitors?.length??0)>0?kn:0;let n=new Date(e.chat.lastMessageAt??e.chat.updatedAt).getTime();return Date.now()-n<nr?y:(e.monitors?.length??0)>0?kn:0}function sr(e,t,n){return {chat:{createdAt:n,id:e,lastMessageAt:n,modelId:t,title:null,updatedAt:n},messages:[],pendingApproval:null}}function vn(e,t,n,o,s,a){return e||(t?{chat:t,messages:[],pendingApproval:null}:n||sr(o,s,a))}function Sn(e,t){let n=new Set([t.userMessage.id,t.assistantMessage.id]);return {...e,messages:pe([...e.messages.filter(o=>!n.has(o.id)),t.userMessage,t.assistantMessage])}}function or(e,t){return {...e,messages:pe([...e.messages.filter(n=>n.id!==t.id),t])}}function ar(e,t,n){return t?we(e[t],n):n}function ir(e){return e==="awaiting_approval"?"awaiting_approval":e==="complete"?"success":e==="failed"?"failed":"running"}function qe({attachments:e$1=[],label:t,text:n}){let{textInput:o}=Lb(),[s,a]=useState(false),u=n.trim().length>0;async function y(){await navigator.clipboard.writeText(n),a(true),setTimeout(()=>a(false),1500);}return jsxs("div",{className:"fk:group fk:ml-auto fk:flex fk:w-fit fk:max-w-[70%] fk:flex-col fk:items-end fk:gap-1",children:[jsx(q,{attachments:e$1}),u?jsx("div",{className:"fk:whitespace-pre-wrap fk:rounded-xl fk:bg-muted fk:dark:bg-white/20 fk:px-3.5 fk:py-2 fk:text-base fk:corner-squircle",children:n}):null,t?jsxs("span",{className:"fk:inline-flex fk:items-center fk:gap-1 fk:text-xs fk:text-muted-foreground",children:[jsx(CornerDownRightIcon,{className:"fk:size-3 fk:shrink-0"}),t]}):null,jsxs("div",{className:u?"fk:flex fk:gap-0.5 fk:opacity-0 fk:transition-opacity fk:group-hover:opacity-100":"fk:hidden",children:[jsxs(b$1,{children:[jsx(c$1,{asChild:true,children:jsx(c$3,{"aria-label":"Copy prompt",className:"fk:size-6 fk:text-muted-foreground",size:"icon",variant:"ghost",onClick:()=>{y();},children:s?jsx(CheckIcon,{className:"fk:size-3.5"}):jsx(CopyIcon,{className:"fk:size-3.5"})})}),jsx(e,{children:"Copy"})]}),jsxs(b$1,{children:[jsx(c$1,{asChild:true,children:jsx(c$3,{"aria-label":"Edit prompt",className:"fk:size-6 fk:text-muted-foreground",size:"icon",variant:"ghost",onClick:()=>o.setInput(n),children:jsx(PencilIcon,{className:"fk:size-3.5"})})}),jsx(e,{children:"Edit"})]})]})]})}function xn(e){let n=e.find(o=>o.type==="data-suggested-prompt")?.data?.prompt;return typeof n=="string"&&n.trim()?n:null}function Mn({prompt:e}){let{textInput:t}=Lb();return jsx("div",{className:"fk:flex fk:justify-start",children:jsxs("button",{className:"fk:inline-flex fk:max-w-full fk:items-center fk:gap-1.5 fk:rounded-full fk:border fk:border-border/70 fk:bg-muted/40 fk:px-3 fk:py-1.5 fk:text-left fk:text-sm fk:text-muted-foreground fk:transition-colors fk:hover:border-border fk:hover:bg-muted fk:hover:ext-foreground fk:corner-squircle",title:"Use as your next message",type:"button",onClick:()=>t.setInput(e),children:[jsx(CornerDownRightIcon,{className:"fk:size-3 fk:shrink-0"}),jsx("span",{className:"fk:truncate",children:e})]})})}function lr({api:e,part:t,partIndex:n,parts:o}){return t.type.startsWith("tool-")?t.state==="output-error"?jsx(G,{message:t.errorText??"The tool call failed."}):null:jsx(F,{api:e,part:t,partIndex:n,parts:o})}function An({api:e,message:t,showSuggestion:n=false}){if(t.kind==="monitor_event"){let u=r(t);return u?jsx(s,{data:u,error:t.error}):null}if(t.kind==="plugin_connected"){let u=w(t.parts);return u?jsx(v,{data:u,error:t.error,label:$e(t.status)}):null}if(t.role==="user")return jsx(qe,{attachments:k$1(t.parts),label:$e(t.status),text:t.textContent});let o=(Array.isArray(t.parts)?t.parts:[]).filter(u=>!e$3(u)&&!(u.type.startsWith("tool-")&&u.state!=="output-error")),s$1=o.some(u=>u.type==="data-turn-error"),a=n&&!t.error?xn(o):null;return o.length===0&&!t.error?null:jsxs("div",{className:"fk:w-full fk:min-w-0 fk:space-y-8",children:[o.map((u,y)=>jsx(lr,{api:e,part:u,partIndex:y,parts:o},u.toolCallId??`${t.id}-${y.toString()}`)),t.error&&!s$1?jsx(G,{message:t.error}):null,a?jsx(Mn,{prompt:a}):null]})}function ur({api:e,chatId:t,detail:n,message:o,onMidTurnDelivered:s,onStatusChange:a,onTurnUpdated:u,questionAnsweredSignal:y}){let M=ir(o.status),p=o.workflowRunId?e.getAgentChatStreamUrl(t,o.workflowRunId):"",[_,A]=useState(0),[C,g]=useState(false),[d,c]=useState({}),I$1=useRef(null),{message:x,status:P}=D(p,{decidedApprovals:d,recordStatus:M,resumeToken:_,suppressApprovalPause:C}),K=useMemo(()=>x?[{...x,parts:x.parts.filter(h=>!e$3(h))}]:[],[x]),L=B(K),Y=useRef(u);Y.current=u;let G=useRef(a);G.current=a;let W=useMemo(()=>({answerQuestion:async(h,X)=>{let{question:$}=await e.answerAgentChatQuestion(t,h,X);return g(true),A(ue=>ue+1),Y.current(),$??null},onApprovalDecided:(h,X)=>{h&&X&&X!=="pending"&&c($=>({...$,[h]:X})),!(h&&I$1.current===h)&&(h&&(I$1.current=h),g(true),A($=>$+1),Y.current());}}),[e,t]);useEffect(()=>{A(0),g(false),I$1.current=null,c({});},[o.id]);let m=useRef(y);useEffect(()=>{y!==m.current&&(m.current=y,y?.messageId===o.id&&(g(true),A(h=>h+1)));},[o.id,y]),useEffect(()=>{C&&o.status==="streaming"&&g(false);},[o.status,C]),useEffect(()=>{(P==="finished"||P==="paused")&&Y.current();},[P]);let O=(x?.parts??[]).filter(h=>h.type==="data-mid-turn-message").map(h=>String(h.data?.messageId??"")).join(`
2
2
  `),Z=useRef(s);Z.current=s,useEffect(()=>{O&&Z.current(O.split(`
3
- `));},[O]);let f=!C&&o.status!=="streaming"&&(o.status==="awaiting_approval"||P==="paused"||g$2(x)||j(x)),B$1=useMemo(()=>new Set(h(x)),[x]),U=n.pendingApproval&&!B$1.has(n.pendingApproval.id)?n.pendingApproval:null,ee=x?.parts[x.parts.length-1],N=ee?.type==="text"&&ee.state==="streaming",re=j(x)?"Waiting for your answer":"Awaiting approval",se=f?re:f$3(x)??"Thinking",b=f?P!=="finished"&&P!=="error":P==="streaming"&&!N;useEffect(()=>{G.current({label:se,visible:b});},[se,b]);let D$1=!!U&&f,oe=P==="finished"?xn(L.flatMap(h=>h.parts)):null;return L.length===0&&!D$1?jsx(z.Provider,{value:W,children:null}):jsx(z.Provider,{value:W,children:jsxs("div",{className:"fk:w-full fk:min-w-0 fk:space-y-8",children:[L.map(h=>jsx("div",{className:"fk:space-y-8 fk:min-w-0",children:h.parts.map((X,$)=>jsx(F,{api:e,part:X,partIndex:$,parts:h.parts},$))},h.id)),U&&D$1?jsx(I,{api:e,message:E(U)}):null,oe?jsx(Mn,{prompt:oe}):null]})})}function fr({draftKey:e}){let{textInput:t}=Lb(),{setInput:n,value:o}=t,s=useRef(null);return useLayoutEffect(()=>{if(s.current===e){c$2(e,o);return}s.current=e;let a=b$2(e);a!==o&&n(a);},[e,n,o]),null}function dr({onRestored:e,text:t}){let{textInput:n}=Lb(),{setInput:o}=n;return useEffect(()=>{t!==null&&(o(t),e(null));},[e,o,t]),null}function cr({api:e,effort:t,modelKey:n$1,modelPending:o$1,models:s,onEffortChange:a,onError:u,onModelChange:y,onSend:M,onStop:p$1,placeholder:_,sending:A,streaming:C}){let{attachments:g,textInput:d$1}=Lb(),c$1=o(e,u),{currentProjectId:I}=f(),{data:x,error:P}=le(I?`/api/flexkit/${I}/plugins`:null,f$1),K=useRef(false),L=s.filter(f=>!f.deprecated||b(f)===n$1),Y=c(s,n$1),G=e$1(Y),W=d(Y,t),m$1=d$1.value.trim().length>0||g.files.length>0,O=hn({hasDraft:m$1,streaming:C}),Z=m$1&&!c$1.isUploading&&!A&&!o$1;return jsxs(Tb,{accept:n,className:"fk:mx-auto fk:max-w-4xl",maxFileSize:l$1,maxFiles:m,multiple:true,onError:f=>u(f.message),onSubmit:({text:f})=>{let B=f?.trim()??"",U=c$1.getUploaded(g.files.map(N=>N.id));if(!B&&U.length===0||c$1.isUploading||A||K.current||o$1||!x&&!P&&I)return Promise.reject(new Error("The message cannot be sent right now."));let ee=c$4(B,x?.plugins??[]);return ee?(d$1.setInput(ee.tokens.reduce((N,re)=>N.split(re).join(""),f)),u(`That looks like a ${ee.label}. It was removed from your message: connect ${ee.plugin.name} from its connect card or AI \u2192 Plugins instead, where it is stored encrypted and never shown to the agent.`),Promise.reject(new Error("The message contains a plugin token."))):(K.current=true,d$1.clear(),M(B,U).catch(N=>{throw d$1.setInput(f),N}).finally(()=>{K.current=false;}))},children:[g.files.length>0?jsx(Wb,{children:jsx(p,{uploads:c$1})}):null,jsx(Ub,{children:jsx(Vb,{disabled:A,placeholder:_})}),jsxs(Xb,{children:[jsxs(Yb,{children:[jsxs(_b,{children:[jsx($b,{"aria-label":"Add attachments",className:"fk:border-0 fk:bg-border fk:corner-round",disabled:A,tooltip:"Add photos or files"}),jsx(ac,{children:jsx(Rb,{})})]}),L.length>0?jsxs(dc,{value:n$1??void 0,onValueChange:y,children:[jsx(ec,{"aria-label":"Model",className:"fk:min-w-44",children:jsx(hc,{placeholder:"Model"})}),jsx(fc,{children:L.map(f=>jsx(gc,{value:b(f),children:f.name},b(f)))})]}):null,G.length>1&&W?jsxs(dc,{value:W,onValueChange:a,children:[jsx(ec,{"aria-label":"Reasoning effort",className:"fk:min-w-28",children:jsx(hc,{placeholder:"Effort"})}),jsx(fc,{children:G.map(f=>jsx(gc,{value:f.value,children:f.label},f.value))})]}):null]}),jsxs("div",{className:"fk:flex fk:items-center fk:gap-3",children:[jsx(Gc,{disabled:A,onAudioRecorded:async(f,B)=>{let{text:U}=await e.transcribeAgentAudio(f,B);return U},onError:f=>u(f.message),onTranscriptionChange:f=>{u(null),d$1.setInput(a$4(d$1.value,f));}}),jsx(cc,{className:"fk:corner-round",disabled:O==="stop"?false:!Z,status:O==="stop"?"streaming":void 0,onStop:()=>{p$1();}})]})]})]})}var je={chatId:null,error:null,loading:false,older:[],page:null},gr=3e3;function pr({api:e,chatId:t,projectId:n,pendingFollowUp:o,pendingMessage:s,questionAnsweredSignal:a,resolveDetail:u}){let{data:y,mutate:M}=le(t?g(n).agentChat(t):null,f$1,{refreshInterval:0}),p=u(y),[_,A]=useState(je),C=_.chatId===t?_:je,g$1=useRef(t);g$1.current=t;let d=(i,S)=>A(w=>{if(w.chatId!==i&&g$1.current!==i)return w;let H=w.chatId===i?w:{...je,chatId:i};return {...H,...S(H)}}),c=useRef({chatId:null,messages:[]}),I=p?.messages;useEffect(()=>{let i=c.current,S=I??[];if(c.current={chatId:t,messages:S},!t||i.chatId!==t)return;let w=new Set(S.map(j=>j.id)),H=i.messages.filter(j=>!w.has(j.id));H.length>0&&d(t,j=>({older:pe([...j.older,...H])}));},[t,I]);let x=new Set(p?.messages.map(i=>i.id)??[]),P=[...C.older.filter(i=>!x.has(i.id)),...p?.messages??[]],K=useRef(p);K.current=p;let L=useRef(void 0);le(t?`${g(n).agentChat(t)}?view=status`:null,f$1,{refreshInterval:()=>rr(K.current),onSuccess:i=>{let S=JSON.stringify(i),w=L.current;L.current=S;let{current:H}=K,j=H?[...H.messages].reverse().find(fe=>fe.role==="assistant"):void 0;(w&&w!==S||j&&i.latestMessage&&(j.id!==i.latestMessage.id||j.status!==i.latestMessage.status||j.workflowRunId!==i.latestMessage.workflowRunId||H?.chat.updatedAt!==i.chat.updatedAt))&&M();}});let Y=async()=>{let i=C.page?.cursor??p?.nextCursor;if(!t||!i||C.loading)return;let S=t;d(S,()=>({error:null,loading:true}));try{let w=await f$1(`${g(n).agentChat(S)}?before=${encodeURIComponent(i)}`);d(S,H=>({loading:!1,older:pe([...w.messages,...H.older]),page:{cursor:w.nextCursor??null,hasMore:w.hasMore??!1}}));}catch{d(S,()=>({error:"Could not load earlier messages. Try again.",loading:false}));}},{after:G,before:W,live:m}=be(P),[O,Z]=useState({ids:[],messageId:""}),f=mn(P);for(let i of m&&O.messageId===m.id?O.ids:[])f.add(i);let B=G.filter(i=>pn(i.status)&&!f.has(i.id)),U=W.filter(i=>!f.has(i.id)),N=(!m&&!s?Te(P):null)?.id??null,[re,se]=useState(0),b=useRef(null);useEffect(()=>{if(!t||!N||b.current===N)return;b.current=N;let i=false,S=null;return e.startQueuedAgentChatMessage(t,N).then(()=>{},()=>{S=setTimeout(()=>{i||se(w=>w+1);},gr);}).finally(()=>{b.current=null,M();}),()=>{i=true,S&&clearTimeout(S);}},[e,t,M,N,re]);let[D,oe]=useState(null),h=m&&D?.messageId===m.id?D.status:null;if(t&&!p&&!s)return jsxs("div",{className:"fk:flex fk:flex-1 fk:items-center fk:justify-center fk:gap-2 fk:text-sm fk:text-muted-foreground",children:[jsx(LoaderCircle,{className:"fk:size-4 fk:animate-spin"}),"Loading chat..."]});let X=!!s||!!m,$=[...U].reverse().find(i=>i.role==="assistant")?.id??null,ue=m?h?.label??"Thinking":"Sending",ae=m?h?.visible??true:true;return jsxs(Ya,{className:"fk:h-0 fk:min-h-0 fk:flex-1",children:[jsx(Za,{className:"fk:gap-0 fk:p-0",children:jsxs("div",{className:"fk:mx-auto fk:w-full fk:max-w-4xl fk:space-y-5 fk:pb-6 fk:pr-4",children:[C.page?.hasMore??p?.hasMore?jsx(c$3,{variant:"ghost",disabled:C.loading,onClick:()=>{Y();},children:C.loading?"Loading\u2026":"Load earlier messages"}):null,C.error?jsx("p",{role:"alert",children:C.error}):null,U.map(i=>jsx(An,{api:e,message:i,showSuggestion:!X&&i.id===$},i.id)),m&&t&&p?jsx(ur,{api:e,chatId:t,detail:p,message:m,onMidTurnDelivered:i=>Z({ids:i,messageId:m.id}),onStatusChange:i=>oe({messageId:m.id,status:i}),onTurnUpdated:()=>{M();},questionAnsweredSignal:a}):null,s&&!m?jsx(qe,{attachments:s.attachments,text:s.text}):null,X?jsx(H,{label:ue,visible:ae}):null,B.map(i=>jsx(An,{api:e,message:i},i.id)),o&&m?jsx(qe,{attachments:o.attachments,text:o.text}):null]})}),jsx($a,{})]})}var Cn=["Where should we begin?","Ready when you are","What\u2019s on the agenda today?","What\u2019s on your mind today?"];function mr(e){return [`How can I help, ${e}?`,`Good to see you, ${e}.`,`Hey, ${e}. Ready to dive in?`]}function hr(e){let t=e?[...Cn,...mr(e)]:Cn;return t[Math.floor(Math.random()*t.length)]??"How can I help?"}var Pn="flexkit-ai:lastModelId",Je="flexkit-ai:lastEffort";function kr(){if(typeof localStorage>"u")return null;try{let e=localStorage.getItem(Pn);return e?{effort:localStorage.getItem(Je),modelKey:e}:null}catch{return null}}function vr(e){return e.selectedModelKey?{effort:e.selectedEffort,modelKey:e.selectedModelKey}:e.awaitingChatModel?{effort:null,modelKey:null}:e.chatSelection?{effort:e.selectedEffort??e.chatSelection.effort,modelKey:e.chatSelection.modelKey}:e.lastUsed?{effort:e.selectedEffort??e.lastUsed.effort,modelKey:e.lastUsed.modelKey}:{effort:e.selectedEffort,modelKey:e.defaultModelKey}}function Sr(e){if(!(typeof localStorage>"u"))try{localStorage.setItem(Pn,e.modelKey),e.effort?localStorage.setItem(Je,e.effort):localStorage.removeItem(Je);}catch{}}function Ar({canSend:e,hasSchema:t,onPrompt:n,projectId:o}){let{data:s,isLoading:a}=le(g(o).agentProfile(),f$1),u=useMemo(()=>a?null:hr(s?.preferredName??null),[s?.preferredName,a]);return jsxs("div",{className:"fk:flex fk:flex-col fk:items-center fk:gap-6 fk:pb-2 fk:text-center",children:[jsx("h2",{className:"fk:text-2xl fk:font-semibold",children:u??"\xA0"}),jsx(cn,{canSend:e,onPrompt:n,projectId:o}),t?null:jsx(Cr,{canSend:e,onPrompt:n,projectId:o})]})}function Cr({canSend:e,onPrompt:t,projectId:n}){let{data:o,error:s}=le(a$5(n),f$1,{revalidateOnFocus:false}),a=Pe(n,"empty-schema",h$1);return o===void 0&&s===void 0||o?.starter||a.visible.length===0?null:jsxs("div",{className:"fk:mx-auto fk:flex fk:w-full fk:max-w-2xl fk:flex-col fk:items-center fk:gap-3",children:[jsx("p",{className:"fk:text-sm fk:text-muted-foreground",children:"This project has no schema yet. Start with:"}),jsx(Xe,{canSend:e,onPrompt:t,suggestions:a})]})}function ls(){let{api:e$1,projectId:t$1}=x(),{currentProject:n,projectSummaries:o}=f(),{chatId:s}=useParams(),a$4=useNavigate(),u$1=useLocation(),y=a(),{mutate:M$1}=useSWRConfig(),{data:p}=le(t$1?g(t$1).tools():null,f$1),{data:_}=le(t$1&&s?g(t$1).agentChat(s):null,f$1),A$1=useRef({});function C(l){return ar(A$1.current,s,l)}let g$2=C(_),d=useMemo(()=>p?.tools.models??[],[p]),[c$2,I]=useState(null),[x$1,P]=useState(null),K=useRef(null),[L,Y]=useState(kr),[G,W]=useState(false),m=useRef(false),[O,Z]=useState(null),f$3=O&&O.chatId===s?O:void 0,[B,U]=useState(null),[ee,N]=useState(null),re=B&&B.chatId===s?B:void 0,[se,b$2]=useState(null),D=g$2?.chat.modelId??null,oe=!!s&&g$2===void 0,h=useMemo(()=>f$2(D,d)??(D?{effort:null,modelKey:D}:null),[D,d]),X=useMemo(()=>{let l=d.find(v=>!v.deprecated);return l?b(l):null},[d]),$=useMemo(()=>{let l=c(d,L?.modelKey??null);return L&&l&&!l.deprecated?L:null},[d,L]),{effort:ue,modelKey:ae}=vr({awaitingChatModel:oe,chatSelection:h,defaultModelKey:X,lastUsed:$,selectedEffort:x$1,selectedModelKey:c$2}),i=ae?g$1({effort:ue,modelKey:ae},d):null,S=oe&&!c$2;useEffect(()=>{K.current=null,I(null),P(null),b$2(null);},[s]),useEffect(()=>{c$2===a$1&&D&&D!==a$1&&D!==K.current&&(I(null),P(null));},[D,c$2]);function w(l){Y(l),Sr(l);}function H(l){K.current=l===a$1?D:null,I(l),P(null),w({effort:null,modelKey:l});}function j(l){P(l),ae&&w({effort:l,modelKey:ae});}let fe=u$1.state?.onboardingPrompt,Ye=useRef(null),[wn,Ge]=useState(null);if(useEffect(()=>{!fe||Ye.current===u$1.key||s||!t$1||!e$1||!p||S||m.current||(Ye.current=u$1.key,a$4(u$1.pathname,{replace:true,state:null}),ve(fe,[]).catch(l=>{Ge(fe),b$2(l instanceof Error?l.message:"Failed to send the message.");}));},[e$1,s,u$1.key,S,fe,t$1,p]),!t$1||!e$1)return jsx("div",{className:"fk:flex fk:h-full fk:items-center fk:justify-center fk:text-sm fk:text-muted-foreground",children:"Select a project to chat with the agent."});let te=e$1,de=t$1,bn=n?.title??o.find(l=>l.id===t$1)?.name??"your project",We=!s&&!f$3,ke=!!(g$2&&be(g$2.messages).live);async function Tn(l,v,V){U({attachments:V,chatId:l,text:v});try{let E=await te.sendAgentChatFollowUp(l,{attachments:V,content:v,modelId:i});if("question"in E){N({messageId:E.question.chatMessageId}),await M$1(g(de).agentChat(l));return}await Ve(l,E);}finally{U(null);}}async function Ve(l,v){await M$1(g(de).agentChat(l),V=>{let E=vn(we(A$1.current[l],V),null,_,l,i,"turn"in v?v.turn.userMessage.createdAt:v.followUp.message.createdAt),ie="turn"in v?Sn(E,v.turn):or(E,v.followUp.message);return A$1.current[l]=ie,ie},{revalidate:false});}let In={onConnected:async l=>{if(!s)return;let v=s;try{await Ve(v,await te.announcePluginConnected(v,l));}catch(V){b$2(V instanceof Error?V.message:"The agent could not continue after the connection.");}}};async function ve(l,v){if(m.current)throw new Error("A message is already being sent.");if(S)throw new Error("This chat is still loading.");m.current=true,W(true),b$2(null);let V=g$2?Te(g$2.messages):null;if(s&&(ke||V)){try{!ke&&V&&await te.startQueuedAgentChatMessage(s,V.id).catch(()=>{}),await Tn(s,l,v);}catch(E){throw b$2(E instanceof Error?E.message:"Failed to send the message."),E}finally{m.current=false,W(false);}return}Z({attachments:v,chatId:s,text:l});try{let E=s?{chat:null,turn:await te.sendAgentChatMessage(s,{attachments:v,content:l,modelId:i})}:await te.startAgentChat({attachments:v,content:l,modelId:i}),{chat:ie,turn:Ze}=E,Se=s??ie.id;await M$1(g(de).agentChat(Se),Rn=>{let et=Sn(vn(we(A$1.current[Se],Rn),ie,_,Se,i,Ze.userMessage.createdAt),Ze);return A$1.current[Se]=et,et},{revalidate:!1}),ie&&a$4(`${y}/chats/${ie.id}`),Z(null);}catch(E){throw Z(null),b$2(E instanceof Error?E.message:"Failed to send the message."),E}finally{m.current=false,W(false);}}async function En(){if(s)try{await te.stopAgentChat(s);}catch(l){b$2(l instanceof Error?l.message:"Failed to stop the turn.");}finally{await M$1(g(de).agentChat(s));}}return jsxs(Nb,{children:[jsx(fr,{draftKey:a$2(de,s)}),jsx(dr,{onRestored:Ge,text:wn}),jsxs("div",{className:"fk:flex fk:h-full fk:min-h-0 fk:flex-col fk:gap-2",children:[jsxs("div",{className:"fk:mb-2 fk:flex fk:shrink-0 fk:items-start fk:gap-2",children:[jsxs(b$1,{children:[jsx(c$1,{asChild:true,children:jsx(M,{className:"fk:-ml-1 fk:h-4 fk:w-4"})}),jsx(e,{children:"Toggle Sidebar"})]}),jsx(l,{orientation:"vertical",className:"fk:mt-1 fk:h-4"}),jsx("div",{className:"fk:flex fk:flex-1 fk:items-center fk:gap-2",children:jsx("h1",{className:"fk:truncate fk:text-lg fk:font-semibold fk:leading-none fk:tracking-tight",children:s?g$2?.chat.title?.trim()??"Chat":"Agent"})})]}),jsx("div",{className:"fk:flex fk:min-h-0 fk:flex-1 fk:gap-4",children:jsxs("div",{className:a$3("fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col fk:gap-3",We&&"fk:justify-center fk:pb-[12vh]"),children:[We?jsx(Ar,{canSend:!G&&!S,hasSchema:n?n.schema.some(l=>!l.name.startsWith("_")):true,onPrompt:l=>ve(l,[]).then(()=>true,v=>(b$2(v instanceof Error?v.message:"Failed to send the message."),false)),projectId:de}):jsx(A.Provider,{value:true,children:jsx(u.Provider,{value:In,children:jsx(pr,{api:te,chatId:s??null,pendingFollowUp:re,pendingMessage:f$3,projectId:t$1,questionAnsweredSignal:ee,resolveDetail:C})})}),jsxs("div",{className:"fk:shrink-0 fk:pb-3",children:[s?jsx(t,{api:te,chatId:s,projectId:t$1,sending:G||S,onTurnIntoAutomation:l=>{m.current||S||ve(`Turn the monitor \u201C${l.description}\u201D into an automation.`,[]).catch(v=>b$2(v instanceof Error?v.message:"Failed to send the message."));}}):null,se?jsx("p",{className:"fk:mx-auto fk:mb-2 fk:max-w-4xl fk:text-xs fk:text-destructive",children:se}):null,jsx(cr,{api:te,effort:ue,modelKey:ae,modelPending:S,models:d,sending:G,streaming:ke,onEffortChange:j,onError:b$2,onModelChange:H,onSend:ve,onStop:En,placeholder:ke?"Add context or steer the agent...":`Ask Flexkit anything about ${bn}...`})]})]})})]})]})}export{ls as AgentChatPage};//# sourceMappingURL=chat-page-DW3FP4UZ.js.map
4
- //# sourceMappingURL=chat-page-DW3FP4UZ.js.map
3
+ `));},[O]);let f=!C&&o.status!=="streaming"&&(o.status==="awaiting_approval"||P==="paused"||g$2(x)||j(x)),B$1=useMemo(()=>new Set(h(x)),[x]),U=n.pendingApproval&&!B$1.has(n.pendingApproval.id)?n.pendingApproval:null,ee=x?.parts[x.parts.length-1],N=ee?.type==="text"&&ee.state==="streaming",re=j(x)?"Waiting for your answer":"Awaiting approval",se=f?re:f$3(x)??"Thinking",b=f?P!=="finished"&&P!=="error":P==="streaming"&&!N;useEffect(()=>{G.current({label:se,visible:b});},[se,b]);let D$1=!!U&&f,oe=P==="finished"?xn(L.flatMap(h=>h.parts)):null;return L.length===0&&!D$1?jsx(z.Provider,{value:W,children:null}):jsx(z.Provider,{value:W,children:jsxs("div",{className:"fk:w-full fk:min-w-0 fk:space-y-8",children:[L.map(h=>jsx("div",{className:"fk:space-y-8 fk:min-w-0",children:h.parts.map((X,$)=>jsx(F,{api:e,part:X,partIndex:$,parts:h.parts},$))},h.id)),U&&D$1?jsx(I,{api:e,message:E(U)}):null,oe?jsx(Mn,{prompt:oe}):null]})})}function fr({draftKey:e}){let{textInput:t}=Lb(),{setInput:n,value:o}=t,s=useRef(null);return useLayoutEffect(()=>{if(s.current===e){c$2(e,o);return}s.current=e;let a=b$2(e);a!==o&&n(a);},[e,n,o]),null}function dr({onRestored:e,text:t}){let{textInput:n}=Lb(),{setInput:o}=n;return useEffect(()=>{t!==null&&(o(t),e(null));},[e,o,t]),null}function cr({api:e,effort:t,modelKey:n$1,modelPending:o$1,models:s,onEffortChange:a,onError:u,onModelChange:y,onSend:M,onStop:p$1,placeholder:_,sending:A,streaming:C}){let{attachments:g,textInput:d$1}=Lb(),c$1=o(e,u),{currentProjectId:I}=f(),{data:x,error:P}=le(I?`/api/flexkit/${I}/plugins`:null,f$1),K=useRef(false),L=s.filter(f=>!f.deprecated||b(f)===n$1),Y=c(s,n$1),G=e$1(Y),W=d(Y,t),m$1=d$1.value.trim().length>0||g.files.length>0,O=hn({hasDraft:m$1,streaming:C}),Z=m$1&&!c$1.isUploading&&!A&&!o$1;return jsxs(Tb,{accept:n,className:"fk:mx-auto fk:max-w-4xl",maxFileSize:l$1,maxFiles:m,multiple:true,onError:f=>u(f.message),onSubmit:({text:f})=>{let B=f?.trim()??"",U=c$1.getUploaded(g.files.map(N=>N.id));if(!B&&U.length===0||c$1.isUploading||A||K.current||o$1||!x&&!P&&I)return Promise.reject(new Error("The message cannot be sent right now."));let ee=c$4(B,x?.plugins??[]);return ee?(d$1.setInput(ee.tokens.reduce((N,re)=>N.split(re).join(""),f)),u(`That looks like a ${ee.label}. It was removed from your message: connect ${ee.plugin.name} from its connect card or AI \u2192 Plugins instead, where it is stored encrypted and never shown to the agent.`),Promise.reject(new Error("The message contains a plugin token."))):(K.current=true,d$1.clear(),M(B,U).catch(N=>{throw d$1.setInput(f),N}).finally(()=>{K.current=false;}))},children:[g.files.length>0?jsx(Wb,{children:jsx(p,{uploads:c$1})}):null,jsx(Ub,{children:jsx(Vb,{disabled:A,placeholder:_})}),jsxs(Xb,{children:[jsxs(Yb,{children:[jsxs(_b,{children:[jsx($b,{"aria-label":"Add attachments",className:"fk:border-0 fk:bg-border fk:corner-round",disabled:A,tooltip:"Add photos or files"}),jsx(ac,{children:jsx(Rb,{})})]}),L.length>0?jsxs(dc,{value:n$1??void 0,onValueChange:y,children:[jsx(ec,{"aria-label":"Model",className:"fk:min-w-44",children:jsx(hc,{placeholder:"Model"})}),jsx(fc,{children:L.map(f=>jsx(gc,{value:b(f),children:f.name},b(f)))})]}):null,G.length>1&&W?jsxs(dc,{value:W,onValueChange:a,children:[jsx(ec,{"aria-label":"Reasoning effort",className:"fk:min-w-28",children:jsx(hc,{placeholder:"Effort"})}),jsx(fc,{children:G.map(f=>jsx(gc,{value:f.value,children:f.label},f.value))})]}):null]}),jsxs("div",{className:"fk:flex fk:items-center fk:gap-3",children:[jsx(Gc,{disabled:A,onAudioRecorded:async(f,B)=>{let{text:U}=await e.transcribeAgentAudio(f,B);return U},onError:f=>u(f.message),onTranscriptionChange:f=>{u(null),d$1.setInput(a$4(d$1.value,f));}}),jsx(cc,{className:"fk:corner-round",disabled:O==="stop"?false:!Z,status:O==="stop"?"streaming":void 0,onStop:()=>{p$1();}})]})]})]})}var je={chatId:null,error:null,loading:false,older:[],page:null},gr=3e3;function pr({api:e,chatId:t,projectId:n,pendingFollowUp:o,pendingMessage:s,questionAnsweredSignal:a,resolveDetail:u}){let{data:y,mutate:M}=le(t?g(n).agentChat(t):null,f$1,{refreshInterval:0}),p=u(y),[_,A]=useState(je),C=_.chatId===t?_:je,g$1=useRef(t);g$1.current=t;let d=(i,S)=>A(w=>{if(w.chatId!==i&&g$1.current!==i)return w;let H=w.chatId===i?w:{...je,chatId:i};return {...H,...S(H)}}),c=useRef({chatId:null,messages:[]}),I=p?.messages;useEffect(()=>{let i=c.current,S=I??[];if(c.current={chatId:t,messages:S},!t||i.chatId!==t)return;let w=new Set(S.map(j=>j.id)),H=i.messages.filter(j=>!w.has(j.id));H.length>0&&d(t,j=>({older:pe([...j.older,...H])}));},[t,I]);let x=new Set(p?.messages.map(i=>i.id)??[]),P=[...C.older.filter(i=>!x.has(i.id)),...p?.messages??[]],K=useRef(p);K.current=p;let L=useRef(void 0);le(t?`${g(n).agentChat(t)}?view=status`:null,f$1,{refreshInterval:()=>rr(K.current),onSuccess:i=>{let S=JSON.stringify(i),w=L.current;L.current=S;let{current:H}=K,j=H?[...H.messages].reverse().find(fe=>fe.role==="assistant"):void 0;(w&&w!==S||j&&i.latestMessage&&(j.id!==i.latestMessage.id||j.status!==i.latestMessage.status||j.workflowRunId!==i.latestMessage.workflowRunId||H?.chat.updatedAt!==i.chat.updatedAt))&&M();}});let Y=async()=>{let i=C.page?.cursor??p?.nextCursor;if(!t||!i||C.loading)return;let S=t;d(S,()=>({error:null,loading:true}));try{let w=await f$1(`${g(n).agentChat(S)}?before=${encodeURIComponent(i)}`);d(S,H=>({loading:!1,older:pe([...w.messages,...H.older]),page:{cursor:w.nextCursor??null,hasMore:w.hasMore??!1}}));}catch{d(S,()=>({error:"Could not load earlier messages. Try again.",loading:false}));}},{after:G,before:W,live:m}=be(P),[O,Z]=useState({ids:[],messageId:""}),f=mn(P);for(let i of m&&O.messageId===m.id?O.ids:[])f.add(i);let B=G.filter(i=>pn(i.status)&&!f.has(i.id)),U=W.filter(i=>!f.has(i.id)),N=(!m&&!s?Te(P):null)?.id??null,[re,se]=useState(0),b=useRef(null);useEffect(()=>{if(!t||!N||b.current===N)return;b.current=N;let i=false,S=null;return e.startQueuedAgentChatMessage(t,N).then(()=>{},()=>{S=setTimeout(()=>{i||se(w=>w+1);},gr);}).finally(()=>{b.current=null,M();}),()=>{i=true,S&&clearTimeout(S);}},[e,t,M,N,re]);let[D,oe]=useState(null),h=m&&D?.messageId===m.id?D.status:null;if(t&&!p&&!s)return jsxs("div",{className:"fk:flex fk:flex-1 fk:items-center fk:justify-center fk:gap-2 fk:text-sm fk:text-muted-foreground",children:[jsx(LoaderCircle,{className:"fk:size-4 fk:animate-spin"}),"Loading chat..."]});let X=!!s||!!m,$=[...U].reverse().find(i=>i.role==="assistant")?.id??null,ue=m?h?.label??"Thinking":"Sending",ae=m?h?.visible??true:true;return jsxs(Ya,{className:"fk:h-0 fk:min-h-0 fk:flex-1",children:[jsx(Za,{className:"fk:gap-0 fk:p-0",children:jsxs("div",{className:"fk:mx-auto fk:w-full fk:max-w-4xl fk:space-y-5 fk:pb-6 fk:pr-4",children:[C.page?.hasMore??p?.hasMore?jsx(c$3,{variant:"ghost",disabled:C.loading,onClick:()=>{Y();},children:C.loading?"Loading\u2026":"Load earlier messages"}):null,C.error?jsx("p",{role:"alert",children:C.error}):null,U.map(i=>jsx(An,{api:e,message:i,showSuggestion:!X&&i.id===$},i.id)),m&&t&&p?jsx(ur,{api:e,chatId:t,detail:p,message:m,onMidTurnDelivered:i=>Z({ids:i,messageId:m.id}),onStatusChange:i=>oe({messageId:m.id,status:i}),onTurnUpdated:()=>{M();},questionAnsweredSignal:a}):null,s&&!m?jsx(qe,{attachments:s.attachments,text:s.text}):null,X?jsx(H,{label:ue,visible:ae}):null,B.map(i=>jsx(An,{api:e,message:i},i.id)),o&&m?jsx(qe,{attachments:o.attachments,text:o.text}):null]})}),jsx($a,{})]})}var Cn=["Where should we begin?","Ready when you are","What\u2019s on the agenda today?","What\u2019s on your mind today?"];function mr(e){return [`How can I help, ${e}?`,`Good to see you, ${e}.`,`Hey, ${e}. Ready to dive in?`]}function hr(e){let t=e?[...Cn,...mr(e)]:Cn;return t[Math.floor(Math.random()*t.length)]??"How can I help?"}var Pn="flexkit-ai:lastModelId",Je="flexkit-ai:lastEffort";function kr(){if(typeof localStorage>"u")return null;try{let e=localStorage.getItem(Pn);return e?{effort:localStorage.getItem(Je),modelKey:e}:null}catch{return null}}function vr(e){return e.selectedModelKey?{effort:e.selectedEffort,modelKey:e.selectedModelKey}:e.awaitingChatModel?{effort:null,modelKey:null}:e.chatSelection?{effort:e.selectedEffort??e.chatSelection.effort,modelKey:e.chatSelection.modelKey}:e.lastUsed?{effort:e.selectedEffort??e.lastUsed.effort,modelKey:e.lastUsed.modelKey}:{effort:e.selectedEffort,modelKey:e.defaultModelKey}}function Sr(e){if(!(typeof localStorage>"u"))try{localStorage.setItem(Pn,e.modelKey),e.effort?localStorage.setItem(Je,e.effort):localStorage.removeItem(Je);}catch{}}function Ar({canSend:e,hasSchema:t,onPrompt:n,projectId:o}){let{data:s,isLoading:a}=le(g(o).agentProfile(),f$1),u=useMemo(()=>a?null:hr(s?.preferredName??null),[s?.preferredName,a]);return jsxs("div",{className:"fk:flex fk:flex-col fk:items-center fk:gap-6 fk:pb-2 fk:text-center",children:[jsx("h2",{className:"fk:text-2xl fk:font-semibold",children:u??"\xA0"}),jsx(cn,{canSend:e,onPrompt:n,projectId:o}),t?null:jsx(Cr,{canSend:e,onPrompt:n,projectId:o})]})}function Cr({canSend:e,onPrompt:t,projectId:n}){let{data:o,error:s}=le(a$5(n),f$1,{revalidateOnFocus:false}),a=Pe(n,"empty-schema",h$1);return o===void 0&&s===void 0||o?.starter||a.visible.length===0?null:jsxs("div",{className:"fk:mx-auto fk:flex fk:w-full fk:max-w-2xl fk:flex-col fk:items-center fk:gap-3",children:[jsx("p",{className:"fk:text-sm fk:text-muted-foreground",children:"This project has no schema yet. Start with:"}),jsx(Xe,{canSend:e,onPrompt:t,suggestions:a})]})}function ls(){let{api:e$1,projectId:t$1}=x(),{currentProject:n,projectSummaries:o}=f(),{chatId:s}=useParams(),a$4=useNavigate(),u$1=useLocation(),y=a(),{mutate:M$1}=useSWRConfig(),{data:p}=le(t$1?g(t$1).tools():null,f$1),{data:_}=le(t$1&&s?g(t$1).agentChat(s):null,f$1),A$1=useRef({});function C(l){return ar(A$1.current,s,l)}let g$2=C(_),d=useMemo(()=>p?.tools.models??[],[p]),[c$2,I]=useState(null),[x$1,P]=useState(null),K=useRef(null),[L,Y]=useState(kr),[G,W]=useState(false),m=useRef(false),[O,Z]=useState(null),f$3=O&&O.chatId===s?O:void 0,[B,U]=useState(null),[ee,N]=useState(null),re=B&&B.chatId===s?B:void 0,[se,b$2]=useState(null),D=g$2?.chat.modelId??null,oe=!!s&&g$2===void 0,h=useMemo(()=>f$2(D,d)??(D?{effort:null,modelKey:D}:null),[D,d]),X=useMemo(()=>{let l=d.find(v=>!v.deprecated);return l?b(l):null},[d]),$=useMemo(()=>{let l=c(d,L?.modelKey??null);return L&&l&&!l.deprecated?L:null},[d,L]),{effort:ue,modelKey:ae}=vr({awaitingChatModel:oe,chatSelection:h,defaultModelKey:X,lastUsed:$,selectedEffort:x$1,selectedModelKey:c$2}),i=ae?g$1({effort:ue,modelKey:ae},d):null,S=oe&&!c$2;useEffect(()=>{K.current=null,I(null),P(null),b$2(null);},[s]),useEffect(()=>{c$2===a$1&&D&&D!==a$1&&D!==K.current&&(I(null),P(null));},[D,c$2]);function w(l){Y(l),Sr(l);}function H(l){K.current=l===a$1?D:null,I(l),P(null),w({effort:null,modelKey:l});}function j(l){P(l),ae&&w({effort:l,modelKey:ae});}let fe=u$1.state?.onboardingPrompt,Ye=useRef(null),[wn,Ge]=useState(null);if(useEffect(()=>{!fe||Ye.current===u$1.key||s||!t$1||!e$1||!p||S||m.current||(Ye.current=u$1.key,a$4(u$1.pathname,{replace:true,state:null}),ve(fe,[]).catch(l=>{Ge(fe),b$2(l instanceof Error?l.message:"Failed to send the message.");}));},[e$1,s,u$1.key,S,fe,t$1,p]),!t$1||!e$1)return jsx("div",{className:"fk:flex fk:h-full fk:items-center fk:justify-center fk:text-sm fk:text-muted-foreground",children:"Select a project to chat with the agent."});let te=e$1,de=t$1,bn=n?.title??o.find(l=>l.id===t$1)?.name??"your project",We=!s&&!f$3,ke=!!(g$2&&be(g$2.messages).live);async function Tn(l,v,V){U({attachments:V,chatId:l,text:v});try{let E=await te.sendAgentChatFollowUp(l,{attachments:V,content:v,modelId:i});if("question"in E){N({messageId:E.question.chatMessageId}),await M$1(g(de).agentChat(l));return}await Ve(l,E);}finally{U(null);}}async function Ve(l,v){await M$1(g(de).agentChat(l),V=>{let E=vn(we(A$1.current[l],V),null,_,l,i,"turn"in v?v.turn.userMessage.createdAt:v.followUp.message.createdAt),ie="turn"in v?Sn(E,v.turn):or(E,v.followUp.message);return A$1.current[l]=ie,ie},{revalidate:false});}let In={onConnected:async l=>{if(!s)return;let v=s;try{await Ve(v,await te.announcePluginConnected(v,l));}catch(V){b$2(V instanceof Error?V.message:"The agent could not continue after the connection.");}}};async function ve(l,v){if(m.current)throw new Error("A message is already being sent.");if(S)throw new Error("This chat is still loading.");m.current=true,W(true),b$2(null);let V=g$2?Te(g$2.messages):null;if(s&&(ke||V)){try{!ke&&V&&await te.startQueuedAgentChatMessage(s,V.id).catch(()=>{}),await Tn(s,l,v);}catch(E){throw b$2(E instanceof Error?E.message:"Failed to send the message."),E}finally{m.current=false,W(false);}return}Z({attachments:v,chatId:s,text:l});try{let E=s?{chat:null,turn:await te.sendAgentChatMessage(s,{attachments:v,content:l,modelId:i})}:await te.startAgentChat({attachments:v,content:l,modelId:i}),{chat:ie,turn:Ze}=E,Se=s??ie.id;await M$1(g(de).agentChat(Se),Rn=>{let et=Sn(vn(we(A$1.current[Se],Rn),ie,_,Se,i,Ze.userMessage.createdAt),Ze);return A$1.current[Se]=et,et},{revalidate:!1}),ie&&a$4(`${y}/chats/${ie.id}`),Z(null);}catch(E){throw Z(null),b$2(E instanceof Error?E.message:"Failed to send the message."),E}finally{m.current=false,W(false);}}async function En(){if(s)try{await te.stopAgentChat(s);}catch(l){b$2(l instanceof Error?l.message:"Failed to stop the turn.");}finally{await M$1(g(de).agentChat(s));}}return jsxs(Nb,{children:[jsx(fr,{draftKey:a$2(de,s)}),jsx(dr,{onRestored:Ge,text:wn}),jsxs("div",{className:"fk:flex fk:h-full fk:min-h-0 fk:flex-col fk:gap-2",children:[jsxs("div",{className:"fk:mb-2 fk:flex fk:shrink-0 fk:items-start fk:gap-2",children:[jsxs(b$1,{children:[jsx(c$1,{asChild:true,children:jsx(M,{className:"fk:-ml-1 fk:h-4 fk:w-4"})}),jsx(e,{children:"Toggle Sidebar"})]}),jsx(l,{orientation:"vertical",className:"fk:mt-1 fk:h-4"}),jsx("div",{className:"fk:flex fk:flex-1 fk:items-center fk:gap-2",children:jsx("h1",{className:"fk:truncate fk:text-lg fk:font-semibold fk:leading-none fk:tracking-tight",children:s?g$2?.chat.title?.trim()??"Chat":"Agent"})})]}),jsx("div",{className:"fk:flex fk:min-h-0 fk:flex-1 fk:gap-4",children:jsxs("div",{className:a$3("fk:flex fk:min-h-0 fk:min-w-0 fk:flex-1 fk:flex-col fk:gap-3",We&&"fk:justify-center fk:pb-[12vh]"),children:[We?jsx(Ar,{canSend:!G&&!S,hasSchema:n?n.schema.some(l=>!l.name.startsWith("_")):true,onPrompt:l=>ve(l,[]).then(()=>true,v=>(b$2(v instanceof Error?v.message:"Failed to send the message."),false)),projectId:de}):jsx(A.Provider,{value:true,children:jsx(u.Provider,{value:In,children:jsx(pr,{api:te,chatId:s??null,pendingFollowUp:re,pendingMessage:f$3,projectId:t$1,questionAnsweredSignal:ee,resolveDetail:C})})}),jsxs("div",{className:"fk:shrink-0 fk:pb-3",children:[s?jsx(t,{api:te,chatId:s,projectId:t$1,sending:G||S,onTurnIntoAutomation:l=>{m.current||S||ve(`Turn the monitor \u201C${l.description}\u201D into an automation.`,[]).catch(v=>b$2(v instanceof Error?v.message:"Failed to send the message."));}}):null,se?jsx("p",{className:"fk:mx-auto fk:mb-2 fk:max-w-4xl fk:text-xs fk:text-destructive",children:se}):null,jsx(cr,{api:te,effort:ue,modelKey:ae,modelPending:S,models:d,sending:G,streaming:ke,onEffortChange:j,onError:b$2,onModelChange:H,onSend:ve,onStop:En,placeholder:ke?"Add context or steer the agent...":`Ask Flexkit anything about ${bn}...`})]})]})})]})]})}export{ls as AgentChatPage};//# sourceMappingURL=chat-page-2ES466GO.js.map
4
+ //# sourceMappingURL=chat-page-2ES466GO.js.map