@tylertech/forge-ai 0.4.0 → 0.5.0

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 (129) hide show
  1. package/custom-elements.json +4691 -637
  2. package/dist/ai-actions-toolbar/ai-actions-toolbar.d.ts +24 -1
  3. package/dist/ai-actions-toolbar/ai-actions-toolbar.mjs +171 -42
  4. package/dist/ai-actions-toolbar/ai-actions-toolbar.scss.mjs +1 -1
  5. package/dist/ai-agent-info/ai-agent-info.d.ts +29 -0
  6. package/dist/ai-agent-info/ai-agent-info.mjs +123 -0
  7. package/dist/ai-agent-info/ai-agent-info.scss.mjs +4 -0
  8. package/dist/ai-agent-info/index.d.ts +1 -0
  9. package/dist/ai-agent-info/index.mjs +5 -0
  10. package/dist/ai-artifact/ai-artifact.scss.mjs +1 -1
  11. package/dist/ai-attachment/ai-attachment.d.ts +39 -0
  12. package/dist/ai-attachment/ai-attachment.mjs +130 -0
  13. package/dist/ai-attachment/ai-attachment.scss.mjs +4 -0
  14. package/dist/ai-attachment/index.d.ts +1 -0
  15. package/dist/ai-attachment/index.mjs +5 -0
  16. package/dist/ai-button/ai-button.mjs +1 -0
  17. package/dist/ai-button/ai-button.scss.mjs +1 -1
  18. package/dist/ai-chain-of-thought/thought-base/thought-base.scss.mjs +1 -1
  19. package/dist/ai-chat-header/ai-chat-header.d.ts +35 -17
  20. package/dist/ai-chat-header/ai-chat-header.mjs +130 -30
  21. package/dist/ai-chat-header/ai-chat-header.scss.mjs +1 -1
  22. package/dist/ai-chat-header/index.d.ts +1 -0
  23. package/dist/ai-chat-interface/ai-chat-interface.d.ts +2 -4
  24. package/dist/ai-chat-interface/ai-chat-interface.mjs +24 -28
  25. package/dist/ai-chat-interface/ai-chat-interface.scss.mjs +1 -1
  26. package/dist/ai-chatbot/ag-ui-adapter.d.ts +22 -0
  27. package/dist/ai-chatbot/ag-ui-adapter.mjs +331 -0
  28. package/dist/ai-chatbot/agent-adapter.d.ts +125 -0
  29. package/dist/ai-chatbot/agent-adapter.mjs +136 -0
  30. package/dist/ai-chatbot/agent-runner.d.ts +41 -0
  31. package/dist/ai-chatbot/agent-runner.mjs +264 -0
  32. package/dist/ai-chatbot/ai-chatbot-tool-call.d.ts +21 -0
  33. package/dist/ai-chatbot/ai-chatbot-tool-call.mjs +189 -0
  34. package/dist/ai-chatbot/ai-chatbot-tool-call.scss.mjs +4 -0
  35. package/dist/ai-chatbot/ai-chatbot.d.ts +133 -0
  36. package/dist/ai-chatbot/ai-chatbot.mjs +755 -0
  37. package/dist/ai-chatbot/ai-chatbot.scss.mjs +4 -0
  38. package/dist/ai-chatbot/create-tool-renderer.d.ts +12 -0
  39. package/dist/ai-chatbot/create-tool-renderer.mjs +28 -0
  40. package/dist/ai-chatbot/event-emitter.d.ts +43 -0
  41. package/dist/ai-chatbot/event-emitter.mjs +81 -0
  42. package/dist/ai-chatbot/file-upload-manager.d.ts +27 -0
  43. package/dist/ai-chatbot/file-upload-manager.mjs +106 -0
  44. package/dist/ai-chatbot/http-agent-with-credentials.d.ts +8 -0
  45. package/dist/ai-chatbot/http-agent-with-credentials.mjs +14 -0
  46. package/dist/ai-chatbot/index.d.ts +15 -0
  47. package/dist/ai-chatbot/index.mjs +30 -0
  48. package/dist/ai-chatbot/markdown-stream-controller.d.ts +13 -0
  49. package/dist/ai-chatbot/markdown-stream-controller.mjs +49 -0
  50. package/dist/ai-chatbot/message-state-controller.d.ts +45 -0
  51. package/dist/ai-chatbot/message-state-controller.mjs +168 -0
  52. package/dist/ai-chatbot/types.d.ts +120 -0
  53. package/dist/ai-chatbot/utils.d.ts +12 -0
  54. package/dist/ai-chatbot/utils.mjs +31 -0
  55. package/dist/ai-confirmation-prompt/ai-confirmation-prompt.d.ts +28 -0
  56. package/dist/ai-confirmation-prompt/ai-confirmation-prompt.mjs +89 -0
  57. package/dist/ai-confirmation-prompt/ai-confirmation-prompt.scss.mjs +4 -0
  58. package/dist/ai-confirmation-prompt/index.d.ts +1 -0
  59. package/dist/ai-confirmation-prompt/index.mjs +5 -0
  60. package/dist/ai-dialog/ai-dialog.scss.mjs +1 -1
  61. package/dist/ai-dropdown-menu/ai-dropdown-menu-item.d.ts +0 -6
  62. package/dist/ai-dropdown-menu/ai-dropdown-menu-item.mjs +3 -16
  63. package/dist/ai-dropdown-menu/ai-dropdown-menu-item.scss.mjs +1 -1
  64. package/dist/ai-dropdown-menu/ai-dropdown-menu.d.ts +6 -0
  65. package/dist/ai-dropdown-menu/ai-dropdown-menu.mjs +6 -2
  66. package/dist/ai-dropdown-menu/ai-dropdown-menu.scss.mjs +1 -1
  67. package/dist/ai-embedded-chat/ai-embedded-chat.d.ts +18 -5
  68. package/dist/ai-embedded-chat/ai-embedded-chat.mjs +43 -18
  69. package/dist/ai-empty-state/ai-empty-state.d.ts +4 -2
  70. package/dist/ai-empty-state/ai-empty-state.mjs +237 -57
  71. package/dist/ai-empty-state/ai-empty-state.scss.mjs +1 -1
  72. package/dist/ai-error-message/ai-error-message.d.ts +19 -0
  73. package/dist/ai-error-message/ai-error-message.mjs +44 -0
  74. package/dist/ai-error-message/ai-error-message.scss.mjs +4 -0
  75. package/dist/ai-error-message/index.d.ts +1 -0
  76. package/dist/ai-error-message/index.mjs +5 -0
  77. package/dist/ai-fab/ai-fab.scss.mjs +1 -1
  78. package/dist/ai-file-picker/ai-file-picker.d.ts +20 -1
  79. package/dist/ai-file-picker/ai-file-picker.mjs +67 -20
  80. package/dist/ai-file-picker/ai-file-picker.scss.mjs +1 -1
  81. package/dist/ai-file-picker/index.d.ts +1 -1
  82. package/dist/ai-floating-chat/ai-floating-chat.d.ts +5 -30
  83. package/dist/ai-floating-chat/ai-floating-chat.mjs +19 -42
  84. package/dist/ai-message-thread/ai-message-thread.d.ts +58 -0
  85. package/dist/ai-message-thread/ai-message-thread.mjs +224 -0
  86. package/dist/ai-message-thread/ai-message-thread.scss.mjs +4 -0
  87. package/dist/ai-message-thread/index.d.ts +2 -0
  88. package/dist/ai-message-thread/index.mjs +5 -0
  89. package/dist/ai-modal/ai-modal.d.ts +6 -0
  90. package/dist/ai-modal/ai-modal.mjs +31 -14
  91. package/dist/ai-modal/ai-modal.scss.mjs +1 -1
  92. package/dist/ai-prompt/ai-prompt.mjs +3 -6
  93. package/dist/ai-prompt/ai-prompt.scss.mjs +1 -1
  94. package/dist/ai-prompt/prompt-button/prompt-button.scss.mjs +1 -1
  95. package/dist/ai-response-message/ai-response-message.d.ts +12 -21
  96. package/dist/ai-response-message/ai-response-message.mjs +32 -89
  97. package/dist/ai-response-message/ai-response-message.scss.mjs +1 -1
  98. package/dist/ai-sidebar/ai-sidebar.mjs +1 -1
  99. package/dist/ai-sidebar-chat/ai-sidebar-chat.d.ts +5 -29
  100. package/dist/ai-sidebar-chat/ai-sidebar-chat.mjs +23 -43
  101. package/dist/ai-spinner/ai-spinner.d.ts +24 -0
  102. package/dist/ai-spinner/ai-spinner.mjs +41 -0
  103. package/dist/ai-spinner/ai-spinner.scss.mjs +4 -0
  104. package/dist/ai-spinner/index.d.ts +1 -0
  105. package/dist/ai-spinner/index.mjs +5 -0
  106. package/dist/ai-suggestions/ai-suggestions.d.ts +2 -0
  107. package/dist/ai-suggestions/ai-suggestions.mjs +66 -7
  108. package/dist/ai-suggestions/ai-suggestions.scss.mjs +1 -1
  109. package/dist/ai-suggestions/index.d.ts +2 -1
  110. package/dist/ai-thinking-indicator/ai-thinking-indicator.d.ts +3 -1
  111. package/dist/ai-thinking-indicator/ai-thinking-indicator.mjs +83 -3
  112. package/dist/ai-thinking-indicator/ai-thinking-indicator.scss.mjs +317 -1
  113. package/dist/ai-threads/ai-threads.d.ts +9 -4
  114. package/dist/ai-threads/ai-threads.mjs +21 -41
  115. package/dist/ai-threads/ai-threads.scss.mjs +1 -1
  116. package/dist/ai-user-message/ai-user-message.scss.mjs +1 -1
  117. package/dist/ai-voice-input/ai-voice-input.scss.mjs +1 -1
  118. package/dist/core/drag-controller.mjs +3 -0
  119. package/dist/core/overlay/overlay.d.ts +10 -0
  120. package/dist/core/overlay/overlay.mjs +24 -4
  121. package/dist/core/popover/popover.d.ts +17 -7
  122. package/dist/core/popover/popover.mjs +17 -3
  123. package/dist/core/popover/popover.scss.mjs +1 -1
  124. package/dist/core/tooltip/tooltip.d.ts +8 -7
  125. package/dist/core/tooltip/tooltip.mjs +45 -16
  126. package/dist/core/tooltip/tooltip.scss.mjs +1 -1
  127. package/dist/index.d.ts +10 -4
  128. package/dist/index.mjs +52 -9
  129. package/package.json +64 -60
@@ -0,0 +1,331 @@
1
+ import { HttpAgentWithCredentials } from "./http-agent-with-credentials.mjs";
2
+ import { AgentAdapter } from "./agent-adapter.mjs";
3
+ import { generateId } from "./utils.mjs";
4
+ class AgUiAdapter extends AgentAdapter {
5
+ #config;
6
+ #agent;
7
+ #toolCalls = /* @__PURE__ */ new Map();
8
+ #threadId;
9
+ #textBuffers = /* @__PURE__ */ new Map();
10
+ constructor(config, threadId) {
11
+ super();
12
+ this.#config = config;
13
+ this.#threadId = threadId ?? generateId("thread");
14
+ this.#agent = new HttpAgentWithCredentials({
15
+ url: config.url,
16
+ headers: config.headers
17
+ });
18
+ this.#agent.threadId = this.#threadId;
19
+ if (config.tools) {
20
+ this.setTools(config.tools);
21
+ }
22
+ this.#setupSubscriber();
23
+ }
24
+ get threadId() {
25
+ return this.#threadId;
26
+ }
27
+ set threadId(value) {
28
+ this.#threadId = value;
29
+ this.#agent.threadId = value;
30
+ }
31
+ static async create(config) {
32
+ const { threadId, ...adapterConfig } = config;
33
+ const adapter = new AgUiAdapter(adapterConfig, threadId ?? generateId("thread"));
34
+ await adapter.connect();
35
+ return adapter;
36
+ }
37
+ async connect() {
38
+ if (this._state.isConnecting || this._state.isConnected) {
39
+ return;
40
+ }
41
+ this._updateState({ isConnecting: true, isConnected: true });
42
+ await Promise.resolve();
43
+ this._updateState({ isConnecting: false });
44
+ }
45
+ async disconnect() {
46
+ this.abort();
47
+ this._updateState({ isConnected: false });
48
+ }
49
+ sendMessage(messages) {
50
+ if (!this._state.isConnected) {
51
+ throw new Error("Adapter not connected. Call connect() first.");
52
+ }
53
+ const transformedMessages = this.#transformMessages(messages);
54
+ const context = this.#config.context ? this.#transformContext(this.#config.context) : void 0;
55
+ this.#agent.setMessages(transformedMessages);
56
+ const tools = this.#transformTools(this._tools);
57
+ this.#agent.runAgent({ tools, context });
58
+ }
59
+ sendToolResult(toolCallId, result, messages) {
60
+ const toolMessage = {
61
+ id: generateId("tool"),
62
+ role: "tool",
63
+ content: JSON.stringify(result),
64
+ timestamp: Date.now(),
65
+ status: "complete",
66
+ toolCallId
67
+ };
68
+ messages = messages ? [...messages, toolMessage] : [toolMessage];
69
+ this.sendMessage(messages);
70
+ this._emitToolResult({ toolCallId, result, message: toolMessage });
71
+ }
72
+ abort() {
73
+ if (this._state.isRunning) {
74
+ try {
75
+ this.#agent.abortRun();
76
+ } catch {
77
+ }
78
+ }
79
+ this.#clearRunState();
80
+ }
81
+ #setupSubscriber() {
82
+ const subscriber = {
83
+ onRunInitialized: this.#handleRunInitialized.bind(this),
84
+ onTextMessageStartEvent: this.#handleTextMessageStart.bind(this),
85
+ onTextMessageContentEvent: this.#handleTextMessageContent.bind(this),
86
+ onTextMessageEndEvent: this.#handleTextMessageEnd.bind(this),
87
+ onToolCallStartEvent: this.#handleToolCallStart.bind(this),
88
+ onToolCallArgsEvent: this.#handleToolCallArgs.bind(this),
89
+ onToolCallEndEvent: this.#handleToolCallEnd.bind(this),
90
+ onToolCallResultEvent: this.#handleToolCallResult.bind(this),
91
+ onRunFinishedEvent: this.#handleRunFinished.bind(this),
92
+ onRunErrorEvent: this.#handleRunError.bind(this),
93
+ onRunFailed: this.#handleRunFailed.bind(this)
94
+ };
95
+ this.#agent.subscribe(subscriber);
96
+ }
97
+ #handleRunInitialized() {
98
+ this._updateState({ isRunning: true });
99
+ this._emitRunStarted();
100
+ }
101
+ #handleTextMessageStart({ event }) {
102
+ this._emitMessageStart(event.messageId);
103
+ }
104
+ #handleTextMessageContent({
105
+ textMessageBuffer,
106
+ event
107
+ }) {
108
+ this.#processTextDelta(event.messageId, textMessageBuffer, false);
109
+ }
110
+ #handleTextMessageEnd({
111
+ textMessageBuffer,
112
+ event
113
+ }) {
114
+ this.#processTextDelta(event.messageId, textMessageBuffer, true);
115
+ this._emitMessageEnd(event.messageId);
116
+ }
117
+ #handleToolCallStart({
118
+ event
119
+ }) {
120
+ const toolCallState = {
121
+ messageId: event.parentMessageId || "",
122
+ name: event.toolCallName,
123
+ argsBuffer: ""
124
+ };
125
+ this.#toolCalls.set(event.toolCallId, toolCallState);
126
+ this._emitToolCallStart({
127
+ id: event.toolCallId,
128
+ messageId: toolCallState.messageId,
129
+ name: toolCallState.name
130
+ });
131
+ }
132
+ #handleToolCallArgs({
133
+ event,
134
+ partialToolCallArgs,
135
+ toolCallBuffer
136
+ }) {
137
+ const toolCall = this.#getToolCallOrWarn(event.toolCallId);
138
+ if (!toolCall) {
139
+ return;
140
+ }
141
+ if (partialToolCallArgs && Object.keys(partialToolCallArgs).length) {
142
+ toolCall.argsBuffer = JSON.stringify(partialToolCallArgs);
143
+ } else {
144
+ toolCall.argsBuffer = toolCallBuffer;
145
+ }
146
+ this._emitToolCallArgs({
147
+ id: event.toolCallId,
148
+ messageId: toolCall.messageId,
149
+ name: toolCall.name,
150
+ argsBuffer: toolCall.argsBuffer,
151
+ partialArgs: partialToolCallArgs
152
+ });
153
+ }
154
+ #handleToolCallEnd({
155
+ event,
156
+ toolCallArgs
157
+ }) {
158
+ const toolCall = this.#getToolCallOrWarn(event.toolCallId);
159
+ if (!toolCall) {
160
+ return;
161
+ }
162
+ const args = toolCallArgs || {};
163
+ const toolDef = this.#findToolDefinition(toolCall.name);
164
+ if (toolDef) {
165
+ const validationError = this.#validateToolArgs(toolCall.name, args, toolDef);
166
+ if (validationError) {
167
+ this._emitError(validationError);
168
+ this.#toolCalls.delete(event.toolCallId);
169
+ return;
170
+ }
171
+ }
172
+ const toolCallEvent = {
173
+ id: event.toolCallId,
174
+ messageId: toolCall.messageId,
175
+ name: toolCall.name,
176
+ args
177
+ };
178
+ this._emitToolCallEnd(toolCallEvent);
179
+ this._emitToolCall(toolCallEvent);
180
+ this.#toolCalls.delete(event.toolCallId);
181
+ }
182
+ #handleToolCallResult({ event }) {
183
+ const result = JSON.parse(event.content);
184
+ const toolMessage = {
185
+ id: generateId("tool"),
186
+ role: "tool",
187
+ content: event.content,
188
+ timestamp: Date.now(),
189
+ status: "complete",
190
+ toolCallId: event.toolCallId
191
+ };
192
+ this._emitToolResult({
193
+ toolCallId: event.toolCallId,
194
+ result,
195
+ message: toolMessage
196
+ });
197
+ }
198
+ #handleRunFinished() {
199
+ this.#clearRunState();
200
+ this._emitRunFinished();
201
+ }
202
+ #handleRunError({ event }) {
203
+ if (event.rawEvent?.name === "AbortError") {
204
+ this.#clearRunState();
205
+ this._emitRunAborted();
206
+ return;
207
+ }
208
+ this._emitError(event.message || "Unknown error");
209
+ this._updateState({ isRunning: false });
210
+ }
211
+ #handleRunFailed() {
212
+ this.#clearRunState();
213
+ this._emitError("An unexpected error occurred. Please try again.");
214
+ }
215
+ #processTextDelta(messageId, buffer, isFinal) {
216
+ const previousBuffer = this.#textBuffers.get(messageId) ?? "";
217
+ const delta = buffer.slice(previousBuffer.length);
218
+ if (delta.length) {
219
+ this._emitMessageDelta(messageId, delta);
220
+ }
221
+ if (isFinal) {
222
+ this.#textBuffers.delete(messageId);
223
+ } else {
224
+ this.#textBuffers.set(messageId, buffer);
225
+ }
226
+ }
227
+ #getToolCallOrWarn(toolCallId) {
228
+ const toolCall = this.#toolCalls.get(toolCallId);
229
+ if (!toolCall) {
230
+ console.warn(`Tool call ${toolCallId} not found in state`);
231
+ }
232
+ return toolCall ?? null;
233
+ }
234
+ #findToolDefinition(name) {
235
+ return this._tools?.find((t) => t.name === name);
236
+ }
237
+ #clearRunState() {
238
+ this.#toolCalls.clear();
239
+ this.#textBuffers.clear();
240
+ this._updateState({ isRunning: false });
241
+ }
242
+ #transformTools(tools) {
243
+ if (!tools || tools.length === 0) {
244
+ return void 0;
245
+ }
246
+ return tools.map((tool) => {
247
+ const agUiTool = {
248
+ name: tool.name,
249
+ description: tool.description ?? "",
250
+ parameters: tool.parameters
251
+ };
252
+ return agUiTool;
253
+ });
254
+ }
255
+ #transformContext(context) {
256
+ return Object.entries(context).map(([key, value]) => ({
257
+ description: `Client context: ${key}`,
258
+ value: typeof value === "string" ? value : JSON.stringify(value)
259
+ }));
260
+ }
261
+ #transformMessages(messages) {
262
+ return messages.filter((msg) => msg.role === "user" || msg.role === "assistant" || msg.role === "system" || msg.role === "tool").filter((msg) => {
263
+ if (msg.role === "assistant") {
264
+ return msg.content.trim().length > 0 || msg.toolCalls && msg.toolCalls.length > 0;
265
+ }
266
+ return true;
267
+ }).map((msg) => {
268
+ switch (msg.role) {
269
+ case "user": {
270
+ const userMsg = {
271
+ id: msg.id,
272
+ role: "user",
273
+ content: msg.content
274
+ };
275
+ return userMsg;
276
+ }
277
+ case "assistant": {
278
+ const assistantMsg = {
279
+ id: msg.id,
280
+ role: "assistant",
281
+ content: msg.content || ""
282
+ };
283
+ if (msg.toolCalls && msg.toolCalls.length) {
284
+ assistantMsg.toolCalls = msg.toolCalls.map((tc) => ({
285
+ id: tc.id,
286
+ type: "function",
287
+ function: {
288
+ name: tc.name,
289
+ arguments: JSON.stringify(tc.args)
290
+ }
291
+ }));
292
+ }
293
+ return assistantMsg;
294
+ }
295
+ case "system": {
296
+ const systemMsg = {
297
+ id: msg.id,
298
+ role: "system",
299
+ content: msg.content
300
+ };
301
+ return systemMsg;
302
+ }
303
+ case "tool": {
304
+ const toolMsg = {
305
+ id: msg.id,
306
+ role: "tool",
307
+ toolCallId: msg.toolCallId || "",
308
+ content: msg.content
309
+ };
310
+ return toolMsg;
311
+ }
312
+ }
313
+ });
314
+ }
315
+ #validateToolArgs(toolName, args, toolDef) {
316
+ const { parameters } = toolDef;
317
+ if (!parameters || parameters.type !== "object") {
318
+ return null;
319
+ }
320
+ const required = parameters.required || [];
321
+ for (const field of required) {
322
+ if (!(field in args)) {
323
+ return `Tool ${toolName} missing required parameter: ${field}`;
324
+ }
325
+ }
326
+ return null;
327
+ }
328
+ }
329
+ export {
330
+ AgUiAdapter
331
+ };
@@ -0,0 +1,125 @@
1
+ import { ChatMessage, FileUploadCallbacks, ToolDefinition } from './types.js';
2
+ import { EventEmitter, Subscription } from './event-emitter.js';
3
+ export interface MessageStartEvent {
4
+ messageId: string;
5
+ }
6
+ export interface MessageDeltaEvent {
7
+ messageId: string;
8
+ delta: string;
9
+ }
10
+ export interface MessageEndEvent {
11
+ messageId: string;
12
+ }
13
+ export interface ToolCallEvent {
14
+ id: string;
15
+ messageId: string;
16
+ name: string;
17
+ args: Record<string, unknown>;
18
+ }
19
+ export interface ToolCallStartEvent {
20
+ id: string;
21
+ messageId: string;
22
+ name: string;
23
+ }
24
+ export interface ToolCallArgsEvent {
25
+ id: string;
26
+ messageId: string;
27
+ name: string;
28
+ argsBuffer: string;
29
+ partialArgs?: Record<string, unknown>;
30
+ }
31
+ export interface ToolCallEndEvent {
32
+ id: string;
33
+ messageId: string;
34
+ name: string;
35
+ args: Record<string, unknown>;
36
+ }
37
+ export interface ToolResultEvent {
38
+ toolCallId: string;
39
+ result: unknown;
40
+ message: ChatMessage;
41
+ }
42
+ export interface AdapterState {
43
+ isConnected: boolean;
44
+ isConnecting: boolean;
45
+ isRunning: boolean;
46
+ }
47
+ export interface FileUploadEvent extends FileUploadCallbacks {
48
+ file: File;
49
+ }
50
+ export interface FileRemoveEvent {
51
+ fileId: string;
52
+ onSuccess: () => void;
53
+ onError: (error: string) => void;
54
+ }
55
+ export interface ErrorEvent {
56
+ message: string;
57
+ }
58
+ export declare abstract class AgentAdapter {
59
+ protected _state: AdapterState;
60
+ protected _tools: ToolDefinition[];
61
+ protected _events: {
62
+ runStarted: EventEmitter<void>;
63
+ runFinished: EventEmitter<void>;
64
+ runAborted: EventEmitter<void>;
65
+ messageStart: EventEmitter<MessageStartEvent>;
66
+ messageDelta: EventEmitter<MessageDeltaEvent>;
67
+ messageEnd: EventEmitter<MessageEndEvent>;
68
+ toolCall: EventEmitter<ToolCallEvent>;
69
+ toolCallStart: EventEmitter<ToolCallStartEvent>;
70
+ toolCallArgs: EventEmitter<ToolCallArgsEvent>;
71
+ toolCallEnd: EventEmitter<ToolCallEndEvent>;
72
+ toolResult: EventEmitter<ToolResultEvent>;
73
+ fileUpload: EventEmitter<FileUploadEvent>;
74
+ fileRemove: EventEmitter<FileRemoveEvent>;
75
+ error: EventEmitter<ErrorEvent>;
76
+ stateChange: EventEmitter<AdapterState>;
77
+ };
78
+ abstract connect(): Promise<void>;
79
+ abstract disconnect(): Promise<void>;
80
+ abstract sendMessage(messages: ChatMessage[]): void;
81
+ abstract sendToolResult(toolCallId: string, result: unknown, messages: ChatMessage[]): void;
82
+ abstract abort(): void;
83
+ abstract get threadId(): string;
84
+ abstract set threadId(value: string);
85
+ clearMemory?(): Promise<void>;
86
+ setTools(tools: ToolDefinition[]): void;
87
+ getTools(): ToolDefinition[];
88
+ getState(): AdapterState;
89
+ get isConnected(): boolean;
90
+ get isConnecting(): boolean;
91
+ get isRunning(): boolean;
92
+ onRunStarted(callback: () => void): Subscription;
93
+ onRunFinished(callback: () => void): Subscription;
94
+ onRunAborted(callback: () => void): Subscription;
95
+ onMessageStart(callback: (event: MessageStartEvent) => void): Subscription;
96
+ onMessageDelta(callback: (event: MessageDeltaEvent) => void): Subscription;
97
+ onMessageEnd(callback: (event: MessageEndEvent) => void): Subscription;
98
+ onToolCall(callback: (event: ToolCallEvent) => void): Subscription;
99
+ onToolCallStart(callback: (event: ToolCallStartEvent) => void): Subscription;
100
+ onToolCallArgs(callback: (event: ToolCallArgsEvent) => void): Subscription;
101
+ onToolCallEnd(callback: (event: ToolCallEndEvent) => void): Subscription;
102
+ onToolCallResult(callback: (event: ToolResultEvent) => void): Subscription;
103
+ onFileUpload(callback: (event: FileUploadEvent) => void): Subscription;
104
+ onFileRemove(callback: (event: FileRemoveEvent) => void): Subscription;
105
+ onError(callback: (event: ErrorEvent) => void): Subscription;
106
+ onStateChange(callback: (state: AdapterState) => void): Subscription;
107
+ protected _emitRunStarted(): void;
108
+ protected _emitRunFinished(): void;
109
+ protected _emitRunAborted(): void;
110
+ protected _emitMessageStart(messageId: string): void;
111
+ protected _emitMessageDelta(messageId: string, delta: string): void;
112
+ protected _emitMessageEnd(messageId: string): void;
113
+ protected _emitToolCall(event: ToolCallEvent): void;
114
+ protected _emitToolCallStart(event: ToolCallStartEvent): void;
115
+ protected _emitToolCallArgs(event: ToolCallArgsEvent): void;
116
+ protected _emitToolCallEnd(event: ToolCallEndEvent): void;
117
+ protected _emitToolResult(event: ToolResultEvent): void;
118
+ emitFileUpload(file: File, callbacks: FileUploadCallbacks): void;
119
+ emitFileRemove(fileId: string, callbacks: {
120
+ onSuccess: () => void;
121
+ onError: (error: string) => void;
122
+ }): void;
123
+ protected _emitError(message: string): void;
124
+ protected _updateState(updates: Partial<AdapterState>): void;
125
+ }
@@ -0,0 +1,136 @@
1
+ import { EventEmitter } from "./event-emitter.mjs";
2
+ class AgentAdapter {
3
+ constructor() {
4
+ this._state = { isConnected: false, isConnecting: false, isRunning: false };
5
+ this._tools = [];
6
+ this._events = {
7
+ runStarted: new EventEmitter(),
8
+ runFinished: new EventEmitter(),
9
+ runAborted: new EventEmitter(),
10
+ messageStart: new EventEmitter(),
11
+ messageDelta: new EventEmitter(),
12
+ messageEnd: new EventEmitter(),
13
+ toolCall: new EventEmitter(),
14
+ toolCallStart: new EventEmitter(),
15
+ toolCallArgs: new EventEmitter(),
16
+ toolCallEnd: new EventEmitter(),
17
+ toolResult: new EventEmitter(),
18
+ fileUpload: new EventEmitter(),
19
+ fileRemove: new EventEmitter(),
20
+ error: new EventEmitter(),
21
+ stateChange: new EventEmitter()
22
+ };
23
+ }
24
+ setTools(tools) {
25
+ this._tools = tools;
26
+ }
27
+ getTools() {
28
+ return [...this._tools];
29
+ }
30
+ getState() {
31
+ return { ...this._state };
32
+ }
33
+ get isConnected() {
34
+ return this._state.isConnected;
35
+ }
36
+ get isConnecting() {
37
+ return this._state.isConnecting;
38
+ }
39
+ get isRunning() {
40
+ return this._state.isRunning;
41
+ }
42
+ onRunStarted(callback) {
43
+ return this._events.runStarted.subscribe(callback);
44
+ }
45
+ onRunFinished(callback) {
46
+ return this._events.runFinished.subscribe(callback);
47
+ }
48
+ onRunAborted(callback) {
49
+ return this._events.runAborted.subscribe(callback);
50
+ }
51
+ onMessageStart(callback) {
52
+ return this._events.messageStart.subscribe(callback);
53
+ }
54
+ onMessageDelta(callback) {
55
+ return this._events.messageDelta.subscribe(callback);
56
+ }
57
+ onMessageEnd(callback) {
58
+ return this._events.messageEnd.subscribe(callback);
59
+ }
60
+ onToolCall(callback) {
61
+ return this._events.toolCall.subscribe(callback);
62
+ }
63
+ onToolCallStart(callback) {
64
+ return this._events.toolCallStart.subscribe(callback);
65
+ }
66
+ onToolCallArgs(callback) {
67
+ return this._events.toolCallArgs.subscribe(callback);
68
+ }
69
+ onToolCallEnd(callback) {
70
+ return this._events.toolCallEnd.subscribe(callback);
71
+ }
72
+ onToolCallResult(callback) {
73
+ return this._events.toolResult.subscribe(callback);
74
+ }
75
+ onFileUpload(callback) {
76
+ return this._events.fileUpload.subscribe(callback);
77
+ }
78
+ onFileRemove(callback) {
79
+ return this._events.fileRemove.subscribe(callback);
80
+ }
81
+ onError(callback) {
82
+ return this._events.error.subscribe(callback);
83
+ }
84
+ onStateChange(callback) {
85
+ return this._events.stateChange.subscribe(callback);
86
+ }
87
+ _emitRunStarted() {
88
+ this._events.runStarted.emit();
89
+ }
90
+ _emitRunFinished() {
91
+ this._events.runFinished.emit();
92
+ }
93
+ _emitRunAborted() {
94
+ this._events.runAborted.emit();
95
+ }
96
+ _emitMessageStart(messageId) {
97
+ this._events.messageStart.emit({ messageId });
98
+ }
99
+ _emitMessageDelta(messageId, delta) {
100
+ this._events.messageDelta.emit({ messageId, delta });
101
+ }
102
+ _emitMessageEnd(messageId) {
103
+ this._events.messageEnd.emit({ messageId });
104
+ }
105
+ _emitToolCall(event) {
106
+ this._events.toolCall.emit(event);
107
+ }
108
+ _emitToolCallStart(event) {
109
+ this._events.toolCallStart.emit(event);
110
+ }
111
+ _emitToolCallArgs(event) {
112
+ this._events.toolCallArgs.emit(event);
113
+ }
114
+ _emitToolCallEnd(event) {
115
+ this._events.toolCallEnd.emit(event);
116
+ }
117
+ _emitToolResult(event) {
118
+ this._events.toolResult.emit(event);
119
+ }
120
+ emitFileUpload(file, callbacks) {
121
+ this._events.fileUpload.emit({ file, ...callbacks });
122
+ }
123
+ emitFileRemove(fileId, callbacks) {
124
+ this._events.fileRemove.emit({ fileId, ...callbacks });
125
+ }
126
+ _emitError(message) {
127
+ this._events.error.emit({ message });
128
+ }
129
+ _updateState(updates) {
130
+ this._state = { ...this._state, ...updates };
131
+ this._events.stateChange.emit(this.getState());
132
+ }
133
+ }
134
+ export {
135
+ AgentAdapter
136
+ };
@@ -0,0 +1,41 @@
1
+ import { AgentAdapter } from './agent-adapter.js';
2
+ import { ChatMessage, ToolCall, ToolDefinition } from './types.js';
3
+ export interface AgentRunnerConfig {
4
+ /** The adapter instance that handles communication with the AI model */
5
+ adapter: AgentAdapter;
6
+ /** The user prompt to send to the agent */
7
+ prompt: string;
8
+ /** Optional tools the agent can call during execution */
9
+ tools?: ToolDefinition[];
10
+ /** Execution mode: 'one-shot' stops after first response, 'multi-turn' allows tool usage loops. @default 'one-shot' */
11
+ mode?: 'one-shot' | 'multi-turn';
12
+ /** Maximum conversation turns in multi-turn mode to prevent infinite loops. @default 20 */
13
+ maxTurns?: number;
14
+ /** Callback fired when agent starts generating a new message */
15
+ onStart?: (messageId: string) => void;
16
+ /** Callback fired for each text chunk as it streams in */
17
+ onDelta?: (delta: string) => void;
18
+ /** Callback fired when agent requests a tool call */
19
+ onToolCall?: (toolCall: ToolCall) => void;
20
+ /** Callback fired when execution completes with final result */
21
+ onComplete?: (result: AgentRunnerResult) => void;
22
+ }
23
+ export interface AgentRunnerResult {
24
+ /** Complete message history including user, assistant, and tool messages */
25
+ messages: ChatMessage[];
26
+ /** The final assistant message returned by the agent */
27
+ finalMessage: ChatMessage;
28
+ /** All tool calls executed during the conversation */
29
+ toolCalls: ToolCall[];
30
+ /** Number of conversation turns completed */
31
+ turns: number;
32
+ /** Whether execution completed successfully without errors */
33
+ success: boolean;
34
+ /** Reason execution stopped: 'text-response' (natural completion), 'max-turns' (hit turn limit), 'error' (failed), or 'one-shot-complete' (single turn mode) */
35
+ stoppedReason: 'text-response' | 'max-turns' | 'error' | 'one-shot-complete';
36
+ }
37
+ export declare class AgentRunner {
38
+ #private;
39
+ private constructor();
40
+ static run(config: AgentRunnerConfig): Promise<AgentRunnerResult>;
41
+ }