@agentuity/pi 1.0.35 → 2.0.16

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/src/index.ts CHANGED
@@ -1,243 +1,465 @@
1
+ /**
2
+ * Agentuity AI Gateway Custom Provider Extension
3
+ *
4
+ * Registers models from the Agentuity AI Gateway using the appropriate API type
5
+ * based on model ID patterns. Models are loaded dynamically from the gateway's /models endpoint.
6
+ *
7
+ * Usage:
8
+ * Use /model to switch to aigateway models
9
+ */
10
+ import { execFileSync } from 'node:child_process';
11
+ import { existsSync } from 'node:fs';
12
+ import { delimiter, join } from 'node:path';
13
+ import { createMinimalLogger, StructuredError } from '@agentuity/core';
14
+ import {
15
+ AIGatewayService,
16
+ type AIGatewayModel,
17
+ type AIGatewayModels,
18
+ } from '@agentuity/core/aigateway';
19
+ import { createServerFetchAdapter } from '@agentuity/server';
1
20
  import type {
2
- AgentToolResult,
3
21
  ExtensionAPI,
4
- ExtensionContext,
5
22
  ExtensionCommandContext,
23
+ ProviderModelConfig,
6
24
  } from '@mariozechner/pi-coding-agent';
7
- import type { TSchema } from '@sinclair/typebox';
8
- import { HubClient } from './client.ts';
9
- import { processActions } from './handlers.ts';
10
- import type { HubResponse, InitMessage } from './protocol.ts';
11
-
12
- const HUB_URL_ENV = 'AGENTUITY_CODER_HUB_URL';
13
-
14
- // All Pi events we subscribe to (order matters — session_start is handled separately)
15
- const PROXY_EVENTS = [
16
- 'session_shutdown',
17
- 'session_before_switch',
18
- 'session_switch',
19
- 'session_before_fork',
20
- 'session_fork',
21
- 'session_before_compact',
22
- 'session_compact',
23
- 'before_agent_start',
24
- 'agent_start',
25
- 'agent_end',
26
- 'turn_start',
27
- 'turn_end',
28
- 'tool_call',
29
- 'tool_result',
30
- 'tool_execution_start',
31
- 'tool_execution_update',
32
- 'tool_execution_end',
33
- 'message_start',
34
- 'message_update',
35
- 'message_end',
36
- 'input',
37
- 'model_select',
38
- 'context',
39
- ] as const;
40
-
41
- // Generic event handler type for the iteration loop
42
- type GenericEventHandler = (
43
- event: string,
44
- handler: (event: unknown, ctx: ExtensionContext) => Promise<unknown>
45
- ) => void;
46
-
47
- function log(msg: string): void {
48
- console.error(`[agentuity-pi] ${msg}`);
49
- }
50
-
51
- export function agentuityCoderHub(pi: ExtensionAPI) {
52
- const hubUrl = process.env[HUB_URL_ENV];
53
-
54
- // No-op if not configured
55
- if (!hubUrl) {
56
- return;
57
- }
58
-
59
- log(`Hub URL: ${hubUrl}`);
60
-
61
- const client = new HubClient();
62
25
 
63
- // Connect to the Hub and register tools/commands
64
- async function connectAndRegister(): Promise<void> {
65
- if (client.connected) return;
66
-
67
- log('Connecting to Hub...');
68
- let initMsg: InitMessage;
26
+ export type KnownApi =
27
+ | 'openai-completions'
28
+ | 'mistral-conversations'
29
+ | 'openai-responses'
30
+ | 'azure-openai-responses'
31
+ | 'openai-codex-responses'
32
+ | 'anthropic-messages'
33
+ | 'bedrock-converse-stream'
34
+ | 'google-generative-ai'
35
+ | 'google-gemini-cli'
36
+ | 'google-vertex';
37
+
38
+ const KNOWN_APIS = new Set<string>([
39
+ 'openai-completions',
40
+ 'mistral-conversations',
41
+ 'openai-responses',
42
+ 'azure-openai-responses',
43
+ 'openai-codex-responses',
44
+ 'anthropic-messages',
45
+ 'bedrock-converse-stream',
46
+ 'google-generative-ai',
47
+ 'google-gemini-cli',
48
+ 'google-vertex',
49
+ ] satisfies KnownApi[]);
50
+
51
+ const AIGatewayModelFetchError = StructuredError('AIGatewayModelFetchError')<{
52
+ cause?: unknown;
53
+ }>();
54
+
55
+ type AgentuityOrganization = {
56
+ id: string;
57
+ name: string;
58
+ };
59
+
60
+ type AgentuityWhoami = {
61
+ organizations?: AgentuityOrganization[];
62
+ };
63
+
64
+ type AgentuityRegion = {
65
+ region: string;
66
+ description: string;
67
+ default?: boolean;
68
+ };
69
+
70
+ function parseFirstJsonObject(value: string): unknown {
71
+ const start = value.indexOf('{');
72
+ if (start === -1) {
73
+ throw new SyntaxError('No JSON object found');
74
+ }
69
75
 
70
- try {
71
- initMsg = await client.connect(hubUrl!);
72
- } catch (err) {
73
- const msg = err instanceof Error ? err.message : String(err);
74
- log(`Failed to connect: ${msg}`);
75
- return;
76
+ let depth = 0;
77
+ let inString = false;
78
+ let escaped = false;
79
+ for (let i = start; i < value.length; i++) {
80
+ const char = value[i];
81
+ if (escaped) {
82
+ escaped = false;
83
+ continue;
76
84
  }
77
-
78
- log(
79
- `Connected. Init: ${initMsg.tools?.length ?? 0} tools, ${initMsg.commands?.length ?? 0} commands`
80
- );
81
-
82
- // Register tools from Hub
83
- if (initMsg.tools) {
84
- for (const toolDef of initMsg.tools) {
85
- log(`Registering tool: ${toolDef.name}`);
86
- pi.registerTool({
87
- name: toolDef.name,
88
- label: toolDef.label,
89
- description: toolDef.description,
90
- parameters: toolDef.parameters as unknown as TSchema,
91
- async execute(
92
- toolCallId: string,
93
- params: unknown,
94
- _signal: AbortSignal | undefined,
95
- _onUpdate: unknown,
96
- ctx: ExtensionContext
97
- ) {
98
- log(`Tool execute: ${toolDef.name}`);
99
- const id = client.nextId();
100
- let response: HubResponse;
101
-
102
- try {
103
- response = await client.send({
104
- id,
105
- type: 'tool',
106
- name: toolDef.name,
107
- toolCallId,
108
- params: params as Record<string, unknown>,
109
- });
110
- } catch {
111
- return {
112
- content: [
113
- {
114
- type: 'text' as const,
115
- text: 'Error: Hub connection lost',
116
- },
117
- ],
118
- details: {},
119
- };
120
- }
121
-
122
- const result = await processActions(response.actions, ctx);
123
-
124
- if (result.returnValue !== undefined) {
125
- return result.returnValue as AgentToolResult<unknown>;
126
- }
127
-
128
- return {
129
- content: [{ type: 'text' as const, text: 'Done' }],
130
- details: {},
131
- };
132
- },
133
- });
85
+ if (char === '\\') {
86
+ escaped = true;
87
+ continue;
88
+ }
89
+ if (char === '"') {
90
+ inString = !inString;
91
+ continue;
92
+ }
93
+ if (inString) {
94
+ continue;
95
+ }
96
+ if (char === '{') {
97
+ depth++;
98
+ } else if (char === '}') {
99
+ depth--;
100
+ if (depth === 0) {
101
+ return JSON.parse(value.slice(start, i + 1));
134
102
  }
135
103
  }
104
+ }
136
105
 
137
- // Register commands from Hub
138
- if (initMsg.commands) {
139
- for (const cmdDef of initMsg.commands) {
140
- log(`Registering command: /${cmdDef.name}`);
141
- pi.registerCommand(cmdDef.name, {
142
- description: cmdDef.description,
143
- handler: async (args: string, ctx: ExtensionCommandContext) => {
144
- log(`Command execute: /${cmdDef.name}`);
145
- const id = client.nextId();
146
- let response: HubResponse;
147
-
148
- try {
149
- response = await client.send({
150
- id,
151
- type: 'command',
152
- name: cmdDef.name,
153
- args,
154
- });
155
- } catch {
156
- ctx.ui.notify('Hub connection lost', 'error');
157
- return;
158
- }
159
-
160
- await processActions(response.actions, ctx);
161
- },
162
- });
163
- }
106
+ throw new SyntaxError('Unterminated JSON object');
107
+ }
108
+
109
+ function parseJson(value: string): unknown {
110
+ const trimmed = value.trim();
111
+ if (trimmed.startsWith('[')) {
112
+ return JSON.parse(trimmed);
113
+ }
114
+ return parseFirstJsonObject(trimmed);
115
+ }
116
+
117
+ function getEnv(...keys: string[]): string | undefined {
118
+ for (const key of keys) {
119
+ if (process.env[key]) {
120
+ return process.env[key];
164
121
  }
122
+ }
123
+ }
165
124
 
166
- log('Registration complete');
125
+ function normalizeCredential(value: unknown): string | undefined {
126
+ if (value === undefined || value === null) {
127
+ return undefined;
167
128
  }
129
+ const normalized = String(value).trim();
130
+ return normalized.length > 0 ? normalized : undefined;
131
+ }
168
132
 
169
- // Helper to send event and process response actions
170
- async function sendEvent(
171
- eventName: string,
172
- data: Record<string, unknown>,
173
- ctx: ExtensionContext
174
- ): Promise<unknown> {
175
- if (!client.connected) return undefined;
133
+ function isKnownApi(api: unknown): api is KnownApi {
134
+ return typeof api === 'string' && KNOWN_APIS.has(api);
135
+ }
176
136
 
177
- const id = client.nextId();
178
- let response: HubResponse;
137
+ function getRegion(): string {
138
+ return getEnv('AGENTUITY_REGION') ?? 'usc';
139
+ }
179
140
 
180
- try {
181
- response = await client.send({
182
- id,
183
- type: 'event',
184
- event: eventName,
185
- data,
186
- });
187
- } catch {
188
- return undefined;
141
+ function getBaseUrl(): string {
142
+ const region = getRegion();
143
+ return `https://aigateway-${region}.agentuity.cloud`;
144
+ }
145
+
146
+ function getAgentuityCliPath(): string | undefined {
147
+ const path = process.env.PATH?.split(delimiter) ?? [];
148
+ for (const dir of path) {
149
+ const fn = join(dir, 'agentuity');
150
+ if (existsSync(fn)) {
151
+ return fn;
189
152
  }
153
+ }
154
+ }
190
155
 
191
- const result = await processActions(response.actions, ctx);
156
+ function fetchOrganizations(): AgentuityOrganization[] {
157
+ const agentuity = getAgentuityCliPath();
158
+ if (!agentuity) {
159
+ return [];
160
+ }
192
161
 
193
- if (result.block) return result.block;
194
- if (result.returnValue !== undefined) return result.returnValue;
195
- return undefined;
162
+ const res = execFileSync(agentuity, ['auth', 'whoami', '--json']);
163
+ const whoami = parseJson(res.toString()) as AgentuityWhoami;
164
+ return (whoami.organizations ?? []).filter(
165
+ (org): org is AgentuityOrganization =>
166
+ typeof org?.id === 'string' &&
167
+ org.id.length > 0 &&
168
+ typeof org?.name === 'string' &&
169
+ org.name.length > 0
170
+ );
171
+ }
172
+
173
+ function fetchRegions(): AgentuityRegion[] {
174
+ const agentuity = getAgentuityCliPath();
175
+ if (!agentuity) {
176
+ return [];
196
177
  }
197
178
 
198
- // Serialize event data strip non-serializable fields
199
- function serializeEvent(event: unknown): Record<string, unknown> {
200
- const data: Record<string, unknown> = {};
201
- if (event && typeof event === 'object') {
202
- for (const [key, value] of Object.entries(event)) {
203
- if (typeof value !== 'function' && key !== 'signal') {
204
- try {
205
- JSON.stringify(value);
206
- data[key] = value;
207
- } catch {
208
- // Skip non-serializable values
179
+ const res = execFileSync(agentuity, ['cloud', 'region', 'list', '--json']);
180
+ const regions = parseJson(res.toString()) as AgentuityRegion[];
181
+ return (Array.isArray(regions) ? regions : []).filter(
182
+ (region): region is AgentuityRegion =>
183
+ typeof region?.region === 'string' &&
184
+ region.region.length > 0 &&
185
+ typeof region?.description === 'string' &&
186
+ region.description.length > 0
187
+ );
188
+ }
189
+
190
+ function getCurrentOrgId(): string | undefined {
191
+ return normalizeCredential(
192
+ getEnv(
193
+ 'AGENTUITY_AIGATEWAY_ORGID',
194
+ 'AGENTUITY_ORGID',
195
+ 'AGENTUITY_CLOUD_ORG_ID',
196
+ 'AGENTUITY_ORG_ID'
197
+ )
198
+ );
199
+ }
200
+
201
+ async function fetchModels(): Promise<AIGatewayModels> {
202
+ const baseUrl = getBaseUrl();
203
+ let apiKey = normalizeCredential(
204
+ getEnv(
205
+ 'AGENTUITY_CODER_API_KEY',
206
+ 'AGENTUITY_SDK_KEY',
207
+ 'AGENTUITY_CLI_API_KEY',
208
+ 'AGENTUITY_CLI_KEY'
209
+ )
210
+ );
211
+ let orgId = normalizeCredential(
212
+ getEnv('AGENTUITY_ORGID', 'AGENTUITY_CLOUD_ORG_ID', 'AGENTUITY_ORG_ID')
213
+ );
214
+
215
+ if (!apiKey) {
216
+ let found = false;
217
+ const fn = getAgentuityCliPath();
218
+ if (fn) {
219
+ try {
220
+ const res = execFileSync(fn, ['auth', 'apikey', '--json']);
221
+ const apiKeyResult = parseJson(res.toString()) as { apiKey: string };
222
+ apiKey = normalizeCredential(apiKeyResult.apiKey);
223
+ found = true;
224
+ if (!orgId) {
225
+ const ores = execFileSync(fn, ['auth', 'org', 'current']);
226
+ orgId = normalizeCredential(ores);
227
+ if (!orgId) {
228
+ return {};
209
229
  }
210
230
  }
231
+ } catch (error) {
232
+ throw new AIGatewayModelFetchError({
233
+ message: 'Failed to fetch models from AI Gateway',
234
+ cause: error,
235
+ });
211
236
  }
212
237
  }
213
- return data;
238
+ if (!found) {
239
+ console.warn(
240
+ 'AGENTUITY_SDK_KEY, AGENTUITY_CLI_API_KEY or AGENTUITY_CLI_KEY not set and cannot find the agentuity cli, cannot fetch models from AI Gateway'
241
+ );
242
+ return {};
243
+ }
244
+ }
245
+
246
+ if (!apiKey) {
247
+ console.warn('Cannot determine the API key, cannot fetch models from AI Gateway');
248
+ return {};
249
+ }
250
+
251
+ process.env.AGENTUITY_AIGATEWAY_KEY = apiKey;
252
+ if (orgId) {
253
+ process.env.AGENTUITY_AIGATEWAY_ORGID = orgId;
254
+ }
255
+
256
+ try {
257
+ const service = new AIGatewayService(
258
+ baseUrl,
259
+ createServerFetchAdapter({ headers: {} }, createMinimalLogger())
260
+ );
261
+ return await service.listModels();
262
+ } catch (error) {
263
+ throw new AIGatewayModelFetchError({
264
+ message: 'Failed to fetch models from AI Gateway',
265
+ cause: error,
266
+ });
214
267
  }
268
+ }
269
+
270
+ function sanitizeModalities(modalities: string[] | undefined): ('text' | 'image')[] {
271
+ const sanitized = (modalities ?? []).filter(
272
+ (modality): modality is 'text' | 'image' => modality === 'text' || modality === 'image'
273
+ );
274
+ return sanitized.length > 0 ? sanitized : ['text'];
275
+ }
215
276
 
216
- // Cast pi.on to generic handler since we iterate over a union of event names
217
- // TypeScript overloads require exact string literal matching which doesn't work in loops
218
- const onEvent = pi.on.bind(pi) as GenericEventHandler;
277
+ function toPiModel(m: AIGatewayModel): ProviderModelConfig {
278
+ return {
279
+ id: m.id,
280
+ name: m.name,
281
+ reasoning: m.reasoning ?? false,
282
+ input: sanitizeModalities(m.input_modalities),
283
+ contextWindow: m.context_window ?? 40000,
284
+ maxTokens: m.max_output_tokens ?? 64000,
285
+ cost: {
286
+ input: m.pricing?.input ?? 0,
287
+ output: m.pricing?.output ?? 0,
288
+ cacheRead: m.pricing?.cached_input ?? 0,
289
+ cacheWrite: 0,
290
+ },
291
+ compat: {
292
+ supportsDeveloperRole: false,
293
+ },
294
+ };
295
+ }
219
296
 
220
- // ── session_start: connect + register BEFORE Pi builds the tool list ──
221
- onEvent('session_start', async (event: unknown, ctx: ExtensionContext) => {
222
- await connectAndRegister();
297
+ async function registerAIGatewayProviders(pi: ExtensionAPI) {
298
+ const models = await fetchModels();
299
+ const baseUrl = getBaseUrl();
223
300
 
224
- if (client.connected) {
225
- return sendEvent('session_start', serializeEvent(event), ctx);
301
+ const allModels: AIGatewayModel[] = [];
302
+ for (const providerModels of Object.values(models)) {
303
+ if (providerModels) {
304
+ allModels.push(...providerModels);
226
305
  }
227
- });
306
+ }
307
+ if (allModels.length === 0) {
308
+ return;
309
+ }
310
+
311
+ const modelsByApi = new Map<KnownApi, ProviderModelConfig[]>();
312
+
313
+ for (const m of allModels) {
314
+ const apiType = m.api;
315
+ if (!isKnownApi(apiType)) {
316
+ continue;
317
+ }
318
+ const existing = modelsByApi.get(apiType) ?? [];
319
+ existing.push(toPiModel(m));
320
+ modelsByApi.set(apiType, existing);
321
+ }
322
+
323
+ const headers: Record<string, string> = {};
324
+ if (process.env.AGENTUITY_AIGATEWAY_ORGID) {
325
+ headers['x-agentuity-orgid'] = process.env.AGENTUITY_AIGATEWAY_ORGID;
326
+ }
228
327
 
229
- for (const eventName of PROXY_EVENTS) {
230
- onEvent(eventName, async (event: unknown, ctx: ExtensionContext) => {
231
- if (!client.connected) return undefined;
232
- return sendEvent(eventName, serializeEvent(event), ctx);
328
+ for (const [apiType, providerModels] of modelsByApi) {
329
+ const apitok = apiType.split('-');
330
+ const name = apitok.length >= 2 ? apitok.slice(0, 2).join('-') : apitok[0];
331
+ const providerName = `agentuity/${name}`;
332
+ pi.registerProvider(providerName, {
333
+ baseUrl,
334
+ apiKey: 'AGENTUITY_AIGATEWAY_KEY',
335
+ headers,
336
+ authHeader: true,
337
+ api: apiType,
338
+ models: providerModels,
233
339
  });
234
340
  }
341
+ }
342
+
343
+ function registerRegionCommand(pi: ExtensionAPI): void {
344
+ pi.registerCommand('region', {
345
+ description: 'Select active Agentuity region',
346
+ handler: async (_args: string, ctx: ExtensionCommandContext) => {
347
+ if (!ctx.hasUI) {
348
+ return;
349
+ }
350
+
351
+ let regions: AgentuityRegion[];
352
+ try {
353
+ regions = fetchRegions();
354
+ } catch (error) {
355
+ ctx.ui.notify(`Failed to load Agentuity regions: ${String(error)}`, 'error');
356
+ return;
357
+ }
358
+
359
+ if (regions.length === 0) {
360
+ ctx.ui.notify('No Agentuity regions found.', 'warning');
361
+ return;
362
+ }
363
+
364
+ const currentRegion = getRegion();
365
+ const labels = regions.map((region) => {
366
+ const marker = region.region === currentRegion ? '* ' : '';
367
+ const defaultLabel = region.default ? ' default' : '';
368
+ return `${marker}${region.description} (${region.region})${defaultLabel}`;
369
+ });
370
+ const selected = await ctx.ui.select('Select Agentuity Region', labels);
371
+ if (!selected) {
372
+ return;
373
+ }
374
+
375
+ const selectedIndex = labels.indexOf(selected);
376
+ const region = regions[selectedIndex];
377
+ if (!region) {
378
+ return;
379
+ }
235
380
 
236
- // Clean up on shutdown
237
- pi.on('session_shutdown', async () => {
238
- log('Shutting down');
239
- client.close();
381
+ process.env.AGENTUITY_REGION = region.region;
382
+ ctx.ui.notify(`Using Agentuity region: ${region.description}`, 'info');
383
+
384
+ try {
385
+ await registerAIGatewayProviders(pi);
386
+ ctx.ui.notify('Agentuity AI Gateway models refreshed.', 'info');
387
+ } catch (error) {
388
+ ctx.ui.notify(`Failed to refresh AI Gateway models: ${String(error)}`, 'error');
389
+ }
390
+ },
391
+ });
392
+ }
393
+
394
+ function registerOrganizationCommand(pi: ExtensionAPI): void {
395
+ pi.registerCommand('organization', {
396
+ description: 'Select active Agentuity organization',
397
+ handler: async (_args: string, ctx: ExtensionCommandContext) => {
398
+ if (!ctx.hasUI) {
399
+ return;
400
+ }
401
+
402
+ let organizations: AgentuityOrganization[];
403
+ try {
404
+ organizations = fetchOrganizations();
405
+ } catch (error) {
406
+ ctx.ui.notify(`Failed to load Agentuity organizations: ${String(error)}`, 'error');
407
+ return;
408
+ }
409
+
410
+ if (organizations.length === 0) {
411
+ ctx.ui.notify('No Agentuity organizations found for the current CLI login.', 'warning');
412
+ return;
413
+ }
414
+
415
+ const currentOrgId = getCurrentOrgId();
416
+ const labels = organizations.map((org) => {
417
+ const marker = org.id === currentOrgId ? '* ' : '';
418
+ return `${marker}${org.name} (${org.id})`;
419
+ });
420
+ const selected = await ctx.ui.select('Select Agentuity Organization', labels);
421
+ if (!selected) {
422
+ return;
423
+ }
424
+
425
+ const selectedIndex = labels.indexOf(selected);
426
+ const organization = organizations[selectedIndex];
427
+ if (!organization) {
428
+ return;
429
+ }
430
+
431
+ process.env.AGENTUITY_AIGATEWAY_ORGID = organization.id;
432
+ process.env.AGENTUITY_ORGID = organization.id;
433
+ process.env.AGENTUITY_CLOUD_ORG_ID = organization.id;
434
+ process.env.AGENTUITY_ORG_ID = organization.id;
435
+
436
+ ctx.ui.notify(`Using Agentuity organization: ${organization.name}`, 'info');
437
+
438
+ try {
439
+ await registerAIGatewayProviders(pi);
440
+ ctx.ui.notify('Agentuity AI Gateway models refreshed.', 'info');
441
+ } catch (error) {
442
+ ctx.ui.notify(`Failed to refresh AI Gateway models: ${String(error)}`, 'error');
443
+ }
444
+ },
445
+ });
446
+ }
447
+
448
+ export async function setupAIGateway(pi: ExtensionAPI) {
449
+ registerOrganizationCommand(pi);
450
+ registerRegionCommand(pi);
451
+ let showedOrganizationPrompt = false;
452
+ pi.on('session_start', (_event, ctx) => {
453
+ if (showedOrganizationPrompt || !ctx.hasUI || getCurrentOrgId()) {
454
+ return;
455
+ }
456
+ showedOrganizationPrompt = true;
457
+ ctx.ui.notify(
458
+ 'Use /organization to select an Agentuity organization for AI Gateway models.',
459
+ 'info'
460
+ );
240
461
  });
462
+ await registerAIGatewayProviders(pi);
241
463
  }
242
464
 
243
- export default agentuityCoderHub;
465
+ export default setupAIGateway;
package/dist/client.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import type { InitMessage, HubRequest, HubResponse } from './protocol.ts';
2
- export declare class HubClient {
3
- private ws;
4
- private pending;
5
- connect(url: string): Promise<InitMessage>;
6
- nextId(): string;
7
- send(request: HubRequest): Promise<HubResponse>;
8
- close(): void;
9
- get connected(): boolean;
10
- }
11
- //# sourceMappingURL=client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAQ1E,qBAAa,SAAS;IACrB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,OAAO,CAOX;IACE,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAuFhD,MAAM,IAAI,MAAM;IAIV,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAwBrD,KAAK,IAAI,IAAI;IAOb,IAAI,SAAS,IAAI,OAAO,CAEvB;CACD"}