chat-agent-toolkit 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +234 -0
  2. package/package.json +101 -0
  3. package/src/config/config-manager.ts +319 -0
  4. package/src/config/config-types.ts +65 -0
  5. package/src/config/environment-variables.ts +8 -0
  6. package/src/config/index.ts +26 -0
  7. package/src/config/language-models-database.ts +1426 -0
  8. package/src/config/mcp-server-registry.ts +24 -0
  9. package/src/config/model-registry.ts +256 -0
  10. package/src/config/model-tester.ts +211 -0
  11. package/src/config/model-utils.ts +193 -0
  12. package/src/config/provider-ui-config.ts +196 -0
  13. package/src/connectors/composio.json +154 -0
  14. package/src/index.ts +22 -0
  15. package/src/memory/ARCHITECTURE.md +302 -0
  16. package/src/memory/MASTRA_INTEGRATION.md +106 -0
  17. package/src/memory/README.md +224 -0
  18. package/src/memory/agent-memory-manager.ts +416 -0
  19. package/src/memory/example.ts +343 -0
  20. package/src/memory/index.ts +47 -0
  21. package/src/memory/mastra-integration.ts +609 -0
  22. package/src/memory/storage/drizzle-storage.ts +205 -0
  23. package/src/memory/storage/in-memory-storage.ts +551 -0
  24. package/src/memory/storage/storage-interface.ts +68 -0
  25. package/src/memory/types.ts +125 -0
  26. package/src/models/providers.ts +5 -0
  27. package/src/models/registry.ts +4 -0
  28. package/src/models/types.ts +4 -0
  29. package/src/search.ts +5 -0
  30. package/src/tools/composio-mastra.ts +305 -0
  31. package/src/tools/composio-mcp.ts +205 -0
  32. package/src/tools/index.ts +13 -0
  33. package/src/tools/qwksearch-api-tools.ts +327 -0
  34. package/src/tools/search/doc-utils.ts +75 -0
  35. package/src/tools/search/document.ts +47 -0
  36. package/src/tools/search/index.ts +13 -0
  37. package/src/tools/search/link-summarizer.ts +112 -0
  38. package/src/tools/search/meta-search-types.ts +62 -0
  39. package/src/tools/search/metaSearchAgent.ts +454 -0
  40. package/src/tools/search/search-handlers.ts +85 -0
  41. package/src/tools/search/suggestionGeneratorAgent.ts +54 -0
  42. package/src/types.d.ts +137 -0
  43. package/src/utils/README.md +98 -0
  44. package/src/utils/chat-helpers.ts +18 -0
  45. package/src/utils/index.ts +2 -0
  46. package/src/utils/markdown-to-html.ts +53 -0
  47. package/src/utils/outputParser.ts +73 -0
  48. package/src/utils/provider-image-cropper.ts +130 -0
package/src/types.d.ts ADDED
@@ -0,0 +1,137 @@
1
+ /**
2
+ * @fileoverview Global Type Definitions
3
+ *
4
+ * Shared TypeScript types for UI configuration, model providers,
5
+ * and MCP server configuration used throughout the toolkit.
6
+ */
7
+
8
+ import { Model } from "./config/config-types";
9
+
10
+ type BaseUIConfigField = {
11
+ name: string;
12
+ key: string;
13
+ required: boolean;
14
+ description: string;
15
+ scope: "client" | "server";
16
+ env?: string;
17
+ };
18
+
19
+ type StringUIConfigField = BaseUIConfigField & {
20
+ type: "string";
21
+ placeholder?: string;
22
+ default?: string;
23
+ };
24
+
25
+ type SelectUIConfigFieldOptions = {
26
+ name: string;
27
+ value: string;
28
+ };
29
+
30
+ type SelectUIConfigField = BaseUIConfigField & {
31
+ type: "select";
32
+ default?: string;
33
+ options: SelectUIConfigFieldOptions[];
34
+ };
35
+
36
+ type PasswordUIConfigField = BaseUIConfigField & {
37
+ type: "password";
38
+ placeholder?: string;
39
+ default?: string;
40
+ };
41
+
42
+ type TextareaUIConfigField = BaseUIConfigField & {
43
+ type: "textarea";
44
+ placeholder?: string;
45
+ default?: string;
46
+ };
47
+
48
+ type SwitchUIConfigField = BaseUIConfigField & {
49
+ type: "switch";
50
+ default?: boolean;
51
+ };
52
+
53
+ type UIConfigField =
54
+ | StringUIConfigField
55
+ | SelectUIConfigField
56
+ | PasswordUIConfigField
57
+ | TextareaUIConfigField
58
+ | SwitchUIConfigField;
59
+
60
+ type ConfigModelProvider = {
61
+ id: string;
62
+ name: string;
63
+ type: string;
64
+ chatModels: Model[];
65
+ config: { [key: string]: any };
66
+ hash: string;
67
+ isEnvBased?: boolean; // True if provider was created from environment variables (global keys)
68
+ };
69
+
70
+ type MCPServerConfig = {
71
+ id: string;
72
+ name: string;
73
+ type: string;
74
+ url?: string;
75
+ apiKey?: string;
76
+ config: { [key: string]: any };
77
+ enabled: boolean;
78
+ hash: string;
79
+ };
80
+
81
+ type Config = {
82
+ version: number;
83
+ setupComplete: boolean;
84
+ preferences: {
85
+ [key: string]: any;
86
+ };
87
+ personalization: {
88
+ [key: string]: any;
89
+ };
90
+ modelProviders: ConfigModelProvider[];
91
+ mcpServers: MCPServerConfig[];
92
+ search: {
93
+ [key: string]: any;
94
+ };
95
+ };
96
+
97
+ type EnvMap = {
98
+ [key: string]: {
99
+ fieldKey: string;
100
+ providerKey: string;
101
+ };
102
+ };
103
+
104
+ type ModelProviderUISection = {
105
+ name: string;
106
+ key: string;
107
+ fields: UIConfigField[];
108
+ };
109
+
110
+ type MCPServerUISection = {
111
+ name: string;
112
+ key: string;
113
+ fields: UIConfigField[];
114
+ };
115
+
116
+ type UIConfigSections = {
117
+ preferences: UIConfigField[];
118
+ personalization: UIConfigField[];
119
+ modelProviders: ModelProviderUISection[];
120
+ mcpServers: MCPServerUISection[];
121
+ search: UIConfigField[];
122
+ };
123
+
124
+ export type {
125
+ UIConfigField,
126
+ Config,
127
+ EnvMap,
128
+ UIConfigSections,
129
+ SelectUIConfigField,
130
+ StringUIConfigField,
131
+ ModelProviderUISection,
132
+ MCPServerUISection,
133
+ ConfigModelProvider,
134
+ MCPServerConfig,
135
+ TextareaUIConfigField,
136
+ SwitchUIConfigField,
137
+ };
@@ -0,0 +1,98 @@
1
+ # Provider Image Cropper
2
+
3
+ Utility for extracting individual provider logos from a sprite sheet.
4
+
5
+ ## Usage
6
+
7
+ ### Basic Usage
8
+
9
+ ```typescript
10
+ import { cropProvider, cropProviderAsDataURL, getProviderImage } from 'agent-toolkit';
11
+
12
+ // Method 1: Load image first, then crop
13
+ const img = new Image();
14
+ img.src = '/providers-sprite.png';
15
+ await img.decode();
16
+ const canvas = await cropProvider(img, 'openai');
17
+
18
+ // Method 2: Get as data URL (for React/Vue components)
19
+ const dataUrl = await cropProviderAsDataURL(img, 'anthropic');
20
+
21
+ // Method 3: Load and crop in one step
22
+ const canvas = await getProviderImage('/providers-sprite.png', 'gemini');
23
+ ```
24
+
25
+ ### React Component Example
26
+
27
+ ```tsx
28
+ import { useEffect, useState } from 'react';
29
+ import { cropProviderAsDataURL, Provider } from 'agent-toolkit';
30
+
31
+ function ProviderIcon({ providerType }: { providerType: Provider }) {
32
+ const [iconUrl, setIconUrl] = useState<string | null>(null);
33
+
34
+ useEffect(() => {
35
+ const loadIcon = async () => {
36
+ const img = new Image();
37
+ img.src = '/providers-sprite.png';
38
+ await img.decode();
39
+ const url = await cropProviderAsDataURL(img, providerType);
40
+ setIconUrl(url);
41
+ };
42
+ loadIcon();
43
+ }, [providerType]);
44
+
45
+ return iconUrl ? <img src={iconUrl} alt={providerType} /> : null;
46
+ }
47
+ ```
48
+
49
+ ## Sprite Sheet Layout
50
+
51
+ The sprite sheet must be organized in a 6×4 grid (6 columns, 4 rows) with the following layout:
52
+
53
+ | Row 0 | Col 0 | Col 1 | Col 2 | Col 3 | Col 4 | Col 5 |
54
+ |-------|-------|-------|-------|-------|-------|-------|
55
+ | **0** | openrouter | tongyi | ollama | huggingface | localai | openllm |
56
+ | **1** | zhipu | replicate | azure | anthropic | groq | sagemaker |
57
+ | **2** | 01ai | bedrock | openai | cohere | together | xorbits |
58
+ | **3** | wenxin | moonshot | gemini | mistral | jina | chatglm |
59
+
60
+ ## Available Providers
61
+
62
+ Use `getProviderNames()` to get all supported providers:
63
+
64
+ ```typescript
65
+ import { getProviderNames } from 'agent-toolkit';
66
+
67
+ const providers = getProviderNames();
68
+ // ['openrouter', 'tongyi', 'ollama', 'huggingface', ...]
69
+ ```
70
+
71
+ ## API Reference
72
+
73
+ ### `cropProvider(image, provider)`
74
+ Returns a canvas element with the cropped provider logo.
75
+
76
+ ### `cropProviderAsBlob(image, provider, type?, quality?)`
77
+ Returns a Blob of the cropped logo. Useful for file uploads.
78
+
79
+ ### `cropProviderAsDataURL(image, provider, type?, quality?)`
80
+ Returns a data URL string. Best for inline images in HTML/React.
81
+
82
+ ### `getProviderImage(spriteSheetUrl, provider)`
83
+ Loads the sprite sheet and returns the cropped canvas in one call.
84
+
85
+ ### `getProviderNames()`
86
+ Returns an array of all supported provider names.
87
+
88
+ ## Creating a Sprite Sheet
89
+
90
+ To create a compatible sprite sheet:
91
+
92
+ 1. Collect 24 provider logos (one for each provider)
93
+ 2. Arrange them in a 6×4 grid following the layout above
94
+ 3. Ensure all logos are the same size
95
+ 4. Export as PNG with transparency
96
+ 5. Save to `public/images/providers-sprite.png`
97
+
98
+ Recommended tile size: 128×128px or 256×256px per provider.
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Chat history formatting utilities
3
+ */
4
+
5
+ type ChatHistoryMessage = {
6
+ content?: unknown;
7
+ role?: string;
8
+ type?: string;
9
+ };
10
+
11
+ export const formatChatHistoryAsString = (history: ChatHistoryMessage[]) => {
12
+ return history
13
+ .map(
14
+ (message) =>
15
+ `${message.role === 'assistant' || message.type === 'ai' ? 'AI' : 'User'}: ${String(message.content ?? '')}`,
16
+ )
17
+ .join('\n');
18
+ };
@@ -0,0 +1,2 @@
1
+ export * from './chat-helpers';
2
+ export * from './outputParser';
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @module research/agents/markdown-to-html
3
+ * @description Converts Markdown to HTML with Highlight.js syntax highlighting.
4
+ */
5
+ import { marked } from "marked";
6
+ import hljs from "highlight.js";
7
+ import { encode, decode } from "html-entities";
8
+
9
+ // Inline onclick: self-contained per button, works in dangerouslySetInnerHTML contexts
10
+ const COPY_ONCLICK = [
11
+ "(function(b){",
12
+ "var c=b.closest('figure.code-block')?.querySelector('pre code');",
13
+ "if(!c)return;",
14
+ "navigator.clipboard.writeText(c.innerText).then(function(){",
15
+ "var t=b.textContent;b.textContent='Copied!';",
16
+ "setTimeout(function(){b.textContent=t},2000)",
17
+ "})",
18
+ "})(this)",
19
+ ].join("");
20
+
21
+ // Configure marked once at module load \u2014 stacking use() calls would duplicate extensions
22
+ marked.use({ breaks: true, gfm: true, async: true });
23
+
24
+ marked.use({
25
+ renderer: {
26
+ code({ text, lang }) {
27
+ const language = lang || "plaintext";
28
+ let highlighted: string;
29
+
30
+ try {
31
+ if (language && hljs.getLanguage(language)) {
32
+ highlighted = hljs.highlight(text, { language }).value;
33
+ } else {
34
+ highlighted = hljs.highlightAuto(text).value;
35
+ }
36
+ } catch (e) {
37
+ highlighted = encode(text);
38
+ }
39
+
40
+ return `<figure class="code-block"><button class="code-copy-btn" type="button" onclick="${COPY_ONCLICK}">Copy</button><pre><code class="hljs language-${language}">${highlighted}</code></pre></figure>`;
41
+ },
42
+ },
43
+ });
44
+
45
+ /**
46
+ * Convert markdown text to HTML with Highlight.js syntax highlighting.
47
+ * Unescapes HTML entities like `&amp;` \u2192 `&`.
48
+ */
49
+ export async function convertMarkdownToHTMLEscaped(
50
+ markdown: string,
51
+ ): Promise<string> {
52
+ return (await marked.parse(decode(markdown))).trim();
53
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @module agent-toolkit/utils/outputParser
3
+ * @description Parsers that extract values from XML-tagged sections of LLM
4
+ * output (e.g. `<links>...</links>`, `<question>...</question>`).
5
+ */
6
+
7
+ const LIST_MARKER_REGEX = /^(\s*(-|\*|\d+\.\s|\d+\)\s|•)\s*)+/;
8
+
9
+ interface LineListOutputParserArgs {
10
+ key?: string;
11
+ }
12
+
13
+ export class LineListOutputParser {
14
+ private key = "questions";
15
+
16
+ constructor(args?: LineListOutputParserArgs) {
17
+ this.key = args?.key ?? this.key;
18
+ }
19
+
20
+ async parse(text: string): Promise<string[]> {
21
+ text = text.trim() || "";
22
+
23
+ const startKeyIndex = text.indexOf(`<${this.key}>`);
24
+ const endKeyIndex = text.indexOf(`</${this.key}>`);
25
+
26
+ if (startKeyIndex === -1 || endKeyIndex === -1) {
27
+ return [];
28
+ }
29
+
30
+ const questionsStartIndex = startKeyIndex + `<${this.key}>`.length;
31
+ const lines = text
32
+ .slice(questionsStartIndex, endKeyIndex)
33
+ .trim()
34
+ .split("\n")
35
+ .filter((line) => line.trim() !== "")
36
+ .map((line) => line.replace(LIST_MARKER_REGEX, ""));
37
+
38
+ return lines;
39
+ }
40
+ }
41
+
42
+ interface LineOutputParserArgs {
43
+ key?: string;
44
+ }
45
+
46
+ export class LineOutputParser {
47
+ private key = "questions";
48
+
49
+ constructor(args?: LineOutputParserArgs) {
50
+ this.key = args?.key ?? this.key;
51
+ }
52
+
53
+ async parse(text: string): Promise<string | undefined> {
54
+ text = text.trim() || "";
55
+
56
+ const startKeyIndex = text.indexOf(`<${this.key}>`);
57
+ const endKeyIndex = text.indexOf(`</${this.key}>`);
58
+
59
+ if (startKeyIndex === -1 || endKeyIndex === -1) {
60
+ return undefined;
61
+ }
62
+
63
+ const questionsStartIndex = startKeyIndex + `<${this.key}>`.length;
64
+ const line = text
65
+ .slice(questionsStartIndex, endKeyIndex)
66
+ .trim()
67
+ .replace(LIST_MARKER_REGEX, "");
68
+
69
+ return line;
70
+ }
71
+ }
72
+
73
+ export default LineOutputParser;
@@ -0,0 +1,130 @@
1
+ const PROVIDERS = {
2
+ openrouter: { row: 0, col: 0 },
3
+ tongyi: { row: 0, col: 1 },
4
+ ollama: { row: 0, col: 2 },
5
+ huggingface: { row: 0, col: 3 },
6
+ localai: { row: 0, col: 4 },
7
+ openllm: { row: 0, col: 5 },
8
+ zhipu: { row: 1, col: 0 },
9
+ replicate: { row: 1, col: 1 },
10
+ azure: { row: 1, col: 2 },
11
+ anthropic: { row: 1, col: 3 },
12
+ groq: { row: 1, col: 4 },
13
+ sagemaker: { row: 1, col: 5 },
14
+ "01ai": { row: 2, col: 0 },
15
+ bedrock: { row: 2, col: 1 },
16
+ openai: { row: 2, col: 2 },
17
+ cohere: { row: 2, col: 3 },
18
+ together: { row: 2, col: 4 },
19
+ xorbits: { row: 2, col: 5 },
20
+ wenxin: { row: 3, col: 0 },
21
+ moonshot: { row: 3, col: 1 },
22
+ gemini: { row: 3, col: 2 },
23
+ mistral: { row: 3, col: 3 },
24
+ jina: { row: 3, col: 4 },
25
+ chatglm: { row: 3, col: 5 },
26
+ } as const;
27
+
28
+ export type Provider = keyof typeof PROVIDERS;
29
+
30
+ const COLS = 6;
31
+ const ROWS = 4;
32
+
33
+ /**
34
+ * Returns a cropped canvas containing just the provider box.
35
+ */
36
+ export async function cropProvider(
37
+ image: HTMLImageElement | ImageBitmap,
38
+ provider: Provider
39
+ ): Promise<HTMLCanvasElement> {
40
+ if (!(provider in PROVIDERS)) {
41
+ throw new Error(`Unknown provider: ${provider}`);
42
+ }
43
+
44
+ const { row, col } = PROVIDERS[provider];
45
+
46
+ const tileWidth = image.width / COLS;
47
+ const tileHeight = image.height / ROWS;
48
+
49
+ const canvas = document.createElement("canvas");
50
+ canvas.width = tileWidth;
51
+ canvas.height = tileHeight;
52
+
53
+ const ctx = canvas.getContext("2d");
54
+ if (!ctx) {
55
+ throw new Error("Failed to get 2D context");
56
+ }
57
+
58
+ ctx.drawImage(
59
+ image,
60
+ col * tileWidth,
61
+ row * tileHeight,
62
+ tileWidth,
63
+ tileHeight,
64
+ 0,
65
+ 0,
66
+ tileWidth,
67
+ tileHeight
68
+ );
69
+
70
+ return canvas;
71
+ }
72
+
73
+ /**
74
+ * Returns the provider image as a Blob.
75
+ */
76
+ export async function cropProviderAsBlob(
77
+ image: HTMLImageElement | ImageBitmap,
78
+ provider: Provider,
79
+ type: "image/png" | "image/jpeg" | "image/webp" = "image/png",
80
+ quality?: number
81
+ ): Promise<Blob> {
82
+ const canvas = await cropProvider(image, provider);
83
+
84
+ return new Promise<Blob>((resolve, reject) => {
85
+ canvas.toBlob(
86
+ (blob) => {
87
+ if (blob) {
88
+ resolve(blob);
89
+ } else {
90
+ reject(new Error("Failed to create blob"));
91
+ }
92
+ },
93
+ type,
94
+ quality
95
+ );
96
+ });
97
+ }
98
+
99
+ /**
100
+ * Returns the provider image as a data URL.
101
+ */
102
+ export async function cropProviderAsDataURL(
103
+ image: HTMLImageElement | ImageBitmap,
104
+ provider: Provider,
105
+ type: "image/png" | "image/jpeg" | "image/webp" = "image/png",
106
+ quality?: number
107
+ ): Promise<string> {
108
+ const canvas = await cropProvider(image, provider);
109
+ return canvas.toDataURL(type, quality);
110
+ }
111
+
112
+ /**
113
+ * Helper to load and crop in one call.
114
+ */
115
+ export async function getProviderImage(
116
+ spriteSheetUrl: string,
117
+ provider: Provider
118
+ ): Promise<HTMLCanvasElement> {
119
+ const img = new Image();
120
+ img.src = spriteSheetUrl;
121
+ await img.decode();
122
+ return cropProvider(img, provider);
123
+ }
124
+
125
+ /**
126
+ * Get all available provider names.
127
+ */
128
+ export function getProviderNames(): Provider[] {
129
+ return Object.keys(PROVIDERS) as Provider[];
130
+ }