@useago/sdk 0.1.7 → 0.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.
- package/README.md +101 -6
- package/dist/AgoClient-CNT-8sh_.js +905 -0
- package/dist/AgoClient-CNT-8sh_.js.map +1 -0
- package/dist/AgoClient-D0l1GTRs.cjs +976 -0
- package/dist/AgoClient-D0l1GTRs.cjs.map +1 -0
- package/dist/angular.cjs +138 -100
- package/dist/angular.cjs.map +1 -1
- package/dist/angular.d.ts +1 -0
- package/dist/angular.js +139 -103
- package/dist/angular.js.map +1 -1
- package/dist/client/types.d.ts +5 -1
- package/dist/createMockClient-Ci_N2tH8.cjs +104 -0
- package/dist/createMockClient-Ci_N2tH8.cjs.map +1 -0
- package/dist/createMockClient-U0ae_AYy.js +99 -0
- package/dist/createMockClient-U0ae_AYy.js.map +1 -0
- package/dist/functions--c6lx3ic.cjs +480 -0
- package/dist/functions--c6lx3ic.cjs.map +1 -0
- package/dist/functions-C9F1dnmh.js +398 -0
- package/dist/functions-C9F1dnmh.js.map +1 -0
- package/dist/helpers.cjs +14 -16
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +2 -17
- package/dist/index.cjs +281 -153
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +256 -166
- package/dist/index.js.map +1 -1
- package/dist/react/components/ChatWidget.d.ts +2 -0
- package/dist/react/components/Markdown.d.ts +12 -0
- package/dist/react/components/Message.d.ts +2 -0
- package/dist/react/components/index.d.ts +2 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react.cjs +22099 -10333
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +1 -0
- package/dist/react.js +22099 -10349
- package/dist/react.js.map +1 -1
- package/dist/rolldown-runtime-BqCkTl7Q.cjs +50 -0
- package/dist/rolldown-runtime-CNZpIYwj.js +33 -0
- package/dist/vue.cjs +287 -208
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.d.ts +1 -0
- package/dist/vue.js +287 -218
- package/dist/vue.js.map +1 -1
- package/dist/widget.cjs +0 -2
- package/dist/widget.d.ts +1 -0
- package/dist/widget.js +0 -2
- package/package.json +8 -6
- package/dist/AgoClient-BDO4avLq.cjs +0 -1036
- package/dist/AgoClient-BDO4avLq.cjs.map +0 -1
- package/dist/AgoClient-D-c91tx5.js +0 -1037
- package/dist/AgoClient-D-c91tx5.js.map +0 -1
- package/dist/createMockClient-B1DcBiIK.js +0 -94
- package/dist/createMockClient-B1DcBiIK.js.map +0 -1
- package/dist/createMockClient-BqNSJUu4.cjs +0 -93
- package/dist/createMockClient-BqNSJUu4.cjs.map +0 -1
- package/dist/functions-B0Z0rNQW.cjs +0 -306
- package/dist/functions-B0Z0rNQW.cjs.map +0 -1
- package/dist/functions-C-wLEc8b.js +0 -306
- package/dist/functions-C-wLEc8b.js.map +0 -1
- package/dist/helpers.cjs.map +0 -1
- package/dist/helpers.js.map +0 -1
- package/dist/widget.cjs.map +0 -1
- package/dist/widget.js.map +0 -1
package/dist/angular.js
CHANGED
|
@@ -1,105 +1,141 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
1
|
+
import { t as AgoClient } from "./AgoClient-CNT-8sh_.js";
|
|
2
|
+
//#region src/angular/ago.service.ts
|
|
3
|
+
/**
|
|
4
|
+
* Angular-style service wrapping AgoClient.
|
|
5
|
+
* Provides RxJS-like Observables for streaming events and standard Promise-based methods.
|
|
6
|
+
*
|
|
7
|
+
* Usage with Angular DI:
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { provideAgo, AgoService } from "@useago/sdk/angular";
|
|
10
|
+
*
|
|
11
|
+
* // In providers array:
|
|
12
|
+
* provideAgo({ baseUrl: "https://YOUR-DOMAIN.useago.com" })
|
|
13
|
+
*
|
|
14
|
+
* // In component:
|
|
15
|
+
* @Component({...})
|
|
16
|
+
* export class ChatComponent {
|
|
17
|
+
* private ago = inject(AgoService);
|
|
18
|
+
* messages$ = this.ago.messages$;
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* Works without Angular DI too — just instantiate directly:
|
|
23
|
+
* ```ts
|
|
24
|
+
* const ago = new AgoService({ baseUrl: "https://YOUR-DOMAIN.useago.com" });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
var AgoService = class {
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.client = new AgoClient(config);
|
|
30
|
+
this.messages$ = this.fromEvent("message:complete");
|
|
31
|
+
this.chunks$ = this.fromEvent("message:chunk");
|
|
32
|
+
this.errors$ = this.fromEvent("message:error");
|
|
33
|
+
this.messageStart$ = this.fromEvent("message:start");
|
|
34
|
+
}
|
|
35
|
+
/** Create a minimal Observable from an AgoClient event */
|
|
36
|
+
fromEvent(event) {
|
|
37
|
+
const client = this.client;
|
|
38
|
+
return { subscribe(observer) {
|
|
39
|
+
const handler = (data) => {
|
|
40
|
+
observer.next?.(data);
|
|
41
|
+
};
|
|
42
|
+
client.on(event, handler);
|
|
43
|
+
return { unsubscribe: () => client.off(event, handler) };
|
|
44
|
+
} };
|
|
45
|
+
}
|
|
46
|
+
/** Send a message and get a streaming response */
|
|
47
|
+
sendMessage(content, options) {
|
|
48
|
+
return this.client.sendMessage(content, options);
|
|
49
|
+
}
|
|
50
|
+
/** Get all conversations */
|
|
51
|
+
getConversations() {
|
|
52
|
+
return this.client.getConversations();
|
|
53
|
+
}
|
|
54
|
+
/** Get a specific conversation with messages */
|
|
55
|
+
getConversation(id) {
|
|
56
|
+
return this.client.getConversation(id);
|
|
57
|
+
}
|
|
58
|
+
/** Get messages for a conversation */
|
|
59
|
+
getMessages(conversationId) {
|
|
60
|
+
return this.client.getMessages(conversationId);
|
|
61
|
+
}
|
|
62
|
+
/** Submit form data for a tool call */
|
|
63
|
+
submitToolCallForm(toolCallId, formData) {
|
|
64
|
+
return this.client.submitToolCallForm(toolCallId, formData);
|
|
65
|
+
}
|
|
66
|
+
/** Confirm a tool call */
|
|
67
|
+
confirmToolCall(toolCallId) {
|
|
68
|
+
return this.client.confirmToolCall(toolCallId);
|
|
69
|
+
}
|
|
70
|
+
/** Reject a tool call */
|
|
71
|
+
rejectToolCall(toolCallId) {
|
|
72
|
+
return this.client.rejectToolCall(toolCallId);
|
|
73
|
+
}
|
|
74
|
+
/** Submit feedback for a message */
|
|
75
|
+
submitFeedback(messageId, rating) {
|
|
76
|
+
return this.client.submitFeedback(messageId, rating);
|
|
77
|
+
}
|
|
78
|
+
registerFunction(nameOrDef, handler, schema) {
|
|
79
|
+
if (typeof nameOrDef === "object") this.client.registerFunction(nameOrDef);
|
|
80
|
+
else this.client.registerFunction(nameOrDef, handler, schema);
|
|
81
|
+
}
|
|
82
|
+
/** Unregister a client-side function */
|
|
83
|
+
unregisterFunction(name) {
|
|
84
|
+
return this.client.unregisterFunction(name);
|
|
85
|
+
}
|
|
86
|
+
/** Register navigation routes */
|
|
87
|
+
registerNavigationFunction(navigate, routes) {
|
|
88
|
+
this.client.registerNavigationFunction(navigate, routes);
|
|
89
|
+
}
|
|
90
|
+
/** Subscribe to a client event */
|
|
91
|
+
on(event, handler) {
|
|
92
|
+
this.client.on(event, handler);
|
|
93
|
+
}
|
|
94
|
+
/** Unsubscribe from a client event */
|
|
95
|
+
off(event, handler) {
|
|
96
|
+
this.client.off(event, handler);
|
|
97
|
+
}
|
|
98
|
+
/** Update client config */
|
|
99
|
+
updateConfig(config) {
|
|
100
|
+
this.client.updateConfig(config);
|
|
101
|
+
}
|
|
102
|
+
/** Get the underlying AgoClient instance */
|
|
103
|
+
getClient() {
|
|
104
|
+
return this.client;
|
|
105
|
+
}
|
|
106
|
+
/** Destroy the service and clean up resources */
|
|
107
|
+
destroy() {
|
|
108
|
+
this.client.destroy();
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
//#endregion
|
|
112
|
+
//#region src/angular/provide.ts
|
|
113
|
+
/**
|
|
114
|
+
* Factory function that returns an Angular-compatible provider.
|
|
115
|
+
* Use in your app's `providers` array or `bootstrapApplication`:
|
|
116
|
+
*
|
|
117
|
+
* ```ts
|
|
118
|
+
* import { provideAgo, AgoService } from "@useago/sdk/angular";
|
|
119
|
+
*
|
|
120
|
+
* bootstrapApplication(AppComponent, {
|
|
121
|
+
* providers: [provideAgo({ baseUrl: "https://YOUR-DOMAIN.useago.com" })],
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* // Then inject in any component:
|
|
125
|
+
* const ago = inject(AgoService);
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* Returns a provider tuple compatible with Angular's DI.
|
|
129
|
+
* Since this package avoids a hard Angular dependency, the provider
|
|
130
|
+
* is returned as a plain object — Angular's injector accepts this format.
|
|
131
|
+
*/
|
|
94
132
|
function provideAgo(options) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
};
|
|
133
|
+
return {
|
|
134
|
+
provide: AgoService,
|
|
135
|
+
useValue: new AgoService(options)
|
|
136
|
+
};
|
|
100
137
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
//# sourceMappingURL=angular.js.map
|
|
138
|
+
//#endregion
|
|
139
|
+
export { AgoService, provideAgo };
|
|
140
|
+
|
|
141
|
+
//# sourceMappingURL=angular.js.map
|
package/dist/angular.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"angular.js","sources":["../src/angular/ago.service.ts","../src/angular/provide.ts"],"sourcesContent":["import { AgoClient } from \"../client/AgoClient\";\nimport type {\n AgoConfig,\n AgoMessage,\n Conversation,\n AgoClientEvents,\n AgoEventName,\n SendMessageOptions,\n} from \"../client/types\";\nimport type { ClientFunctionDefinition, ClientFunctionHandler, ClientFunctionSchema } from \"../functions/types\";\n\ninterface Observable<T> {\n subscribe(observer: { next?: (value: T) => void; error?: (err: unknown) => void }): { unsubscribe: () => void };\n}\n\n/**\n * Angular-style service wrapping AgoClient.\n * Provides RxJS-like Observables for streaming events and standard Promise-based methods.\n *\n * Usage with Angular DI:\n * ```ts\n * import { provideAgo, AgoService } from \"@useago/sdk/angular\";\n *\n * // In providers array:\n * provideAgo({ baseUrl: \"https://YOUR-DOMAIN.useago.com\" })\n *\n * // In component:\n * @Component({...})\n * export class ChatComponent {\n * private ago = inject(AgoService);\n * messages$ = this.ago.messages$;\n * }\n * ```\n *\n * Works without Angular DI too — just instantiate directly:\n * ```ts\n * const ago = new AgoService({ baseUrl: \"https://YOUR-DOMAIN.useago.com\" });\n * ```\n */\nexport class AgoService {\n private client: AgoClient;\n\n /** Observable of complete messages */\n readonly messages$: Observable<AgoMessage>;\n\n /** Observable of streaming chunks */\n readonly chunks$: Observable<{ content: string; conversationId: string; messageId: string }>;\n\n /** Observable of errors */\n readonly errors$: Observable<{ error: string; conversationId?: string; messageId?: string }>;\n\n /** Observable of message start events */\n readonly messageStart$: Observable<{ conversationId: string; messageId: string }>;\n\n constructor(config: AgoConfig) {\n this.client = new AgoClient(config);\n\n this.messages$ = this.fromEvent(\"message:complete\");\n this.chunks$ = this.fromEvent(\"message:chunk\");\n this.errors$ = this.fromEvent(\"message:error\");\n this.messageStart$ = this.fromEvent(\"message:start\");\n }\n\n /** Create a minimal Observable from an AgoClient event */\n private fromEvent<K extends AgoEventName>(event: K): Observable<AgoClientEvents[K]> {\n const client = this.client;\n return {\n subscribe(observer: { next?: (value: AgoClientEvents[K]) => void; error?: (err: unknown) => void }) {\n const handler = (data: AgoClientEvents[K]) => {\n observer.next?.(data);\n };\n client.on(event, handler);\n return {\n unsubscribe: () => client.off(event, handler),\n };\n },\n };\n }\n\n /** Send a message and get a streaming response */\n sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage> {\n return this.client.sendMessage(content, options);\n }\n\n /** Get all conversations */\n getConversations(): Promise<Conversation[]> {\n return this.client.getConversations();\n }\n\n /** Get a specific conversation with messages */\n getConversation(id: string): Promise<Conversation> {\n return this.client.getConversation(id);\n }\n\n /** Get messages for a conversation */\n getMessages(conversationId: string): Promise<AgoMessage[]> {\n return this.client.getMessages(conversationId);\n }\n\n /** Submit form data for a tool call */\n submitToolCallForm(toolCallId: string, formData: Record<string, unknown>): Promise<void> {\n return this.client.submitToolCallForm(toolCallId, formData);\n }\n\n /** Confirm a tool call */\n confirmToolCall(toolCallId: string): Promise<void> {\n return this.client.confirmToolCall(toolCallId);\n }\n\n /** Reject a tool call */\n rejectToolCall(toolCallId: string): Promise<void> {\n return this.client.rejectToolCall(toolCallId);\n }\n\n /** Submit feedback for a message */\n submitFeedback(messageId: string, rating: \"positive\" | \"negative\"): Promise<void> {\n return this.client.submitFeedback(messageId, rating);\n }\n\n /** Register a client-side function */\n registerFunction(definition: ClientFunctionDefinition): void;\n registerFunction(name: string, handler: ClientFunctionHandler, schema: Omit<ClientFunctionSchema, \"name\">): void;\n registerFunction(\n nameOrDef: string | ClientFunctionDefinition,\n handler?: ClientFunctionHandler,\n schema?: Omit<ClientFunctionSchema, \"name\">\n ): void {\n if (typeof nameOrDef === \"object\") {\n this.client.registerFunction(nameOrDef);\n } else {\n this.client.registerFunction(nameOrDef, handler!, schema!);\n }\n }\n\n /** Unregister a client-side function */\n unregisterFunction(name: string): boolean {\n return this.client.unregisterFunction(name);\n }\n\n /** Register navigation routes */\n registerNavigationFunction(\n navigate: (path: string) => void,\n routes: Array<{ name: string; path: string; description: string }>\n ): void {\n this.client.registerNavigationFunction(navigate, routes);\n }\n\n /** Subscribe to a client event */\n on<K extends AgoEventName>(\n event: K,\n handler: (data: AgoClientEvents[K]) => void\n ): void {\n this.client.on(event, handler);\n }\n\n /** Unsubscribe from a client event */\n off<K extends AgoEventName>(\n event: K,\n handler: (data: AgoClientEvents[K]) => void\n ): void {\n this.client.off(event, handler);\n }\n\n /** Update client config */\n updateConfig(config: Partial<AgoConfig>): void {\n this.client.updateConfig(config);\n }\n\n /** Get the underlying AgoClient instance */\n getClient(): AgoClient {\n return this.client;\n }\n\n /** Destroy the service and clean up resources */\n destroy(): void {\n this.client.destroy();\n }\n}\n","import type { AgoConfig } from \"../client/types\";\nimport { AgoService } from \"./ago.service\";\n\nexport interface AgoProvideOptions extends AgoConfig {}\n\n/**\n * Factory function that returns an Angular-compatible provider.\n * Use in your app's `providers` array or `bootstrapApplication`:\n *\n * ```ts\n * import { provideAgo, AgoService } from \"@useago/sdk/angular\";\n *\n * bootstrapApplication(AppComponent, {\n * providers: [provideAgo({ baseUrl: \"https://YOUR-DOMAIN.useago.com\" })],\n * });\n *\n * // Then inject in any component:\n * const ago = inject(AgoService);\n * ```\n *\n * Returns a provider tuple compatible with Angular's DI.\n * Since this package avoids a hard Angular dependency, the provider\n * is returned as a plain object — Angular's injector accepts this format.\n */\nexport function provideAgo(options: AgoProvideOptions) {\n const service = new AgoService(options);\n return {\n provide: AgoService,\n useValue: service,\n };\n}\n"],"
|
|
1
|
+
{"version":3,"file":"angular.js","names":[],"sources":["../src/angular/ago.service.ts","../src/angular/provide.ts"],"sourcesContent":["import { AgoClient } from \"../client/AgoClient\";\nimport type {\n AgoConfig,\n AgoMessage,\n Conversation,\n AgoClientEvents,\n AgoEventName,\n SendMessageOptions,\n} from \"../client/types\";\nimport type { ClientFunctionDefinition, ClientFunctionHandler, ClientFunctionSchema } from \"../functions/types\";\n\ninterface Observable<T> {\n subscribe(observer: { next?: (value: T) => void; error?: (err: unknown) => void }): { unsubscribe: () => void };\n}\n\n/**\n * Angular-style service wrapping AgoClient.\n * Provides RxJS-like Observables for streaming events and standard Promise-based methods.\n *\n * Usage with Angular DI:\n * ```ts\n * import { provideAgo, AgoService } from \"@useago/sdk/angular\";\n *\n * // In providers array:\n * provideAgo({ baseUrl: \"https://YOUR-DOMAIN.useago.com\" })\n *\n * // In component:\n * @Component({...})\n * export class ChatComponent {\n * private ago = inject(AgoService);\n * messages$ = this.ago.messages$;\n * }\n * ```\n *\n * Works without Angular DI too — just instantiate directly:\n * ```ts\n * const ago = new AgoService({ baseUrl: \"https://YOUR-DOMAIN.useago.com\" });\n * ```\n */\nexport class AgoService {\n private client: AgoClient;\n\n /** Observable of complete messages */\n readonly messages$: Observable<AgoMessage>;\n\n /** Observable of streaming chunks */\n readonly chunks$: Observable<{ content: string; conversationId: string; messageId: string }>;\n\n /** Observable of errors */\n readonly errors$: Observable<{ error: string; conversationId?: string; messageId?: string }>;\n\n /** Observable of message start events */\n readonly messageStart$: Observable<{ conversationId: string; messageId: string }>;\n\n constructor(config: AgoConfig) {\n this.client = new AgoClient(config);\n\n this.messages$ = this.fromEvent(\"message:complete\");\n this.chunks$ = this.fromEvent(\"message:chunk\");\n this.errors$ = this.fromEvent(\"message:error\");\n this.messageStart$ = this.fromEvent(\"message:start\");\n }\n\n /** Create a minimal Observable from an AgoClient event */\n private fromEvent<K extends AgoEventName>(event: K): Observable<AgoClientEvents[K]> {\n const client = this.client;\n return {\n subscribe(observer: { next?: (value: AgoClientEvents[K]) => void; error?: (err: unknown) => void }) {\n const handler = (data: AgoClientEvents[K]) => {\n observer.next?.(data);\n };\n client.on(event, handler);\n return {\n unsubscribe: () => client.off(event, handler),\n };\n },\n };\n }\n\n /** Send a message and get a streaming response */\n sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage> {\n return this.client.sendMessage(content, options);\n }\n\n /** Get all conversations */\n getConversations(): Promise<Conversation[]> {\n return this.client.getConversations();\n }\n\n /** Get a specific conversation with messages */\n getConversation(id: string): Promise<Conversation> {\n return this.client.getConversation(id);\n }\n\n /** Get messages for a conversation */\n getMessages(conversationId: string): Promise<AgoMessage[]> {\n return this.client.getMessages(conversationId);\n }\n\n /** Submit form data for a tool call */\n submitToolCallForm(toolCallId: string, formData: Record<string, unknown>): Promise<void> {\n return this.client.submitToolCallForm(toolCallId, formData);\n }\n\n /** Confirm a tool call */\n confirmToolCall(toolCallId: string): Promise<void> {\n return this.client.confirmToolCall(toolCallId);\n }\n\n /** Reject a tool call */\n rejectToolCall(toolCallId: string): Promise<void> {\n return this.client.rejectToolCall(toolCallId);\n }\n\n /** Submit feedback for a message */\n submitFeedback(messageId: string, rating: \"positive\" | \"negative\"): Promise<void> {\n return this.client.submitFeedback(messageId, rating);\n }\n\n /** Register a client-side function */\n registerFunction(definition: ClientFunctionDefinition): void;\n registerFunction(name: string, handler: ClientFunctionHandler, schema: Omit<ClientFunctionSchema, \"name\">): void;\n registerFunction(\n nameOrDef: string | ClientFunctionDefinition,\n handler?: ClientFunctionHandler,\n schema?: Omit<ClientFunctionSchema, \"name\">\n ): void {\n if (typeof nameOrDef === \"object\") {\n this.client.registerFunction(nameOrDef);\n } else {\n this.client.registerFunction(nameOrDef, handler!, schema!);\n }\n }\n\n /** Unregister a client-side function */\n unregisterFunction(name: string): boolean {\n return this.client.unregisterFunction(name);\n }\n\n /** Register navigation routes */\n registerNavigationFunction(\n navigate: (path: string) => void,\n routes: Array<{ name: string; path: string; description: string }>\n ): void {\n this.client.registerNavigationFunction(navigate, routes);\n }\n\n /** Subscribe to a client event */\n on<K extends AgoEventName>(\n event: K,\n handler: (data: AgoClientEvents[K]) => void\n ): void {\n this.client.on(event, handler);\n }\n\n /** Unsubscribe from a client event */\n off<K extends AgoEventName>(\n event: K,\n handler: (data: AgoClientEvents[K]) => void\n ): void {\n this.client.off(event, handler);\n }\n\n /** Update client config */\n updateConfig(config: Partial<AgoConfig>): void {\n this.client.updateConfig(config);\n }\n\n /** Get the underlying AgoClient instance */\n getClient(): AgoClient {\n return this.client;\n }\n\n /** Destroy the service and clean up resources */\n destroy(): void {\n this.client.destroy();\n }\n}\n","import type { AgoConfig } from \"../client/types\";\nimport { AgoService } from \"./ago.service\";\n\nexport interface AgoProvideOptions extends AgoConfig {}\n\n/**\n * Factory function that returns an Angular-compatible provider.\n * Use in your app's `providers` array or `bootstrapApplication`:\n *\n * ```ts\n * import { provideAgo, AgoService } from \"@useago/sdk/angular\";\n *\n * bootstrapApplication(AppComponent, {\n * providers: [provideAgo({ baseUrl: \"https://YOUR-DOMAIN.useago.com\" })],\n * });\n *\n * // Then inject in any component:\n * const ago = inject(AgoService);\n * ```\n *\n * Returns a provider tuple compatible with Angular's DI.\n * Since this package avoids a hard Angular dependency, the provider\n * is returned as a plain object — Angular's injector accepts this format.\n */\nexport function provideAgo(options: AgoProvideOptions) {\n const service = new AgoService(options);\n return {\n provide: AgoService,\n useValue: service,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,IAAa,aAAb,MAAwB;CAetB,YAAY,QAAmB;AAC7B,OAAK,SAAS,IAAI,UAAU,OAAO;AAEnC,OAAK,YAAY,KAAK,UAAU,mBAAmB;AACnD,OAAK,UAAU,KAAK,UAAU,gBAAgB;AAC9C,OAAK,UAAU,KAAK,UAAU,gBAAgB;AAC9C,OAAK,gBAAgB,KAAK,UAAU,gBAAgB;;;CAItD,UAA0C,OAA0C;EAClF,MAAM,SAAS,KAAK;AACpB,SAAO,EACL,UAAU,UAA0F;GAClG,MAAM,WAAW,SAA6B;AAC5C,aAAS,OAAO,KAAK;;AAEvB,UAAO,GAAG,OAAO,QAAQ;AACzB,UAAO,EACL,mBAAmB,OAAO,IAAI,OAAO,QAAQ,EAC9C;KAEJ;;;CAIH,YAAY,SAAiB,SAAmD;AAC9E,SAAO,KAAK,OAAO,YAAY,SAAS,QAAQ;;;CAIlD,mBAA4C;AAC1C,SAAO,KAAK,OAAO,kBAAkB;;;CAIvC,gBAAgB,IAAmC;AACjD,SAAO,KAAK,OAAO,gBAAgB,GAAG;;;CAIxC,YAAY,gBAA+C;AACzD,SAAO,KAAK,OAAO,YAAY,eAAe;;;CAIhD,mBAAmB,YAAoB,UAAkD;AACvF,SAAO,KAAK,OAAO,mBAAmB,YAAY,SAAS;;;CAI7D,gBAAgB,YAAmC;AACjD,SAAO,KAAK,OAAO,gBAAgB,WAAW;;;CAIhD,eAAe,YAAmC;AAChD,SAAO,KAAK,OAAO,eAAe,WAAW;;;CAI/C,eAAe,WAAmB,QAAgD;AAChF,SAAO,KAAK,OAAO,eAAe,WAAW,OAAO;;CAMtD,iBACE,WACA,SACA,QACM;AACN,MAAI,OAAO,cAAc,SACvB,MAAK,OAAO,iBAAiB,UAAU;MAEvC,MAAK,OAAO,iBAAiB,WAAW,SAAU,OAAQ;;;CAK9D,mBAAmB,MAAuB;AACxC,SAAO,KAAK,OAAO,mBAAmB,KAAK;;;CAI7C,2BACE,UACA,QACM;AACN,OAAK,OAAO,2BAA2B,UAAU,OAAO;;;CAI1D,GACE,OACA,SACM;AACN,OAAK,OAAO,GAAG,OAAO,QAAQ;;;CAIhC,IACE,OACA,SACM;AACN,OAAK,OAAO,IAAI,OAAO,QAAQ;;;CAIjC,aAAa,QAAkC;AAC7C,OAAK,OAAO,aAAa,OAAO;;;CAIlC,YAAuB;AACrB,SAAO,KAAK;;;CAId,UAAgB;AACd,OAAK,OAAO,SAAS;;;;;;;;;;;;;;;;;;;;;;;;ACvJzB,SAAgB,WAAW,SAA4B;AAErD,QAAO;EACL,SAAS;EACT,UAAU,IAHQ,WAAW,QAGnB;EACX"}
|
package/dist/client/types.d.ts
CHANGED
|
@@ -6,8 +6,12 @@ export interface AgoConfig {
|
|
|
6
6
|
baseUrl: string;
|
|
7
7
|
/** Widget ID (X-Widget-Id header). Auto-generated if not provided. */
|
|
8
8
|
widgetId?: string;
|
|
9
|
-
/** Default agent
|
|
9
|
+
/** Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`. */
|
|
10
|
+
agent?: string;
|
|
11
|
+
/** Default agent ID for new conversations. Prefer `agent`. */
|
|
10
12
|
defaultAgentId?: string;
|
|
13
|
+
/** Permission name to apply to all requests (sent as `X-Widget-Permission`). Mirrors the widget's `window.AGO.permission`. */
|
|
14
|
+
permission?: string;
|
|
11
15
|
/** User email for identification */
|
|
12
16
|
userEmail?: string;
|
|
13
17
|
/** JWT token for authenticated users */
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
//#region src/testing/createMockClient.ts
|
|
2
|
+
/**
|
|
3
|
+
* Create a mock AgoClient for testing. Works with any framework.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { createMockClient } from "@useago/sdk/testing";
|
|
7
|
+
*
|
|
8
|
+
* const mock = createMockClient();
|
|
9
|
+
* mock.__emitEvent("message:complete", someMessage);
|
|
10
|
+
* expect(mock.__callsFor("sendMessage")).toHaveLength(1);
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
function createMockClient(options = {}) {
|
|
14
|
+
const { overrides = {} } = options;
|
|
15
|
+
const noopMessage = {
|
|
16
|
+
id: "mock-msg-1",
|
|
17
|
+
conversationId: "mock-conv-1",
|
|
18
|
+
content: "Mock response",
|
|
19
|
+
role: "assistant",
|
|
20
|
+
status: "DONE",
|
|
21
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
22
|
+
};
|
|
23
|
+
const noopConversation = {
|
|
24
|
+
id: "mock-conv-1",
|
|
25
|
+
title: "Mock Conversation",
|
|
26
|
+
lastMessageDate: /* @__PURE__ */ new Date()
|
|
27
|
+
};
|
|
28
|
+
const listeners = /* @__PURE__ */ new Map();
|
|
29
|
+
const calls = [];
|
|
30
|
+
const merged = {
|
|
31
|
+
sendMessage: async () => noopMessage,
|
|
32
|
+
getConversations: async () => [noopConversation],
|
|
33
|
+
getConversation: async () => noopConversation,
|
|
34
|
+
getMessages: async () => [noopMessage],
|
|
35
|
+
submitToolCallForm: async () => void 0,
|
|
36
|
+
confirmToolCall: async () => void 0,
|
|
37
|
+
rejectToolCall: async () => void 0,
|
|
38
|
+
submitFeedback: async () => void 0,
|
|
39
|
+
registerFunction: () => void 0,
|
|
40
|
+
unregisterFunction: () => true,
|
|
41
|
+
getRegisteredFunctions: () => [],
|
|
42
|
+
registerNavigationFunction: () => void 0,
|
|
43
|
+
on: (event, handler) => {
|
|
44
|
+
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
45
|
+
listeners.get(event).add(handler);
|
|
46
|
+
},
|
|
47
|
+
off: (event, handler) => {
|
|
48
|
+
listeners.get(event)?.delete(handler);
|
|
49
|
+
},
|
|
50
|
+
once: (event, handler) => {
|
|
51
|
+
const wrapper = (...args) => {
|
|
52
|
+
listeners.get(event)?.delete(wrapper);
|
|
53
|
+
handler(...args);
|
|
54
|
+
};
|
|
55
|
+
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
56
|
+
listeners.get(event).add(wrapper);
|
|
57
|
+
},
|
|
58
|
+
waitFor: (event, options) => {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
let timer;
|
|
61
|
+
const handler = (data) => {
|
|
62
|
+
if (timer) clearTimeout(timer);
|
|
63
|
+
listeners.get(event)?.delete(handler);
|
|
64
|
+
resolve(data);
|
|
65
|
+
};
|
|
66
|
+
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
67
|
+
listeners.get(event).add(handler);
|
|
68
|
+
if (options?.timeout) timer = setTimeout(() => {
|
|
69
|
+
listeners.get(event)?.delete(handler);
|
|
70
|
+
reject(/* @__PURE__ */ new Error(`waitFor("${event}") timed out after ${options.timeout}ms`));
|
|
71
|
+
}, options.timeout);
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
updateConfig: () => void 0,
|
|
75
|
+
destroy: () => {
|
|
76
|
+
listeners.clear();
|
|
77
|
+
},
|
|
78
|
+
...overrides
|
|
79
|
+
};
|
|
80
|
+
const mock = {};
|
|
81
|
+
for (const [key, fn] of Object.entries(merged)) mock[key] = (...args) => {
|
|
82
|
+
calls.push({
|
|
83
|
+
method: key,
|
|
84
|
+
args
|
|
85
|
+
});
|
|
86
|
+
return fn(...args);
|
|
87
|
+
};
|
|
88
|
+
mock.__calls = calls;
|
|
89
|
+
mock.__callsFor = (method) => calls.filter((c) => c.method === method);
|
|
90
|
+
mock.__emitEvent = (event, data) => {
|
|
91
|
+
const handlers = listeners.get(event);
|
|
92
|
+
if (handlers) [...handlers].forEach((h) => h(data));
|
|
93
|
+
};
|
|
94
|
+
return mock;
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
Object.defineProperty(exports, "createMockClient", {
|
|
98
|
+
enumerable: true,
|
|
99
|
+
get: function() {
|
|
100
|
+
return createMockClient;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=createMockClient-Ci_N2tH8.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createMockClient-Ci_N2tH8.cjs","names":[],"sources":["../src/testing/createMockClient.ts"],"sourcesContent":["import type { AgoClient } from \"../client/AgoClient\";\nimport type {\n AgoClientEvents,\n AgoEventName,\n AgoMessage,\n Conversation,\n} from \"../client/types\";\nimport type { ClientFunctionSchema } from \"../functions/types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype MockFn = (...args: any[]) => any;\n\nexport interface MockAgoClientOptions {\n overrides?: Partial<Record<string, MockFn>>;\n}\n\nexport interface MockAgoClient extends AgoClient {\n /**\n * Simulate a server-pushed event.\n * ```ts\n * mock.__emitEvent(\"message:complete\", { id: \"1\", content: \"hi\", ... });\n * ```\n */\n __emitEvent<K extends AgoEventName>(event: K, data: AgoClientEvents[K]): void;\n\n /**\n * All recorded method calls: `[methodName, ...args][]`\n */\n __calls: Array<{ method: string; args: unknown[] }>;\n\n /**\n * Get calls for a specific method.\n */\n __callsFor(method: string): Array<{ method: string; args: unknown[] }>;\n}\n\n/**\n * Create a mock AgoClient for testing. Works with any framework.\n *\n * ```ts\n * import { createMockClient } from \"@useago/sdk/testing\";\n *\n * const mock = createMockClient();\n * mock.__emitEvent(\"message:complete\", someMessage);\n * expect(mock.__callsFor(\"sendMessage\")).toHaveLength(1);\n * ```\n */\nexport function createMockClient(\n options: MockAgoClientOptions = {}\n): MockAgoClient {\n const { overrides = {} } = options;\n\n const noopMessage: AgoMessage = {\n id: \"mock-msg-1\",\n conversationId: \"mock-conv-1\",\n content: \"Mock response\",\n role: \"assistant\",\n status: \"DONE\",\n createdAt: new Date(),\n };\n\n const noopConversation: Conversation = {\n id: \"mock-conv-1\",\n title: \"Mock Conversation\",\n lastMessageDate: new Date(),\n };\n\n const listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n const calls: Array<{ method: string; args: unknown[] }> = [];\n\n const defaults: Record<string, MockFn> = {\n sendMessage: async () => noopMessage,\n getConversations: async () => [noopConversation],\n getConversation: async () => noopConversation,\n getMessages: async () => [noopMessage],\n submitToolCallForm: async () => undefined,\n confirmToolCall: async () => undefined,\n rejectToolCall: async () => undefined,\n submitFeedback: async () => undefined,\n registerFunction: () => undefined,\n unregisterFunction: () => true,\n getRegisteredFunctions: () => [] as ClientFunctionSchema[],\n registerNavigationFunction: () => undefined,\n on: (event: string, handler: (...args: unknown[]) => void) => {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n },\n off: (event: string, handler: (...args: unknown[]) => void) => {\n listeners.get(event)?.delete(handler);\n },\n once: (event: string, handler: (...args: unknown[]) => void) => {\n const wrapper = (...args: unknown[]) => {\n listeners.get(event)?.delete(wrapper);\n handler(...args);\n };\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(wrapper);\n },\n waitFor: (event: string, options?: { timeout?: number }) => {\n return new Promise((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const handler = (data: unknown) => {\n if (timer) clearTimeout(timer);\n listeners.get(event)?.delete(handler);\n resolve(data);\n };\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n if (options?.timeout) {\n timer = setTimeout(() => {\n listeners.get(event)?.delete(handler);\n reject(new Error(`waitFor(\"${event}\") timed out after ${options.timeout}ms`));\n }, options.timeout);\n }\n });\n },\n updateConfig: () => undefined,\n destroy: () => {\n listeners.clear();\n },\n };\n\n const merged = { ...defaults, ...overrides } as Record<string, MockFn>;\n\n // Wrap all methods to record calls\n const mock: Record<string, unknown> = {};\n\n for (const [key, fn] of Object.entries(merged)) {\n mock[key] = (...args: unknown[]) => {\n calls.push({ method: key, args });\n return (fn as MockFn)(...args);\n };\n }\n\n // Test helpers (not recorded)\n mock.__calls = calls;\n mock.__callsFor = (method: string) => calls.filter((c) => c.method === method);\n mock.__emitEvent = (event: string, data: unknown) => {\n // Copy the set to avoid mutation during iteration (once handlers remove themselves)\n const handlers = listeners.get(event);\n if (handlers) {\n [...handlers].forEach((h) => h(data));\n }\n };\n\n return mock as unknown as MockAgoClient;\n}\n"],"mappings":";;;;;;;;;;;;AA+CA,SAAgB,iBACd,UAAgC,EAAE,EACnB;CACf,MAAM,EAAE,YAAY,EAAE,KAAK;CAE3B,MAAM,cAA0B;EAC9B,IAAI;EACJ,gBAAgB;EAChB,SAAS;EACT,MAAM;EACN,QAAQ;EACR,2BAAW,IAAI,MAAM;EACtB;CAED,MAAM,mBAAiC;EACrC,IAAI;EACJ,OAAO;EACP,iCAAiB,IAAI,MAAM;EAC5B;CAED,MAAM,4BAAY,IAAI,KAAgD;CACtE,MAAM,QAAoD,EAAE;CAsD5D,MAAM,SAAS;EAnDb,aAAa,YAAY;EACzB,kBAAkB,YAAY,CAAC,iBAAiB;EAChD,iBAAiB,YAAY;EAC7B,aAAa,YAAY,CAAC,YAAY;EACtC,oBAAoB,YAAY,KAAA;EAChC,iBAAiB,YAAY,KAAA;EAC7B,gBAAgB,YAAY,KAAA;EAC5B,gBAAgB,YAAY,KAAA;EAC5B,wBAAwB,KAAA;EACxB,0BAA0B;EAC1B,8BAA8B,EAAE;EAChC,kCAAkC,KAAA;EAClC,KAAK,OAAe,YAA0C;AAC5D,OAAI,CAAC,UAAU,IAAI,MAAM,CAAE,WAAU,IAAI,uBAAO,IAAI,KAAK,CAAC;AAC1D,aAAU,IAAI,MAAM,CAAE,IAAI,QAAQ;;EAEpC,MAAM,OAAe,YAA0C;AAC7D,aAAU,IAAI,MAAM,EAAE,OAAO,QAAQ;;EAEvC,OAAO,OAAe,YAA0C;GAC9D,MAAM,WAAW,GAAG,SAAoB;AACtC,cAAU,IAAI,MAAM,EAAE,OAAO,QAAQ;AACrC,YAAQ,GAAG,KAAK;;AAElB,OAAI,CAAC,UAAU,IAAI,MAAM,CAAE,WAAU,IAAI,uBAAO,IAAI,KAAK,CAAC;AAC1D,aAAU,IAAI,MAAM,CAAE,IAAI,QAAQ;;EAEpC,UAAU,OAAe,YAAmC;AAC1D,UAAO,IAAI,SAAS,SAAS,WAAW;IACtC,IAAI;IACJ,MAAM,WAAW,SAAkB;AACjC,SAAI,MAAO,cAAa,MAAM;AAC9B,eAAU,IAAI,MAAM,EAAE,OAAO,QAAQ;AACrC,aAAQ,KAAK;;AAEf,QAAI,CAAC,UAAU,IAAI,MAAM,CAAE,WAAU,IAAI,uBAAO,IAAI,KAAK,CAAC;AAC1D,cAAU,IAAI,MAAM,CAAE,IAAI,QAAQ;AAClC,QAAI,SAAS,QACX,SAAQ,iBAAiB;AACvB,eAAU,IAAI,MAAM,EAAE,OAAO,QAAQ;AACrC,4BAAO,IAAI,MAAM,YAAY,MAAM,qBAAqB,QAAQ,QAAQ,IAAI,CAAC;OAC5E,QAAQ,QAAQ;KAErB;;EAEJ,oBAAoB,KAAA;EACpB,eAAe;AACb,aAAU,OAAO;;EAIS,GAAG;EAAW;CAG5C,MAAM,OAAgC,EAAE;AAExC,MAAK,MAAM,CAAC,KAAK,OAAO,OAAO,QAAQ,OAAO,CAC5C,MAAK,QAAQ,GAAG,SAAoB;AAClC,QAAM,KAAK;GAAE,QAAQ;GAAK;GAAM,CAAC;AACjC,SAAQ,GAAc,GAAG,KAAK;;AAKlC,MAAK,UAAU;AACf,MAAK,cAAc,WAAmB,MAAM,QAAQ,MAAM,EAAE,WAAW,OAAO;AAC9E,MAAK,eAAe,OAAe,SAAkB;EAEnD,MAAM,WAAW,UAAU,IAAI,MAAM;AACrC,MAAI,SACF,EAAC,GAAG,SAAS,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC;;AAIzC,QAAO"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
//#region src/testing/createMockClient.ts
|
|
2
|
+
/**
|
|
3
|
+
* Create a mock AgoClient for testing. Works with any framework.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { createMockClient } from "@useago/sdk/testing";
|
|
7
|
+
*
|
|
8
|
+
* const mock = createMockClient();
|
|
9
|
+
* mock.__emitEvent("message:complete", someMessage);
|
|
10
|
+
* expect(mock.__callsFor("sendMessage")).toHaveLength(1);
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
function createMockClient(options = {}) {
|
|
14
|
+
const { overrides = {} } = options;
|
|
15
|
+
const noopMessage = {
|
|
16
|
+
id: "mock-msg-1",
|
|
17
|
+
conversationId: "mock-conv-1",
|
|
18
|
+
content: "Mock response",
|
|
19
|
+
role: "assistant",
|
|
20
|
+
status: "DONE",
|
|
21
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
22
|
+
};
|
|
23
|
+
const noopConversation = {
|
|
24
|
+
id: "mock-conv-1",
|
|
25
|
+
title: "Mock Conversation",
|
|
26
|
+
lastMessageDate: /* @__PURE__ */ new Date()
|
|
27
|
+
};
|
|
28
|
+
const listeners = /* @__PURE__ */ new Map();
|
|
29
|
+
const calls = [];
|
|
30
|
+
const merged = {
|
|
31
|
+
sendMessage: async () => noopMessage,
|
|
32
|
+
getConversations: async () => [noopConversation],
|
|
33
|
+
getConversation: async () => noopConversation,
|
|
34
|
+
getMessages: async () => [noopMessage],
|
|
35
|
+
submitToolCallForm: async () => void 0,
|
|
36
|
+
confirmToolCall: async () => void 0,
|
|
37
|
+
rejectToolCall: async () => void 0,
|
|
38
|
+
submitFeedback: async () => void 0,
|
|
39
|
+
registerFunction: () => void 0,
|
|
40
|
+
unregisterFunction: () => true,
|
|
41
|
+
getRegisteredFunctions: () => [],
|
|
42
|
+
registerNavigationFunction: () => void 0,
|
|
43
|
+
on: (event, handler) => {
|
|
44
|
+
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
45
|
+
listeners.get(event).add(handler);
|
|
46
|
+
},
|
|
47
|
+
off: (event, handler) => {
|
|
48
|
+
listeners.get(event)?.delete(handler);
|
|
49
|
+
},
|
|
50
|
+
once: (event, handler) => {
|
|
51
|
+
const wrapper = (...args) => {
|
|
52
|
+
listeners.get(event)?.delete(wrapper);
|
|
53
|
+
handler(...args);
|
|
54
|
+
};
|
|
55
|
+
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
56
|
+
listeners.get(event).add(wrapper);
|
|
57
|
+
},
|
|
58
|
+
waitFor: (event, options) => {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
let timer;
|
|
61
|
+
const handler = (data) => {
|
|
62
|
+
if (timer) clearTimeout(timer);
|
|
63
|
+
listeners.get(event)?.delete(handler);
|
|
64
|
+
resolve(data);
|
|
65
|
+
};
|
|
66
|
+
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
67
|
+
listeners.get(event).add(handler);
|
|
68
|
+
if (options?.timeout) timer = setTimeout(() => {
|
|
69
|
+
listeners.get(event)?.delete(handler);
|
|
70
|
+
reject(/* @__PURE__ */ new Error(`waitFor("${event}") timed out after ${options.timeout}ms`));
|
|
71
|
+
}, options.timeout);
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
updateConfig: () => void 0,
|
|
75
|
+
destroy: () => {
|
|
76
|
+
listeners.clear();
|
|
77
|
+
},
|
|
78
|
+
...overrides
|
|
79
|
+
};
|
|
80
|
+
const mock = {};
|
|
81
|
+
for (const [key, fn] of Object.entries(merged)) mock[key] = (...args) => {
|
|
82
|
+
calls.push({
|
|
83
|
+
method: key,
|
|
84
|
+
args
|
|
85
|
+
});
|
|
86
|
+
return fn(...args);
|
|
87
|
+
};
|
|
88
|
+
mock.__calls = calls;
|
|
89
|
+
mock.__callsFor = (method) => calls.filter((c) => c.method === method);
|
|
90
|
+
mock.__emitEvent = (event, data) => {
|
|
91
|
+
const handlers = listeners.get(event);
|
|
92
|
+
if (handlers) [...handlers].forEach((h) => h(data));
|
|
93
|
+
};
|
|
94
|
+
return mock;
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
export { createMockClient as t };
|
|
98
|
+
|
|
99
|
+
//# sourceMappingURL=createMockClient-U0ae_AYy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createMockClient-U0ae_AYy.js","names":[],"sources":["../src/testing/createMockClient.ts"],"sourcesContent":["import type { AgoClient } from \"../client/AgoClient\";\nimport type {\n AgoClientEvents,\n AgoEventName,\n AgoMessage,\n Conversation,\n} from \"../client/types\";\nimport type { ClientFunctionSchema } from \"../functions/types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype MockFn = (...args: any[]) => any;\n\nexport interface MockAgoClientOptions {\n overrides?: Partial<Record<string, MockFn>>;\n}\n\nexport interface MockAgoClient extends AgoClient {\n /**\n * Simulate a server-pushed event.\n * ```ts\n * mock.__emitEvent(\"message:complete\", { id: \"1\", content: \"hi\", ... });\n * ```\n */\n __emitEvent<K extends AgoEventName>(event: K, data: AgoClientEvents[K]): void;\n\n /**\n * All recorded method calls: `[methodName, ...args][]`\n */\n __calls: Array<{ method: string; args: unknown[] }>;\n\n /**\n * Get calls for a specific method.\n */\n __callsFor(method: string): Array<{ method: string; args: unknown[] }>;\n}\n\n/**\n * Create a mock AgoClient for testing. Works with any framework.\n *\n * ```ts\n * import { createMockClient } from \"@useago/sdk/testing\";\n *\n * const mock = createMockClient();\n * mock.__emitEvent(\"message:complete\", someMessage);\n * expect(mock.__callsFor(\"sendMessage\")).toHaveLength(1);\n * ```\n */\nexport function createMockClient(\n options: MockAgoClientOptions = {}\n): MockAgoClient {\n const { overrides = {} } = options;\n\n const noopMessage: AgoMessage = {\n id: \"mock-msg-1\",\n conversationId: \"mock-conv-1\",\n content: \"Mock response\",\n role: \"assistant\",\n status: \"DONE\",\n createdAt: new Date(),\n };\n\n const noopConversation: Conversation = {\n id: \"mock-conv-1\",\n title: \"Mock Conversation\",\n lastMessageDate: new Date(),\n };\n\n const listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n const calls: Array<{ method: string; args: unknown[] }> = [];\n\n const defaults: Record<string, MockFn> = {\n sendMessage: async () => noopMessage,\n getConversations: async () => [noopConversation],\n getConversation: async () => noopConversation,\n getMessages: async () => [noopMessage],\n submitToolCallForm: async () => undefined,\n confirmToolCall: async () => undefined,\n rejectToolCall: async () => undefined,\n submitFeedback: async () => undefined,\n registerFunction: () => undefined,\n unregisterFunction: () => true,\n getRegisteredFunctions: () => [] as ClientFunctionSchema[],\n registerNavigationFunction: () => undefined,\n on: (event: string, handler: (...args: unknown[]) => void) => {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n },\n off: (event: string, handler: (...args: unknown[]) => void) => {\n listeners.get(event)?.delete(handler);\n },\n once: (event: string, handler: (...args: unknown[]) => void) => {\n const wrapper = (...args: unknown[]) => {\n listeners.get(event)?.delete(wrapper);\n handler(...args);\n };\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(wrapper);\n },\n waitFor: (event: string, options?: { timeout?: number }) => {\n return new Promise((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const handler = (data: unknown) => {\n if (timer) clearTimeout(timer);\n listeners.get(event)?.delete(handler);\n resolve(data);\n };\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n if (options?.timeout) {\n timer = setTimeout(() => {\n listeners.get(event)?.delete(handler);\n reject(new Error(`waitFor(\"${event}\") timed out after ${options.timeout}ms`));\n }, options.timeout);\n }\n });\n },\n updateConfig: () => undefined,\n destroy: () => {\n listeners.clear();\n },\n };\n\n const merged = { ...defaults, ...overrides } as Record<string, MockFn>;\n\n // Wrap all methods to record calls\n const mock: Record<string, unknown> = {};\n\n for (const [key, fn] of Object.entries(merged)) {\n mock[key] = (...args: unknown[]) => {\n calls.push({ method: key, args });\n return (fn as MockFn)(...args);\n };\n }\n\n // Test helpers (not recorded)\n mock.__calls = calls;\n mock.__callsFor = (method: string) => calls.filter((c) => c.method === method);\n mock.__emitEvent = (event: string, data: unknown) => {\n // Copy the set to avoid mutation during iteration (once handlers remove themselves)\n const handlers = listeners.get(event);\n if (handlers) {\n [...handlers].forEach((h) => h(data));\n }\n };\n\n return mock as unknown as MockAgoClient;\n}\n"],"mappings":";;;;;;;;;;;;AA+CA,SAAgB,iBACd,UAAgC,EAAE,EACnB;CACf,MAAM,EAAE,YAAY,EAAE,KAAK;CAE3B,MAAM,cAA0B;EAC9B,IAAI;EACJ,gBAAgB;EAChB,SAAS;EACT,MAAM;EACN,QAAQ;EACR,2BAAW,IAAI,MAAM;EACtB;CAED,MAAM,mBAAiC;EACrC,IAAI;EACJ,OAAO;EACP,iCAAiB,IAAI,MAAM;EAC5B;CAED,MAAM,4BAAY,IAAI,KAAgD;CACtE,MAAM,QAAoD,EAAE;CAsD5D,MAAM,SAAS;EAnDb,aAAa,YAAY;EACzB,kBAAkB,YAAY,CAAC,iBAAiB;EAChD,iBAAiB,YAAY;EAC7B,aAAa,YAAY,CAAC,YAAY;EACtC,oBAAoB,YAAY,KAAA;EAChC,iBAAiB,YAAY,KAAA;EAC7B,gBAAgB,YAAY,KAAA;EAC5B,gBAAgB,YAAY,KAAA;EAC5B,wBAAwB,KAAA;EACxB,0BAA0B;EAC1B,8BAA8B,EAAE;EAChC,kCAAkC,KAAA;EAClC,KAAK,OAAe,YAA0C;AAC5D,OAAI,CAAC,UAAU,IAAI,MAAM,CAAE,WAAU,IAAI,uBAAO,IAAI,KAAK,CAAC;AAC1D,aAAU,IAAI,MAAM,CAAE,IAAI,QAAQ;;EAEpC,MAAM,OAAe,YAA0C;AAC7D,aAAU,IAAI,MAAM,EAAE,OAAO,QAAQ;;EAEvC,OAAO,OAAe,YAA0C;GAC9D,MAAM,WAAW,GAAG,SAAoB;AACtC,cAAU,IAAI,MAAM,EAAE,OAAO,QAAQ;AACrC,YAAQ,GAAG,KAAK;;AAElB,OAAI,CAAC,UAAU,IAAI,MAAM,CAAE,WAAU,IAAI,uBAAO,IAAI,KAAK,CAAC;AAC1D,aAAU,IAAI,MAAM,CAAE,IAAI,QAAQ;;EAEpC,UAAU,OAAe,YAAmC;AAC1D,UAAO,IAAI,SAAS,SAAS,WAAW;IACtC,IAAI;IACJ,MAAM,WAAW,SAAkB;AACjC,SAAI,MAAO,cAAa,MAAM;AAC9B,eAAU,IAAI,MAAM,EAAE,OAAO,QAAQ;AACrC,aAAQ,KAAK;;AAEf,QAAI,CAAC,UAAU,IAAI,MAAM,CAAE,WAAU,IAAI,uBAAO,IAAI,KAAK,CAAC;AAC1D,cAAU,IAAI,MAAM,CAAE,IAAI,QAAQ;AAClC,QAAI,SAAS,QACX,SAAQ,iBAAiB;AACvB,eAAU,IAAI,MAAM,EAAE,OAAO,QAAQ;AACrC,4BAAO,IAAI,MAAM,YAAY,MAAM,qBAAqB,QAAQ,QAAQ,IAAI,CAAC;OAC5E,QAAQ,QAAQ;KAErB;;EAEJ,oBAAoB,KAAA;EACpB,eAAe;AACb,aAAU,OAAO;;EAIS,GAAG;EAAW;CAG5C,MAAM,OAAgC,EAAE;AAExC,MAAK,MAAM,CAAC,KAAK,OAAO,OAAO,QAAQ,OAAO,CAC5C,MAAK,QAAQ,GAAG,SAAoB;AAClC,QAAM,KAAK;GAAE,QAAQ;GAAK;GAAM,CAAC;AACjC,SAAQ,GAAc,GAAG,KAAK;;AAKlC,MAAK,UAAU;AACf,MAAK,cAAc,WAAmB,MAAM,QAAQ,MAAM,EAAE,WAAW,OAAO;AAC9E,MAAK,eAAe,OAAe,SAAkB;EAEnD,MAAM,WAAW,UAAU,IAAI,MAAM;AACrC,MAAI,SACF,EAAC,GAAG,SAAS,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC;;AAIzC,QAAO"}
|