@lssm/module.ai-chat 0.0.0-canary-20251217062139 → 0.0.0-canary-20251217072406

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 (48) hide show
  1. package/dist/ai-chat.feature.js +93 -1
  2. package/dist/context/context-builder.js +147 -2
  3. package/dist/context/file-operations.js +174 -1
  4. package/dist/context/index.js +5 -1
  5. package/dist/context/workspace-context.js +123 -2
  6. package/dist/core/chat-service.js +211 -2
  7. package/dist/core/conversation-store.js +108 -1
  8. package/dist/core/index.js +4 -1
  9. package/dist/index.js +22 -1
  10. package/dist/libs/ai-providers/dist/factory.js +225 -1
  11. package/dist/libs/ai-providers/dist/index.js +4 -1
  12. package/dist/libs/ai-providers/dist/legacy.js +2 -1
  13. package/dist/libs/ai-providers/dist/models.js +299 -1
  14. package/dist/libs/ai-providers/dist/validation.js +60 -1
  15. package/dist/libs/design-system/dist/_virtual/rolldown_runtime.js +5 -1
  16. package/dist/libs/design-system/dist/components/atoms/Button.js +33 -1
  17. package/dist/libs/design-system/dist/components/atoms/Textarea.js +35 -1
  18. package/dist/libs/design-system/dist/lib/keyboard.js +193 -1
  19. package/dist/libs/design-system/dist/ui-kit-web/dist/ui/button.js +55 -1
  20. package/dist/libs/design-system/dist/ui-kit-web/dist/ui/textarea.js +16 -1
  21. package/dist/libs/design-system/dist/ui-kit-web/dist/ui-kit-core/dist/utils.js +13 -1
  22. package/dist/libs/ui-kit-web/dist/ui/avatar.js +25 -1
  23. package/dist/libs/ui-kit-web/dist/ui/badge.js +26 -1
  24. package/dist/libs/ui-kit-web/dist/ui/scroll-area.js +39 -1
  25. package/dist/libs/ui-kit-web/dist/ui/select.js +79 -1
  26. package/dist/libs/ui-kit-web/dist/ui/skeleton.js +14 -1
  27. package/dist/libs/ui-kit-web/dist/ui/tooltip.js +39 -1
  28. package/dist/libs/ui-kit-web/dist/ui/utils.js +10 -1
  29. package/dist/libs/ui-kit-web/dist/ui-kit-core/dist/utils.js +10 -1
  30. package/dist/presentation/components/ChatContainer.js +62 -1
  31. package/dist/presentation/components/ChatInput.d.ts +2 -2
  32. package/dist/presentation/components/ChatInput.js +149 -1
  33. package/dist/presentation/components/ChatMessage.d.ts +2 -2
  34. package/dist/presentation/components/ChatMessage.js +135 -1
  35. package/dist/presentation/components/CodePreview.d.ts +2 -2
  36. package/dist/presentation/components/CodePreview.js +126 -2
  37. package/dist/presentation/components/ContextIndicator.d.ts +2 -2
  38. package/dist/presentation/components/ContextIndicator.js +96 -1
  39. package/dist/presentation/components/ModelPicker.d.ts +2 -2
  40. package/dist/presentation/components/ModelPicker.js +197 -1
  41. package/dist/presentation/components/index.js +8 -1
  42. package/dist/presentation/hooks/index.js +4 -1
  43. package/dist/presentation/hooks/useChat.js +171 -1
  44. package/dist/presentation/hooks/useProviders.js +42 -1
  45. package/dist/presentation/index.js +12 -1
  46. package/dist/providers/chat-utilities.js +16 -1
  47. package/dist/providers/index.js +7 -1
  48. package/package.json +10 -10
@@ -1 +1,171 @@
1
- "use client";import{ChatService as e}from"../../core/chat-service.js";import{c as t}from"../../libs/ai-providers/dist/factory.js";import"../../libs/ai-providers/dist/index.js";import*as n from"react";function r(r={}){let{provider:i=`openai`,mode:a=`byok`,model:o,apiKey:s,proxyUrl:c,conversationId:l,systemPrompt:u,streaming:d=!0,onSend:f,onResponse:p,onError:m,onUsage:h}=r,[g,_]=n.useState([]),[v,y]=n.useState(null),[b,x]=n.useState(!1),[S,C]=n.useState(null),[w,T]=n.useState(l??null),E=n.useRef(null),D=n.useRef(null);n.useEffect(()=>{D.current=new e({provider:t({provider:i,model:o,apiKey:s,proxyUrl:c}),systemPrompt:u,onUsage:h})},[i,a,o,s,c,u,h]),n.useEffect(()=>{!w||!D.current||(async()=>{let e=await D.current.getConversation(w);e&&(y(e),_(e.messages))})().catch(console.error)},[w]);let O=n.useCallback(async(e,t)=>{if(!D.current)throw Error(`Chat service not initialized`);x(!0),C(null),E.current=new AbortController;try{let n={id:`msg_${Date.now()}`,conversationId:w??``,role:`user`,content:e,status:`completed`,createdAt:new Date,updatedAt:new Date,attachments:t};if(_(e=>[...e,n]),f?.(n),d){let n=await D.current.stream({conversationId:w??void 0,content:e,attachments:t});w||T(n.conversationId);let r={id:n.messageId,conversationId:n.conversationId,role:`assistant`,content:``,status:`streaming`,createdAt:new Date,updatedAt:new Date};_(e=>[...e,r]);let i=``;for await(let e of n.stream)if(e.type===`text`&&e.content)i+=e.content,_(e=>e.map(e=>e.id===n.messageId?{...e,content:i}:e));else if(e.type===`done`)_(t=>t.map(t=>t.id===n.messageId?{...t,status:`completed`,usage:e.usage,updatedAt:new Date}:t)),p?.(g.find(e=>e.id===n.messageId)??r);else if(e.type===`error`&&(_(t=>t.map(t=>t.id===n.messageId?{...t,status:`error`,error:e.error,updatedAt:new Date}:t)),e.error)){let t=Error(e.error.message);C(t),m?.(t)}}else{let n=await D.current.send({conversationId:w??void 0,content:e,attachments:t});y(n.conversation),_(n.conversation.messages),w||T(n.conversation.id),p?.(n.message)}}catch(e){let t=e instanceof Error?e:Error(String(e));C(t),m?.(t)}finally{x(!1),E.current=null}},[w,d,f,p,m,g]);return{messages:g,conversation:v,isLoading:b,error:S,sendMessage:O,clearConversation:n.useCallback(()=>{_([]),y(null),T(null),C(null)},[]),setConversationId:T,regenerate:n.useCallback(async()=>{let e=g.findLastIndex(e=>e.role===`user`);if(e===-1)return;let t=g[e];t&&(_(t=>t.slice(0,e+1)),await O(t.content,t.attachments))},[g,O]),stop:n.useCallback(()=>{E.current?.abort(),x(!1)},[])}}export{r as useChat};
1
+ 'use client';
2
+
3
+ import { ChatService } from "../../core/chat-service.js";
4
+ import { createProvider } from "../../libs/ai-providers/dist/factory.js";
5
+ import "../../libs/ai-providers/dist/index.js";
6
+ import * as React from "react";
7
+
8
+ //#region src/presentation/hooks/useChat.tsx
9
+ /**
10
+ * Hook for managing AI chat state
11
+ */
12
+ function useChat(options = {}) {
13
+ const { provider = "openai", mode = "byok", model, apiKey, proxyUrl, conversationId: initialConversationId, systemPrompt, streaming = true, onSend, onResponse, onError, onUsage } = options;
14
+ const [messages, setMessages] = React.useState([]);
15
+ const [conversation, setConversation] = React.useState(null);
16
+ const [isLoading, setIsLoading] = React.useState(false);
17
+ const [error, setError] = React.useState(null);
18
+ const [conversationId, setConversationId] = React.useState(initialConversationId ?? null);
19
+ const abortControllerRef = React.useRef(null);
20
+ const chatServiceRef = React.useRef(null);
21
+ React.useEffect(() => {
22
+ chatServiceRef.current = new ChatService({
23
+ provider: createProvider({
24
+ provider,
25
+ model,
26
+ apiKey,
27
+ proxyUrl
28
+ }),
29
+ systemPrompt,
30
+ onUsage
31
+ });
32
+ }, [
33
+ provider,
34
+ mode,
35
+ model,
36
+ apiKey,
37
+ proxyUrl,
38
+ systemPrompt,
39
+ onUsage
40
+ ]);
41
+ React.useEffect(() => {
42
+ if (!conversationId || !chatServiceRef.current) return;
43
+ const loadConversation = async () => {
44
+ const conv = await chatServiceRef.current.getConversation(conversationId);
45
+ if (conv) {
46
+ setConversation(conv);
47
+ setMessages(conv.messages);
48
+ }
49
+ };
50
+ loadConversation().catch(console.error);
51
+ }, [conversationId]);
52
+ const sendMessage = React.useCallback(async (content, attachments) => {
53
+ if (!chatServiceRef.current) throw new Error("Chat service not initialized");
54
+ setIsLoading(true);
55
+ setError(null);
56
+ abortControllerRef.current = new AbortController();
57
+ try {
58
+ const userMessage = {
59
+ id: `msg_${Date.now()}`,
60
+ conversationId: conversationId ?? "",
61
+ role: "user",
62
+ content,
63
+ status: "completed",
64
+ createdAt: /* @__PURE__ */ new Date(),
65
+ updatedAt: /* @__PURE__ */ new Date(),
66
+ attachments
67
+ };
68
+ setMessages((prev) => [...prev, userMessage]);
69
+ onSend?.(userMessage);
70
+ if (streaming) {
71
+ const result = await chatServiceRef.current.stream({
72
+ conversationId: conversationId ?? void 0,
73
+ content,
74
+ attachments
75
+ });
76
+ if (!conversationId) setConversationId(result.conversationId);
77
+ const assistantMessage = {
78
+ id: result.messageId,
79
+ conversationId: result.conversationId,
80
+ role: "assistant",
81
+ content: "",
82
+ status: "streaming",
83
+ createdAt: /* @__PURE__ */ new Date(),
84
+ updatedAt: /* @__PURE__ */ new Date()
85
+ };
86
+ setMessages((prev) => [...prev, assistantMessage]);
87
+ let fullContent = "";
88
+ for await (const chunk of result.stream) if (chunk.type === "text" && chunk.content) {
89
+ fullContent += chunk.content;
90
+ setMessages((prev) => prev.map((m) => m.id === result.messageId ? {
91
+ ...m,
92
+ content: fullContent
93
+ } : m));
94
+ } else if (chunk.type === "done") {
95
+ setMessages((prev) => prev.map((m) => m.id === result.messageId ? {
96
+ ...m,
97
+ status: "completed",
98
+ usage: chunk.usage,
99
+ updatedAt: /* @__PURE__ */ new Date()
100
+ } : m));
101
+ onResponse?.(messages.find((m) => m.id === result.messageId) ?? assistantMessage);
102
+ } else if (chunk.type === "error") {
103
+ setMessages((prev) => prev.map((m) => m.id === result.messageId ? {
104
+ ...m,
105
+ status: "error",
106
+ error: chunk.error,
107
+ updatedAt: /* @__PURE__ */ new Date()
108
+ } : m));
109
+ if (chunk.error) {
110
+ const err = new Error(chunk.error.message);
111
+ setError(err);
112
+ onError?.(err);
113
+ }
114
+ }
115
+ } else {
116
+ const result = await chatServiceRef.current.send({
117
+ conversationId: conversationId ?? void 0,
118
+ content,
119
+ attachments
120
+ });
121
+ setConversation(result.conversation);
122
+ setMessages(result.conversation.messages);
123
+ if (!conversationId) setConversationId(result.conversation.id);
124
+ onResponse?.(result.message);
125
+ }
126
+ } catch (err) {
127
+ const error$1 = err instanceof Error ? err : new Error(String(err));
128
+ setError(error$1);
129
+ onError?.(error$1);
130
+ } finally {
131
+ setIsLoading(false);
132
+ abortControllerRef.current = null;
133
+ }
134
+ }, [
135
+ conversationId,
136
+ streaming,
137
+ onSend,
138
+ onResponse,
139
+ onError,
140
+ messages
141
+ ]);
142
+ return {
143
+ messages,
144
+ conversation,
145
+ isLoading,
146
+ error,
147
+ sendMessage,
148
+ clearConversation: React.useCallback(() => {
149
+ setMessages([]);
150
+ setConversation(null);
151
+ setConversationId(null);
152
+ setError(null);
153
+ }, []),
154
+ setConversationId,
155
+ regenerate: React.useCallback(async () => {
156
+ const lastUserMessageIndex = messages.findLastIndex((m) => m.role === "user");
157
+ if (lastUserMessageIndex === -1) return;
158
+ const lastUserMessage = messages[lastUserMessageIndex];
159
+ if (!lastUserMessage) return;
160
+ setMessages((prev) => prev.slice(0, lastUserMessageIndex + 1));
161
+ await sendMessage(lastUserMessage.content, lastUserMessage.attachments);
162
+ }, [messages, sendMessage]),
163
+ stop: React.useCallback(() => {
164
+ abortControllerRef.current?.abort();
165
+ setIsLoading(false);
166
+ }, [])
167
+ };
168
+ }
169
+
170
+ //#endregion
171
+ export { useChat };
@@ -1 +1,42 @@
1
- "use client";import{n as e}from"../../libs/ai-providers/dist/models.js";import{u as t}from"../../libs/ai-providers/dist/factory.js";import"../../libs/ai-providers/dist/index.js";import*as n from"react";function r(){let[r,i]=n.useState([]),[a,o]=n.useState(!0),s=n.useCallback(async()=>{o(!0);try{i(t().map(t=>({...t,models:e(t.provider)})))}catch(e){console.error(`Failed to load providers:`,e)}finally{o(!1)}},[]);return n.useEffect(()=>{s()},[s]),{providers:r,availableProviders:n.useMemo(()=>r.filter(e=>e.available),[r]),isAvailable:n.useCallback(e=>r.some(t=>t.provider===e&&t.available),[r]),getModels:n.useCallback(e=>r.find(t=>t.provider===e)?.models??[],[r]),isLoading:a,refresh:s}}export{r as useProviders};
1
+ 'use client';
2
+
3
+ import { getModelsForProvider } from "../../libs/ai-providers/dist/models.js";
4
+ import { getAvailableProviders } from "../../libs/ai-providers/dist/factory.js";
5
+ import "../../libs/ai-providers/dist/index.js";
6
+ import * as React from "react";
7
+
8
+ //#region src/presentation/hooks/useProviders.tsx
9
+ /**
10
+ * Hook for managing AI provider information
11
+ */
12
+ function useProviders() {
13
+ const [providers, setProviders] = React.useState([]);
14
+ const [isLoading, setIsLoading] = React.useState(true);
15
+ const loadProviders = React.useCallback(async () => {
16
+ setIsLoading(true);
17
+ try {
18
+ setProviders(getAvailableProviders().map((p) => ({
19
+ ...p,
20
+ models: getModelsForProvider(p.provider)
21
+ })));
22
+ } catch (error) {
23
+ console.error("Failed to load providers:", error);
24
+ } finally {
25
+ setIsLoading(false);
26
+ }
27
+ }, []);
28
+ React.useEffect(() => {
29
+ loadProviders();
30
+ }, [loadProviders]);
31
+ return {
32
+ providers,
33
+ availableProviders: React.useMemo(() => providers.filter((p) => p.available), [providers]),
34
+ isAvailable: React.useCallback((provider) => providers.some((p) => p.provider === provider && p.available), [providers]),
35
+ getModels: React.useCallback((provider) => providers.find((p) => p.provider === provider)?.models ?? [], [providers]),
36
+ isLoading,
37
+ refresh: loadProviders
38
+ };
39
+ }
40
+
41
+ //#endregion
42
+ export { useProviders };
@@ -1 +1,12 @@
1
- import{ChatContainer as e}from"./components/ChatContainer.js";import{CodePreview as t}from"./components/CodePreview.js";import{ChatMessage as n}from"./components/ChatMessage.js";import{ChatInput as r}from"./components/ChatInput.js";import{ModelPicker as i}from"./components/ModelPicker.js";import{ContextIndicator as a}from"./components/ContextIndicator.js";import"./components/index.js";import{useChat as o}from"./hooks/useChat.js";import{useProviders as s}from"./hooks/useProviders.js";import"./hooks/index.js";export{e as ChatContainer,r as ChatInput,n as ChatMessage,t as CodePreview,a as ContextIndicator,i as ModelPicker,o as useChat,s as useProviders};
1
+ import { ChatContainer } from "./components/ChatContainer.js";
2
+ import { CodePreview } from "./components/CodePreview.js";
3
+ import { ChatMessage } from "./components/ChatMessage.js";
4
+ import { ChatInput } from "./components/ChatInput.js";
5
+ import { ModelPicker } from "./components/ModelPicker.js";
6
+ import { ContextIndicator } from "./components/ContextIndicator.js";
7
+ import "./components/index.js";
8
+ import { useChat } from "./hooks/useChat.js";
9
+ import { useProviders } from "./hooks/useProviders.js";
10
+ import "./hooks/index.js";
11
+
12
+ export { ChatContainer, ChatInput, ChatMessage, CodePreview, ContextIndicator, ModelPicker, useChat, useProviders };
@@ -1 +1,16 @@
1
- function e(e){return e===`ollama`}function t(e){return e!==`ollama`}export{t as isStudioAvailable,e as supportsLocalMode};
1
+ //#region src/providers/chat-utilities.ts
2
+ /**
3
+ * Check if a provider supports local mode
4
+ */
5
+ function supportsLocalMode(provider) {
6
+ return provider === "ollama";
7
+ }
8
+ /**
9
+ * Check if a provider is available in Studio (cloud only)
10
+ */
11
+ function isStudioAvailable(provider) {
12
+ return provider !== "ollama";
13
+ }
14
+
15
+ //#endregion
16
+ export { isStudioAvailable, supportsLocalMode };
@@ -1 +1,7 @@
1
- import{a as e,e as t,i as n,n as r,r as i,t as a}from"../libs/ai-providers/dist/models.js";import{c as o,l as s,u as c}from"../libs/ai-providers/dist/factory.js";import{a as l,i as u,n as d,r as f,t as p}from"../libs/ai-providers/dist/validation.js";import"../libs/ai-providers/dist/index.js";import{isStudioAvailable as m,supportsLocalMode as h}from"./chat-utilities.js";export{t as DEFAULT_MODELS,a as MODELS,o as createProvider,s as createProviderFromEnv,c as getAvailableProviders,e as getDefaultModel,f as getEnvVarName,i as getModelInfo,r as getModelsForProvider,n as getRecommendedModels,d as hasCredentials,u as isOllamaRunning,m as isStudioAvailable,l as listOllamaModels,h as supportsLocalMode,p as validateProvider};
1
+ import { DEFAULT_MODELS, MODELS, getDefaultModel, getModelInfo, getModelsForProvider, getRecommendedModels } from "../libs/ai-providers/dist/models.js";
2
+ import { createProvider, createProviderFromEnv, getAvailableProviders } from "../libs/ai-providers/dist/factory.js";
3
+ import { getEnvVarName, hasCredentials, isOllamaRunning, listOllamaModels, validateProvider } from "../libs/ai-providers/dist/validation.js";
4
+ import "../libs/ai-providers/dist/index.js";
5
+ import { isStudioAvailable, supportsLocalMode } from "./chat-utilities.js";
6
+
7
+ export { DEFAULT_MODELS, MODELS, createProvider, createProviderFromEnv, getAvailableProviders, getDefaultModel, getEnvVarName, getModelInfo, getModelsForProvider, getRecommendedModels, hasCredentials, isOllamaRunning, isStudioAvailable, listOllamaModels, supportsLocalMode, validateProvider };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lssm/module.ai-chat",
3
- "version": "0.0.0-canary-20251217062139",
3
+ "version": "0.0.0-canary-20251217072406",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -23,13 +23,13 @@
23
23
  "test": "bun test"
24
24
  },
25
25
  "dependencies": {
26
- "@lssm/lib.ai-agent": "0.0.0-canary-20251217062139",
27
- "@lssm/lib.ai-providers": "0.0.0-canary-20251217062139",
28
- "@lssm/lib.contracts": "0.0.0-canary-20251217062139",
29
- "@lssm/lib.metering": "0.0.0-canary-20251217062139",
30
- "@lssm/lib.cost-tracking": "0.0.0-canary-20251217062139",
31
- "@lssm/lib.design-system": "0.0.0-canary-20251217062139",
32
- "@lssm/lib.ui-kit-web": "0.0.0-canary-20251217062139",
26
+ "@lssm/lib.ai-agent": "0.0.0-canary-20251217072406",
27
+ "@lssm/lib.ai-providers": "0.0.0-canary-20251217072406",
28
+ "@lssm/lib.contracts": "0.0.0-canary-20251217072406",
29
+ "@lssm/lib.metering": "0.0.0-canary-20251217072406",
30
+ "@lssm/lib.cost-tracking": "0.0.0-canary-20251217072406",
31
+ "@lssm/lib.design-system": "0.0.0-canary-20251217072406",
32
+ "@lssm/lib.ui-kit-web": "0.0.0-canary-20251217072406",
33
33
  "@ai-sdk/react": "beta",
34
34
  "ai": "beta",
35
35
  "lucide-react": "^0.535.0",
@@ -37,8 +37,8 @@
37
37
  "zod": "^4.1.13"
38
38
  },
39
39
  "devDependencies": {
40
- "@lssm/tool.tsdown": "0.0.0-canary-20251217062139",
41
- "@lssm/tool.typescript": "0.0.0-canary-20251217062139",
40
+ "@lssm/tool.tsdown": "0.0.0-canary-20251217072406",
41
+ "@lssm/tool.typescript": "0.0.0-canary-20251217072406",
42
42
  "@types/react": "^19.0.14",
43
43
  "tsdown": "^0.17.4",
44
44
  "typescript": "^5.9.3"