@useago/sdk 0.3.2 → 0.3.4
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/AgoClient-DF7M2WAz.js +575 -0
- package/dist/AgoClient-bjN-z2ZQ.cjs +6 -0
- package/dist/angular.cjs +1 -143
- package/dist/angular.d.cts +530 -0
- package/dist/angular.d.ts +530 -2
- package/dist/angular.js +71 -139
- package/dist/createFormCollector-ClzHfaBd.js +185 -0
- package/dist/createFormCollector-H4Me_2uj.cjs +1 -0
- package/dist/createMockClient-C50gjV0b.js +71 -0
- package/dist/createMockClient-DQvFFWnc.cjs +1 -0
- package/dist/devtools.cjs +26 -100
- package/dist/devtools.d.cts +443 -0
- package/dist/devtools.d.ts +443 -2
- package/dist/devtools.js +68 -93
- package/dist/functions-BH1X5kas.cjs +1 -0
- package/dist/functions-CWSRi3xv.js +312 -0
- package/dist/helpers.cjs +1 -15
- package/dist/{helpers/functions.d.ts → helpers.d.cts} +121 -62
- package/dist/helpers.d.ts +121 -2
- package/dist/helpers.js +16 -2
- package/dist/index.cjs +1 -347
- package/dist/index.d.cts +1150 -0
- package/dist/index.d.ts +1150 -20
- package/dist/index.js +129 -298
- package/dist/react.cjs +31 -22438
- package/dist/react.d.cts +999 -0
- package/dist/react.d.ts +999 -2
- package/dist/react.js +8416 -22376
- package/dist/rolldown-runtime-CaekUdDJ.cjs +1 -0
- package/dist/rolldown-runtime-DxmricAu.js +25 -0
- package/dist/vue.cjs +1 -336
- package/dist/vue.d.cts +1063 -0
- package/dist/vue.d.ts +1063 -2
- package/dist/vue.js +174 -316
- package/dist/widget.cjs +1 -0
- package/dist/widget.d.cts +577 -0
- package/dist/widget.d.ts +577 -2
- package/dist/widget.js +398 -0
- package/package.json +35 -24
- package/dist/AgoClient-DPZdN5n2.js +0 -905
- package/dist/AgoClient-DPZdN5n2.js.map +0 -1
- package/dist/AgoClient-wMVUQqCD.cjs +0 -976
- package/dist/AgoClient-wMVUQqCD.cjs.map +0 -1
- package/dist/angular/ago.service.d.ts +0 -98
- package/dist/angular/index.d.ts +0 -4
- package/dist/angular/provide.d.ts +0 -27
- package/dist/angular.cjs.map +0 -1
- package/dist/angular.js.map +0 -1
- package/dist/api/HttpClient.d.ts +0 -31
- package/dist/api/index.d.ts +0 -1
- package/dist/auto/createAgo.d.ts +0 -39
- package/dist/auto/index.d.ts +0 -1
- package/dist/client/AgoClient.d.ts +0 -169
- package/dist/client/errors.d.ts +0 -48
- package/dist/client/index.d.ts +0 -3
- package/dist/client/types.d.ts +0 -205
- package/dist/createMockClient-Ci_N2tH8.cjs +0 -104
- package/dist/createMockClient-Ci_N2tH8.cjs.map +0 -1
- package/dist/createMockClient-U0ae_AYy.js +0 -99
- package/dist/createMockClient-U0ae_AYy.js.map +0 -1
- package/dist/devtools/index.d.ts +0 -2
- package/dist/devtools/initDevPanel.d.ts +0 -15
- package/dist/devtools.cjs.map +0 -1
- package/dist/devtools.js.map +0 -1
- package/dist/functions/FunctionRegistry.d.ts +0 -41
- package/dist/functions/defineFunction.d.ts +0 -22
- package/dist/functions/index.d.ts +0 -2
- package/dist/functions/types.d.ts +0 -50
- package/dist/functions--c6lx3ic.cjs +0 -480
- package/dist/functions--c6lx3ic.cjs.map +0 -1
- package/dist/functions-C9F1dnmh.js +0 -398
- package/dist/functions-C9F1dnmh.js.map +0 -1
- package/dist/helpers/factory.d.ts +0 -20
- package/dist/helpers/index.d.ts +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/react/components/ChatInput.d.ts +0 -12
- package/dist/react/components/ChatWidget.d.ts +0 -35
- package/dist/react/components/Markdown.d.ts +0 -12
- package/dist/react/components/Message.d.ts +0 -9
- package/dist/react/components/index.d.ts +0 -8
- package/dist/react/context/AgoContext.d.ts +0 -62
- package/dist/react/context/index.d.ts +0 -2
- package/dist/react/hooks/index.d.ts +0 -7
- package/dist/react/hooks/useAgo.d.ts +0 -14
- package/dist/react/hooks/useAgoContext.d.ts +0 -40
- package/dist/react/hooks/useAgoFunction.d.ts +0 -58
- package/dist/react/hooks/useAgoStore.d.ts +0 -17
- package/dist/react/hooks/useChat.d.ts +0 -45
- package/dist/react/hooks/useConversation.d.ts +0 -28
- package/dist/react/hooks/useMessages.d.ts +0 -26
- package/dist/react/index.d.ts +0 -24
- package/dist/react/testing.d.ts +0 -2
- package/dist/react.cjs.map +0 -1
- package/dist/react.js.map +0 -1
- package/dist/rolldown-runtime-BqCkTl7Q.cjs +0 -50
- package/dist/rolldown-runtime-CNZpIYwj.js +0 -33
- package/dist/state/ClientContextRegistry.d.ts +0 -64
- package/dist/state/createStore.d.ts +0 -30
- package/dist/streaming/SSEHandler.d.ts +0 -46
- package/dist/streaming/helpers.d.ts +0 -67
- package/dist/streaming/index.d.ts +0 -2
- package/dist/testing/createMockClient.d.ts +0 -42
- package/dist/testing/index.d.ts +0 -2
- package/dist/utils/eventEmitter.d.ts +0 -23
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/logger.d.ts +0 -14
- package/dist/vue/composables/useAgo.d.ts +0 -17
- package/dist/vue/composables/useAgoEvents.d.ts +0 -11
- package/dist/vue/composables/useAgoFunction.d.ts +0 -34
- package/dist/vue/composables/useAgoStore.d.ts +0 -18
- package/dist/vue/composables/useChat.d.ts +0 -251
- package/dist/vue/composables/useConversation.d.ts +0 -178
- package/dist/vue/composables/useMessages.d.ts +0 -89
- package/dist/vue/index.d.ts +0 -11
- package/dist/vue/plugin.d.ts +0 -16
- package/dist/vue/symbols.d.ts +0 -3
- package/dist/vue.cjs.map +0 -1
- package/dist/vue.js.map +0 -1
- package/dist/widget/index.d.ts +0 -1
- package/dist/widget/types.d.ts +0 -43
package/dist/client/types.d.ts
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SDK Configuration
|
|
3
|
-
*/
|
|
4
|
-
export interface AgoConfig {
|
|
5
|
-
/** API base URL (e.g., https://YOUR-DOMAIN.useago.com) */
|
|
6
|
-
baseUrl: string;
|
|
7
|
-
/** Widget ID (X-Widget-Id header). Auto-generated if not provided. */
|
|
8
|
-
widgetId?: string;
|
|
9
|
-
/** Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`. */
|
|
10
|
-
agent?: string;
|
|
11
|
-
/** Default agent ID for new conversations. Prefer `agent`. */
|
|
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;
|
|
15
|
-
/** User email for identification */
|
|
16
|
-
userEmail?: string;
|
|
17
|
-
/** JWT token for authenticated users */
|
|
18
|
-
userJwt?: string;
|
|
19
|
-
/** Enable debug logging */
|
|
20
|
-
debug?: boolean;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Options for sending a message
|
|
24
|
-
*/
|
|
25
|
-
export interface SendMessageOptions {
|
|
26
|
-
/** Existing conversation ID */
|
|
27
|
-
conversationId?: string;
|
|
28
|
-
/** Override default agent */
|
|
29
|
-
agentId?: string;
|
|
30
|
-
/** File attachments */
|
|
31
|
-
files?: File[];
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Message from AGO
|
|
35
|
-
*/
|
|
36
|
-
export interface AgoMessage {
|
|
37
|
-
id: string;
|
|
38
|
-
conversationId: string;
|
|
39
|
-
content: string;
|
|
40
|
-
role: "user" | "assistant";
|
|
41
|
-
status: MessageStatus;
|
|
42
|
-
agent?: AgoAgent;
|
|
43
|
-
sources?: AgoSource[];
|
|
44
|
-
toolCalls?: ToolCallData[];
|
|
45
|
-
followUpReplies?: string[];
|
|
46
|
-
createdAt: Date;
|
|
47
|
-
}
|
|
48
|
-
export type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCELED";
|
|
49
|
-
/**
|
|
50
|
-
* Agent information
|
|
51
|
-
*/
|
|
52
|
-
export interface AgoAgent {
|
|
53
|
-
id: string;
|
|
54
|
-
name: string;
|
|
55
|
-
displayName?: string;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Knowledge source citation
|
|
59
|
-
*/
|
|
60
|
-
export interface AgoSource {
|
|
61
|
-
id: string;
|
|
62
|
-
title: string;
|
|
63
|
-
url?: string;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Conversation/Thread
|
|
67
|
-
*/
|
|
68
|
-
export interface Conversation {
|
|
69
|
-
id: string;
|
|
70
|
-
title: string;
|
|
71
|
-
lastMessageDate: Date;
|
|
72
|
-
messages?: AgoMessage[];
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Tool call data from SSE stream
|
|
76
|
-
*/
|
|
77
|
-
export interface ToolCallData {
|
|
78
|
-
id: string;
|
|
79
|
-
type: ToolCallType;
|
|
80
|
-
status: string;
|
|
81
|
-
toolName: string;
|
|
82
|
-
toolDisplayName?: string;
|
|
83
|
-
message?: string;
|
|
84
|
-
formSchema?: FormSchema;
|
|
85
|
-
data?: Record<string, unknown>;
|
|
86
|
-
functionName?: string;
|
|
87
|
-
arguments?: Record<string, unknown>;
|
|
88
|
-
}
|
|
89
|
-
export type ToolCallType = "form" | "confirmation_input" | "status_message" | "progress_indicator" | "client_function" | "reasoning" | "mcp_ui_resource";
|
|
90
|
-
/**
|
|
91
|
-
* Form schema for tool calls requiring user input
|
|
92
|
-
*/
|
|
93
|
-
export interface FormSchema {
|
|
94
|
-
type: "object";
|
|
95
|
-
properties: Record<string, FormField>;
|
|
96
|
-
required?: string[];
|
|
97
|
-
}
|
|
98
|
-
export interface FormField {
|
|
99
|
-
type: "string" | "number" | "boolean" | "array";
|
|
100
|
-
title?: string;
|
|
101
|
-
description?: string;
|
|
102
|
-
enum?: string[];
|
|
103
|
-
default?: unknown;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Client-side function types
|
|
107
|
-
*/
|
|
108
|
-
export interface FunctionSchema {
|
|
109
|
-
name: string;
|
|
110
|
-
description: string;
|
|
111
|
-
parameters: {
|
|
112
|
-
type: "object";
|
|
113
|
-
properties: Record<string, {
|
|
114
|
-
type: string;
|
|
115
|
-
description?: string;
|
|
116
|
-
enum?: string[];
|
|
117
|
-
}>;
|
|
118
|
-
required?: string[];
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
export type ClientFunction = (args: Record<string, unknown>) => Promise<unknown> | unknown;
|
|
122
|
-
export interface FunctionDefinition {
|
|
123
|
-
name: string;
|
|
124
|
-
schema: FunctionSchema;
|
|
125
|
-
handler: ClientFunction;
|
|
126
|
-
}
|
|
127
|
-
export interface ClientFunctionInvocation {
|
|
128
|
-
invocationId: string;
|
|
129
|
-
functionName: string;
|
|
130
|
-
arguments: Record<string, unknown>;
|
|
131
|
-
conversationId: string;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* SSE stream chunk data
|
|
135
|
-
*/
|
|
136
|
-
export interface SSEChunkData {
|
|
137
|
-
content?: string;
|
|
138
|
-
full_content?: string;
|
|
139
|
-
message_id?: string;
|
|
140
|
-
status?: MessageStatus;
|
|
141
|
-
thread?: {
|
|
142
|
-
id: string;
|
|
143
|
-
};
|
|
144
|
-
agent?: {
|
|
145
|
-
id: string;
|
|
146
|
-
name: string;
|
|
147
|
-
display_name?: string;
|
|
148
|
-
};
|
|
149
|
-
knowledge_sources?: Array<{
|
|
150
|
-
knowledge_document: {
|
|
151
|
-
id: string;
|
|
152
|
-
title: string;
|
|
153
|
-
use_external_link: boolean;
|
|
154
|
-
external_link_url?: string;
|
|
155
|
-
internal_link_url?: string;
|
|
156
|
-
};
|
|
157
|
-
position: number;
|
|
158
|
-
}>;
|
|
159
|
-
tool_call_data?: boolean;
|
|
160
|
-
type?: string;
|
|
161
|
-
id?: string;
|
|
162
|
-
tool_name?: string;
|
|
163
|
-
tool_display_name?: string;
|
|
164
|
-
function_name?: string;
|
|
165
|
-
arguments?: Record<string, unknown>;
|
|
166
|
-
form_schema?: FormSchema;
|
|
167
|
-
message?: string;
|
|
168
|
-
data?: Record<string, unknown>;
|
|
169
|
-
follow_up_replies?: string[];
|
|
170
|
-
satisfaction_feedback?: unknown;
|
|
171
|
-
ask_to_talk_to_human?: boolean;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* SDK Events
|
|
175
|
-
*/
|
|
176
|
-
export interface AgoClientEvents {
|
|
177
|
-
"message:start": {
|
|
178
|
-
conversationId: string;
|
|
179
|
-
messageId: string;
|
|
180
|
-
};
|
|
181
|
-
"message:chunk": {
|
|
182
|
-
content: string;
|
|
183
|
-
conversationId: string;
|
|
184
|
-
messageId: string;
|
|
185
|
-
};
|
|
186
|
-
"message:complete": AgoMessage;
|
|
187
|
-
"message:error": {
|
|
188
|
-
error: string;
|
|
189
|
-
conversationId?: string;
|
|
190
|
-
messageId?: string;
|
|
191
|
-
};
|
|
192
|
-
"toolCall:received": ToolCallData;
|
|
193
|
-
"toolCall:form": ToolCallData;
|
|
194
|
-
"function:invoke": ClientFunctionInvocation;
|
|
195
|
-
"function:result": {
|
|
196
|
-
invocationId: string;
|
|
197
|
-
result: unknown;
|
|
198
|
-
error?: string;
|
|
199
|
-
};
|
|
200
|
-
"connection:status": {
|
|
201
|
-
connected: boolean;
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
export type AgoEventName = keyof AgoClientEvents;
|
|
205
|
-
export type AgoEventHandler<K extends AgoEventName> = (data: AgoClientEvents[K]) => void;
|
|
@@ -1,104 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,99 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
package/dist/devtools/index.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { AgoClient } from "../client/AgoClient";
|
|
2
|
-
import type { Store } from "../state/createStore";
|
|
3
|
-
/** Options for {@link initDevPanel}. */
|
|
4
|
-
export interface DevPanelOptions {
|
|
5
|
-
/** The store whose state the panel renders live. */
|
|
6
|
-
store: Store<unknown>;
|
|
7
|
-
/**
|
|
8
|
-
* Client to read registered functions from and listen to function events on.
|
|
9
|
-
* Typed structurally so a mock client works too.
|
|
10
|
-
*/
|
|
11
|
-
client: Pick<AgoClient, "on" | "getRegisteredFunctions">;
|
|
12
|
-
/** Where to mount: a CSS selector, an Element, or `document.body` (default). */
|
|
13
|
-
target?: string | Element;
|
|
14
|
-
}
|
|
15
|
-
export declare function initDevPanel(options: DevPanelOptions): void;
|
package/dist/devtools.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.cjs","names":[],"sources":["../src/devtools/initDevPanel.ts"],"sourcesContent":["import type { AgoClient } from \"../client/AgoClient\";\nimport type { Store } from \"../state/createStore\";\n\n/** Options for {@link initDevPanel}. */\nexport interface DevPanelOptions {\n /** The store whose state the panel renders live. */\n store: Store<unknown>;\n /**\n * Client to read registered functions from and listen to function events on.\n * Typed structurally so a mock client works too.\n */\n client: Pick<AgoClient, \"on\" | \"getRegisteredFunctions\">;\n /** Where to mount: a CSS selector, an Element, or `document.body` (default). */\n target?: string | Element;\n}\n\nlet stateEl: HTMLElement | null;\nlet logEl: HTMLElement | null;\nlet getStateFn: () => unknown = () => ({});\n\n// Re-render the JSON object. Wired to the store's subscribe() in initDevPanel.\nfunction renderState(): void {\n if (!stateEl) return;\n stateEl.textContent = JSON.stringify(getStateFn(), null, 2);\n}\n\nfunction logLine(text: string, kind: \"invoke\" | \"result\" | \"error\"): void {\n if (!logEl) return;\n const line = document.createElement(\"div\");\n line.className = `dev-log-line dev-log-${kind}`;\n const time = new Date().toLocaleTimeString();\n line.textContent = `${time} ${text}`;\n logEl.appendChild(line);\n logEl.scrollTop = logEl.scrollHeight;\n}\n\nconst COLLAPSE_KEY = \"devPanelCollapsed\";\n\nfunction setCollapsed(panel: HTMLElement, collapsed: boolean): void {\n panel.classList.toggle(\"collapsed\", collapsed);\n const toggle = panel.querySelector<HTMLButtonElement>(\".dev-toggle\");\n if (toggle) {\n toggle.textContent = collapsed ? \"▢\" : \"—\";\n toggle.title = collapsed ? \"Expand dev tools\" : \"Collapse dev tools\";\n toggle.setAttribute(\"aria-expanded\", String(!collapsed));\n }\n try {\n localStorage.setItem(COLLAPSE_KEY, collapsed ? \"1\" : \"0\");\n } catch {\n // localStorage may be unavailable; collapse state just won't persist.\n }\n}\n\nexport function initDevPanel(options: DevPanelOptions): void {\n const { store, client, target } = options;\n getStateFn = store.get;\n injectStyles();\n const host =\n typeof target === \"string\"\n ? document.querySelector(target)\n : target instanceof Element\n ? target\n : document.body;\n const panel = document.createElement(\"aside\");\n panel.id = \"dev-panel\";\n (host ?? document.body).appendChild(panel);\n\n const registered = client.getRegisteredFunctions?.() ?? [];\n const fnNames = registered.map((f) => f.name).join(\", \") || \"—\";\n\n panel.innerHTML = `\n <div class=\"dev-head\">\n <span class=\"dev-badge\">DEV</span>\n <span class=\"dev-title\">DEV TOOLS · client-side function state — not for production</span>\n <button type=\"button\" class=\"dev-toggle\" aria-label=\"Toggle dev tools\">—</button>\n </div>\n <div class=\"dev-body\">\n <div class=\"dev-fns\">Registered functions: <code>${fnNames}</code></div>\n <div class=\"dev-section-label\">JSON object (built by the agent)</div>\n <pre class=\"dev-state\" id=\"dev-state\"></pre>\n <div class=\"dev-section-label\">Function calls</div>\n <div class=\"dev-log\" id=\"dev-log\"></div>\n </div>\n `;\n\n stateEl = panel.querySelector<HTMLElement>(\"#dev-state\");\n logEl = panel.querySelector<HTMLElement>(\"#dev-log\");\n\n const toggle = panel.querySelector<HTMLButtonElement>(\".dev-toggle\");\n toggle?.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n setCollapsed(panel, !panel.classList.contains(\"collapsed\"));\n });\n // When collapsed, the whole widget acts as an expand button.\n panel.addEventListener(\"click\", () => {\n if (panel.classList.contains(\"collapsed\")) setCollapsed(panel, false);\n });\n\n let startCollapsed = false;\n try {\n startCollapsed = localStorage.getItem(COLLAPSE_KEY) === \"1\";\n } catch {\n // ignore\n }\n setCollapsed(panel, startCollapsed);\n\n client.on(\"function:invoke\", ({ functionName, arguments: args }) => {\n logLine(`→ ${functionName}(${JSON.stringify(args ?? {})})`, \"invoke\");\n });\n client.on(\"function:result\", ({ result, error }) => {\n logLine(\n error ? `✗ error: ${error}` : `← ${JSON.stringify(result)}`,\n error ? \"error\" : \"result\",\n );\n });\n\n // Re-render the JSON object on every state change, then paint the initial state.\n store.subscribe(renderState);\n renderState();\n}\n\nconst STYLE_ID = \"dev-panel-styles\";\n\nfunction injectStyles(): void {\n if (document.getElementById(STYLE_ID)) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = PANEL_CSS;\n document.head.appendChild(style);\n}\n\nconst PANEL_CSS = `\n#dev-panel {\n position: fixed;\n top: 16px;\n right: 16px;\n width: min(360px, calc(100vw - 32px));\n max-width: calc(100vw - 32px);\n box-sizing: border-box;\n max-height: calc(100vh - 32px);\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px 14px;\n background: #0f1419;\n color: #d7e0e8;\n border: 1px solid #2a3441;\n border-radius: 12px;\n box-shadow: 0 20px 50px -20px rgba(0,0,0,.6);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n z-index: 1000;\n}\n#dev-panel .dev-head { display: flex; align-items: center; gap: 8px; }\n#dev-panel .dev-toggle {\n margin-left: auto;\n flex: none;\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: #7c8a99;\n border: 1px solid #2a3441;\n border-radius: 6px;\n font-size: 12px;\n line-height: 1;\n cursor: pointer;\n}\n#dev-panel .dev-toggle:hover { color: #d7e0e8; border-color: #3a4655; }\n#dev-panel .dev-body { display: flex; flex-direction: column; gap: 8px; }\n\n/* Collapsed: shrink to a small clickable widget showing only the DEV badge. */\n#dev-panel.collapsed {\n width: auto;\n cursor: pointer;\n padding: 8px 10px;\n}\n#dev-panel.collapsed .dev-title,\n#dev-panel.collapsed .dev-body { display: none; }\n#dev-panel.collapsed .dev-toggle { margin-left: 6px; }\n#dev-panel .dev-badge {\n background: #f59e0b;\n color: #1c1206;\n font-weight: 700;\n font-size: 10px;\n letter-spacing: .08em;\n padding: 2px 6px;\n border-radius: 5px;\n}\n#dev-panel .dev-title { color: #f59e0b; font-size: 11px; line-height: 1.3; }\n#dev-panel .dev-fns { color: #7c8a99; font-size: 11px; }\n#dev-panel .dev-fns code { color: #9ecbff; }\n#dev-panel .dev-section-label {\n color: #7c8a99;\n text-transform: uppercase;\n letter-spacing: .08em;\n font-size: 10px;\n margin-top: 4px;\n}\n#dev-panel .dev-state {\n margin: 0;\n padding: 8px;\n background: #060a0e;\n border-radius: 8px;\n overflow: auto;\n max-height: 40vh;\n white-space: pre;\n color: #c8e6c9;\n}\n#dev-panel .dev-log {\n display: flex;\n flex-direction: column;\n gap: 2px;\n overflow-y: auto;\n max-height: 24vh;\n background: #060a0e;\n border-radius: 8px;\n padding: 6px 8px;\n}\n#dev-panel .dev-log-line { white-space: pre-wrap; word-break: break-word; line-height: 1.4; }\n#dev-panel .dev-log-invoke { color: #9ecbff; }\n#dev-panel .dev-log-result { color: #86efac; }\n#dev-panel .dev-log-error { color: #fca5a5; }\n`;\n"],"mappings":";;AAgBA,IAAI;AACJ,IAAI;AACJ,IAAI,oBAAmC,EAAE;AAGzC,SAAS,cAAoB;AAC3B,KAAI,CAAC,QAAS;AACd,SAAQ,cAAc,KAAK,UAAU,YAAY,EAAE,MAAM,EAAE;;AAG7D,SAAS,QAAQ,MAAc,MAA2C;AACxE,KAAI,CAAC,MAAO;CACZ,MAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,MAAK,YAAY,wBAAwB;AAEzC,MAAK,cAAc,oBADN,IAAI,MAAM,EAAC,oBACF,CAAK,IAAI;AAC/B,OAAM,YAAY,KAAK;AACvB,OAAM,YAAY,MAAM;;AAG1B,IAAM,eAAe;AAErB,SAAS,aAAa,OAAoB,WAA0B;AAClE,OAAM,UAAU,OAAO,aAAa,UAAU;CAC9C,MAAM,SAAS,MAAM,cAAiC,cAAc;AACpE,KAAI,QAAQ;AACV,SAAO,cAAc,YAAY,MAAM;AACvC,SAAO,QAAQ,YAAY,qBAAqB;AAChD,SAAO,aAAa,iBAAiB,OAAO,CAAC,UAAU,CAAC;;AAE1D,KAAI;AACF,eAAa,QAAQ,cAAc,YAAY,MAAM,IAAI;SACnD;;AAKV,SAAgB,aAAa,SAAgC;CAC3D,MAAM,EAAE,OAAO,QAAQ,WAAW;AAClC,cAAa,MAAM;AACnB,eAAc;CACd,MAAM,OACJ,OAAO,WAAW,WACd,SAAS,cAAc,OAAO,GAC9B,kBAAkB,UAChB,SACA,SAAS;CACjB,MAAM,QAAQ,SAAS,cAAc,QAAQ;AAC7C,OAAM,KAAK;AACX,EAAC,QAAQ,SAAS,MAAM,YAAY,MAAM;AAK1C,OAAM,YAAY;;;;;;;0DAHC,OAAO,0BAA0B,IAAI,EAAE,EAC/B,KAAK,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,IAAI,IASG;;;;;;;AAQ/D,WAAU,MAAM,cAA2B,aAAa;AACxD,SAAQ,MAAM,cAA2B,WAAW;AAErC,OAAM,cAAiC,cACtD,EAAQ,iBAAiB,UAAU,MAAM;AACvC,IAAE,iBAAiB;AACnB,eAAa,OAAO,CAAC,MAAM,UAAU,SAAS,YAAY,CAAC;GAC3D;AAEF,OAAM,iBAAiB,eAAe;AACpC,MAAI,MAAM,UAAU,SAAS,YAAY,CAAE,cAAa,OAAO,MAAM;GACrE;CAEF,IAAI,iBAAiB;AACrB,KAAI;AACF,mBAAiB,aAAa,QAAQ,aAAa,KAAK;SAClD;AAGR,cAAa,OAAO,eAAe;AAEnC,QAAO,GAAG,oBAAoB,EAAE,cAAc,WAAW,WAAW;AAClE,UAAQ,KAAK,aAAa,GAAG,KAAK,UAAU,QAAQ,EAAE,CAAC,CAAC,IAAI,SAAS;GACrE;AACF,QAAO,GAAG,oBAAoB,EAAE,QAAQ,YAAY;AAClD,UACE,QAAQ,YAAY,UAAU,KAAK,KAAK,UAAU,OAAO,IACzD,QAAQ,UAAU,SACnB;GACD;AAGF,OAAM,UAAU,YAAY;AAC5B,cAAa;;AAGf,IAAM,WAAW;AAEjB,SAAS,eAAqB;AAC5B,KAAI,SAAS,eAAe,SAAS,CAAE;CACvC,MAAM,QAAQ,SAAS,cAAc,QAAQ;AAC7C,OAAM,KAAK;AACX,OAAM,cAAc;AACpB,UAAS,KAAK,YAAY,MAAM;;AAGlC,IAAM,YAAY"}
|
package/dist/devtools.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.js","names":[],"sources":["../src/devtools/initDevPanel.ts"],"sourcesContent":["import type { AgoClient } from \"../client/AgoClient\";\nimport type { Store } from \"../state/createStore\";\n\n/** Options for {@link initDevPanel}. */\nexport interface DevPanelOptions {\n /** The store whose state the panel renders live. */\n store: Store<unknown>;\n /**\n * Client to read registered functions from and listen to function events on.\n * Typed structurally so a mock client works too.\n */\n client: Pick<AgoClient, \"on\" | \"getRegisteredFunctions\">;\n /** Where to mount: a CSS selector, an Element, or `document.body` (default). */\n target?: string | Element;\n}\n\nlet stateEl: HTMLElement | null;\nlet logEl: HTMLElement | null;\nlet getStateFn: () => unknown = () => ({});\n\n// Re-render the JSON object. Wired to the store's subscribe() in initDevPanel.\nfunction renderState(): void {\n if (!stateEl) return;\n stateEl.textContent = JSON.stringify(getStateFn(), null, 2);\n}\n\nfunction logLine(text: string, kind: \"invoke\" | \"result\" | \"error\"): void {\n if (!logEl) return;\n const line = document.createElement(\"div\");\n line.className = `dev-log-line dev-log-${kind}`;\n const time = new Date().toLocaleTimeString();\n line.textContent = `${time} ${text}`;\n logEl.appendChild(line);\n logEl.scrollTop = logEl.scrollHeight;\n}\n\nconst COLLAPSE_KEY = \"devPanelCollapsed\";\n\nfunction setCollapsed(panel: HTMLElement, collapsed: boolean): void {\n panel.classList.toggle(\"collapsed\", collapsed);\n const toggle = panel.querySelector<HTMLButtonElement>(\".dev-toggle\");\n if (toggle) {\n toggle.textContent = collapsed ? \"▢\" : \"—\";\n toggle.title = collapsed ? \"Expand dev tools\" : \"Collapse dev tools\";\n toggle.setAttribute(\"aria-expanded\", String(!collapsed));\n }\n try {\n localStorage.setItem(COLLAPSE_KEY, collapsed ? \"1\" : \"0\");\n } catch {\n // localStorage may be unavailable; collapse state just won't persist.\n }\n}\n\nexport function initDevPanel(options: DevPanelOptions): void {\n const { store, client, target } = options;\n getStateFn = store.get;\n injectStyles();\n const host =\n typeof target === \"string\"\n ? document.querySelector(target)\n : target instanceof Element\n ? target\n : document.body;\n const panel = document.createElement(\"aside\");\n panel.id = \"dev-panel\";\n (host ?? document.body).appendChild(panel);\n\n const registered = client.getRegisteredFunctions?.() ?? [];\n const fnNames = registered.map((f) => f.name).join(\", \") || \"—\";\n\n panel.innerHTML = `\n <div class=\"dev-head\">\n <span class=\"dev-badge\">DEV</span>\n <span class=\"dev-title\">DEV TOOLS · client-side function state — not for production</span>\n <button type=\"button\" class=\"dev-toggle\" aria-label=\"Toggle dev tools\">—</button>\n </div>\n <div class=\"dev-body\">\n <div class=\"dev-fns\">Registered functions: <code>${fnNames}</code></div>\n <div class=\"dev-section-label\">JSON object (built by the agent)</div>\n <pre class=\"dev-state\" id=\"dev-state\"></pre>\n <div class=\"dev-section-label\">Function calls</div>\n <div class=\"dev-log\" id=\"dev-log\"></div>\n </div>\n `;\n\n stateEl = panel.querySelector<HTMLElement>(\"#dev-state\");\n logEl = panel.querySelector<HTMLElement>(\"#dev-log\");\n\n const toggle = panel.querySelector<HTMLButtonElement>(\".dev-toggle\");\n toggle?.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n setCollapsed(panel, !panel.classList.contains(\"collapsed\"));\n });\n // When collapsed, the whole widget acts as an expand button.\n panel.addEventListener(\"click\", () => {\n if (panel.classList.contains(\"collapsed\")) setCollapsed(panel, false);\n });\n\n let startCollapsed = false;\n try {\n startCollapsed = localStorage.getItem(COLLAPSE_KEY) === \"1\";\n } catch {\n // ignore\n }\n setCollapsed(panel, startCollapsed);\n\n client.on(\"function:invoke\", ({ functionName, arguments: args }) => {\n logLine(`→ ${functionName}(${JSON.stringify(args ?? {})})`, \"invoke\");\n });\n client.on(\"function:result\", ({ result, error }) => {\n logLine(\n error ? `✗ error: ${error}` : `← ${JSON.stringify(result)}`,\n error ? \"error\" : \"result\",\n );\n });\n\n // Re-render the JSON object on every state change, then paint the initial state.\n store.subscribe(renderState);\n renderState();\n}\n\nconst STYLE_ID = \"dev-panel-styles\";\n\nfunction injectStyles(): void {\n if (document.getElementById(STYLE_ID)) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = PANEL_CSS;\n document.head.appendChild(style);\n}\n\nconst PANEL_CSS = `\n#dev-panel {\n position: fixed;\n top: 16px;\n right: 16px;\n width: min(360px, calc(100vw - 32px));\n max-width: calc(100vw - 32px);\n box-sizing: border-box;\n max-height: calc(100vh - 32px);\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px 14px;\n background: #0f1419;\n color: #d7e0e8;\n border: 1px solid #2a3441;\n border-radius: 12px;\n box-shadow: 0 20px 50px -20px rgba(0,0,0,.6);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n z-index: 1000;\n}\n#dev-panel .dev-head { display: flex; align-items: center; gap: 8px; }\n#dev-panel .dev-toggle {\n margin-left: auto;\n flex: none;\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: #7c8a99;\n border: 1px solid #2a3441;\n border-radius: 6px;\n font-size: 12px;\n line-height: 1;\n cursor: pointer;\n}\n#dev-panel .dev-toggle:hover { color: #d7e0e8; border-color: #3a4655; }\n#dev-panel .dev-body { display: flex; flex-direction: column; gap: 8px; }\n\n/* Collapsed: shrink to a small clickable widget showing only the DEV badge. */\n#dev-panel.collapsed {\n width: auto;\n cursor: pointer;\n padding: 8px 10px;\n}\n#dev-panel.collapsed .dev-title,\n#dev-panel.collapsed .dev-body { display: none; }\n#dev-panel.collapsed .dev-toggle { margin-left: 6px; }\n#dev-panel .dev-badge {\n background: #f59e0b;\n color: #1c1206;\n font-weight: 700;\n font-size: 10px;\n letter-spacing: .08em;\n padding: 2px 6px;\n border-radius: 5px;\n}\n#dev-panel .dev-title { color: #f59e0b; font-size: 11px; line-height: 1.3; }\n#dev-panel .dev-fns { color: #7c8a99; font-size: 11px; }\n#dev-panel .dev-fns code { color: #9ecbff; }\n#dev-panel .dev-section-label {\n color: #7c8a99;\n text-transform: uppercase;\n letter-spacing: .08em;\n font-size: 10px;\n margin-top: 4px;\n}\n#dev-panel .dev-state {\n margin: 0;\n padding: 8px;\n background: #060a0e;\n border-radius: 8px;\n overflow: auto;\n max-height: 40vh;\n white-space: pre;\n color: #c8e6c9;\n}\n#dev-panel .dev-log {\n display: flex;\n flex-direction: column;\n gap: 2px;\n overflow-y: auto;\n max-height: 24vh;\n background: #060a0e;\n border-radius: 8px;\n padding: 6px 8px;\n}\n#dev-panel .dev-log-line { white-space: pre-wrap; word-break: break-word; line-height: 1.4; }\n#dev-panel .dev-log-invoke { color: #9ecbff; }\n#dev-panel .dev-log-result { color: #86efac; }\n#dev-panel .dev-log-error { color: #fca5a5; }\n`;\n"],"mappings":";AAgBA,IAAI;AACJ,IAAI;AACJ,IAAI,oBAAmC,EAAE;AAGzC,SAAS,cAAoB;AAC3B,KAAI,CAAC,QAAS;AACd,SAAQ,cAAc,KAAK,UAAU,YAAY,EAAE,MAAM,EAAE;;AAG7D,SAAS,QAAQ,MAAc,MAA2C;AACxE,KAAI,CAAC,MAAO;CACZ,MAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,MAAK,YAAY,wBAAwB;AAEzC,MAAK,cAAc,oBADN,IAAI,MAAM,EAAC,oBACF,CAAK,IAAI;AAC/B,OAAM,YAAY,KAAK;AACvB,OAAM,YAAY,MAAM;;AAG1B,IAAM,eAAe;AAErB,SAAS,aAAa,OAAoB,WAA0B;AAClE,OAAM,UAAU,OAAO,aAAa,UAAU;CAC9C,MAAM,SAAS,MAAM,cAAiC,cAAc;AACpE,KAAI,QAAQ;AACV,SAAO,cAAc,YAAY,MAAM;AACvC,SAAO,QAAQ,YAAY,qBAAqB;AAChD,SAAO,aAAa,iBAAiB,OAAO,CAAC,UAAU,CAAC;;AAE1D,KAAI;AACF,eAAa,QAAQ,cAAc,YAAY,MAAM,IAAI;SACnD;;AAKV,SAAgB,aAAa,SAAgC;CAC3D,MAAM,EAAE,OAAO,QAAQ,WAAW;AAClC,cAAa,MAAM;AACnB,eAAc;CACd,MAAM,OACJ,OAAO,WAAW,WACd,SAAS,cAAc,OAAO,GAC9B,kBAAkB,UAChB,SACA,SAAS;CACjB,MAAM,QAAQ,SAAS,cAAc,QAAQ;AAC7C,OAAM,KAAK;AACX,EAAC,QAAQ,SAAS,MAAM,YAAY,MAAM;AAK1C,OAAM,YAAY;;;;;;;0DAHC,OAAO,0BAA0B,IAAI,EAAE,EAC/B,KAAK,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,IAAI,IASG;;;;;;;AAQ/D,WAAU,MAAM,cAA2B,aAAa;AACxD,SAAQ,MAAM,cAA2B,WAAW;AAErC,OAAM,cAAiC,cACtD,EAAQ,iBAAiB,UAAU,MAAM;AACvC,IAAE,iBAAiB;AACnB,eAAa,OAAO,CAAC,MAAM,UAAU,SAAS,YAAY,CAAC;GAC3D;AAEF,OAAM,iBAAiB,eAAe;AACpC,MAAI,MAAM,UAAU,SAAS,YAAY,CAAE,cAAa,OAAO,MAAM;GACrE;CAEF,IAAI,iBAAiB;AACrB,KAAI;AACF,mBAAiB,aAAa,QAAQ,aAAa,KAAK;SAClD;AAGR,cAAa,OAAO,eAAe;AAEnC,QAAO,GAAG,oBAAoB,EAAE,cAAc,WAAW,WAAW;AAClE,UAAQ,KAAK,aAAa,GAAG,KAAK,UAAU,QAAQ,EAAE,CAAC,CAAC,IAAI,SAAS;GACrE;AACF,QAAO,GAAG,oBAAoB,EAAE,QAAQ,YAAY;AAClD,UACE,QAAQ,YAAY,UAAU,KAAK,KAAK,UAAU,OAAO,IACzD,QAAQ,UAAU,SACnB;GACD;AAGF,OAAM,UAAU,YAAY;AAC5B,cAAa;;AAGf,IAAM,WAAW;AAEjB,SAAS,eAAqB;AAC5B,KAAI,SAAS,eAAe,SAAS,CAAE;CACvC,MAAM,QAAQ,SAAS,cAAc,QAAQ;AAC7C,OAAM,KAAK;AACX,OAAM,cAAc;AACpB,UAAS,KAAK,YAAY,MAAM;;AAGlC,IAAM,YAAY"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import type { ClientFunctionDefinition, ClientFunctionHandler, ClientFunctionSchema, RegisteredFunction } from "./types";
|
|
2
|
-
/**
|
|
3
|
-
* Registry for client-side functions that AGO can call
|
|
4
|
-
*/
|
|
5
|
-
export declare class FunctionRegistry {
|
|
6
|
-
private functions;
|
|
7
|
-
/**
|
|
8
|
-
* Register a function that AGO can call.
|
|
9
|
-
* Accepts either a single definition object or (name, handler, schema) args.
|
|
10
|
-
*/
|
|
11
|
-
register(definition: ClientFunctionDefinition): void;
|
|
12
|
-
register(name: string, handler: ClientFunctionHandler, schema: Omit<ClientFunctionSchema, "name">): void;
|
|
13
|
-
/**
|
|
14
|
-
* Unregister a function
|
|
15
|
-
*/
|
|
16
|
-
unregister(name: string): boolean;
|
|
17
|
-
/**
|
|
18
|
-
* Get a registered function
|
|
19
|
-
*/
|
|
20
|
-
get(name: string): RegisteredFunction | undefined;
|
|
21
|
-
/**
|
|
22
|
-
* Check if a function is registered
|
|
23
|
-
*/
|
|
24
|
-
has(name: string): boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Get all registered function schemas (for sending to backend)
|
|
27
|
-
*/
|
|
28
|
-
getSchemas(): ClientFunctionSchema[];
|
|
29
|
-
/**
|
|
30
|
-
* Execute a registered function
|
|
31
|
-
*/
|
|
32
|
-
execute(name: string, args: Record<string, unknown>): Promise<unknown>;
|
|
33
|
-
/**
|
|
34
|
-
* Clear all registered functions
|
|
35
|
-
*/
|
|
36
|
-
clear(): void;
|
|
37
|
-
/**
|
|
38
|
-
* Get the number of registered functions
|
|
39
|
-
*/
|
|
40
|
-
get size(): number;
|
|
41
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { ClientFunctionDefinition } from "./types";
|
|
2
|
-
/**
|
|
3
|
-
* Create a reusable function definition.
|
|
4
|
-
* Returns the same object — this is an identity function for discoverability and type-checking.
|
|
5
|
-
*
|
|
6
|
-
* ```ts
|
|
7
|
-
* // Define once, reuse anywhere
|
|
8
|
-
* export const lookupOrder = defineFunction({
|
|
9
|
-
* name: "lookupOrder",
|
|
10
|
-
* description: "Look up an order by ID",
|
|
11
|
-
* parameters: { type: "object", properties: { id: { type: "string" } }, required: ["id"] },
|
|
12
|
-
* handler: async (args) => fetchOrder(args.id as string),
|
|
13
|
-
* });
|
|
14
|
-
*
|
|
15
|
-
* // Register with client
|
|
16
|
-
* client.registerFunction(lookupOrder);
|
|
17
|
-
*
|
|
18
|
-
* // Or use in React
|
|
19
|
-
* useAgoFunction(lookupOrder.name, lookupOrder);
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export declare function defineFunction(definition: ClientFunctionDefinition): ClientFunctionDefinition;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Schema for a client-side function that AGO can call
|
|
3
|
-
*/
|
|
4
|
-
export interface ClientFunctionSchema {
|
|
5
|
-
/** Function name (must be unique) */
|
|
6
|
-
name: string;
|
|
7
|
-
/** Description for the LLM to understand when to call this function */
|
|
8
|
-
description: string;
|
|
9
|
-
/** JSON Schema for function parameters */
|
|
10
|
-
parameters: {
|
|
11
|
-
type: "object";
|
|
12
|
-
properties: Record<string, {
|
|
13
|
-
type: string;
|
|
14
|
-
description?: string;
|
|
15
|
-
enum?: string[];
|
|
16
|
-
default?: unknown;
|
|
17
|
-
}>;
|
|
18
|
-
required?: string[];
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Function handler type
|
|
23
|
-
*/
|
|
24
|
-
export type ClientFunctionHandler = (args: Record<string, unknown>) => Promise<unknown> | unknown;
|
|
25
|
-
/**
|
|
26
|
-
* Registered function with handler
|
|
27
|
-
*/
|
|
28
|
-
export interface RegisteredFunction {
|
|
29
|
-
schema: ClientFunctionSchema;
|
|
30
|
-
handler: ClientFunctionHandler;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Single-object function definition — combines name, schema, and handler.
|
|
34
|
-
*
|
|
35
|
-
* ```ts
|
|
36
|
-
* const fn = defineFunction({
|
|
37
|
-
* name: "lookupOrder",
|
|
38
|
-
* description: "Look up an order by ID",
|
|
39
|
-
* parameters: { type: "object", properties: { id: { type: "string" } }, required: ["id"] },
|
|
40
|
-
* handler: async (args) => fetchOrder(args.id as string),
|
|
41
|
-
* });
|
|
42
|
-
* client.registerFunction(fn);
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export interface ClientFunctionDefinition {
|
|
46
|
-
name: string;
|
|
47
|
-
description: string;
|
|
48
|
-
parameters: ClientFunctionSchema["parameters"];
|
|
49
|
-
handler: ClientFunctionHandler;
|
|
50
|
-
}
|