@sinas/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,305 @@
1
+ // src/client/errors.ts
2
+ var SinasError = class extends Error {
3
+ constructor(message, status = 0, detail) {
4
+ super(message);
5
+ this.name = "SinasError";
6
+ this.status = status;
7
+ this.detail = detail || message;
8
+ }
9
+ };
10
+ var SinasAuthError = class extends SinasError {
11
+ constructor(message = "Authentication required") {
12
+ super(message, 401);
13
+ this.name = "SinasAuthError";
14
+ }
15
+ };
16
+ var SinasPermissionError = class extends SinasError {
17
+ constructor(message = "Permission denied") {
18
+ super(message, 403);
19
+ this.name = "SinasPermissionError";
20
+ }
21
+ };
22
+ var SinasNotFoundError = class extends SinasError {
23
+ constructor(resource) {
24
+ super(`${resource} not found`, 404);
25
+ this.name = "SinasNotFoundError";
26
+ }
27
+ };
28
+ var SinasTimeoutError = class extends SinasError {
29
+ constructor(message = "Request timed out") {
30
+ super(message, 408);
31
+ this.name = "SinasTimeoutError";
32
+ }
33
+ };
34
+
35
+ // src/client/SinasClient.ts
36
+ var SinasClient = class {
37
+ constructor(config) {
38
+ this.configOverride = config;
39
+ }
40
+ getConfig() {
41
+ const config = this.configOverride || window.__SINAS_CONFIG__;
42
+ if (!config) {
43
+ return {
44
+ apiBase: "",
45
+ component: { namespace: "", name: "", version: "" },
46
+ resources: {
47
+ enabledAgents: [],
48
+ enabledFunctions: [],
49
+ enabledQueries: [],
50
+ enabledComponents: [],
51
+ stateNamespacesReadonly: [],
52
+ stateNamespacesReadwrite: []
53
+ },
54
+ input: {}
55
+ };
56
+ }
57
+ return config;
58
+ }
59
+ getInput() {
60
+ return this.getConfig().input || {};
61
+ }
62
+ getAuthHeaders() {
63
+ const token = window.__SINAS_AUTH_TOKEN__;
64
+ const headers = { "Content-Type": "application/json" };
65
+ if (token) {
66
+ headers["Authorization"] = `Bearer ${token}`;
67
+ }
68
+ return headers;
69
+ }
70
+ getProxyBase() {
71
+ const config = this.getConfig();
72
+ const comp = config.component;
73
+ return `${config.apiBase}/components/${comp.namespace}/${comp.name}/proxy`;
74
+ }
75
+ async fetch(url, options = {}) {
76
+ const res = await fetch(url, {
77
+ ...options,
78
+ headers: {
79
+ ...this.getAuthHeaders(),
80
+ ...options.headers || {}
81
+ }
82
+ });
83
+ if (!res.ok) {
84
+ const body = await res.json().catch(() => ({ detail: res.statusText }));
85
+ const message = body.detail || body.message || res.statusText;
86
+ if (res.status === 401) throw new SinasAuthError(message);
87
+ if (res.status === 403) throw new SinasPermissionError(message);
88
+ if (res.status === 404) throw new SinasNotFoundError(message);
89
+ throw new SinasError(message, res.status);
90
+ }
91
+ return res;
92
+ }
93
+ };
94
+
95
+ // src/client/queries.ts
96
+ function parseRef(ref) {
97
+ const parts = ref.split("/");
98
+ if (parts.length !== 2) {
99
+ throw new Error(`Invalid query ref "${ref}": expected "namespace/name"`);
100
+ }
101
+ return [parts[0], parts[1]];
102
+ }
103
+ async function executeQuery(client, ref, input = {}) {
104
+ const [ns, name] = parseRef(ref);
105
+ const base = client.getProxyBase();
106
+ const res = await client.fetch(`${base}/queries/${ns}/${name}/execute`, {
107
+ method: "POST",
108
+ body: JSON.stringify({ input })
109
+ });
110
+ const data = await res.json();
111
+ return {
112
+ success: data.success,
113
+ operation: data.operation,
114
+ data: data.data,
115
+ rowCount: data.row_count,
116
+ affectedRows: data.affected_rows,
117
+ durationMs: data.duration_ms
118
+ };
119
+ }
120
+
121
+ // src/client/functions.ts
122
+ function parseRef2(ref) {
123
+ const parts = ref.split("/");
124
+ if (parts.length !== 2) {
125
+ throw new Error(`Invalid function ref "${ref}": expected "namespace/name"`);
126
+ }
127
+ return [parts[0], parts[1]];
128
+ }
129
+ async function executeFunction(client, ref, input = {}, timeout) {
130
+ const [ns, name] = parseRef2(ref);
131
+ const base = client.getProxyBase();
132
+ const body = { input };
133
+ if (timeout !== void 0) {
134
+ body.timeout = timeout;
135
+ }
136
+ const res = await client.fetch(`${base}/functions/${ns}/${name}/execute`, {
137
+ method: "POST",
138
+ body: JSON.stringify(body)
139
+ });
140
+ const data = await res.json();
141
+ return {
142
+ status: data.status,
143
+ executionId: data.execution_id,
144
+ result: data.result,
145
+ error: data.error
146
+ };
147
+ }
148
+
149
+ // src/client/states.ts
150
+ async function stateGet(client, ns, key) {
151
+ const base = client.getProxyBase();
152
+ const res = await client.fetch(`${base}/states/${ns}`, {
153
+ method: "POST",
154
+ body: JSON.stringify({ action: "get", key })
155
+ });
156
+ return res.json();
157
+ }
158
+ async function stateSet(client, ns, key, value, visibility = "private") {
159
+ const base = client.getProxyBase();
160
+ await client.fetch(`${base}/states/${ns}`, {
161
+ method: "POST",
162
+ body: JSON.stringify({ action: "set", key, value, visibility })
163
+ });
164
+ }
165
+ async function stateDelete(client, ns, key) {
166
+ const base = client.getProxyBase();
167
+ await client.fetch(`${base}/states/${ns}`, {
168
+ method: "POST",
169
+ body: JSON.stringify({ action: "delete", key })
170
+ });
171
+ }
172
+ async function stateList(client, ns) {
173
+ const base = client.getProxyBase();
174
+ const res = await client.fetch(`${base}/states/${ns}`, {
175
+ method: "POST",
176
+ body: JSON.stringify({ action: "list" })
177
+ });
178
+ return res.json();
179
+ }
180
+
181
+ // src/client/chat.ts
182
+ async function createChat(client, agentRef, input) {
183
+ const [ns, name] = agentRef.split("/");
184
+ if (!ns || !name) {
185
+ throw new Error(`Invalid agent ref "${agentRef}": expected "namespace/name"`);
186
+ }
187
+ const config = client.getConfig();
188
+ const res = await client.fetch(`${config.apiBase}/agents/${ns}/${name}/chats`, {
189
+ method: "POST",
190
+ body: JSON.stringify({ input: input || {} })
191
+ });
192
+ const data = await res.json();
193
+ return {
194
+ id: data.id,
195
+ agentNamespace: data.agent_namespace,
196
+ agentName: data.agent_name,
197
+ title: data.title
198
+ };
199
+ }
200
+ async function sendMessage(client, chatId, content) {
201
+ const config = client.getConfig();
202
+ const res = await client.fetch(`${config.apiBase}/chats/${chatId}/messages`, {
203
+ method: "POST",
204
+ body: JSON.stringify({ content })
205
+ });
206
+ const data = await res.json();
207
+ return {
208
+ id: data.id,
209
+ chatId: data.chat_id,
210
+ role: data.role,
211
+ content: data.content,
212
+ createdAt: data.created_at
213
+ };
214
+ }
215
+ function parseSSE(buffer) {
216
+ const chunks = [];
217
+ const lines = buffer.split("\n");
218
+ let event = "";
219
+ let data = "";
220
+ let remaining = "";
221
+ for (let i = 0; i < lines.length; i++) {
222
+ const line = lines[i];
223
+ if (i === lines.length - 1 && !buffer.endsWith("\n")) {
224
+ remaining = line;
225
+ break;
226
+ }
227
+ if (line.startsWith("event:")) {
228
+ event = line.slice(6).trim();
229
+ } else if (line.startsWith("data:")) {
230
+ data = line.slice(5).trim();
231
+ } else if (line === "") {
232
+ if (event || data) {
233
+ chunks.push({ event: event || "message", data });
234
+ event = "";
235
+ data = "";
236
+ }
237
+ }
238
+ }
239
+ return { chunks, remaining };
240
+ }
241
+ function streamMessage(client, chatId, content, onChunk, onDone, onError) {
242
+ const controller = new AbortController();
243
+ const config = client.getConfig();
244
+ (async () => {
245
+ try {
246
+ const res = await fetch(`${config.apiBase}/chats/${chatId}/messages/stream`, {
247
+ method: "POST",
248
+ headers: client.getAuthHeaders(),
249
+ body: JSON.stringify({ content }),
250
+ signal: controller.signal
251
+ });
252
+ if (!res.ok) {
253
+ const body = await res.json().catch(() => ({ detail: res.statusText }));
254
+ throw new Error(body.detail || "Stream request failed");
255
+ }
256
+ const reader = res.body.getReader();
257
+ const decoder = new TextDecoder();
258
+ let buffer = "";
259
+ while (true) {
260
+ const { done, value } = await reader.read();
261
+ if (done) break;
262
+ buffer += decoder.decode(value, { stream: true });
263
+ const { chunks, remaining } = parseSSE(buffer);
264
+ buffer = remaining;
265
+ for (const chunk of chunks) {
266
+ onChunk(chunk);
267
+ if (chunk.event === "done") {
268
+ onDone?.();
269
+ return;
270
+ }
271
+ }
272
+ }
273
+ if (buffer.trim()) {
274
+ const { chunks } = parseSSE(buffer + "\n\n");
275
+ for (const chunk of chunks) {
276
+ onChunk(chunk);
277
+ }
278
+ }
279
+ onDone?.();
280
+ } catch (err) {
281
+ if (err.name === "AbortError") return;
282
+ onError?.(err);
283
+ }
284
+ })();
285
+ return controller;
286
+ }
287
+
288
+ export {
289
+ SinasError,
290
+ SinasAuthError,
291
+ SinasPermissionError,
292
+ SinasNotFoundError,
293
+ SinasTimeoutError,
294
+ SinasClient,
295
+ executeQuery,
296
+ executeFunction,
297
+ stateGet,
298
+ stateSet,
299
+ stateDelete,
300
+ stateList,
301
+ createChat,
302
+ sendMessage,
303
+ streamMessage
304
+ };
305
+ //# sourceMappingURL=chunk-M7YHE5Y6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client/errors.ts","../src/client/SinasClient.ts","../src/client/queries.ts","../src/client/functions.ts","../src/client/states.ts","../src/client/chat.ts"],"sourcesContent":["export class SinasError extends Error {\n public readonly status: number;\n public readonly detail: string;\n\n constructor(message: string, status: number = 0, detail?: string) {\n super(message);\n this.name = 'SinasError';\n this.status = status;\n this.detail = detail || message;\n }\n}\n\nexport class SinasAuthError extends SinasError {\n constructor(message: string = 'Authentication required') {\n super(message, 401);\n this.name = 'SinasAuthError';\n }\n}\n\nexport class SinasPermissionError extends SinasError {\n constructor(message: string = 'Permission denied') {\n super(message, 403);\n this.name = 'SinasPermissionError';\n }\n}\n\nexport class SinasNotFoundError extends SinasError {\n constructor(resource: string) {\n super(`${resource} not found`, 404);\n this.name = 'SinasNotFoundError';\n }\n}\n\nexport class SinasTimeoutError extends SinasError {\n constructor(message: string = 'Request timed out') {\n super(message, 408);\n this.name = 'SinasTimeoutError';\n }\n}\n","import { SinasError, SinasAuthError, SinasPermissionError, SinasNotFoundError } from './errors';\nimport type { SinasConfig } from './types';\n\ndeclare global {\n interface Window {\n __SINAS_CONFIG__?: SinasConfig;\n __SINAS_AUTH_TOKEN__?: string | null;\n }\n}\n\nexport class SinasClient {\n private configOverride?: SinasConfig;\n\n constructor(config?: SinasConfig) {\n this.configOverride = config;\n }\n\n getConfig(): SinasConfig {\n const config = this.configOverride || window.__SINAS_CONFIG__;\n if (!config) {\n return {\n apiBase: '',\n component: { namespace: '', name: '', version: '' },\n resources: {\n enabledAgents: [],\n enabledFunctions: [],\n enabledQueries: [],\n enabledComponents: [],\n stateNamespacesReadonly: [],\n stateNamespacesReadwrite: [],\n },\n input: {},\n };\n }\n return config;\n }\n\n getInput(): Record<string, unknown> {\n return this.getConfig().input || {};\n }\n\n getAuthHeaders(): Record<string, string> {\n const token = window.__SINAS_AUTH_TOKEN__;\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n return headers;\n }\n\n getProxyBase(): string {\n const config = this.getConfig();\n const comp = config.component;\n return `${config.apiBase}/components/${comp.namespace}/${comp.name}/proxy`;\n }\n\n async fetch(url: string, options: RequestInit = {}): Promise<Response> {\n const res = await fetch(url, {\n ...options,\n headers: {\n ...this.getAuthHeaders(),\n ...(options.headers as Record<string, string> || {}),\n },\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({ detail: res.statusText }));\n const message = body.detail || body.message || res.statusText;\n\n if (res.status === 401) throw new SinasAuthError(message);\n if (res.status === 403) throw new SinasPermissionError(message);\n if (res.status === 404) throw new SinasNotFoundError(message);\n throw new SinasError(message, res.status);\n }\n\n return res;\n }\n}\n","import type { SinasClient } from './SinasClient';\nimport type { QueryResult } from './types';\n\nfunction parseRef(ref: string): [string, string] {\n const parts = ref.split('/');\n if (parts.length !== 2) {\n throw new Error(`Invalid query ref \"${ref}\": expected \"namespace/name\"`);\n }\n return [parts[0], parts[1]];\n}\n\nexport async function executeQuery(\n client: SinasClient,\n ref: string,\n input: Record<string, unknown> = {}\n): Promise<QueryResult> {\n const [ns, name] = parseRef(ref);\n const base = client.getProxyBase();\n const res = await client.fetch(`${base}/queries/${ns}/${name}/execute`, {\n method: 'POST',\n body: JSON.stringify({ input }),\n });\n const data = await res.json();\n return {\n success: data.success,\n operation: data.operation,\n data: data.data,\n rowCount: data.row_count,\n affectedRows: data.affected_rows,\n durationMs: data.duration_ms,\n };\n}\n","import type { SinasClient } from './SinasClient';\nimport type { FunctionResult } from './types';\n\nfunction parseRef(ref: string): [string, string] {\n const parts = ref.split('/');\n if (parts.length !== 2) {\n throw new Error(`Invalid function ref \"${ref}\": expected \"namespace/name\"`);\n }\n return [parts[0], parts[1]];\n}\n\nexport async function executeFunction(\n client: SinasClient,\n ref: string,\n input: Record<string, unknown> = {},\n timeout?: number\n): Promise<FunctionResult> {\n const [ns, name] = parseRef(ref);\n const base = client.getProxyBase();\n const body: Record<string, unknown> = { input };\n if (timeout !== undefined) {\n body.timeout = timeout;\n }\n const res = await client.fetch(`${base}/functions/${ns}/${name}/execute`, {\n method: 'POST',\n body: JSON.stringify(body),\n });\n const data = await res.json();\n return {\n status: data.status,\n executionId: data.execution_id,\n result: data.result,\n error: data.error,\n };\n}\n","import type { SinasClient } from './SinasClient';\nimport type { StateGetResult, StateListResult } from './types';\n\nexport async function stateGet(\n client: SinasClient,\n ns: string,\n key: string\n): Promise<StateGetResult> {\n const base = client.getProxyBase();\n const res = await client.fetch(`${base}/states/${ns}`, {\n method: 'POST',\n body: JSON.stringify({ action: 'get', key }),\n });\n return res.json();\n}\n\nexport async function stateSet(\n client: SinasClient,\n ns: string,\n key: string,\n value: unknown,\n visibility: 'private' | 'shared' = 'private'\n): Promise<void> {\n const base = client.getProxyBase();\n await client.fetch(`${base}/states/${ns}`, {\n method: 'POST',\n body: JSON.stringify({ action: 'set', key, value, visibility }),\n });\n}\n\nexport async function stateDelete(\n client: SinasClient,\n ns: string,\n key: string\n): Promise<void> {\n const base = client.getProxyBase();\n await client.fetch(`${base}/states/${ns}`, {\n method: 'POST',\n body: JSON.stringify({ action: 'delete', key }),\n });\n}\n\nexport async function stateList(\n client: SinasClient,\n ns: string\n): Promise<StateListResult> {\n const base = client.getProxyBase();\n const res = await client.fetch(`${base}/states/${ns}`, {\n method: 'POST',\n body: JSON.stringify({ action: 'list' }),\n });\n return res.json();\n}\n","import type { SinasClient } from './SinasClient';\nimport type { ChatCreateResult, ChatMessage, SSEChunk } from './types';\n\nexport async function createChat(\n client: SinasClient,\n agentRef: string,\n input?: Record<string, unknown>\n): Promise<ChatCreateResult> {\n const [ns, name] = agentRef.split('/');\n if (!ns || !name) {\n throw new Error(`Invalid agent ref \"${agentRef}\": expected \"namespace/name\"`);\n }\n const config = client.getConfig();\n const res = await client.fetch(`${config.apiBase}/agents/${ns}/${name}/chats`, {\n method: 'POST',\n body: JSON.stringify({ input: input || {} }),\n });\n const data = await res.json();\n return {\n id: data.id,\n agentNamespace: data.agent_namespace,\n agentName: data.agent_name,\n title: data.title,\n };\n}\n\nexport async function sendMessage(\n client: SinasClient,\n chatId: string,\n content: string\n): Promise<ChatMessage> {\n const config = client.getConfig();\n const res = await client.fetch(`${config.apiBase}/chats/${chatId}/messages`, {\n method: 'POST',\n body: JSON.stringify({ content }),\n });\n const data = await res.json();\n return {\n id: data.id,\n chatId: data.chat_id,\n role: data.role,\n content: data.content,\n createdAt: data.created_at,\n };\n}\n\nfunction parseSSE(buffer: string): { chunks: SSEChunk[]; remaining: string } {\n const chunks: SSEChunk[] = [];\n const lines = buffer.split('\\n');\n let event = '';\n let data = '';\n let remaining = '';\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // If last line and doesn't end with newline, it's incomplete\n if (i === lines.length - 1 && !buffer.endsWith('\\n')) {\n remaining = line;\n break;\n }\n\n if (line.startsWith('event:')) {\n event = line.slice(6).trim();\n } else if (line.startsWith('data:')) {\n data = line.slice(5).trim();\n } else if (line === '') {\n if (event || data) {\n chunks.push({ event: event || 'message', data });\n event = '';\n data = '';\n }\n }\n }\n\n return { chunks, remaining };\n}\n\nexport function streamMessage(\n client: SinasClient,\n chatId: string,\n content: string,\n onChunk: (chunk: SSEChunk) => void,\n onDone?: () => void,\n onError?: (error: Error) => void\n): AbortController {\n const controller = new AbortController();\n const config = client.getConfig();\n\n (async () => {\n try {\n const res = await fetch(`${config.apiBase}/chats/${chatId}/messages/stream`, {\n method: 'POST',\n headers: client.getAuthHeaders(),\n body: JSON.stringify({ content }),\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({ detail: res.statusText }));\n throw new Error(body.detail || 'Stream request failed');\n }\n\n const reader = res.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const { chunks, remaining } = parseSSE(buffer);\n buffer = remaining;\n\n for (const chunk of chunks) {\n onChunk(chunk);\n if (chunk.event === 'done') {\n onDone?.();\n return;\n }\n }\n }\n\n // Process any remaining buffer\n if (buffer.trim()) {\n const { chunks } = parseSSE(buffer + '\\n\\n');\n for (const chunk of chunks) {\n onChunk(chunk);\n }\n }\n\n onDone?.();\n } catch (err) {\n if ((err as Error).name === 'AbortError') return;\n onError?.(err as Error);\n }\n })();\n\n return controller;\n}\n"],"mappings":"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","names":["parseRef"]}
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/client/index.ts
21
+ var client_exports = {};
22
+ __export(client_exports, {
23
+ SinasAuthError: () => SinasAuthError,
24
+ SinasClient: () => SinasClient,
25
+ SinasError: () => SinasError,
26
+ SinasNotFoundError: () => SinasNotFoundError,
27
+ SinasPermissionError: () => SinasPermissionError,
28
+ SinasTimeoutError: () => SinasTimeoutError,
29
+ createChat: () => createChat,
30
+ executeFunction: () => executeFunction,
31
+ executeQuery: () => executeQuery,
32
+ sendMessage: () => sendMessage,
33
+ stateDelete: () => stateDelete,
34
+ stateGet: () => stateGet,
35
+ stateList: () => stateList,
36
+ stateSet: () => stateSet,
37
+ streamMessage: () => streamMessage
38
+ });
39
+ module.exports = __toCommonJS(client_exports);
40
+
41
+ // src/client/errors.ts
42
+ var SinasError = class extends Error {
43
+ constructor(message, status = 0, detail) {
44
+ super(message);
45
+ this.name = "SinasError";
46
+ this.status = status;
47
+ this.detail = detail || message;
48
+ }
49
+ };
50
+ var SinasAuthError = class extends SinasError {
51
+ constructor(message = "Authentication required") {
52
+ super(message, 401);
53
+ this.name = "SinasAuthError";
54
+ }
55
+ };
56
+ var SinasPermissionError = class extends SinasError {
57
+ constructor(message = "Permission denied") {
58
+ super(message, 403);
59
+ this.name = "SinasPermissionError";
60
+ }
61
+ };
62
+ var SinasNotFoundError = class extends SinasError {
63
+ constructor(resource) {
64
+ super(`${resource} not found`, 404);
65
+ this.name = "SinasNotFoundError";
66
+ }
67
+ };
68
+ var SinasTimeoutError = class extends SinasError {
69
+ constructor(message = "Request timed out") {
70
+ super(message, 408);
71
+ this.name = "SinasTimeoutError";
72
+ }
73
+ };
74
+
75
+ // src/client/SinasClient.ts
76
+ var SinasClient = class {
77
+ constructor(config) {
78
+ this.configOverride = config;
79
+ }
80
+ getConfig() {
81
+ const config = this.configOverride || window.__SINAS_CONFIG__;
82
+ if (!config) {
83
+ return {
84
+ apiBase: "",
85
+ component: { namespace: "", name: "", version: "" },
86
+ resources: {
87
+ enabledAgents: [],
88
+ enabledFunctions: [],
89
+ enabledQueries: [],
90
+ enabledComponents: [],
91
+ stateNamespacesReadonly: [],
92
+ stateNamespacesReadwrite: []
93
+ },
94
+ input: {}
95
+ };
96
+ }
97
+ return config;
98
+ }
99
+ getInput() {
100
+ return this.getConfig().input || {};
101
+ }
102
+ getAuthHeaders() {
103
+ const token = window.__SINAS_AUTH_TOKEN__;
104
+ const headers = { "Content-Type": "application/json" };
105
+ if (token) {
106
+ headers["Authorization"] = `Bearer ${token}`;
107
+ }
108
+ return headers;
109
+ }
110
+ getProxyBase() {
111
+ const config = this.getConfig();
112
+ const comp = config.component;
113
+ return `${config.apiBase}/components/${comp.namespace}/${comp.name}/proxy`;
114
+ }
115
+ async fetch(url, options = {}) {
116
+ const res = await fetch(url, {
117
+ ...options,
118
+ headers: {
119
+ ...this.getAuthHeaders(),
120
+ ...options.headers || {}
121
+ }
122
+ });
123
+ if (!res.ok) {
124
+ const body = await res.json().catch(() => ({ detail: res.statusText }));
125
+ const message = body.detail || body.message || res.statusText;
126
+ if (res.status === 401) throw new SinasAuthError(message);
127
+ if (res.status === 403) throw new SinasPermissionError(message);
128
+ if (res.status === 404) throw new SinasNotFoundError(message);
129
+ throw new SinasError(message, res.status);
130
+ }
131
+ return res;
132
+ }
133
+ };
134
+
135
+ // src/client/queries.ts
136
+ function parseRef(ref) {
137
+ const parts = ref.split("/");
138
+ if (parts.length !== 2) {
139
+ throw new Error(`Invalid query ref "${ref}": expected "namespace/name"`);
140
+ }
141
+ return [parts[0], parts[1]];
142
+ }
143
+ async function executeQuery(client, ref, input = {}) {
144
+ const [ns, name] = parseRef(ref);
145
+ const base = client.getProxyBase();
146
+ const res = await client.fetch(`${base}/queries/${ns}/${name}/execute`, {
147
+ method: "POST",
148
+ body: JSON.stringify({ input })
149
+ });
150
+ const data = await res.json();
151
+ return {
152
+ success: data.success,
153
+ operation: data.operation,
154
+ data: data.data,
155
+ rowCount: data.row_count,
156
+ affectedRows: data.affected_rows,
157
+ durationMs: data.duration_ms
158
+ };
159
+ }
160
+
161
+ // src/client/functions.ts
162
+ function parseRef2(ref) {
163
+ const parts = ref.split("/");
164
+ if (parts.length !== 2) {
165
+ throw new Error(`Invalid function ref "${ref}": expected "namespace/name"`);
166
+ }
167
+ return [parts[0], parts[1]];
168
+ }
169
+ async function executeFunction(client, ref, input = {}, timeout) {
170
+ const [ns, name] = parseRef2(ref);
171
+ const base = client.getProxyBase();
172
+ const body = { input };
173
+ if (timeout !== void 0) {
174
+ body.timeout = timeout;
175
+ }
176
+ const res = await client.fetch(`${base}/functions/${ns}/${name}/execute`, {
177
+ method: "POST",
178
+ body: JSON.stringify(body)
179
+ });
180
+ const data = await res.json();
181
+ return {
182
+ status: data.status,
183
+ executionId: data.execution_id,
184
+ result: data.result,
185
+ error: data.error
186
+ };
187
+ }
188
+
189
+ // src/client/states.ts
190
+ async function stateGet(client, ns, key) {
191
+ const base = client.getProxyBase();
192
+ const res = await client.fetch(`${base}/states/${ns}`, {
193
+ method: "POST",
194
+ body: JSON.stringify({ action: "get", key })
195
+ });
196
+ return res.json();
197
+ }
198
+ async function stateSet(client, ns, key, value, visibility = "private") {
199
+ const base = client.getProxyBase();
200
+ await client.fetch(`${base}/states/${ns}`, {
201
+ method: "POST",
202
+ body: JSON.stringify({ action: "set", key, value, visibility })
203
+ });
204
+ }
205
+ async function stateDelete(client, ns, key) {
206
+ const base = client.getProxyBase();
207
+ await client.fetch(`${base}/states/${ns}`, {
208
+ method: "POST",
209
+ body: JSON.stringify({ action: "delete", key })
210
+ });
211
+ }
212
+ async function stateList(client, ns) {
213
+ const base = client.getProxyBase();
214
+ const res = await client.fetch(`${base}/states/${ns}`, {
215
+ method: "POST",
216
+ body: JSON.stringify({ action: "list" })
217
+ });
218
+ return res.json();
219
+ }
220
+
221
+ // src/client/chat.ts
222
+ async function createChat(client, agentRef, input) {
223
+ const [ns, name] = agentRef.split("/");
224
+ if (!ns || !name) {
225
+ throw new Error(`Invalid agent ref "${agentRef}": expected "namespace/name"`);
226
+ }
227
+ const config = client.getConfig();
228
+ const res = await client.fetch(`${config.apiBase}/agents/${ns}/${name}/chats`, {
229
+ method: "POST",
230
+ body: JSON.stringify({ input: input || {} })
231
+ });
232
+ const data = await res.json();
233
+ return {
234
+ id: data.id,
235
+ agentNamespace: data.agent_namespace,
236
+ agentName: data.agent_name,
237
+ title: data.title
238
+ };
239
+ }
240
+ async function sendMessage(client, chatId, content) {
241
+ const config = client.getConfig();
242
+ const res = await client.fetch(`${config.apiBase}/chats/${chatId}/messages`, {
243
+ method: "POST",
244
+ body: JSON.stringify({ content })
245
+ });
246
+ const data = await res.json();
247
+ return {
248
+ id: data.id,
249
+ chatId: data.chat_id,
250
+ role: data.role,
251
+ content: data.content,
252
+ createdAt: data.created_at
253
+ };
254
+ }
255
+ function parseSSE(buffer) {
256
+ const chunks = [];
257
+ const lines = buffer.split("\n");
258
+ let event = "";
259
+ let data = "";
260
+ let remaining = "";
261
+ for (let i = 0; i < lines.length; i++) {
262
+ const line = lines[i];
263
+ if (i === lines.length - 1 && !buffer.endsWith("\n")) {
264
+ remaining = line;
265
+ break;
266
+ }
267
+ if (line.startsWith("event:")) {
268
+ event = line.slice(6).trim();
269
+ } else if (line.startsWith("data:")) {
270
+ data = line.slice(5).trim();
271
+ } else if (line === "") {
272
+ if (event || data) {
273
+ chunks.push({ event: event || "message", data });
274
+ event = "";
275
+ data = "";
276
+ }
277
+ }
278
+ }
279
+ return { chunks, remaining };
280
+ }
281
+ function streamMessage(client, chatId, content, onChunk, onDone, onError) {
282
+ const controller = new AbortController();
283
+ const config = client.getConfig();
284
+ (async () => {
285
+ try {
286
+ const res = await fetch(`${config.apiBase}/chats/${chatId}/messages/stream`, {
287
+ method: "POST",
288
+ headers: client.getAuthHeaders(),
289
+ body: JSON.stringify({ content }),
290
+ signal: controller.signal
291
+ });
292
+ if (!res.ok) {
293
+ const body = await res.json().catch(() => ({ detail: res.statusText }));
294
+ throw new Error(body.detail || "Stream request failed");
295
+ }
296
+ const reader = res.body.getReader();
297
+ const decoder = new TextDecoder();
298
+ let buffer = "";
299
+ while (true) {
300
+ const { done, value } = await reader.read();
301
+ if (done) break;
302
+ buffer += decoder.decode(value, { stream: true });
303
+ const { chunks, remaining } = parseSSE(buffer);
304
+ buffer = remaining;
305
+ for (const chunk of chunks) {
306
+ onChunk(chunk);
307
+ if (chunk.event === "done") {
308
+ onDone?.();
309
+ return;
310
+ }
311
+ }
312
+ }
313
+ if (buffer.trim()) {
314
+ const { chunks } = parseSSE(buffer + "\n\n");
315
+ for (const chunk of chunks) {
316
+ onChunk(chunk);
317
+ }
318
+ }
319
+ onDone?.();
320
+ } catch (err) {
321
+ if (err.name === "AbortError") return;
322
+ onError?.(err);
323
+ }
324
+ })();
325
+ return controller;
326
+ }
327
+ // Annotate the CommonJS export names for ESM import in node:
328
+ 0 && (module.exports = {
329
+ SinasAuthError,
330
+ SinasClient,
331
+ SinasError,
332
+ SinasNotFoundError,
333
+ SinasPermissionError,
334
+ SinasTimeoutError,
335
+ createChat,
336
+ executeFunction,
337
+ executeQuery,
338
+ sendMessage,
339
+ stateDelete,
340
+ stateGet,
341
+ stateList,
342
+ stateSet,
343
+ streamMessage
344
+ });
345
+ //# sourceMappingURL=client.cjs.map