fullstacked 0.12.0-1273 → 0.12.0-1290

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 (161) hide show
  1. package/fullstacked_modules/@fullstacked/ai-agent/index.ts +20 -2
  2. package/fullstacked_modules/@fullstacked/ai-agent/lock.json +469 -38
  3. package/fullstacked_modules/@fullstacked/ai-agent/package.json +11 -1
  4. package/fullstacked_modules/@fullstacked/ai-agent/src/conversation.ts +72 -14
  5. package/fullstacked_modules/@fullstacked/ai-agent/src/index.ts +1 -2
  6. package/fullstacked_modules/@fullstacked/ai-agent/src/markdown.ts +8 -4
  7. package/fullstacked_modules/@fullstacked/ai-agent/src/providers/anthropic.ts +46 -0
  8. package/fullstacked_modules/@fullstacked/ai-agent/src/providers/deepseek.ts +46 -0
  9. package/fullstacked_modules/@fullstacked/ai-agent/src/providers/google.ts +40 -0
  10. package/fullstacked_modules/@fullstacked/ai-agent/src/providers/index.ts +41 -0
  11. package/fullstacked_modules/@fullstacked/ai-agent/src/providers/interface.ts +19 -0
  12. package/fullstacked_modules/@fullstacked/ai-agent/src/providers/mistral.ts +47 -0
  13. package/fullstacked_modules/@fullstacked/ai-agent/src/providers/ollama.ts +26 -9
  14. package/fullstacked_modules/@fullstacked/ai-agent/src/providers/openai.ts +21 -9
  15. package/fullstacked_modules/@fullstacked/ai-agent/src/providers/xai.ts +43 -0
  16. package/fullstacked_modules/@fullstacked/ai-agent/summary.txt +7 -0
  17. package/fullstacked_modules/ai/index.js +155662 -87448
  18. package/fullstacked_modules/fetch/index.ts +1 -4
  19. package/fullstacked_modules/zod/README.md +3 -3
  20. package/fullstacked_modules/zod/index.d.cts +2 -2
  21. package/fullstacked_modules/zod/index.d.ts +2 -2
  22. package/fullstacked_modules/zod/package.json +10 -26
  23. package/fullstacked_modules/zod/src/index.ts +2 -2
  24. package/fullstacked_modules/zod/src/v3/tests/string.test.ts +2 -2
  25. package/fullstacked_modules/zod/src/v3/types.ts +1 -3
  26. package/fullstacked_modules/zod/src/v4/classic/checks.ts +0 -1
  27. package/fullstacked_modules/zod/src/v4/classic/compat.ts +0 -4
  28. package/fullstacked_modules/zod/src/v4/classic/errors.ts +2 -9
  29. package/fullstacked_modules/zod/src/v4/classic/schemas.ts +47 -24
  30. package/fullstacked_modules/zod/src/v4/classic/tests/catch.test.ts +5 -4
  31. package/fullstacked_modules/zod/src/v4/classic/tests/datetime.test.ts +0 -6
  32. package/fullstacked_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +0 -42
  33. package/fullstacked_modules/zod/src/v4/classic/tests/error-utils.test.ts +2 -70
  34. package/fullstacked_modules/zod/src/v4/classic/tests/file.test.ts +2 -5
  35. package/fullstacked_modules/zod/src/v4/classic/tests/literal.test.ts +0 -25
  36. package/fullstacked_modules/zod/src/v4/classic/tests/number.test.ts +0 -23
  37. package/fullstacked_modules/zod/src/v4/classic/tests/optional.test.ts +0 -13
  38. package/fullstacked_modules/zod/src/v4/classic/tests/partial.test.ts +0 -193
  39. package/fullstacked_modules/zod/src/v4/classic/tests/pickomit.test.ts +5 -5
  40. package/fullstacked_modules/zod/src/v4/classic/tests/preprocess.test.ts +15 -4
  41. package/fullstacked_modules/zod/src/v4/classic/tests/record.test.ts +1 -15
  42. package/fullstacked_modules/zod/src/v4/classic/tests/recursive-types.test.ts +0 -121
  43. package/fullstacked_modules/zod/src/v4/classic/tests/string.test.ts +4 -119
  44. package/fullstacked_modules/zod/src/v4/classic/tests/template-literal.test.ts +0 -3
  45. package/fullstacked_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +0 -27
  46. package/fullstacked_modules/zod/src/v4/classic/tests/transform.test.ts +0 -104
  47. package/fullstacked_modules/zod/src/v4/classic/tests/tuple.test.ts +2 -2
  48. package/fullstacked_modules/zod/src/v4/classic/tests/union.test.ts +3 -90
  49. package/fullstacked_modules/zod/src/v4/core/api.ts +96 -130
  50. package/fullstacked_modules/zod/src/v4/core/checks.ts +2 -4
  51. package/fullstacked_modules/zod/src/v4/core/doc.ts +2 -2
  52. package/fullstacked_modules/zod/src/v4/core/errors.ts +44 -43
  53. package/fullstacked_modules/zod/src/v4/core/json-schema.ts +3 -6
  54. package/fullstacked_modules/zod/src/v4/core/regexes.ts +6 -9
  55. package/fullstacked_modules/zod/src/v4/core/registries.ts +2 -3
  56. package/fullstacked_modules/zod/src/v4/core/schemas.ts +107 -165
  57. package/fullstacked_modules/zod/src/v4/core/to-json-schema.ts +11 -38
  58. package/fullstacked_modules/zod/src/v4/core/util.ts +105 -157
  59. package/fullstacked_modules/zod/src/v4/core/versions.ts +1 -1
  60. package/fullstacked_modules/zod/src/v4/locales/index.ts +0 -3
  61. package/fullstacked_modules/zod/src/v4/mini/schemas.ts +1 -14
  62. package/fullstacked_modules/zod/src/v4/mini/tests/assignability.test.ts +1 -1
  63. package/fullstacked_modules/zod/src/v4/mini/tests/computed.test.ts +1 -1
  64. package/fullstacked_modules/zod/src/v4/mini/tests/error.test.ts +1 -1
  65. package/fullstacked_modules/zod/src/v4/mini/tests/index.test.ts +1 -1
  66. package/fullstacked_modules/zod/src/v4/mini/tests/number.test.ts +1 -1
  67. package/fullstacked_modules/zod/src/v4/mini/tests/object.test.ts +1 -1
  68. package/fullstacked_modules/zod/src/v4/mini/tests/prototypes.test.ts +1 -1
  69. package/fullstacked_modules/zod/src/v4/mini/tests/recursive-types.test.ts +1 -1
  70. package/fullstacked_modules/zod/src/v4/mini/tests/string.test.ts +1 -1
  71. package/fullstacked_modules/zod/v3/ZodError.d.cts +6 -6
  72. package/fullstacked_modules/zod/v3/ZodError.d.ts +6 -6
  73. package/fullstacked_modules/zod/v3/locales/en.d.cts +1 -1
  74. package/fullstacked_modules/zod/v3/types.d.cts +1 -4
  75. package/fullstacked_modules/zod/v3/types.d.ts +1 -4
  76. package/fullstacked_modules/zod/v4/classic/checks.d.cts +1 -1
  77. package/fullstacked_modules/zod/v4/classic/checks.d.ts +1 -1
  78. package/fullstacked_modules/zod/v4/classic/compat.d.cts +0 -4
  79. package/fullstacked_modules/zod/v4/classic/compat.d.ts +0 -4
  80. package/fullstacked_modules/zod/v4/classic/schemas.d.cts +20 -9
  81. package/fullstacked_modules/zod/v4/classic/schemas.d.ts +20 -9
  82. package/fullstacked_modules/zod/v4/core/api.d.cts +72 -84
  83. package/fullstacked_modules/zod/v4/core/api.d.ts +72 -84
  84. package/fullstacked_modules/zod/v4/core/checks.d.cts +2 -2
  85. package/fullstacked_modules/zod/v4/core/checks.d.ts +2 -2
  86. package/fullstacked_modules/zod/v4/core/doc.d.cts +1 -1
  87. package/fullstacked_modules/zod/v4/core/doc.d.ts +1 -1
  88. package/fullstacked_modules/zod/v4/core/errors.d.cts +22 -24
  89. package/fullstacked_modules/zod/v4/core/errors.d.ts +22 -24
  90. package/fullstacked_modules/zod/v4/core/json-schema.d.cts +3 -3
  91. package/fullstacked_modules/zod/v4/core/json-schema.d.ts +3 -3
  92. package/fullstacked_modules/zod/v4/core/regexes.d.cts +2 -2
  93. package/fullstacked_modules/zod/v4/core/regexes.d.ts +2 -2
  94. package/fullstacked_modules/zod/v4/core/registries.d.cts +1 -1
  95. package/fullstacked_modules/zod/v4/core/registries.d.ts +1 -1
  96. package/fullstacked_modules/zod/v4/core/schemas.d.cts +6 -20
  97. package/fullstacked_modules/zod/v4/core/schemas.d.ts +6 -20
  98. package/fullstacked_modules/zod/v4/core/to-json-schema.d.cts +3 -4
  99. package/fullstacked_modules/zod/v4/core/to-json-schema.d.ts +3 -4
  100. package/fullstacked_modules/zod/v4/core/util.d.cts +0 -2
  101. package/fullstacked_modules/zod/v4/core/util.d.ts +0 -2
  102. package/fullstacked_modules/zod/v4/locales/ar.d.cts +1 -2
  103. package/fullstacked_modules/zod/v4/locales/az.d.cts +1 -2
  104. package/fullstacked_modules/zod/v4/locales/be.d.cts +1 -2
  105. package/fullstacked_modules/zod/v4/locales/ca.d.cts +1 -2
  106. package/fullstacked_modules/zod/v4/locales/cs.d.cts +1 -2
  107. package/fullstacked_modules/zod/v4/locales/de.d.cts +1 -2
  108. package/fullstacked_modules/zod/v4/locales/es.d.cts +1 -2
  109. package/fullstacked_modules/zod/v4/locales/fa.d.cts +1 -2
  110. package/fullstacked_modules/zod/v4/locales/fi.d.cts +1 -2
  111. package/fullstacked_modules/zod/v4/locales/fr-CA.d.cts +1 -2
  112. package/fullstacked_modules/zod/v4/locales/fr.d.cts +1 -2
  113. package/fullstacked_modules/zod/v4/locales/he.d.cts +1 -2
  114. package/fullstacked_modules/zod/v4/locales/hu.d.cts +1 -2
  115. package/fullstacked_modules/zod/v4/locales/id.d.cts +1 -2
  116. package/fullstacked_modules/zod/v4/locales/index.d.cts +0 -3
  117. package/fullstacked_modules/zod/v4/locales/index.d.ts +0 -3
  118. package/fullstacked_modules/zod/v4/locales/it.d.cts +1 -2
  119. package/fullstacked_modules/zod/v4/locales/ja.d.cts +1 -2
  120. package/fullstacked_modules/zod/v4/locales/kh.d.cts +1 -2
  121. package/fullstacked_modules/zod/v4/locales/ko.d.cts +1 -2
  122. package/fullstacked_modules/zod/v4/locales/mk.d.cts +1 -2
  123. package/fullstacked_modules/zod/v4/locales/ms.d.cts +1 -2
  124. package/fullstacked_modules/zod/v4/locales/nl.d.cts +1 -2
  125. package/fullstacked_modules/zod/v4/locales/no.d.cts +1 -2
  126. package/fullstacked_modules/zod/v4/locales/ota.d.cts +1 -2
  127. package/fullstacked_modules/zod/v4/locales/pl.d.cts +1 -2
  128. package/fullstacked_modules/zod/v4/locales/ps.d.cts +1 -2
  129. package/fullstacked_modules/zod/v4/locales/pt.d.cts +1 -2
  130. package/fullstacked_modules/zod/v4/locales/ru.d.cts +1 -2
  131. package/fullstacked_modules/zod/v4/locales/sl.d.cts +1 -2
  132. package/fullstacked_modules/zod/v4/locales/sv.d.cts +1 -2
  133. package/fullstacked_modules/zod/v4/locales/ta.d.cts +1 -2
  134. package/fullstacked_modules/zod/v4/locales/th.d.cts +1 -2
  135. package/fullstacked_modules/zod/v4/locales/ua.d.cts +1 -2
  136. package/fullstacked_modules/zod/v4/locales/ur.d.cts +1 -2
  137. package/fullstacked_modules/zod/v4/locales/vi.d.cts +1 -2
  138. package/fullstacked_modules/zod/v4/locales/zh-CN.d.cts +1 -2
  139. package/fullstacked_modules/zod/v4/locales/zh-TW.d.cts +1 -2
  140. package/fullstacked_modules/zod/v4/mini/schemas.d.cts +0 -2
  141. package/fullstacked_modules/zod/v4/mini/schemas.d.ts +0 -2
  142. package/package.json +1 -1
  143. package/fullstacked_modules/zod/locales/index.d.cts +0 -1
  144. package/fullstacked_modules/zod/locales/index.d.ts +0 -1
  145. package/fullstacked_modules/zod/mini/index.d.cts +0 -1
  146. package/fullstacked_modules/zod/mini/index.d.ts +0 -1
  147. package/fullstacked_modules/zod/src/locales/index.ts +0 -1
  148. package/fullstacked_modules/zod/src/mini/index.ts +0 -1
  149. package/fullstacked_modules/zod/src/v4/core/tests/extend.test.ts +0 -18
  150. package/fullstacked_modules/zod/src/v4/locales/bg.ts +0 -136
  151. package/fullstacked_modules/zod/src/v4/locales/da.ts +0 -141
  152. package/fullstacked_modules/zod/src/v4/locales/is.ts +0 -127
  153. package/fullstacked_modules/zod/src/v4/locales/yo.ts +0 -131
  154. package/fullstacked_modules/zod/v4/locales/bg.d.cts +0 -5
  155. package/fullstacked_modules/zod/v4/locales/bg.d.ts +0 -5
  156. package/fullstacked_modules/zod/v4/locales/da.d.cts +0 -5
  157. package/fullstacked_modules/zod/v4/locales/da.d.ts +0 -4
  158. package/fullstacked_modules/zod/v4/locales/is.d.cts +0 -5
  159. package/fullstacked_modules/zod/v4/locales/is.d.ts +0 -5
  160. package/fullstacked_modules/zod/v4/locales/yo.d.cts +0 -5
  161. package/fullstacked_modules/zod/v4/locales/yo.d.ts +0 -4
@@ -1,13 +1,23 @@
1
1
  {
2
2
  "dependencies": {
3
+ "@anthropic-ai/sdk": "^0.64.0",
3
4
  "@fullstacked/codemirror-view": "git+https://github.com:fullstackedorg/codemirror-view",
5
+ "@google/genai": "^1.21.0",
6
+ "@langchain/anthropic": "^0.3.28",
4
7
  "@langchain/core": "^0.3.66",
8
+ "@langchain/deepseek": "^0.1.0",
9
+ "@langchain/google-genai": "^0.2.18",
10
+ "@langchain/mistralai": "^0.2.1",
5
11
  "@langchain/ollama": "^0.2.3",
6
12
  "@langchain/openai": "^0.6.3",
13
+ "@langchain/xai": "^0.1.0",
7
14
  "ollama": "^0.5.16",
8
15
  "openai": "^5.10.2",
9
16
  "streaming-markdown": "^0.2.15",
10
- "zod": "^4.0.14"
17
+ "zod": "^3.25.76"
18
+ },
19
+ "devDependencies": {
20
+ "@codemirror/theme-one-dark": "^6.1.3"
11
21
  },
12
22
  "main": "./src/index.ts",
13
23
  "name": "@fullstacked/ai-agent",
@@ -14,12 +14,18 @@ import { tool } from "@langchain/core/tools";
14
14
  import { ToolCall } from "@langchain/core/messages/tool";
15
15
  import { z } from "zod";
16
16
  import { Provider } from "./providers/interface";
17
+ import { Extension } from "@codemirror/state";
18
+ import { Runnable } from "@langchain/core/runnables";
19
+ import { BaseLanguageModelInput } from "@langchain/core/language_models/base";
20
+ import { BaseChatModelCallOptions } from "@langchain/core/language_models/chat_models";
17
21
 
18
22
  type ConversationOptions = {
19
23
  model: string;
20
24
  provider: Provider;
21
25
  messages?: StoredMessage[];
22
26
  tools?: ReturnType<typeof createTool>[];
27
+ codemirrorViewExtension?: Extension[];
28
+ onStateChange?: (state: "STREAMING" | "IDLE" | "ERROR") => void;
23
29
  };
24
30
 
25
31
  export function createTool<T extends z.ZodSchema>(opts: {
@@ -53,17 +59,25 @@ function classForMessageType(message: BaseMessage) {
53
59
  }
54
60
 
55
61
  export function createConversation(opts: ConversationOptions) {
56
- const client = opts.provider.client(opts.model);
62
+ let chatModel: Runnable<
63
+ BaseLanguageModelInput,
64
+ AIMessageChunk,
65
+ BaseChatModelCallOptions
66
+ >;
67
+ const updateChatModel = (provider: Provider, model: string) => {
68
+ const client = provider.client(model);
69
+ chatModel = opts.tools
70
+ ? client.bindTools(opts.tools.map(({ tool }) => tool))
71
+ : client;
72
+ };
57
73
 
58
- const chatModel = opts.tools
59
- ? client.bindTools(opts.tools.map(({ tool }) => tool))
60
- : client;
74
+ updateChatModel(opts.provider, opts.model);
61
75
 
62
76
  const element = document.createElement("div");
63
77
  element.classList.add("conversation");
64
78
 
65
79
  const conversation: BaseMessage[] = mapStoredMessagesToChatMessages(
66
- opts?.messages || [],
80
+ opts.messages || [],
67
81
  );
68
82
  const messagesContainer = document.createElement("div");
69
83
  messagesContainer.classList.add("messages");
@@ -72,8 +86,14 @@ export function createConversation(opts: ConversationOptions) {
72
86
  const messageContainer = document.createElement("div");
73
87
  messageContainer.classList.add(classForMessageType(message));
74
88
  messagesContainer.append(messageContainer);
75
- const renderer = createMarkdownStreamRenderer(messageContainer);
76
- renderer.write(message.response_metadata["user-defined-message"] || message.content as string);
89
+ const renderer = createMarkdownStreamRenderer(
90
+ messageContainer,
91
+ opts.codemirrorViewExtension,
92
+ );
93
+ renderer.write(
94
+ message.response_metadata["user-defined-message"] ||
95
+ (message.content as string),
96
+ );
77
97
  renderer.end();
78
98
  };
79
99
 
@@ -85,10 +105,17 @@ export function createConversation(opts: ConversationOptions) {
85
105
  );
86
106
 
87
107
  const container = document.createElement("div");
88
- const userDefinedMessage = t.message?.(toolCall.args) || `Using tool ${toolCall.name}`;
89
- container.innerText = userDefinedMessage;
108
+ const userDefinedMessage =
109
+ t.message?.(toolCall.args) || `Using tool ${toolCall.name}`;
90
110
  messagesContainer.append(container);
91
111
 
112
+ const renderer = createMarkdownStreamRenderer(
113
+ container,
114
+ opts.codemirrorViewExtension,
115
+ );
116
+ renderer.write(userDefinedMessage);
117
+ renderer.end();
118
+
92
119
  const toolResponse: ToolMessage = await t.tool.invoke(toolCall);
93
120
  toolResponse.response_metadata["user-defined-message"] =
94
121
  userDefinedMessage;
@@ -125,8 +152,21 @@ export function createConversation(opts: ConversationOptions) {
125
152
 
126
153
  aiMessageContainer.append(responseContainer, loadingContainer);
127
154
 
128
- const renderer = createMarkdownStreamRenderer(responseContainer);
129
- const stream = await chatModel.stream(conversation);
155
+ opts.onStateChange?.("STREAMING");
156
+ const renderer = createMarkdownStreamRenderer(
157
+ responseContainer,
158
+ opts.codemirrorViewExtension,
159
+ );
160
+ let stream: Awaited<ReturnType<typeof chatModel.stream>>;
161
+ try {
162
+ stream = await chatModel.stream(conversation);
163
+ } catch (e) {
164
+ renderer.write(e.toString());
165
+ opts.onStateChange?.("ERROR");
166
+ done = true;
167
+ renderer.end();
168
+ return;
169
+ }
130
170
  let messageIndex: number = null;
131
171
  for await (const chunk of stream) {
132
172
  if (messageIndex === null) {
@@ -148,10 +188,13 @@ export function createConversation(opts: ConversationOptions) {
148
188
  const aiMessage = conversation.at(messageIndex) as AIMessageChunk;
149
189
  const toolPromises = aiMessage.tool_calls.map((t) => onToolRequest(t));
150
190
  const awaitedToolPromises = await Promise.all(toolPromises);
151
- if (awaitedToolPromises.some((r) => r)) {
152
- promptAgent();
153
- }
191
+
154
192
  done = true;
193
+
194
+ if (toolPromises.length) {
195
+ return promptAgent();
196
+ }
197
+ opts.onStateChange?.("IDLE");
155
198
  };
156
199
 
157
200
  const humanInput = createHumanInput({
@@ -165,5 +208,20 @@ export function createConversation(opts: ConversationOptions) {
165
208
  return {
166
209
  element,
167
210
  serialize,
211
+ updateChatModel,
212
+ prompt: onHumanPrompt,
213
+ generateConversationTitle: async () => {
214
+ const response = await chatModel.invoke([
215
+ ...conversation,
216
+ new HumanMessage(
217
+ "Generate a title for this conversation with a 1 to 3 words.",
218
+ ),
219
+ ]);
220
+ return response.content
221
+ .toString()
222
+ .replace(/<think>(.|\s)*<\/think>\s*/g, "") // remove ollama think tags
223
+ .replace(/(\*|\"|\')*/g, "") // remove any md formatting
224
+ .trim();
225
+ },
168
226
  };
169
227
  }
@@ -1,3 +1,2 @@
1
1
  export * from "./conversation";
2
- export * from "./providers/ollama";
3
- export * from "./providers/openai";
2
+ export * from "./providers";
@@ -1,8 +1,12 @@
1
1
  import * as smd from "streaming-markdown";
2
2
  import { createCodeMirrorView } from "@fullstacked/codemirror-view";
3
3
  import { SupportedLanguage } from "@fullstacked/codemirror-view/languages";
4
+ import { Extension } from "@codemirror/state";
4
5
 
5
- export function createMarkdownStreamRenderer(el: HTMLElement) {
6
+ export function createMarkdownStreamRenderer(
7
+ el: HTMLElement,
8
+ cmExtensions?: Extension[],
9
+ ) {
6
10
  const renderer = smd.default_renderer(el);
7
11
  const defaultAddToken = renderer.add_token;
8
12
  renderer.add_token = function (data: any, type: any) {
@@ -11,9 +15,9 @@ export function createMarkdownStreamRenderer(el: HTMLElement) {
11
15
  }
12
16
 
13
17
  let parent = data.nodes[data.index];
14
- const codeView = createCodeMirrorView() as ReturnType<
15
- typeof createCodeMirrorView
16
- > & {
18
+ const codeView = createCodeMirrorView({
19
+ extensions: cmExtensions || [],
20
+ }) as ReturnType<typeof createCodeMirrorView> & {
17
21
  setAttribute(attr: string, value: string): void;
18
22
  appendChild(text: Text): void;
19
23
  };
@@ -0,0 +1,46 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import { ChatAnthropic } from "@langchain/anthropic";
3
+ import { ProviderInfo } from "./interface";
4
+ import { core_fetch2 } from "fetch";
5
+ import { Provider } from "@fullstacked/ai-agent/src/providers/interface";
6
+
7
+ export const AnthropicInfo: ProviderInfo = {
8
+ id: "anthropic",
9
+ title: "Anthropic",
10
+ configs: [
11
+ {
12
+ id: "apiKey",
13
+ title: "API Key",
14
+ type: "string",
15
+ value: "",
16
+ },
17
+ ],
18
+ };
19
+
20
+ async function models(apiKey: string) {
21
+ const anthropicClient = new Anthropic({
22
+ apiKey: apiKey,
23
+ fetch: core_fetch2,
24
+ dangerouslyAllowBrowser: true,
25
+ });
26
+
27
+ const models = await anthropicClient.models.list();
28
+ return models.data.map(({ id }) => id);
29
+ }
30
+
31
+ export function createClaude(opts?: typeof AnthropicInfo.configs): Provider {
32
+ const apiKey =
33
+ (opts?.find(({ id }) => id === "apiKey")?.value as string) || "";
34
+
35
+ return {
36
+ models: () => models(apiKey),
37
+ client: (model) =>
38
+ new ChatAnthropic({
39
+ model,
40
+ apiKey,
41
+ clientOptions: {
42
+ fetch: core_fetch2,
43
+ },
44
+ }),
45
+ };
46
+ }
@@ -0,0 +1,46 @@
1
+ import { core_fetch2 } from "fetch";
2
+ import { Provider, ProviderInfo } from "./interface";
3
+ import openai from "openai";
4
+ import { ChatDeepSeek } from "@langchain/deepseek";
5
+
6
+ export const DeepSeekInfo: ProviderInfo = {
7
+ id: "deepseek",
8
+ title: "DeepSeek",
9
+ configs: [
10
+ {
11
+ id: "apiKey",
12
+ title: "API Key",
13
+ type: "string",
14
+ value: "",
15
+ },
16
+ ],
17
+ };
18
+
19
+ async function models(apiKey: string) {
20
+ const client = new openai({
21
+ apiKey,
22
+ baseURL: "https://api.deepseek.com",
23
+ fetch: core_fetch2,
24
+ dangerouslyAllowBrowser: true,
25
+ });
26
+
27
+ const models = await client.models.list();
28
+ return models.data.map(({ id }) => id);
29
+ }
30
+
31
+ export function createDeepSeek(opts?: typeof DeepSeekInfo.configs): Provider {
32
+ const apiKey =
33
+ (opts?.find(({ id }) => id === "apiKey")?.value as string) || "";
34
+
35
+ return {
36
+ models: () => models(apiKey),
37
+ client: (model) =>
38
+ new ChatDeepSeek({
39
+ model,
40
+ apiKey,
41
+ configuration: {
42
+ fetch: core_fetch2,
43
+ },
44
+ }),
45
+ };
46
+ }
@@ -0,0 +1,40 @@
1
+ import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
2
+ import { GoogleGenAI } from "@google/genai";
3
+ import { Provider } from "@fullstacked/ai-agent/src/providers/interface";
4
+ import { ProviderInfo } from "./interface";
5
+
6
+ export const GoogleInfo: ProviderInfo = {
7
+ id: "google",
8
+ title: "Google",
9
+ configs: [
10
+ {
11
+ id: "apiKey",
12
+ title: "API Key",
13
+ type: "string",
14
+ value: "",
15
+ },
16
+ ],
17
+ };
18
+
19
+ async function models(apiKey: string) {
20
+ const googleClient = new GoogleGenAI({
21
+ apiKey,
22
+ });
23
+
24
+ const models = await googleClient.models.list();
25
+ return models.page.map(({ name }) => name.slice("models/".length));
26
+ }
27
+
28
+ export function createGemini(opts?: typeof GoogleInfo.configs): Provider {
29
+ const apiKey =
30
+ (opts?.find(({ id }) => id === "apiKey")?.value as string) || "";
31
+
32
+ return {
33
+ models: () => models(apiKey),
34
+ client: (model) =>
35
+ new ChatGoogleGenerativeAI({
36
+ model,
37
+ apiKey,
38
+ }),
39
+ };
40
+ }
@@ -0,0 +1,41 @@
1
+ import { ProviderInfo } from "./interface";
2
+ import { OpenAIInfo, createOpenAI } from "./openai";
3
+ import { OllamaInfo, createOllama } from "./ollama";
4
+ import { Provider } from "./interface";
5
+ import { AnthropicInfo, createClaude } from "./anthropic";
6
+ import { GoogleInfo, createGemini } from "./google";
7
+ import { createGrok, xAIInfo } from "./xai";
8
+ import { DeepSeekInfo, createDeepSeek } from "./deepseek";
9
+ import { MistralInfo, createMistral } from "./mistral";
10
+
11
+ export function providers(): ProviderInfo[] {
12
+ return [
13
+ OllamaInfo,
14
+ OpenAIInfo,
15
+ AnthropicInfo,
16
+ GoogleInfo,
17
+ xAIInfo,
18
+ DeepSeekInfo,
19
+ MistralInfo,
20
+ ];
21
+ }
22
+
23
+ export function getProvider(providerInfo: ProviderInfo) {
24
+ switch (providerInfo.id) {
25
+ case "ollama":
26
+ return createOllama(providerInfo.configs);
27
+ case "openai":
28
+ return createOpenAI(providerInfo.configs);
29
+ case "anthropic":
30
+ return createClaude(providerInfo.configs);
31
+ case "google":
32
+ return createGemini(providerInfo.configs);
33
+ case "xai":
34
+ return createGrok(providerInfo.configs);
35
+ case "deepseek":
36
+ return createDeepSeek(providerInfo.configs);
37
+ case "mistral":
38
+ return createMistral(providerInfo.configs);
39
+ }
40
+ return null;
41
+ }
@@ -1,5 +1,24 @@
1
1
  import { BaseChatModel } from "@langchain/core/language_models/chat_models";
2
2
 
3
+ type ConfigType =
4
+ | {
5
+ type: "string";
6
+ value: string;
7
+ }
8
+ | {
9
+ type: "key-value";
10
+ value: [string, string][];
11
+ };
12
+
13
+ export type ProviderInfo = {
14
+ id: string;
15
+ title: string;
16
+ configs: (ConfigType & {
17
+ id: string;
18
+ title: string;
19
+ })[];
20
+ };
21
+
3
22
  export interface Provider {
4
23
  models(): Promise<string[]>;
5
24
  client(model: string): BaseChatModel;
@@ -0,0 +1,47 @@
1
+ import { core_fetch2 } from "fetch";
2
+ import { Provider, ProviderInfo } from "./interface";
3
+ import { ChatMistralAI } from "@langchain/mistralai";
4
+ import { HTTPClient } from "@mistralai/mistralai/lib/http";
5
+ import { Mistral } from "@mistralai/mistralai";
6
+
7
+ export const MistralInfo: ProviderInfo = {
8
+ id: "mistral",
9
+ title: "Mistral AI",
10
+ configs: [
11
+ {
12
+ id: "apiKey",
13
+ title: "API Key",
14
+ type: "string",
15
+ value: "",
16
+ },
17
+ ],
18
+ };
19
+
20
+ async function models(apiKey: string) {
21
+ const mistralClient = new Mistral({
22
+ apiKey: apiKey,
23
+ httpClient: {
24
+ request: (r) => core_fetch2(r),
25
+ } as HTTPClient,
26
+ });
27
+
28
+ const models = await mistralClient.models.list();
29
+ return models.data.map(({ id }) => id);
30
+ }
31
+
32
+ export function createMistral(opts?: typeof MistralInfo.configs): Provider {
33
+ const apiKey =
34
+ (opts?.find(({ id }) => id === "apiKey")?.value as string) || "";
35
+
36
+ return {
37
+ models: () => models(apiKey),
38
+ client: (model) =>
39
+ new ChatMistralAI({
40
+ model,
41
+ apiKey,
42
+ httpClient: {
43
+ request: (r) => core_fetch2(r),
44
+ } as HTTPClient,
45
+ }),
46
+ };
47
+ }
@@ -1,10 +1,29 @@
1
1
  // @ts-ignore
2
2
  import { Ollama as OllamaClient } from "ollama/browser";
3
3
  import type * as ollama from "ollama";
4
- import { Provider } from "./interface";
4
+ import { Provider, ProviderInfo } from "./interface";
5
5
  import { core_fetch2 } from "fetch";
6
6
  import { ChatOllama } from "@langchain/ollama";
7
7
 
8
+ export const OllamaInfo: ProviderInfo = {
9
+ id: "ollama",
10
+ title: "Ollama",
11
+ configs: [
12
+ {
13
+ id: "host",
14
+ title: "Host",
15
+ type: "string",
16
+ value: "http://localhost:11434",
17
+ },
18
+ {
19
+ id: "headers",
20
+ title: "Custom Headers",
21
+ type: "key-value",
22
+ value: [],
23
+ },
24
+ ],
25
+ };
26
+
8
27
  async function models(opts: ollama.Config) {
9
28
  const ollamaClient: ollama.Ollama = new OllamaClient({
10
29
  ...opts,
@@ -16,14 +35,12 @@ async function models(opts: ollama.Config) {
16
35
  return models.map((m) => m.name);
17
36
  }
18
37
 
19
- type OllamaOptions = {
20
- host: string;
21
- headers: { [key: string]: string };
22
- };
23
-
24
- export function createOllama(opts?: Partial<OllamaOptions>): Provider {
25
- const baseUrl = opts?.host || "http://localhost:11434";
26
- const headers = opts?.headers || {};
38
+ export function createOllama(opts?: typeof OllamaInfo.configs): Provider {
39
+ const baseUrl =
40
+ (opts?.find(({ id }) => id === "host")?.value as string) ||
41
+ "http://localhost:11434";
42
+ const headers =
43
+ (opts?.find(({ id }) => id === "headers")?.value as {}) || {};
27
44
 
28
45
  return {
29
46
  models: () =>
@@ -1,11 +1,24 @@
1
1
  import { core_fetch2 } from "fetch";
2
- import { Provider } from "./interface";
2
+ import { Provider, ProviderInfo } from "./interface";
3
3
  import openai from "openai";
4
4
  import { ChatOpenAI } from "@langchain/openai";
5
5
 
6
- async function models(opts: OpenAIOptions) {
6
+ export const OpenAIInfo: ProviderInfo = {
7
+ id: "openai",
8
+ title: "OpenAI",
9
+ configs: [
10
+ {
11
+ id: "apiKey",
12
+ title: "API Key",
13
+ type: "string",
14
+ value: "",
15
+ },
16
+ ],
17
+ };
18
+
19
+ async function models(apiKey: string) {
7
20
  const openAIClient = new openai({
8
- apiKey: opts.apiKey,
21
+ apiKey,
9
22
  fetch: core_fetch2,
10
23
  dangerouslyAllowBrowser: true,
11
24
  });
@@ -14,17 +27,16 @@ async function models(opts: OpenAIOptions) {
14
27
  return models.data.map(({ id }) => id);
15
28
  }
16
29
 
17
- type OpenAIOptions = {
18
- apiKey: string;
19
- };
30
+ export function createOpenAI(opts?: typeof OpenAIInfo.configs): Provider {
31
+ const apiKey =
32
+ (opts?.find(({ id }) => id === "apiKey")?.value as string) || "";
20
33
 
21
- export function createOpenAI(opts: OpenAIOptions): Provider {
22
34
  return {
23
- models: () => models(opts),
35
+ models: () => models(apiKey),
24
36
  client: (model) =>
25
37
  new ChatOpenAI({
26
38
  model,
27
- apiKey: opts.apiKey,
39
+ apiKey,
28
40
  configuration: {
29
41
  fetch: core_fetch2,
30
42
  },
@@ -0,0 +1,43 @@
1
+ import { core_fetch2 } from "fetch";
2
+ import { Provider, ProviderInfo } from "./interface";
3
+ import openai from "openai";
4
+ import { ChatXAI } from "@langchain/xai";
5
+
6
+ export const xAIInfo: ProviderInfo = {
7
+ id: "xai",
8
+ title: "xAI",
9
+ configs: [
10
+ {
11
+ id: "apiKey",
12
+ title: "API Key",
13
+ type: "string",
14
+ value: "",
15
+ },
16
+ ],
17
+ };
18
+
19
+ async function models(apiKey: string) {
20
+ const client = new openai({
21
+ apiKey,
22
+ fetch: core_fetch2,
23
+ baseURL: "https://api.x.ai/v1",
24
+ dangerouslyAllowBrowser: true,
25
+ });
26
+
27
+ const models = await client.models.list();
28
+ return models.data.map(({ id }) => id);
29
+ }
30
+
31
+ export function createGrok(opts?: typeof xAIInfo.configs): Provider {
32
+ const apiKey =
33
+ (opts?.find(({ id }) => id === "apiKey")?.value as string) || "";
34
+
35
+ return {
36
+ models: () => models(apiKey),
37
+ client: (model) =>
38
+ new ChatXAI({
39
+ model,
40
+ apiKey,
41
+ }),
42
+ };
43
+ }
@@ -0,0 +1,7 @@
1
+ Once upon a time, in a land far away, there was a curious little fox named Felix. Felix had a peculiar habit of collecting shiny objects. One day, while exploring the forest, he stumbled upon a magical mirror that showed not his reflection, but his deepest desires.
2
+
3
+ Felix looked into the mirror and saw himself as a mighty king, ruling over a grand kingdom. He wished for that life instantly. The mirror granted his wish, and suddenly, Felix was a king with a golden crown and a kingdom of his own.
4
+
5
+ But as days passed, Felix realized that being a king was lonely. He missed the simplicity of his forest life. One day, he decided to return to the mirror and wished to be himself again. The mirror, surprised by his honesty, granted his wish and returned him to the forest.
6
+
7
+ From that day on, Felix learned that true happiness comes from being himself, not from what he desires. And so, he continued his adventures, collecting shiny objects, but always remembering the lesson he learned from the magical mirror.