@useago/sdk 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/dist/AgoClient-DF7M2WAz.js +575 -0
  2. package/dist/AgoClient-bjN-z2ZQ.cjs +6 -0
  3. package/dist/angular.cjs +1 -143
  4. package/dist/angular.d.cts +530 -0
  5. package/dist/angular.d.ts +530 -2
  6. package/dist/angular.js +71 -139
  7. package/dist/createMockClient-D6uVh-B9.js +254 -0
  8. package/dist/createMockClient-DecMEUcK.cjs +1 -0
  9. package/dist/devtools.cjs +4 -78
  10. package/dist/devtools.d.cts +443 -0
  11. package/dist/devtools.d.ts +443 -2
  12. package/dist/devtools.js +46 -71
  13. package/dist/functions-Bz-1Bs3I.cjs +1 -0
  14. package/dist/functions-DdROP6Ui.js +312 -0
  15. package/dist/helpers.cjs +1 -15
  16. package/dist/{helpers/functions.d.ts → helpers.d.cts} +121 -62
  17. package/dist/helpers.d.ts +121 -2
  18. package/dist/helpers.js +16 -2
  19. package/dist/index.cjs +1 -347
  20. package/dist/index.d.cts +1150 -0
  21. package/dist/index.d.ts +1150 -20
  22. package/dist/index.js +128 -298
  23. package/dist/react.cjs +31 -22438
  24. package/dist/react.d.cts +960 -0
  25. package/dist/react.d.ts +960 -2
  26. package/dist/react.js +8401 -22376
  27. package/dist/rolldown-runtime-CaekUdDJ.cjs +1 -0
  28. package/dist/rolldown-runtime-DxmricAu.js +25 -0
  29. package/dist/vue.cjs +1 -336
  30. package/dist/vue.d.cts +1063 -0
  31. package/dist/vue.d.ts +1063 -2
  32. package/dist/vue.js +174 -316
  33. package/dist/{widget/types.d.ts → widget.d.cts} +41 -43
  34. package/dist/widget.d.ts +41 -2
  35. package/package.json +35 -24
  36. package/dist/AgoClient-DPZdN5n2.js +0 -905
  37. package/dist/AgoClient-DPZdN5n2.js.map +0 -1
  38. package/dist/AgoClient-wMVUQqCD.cjs +0 -976
  39. package/dist/AgoClient-wMVUQqCD.cjs.map +0 -1
  40. package/dist/angular/ago.service.d.ts +0 -98
  41. package/dist/angular/index.d.ts +0 -4
  42. package/dist/angular/provide.d.ts +0 -27
  43. package/dist/angular.cjs.map +0 -1
  44. package/dist/angular.js.map +0 -1
  45. package/dist/api/HttpClient.d.ts +0 -31
  46. package/dist/api/index.d.ts +0 -1
  47. package/dist/auto/createAgo.d.ts +0 -39
  48. package/dist/auto/index.d.ts +0 -1
  49. package/dist/client/AgoClient.d.ts +0 -169
  50. package/dist/client/errors.d.ts +0 -48
  51. package/dist/client/index.d.ts +0 -3
  52. package/dist/client/types.d.ts +0 -205
  53. package/dist/createMockClient-Ci_N2tH8.cjs +0 -104
  54. package/dist/createMockClient-Ci_N2tH8.cjs.map +0 -1
  55. package/dist/createMockClient-U0ae_AYy.js +0 -99
  56. package/dist/createMockClient-U0ae_AYy.js.map +0 -1
  57. package/dist/devtools/index.d.ts +0 -2
  58. package/dist/devtools/initDevPanel.d.ts +0 -15
  59. package/dist/devtools.cjs.map +0 -1
  60. package/dist/devtools.js.map +0 -1
  61. package/dist/functions/FunctionRegistry.d.ts +0 -41
  62. package/dist/functions/defineFunction.d.ts +0 -22
  63. package/dist/functions/index.d.ts +0 -2
  64. package/dist/functions/types.d.ts +0 -50
  65. package/dist/functions--c6lx3ic.cjs +0 -480
  66. package/dist/functions--c6lx3ic.cjs.map +0 -1
  67. package/dist/functions-C9F1dnmh.js +0 -398
  68. package/dist/functions-C9F1dnmh.js.map +0 -1
  69. package/dist/helpers/factory.d.ts +0 -20
  70. package/dist/helpers/index.d.ts +0 -1
  71. package/dist/index.cjs.map +0 -1
  72. package/dist/index.js.map +0 -1
  73. package/dist/react/components/ChatInput.d.ts +0 -12
  74. package/dist/react/components/ChatWidget.d.ts +0 -35
  75. package/dist/react/components/Markdown.d.ts +0 -12
  76. package/dist/react/components/Message.d.ts +0 -9
  77. package/dist/react/components/index.d.ts +0 -8
  78. package/dist/react/context/AgoContext.d.ts +0 -62
  79. package/dist/react/context/index.d.ts +0 -2
  80. package/dist/react/hooks/index.d.ts +0 -7
  81. package/dist/react/hooks/useAgo.d.ts +0 -14
  82. package/dist/react/hooks/useAgoContext.d.ts +0 -40
  83. package/dist/react/hooks/useAgoFunction.d.ts +0 -58
  84. package/dist/react/hooks/useAgoStore.d.ts +0 -17
  85. package/dist/react/hooks/useChat.d.ts +0 -45
  86. package/dist/react/hooks/useConversation.d.ts +0 -28
  87. package/dist/react/hooks/useMessages.d.ts +0 -26
  88. package/dist/react/index.d.ts +0 -24
  89. package/dist/react/testing.d.ts +0 -2
  90. package/dist/react.cjs.map +0 -1
  91. package/dist/react.js.map +0 -1
  92. package/dist/rolldown-runtime-BqCkTl7Q.cjs +0 -50
  93. package/dist/rolldown-runtime-CNZpIYwj.js +0 -33
  94. package/dist/state/ClientContextRegistry.d.ts +0 -64
  95. package/dist/state/createStore.d.ts +0 -30
  96. package/dist/streaming/SSEHandler.d.ts +0 -46
  97. package/dist/streaming/helpers.d.ts +0 -67
  98. package/dist/streaming/index.d.ts +0 -2
  99. package/dist/testing/createMockClient.d.ts +0 -42
  100. package/dist/testing/index.d.ts +0 -2
  101. package/dist/utils/eventEmitter.d.ts +0 -23
  102. package/dist/utils/index.d.ts +0 -2
  103. package/dist/utils/logger.d.ts +0 -14
  104. package/dist/vue/composables/useAgo.d.ts +0 -17
  105. package/dist/vue/composables/useAgoEvents.d.ts +0 -11
  106. package/dist/vue/composables/useAgoFunction.d.ts +0 -34
  107. package/dist/vue/composables/useAgoStore.d.ts +0 -18
  108. package/dist/vue/composables/useChat.d.ts +0 -251
  109. package/dist/vue/composables/useConversation.d.ts +0 -178
  110. package/dist/vue/composables/useMessages.d.ts +0 -89
  111. package/dist/vue/index.d.ts +0 -11
  112. package/dist/vue/plugin.d.ts +0 -16
  113. package/dist/vue/symbols.d.ts +0 -3
  114. package/dist/vue.cjs.map +0 -1
  115. package/dist/vue.js.map +0 -1
  116. package/dist/widget/index.d.ts +0 -1
@@ -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"}
@@ -1,2 +0,0 @@
1
- export { initDevPanel } from "./initDevPanel";
2
- export type { DevPanelOptions } from "./initDevPanel";
@@ -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;
@@ -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"}
@@ -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,2 +0,0 @@
1
- export { FunctionRegistry } from "./FunctionRegistry";
2
- export type { ClientFunctionSchema, ClientFunctionHandler, RegisteredFunction, } from "./types";
@@ -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
- }