@tanstack/ai-devtools-core 0.0.3 → 0.1.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 CHANGED
@@ -38,7 +38,9 @@
38
38
  A powerful, type-safe AI SDK for building AI-powered applications.
39
39
 
40
40
  - Provider-agnostic adapters (OpenAI, Anthropic, Gemini, Ollama, etc.)
41
+ - **Tree-shakeable adapters** - Import only what you need for smaller bundles
41
42
  - **Multimodal content support** - Send images, audio, video, and documents
43
+ - **Image generation** - Generate images with OpenAI DALL-E/GPT-Image and Gemini Imagen
42
44
  - Chat completion, streaming, and agent loop strategies
43
45
  - Headless chat state management with adapters (SSE, HTTP stream, custom)
44
46
  - Isomorphic type-safe tools with server/client execution
@@ -46,6 +48,30 @@ A powerful, type-safe AI SDK for building AI-powered applications.
46
48
 
47
49
  ### <a href="https://tanstack.com/ai">Read the docs →</b></a>
48
50
 
51
+ ## Tree-Shakeable Adapters
52
+
53
+ Import only the functionality you need for smaller bundle sizes:
54
+
55
+ ```typescript
56
+ // Only chat functionality - no summarization code bundled
57
+ import { openaiText } from '@tanstack/ai-openai/adapters'
58
+ import { generate } from '@tanstack/ai'
59
+
60
+ const textAdapter = openaiText()
61
+
62
+ const result = generate({
63
+ adapter: textAdapter,
64
+ model: 'gpt-4o',
65
+ messages: [{ role: 'user', content: [{ type: 'text', content: 'Hello!' }] }],
66
+ })
67
+
68
+ for await (const chunk of result) {
69
+ console.log(chunk)
70
+ }
71
+ ```
72
+
73
+ Available adapters: `openaiText`, `openaiEmbed`, `openaiSummarize`, `anthropicText`, `geminiText`, `ollamaText`, and more.
74
+
49
75
  ## Bonus: TanStack Start Integration
50
76
 
51
77
  TanStack AI works with **any** framework (Next.js, Express, Remix, etc.).
@@ -6,7 +6,6 @@ import { ConversationHeader } from "./conversation/ConversationHeader.js";
6
6
  import { ConversationTabs } from "./conversation/ConversationTabs.js";
7
7
  import { MessagesTab } from "./conversation/MessagesTab.js";
8
8
  import { ChunksTab } from "./conversation/ChunksTab.js";
9
- import { EmbeddingsTab } from "./conversation/EmbeddingsTab.js";
10
9
  import { SummariesTab } from "./conversation/SummariesTab.js";
11
10
  var _tmpl$ = /* @__PURE__ */ template(`<div>Select a conversation to view details`), _tmpl$2 = /* @__PURE__ */ template(`<div><div>`);
12
11
  const ConversationDetails = () => {
@@ -25,8 +24,6 @@ const ConversationDetails = () => {
25
24
  if (conv.type === "server") {
26
25
  if (conv.chunks.length > 0) {
27
26
  setActiveTab("chunks");
28
- } else if (conv.hasEmbedding || conv.embeddings && conv.embeddings.length > 0) {
29
- setActiveTab("embeddings");
30
27
  } else if (conv.hasSummarize || conv.summaries && conv.summaries.length > 0) {
31
28
  setActiveTab("summaries");
32
29
  } else {
@@ -91,18 +88,6 @@ const ConversationDetails = () => {
91
88
  });
92
89
  }
93
90
  }), null);
94
- insert(_el$3, createComponent(Show, {
95
- get when() {
96
- return activeTab() === "embeddings";
97
- },
98
- get children() {
99
- return createComponent(EmbeddingsTab, {
100
- get embeddings() {
101
- return conv().embeddings ?? [];
102
- }
103
- });
104
- }
105
- }), null);
106
91
  insert(_el$3, createComponent(Show, {
107
92
  get when() {
108
93
  return activeTab() === "summaries";
@@ -1 +1 @@
1
- {"version":3,"file":"ConversationDetails.js","sources":["../../../src/components/ConversationDetails.tsx"],"sourcesContent":["import { Show, createEffect, createSignal } from 'solid-js'\nimport { useStyles } from '../styles/use-styles'\nimport { useAIStore } from '../store/ai-context'\nimport {\n ChunksTab,\n ConversationHeader,\n ConversationTabs,\n EmbeddingsTab,\n MessagesTab,\n SummariesTab,\n} from './conversation'\nimport type { TabType } from './conversation'\nimport type { Conversation } from '../store/ai-context'\nimport type { Component } from 'solid-js'\n\nexport const ConversationDetails: Component = () => {\n const { state } = useAIStore()\n const styles = useStyles()\n const [activeTab, setActiveTab] = createSignal<TabType>('messages')\n\n const activeConversation = (): Conversation | undefined => {\n if (!state.activeConversationId) return undefined\n return state.conversations[state.activeConversationId]\n }\n\n // Update active tab when conversation changes\n createEffect(() => {\n const conv = activeConversation()\n if (conv) {\n // For server conversations, always use chunks (messages tab is hidden)\n if (conv.type === 'server') {\n if (conv.chunks.length > 0) {\n setActiveTab('chunks')\n } else if (\n conv.hasEmbedding ||\n (conv.embeddings && conv.embeddings.length > 0)\n ) {\n setActiveTab('embeddings')\n } else if (\n conv.hasSummarize ||\n (conv.summaries && conv.summaries.length > 0)\n ) {\n setActiveTab('summaries')\n } else {\n setActiveTab('chunks')\n }\n } else {\n // For client conversations, default to messages tab\n setActiveTab('messages')\n }\n }\n })\n\n return (\n <Show\n when={activeConversation()}\n fallback={\n <div class={styles().conversationDetails.emptyState}>\n Select a conversation to view details\n </div>\n }\n >\n {(conv) => (\n <div class={styles().conversationDetails.container}>\n <ConversationHeader conversation={conv()} />\n <ConversationTabs\n conversation={conv()}\n activeTab={activeTab()}\n onTabChange={setActiveTab}\n />\n <div class={styles().conversationDetails.contentArea}>\n <Show when={activeTab() === 'messages'}>\n <MessagesTab messages={conv().messages} />\n </Show>\n <Show when={activeTab() === 'chunks'}>\n <ChunksTab chunks={conv().chunks} messages={conv().messages} />\n </Show>\n <Show when={activeTab() === 'embeddings'}>\n <EmbeddingsTab embeddings={conv().embeddings ?? []} />\n </Show>\n <Show when={activeTab() === 'summaries'}>\n <SummariesTab summaries={conv().summaries ?? []} />\n </Show>\n </div>\n </div>\n )}\n </Show>\n )\n}\n"],"names":["ConversationDetails","state","useAIStore","styles","useStyles","activeTab","setActiveTab","createSignal","activeConversation","activeConversationId","undefined","conversations","createEffect","conv","type","chunks","length","hasEmbedding","embeddings","hasSummarize","summaries","_$createComponent","Show","when","fallback","_el$","_tmpl$","_$effect","_$className","conversationDetails","emptyState","children","_el$2","_tmpl$2","_el$3","firstChild","_$insert","ConversationHeader","conversation","ConversationTabs","onTabChange","MessagesTab","messages","ChunksTab","EmbeddingsTab","SummariesTab","_p$","_v$","container","_v$2","contentArea","e","t"],"mappings":";;;;;;;;;;;AAeO,MAAMA,sBAAiCA,MAAM;AAClD,QAAM;AAAA,IAAEC;AAAAA,EAAAA,IAAUC,WAAAA;AAClB,QAAMC,SAASC,UAAAA;AACf,QAAM,CAACC,WAAWC,YAAY,IAAIC,aAAsB,UAAU;AAElE,QAAMC,qBAAqBA,MAAgC;AACzD,QAAI,CAACP,MAAMQ,qBAAsB,QAAOC;AACxC,WAAOT,MAAMU,cAAcV,MAAMQ,oBAAoB;AAAA,EACvD;AAGAG,eAAa,MAAM;AACjB,UAAMC,OAAOL,mBAAAA;AACb,QAAIK,MAAM;AAER,UAAIA,KAAKC,SAAS,UAAU;AAC1B,YAAID,KAAKE,OAAOC,SAAS,GAAG;AAC1BV,uBAAa,QAAQ;AAAA,QACvB,WACEO,KAAKI,gBACJJ,KAAKK,cAAcL,KAAKK,WAAWF,SAAS,GAC7C;AACAV,uBAAa,YAAY;AAAA,QAC3B,WACEO,KAAKM,gBACJN,KAAKO,aAAaP,KAAKO,UAAUJ,SAAS,GAC3C;AACAV,uBAAa,WAAW;AAAA,QAC1B,OAAO;AACLA,uBAAa,QAAQ;AAAA,QACvB;AAAA,MACF,OAAO;AAELA,qBAAa,UAAU;AAAA,MACzB;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAAe,gBACGC,MAAI;AAAA,IAAA,IACHC,OAAI;AAAA,aAAEf,mBAAAA;AAAAA,IAAoB;AAAA,IAAA,IAC1BgB,WAAQ;AAAA,cAAA,MAAA;AAAA,YAAAC,OAAAC,OAAAA;AAAAC,eAAA,MAAAC,UAAAH,MACMtB,SAAS0B,oBAAoBC,UAAU,CAAA;AAAA,eAAAL;AAAAA,MAAA,GAAA;AAAA,IAAA;AAAA,IAAAM,UAKnDlB,WAAI,MAAA;AAAA,UAAAmB,QAAAC,QAAAA,GAAAC,QAAAF,MAAAG;AAAAC,aAAAJ,OAAAX,gBAEDgB,oBAAkB;AAAA,QAAA,IAACC,eAAY;AAAA,iBAAEzB,KAAAA;AAAAA,QAAM;AAAA,MAAA,CAAA,GAAAqB,KAAA;AAAAE,aAAAJ,OAAAX,gBACvCkB,kBAAgB;AAAA,QAAA,IACfD,eAAY;AAAA,iBAAEzB,KAAAA;AAAAA,QAAM;AAAA,QAAA,IACpBR,YAAS;AAAA,iBAAEA,UAAAA;AAAAA,QAAW;AAAA,QACtBmC,aAAalC;AAAAA,MAAAA,CAAY,GAAA4B,KAAA;AAAAE,aAAAF,OAAAb,gBAGxBC,MAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAElB,gBAAgB;AAAA,QAAU;AAAA,QAAA,IAAA0B,WAAA;AAAA,iBAAAV,gBACnCoB,aAAW;AAAA,YAAA,IAACC,WAAQ;AAAA,qBAAE7B,OAAO6B;AAAAA,YAAQ;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAA,IAAA;AAAAN,aAAAF,OAAAb,gBAEvCC,MAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAElB,gBAAgB;AAAA,QAAQ;AAAA,QAAA,IAAA0B,WAAA;AAAA,iBAAAV,gBACjCsB,WAAS;AAAA,YAAA,IAAC5B,SAAM;AAAA,qBAAEF,OAAOE;AAAAA,YAAM;AAAA,YAAA,IAAE2B,WAAQ;AAAA,qBAAE7B,OAAO6B;AAAAA,YAAQ;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAA,IAAA;AAAAN,aAAAF,OAAAb,gBAE5DC,MAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAElB,gBAAgB;AAAA,QAAY;AAAA,QAAA,IAAA0B,WAAA;AAAA,iBAAAV,gBACrCuB,eAAa;AAAA,YAAA,IAAC1B,aAAU;AAAA,qBAAEL,KAAAA,EAAOK,cAAc,CAAA;AAAA,YAAE;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAA,IAAA;AAAAkB,aAAAF,OAAAb,gBAEnDC,MAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAElB,gBAAgB;AAAA,QAAW;AAAA,QAAA,IAAA0B,WAAA;AAAA,iBAAAV,gBACpCwB,cAAY;AAAA,YAAA,IAACzB,YAAS;AAAA,qBAAEP,KAAAA,EAAOO,aAAa,CAAA;AAAA,YAAE;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAA,IAAA;AAAAO,aAAAmB,CAAAA,QAAA;AAAA,YAAAC,MAlBzC5C,SAAS0B,oBAAoBmB,WAASC,OAOpC9C,SAAS0B,oBAAoBqB;AAAWH,gBAAAD,IAAAK,KAAAvB,UAAAI,OAAAc,IAAAK,IAAAJ,GAAA;AAAAE,iBAAAH,IAAAM,KAAAxB,UAAAM,OAAAY,IAAAM,IAAAH,IAAA;AAAA,eAAAH;AAAAA,MAAA,GAAA;AAAA,QAAAK,GAAAzC;AAAAA,QAAA0C,GAAA1C;AAAAA,MAAAA,CAAA;AAAA,aAAAsB;AAAAA,IAAA,GAAA;AAAA,EAAA,CAevD;AAGP;"}
1
+ {"version":3,"file":"ConversationDetails.js","sources":["../../../src/components/ConversationDetails.tsx"],"sourcesContent":["import { Show, createEffect, createSignal } from 'solid-js'\nimport { useStyles } from '../styles/use-styles'\nimport { useAIStore } from '../store/ai-context'\nimport {\n ChunksTab,\n ConversationHeader,\n ConversationTabs,\n MessagesTab,\n SummariesTab,\n} from './conversation'\nimport type { TabType } from './conversation'\nimport type { Conversation } from '../store/ai-context'\nimport type { Component } from 'solid-js'\n\nexport const ConversationDetails: Component = () => {\n const { state } = useAIStore()\n const styles = useStyles()\n const [activeTab, setActiveTab] = createSignal<TabType>('messages')\n\n const activeConversation = (): Conversation | undefined => {\n if (!state.activeConversationId) return undefined\n return state.conversations[state.activeConversationId]\n }\n\n // Update active tab when conversation changes\n createEffect(() => {\n const conv = activeConversation()\n if (conv) {\n // For server conversations, always use chunks (messages tab is hidden)\n if (conv.type === 'server') {\n if (conv.chunks.length > 0) {\n setActiveTab('chunks')\n } else if (\n conv.hasSummarize ||\n (conv.summaries && conv.summaries.length > 0)\n ) {\n setActiveTab('summaries')\n } else {\n setActiveTab('chunks')\n }\n } else {\n // For client conversations, default to messages tab\n setActiveTab('messages')\n }\n }\n })\n\n return (\n <Show\n when={activeConversation()}\n fallback={\n <div class={styles().conversationDetails.emptyState}>\n Select a conversation to view details\n </div>\n }\n >\n {(conv) => (\n <div class={styles().conversationDetails.container}>\n <ConversationHeader conversation={conv()} />\n <ConversationTabs\n conversation={conv()}\n activeTab={activeTab()}\n onTabChange={setActiveTab}\n />\n <div class={styles().conversationDetails.contentArea}>\n <Show when={activeTab() === 'messages'}>\n <MessagesTab messages={conv().messages} />\n </Show>\n <Show when={activeTab() === 'chunks'}>\n <ChunksTab chunks={conv().chunks} messages={conv().messages} />\n </Show>\n <Show when={activeTab() === 'summaries'}>\n <SummariesTab summaries={conv().summaries ?? []} />\n </Show>\n </div>\n </div>\n )}\n </Show>\n )\n}\n"],"names":["ConversationDetails","state","useAIStore","styles","useStyles","activeTab","setActiveTab","createSignal","activeConversation","activeConversationId","undefined","conversations","createEffect","conv","type","chunks","length","hasSummarize","summaries","_$createComponent","Show","when","fallback","_el$","_tmpl$","_$effect","_$className","conversationDetails","emptyState","children","_el$2","_tmpl$2","_el$3","firstChild","_$insert","ConversationHeader","conversation","ConversationTabs","onTabChange","MessagesTab","messages","ChunksTab","SummariesTab","_p$","_v$","container","_v$2","contentArea","e","t"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChunksCollapsible.js","sources":["../../../../src/components/conversation/ChunksCollapsible.tsx"],"sourcesContent":["import { For, Show } from 'solid-js'\nimport { useStyles } from '../../styles/use-styles'\nimport { ChunkItem } from './ChunkItem'\nimport { ChunkBadges } from './ChunkBadges'\nimport type { Component } from 'solid-js'\nimport type { Chunk } from '../../store/ai-store'\n\ninterface ChunksCollapsibleProps {\n chunks: Array<Chunk>\n}\n\nexport const ChunksCollapsible: Component<ChunksCollapsibleProps> = (props) => {\n const styles = useStyles()\n\n const accumulatedContent = () =>\n props.chunks\n .filter((c) => c.type === 'content' && (c.content || c.delta))\n .map((c) => c.delta || c.content)\n .join('')\n\n // Total raw chunks = sum of all chunkCounts\n const totalRawChunks = () =>\n props.chunks.reduce((sum, c) => sum + (c.chunkCount || 1), 0)\n\n return (\n <details class={styles().conversationDetails.chunksDetails}>\n <summary class={styles().conversationDetails.chunksSummary}>\n <div class={styles().conversationDetails.chunksSummaryRow}>\n <span class={styles().conversationDetails.chunksSummaryArrow}>\n ▶\n </span>\n <span class={styles().conversationDetails.chunksSummaryTitle}>\n 📦 {totalRawChunks()} chunks\n </span>\n <ChunkBadges chunks={props.chunks} />\n </div>\n {/* Accumulated Content Preview */}\n <Show when={accumulatedContent()}>\n <div\n class={styles().conversationDetails.contentPreview}\n title={accumulatedContent()}\n >\n {accumulatedContent()}\n </div>\n </Show>\n </summary>\n <div class={styles().conversationDetails.chunksContainer}>\n <div class={styles().conversationDetails.chunksList}>\n <For each={props.chunks}>\n {(chunk, index) => (\n <ChunkItem chunk={chunk} index={index()} variant=\"small\" />\n )}\n </For>\n </div>\n </div>\n </details>\n )\n}\n"],"names":["ChunksCollapsible","props","styles","useStyles","accumulatedContent","chunks","filter","c","type","content","delta","map","join","totalRawChunks","reduce","sum","chunkCount","_el$","_tmpl$2","_el$2","firstChild","_el$3","_el$4","_el$5","nextSibling","_el$6","_el$8","_el$0","_el$1","_$insert","_$createComponent","ChunkBadges","Show","when","children","_el$9","_tmpl$","_$effect","_p$","_v$","conversationDetails","contentPreview","_v$2","e","_$className","t","_$setAttribute","undefined","For","each","chunk","index","ChunkItem","variant","_v$3","chunksDetails","_v$4","chunksSummary","_v$5","chunksSummaryRow","_v$6","chunksSummaryArrow","_v$7","chunksSummaryTitle","_v$8","chunksContainer","_v$9","chunksList","a","o","i","n","s"],"mappings":"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"}
1
+ {"version":3,"file":"ChunksCollapsible.js","sources":["../../../../src/components/conversation/ChunksCollapsible.tsx"],"sourcesContent":["import { For, Show } from 'solid-js'\nimport { useStyles } from '../../styles/use-styles'\nimport { ChunkItem } from './ChunkItem'\nimport { ChunkBadges } from './ChunkBadges'\nimport type { Component } from 'solid-js'\nimport type { Chunk } from '../../store/ai-store'\n\ninterface ChunksCollapsibleProps {\n chunks: Array<Chunk>\n}\n\nexport const ChunksCollapsible: Component<ChunksCollapsibleProps> = (props) => {\n const styles = useStyles()\n\n const accumulatedContent = () =>\n props.chunks\n .filter((c) => c.type === 'content' && (c.content || c.delta))\n .map((c) => c.delta || c.content)\n .join('')\n\n // Total raw chunks = sum of all chunkCounts\n const totalRawChunks = () =>\n props.chunks.reduce((sum, c) => sum + (c.chunkCount || 1), 0)\n\n return (\n <details class={styles().conversationDetails.chunksDetails}>\n <summary class={styles().conversationDetails.chunksSummary}>\n <div class={styles().conversationDetails.chunksSummaryRow}>\n <span class={styles().conversationDetails.chunksSummaryArrow}>▶</span>\n <span class={styles().conversationDetails.chunksSummaryTitle}>\n 📦 {totalRawChunks()} chunks\n </span>\n <ChunkBadges chunks={props.chunks} />\n </div>\n {/* Accumulated Content Preview */}\n <Show when={accumulatedContent()}>\n <div\n class={styles().conversationDetails.contentPreview}\n title={accumulatedContent()}\n >\n {accumulatedContent()}\n </div>\n </Show>\n </summary>\n <div class={styles().conversationDetails.chunksContainer}>\n <div class={styles().conversationDetails.chunksList}>\n <For each={props.chunks}>\n {(chunk, index) => (\n <ChunkItem chunk={chunk} index={index()} variant=\"small\" />\n )}\n </For>\n </div>\n </div>\n </details>\n )\n}\n"],"names":["ChunksCollapsible","props","styles","useStyles","accumulatedContent","chunks","filter","c","type","content","delta","map","join","totalRawChunks","reduce","sum","chunkCount","_el$","_tmpl$2","_el$2","firstChild","_el$3","_el$4","_el$5","nextSibling","_el$6","_el$8","_el$0","_el$1","_$insert","_$createComponent","ChunkBadges","Show","when","children","_el$9","_tmpl$","_$effect","_p$","_v$","conversationDetails","contentPreview","_v$2","e","_$className","t","_$setAttribute","undefined","For","each","chunk","index","ChunkItem","variant","_v$3","chunksDetails","_v$4","chunksSummary","_v$5","chunksSummaryRow","_v$6","chunksSummaryArrow","_v$7","chunksSummaryTitle","_v$8","chunksContainer","_v$9","chunksList","a","o","i","n","s"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { Component } from 'solid-js';
2
2
  import { Conversation } from '../../store/ai-context.js';
3
- export type TabType = 'messages' | 'chunks' | 'embeddings' | 'summaries';
3
+ export type TabType = 'messages' | 'chunks' | 'summaries';
4
4
  interface ConversationTabsProps {
5
5
  conversation: Conversation;
6
6
  activeTab: TabType;
@@ -1,22 +1,19 @@
1
1
  import { template, insert, createComponent, effect, className, memo, delegateEvents } from "solid-js/web";
2
2
  import { Show } from "solid-js";
3
3
  import { useStyles } from "../../styles/use-styles.js";
4
- var _tmpl$ = /* @__PURE__ */ template(`<button>💬 Messages (<!>)`), _tmpl$2 = /* @__PURE__ */ template(`<button>📦 Chunks (<!>)`), _tmpl$3 = /* @__PURE__ */ template(`<button>🔢 Embeddings (<!>)`), _tmpl$4 = /* @__PURE__ */ template(`<button>📝 Summaries (<!>)`), _tmpl$5 = /* @__PURE__ */ template(`<div>`);
4
+ var _tmpl$ = /* @__PURE__ */ template(`<button>💬 Messages (<!>)`), _tmpl$2 = /* @__PURE__ */ template(`<button>📦 Chunks (<!>)`), _tmpl$3 = /* @__PURE__ */ template(`<button>📝 Summaries (<!>)`), _tmpl$4 = /* @__PURE__ */ template(`<div>`);
5
5
  const ConversationTabs = (props) => {
6
6
  const styles = useStyles();
7
7
  const conv = () => props.conversation;
8
8
  const totalRawChunks = () => conv().chunks.reduce((sum, c) => sum + (c.chunkCount || 1), 0);
9
- const embeddingsCount = () => conv().embeddings?.length ?? 0;
10
9
  const summariesCount = () => conv().summaries?.length ?? 0;
11
10
  const hasMessages = () => conv().type === "client" && conv().messages.length > 0;
12
11
  const hasChunks = () => conv().chunks.length > 0 || conv().type === "server";
13
- const hasEmbeddings = () => conv().hasEmbedding || embeddingsCount() > 0;
14
12
  const hasSummaries = () => conv().hasSummarize || summariesCount() > 0;
15
13
  const visibleTabCount = () => {
16
14
  let count = 0;
17
15
  if (hasMessages()) count++;
18
16
  if (hasChunks() && conv().type === "server") count++;
19
- if (hasEmbeddings()) count++;
20
17
  if (hasSummaries()) count++;
21
18
  return count;
22
19
  };
@@ -24,7 +21,7 @@ const ConversationTabs = (props) => {
24
21
  return null;
25
22
  }
26
23
  return (() => {
27
- var _el$ = _tmpl$5();
24
+ var _el$ = _tmpl$4();
28
25
  insert(_el$, createComponent(Show, {
29
26
  get when() {
30
27
  return hasMessages();
@@ -53,30 +50,17 @@ const ConversationTabs = (props) => {
53
50
  }), null);
54
51
  insert(_el$, createComponent(Show, {
55
52
  get when() {
56
- return hasEmbeddings();
53
+ return hasSummaries();
57
54
  },
58
55
  get children() {
59
56
  var _el$0 = _tmpl$3(), _el$1 = _el$0.firstChild, _el$11 = _el$1.nextSibling;
60
57
  _el$11.nextSibling;
61
- _el$0.$$click = () => props.onTabChange("embeddings");
62
- insert(_el$0, embeddingsCount, _el$11);
63
- effect(() => className(_el$0, `${styles().actionButton} ${props.activeTab === "embeddings" ? styles().conversationDetails.tabButtonActive : ""}`));
58
+ _el$0.$$click = () => props.onTabChange("summaries");
59
+ insert(_el$0, summariesCount, _el$11);
60
+ effect(() => className(_el$0, `${styles().actionButton} ${props.activeTab === "summaries" ? styles().conversationDetails.tabButtonActive : ""}`));
64
61
  return _el$0;
65
62
  }
66
63
  }), null);
67
- insert(_el$, createComponent(Show, {
68
- get when() {
69
- return hasSummaries();
70
- },
71
- get children() {
72
- var _el$12 = _tmpl$4(), _el$13 = _el$12.firstChild, _el$15 = _el$13.nextSibling;
73
- _el$15.nextSibling;
74
- _el$12.$$click = () => props.onTabChange("summaries");
75
- insert(_el$12, summariesCount, _el$15);
76
- effect(() => className(_el$12, `${styles().actionButton} ${props.activeTab === "summaries" ? styles().conversationDetails.tabButtonActive : ""}`));
77
- return _el$12;
78
- }
79
- }), null);
80
64
  effect(() => className(_el$, styles().conversationDetails.tabsContainer));
81
65
  return _el$;
82
66
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"ConversationTabs.js","sources":["../../../../src/components/conversation/ConversationTabs.tsx"],"sourcesContent":["import { Show } from 'solid-js'\nimport { useStyles } from '../../styles/use-styles'\nimport type { Component } from 'solid-js'\nimport type { Conversation } from '../../store/ai-context'\n\nexport type TabType = 'messages' | 'chunks' | 'embeddings' | 'summaries'\n\ninterface ConversationTabsProps {\n conversation: Conversation\n activeTab: TabType\n onTabChange: (tab: TabType) => void\n}\n\nexport const ConversationTabs: Component<ConversationTabsProps> = (props) => {\n const styles = useStyles()\n const conv = () => props.conversation\n\n // Total raw chunks = sum of all chunkCounts\n const totalRawChunks = () =>\n conv().chunks.reduce((sum, c) => sum + (c.chunkCount || 1), 0)\n\n const embeddingsCount = () => conv().embeddings?.length ?? 0\n const summariesCount = () => conv().summaries?.length ?? 0\n\n // Determine if we should show any chat-related tabs\n // For server conversations, don't show messages tab - only chunks\n const hasMessages = () =>\n conv().type === 'client' && conv().messages.length > 0\n const hasChunks = () => conv().chunks.length > 0 || conv().type === 'server'\n const hasEmbeddings = () => conv().hasEmbedding || embeddingsCount() > 0\n const hasSummaries = () => conv().hasSummarize || summariesCount() > 0\n\n // Count how many tabs would be visible\n const visibleTabCount = () => {\n let count = 0\n if (hasMessages()) count++\n if (hasChunks() && conv().type === 'server') count++\n if (hasEmbeddings()) count++\n if (hasSummaries()) count++\n return count\n }\n\n // Don't render tabs if only one tab would be visible\n if (visibleTabCount() <= 1) {\n return null\n }\n\n return (\n <div class={styles().conversationDetails.tabsContainer}>\n {/* Show messages tab for client conversations or when there are messages */}\n <Show when={hasMessages()}>\n <button\n class={`${styles().actionButton} ${\n props.activeTab === 'messages'\n ? styles().conversationDetails.tabButtonActive\n : ''\n }`}\n onClick={() => props.onTabChange('messages')}\n >\n 💬 Messages ({conv().messages.length})\n </button>\n </Show>\n {/* Show chunks tab for server conversations or when there are chunks */}\n <Show when={hasChunks() && conv().type === 'server'}>\n <button\n class={`${styles().actionButton} ${\n props.activeTab === 'chunks'\n ? styles().conversationDetails.tabButtonActive\n : ''\n }`}\n onClick={() => props.onTabChange('chunks')}\n >\n 📦 Chunks ({totalRawChunks()})\n </button>\n </Show>\n {/* Show embeddings tab if there are embedding operations */}\n <Show when={hasEmbeddings()}>\n <button\n class={`${styles().actionButton} ${\n props.activeTab === 'embeddings'\n ? styles().conversationDetails.tabButtonActive\n : ''\n }`}\n onClick={() => props.onTabChange('embeddings')}\n >\n 🔢 Embeddings ({embeddingsCount()})\n </button>\n </Show>\n {/* Show summaries tab if there are summarize operations */}\n <Show when={hasSummaries()}>\n <button\n class={`${styles().actionButton} ${\n props.activeTab === 'summaries'\n ? styles().conversationDetails.tabButtonActive\n : ''\n }`}\n onClick={() => props.onTabChange('summaries')}\n >\n 📝 Summaries ({summariesCount()})\n </button>\n </Show>\n </div>\n )\n}\n"],"names":["ConversationTabs","props","styles","useStyles","conv","conversation","totalRawChunks","chunks","reduce","sum","c","chunkCount","embeddingsCount","embeddings","length","summariesCount","summaries","hasMessages","type","messages","hasChunks","hasEmbeddings","hasEmbedding","hasSummaries","hasSummarize","visibleTabCount","count","_el$","_tmpl$5","_$insert","_$createComponent","Show","when","children","_el$2","_tmpl$","_el$3","firstChild","_el$5","nextSibling","$$click","onTabChange","_$effect","_$className","actionButton","activeTab","conversationDetails","tabButtonActive","_$memo","_el$6","_tmpl$2","_el$7","_el$9","_el$0","_tmpl$3","_el$1","_el$11","_el$12","_tmpl$4","_el$13","_el$15","tabsContainer","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"ConversationTabs.js","sources":["../../../../src/components/conversation/ConversationTabs.tsx"],"sourcesContent":["import { Show } from 'solid-js'\nimport { useStyles } from '../../styles/use-styles'\nimport type { Component } from 'solid-js'\nimport type { Conversation } from '../../store/ai-context'\n\nexport type TabType = 'messages' | 'chunks' | 'summaries'\n\ninterface ConversationTabsProps {\n conversation: Conversation\n activeTab: TabType\n onTabChange: (tab: TabType) => void\n}\n\nexport const ConversationTabs: Component<ConversationTabsProps> = (props) => {\n const styles = useStyles()\n const conv = () => props.conversation\n\n // Total raw chunks = sum of all chunkCounts\n const totalRawChunks = () =>\n conv().chunks.reduce((sum, c) => sum + (c.chunkCount || 1), 0)\n\n const summariesCount = () => conv().summaries?.length ?? 0\n\n // Determine if we should show any chat-related tabs\n // For server conversations, don't show messages tab - only chunks\n const hasMessages = () =>\n conv().type === 'client' && conv().messages.length > 0\n const hasChunks = () => conv().chunks.length > 0 || conv().type === 'server'\n const hasSummaries = () => conv().hasSummarize || summariesCount() > 0\n\n // Count how many tabs would be visible\n const visibleTabCount = () => {\n let count = 0\n if (hasMessages()) count++\n if (hasChunks() && conv().type === 'server') count++\n if (hasSummaries()) count++\n return count\n }\n\n // Don't render tabs if only one tab would be visible\n if (visibleTabCount() <= 1) {\n return null\n }\n\n return (\n <div class={styles().conversationDetails.tabsContainer}>\n {/* Show messages tab for client conversations or when there are messages */}\n <Show when={hasMessages()}>\n <button\n class={`${styles().actionButton} ${\n props.activeTab === 'messages'\n ? styles().conversationDetails.tabButtonActive\n : ''\n }`}\n onClick={() => props.onTabChange('messages')}\n >\n 💬 Messages ({conv().messages.length})\n </button>\n </Show>\n {/* Show chunks tab for server conversations or when there are chunks */}\n <Show when={hasChunks() && conv().type === 'server'}>\n <button\n class={`${styles().actionButton} ${\n props.activeTab === 'chunks'\n ? styles().conversationDetails.tabButtonActive\n : ''\n }`}\n onClick={() => props.onTabChange('chunks')}\n >\n 📦 Chunks ({totalRawChunks()})\n </button>\n </Show>\n {/* Show summaries tab if there are summarize operations */}\n <Show when={hasSummaries()}>\n <button\n class={`${styles().actionButton} ${\n props.activeTab === 'summaries'\n ? styles().conversationDetails.tabButtonActive\n : ''\n }`}\n onClick={() => props.onTabChange('summaries')}\n >\n 📝 Summaries ({summariesCount()})\n </button>\n </Show>\n </div>\n )\n}\n"],"names":["ConversationTabs","props","styles","useStyles","conv","conversation","totalRawChunks","chunks","reduce","sum","c","chunkCount","summariesCount","summaries","length","hasMessages","type","messages","hasChunks","hasSummaries","hasSummarize","visibleTabCount","count","_el$","_tmpl$4","_$insert","_$createComponent","Show","when","children","_el$2","_tmpl$","_el$3","firstChild","_el$5","nextSibling","$$click","onTabChange","_$effect","_$className","actionButton","activeTab","conversationDetails","tabButtonActive","_$memo","_el$6","_tmpl$2","_el$7","_el$9","_el$0","_tmpl$3","_el$1","_el$11","tabsContainer","_$delegateEvents"],"mappings":"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"}
@@ -3,5 +3,4 @@ export { ConversationTabs } from './ConversationTabs.js';
3
3
  export type { TabType } from './ConversationTabs.js';
4
4
  export { MessagesTab } from './MessagesTab.js';
5
5
  export { ChunksTab } from './ChunksTab.js';
6
- export { EmbeddingsTab } from './EmbeddingsTab.js';
7
6
  export { SummariesTab } from './SummariesTab.js';
@@ -70,14 +70,6 @@ export interface Chunk {
70
70
  /** Number of raw chunks that were merged into this consolidated chunk */
71
71
  chunkCount: number;
72
72
  }
73
- export interface EmbeddingOperation {
74
- id: string;
75
- model: string;
76
- inputCount: number;
77
- duration: number;
78
- timestamp: number;
79
- status: 'started' | 'completed';
80
- }
81
73
  export interface SummarizeOperation {
82
74
  id: string;
83
75
  model: string;
@@ -105,10 +97,7 @@ export interface Conversation {
105
97
  providerOptions?: Record<string, unknown>;
106
98
  /** Flags for which operation types this conversation has */
107
99
  hasChat?: boolean;
108
- hasEmbedding?: boolean;
109
100
  hasSummarize?: boolean;
110
- /** Embedding operations in this conversation */
111
- embeddings?: Array<EmbeddingOperation>;
112
101
  /** Summarize operations in this conversation */
113
102
  summaries?: Array<SummarizeOperation>;
114
103
  }
@@ -744,7 +744,7 @@ const AIProvider = (props) => {
744
744
  }
745
745
  }
746
746
  }));
747
- cleanupFns.push(aiEventClient.on("chat:started", (e) => {
747
+ cleanupFns.push(aiEventClient.on("text:started", (e) => {
748
748
  const streamId = e.payload.streamId;
749
749
  const model = e.payload.model;
750
750
  e.payload.provider;
@@ -781,7 +781,7 @@ const AIProvider = (props) => {
781
781
  }
782
782
  }
783
783
  }));
784
- cleanupFns.push(aiEventClient.on("chat:completed", (e) => {
784
+ cleanupFns.push(aiEventClient.on("text:completed", (e) => {
785
785
  const {
786
786
  requestId,
787
787
  usage
@@ -801,7 +801,7 @@ const AIProvider = (props) => {
801
801
  }
802
802
  }
803
803
  }));
804
- cleanupFns.push(aiEventClient.on("chat:iteration", (e) => {
804
+ cleanupFns.push(aiEventClient.on("text:iteration", (e) => {
805
805
  const {
806
806
  requestId,
807
807
  iterationNumber
@@ -879,60 +879,6 @@ const AIProvider = (props) => {
879
879
  }
880
880
  }
881
881
  }));
882
- cleanupFns.push(aiEventClient.on("embedding:started", (e) => {
883
- const {
884
- requestId,
885
- model,
886
- inputCount,
887
- timestamp,
888
- clientId
889
- } = e.payload;
890
- let conversationId = clientId;
891
- if (!conversationId || !state.conversations[conversationId]) {
892
- const activeClients = Object.values(state.conversations).filter((c) => c.type === "client" && c.status === "active").sort((a, b) => b.startedAt - a.startedAt);
893
- if (activeClients.length > 0 && activeClients[0]) {
894
- conversationId = activeClients[0].id;
895
- } else {
896
- conversationId = `embedding-${requestId}`;
897
- getOrCreateConversation(conversationId, "server", `Embedding (${model})`);
898
- updateConversation(conversationId, {
899
- model
900
- });
901
- }
902
- }
903
- requestToConversation.set(requestId, conversationId);
904
- const embeddingOp = {
905
- id: requestId,
906
- model,
907
- inputCount,
908
- duration: 0,
909
- timestamp,
910
- status: "started"
911
- };
912
- const conv = state.conversations[conversationId];
913
- if (conv) {
914
- const embeddings = conv.embeddings || [];
915
- setState("conversations", conversationId, "embeddings", [...embeddings, embeddingOp]);
916
- setState("conversations", conversationId, "hasEmbedding", true);
917
- }
918
- }));
919
- cleanupFns.push(aiEventClient.on("embedding:completed", (e) => {
920
- const {
921
- requestId,
922
- duration
923
- } = e.payload;
924
- const conversationId = requestToConversation.get(requestId);
925
- if (!conversationId || !state.conversations[conversationId]) return;
926
- const conv = state.conversations[conversationId];
927
- if (!conv.embeddings) return;
928
- const embeddingIndex = conv.embeddings.findIndex((op) => op.id === requestId);
929
- if (embeddingIndex >= 0) {
930
- setState("conversations", conversationId, "embeddings", embeddingIndex, produce((op) => {
931
- op.duration = duration;
932
- op.status = "completed";
933
- }));
934
- }
935
- }));
936
882
  cleanupFns.push(aiEventClient.on("summarize:started", (e) => {
937
883
  const {
938
884
  requestId,