@ash-cloud/ash-ai 0.1.8
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/dist/ash-widget.js +2 -0
- package/dist/ash-widget.js.map +1 -0
- package/dist/embed.cjs +19 -0
- package/dist/embed.cjs.map +1 -0
- package/dist/embed.d.cts +278 -0
- package/dist/embed.d.ts +278 -0
- package/dist/embed.js +16 -0
- package/dist/embed.js.map +1 -0
- package/dist/icons.cjs +156 -0
- package/dist/icons.cjs.map +1 -0
- package/dist/icons.d.cts +1 -0
- package/dist/icons.d.ts +1 -0
- package/dist/icons.js +3 -0
- package/dist/icons.js.map +1 -0
- package/dist/index-DJwpy-R5.js +6797 -0
- package/dist/index.cjs +17502 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +9590 -0
- package/dist/index.d.ts +9590 -0
- package/dist/index.js +17328 -0
- package/dist/index.js.map +1 -0
- package/dist/playground/App.d.ts +2 -0
- package/dist/playground/App.d.ts.map +1 -0
- package/dist/playground/Playground.d.ts +62 -0
- package/dist/playground/Playground.d.ts.map +1 -0
- package/dist/playground/components/ChatInput.d.ts +60 -0
- package/dist/playground/components/ChatInput.d.ts.map +1 -0
- package/dist/playground/components/MessageList.d.ts +28 -0
- package/dist/playground/components/MessageList.d.ts.map +1 -0
- package/dist/playground/components/NormalizedMessageList.d.ts +26 -0
- package/dist/playground/components/NormalizedMessageList.d.ts.map +1 -0
- package/dist/playground/components/SandboxLogsPanel.d.ts +16 -0
- package/dist/playground/components/SandboxLogsPanel.d.ts.map +1 -0
- package/dist/playground/components/Sidebar.d.ts +7 -0
- package/dist/playground/components/Sidebar.d.ts.map +1 -0
- package/dist/playground/components/ToolCallCard.d.ts +9 -0
- package/dist/playground/components/ToolCallCard.d.ts.map +1 -0
- package/dist/playground/components/icons.d.ts +9 -0
- package/dist/playground/components/icons.d.ts.map +1 -0
- package/dist/playground/contexts/ThemeContext.d.ts +9 -0
- package/dist/playground/contexts/ThemeContext.d.ts.map +1 -0
- package/dist/playground/index.d.ts +30 -0
- package/dist/playground/index.d.ts.map +1 -0
- package/dist/playground/main.d.ts +1 -0
- package/dist/playground/main.d.ts.map +1 -0
- package/dist/playground/pages/AgentsPage.d.ts +2 -0
- package/dist/playground/pages/AgentsPage.d.ts.map +1 -0
- package/dist/playground/pages/ChatPage.d.ts +2 -0
- package/dist/playground/pages/ChatPage.d.ts.map +1 -0
- package/dist/playground/pages/SessionsPage.d.ts +2 -0
- package/dist/playground/pages/SessionsPage.d.ts.map +1 -0
- package/dist/playground.css +1 -0
- package/dist/playground.d.ts +18 -0
- package/dist/playground.d.ts.map +1 -0
- package/dist/playground.js +3753 -0
- package/dist/schema-B_CVsJm5.d.cts +1585 -0
- package/dist/schema-B_CVsJm5.d.ts +1585 -0
- package/dist/schema.cjs +254 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.cts +3 -0
- package/dist/schema.d.ts +3 -0
- package/dist/schema.js +235 -0
- package/dist/schema.js.map +1 -0
- package/package.json +108 -0
package/dist/embed.cjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/embed/loader.ts
|
|
4
|
+
function generateEmbedSnippet(widgetUrl, settings) {
|
|
5
|
+
const settingsJson = JSON.stringify(settings, null, 2);
|
|
6
|
+
return `<!-- Ash AI Widget -->
|
|
7
|
+
<script>
|
|
8
|
+
window.AshSettings = ${settingsJson};
|
|
9
|
+
(function(){var w=window;var a=w.Ash;if(typeof a==="function"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='${widgetUrl}';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();
|
|
10
|
+
</script>`;
|
|
11
|
+
}
|
|
12
|
+
function generateMinifiedLoader(widgetUrl) {
|
|
13
|
+
return `(function(){var w=window;var a=w.Ash;if(typeof a==="function"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='${widgetUrl}';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.generateEmbedSnippet = generateEmbedSnippet;
|
|
17
|
+
exports.generateMinifiedLoader = generateMinifiedLoader;
|
|
18
|
+
//# sourceMappingURL=embed.cjs.map
|
|
19
|
+
//# sourceMappingURL=embed.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/embed/loader.ts"],"names":[],"mappings":";;;AA2WO,SAAS,oBAAA,CACd,WACA,QAAA,EACQ;AACR,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,MAAM,CAAC,CAAA;AAErD,EAAA,OAAO,CAAA;AAAA;AAAA,uBAAA,EAEgB,YAAY,CAAA;AAAA,iSAAA,EAC8P,SAAS,CAAA;AAAA,SAAA,CAAA;AAE5S;AAKO,SAAS,uBAAuB,SAAA,EAA2B;AAChE,EAAA,OAAO,kSAAkS,SAAS,CAAA,wNAAA,CAAA;AACpT","file":"embed.cjs","sourcesContent":["/**\n * Ash AI Embeddable Widget Loader\n *\n * This is the lightweight loader script that users embed on their sites.\n * It creates a command queue and asynchronously loads the full widget bundle.\n *\n * Usage:\n * ```html\n * <script>\n * window.AshSettings = {\n * apiBasePath: 'https://your-api.com/api',\n * agent: 'your-agent-slug'\n * };\n * (function(){var w=window;var a=w.Ash;if(typeof a===\"function\"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://cdn.your-domain.com/ash-widget.js';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();\n * </script>\n * ```\n */\n\n// =============================================================================\n// Event Types\n// =============================================================================\n\n/**\n * Tool use event - fired when the agent invokes a tool\n */\nexport interface AshToolUseEvent {\n type: 'tool_use';\n toolName: string;\n toolId: string;\n input: unknown;\n}\n\n/**\n * Tool result event - fired when a tool returns a result\n */\nexport interface AshToolResultEvent {\n type: 'tool_result';\n toolId: string;\n result: unknown;\n isError?: boolean;\n}\n\n/**\n * Streaming event - fired during message streaming\n */\nexport interface AshStreamEvent {\n type: 'stream_start' | 'stream_delta' | 'stream_end';\n content?: string;\n fullContent?: string;\n}\n\n/**\n * Error event - fired when an error occurs\n */\nexport interface AshErrorEvent {\n type: 'error';\n error: string;\n code?: string;\n}\n\n/**\n * Message event - fired for complete messages\n */\nexport interface AshMessageEvent {\n type: 'message';\n role: 'user' | 'assistant';\n content: string;\n messageId?: string;\n}\n\n/**\n * Todo item in a todo update\n */\nexport interface AshTodoItem {\n content: string;\n status: 'pending' | 'in_progress' | 'completed';\n activeForm: string;\n}\n\n/**\n * Todo update event - fired when todos are updated\n */\nexport interface AshTodoUpdateEvent {\n type: 'todo_update';\n todos: AshTodoItem[];\n stats: {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n };\n}\n\n/**\n * Union of all widget events\n */\nexport type AshEvent =\n | AshToolUseEvent\n | AshToolResultEvent\n | AshStreamEvent\n | AshErrorEvent\n | AshMessageEvent\n | AshTodoUpdateEvent;\n\n/**\n * Context data that can be pushed to the widget\n */\nexport interface AshContextData {\n /**\n * Key-value pairs to include in the system context\n */\n [key: string]: unknown;\n}\n\n// =============================================================================\n// Settings Interface\n// =============================================================================\n\nexport interface AshWidgetSettings {\n /**\n * Base path for API calls (e.g., \"https://your-api.com/api\")\n */\n apiBasePath: string;\n\n /**\n * Agent slug to use (optional - auto-selects first agent if not specified)\n */\n agent?: string;\n\n /**\n * Widget position on the page\n * - 'bottom-right', 'bottom-left', 'top-right', 'top-left': Floating widget in corner\n * - 'inline' or 'embedded': Widget fills its parent container (use with containerId)\n * @default 'bottom-right'\n */\n position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'inline' | 'embedded';\n\n /**\n * Container element ID for inline/embedded mode.\n * The widget will render inside this element and fill it completely.\n * Make sure to set a height on the container element.\n */\n containerId?: string;\n\n /**\n * Initial session ID to resume\n */\n sessionId?: string;\n\n /**\n * Whether to show the widget on load\n * @default false (shows launcher button)\n */\n open?: boolean;\n\n /**\n * Custom launcher button text\n * @default undefined (shows icon only)\n */\n launcherText?: string;\n\n /**\n * Theme customization\n */\n theme?: {\n /**\n * Primary accent color (hex)\n * @default '#ccff00'\n */\n accentColor?: string;\n\n /**\n * Background color for widget (hex)\n * @default '#0a0a0a'\n */\n backgroundColor?: string;\n\n /**\n * Text color (hex)\n * @default '#f3f4f6'\n */\n textColor?: string;\n\n /**\n * Border radius for the widget container\n * @default '16px'\n */\n borderRadius?: string;\n };\n\n /**\n * Widget dimensions\n */\n size?: {\n /**\n * Width of the widget panel\n * @default '400px'\n */\n width?: string;\n\n /**\n * Height of the widget panel\n * @default '600px'\n */\n height?: string;\n\n /**\n * Maximum height (for inline mode)\n */\n maxHeight?: string;\n };\n\n /**\n * Z-index for the widget\n * @default 2147483647 (max z-index)\n */\n zIndex?: number;\n\n /**\n * Custom greeting message shown before first interaction\n */\n greeting?: string;\n\n /**\n * Placeholder text for the input field\n * @default 'Type a message...'\n */\n placeholder?: string;\n\n /**\n * Callback when widget is opened\n */\n onOpen?: () => void;\n\n /**\n * Callback when widget is closed\n */\n onClose?: () => void;\n\n /**\n * Callback when a session starts\n */\n onSessionStart?: (sessionId: string) => void;\n\n /**\n * Callback when a message is sent\n */\n onMessageSent?: (message: string) => void;\n\n /**\n * Callback when a message is received\n */\n onMessageReceived?: (message: string) => void;\n\n // =========================================================================\n // Advanced Event Hooks\n // =========================================================================\n\n /**\n * Callback for all events (use for logging or custom handling)\n * This is called for every event type\n */\n onEvent?: (event: AshEvent) => void;\n\n /**\n * Callback when the agent uses a tool\n */\n onToolUse?: (event: AshToolUseEvent) => void;\n\n /**\n * Callback when a tool returns a result\n */\n onToolResult?: (event: AshToolResultEvent) => void;\n\n /**\n * Callback when streaming starts\n */\n onStreamStart?: () => void;\n\n /**\n * Callback during streaming with delta content\n */\n onStreamDelta?: (content: string, fullContent: string) => void;\n\n /**\n * Callback when streaming ends\n */\n onStreamEnd?: (fullContent: string) => void;\n\n /**\n * Callback when an error occurs\n */\n onError?: (error: string, code?: string) => void;\n\n /**\n * Callback when todos are updated (TodoWrite tool is called)\n */\n onTodoUpdate?: (event: AshTodoUpdateEvent) => void;\n\n // =========================================================================\n // Context & Data\n // =========================================================================\n\n /**\n * Initial context data to include with messages\n * This data will be sent as part of the system context\n */\n context?: AshContextData;\n\n /**\n * Hide the default launcher button (for custom triggers)\n * @default false\n */\n hideLauncher?: boolean;\n}\n\nexport type AshCommand =\n // Lifecycle commands\n | ['boot', AshWidgetSettings]\n | ['shutdown']\n // Visibility commands\n | ['open']\n | ['close']\n | ['toggle']\n | ['show']\n | ['hide']\n | ['showLauncher']\n | ['hideLauncher']\n // Configuration commands\n | ['update', Partial<AshWidgetSettings>]\n // Event listener commands\n | ['onOpen', () => void]\n | ['onClose', () => void]\n | ['onEvent', (event: AshEvent) => void]\n // Data/Context commands\n | ['setContext', AshContextData]\n | ['updateContext', Partial<AshContextData>]\n | ['clearContext']\n // Message commands\n | ['sendMessage', string]\n | ['sendMessageWithContext', string, AshContextData]\n // Query commands (returns via callback)\n | ['getSessionId', (sessionId: string | null) => void]\n | ['getContext', (context: AshContextData) => void]\n | ['getMessages', (messages: Array<{ role: string; content: string }>) => void];\n\nexport interface AshWidget {\n (command: AshCommand[0], ...args: unknown[]): void;\n q?: AshCommand[];\n c?: (args: AshCommand) => void;\n booted?: boolean;\n}\n\ndeclare global {\n interface Window {\n Ash: AshWidget;\n AshSettings?: AshWidgetSettings;\n }\n}\n\n/**\n * Generate the embed snippet for a given configuration\n */\nexport function generateEmbedSnippet(\n widgetUrl: string,\n settings: Partial<AshWidgetSettings>\n): string {\n const settingsJson = JSON.stringify(settings, null, 2);\n\n return `<!-- Ash AI Widget -->\n<script>\n window.AshSettings = ${settingsJson};\n (function(){var w=window;var a=w.Ash;if(typeof a===\"function\"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='${widgetUrl}';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();\n</script>`;\n}\n\n/**\n * Generate a minified version of the loader\n */\nexport function generateMinifiedLoader(widgetUrl: string): string {\n return `(function(){var w=window;var a=w.Ash;if(typeof a===\"function\"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='${widgetUrl}';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();`;\n}\n"]}
|
package/dist/embed.d.cts
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ash AI Embeddable Widget Loader
|
|
3
|
+
*
|
|
4
|
+
* This is the lightweight loader script that users embed on their sites.
|
|
5
|
+
* It creates a command queue and asynchronously loads the full widget bundle.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```html
|
|
9
|
+
* <script>
|
|
10
|
+
* window.AshSettings = {
|
|
11
|
+
* apiBasePath: 'https://your-api.com/api',
|
|
12
|
+
* agent: 'your-agent-slug'
|
|
13
|
+
* };
|
|
14
|
+
* (function(){var w=window;var a=w.Ash;if(typeof a==="function"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://cdn.your-domain.com/ash-widget.js';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();
|
|
15
|
+
* </script>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Tool use event - fired when the agent invokes a tool
|
|
20
|
+
*/
|
|
21
|
+
interface AshToolUseEvent {
|
|
22
|
+
type: 'tool_use';
|
|
23
|
+
toolName: string;
|
|
24
|
+
toolId: string;
|
|
25
|
+
input: unknown;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Tool result event - fired when a tool returns a result
|
|
29
|
+
*/
|
|
30
|
+
interface AshToolResultEvent {
|
|
31
|
+
type: 'tool_result';
|
|
32
|
+
toolId: string;
|
|
33
|
+
result: unknown;
|
|
34
|
+
isError?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Streaming event - fired during message streaming
|
|
38
|
+
*/
|
|
39
|
+
interface AshStreamEvent {
|
|
40
|
+
type: 'stream_start' | 'stream_delta' | 'stream_end';
|
|
41
|
+
content?: string;
|
|
42
|
+
fullContent?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Error event - fired when an error occurs
|
|
46
|
+
*/
|
|
47
|
+
interface AshErrorEvent {
|
|
48
|
+
type: 'error';
|
|
49
|
+
error: string;
|
|
50
|
+
code?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Message event - fired for complete messages
|
|
54
|
+
*/
|
|
55
|
+
interface AshMessageEvent {
|
|
56
|
+
type: 'message';
|
|
57
|
+
role: 'user' | 'assistant';
|
|
58
|
+
content: string;
|
|
59
|
+
messageId?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Todo item in a todo update
|
|
63
|
+
*/
|
|
64
|
+
interface AshTodoItem {
|
|
65
|
+
content: string;
|
|
66
|
+
status: 'pending' | 'in_progress' | 'completed';
|
|
67
|
+
activeForm: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Todo update event - fired when todos are updated
|
|
71
|
+
*/
|
|
72
|
+
interface AshTodoUpdateEvent {
|
|
73
|
+
type: 'todo_update';
|
|
74
|
+
todos: AshTodoItem[];
|
|
75
|
+
stats: {
|
|
76
|
+
total: number;
|
|
77
|
+
completed: number;
|
|
78
|
+
inProgress: number;
|
|
79
|
+
pending: number;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Union of all widget events
|
|
84
|
+
*/
|
|
85
|
+
type AshEvent = AshToolUseEvent | AshToolResultEvent | AshStreamEvent | AshErrorEvent | AshMessageEvent | AshTodoUpdateEvent;
|
|
86
|
+
/**
|
|
87
|
+
* Context data that can be pushed to the widget
|
|
88
|
+
*/
|
|
89
|
+
interface AshContextData {
|
|
90
|
+
/**
|
|
91
|
+
* Key-value pairs to include in the system context
|
|
92
|
+
*/
|
|
93
|
+
[key: string]: unknown;
|
|
94
|
+
}
|
|
95
|
+
interface AshWidgetSettings {
|
|
96
|
+
/**
|
|
97
|
+
* Base path for API calls (e.g., "https://your-api.com/api")
|
|
98
|
+
*/
|
|
99
|
+
apiBasePath: string;
|
|
100
|
+
/**
|
|
101
|
+
* Agent slug to use (optional - auto-selects first agent if not specified)
|
|
102
|
+
*/
|
|
103
|
+
agent?: string;
|
|
104
|
+
/**
|
|
105
|
+
* Widget position on the page
|
|
106
|
+
* - 'bottom-right', 'bottom-left', 'top-right', 'top-left': Floating widget in corner
|
|
107
|
+
* - 'inline' or 'embedded': Widget fills its parent container (use with containerId)
|
|
108
|
+
* @default 'bottom-right'
|
|
109
|
+
*/
|
|
110
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'inline' | 'embedded';
|
|
111
|
+
/**
|
|
112
|
+
* Container element ID for inline/embedded mode.
|
|
113
|
+
* The widget will render inside this element and fill it completely.
|
|
114
|
+
* Make sure to set a height on the container element.
|
|
115
|
+
*/
|
|
116
|
+
containerId?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Initial session ID to resume
|
|
119
|
+
*/
|
|
120
|
+
sessionId?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Whether to show the widget on load
|
|
123
|
+
* @default false (shows launcher button)
|
|
124
|
+
*/
|
|
125
|
+
open?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* Custom launcher button text
|
|
128
|
+
* @default undefined (shows icon only)
|
|
129
|
+
*/
|
|
130
|
+
launcherText?: string;
|
|
131
|
+
/**
|
|
132
|
+
* Theme customization
|
|
133
|
+
*/
|
|
134
|
+
theme?: {
|
|
135
|
+
/**
|
|
136
|
+
* Primary accent color (hex)
|
|
137
|
+
* @default '#ccff00'
|
|
138
|
+
*/
|
|
139
|
+
accentColor?: string;
|
|
140
|
+
/**
|
|
141
|
+
* Background color for widget (hex)
|
|
142
|
+
* @default '#0a0a0a'
|
|
143
|
+
*/
|
|
144
|
+
backgroundColor?: string;
|
|
145
|
+
/**
|
|
146
|
+
* Text color (hex)
|
|
147
|
+
* @default '#f3f4f6'
|
|
148
|
+
*/
|
|
149
|
+
textColor?: string;
|
|
150
|
+
/**
|
|
151
|
+
* Border radius for the widget container
|
|
152
|
+
* @default '16px'
|
|
153
|
+
*/
|
|
154
|
+
borderRadius?: string;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Widget dimensions
|
|
158
|
+
*/
|
|
159
|
+
size?: {
|
|
160
|
+
/**
|
|
161
|
+
* Width of the widget panel
|
|
162
|
+
* @default '400px'
|
|
163
|
+
*/
|
|
164
|
+
width?: string;
|
|
165
|
+
/**
|
|
166
|
+
* Height of the widget panel
|
|
167
|
+
* @default '600px'
|
|
168
|
+
*/
|
|
169
|
+
height?: string;
|
|
170
|
+
/**
|
|
171
|
+
* Maximum height (for inline mode)
|
|
172
|
+
*/
|
|
173
|
+
maxHeight?: string;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Z-index for the widget
|
|
177
|
+
* @default 2147483647 (max z-index)
|
|
178
|
+
*/
|
|
179
|
+
zIndex?: number;
|
|
180
|
+
/**
|
|
181
|
+
* Custom greeting message shown before first interaction
|
|
182
|
+
*/
|
|
183
|
+
greeting?: string;
|
|
184
|
+
/**
|
|
185
|
+
* Placeholder text for the input field
|
|
186
|
+
* @default 'Type a message...'
|
|
187
|
+
*/
|
|
188
|
+
placeholder?: string;
|
|
189
|
+
/**
|
|
190
|
+
* Callback when widget is opened
|
|
191
|
+
*/
|
|
192
|
+
onOpen?: () => void;
|
|
193
|
+
/**
|
|
194
|
+
* Callback when widget is closed
|
|
195
|
+
*/
|
|
196
|
+
onClose?: () => void;
|
|
197
|
+
/**
|
|
198
|
+
* Callback when a session starts
|
|
199
|
+
*/
|
|
200
|
+
onSessionStart?: (sessionId: string) => void;
|
|
201
|
+
/**
|
|
202
|
+
* Callback when a message is sent
|
|
203
|
+
*/
|
|
204
|
+
onMessageSent?: (message: string) => void;
|
|
205
|
+
/**
|
|
206
|
+
* Callback when a message is received
|
|
207
|
+
*/
|
|
208
|
+
onMessageReceived?: (message: string) => void;
|
|
209
|
+
/**
|
|
210
|
+
* Callback for all events (use for logging or custom handling)
|
|
211
|
+
* This is called for every event type
|
|
212
|
+
*/
|
|
213
|
+
onEvent?: (event: AshEvent) => void;
|
|
214
|
+
/**
|
|
215
|
+
* Callback when the agent uses a tool
|
|
216
|
+
*/
|
|
217
|
+
onToolUse?: (event: AshToolUseEvent) => void;
|
|
218
|
+
/**
|
|
219
|
+
* Callback when a tool returns a result
|
|
220
|
+
*/
|
|
221
|
+
onToolResult?: (event: AshToolResultEvent) => void;
|
|
222
|
+
/**
|
|
223
|
+
* Callback when streaming starts
|
|
224
|
+
*/
|
|
225
|
+
onStreamStart?: () => void;
|
|
226
|
+
/**
|
|
227
|
+
* Callback during streaming with delta content
|
|
228
|
+
*/
|
|
229
|
+
onStreamDelta?: (content: string, fullContent: string) => void;
|
|
230
|
+
/**
|
|
231
|
+
* Callback when streaming ends
|
|
232
|
+
*/
|
|
233
|
+
onStreamEnd?: (fullContent: string) => void;
|
|
234
|
+
/**
|
|
235
|
+
* Callback when an error occurs
|
|
236
|
+
*/
|
|
237
|
+
onError?: (error: string, code?: string) => void;
|
|
238
|
+
/**
|
|
239
|
+
* Callback when todos are updated (TodoWrite tool is called)
|
|
240
|
+
*/
|
|
241
|
+
onTodoUpdate?: (event: AshTodoUpdateEvent) => void;
|
|
242
|
+
/**
|
|
243
|
+
* Initial context data to include with messages
|
|
244
|
+
* This data will be sent as part of the system context
|
|
245
|
+
*/
|
|
246
|
+
context?: AshContextData;
|
|
247
|
+
/**
|
|
248
|
+
* Hide the default launcher button (for custom triggers)
|
|
249
|
+
* @default false
|
|
250
|
+
*/
|
|
251
|
+
hideLauncher?: boolean;
|
|
252
|
+
}
|
|
253
|
+
type AshCommand = ['boot', AshWidgetSettings] | ['shutdown'] | ['open'] | ['close'] | ['toggle'] | ['show'] | ['hide'] | ['showLauncher'] | ['hideLauncher'] | ['update', Partial<AshWidgetSettings>] | ['onOpen', () => void] | ['onClose', () => void] | ['onEvent', (event: AshEvent) => void] | ['setContext', AshContextData] | ['updateContext', Partial<AshContextData>] | ['clearContext'] | ['sendMessage', string] | ['sendMessageWithContext', string, AshContextData] | ['getSessionId', (sessionId: string | null) => void] | ['getContext', (context: AshContextData) => void] | ['getMessages', (messages: Array<{
|
|
254
|
+
role: string;
|
|
255
|
+
content: string;
|
|
256
|
+
}>) => void];
|
|
257
|
+
interface AshWidget {
|
|
258
|
+
(command: AshCommand[0], ...args: unknown[]): void;
|
|
259
|
+
q?: AshCommand[];
|
|
260
|
+
c?: (args: AshCommand) => void;
|
|
261
|
+
booted?: boolean;
|
|
262
|
+
}
|
|
263
|
+
declare global {
|
|
264
|
+
interface Window {
|
|
265
|
+
Ash: AshWidget;
|
|
266
|
+
AshSettings?: AshWidgetSettings;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Generate the embed snippet for a given configuration
|
|
271
|
+
*/
|
|
272
|
+
declare function generateEmbedSnippet(widgetUrl: string, settings: Partial<AshWidgetSettings>): string;
|
|
273
|
+
/**
|
|
274
|
+
* Generate a minified version of the loader
|
|
275
|
+
*/
|
|
276
|
+
declare function generateMinifiedLoader(widgetUrl: string): string;
|
|
277
|
+
|
|
278
|
+
export { type AshCommand, type AshContextData, type AshErrorEvent, type AshEvent, type AshMessageEvent, type AshStreamEvent, type AshTodoItem, type AshTodoUpdateEvent, type AshToolResultEvent, type AshToolUseEvent, type AshWidget, type AshWidgetSettings, generateEmbedSnippet, generateMinifiedLoader };
|
package/dist/embed.d.ts
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ash AI Embeddable Widget Loader
|
|
3
|
+
*
|
|
4
|
+
* This is the lightweight loader script that users embed on their sites.
|
|
5
|
+
* It creates a command queue and asynchronously loads the full widget bundle.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```html
|
|
9
|
+
* <script>
|
|
10
|
+
* window.AshSettings = {
|
|
11
|
+
* apiBasePath: 'https://your-api.com/api',
|
|
12
|
+
* agent: 'your-agent-slug'
|
|
13
|
+
* };
|
|
14
|
+
* (function(){var w=window;var a=w.Ash;if(typeof a==="function"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://cdn.your-domain.com/ash-widget.js';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();
|
|
15
|
+
* </script>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Tool use event - fired when the agent invokes a tool
|
|
20
|
+
*/
|
|
21
|
+
interface AshToolUseEvent {
|
|
22
|
+
type: 'tool_use';
|
|
23
|
+
toolName: string;
|
|
24
|
+
toolId: string;
|
|
25
|
+
input: unknown;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Tool result event - fired when a tool returns a result
|
|
29
|
+
*/
|
|
30
|
+
interface AshToolResultEvent {
|
|
31
|
+
type: 'tool_result';
|
|
32
|
+
toolId: string;
|
|
33
|
+
result: unknown;
|
|
34
|
+
isError?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Streaming event - fired during message streaming
|
|
38
|
+
*/
|
|
39
|
+
interface AshStreamEvent {
|
|
40
|
+
type: 'stream_start' | 'stream_delta' | 'stream_end';
|
|
41
|
+
content?: string;
|
|
42
|
+
fullContent?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Error event - fired when an error occurs
|
|
46
|
+
*/
|
|
47
|
+
interface AshErrorEvent {
|
|
48
|
+
type: 'error';
|
|
49
|
+
error: string;
|
|
50
|
+
code?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Message event - fired for complete messages
|
|
54
|
+
*/
|
|
55
|
+
interface AshMessageEvent {
|
|
56
|
+
type: 'message';
|
|
57
|
+
role: 'user' | 'assistant';
|
|
58
|
+
content: string;
|
|
59
|
+
messageId?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Todo item in a todo update
|
|
63
|
+
*/
|
|
64
|
+
interface AshTodoItem {
|
|
65
|
+
content: string;
|
|
66
|
+
status: 'pending' | 'in_progress' | 'completed';
|
|
67
|
+
activeForm: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Todo update event - fired when todos are updated
|
|
71
|
+
*/
|
|
72
|
+
interface AshTodoUpdateEvent {
|
|
73
|
+
type: 'todo_update';
|
|
74
|
+
todos: AshTodoItem[];
|
|
75
|
+
stats: {
|
|
76
|
+
total: number;
|
|
77
|
+
completed: number;
|
|
78
|
+
inProgress: number;
|
|
79
|
+
pending: number;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Union of all widget events
|
|
84
|
+
*/
|
|
85
|
+
type AshEvent = AshToolUseEvent | AshToolResultEvent | AshStreamEvent | AshErrorEvent | AshMessageEvent | AshTodoUpdateEvent;
|
|
86
|
+
/**
|
|
87
|
+
* Context data that can be pushed to the widget
|
|
88
|
+
*/
|
|
89
|
+
interface AshContextData {
|
|
90
|
+
/**
|
|
91
|
+
* Key-value pairs to include in the system context
|
|
92
|
+
*/
|
|
93
|
+
[key: string]: unknown;
|
|
94
|
+
}
|
|
95
|
+
interface AshWidgetSettings {
|
|
96
|
+
/**
|
|
97
|
+
* Base path for API calls (e.g., "https://your-api.com/api")
|
|
98
|
+
*/
|
|
99
|
+
apiBasePath: string;
|
|
100
|
+
/**
|
|
101
|
+
* Agent slug to use (optional - auto-selects first agent if not specified)
|
|
102
|
+
*/
|
|
103
|
+
agent?: string;
|
|
104
|
+
/**
|
|
105
|
+
* Widget position on the page
|
|
106
|
+
* - 'bottom-right', 'bottom-left', 'top-right', 'top-left': Floating widget in corner
|
|
107
|
+
* - 'inline' or 'embedded': Widget fills its parent container (use with containerId)
|
|
108
|
+
* @default 'bottom-right'
|
|
109
|
+
*/
|
|
110
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'inline' | 'embedded';
|
|
111
|
+
/**
|
|
112
|
+
* Container element ID for inline/embedded mode.
|
|
113
|
+
* The widget will render inside this element and fill it completely.
|
|
114
|
+
* Make sure to set a height on the container element.
|
|
115
|
+
*/
|
|
116
|
+
containerId?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Initial session ID to resume
|
|
119
|
+
*/
|
|
120
|
+
sessionId?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Whether to show the widget on load
|
|
123
|
+
* @default false (shows launcher button)
|
|
124
|
+
*/
|
|
125
|
+
open?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* Custom launcher button text
|
|
128
|
+
* @default undefined (shows icon only)
|
|
129
|
+
*/
|
|
130
|
+
launcherText?: string;
|
|
131
|
+
/**
|
|
132
|
+
* Theme customization
|
|
133
|
+
*/
|
|
134
|
+
theme?: {
|
|
135
|
+
/**
|
|
136
|
+
* Primary accent color (hex)
|
|
137
|
+
* @default '#ccff00'
|
|
138
|
+
*/
|
|
139
|
+
accentColor?: string;
|
|
140
|
+
/**
|
|
141
|
+
* Background color for widget (hex)
|
|
142
|
+
* @default '#0a0a0a'
|
|
143
|
+
*/
|
|
144
|
+
backgroundColor?: string;
|
|
145
|
+
/**
|
|
146
|
+
* Text color (hex)
|
|
147
|
+
* @default '#f3f4f6'
|
|
148
|
+
*/
|
|
149
|
+
textColor?: string;
|
|
150
|
+
/**
|
|
151
|
+
* Border radius for the widget container
|
|
152
|
+
* @default '16px'
|
|
153
|
+
*/
|
|
154
|
+
borderRadius?: string;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Widget dimensions
|
|
158
|
+
*/
|
|
159
|
+
size?: {
|
|
160
|
+
/**
|
|
161
|
+
* Width of the widget panel
|
|
162
|
+
* @default '400px'
|
|
163
|
+
*/
|
|
164
|
+
width?: string;
|
|
165
|
+
/**
|
|
166
|
+
* Height of the widget panel
|
|
167
|
+
* @default '600px'
|
|
168
|
+
*/
|
|
169
|
+
height?: string;
|
|
170
|
+
/**
|
|
171
|
+
* Maximum height (for inline mode)
|
|
172
|
+
*/
|
|
173
|
+
maxHeight?: string;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Z-index for the widget
|
|
177
|
+
* @default 2147483647 (max z-index)
|
|
178
|
+
*/
|
|
179
|
+
zIndex?: number;
|
|
180
|
+
/**
|
|
181
|
+
* Custom greeting message shown before first interaction
|
|
182
|
+
*/
|
|
183
|
+
greeting?: string;
|
|
184
|
+
/**
|
|
185
|
+
* Placeholder text for the input field
|
|
186
|
+
* @default 'Type a message...'
|
|
187
|
+
*/
|
|
188
|
+
placeholder?: string;
|
|
189
|
+
/**
|
|
190
|
+
* Callback when widget is opened
|
|
191
|
+
*/
|
|
192
|
+
onOpen?: () => void;
|
|
193
|
+
/**
|
|
194
|
+
* Callback when widget is closed
|
|
195
|
+
*/
|
|
196
|
+
onClose?: () => void;
|
|
197
|
+
/**
|
|
198
|
+
* Callback when a session starts
|
|
199
|
+
*/
|
|
200
|
+
onSessionStart?: (sessionId: string) => void;
|
|
201
|
+
/**
|
|
202
|
+
* Callback when a message is sent
|
|
203
|
+
*/
|
|
204
|
+
onMessageSent?: (message: string) => void;
|
|
205
|
+
/**
|
|
206
|
+
* Callback when a message is received
|
|
207
|
+
*/
|
|
208
|
+
onMessageReceived?: (message: string) => void;
|
|
209
|
+
/**
|
|
210
|
+
* Callback for all events (use for logging or custom handling)
|
|
211
|
+
* This is called for every event type
|
|
212
|
+
*/
|
|
213
|
+
onEvent?: (event: AshEvent) => void;
|
|
214
|
+
/**
|
|
215
|
+
* Callback when the agent uses a tool
|
|
216
|
+
*/
|
|
217
|
+
onToolUse?: (event: AshToolUseEvent) => void;
|
|
218
|
+
/**
|
|
219
|
+
* Callback when a tool returns a result
|
|
220
|
+
*/
|
|
221
|
+
onToolResult?: (event: AshToolResultEvent) => void;
|
|
222
|
+
/**
|
|
223
|
+
* Callback when streaming starts
|
|
224
|
+
*/
|
|
225
|
+
onStreamStart?: () => void;
|
|
226
|
+
/**
|
|
227
|
+
* Callback during streaming with delta content
|
|
228
|
+
*/
|
|
229
|
+
onStreamDelta?: (content: string, fullContent: string) => void;
|
|
230
|
+
/**
|
|
231
|
+
* Callback when streaming ends
|
|
232
|
+
*/
|
|
233
|
+
onStreamEnd?: (fullContent: string) => void;
|
|
234
|
+
/**
|
|
235
|
+
* Callback when an error occurs
|
|
236
|
+
*/
|
|
237
|
+
onError?: (error: string, code?: string) => void;
|
|
238
|
+
/**
|
|
239
|
+
* Callback when todos are updated (TodoWrite tool is called)
|
|
240
|
+
*/
|
|
241
|
+
onTodoUpdate?: (event: AshTodoUpdateEvent) => void;
|
|
242
|
+
/**
|
|
243
|
+
* Initial context data to include with messages
|
|
244
|
+
* This data will be sent as part of the system context
|
|
245
|
+
*/
|
|
246
|
+
context?: AshContextData;
|
|
247
|
+
/**
|
|
248
|
+
* Hide the default launcher button (for custom triggers)
|
|
249
|
+
* @default false
|
|
250
|
+
*/
|
|
251
|
+
hideLauncher?: boolean;
|
|
252
|
+
}
|
|
253
|
+
type AshCommand = ['boot', AshWidgetSettings] | ['shutdown'] | ['open'] | ['close'] | ['toggle'] | ['show'] | ['hide'] | ['showLauncher'] | ['hideLauncher'] | ['update', Partial<AshWidgetSettings>] | ['onOpen', () => void] | ['onClose', () => void] | ['onEvent', (event: AshEvent) => void] | ['setContext', AshContextData] | ['updateContext', Partial<AshContextData>] | ['clearContext'] | ['sendMessage', string] | ['sendMessageWithContext', string, AshContextData] | ['getSessionId', (sessionId: string | null) => void] | ['getContext', (context: AshContextData) => void] | ['getMessages', (messages: Array<{
|
|
254
|
+
role: string;
|
|
255
|
+
content: string;
|
|
256
|
+
}>) => void];
|
|
257
|
+
interface AshWidget {
|
|
258
|
+
(command: AshCommand[0], ...args: unknown[]): void;
|
|
259
|
+
q?: AshCommand[];
|
|
260
|
+
c?: (args: AshCommand) => void;
|
|
261
|
+
booted?: boolean;
|
|
262
|
+
}
|
|
263
|
+
declare global {
|
|
264
|
+
interface Window {
|
|
265
|
+
Ash: AshWidget;
|
|
266
|
+
AshSettings?: AshWidgetSettings;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Generate the embed snippet for a given configuration
|
|
271
|
+
*/
|
|
272
|
+
declare function generateEmbedSnippet(widgetUrl: string, settings: Partial<AshWidgetSettings>): string;
|
|
273
|
+
/**
|
|
274
|
+
* Generate a minified version of the loader
|
|
275
|
+
*/
|
|
276
|
+
declare function generateMinifiedLoader(widgetUrl: string): string;
|
|
277
|
+
|
|
278
|
+
export { type AshCommand, type AshContextData, type AshErrorEvent, type AshEvent, type AshMessageEvent, type AshStreamEvent, type AshTodoItem, type AshTodoUpdateEvent, type AshToolResultEvent, type AshToolUseEvent, type AshWidget, type AshWidgetSettings, generateEmbedSnippet, generateMinifiedLoader };
|
package/dist/embed.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/embed/loader.ts
|
|
2
|
+
function generateEmbedSnippet(widgetUrl, settings) {
|
|
3
|
+
const settingsJson = JSON.stringify(settings, null, 2);
|
|
4
|
+
return `<!-- Ash AI Widget -->
|
|
5
|
+
<script>
|
|
6
|
+
window.AshSettings = ${settingsJson};
|
|
7
|
+
(function(){var w=window;var a=w.Ash;if(typeof a==="function"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='${widgetUrl}';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();
|
|
8
|
+
</script>`;
|
|
9
|
+
}
|
|
10
|
+
function generateMinifiedLoader(widgetUrl) {
|
|
11
|
+
return `(function(){var w=window;var a=w.Ash;if(typeof a==="function"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='${widgetUrl}';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { generateEmbedSnippet, generateMinifiedLoader };
|
|
15
|
+
//# sourceMappingURL=embed.js.map
|
|
16
|
+
//# sourceMappingURL=embed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/embed/loader.ts"],"names":[],"mappings":";AA2WO,SAAS,oBAAA,CACd,WACA,QAAA,EACQ;AACR,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,MAAM,CAAC,CAAA;AAErD,EAAA,OAAO,CAAA;AAAA;AAAA,uBAAA,EAEgB,YAAY,CAAA;AAAA,iSAAA,EAC8P,SAAS,CAAA;AAAA,SAAA,CAAA;AAE5S;AAKO,SAAS,uBAAuB,SAAA,EAA2B;AAChE,EAAA,OAAO,kSAAkS,SAAS,CAAA,wNAAA,CAAA;AACpT","file":"embed.js","sourcesContent":["/**\n * Ash AI Embeddable Widget Loader\n *\n * This is the lightweight loader script that users embed on their sites.\n * It creates a command queue and asynchronously loads the full widget bundle.\n *\n * Usage:\n * ```html\n * <script>\n * window.AshSettings = {\n * apiBasePath: 'https://your-api.com/api',\n * agent: 'your-agent-slug'\n * };\n * (function(){var w=window;var a=w.Ash;if(typeof a===\"function\"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://cdn.your-domain.com/ash-widget.js';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();\n * </script>\n * ```\n */\n\n// =============================================================================\n// Event Types\n// =============================================================================\n\n/**\n * Tool use event - fired when the agent invokes a tool\n */\nexport interface AshToolUseEvent {\n type: 'tool_use';\n toolName: string;\n toolId: string;\n input: unknown;\n}\n\n/**\n * Tool result event - fired when a tool returns a result\n */\nexport interface AshToolResultEvent {\n type: 'tool_result';\n toolId: string;\n result: unknown;\n isError?: boolean;\n}\n\n/**\n * Streaming event - fired during message streaming\n */\nexport interface AshStreamEvent {\n type: 'stream_start' | 'stream_delta' | 'stream_end';\n content?: string;\n fullContent?: string;\n}\n\n/**\n * Error event - fired when an error occurs\n */\nexport interface AshErrorEvent {\n type: 'error';\n error: string;\n code?: string;\n}\n\n/**\n * Message event - fired for complete messages\n */\nexport interface AshMessageEvent {\n type: 'message';\n role: 'user' | 'assistant';\n content: string;\n messageId?: string;\n}\n\n/**\n * Todo item in a todo update\n */\nexport interface AshTodoItem {\n content: string;\n status: 'pending' | 'in_progress' | 'completed';\n activeForm: string;\n}\n\n/**\n * Todo update event - fired when todos are updated\n */\nexport interface AshTodoUpdateEvent {\n type: 'todo_update';\n todos: AshTodoItem[];\n stats: {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n };\n}\n\n/**\n * Union of all widget events\n */\nexport type AshEvent =\n | AshToolUseEvent\n | AshToolResultEvent\n | AshStreamEvent\n | AshErrorEvent\n | AshMessageEvent\n | AshTodoUpdateEvent;\n\n/**\n * Context data that can be pushed to the widget\n */\nexport interface AshContextData {\n /**\n * Key-value pairs to include in the system context\n */\n [key: string]: unknown;\n}\n\n// =============================================================================\n// Settings Interface\n// =============================================================================\n\nexport interface AshWidgetSettings {\n /**\n * Base path for API calls (e.g., \"https://your-api.com/api\")\n */\n apiBasePath: string;\n\n /**\n * Agent slug to use (optional - auto-selects first agent if not specified)\n */\n agent?: string;\n\n /**\n * Widget position on the page\n * - 'bottom-right', 'bottom-left', 'top-right', 'top-left': Floating widget in corner\n * - 'inline' or 'embedded': Widget fills its parent container (use with containerId)\n * @default 'bottom-right'\n */\n position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'inline' | 'embedded';\n\n /**\n * Container element ID for inline/embedded mode.\n * The widget will render inside this element and fill it completely.\n * Make sure to set a height on the container element.\n */\n containerId?: string;\n\n /**\n * Initial session ID to resume\n */\n sessionId?: string;\n\n /**\n * Whether to show the widget on load\n * @default false (shows launcher button)\n */\n open?: boolean;\n\n /**\n * Custom launcher button text\n * @default undefined (shows icon only)\n */\n launcherText?: string;\n\n /**\n * Theme customization\n */\n theme?: {\n /**\n * Primary accent color (hex)\n * @default '#ccff00'\n */\n accentColor?: string;\n\n /**\n * Background color for widget (hex)\n * @default '#0a0a0a'\n */\n backgroundColor?: string;\n\n /**\n * Text color (hex)\n * @default '#f3f4f6'\n */\n textColor?: string;\n\n /**\n * Border radius for the widget container\n * @default '16px'\n */\n borderRadius?: string;\n };\n\n /**\n * Widget dimensions\n */\n size?: {\n /**\n * Width of the widget panel\n * @default '400px'\n */\n width?: string;\n\n /**\n * Height of the widget panel\n * @default '600px'\n */\n height?: string;\n\n /**\n * Maximum height (for inline mode)\n */\n maxHeight?: string;\n };\n\n /**\n * Z-index for the widget\n * @default 2147483647 (max z-index)\n */\n zIndex?: number;\n\n /**\n * Custom greeting message shown before first interaction\n */\n greeting?: string;\n\n /**\n * Placeholder text for the input field\n * @default 'Type a message...'\n */\n placeholder?: string;\n\n /**\n * Callback when widget is opened\n */\n onOpen?: () => void;\n\n /**\n * Callback when widget is closed\n */\n onClose?: () => void;\n\n /**\n * Callback when a session starts\n */\n onSessionStart?: (sessionId: string) => void;\n\n /**\n * Callback when a message is sent\n */\n onMessageSent?: (message: string) => void;\n\n /**\n * Callback when a message is received\n */\n onMessageReceived?: (message: string) => void;\n\n // =========================================================================\n // Advanced Event Hooks\n // =========================================================================\n\n /**\n * Callback for all events (use for logging or custom handling)\n * This is called for every event type\n */\n onEvent?: (event: AshEvent) => void;\n\n /**\n * Callback when the agent uses a tool\n */\n onToolUse?: (event: AshToolUseEvent) => void;\n\n /**\n * Callback when a tool returns a result\n */\n onToolResult?: (event: AshToolResultEvent) => void;\n\n /**\n * Callback when streaming starts\n */\n onStreamStart?: () => void;\n\n /**\n * Callback during streaming with delta content\n */\n onStreamDelta?: (content: string, fullContent: string) => void;\n\n /**\n * Callback when streaming ends\n */\n onStreamEnd?: (fullContent: string) => void;\n\n /**\n * Callback when an error occurs\n */\n onError?: (error: string, code?: string) => void;\n\n /**\n * Callback when todos are updated (TodoWrite tool is called)\n */\n onTodoUpdate?: (event: AshTodoUpdateEvent) => void;\n\n // =========================================================================\n // Context & Data\n // =========================================================================\n\n /**\n * Initial context data to include with messages\n * This data will be sent as part of the system context\n */\n context?: AshContextData;\n\n /**\n * Hide the default launcher button (for custom triggers)\n * @default false\n */\n hideLauncher?: boolean;\n}\n\nexport type AshCommand =\n // Lifecycle commands\n | ['boot', AshWidgetSettings]\n | ['shutdown']\n // Visibility commands\n | ['open']\n | ['close']\n | ['toggle']\n | ['show']\n | ['hide']\n | ['showLauncher']\n | ['hideLauncher']\n // Configuration commands\n | ['update', Partial<AshWidgetSettings>]\n // Event listener commands\n | ['onOpen', () => void]\n | ['onClose', () => void]\n | ['onEvent', (event: AshEvent) => void]\n // Data/Context commands\n | ['setContext', AshContextData]\n | ['updateContext', Partial<AshContextData>]\n | ['clearContext']\n // Message commands\n | ['sendMessage', string]\n | ['sendMessageWithContext', string, AshContextData]\n // Query commands (returns via callback)\n | ['getSessionId', (sessionId: string | null) => void]\n | ['getContext', (context: AshContextData) => void]\n | ['getMessages', (messages: Array<{ role: string; content: string }>) => void];\n\nexport interface AshWidget {\n (command: AshCommand[0], ...args: unknown[]): void;\n q?: AshCommand[];\n c?: (args: AshCommand) => void;\n booted?: boolean;\n}\n\ndeclare global {\n interface Window {\n Ash: AshWidget;\n AshSettings?: AshWidgetSettings;\n }\n}\n\n/**\n * Generate the embed snippet for a given configuration\n */\nexport function generateEmbedSnippet(\n widgetUrl: string,\n settings: Partial<AshWidgetSettings>\n): string {\n const settingsJson = JSON.stringify(settings, null, 2);\n\n return `<!-- Ash AI Widget -->\n<script>\n window.AshSettings = ${settingsJson};\n (function(){var w=window;var a=w.Ash;if(typeof a===\"function\"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='${widgetUrl}';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();\n</script>`;\n}\n\n/**\n * Generate a minified version of the loader\n */\nexport function generateMinifiedLoader(widgetUrl: string): string {\n return `(function(){var w=window;var a=w.Ash;if(typeof a===\"function\"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='${widgetUrl}';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();`;\n}\n"]}
|