@infolang/sdk 0.2.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.
package/dist/index.js ADDED
@@ -0,0 +1,748 @@
1
+ import { readFile, writeFile } from 'fs/promises';
2
+ import { homedir } from 'os';
3
+ import { join } from 'path';
4
+
5
+ // src/auth.ts
6
+
7
+ // src/errors.ts
8
+ var InfoLangError = class extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = new.target.name;
12
+ }
13
+ };
14
+ var InfoLangConfigError = class extends InfoLangError {
15
+ };
16
+ var InfoLangConnectionError = class extends InfoLangError {
17
+ };
18
+ var InfoLangAPIError = class extends InfoLangError {
19
+ status;
20
+ body;
21
+ requestId;
22
+ constructor(message, options) {
23
+ const suffix = options.requestId ? ` (request_id=${options.requestId})` : "";
24
+ super(`${message}${suffix}`);
25
+ this.status = options.status;
26
+ this.body = options.body;
27
+ this.requestId = options.requestId;
28
+ }
29
+ };
30
+ var AuthenticationError = class extends InfoLangAPIError {
31
+ };
32
+ var NotFoundError = class extends InfoLangAPIError {
33
+ };
34
+ var ValidationError = class extends InfoLangAPIError {
35
+ };
36
+ var RateLimitError = class extends InfoLangAPIError {
37
+ retryAfter;
38
+ constructor(message, options) {
39
+ super(message, options);
40
+ this.retryAfter = options.retryAfter;
41
+ }
42
+ };
43
+ var ServerError = class extends InfoLangAPIError {
44
+ };
45
+ function messageFromBody(body) {
46
+ if (body && typeof body === "object") {
47
+ const record = body;
48
+ for (const key of ["error", "message", "detail"]) {
49
+ const value = record[key];
50
+ if (typeof value === "string" && value) return value;
51
+ }
52
+ }
53
+ if (typeof body === "string" && body) return body;
54
+ return void 0;
55
+ }
56
+ function errorFromResponse(options) {
57
+ const message = messageFromBody(options.body) ?? `InfoLang request failed with status ${options.status}`;
58
+ switch (true) {
59
+ case (options.status === 401 || options.status === 403):
60
+ return new AuthenticationError(message, options);
61
+ case options.status === 404:
62
+ return new NotFoundError(message, options);
63
+ case (options.status === 400 || options.status === 422):
64
+ return new ValidationError(message, options);
65
+ case options.status === 429:
66
+ return new RateLimitError(message, options);
67
+ case options.status >= 500:
68
+ return new ServerError(message, options);
69
+ default:
70
+ return new InfoLangAPIError(message, options);
71
+ }
72
+ }
73
+
74
+ // src/auth.ts
75
+ var DEFAULT_SESSION_PATH = join(homedir(), ".config", "infolang", "session.json");
76
+ var ApiKeyAuth = class {
77
+ constructor(apiKey) {
78
+ this.apiKey = apiKey;
79
+ if (!apiKey) throw new InfoLangConfigError("apiKey must not be empty");
80
+ }
81
+ apiKey;
82
+ async headers() {
83
+ return { Authorization: `Bearer ${this.apiKey}` };
84
+ }
85
+ };
86
+ var DevKeyAuth = class {
87
+ namespace;
88
+ token;
89
+ constructor(devKey) {
90
+ const idx = devKey.indexOf(":");
91
+ if (idx < 0) throw new InfoLangConfigError("dev key must be in 'key:namespace' form");
92
+ this.token = devKey.slice(0, idx);
93
+ this.namespace = devKey.slice(idx + 1);
94
+ }
95
+ async headers() {
96
+ return { Authorization: `Bearer ${this.token}` };
97
+ }
98
+ };
99
+ var SessionFileAuth = class {
100
+ constructor(path = DEFAULT_SESSION_PATH) {
101
+ this.path = path;
102
+ }
103
+ path;
104
+ cache;
105
+ async load() {
106
+ let raw;
107
+ try {
108
+ raw = await readFile(this.path, "utf8");
109
+ } catch {
110
+ throw new InfoLangConfigError(
111
+ `session file not found at ${this.path}; run 'npx @infolang/cursor-setup'`
112
+ );
113
+ }
114
+ try {
115
+ return JSON.parse(raw);
116
+ } catch {
117
+ throw new InfoLangConfigError(`session file at ${this.path} is not valid JSON`);
118
+ }
119
+ }
120
+ async headers() {
121
+ let session = this.cache ?? await this.load();
122
+ if (this.isExpired(session)) session = await this.refresh(session);
123
+ this.cache = session;
124
+ if (!session.access_token) {
125
+ throw new InfoLangConfigError("session file is missing 'access_token'");
126
+ }
127
+ return { Authorization: `Bearer ${session.access_token}` };
128
+ }
129
+ isExpired(session) {
130
+ if (typeof session.expires_at !== "number") return false;
131
+ return Date.now() / 1e3 >= session.expires_at - 30;
132
+ }
133
+ async refresh(session) {
134
+ if (!session.refresh_token || !session.token_url) return session;
135
+ const resp = await fetch(session.token_url, {
136
+ method: "POST",
137
+ headers: { "content-type": "application/json" },
138
+ body: JSON.stringify({
139
+ grant_type: "refresh_token",
140
+ refresh_token: session.refresh_token
141
+ })
142
+ });
143
+ if (!resp.ok) return session;
144
+ const data = await resp.json();
145
+ const merged = { ...session, ...data };
146
+ if (typeof data.expires_in === "number") {
147
+ merged.expires_at = Date.now() / 1e3 + data.expires_in;
148
+ }
149
+ try {
150
+ await writeFile(this.path, JSON.stringify(merged));
151
+ } catch {
152
+ }
153
+ return merged;
154
+ }
155
+ };
156
+ var OriginAuth = class {
157
+ constructor(workspace, secret) {
158
+ this.workspace = workspace;
159
+ this.secret = secret;
160
+ }
161
+ workspace;
162
+ secret;
163
+ async headers() {
164
+ return {
165
+ "X-InfoLang-Workspace": this.workspace,
166
+ "X-InfoLang-Origin-Secret": this.secret
167
+ };
168
+ }
169
+ };
170
+
171
+ // src/resources/ops.ts
172
+ function compact(payload) {
173
+ return Object.fromEntries(Object.entries(payload).filter(([, v]) => v !== void 0));
174
+ }
175
+ function buildRecall(query, opts) {
176
+ return {
177
+ method: "POST",
178
+ path: "/v1/recall",
179
+ body: compact({
180
+ query,
181
+ namespace: opts.namespace,
182
+ top_k: opts.topK,
183
+ filters: opts.filters,
184
+ verbose: opts.verbose
185
+ })
186
+ };
187
+ }
188
+ function hitToChunk(hit) {
189
+ return {
190
+ i: hit.id ?? hit.i,
191
+ t: hit.text ?? hit.t ?? "",
192
+ g: hit.tags ?? hit.g,
193
+ s: hit.similarity ?? hit.score ?? hit.s
194
+ };
195
+ }
196
+ function parseRecall(data, metering) {
197
+ const record = data && typeof data === "object" ? data : {};
198
+ const rawChunks = Array.isArray(record.chunks) ? record.chunks : Array.isArray(record.hits) ? record.hits.map((hit) => hitToChunk(hit)) : Array.isArray(data) ? data : [];
199
+ const chunks = rawChunks.map((c) => {
200
+ const item = c;
201
+ return {
202
+ id: String(item.i ?? item.id ?? ""),
203
+ score: typeof item.s === "number" ? item.s : item.score,
204
+ text: String(item.t ?? item.text ?? ""),
205
+ tags: item.g ?? item.tags
206
+ };
207
+ });
208
+ const top = chunks[0]?.score;
209
+ return {
210
+ chunks,
211
+ namespace: record.namespace,
212
+ metering,
213
+ weak: top !== void 0 && top < 0.85
214
+ };
215
+ }
216
+ function buildRemember(text, opts) {
217
+ return {
218
+ method: "POST",
219
+ path: "/v1/remember",
220
+ body: compact({ text, namespace: opts.namespace, source: opts.source, tags: opts.tags })
221
+ };
222
+ }
223
+ function parseRemember(data) {
224
+ const record = data && typeof data === "object" ? data : {};
225
+ return {
226
+ memoryId: record.id ?? record.memory_id,
227
+ namespace: record.namespace
228
+ };
229
+ }
230
+ function buildForget(memoryId, namespace) {
231
+ return {
232
+ method: "DELETE",
233
+ path: `/v1/memories/${encodeURIComponent(memoryId)}`
234
+ };
235
+ }
236
+ function buildListBanks() {
237
+ return { method: "GET", path: "/v1/banks" };
238
+ }
239
+ function parseBanks(data) {
240
+ const record = data;
241
+ const items = Array.isArray(data) ? data : Array.isArray(record?.banks) ? record.banks : [];
242
+ return items.map((b) => {
243
+ const item = b;
244
+ const count = typeof item.count === "number" ? item.count : typeof item.total_memories === "number" ? item.total_memories : void 0;
245
+ return {
246
+ namespace: String(item.namespace ?? ""),
247
+ count
248
+ };
249
+ });
250
+ }
251
+ function buildListRecent(opts) {
252
+ const params = new URLSearchParams();
253
+ if (opts.namespace) params.set("namespace", opts.namespace);
254
+ if (opts.n !== void 0) params.set("limit", String(opts.n));
255
+ const query = params.toString();
256
+ return { method: "GET", path: `/v1/memories${query ? `?${query}` : ""}` };
257
+ }
258
+ function buildContextPack(query, opts) {
259
+ return {
260
+ method: "POST",
261
+ path: "/v1/context-pack",
262
+ body: compact({
263
+ query,
264
+ namespace: opts.namespace,
265
+ max_tokens: opts.maxTokens,
266
+ repo_root: opts.repoRoot
267
+ })
268
+ };
269
+ }
270
+ function parseContextPack(data, metering) {
271
+ const record = data && typeof data === "object" ? data : {};
272
+ return {
273
+ pack: String(record.pack ?? record.context ?? record.text ?? data ?? ""),
274
+ tokensEstimated: record.tokens_estimated,
275
+ namespace: record.namespace,
276
+ metering
277
+ };
278
+ }
279
+ function buildIngestRepo(namespace, opts) {
280
+ return {
281
+ method: "POST",
282
+ path: `/v1/repos/${encodeURIComponent(namespace)}/ingest`,
283
+ body: compact({ repo_root: opts.repoRoot, ref: opts.ref })
284
+ };
285
+ }
286
+ function buildExecute(operations) {
287
+ return { method: "POST", path: "/v1/execute", body: { operations } };
288
+ }
289
+ function buildHealth() {
290
+ return { method: "GET", path: "/v1/health" };
291
+ }
292
+ function filterHitsByTags(chunks, tagFilter, topK) {
293
+ let ordered = chunks;
294
+ if (tagFilter && tagFilter.length > 0) {
295
+ const wanted = new Set(
296
+ tagFilter.map((t) => t.trim().toLowerCase()).filter(Boolean)
297
+ );
298
+ const matches = (chunk) => {
299
+ if (!chunk.tags) return false;
300
+ const have = new Set(
301
+ chunk.tags.split(",").map((t) => t.trim().toLowerCase()).filter(Boolean)
302
+ );
303
+ for (const t of wanted) {
304
+ if (have.has(t)) return true;
305
+ }
306
+ return false;
307
+ };
308
+ ordered = [...chunks.filter(matches), ...chunks.filter((c) => !matches(c))];
309
+ }
310
+ return topK !== void 0 ? ordered.slice(0, topK) : ordered;
311
+ }
312
+ function buildRememberBatch(items, opts) {
313
+ const batchItems = items.map(
314
+ (item) => compact({
315
+ text: item.text,
316
+ source: item.source ?? opts.source,
317
+ tags: item.tags
318
+ })
319
+ );
320
+ return buildExecute([
321
+ {
322
+ op: "remember_batch",
323
+ args: compact({
324
+ items: batchItems,
325
+ namespace: opts.namespace,
326
+ source: opts.source
327
+ })
328
+ }
329
+ ]);
330
+ }
331
+ function parseExecuteRememberBatch(data) {
332
+ const record = data;
333
+ const results = Array.isArray(record?.results) ? record.results : [];
334
+ const out = [];
335
+ for (const result of results) {
336
+ const payload = result?.payload;
337
+ const inner = Array.isArray(payload?.results) ? payload.results : null;
338
+ if (inner) {
339
+ for (const r of inner) {
340
+ out.push(parseRemember(r));
341
+ }
342
+ } else {
343
+ out.push(parseRemember(payload ?? {}));
344
+ }
345
+ }
346
+ return out;
347
+ }
348
+ function normalizeRememberItems(items, defaultSource) {
349
+ return items.map((item) => {
350
+ if (typeof item === "string") {
351
+ return { text: item, source: defaultSource };
352
+ }
353
+ if (item && typeof item === "object" && typeof item.text === "string") {
354
+ return item;
355
+ }
356
+ throw new TypeError("rememberBatch items must be string or { text } object");
357
+ });
358
+ }
359
+
360
+ // src/resources/context.ts
361
+ var ContextResource = class {
362
+ constructor(transport, defaultNamespace) {
363
+ this.transport = transport;
364
+ this.defaultNamespace = defaultNamespace;
365
+ }
366
+ transport;
367
+ defaultNamespace;
368
+ async contextPack(query, options = {}) {
369
+ const namespace = options.namespace ?? this.defaultNamespace;
370
+ if (!namespace) {
371
+ throw new InfoLangConfigError(
372
+ "contextPack requires a namespace (set one on the client or pass it)"
373
+ );
374
+ }
375
+ const { data, metering } = await this.transport.request(
376
+ buildContextPack(query, {
377
+ namespace,
378
+ maxTokens: options.maxTokens,
379
+ repoRoot: options.repoRoot
380
+ })
381
+ );
382
+ return parseContextPack(data, metering);
383
+ }
384
+ async ingestRepo(namespace, options) {
385
+ const { data } = await this.transport.request(
386
+ buildIngestRepo(namespace, options)
387
+ );
388
+ return data && typeof data === "object" ? data : { result: data };
389
+ }
390
+ async execute(operations) {
391
+ const { data } = await this.transport.request(buildExecute(operations));
392
+ return data && typeof data === "object" ? data : { results: data };
393
+ }
394
+ };
395
+
396
+ // src/resources/health.ts
397
+ var HealthResource = class {
398
+ constructor(transport) {
399
+ this.transport = transport;
400
+ }
401
+ transport;
402
+ async check() {
403
+ const { data } = await this.transport.request(buildHealth());
404
+ return data && typeof data === "object" ? data : { status: data };
405
+ }
406
+ };
407
+
408
+ // src/resources/memory.ts
409
+ var MemoryResource = class {
410
+ constructor(transport, defaultNamespace) {
411
+ this.transport = transport;
412
+ this.defaultNamespace = defaultNamespace;
413
+ }
414
+ transport;
415
+ defaultNamespace;
416
+ async recall(query, options = {}) {
417
+ const { data, metering } = await this.transport.request(
418
+ buildRecall(query, {
419
+ namespace: options.namespace ?? this.defaultNamespace,
420
+ topK: options.topK,
421
+ filters: options.filters,
422
+ verbose: options.verbose
423
+ })
424
+ );
425
+ return parseRecall(data, metering);
426
+ }
427
+ /** Agent-style recall with a sensible default `topK` of 5. */
428
+ async investigate(query, options = {}) {
429
+ return this.recall(query, {
430
+ namespace: options.namespaceHint,
431
+ topK: options.topK ?? 5
432
+ });
433
+ }
434
+ async remember(text, options = {}) {
435
+ const { data } = await this.transport.request(
436
+ buildRemember(text, {
437
+ namespace: options.namespace ?? this.defaultNamespace,
438
+ source: options.source,
439
+ tags: options.tags
440
+ })
441
+ );
442
+ return parseRemember(data);
443
+ }
444
+ /** Alias for `remember` matching the `auto_memorize` tool. */
445
+ async memorize(content, options = {}) {
446
+ return this.remember(content, options);
447
+ }
448
+ async forget(memoryId, options = {}) {
449
+ await this.transport.request(
450
+ buildForget(memoryId, options.namespace ?? this.defaultNamespace)
451
+ );
452
+ }
453
+ async listBanks() {
454
+ const { data } = await this.transport.request(buildListBanks());
455
+ return parseBanks(data);
456
+ }
457
+ async listRecent(options = {}) {
458
+ const { data } = await this.transport.request(
459
+ buildListRecent({ namespace: options.namespace ?? this.defaultNamespace, n: options.n })
460
+ );
461
+ if (Array.isArray(data)) return data;
462
+ const record = data;
463
+ return Array.isArray(record?.memories) ? record.memories : [];
464
+ }
465
+ /** Recall with tag-inclusion ordering over a candidate pool (client-side). */
466
+ async recallHybrid(query, options = {}) {
467
+ void options.useHybrid;
468
+ const ns = options.namespace ?? this.defaultNamespace;
469
+ const topK = options.topK ?? 10;
470
+ const pool = Math.max(options.candidatePool ?? 0, topK) || topK;
471
+ const result = await this.recall(query, { namespace: ns, topK: pool });
472
+ result.chunks = filterHitsByTags(result.chunks, options.tagFilter, topK);
473
+ return result;
474
+ }
475
+ /** Store many memories via POST /v1/execute remember_batch. */
476
+ async rememberBatch(items, options = {}) {
477
+ if (!items.length) return [];
478
+ const records = normalizeRememberItems(items, options.source);
479
+ const { data } = await this.transport.request(
480
+ buildRememberBatch(records, {
481
+ namespace: options.namespace ?? this.defaultNamespace,
482
+ source: options.source
483
+ })
484
+ );
485
+ return parseExecuteRememberBatch(data);
486
+ }
487
+ /** Best-effort bulk clear (list + forget loop). */
488
+ async resetNamespace(namespace, options = {}) {
489
+ const ns = namespace ?? this.defaultNamespace;
490
+ const batch = options.batch ?? 500;
491
+ let deleted = 0;
492
+ while (true) {
493
+ const recent = await this.listRecent({ namespace: ns, n: batch });
494
+ const ids = recent.map((r) => {
495
+ if (!r || typeof r !== "object") return null;
496
+ const row = r;
497
+ for (const key of ["id", "memory_id", "i"]) {
498
+ const v = row[key];
499
+ if (typeof v === "string" && v) return v;
500
+ }
501
+ return null;
502
+ }).filter((id) => Boolean(id));
503
+ if (!ids.length) break;
504
+ for (const id of ids) {
505
+ await this.forget(id, { namespace: ns });
506
+ deleted += 1;
507
+ }
508
+ if (ids.length < batch) break;
509
+ }
510
+ return deleted;
511
+ }
512
+ };
513
+
514
+ // src/transport.ts
515
+ var RETRY_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
516
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
517
+ function parseMetering(headers) {
518
+ const num = (name) => {
519
+ const raw = headers.get(name);
520
+ if (raw == null) return void 0;
521
+ const value = Number(raw);
522
+ return Number.isFinite(value) ? value : void 0;
523
+ };
524
+ return {
525
+ tokensSaved: num("x-infolang-tokens-saved"),
526
+ chunksUsed: num("x-infolang-chunks-used"),
527
+ repoCoverage: num("x-infolang-repo-coverage"),
528
+ requestId: headers.get("x-request-id") ?? void 0
529
+ };
530
+ }
531
+ function retryAfter(headers) {
532
+ const raw = headers.get("retry-after");
533
+ if (!raw) return void 0;
534
+ const value = Number(raw);
535
+ return Number.isFinite(value) ? value : void 0;
536
+ }
537
+ var Transport = class {
538
+ baseUrl;
539
+ auth;
540
+ fetchImpl;
541
+ timeoutMs;
542
+ maxRetries;
543
+ backoffBaseMs;
544
+ backoffCapMs;
545
+ userAgent;
546
+ workspaceId;
547
+ constructor(options) {
548
+ this.baseUrl = options.baseUrl.replace(/\/$/, "");
549
+ this.auth = options.auth;
550
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
551
+ this.timeoutMs = options.timeoutMs ?? 3e4;
552
+ this.maxRetries = options.maxRetries ?? 2;
553
+ this.backoffBaseMs = options.backoffBaseMs ?? 500;
554
+ this.backoffCapMs = options.backoffCapMs ?? 8e3;
555
+ this.userAgent = options.userAgent;
556
+ this.workspaceId = options.workspaceId;
557
+ if (!this.fetchImpl) {
558
+ throw new InfoLangConnectionError(
559
+ "global fetch is unavailable; pass a fetch implementation via the client options"
560
+ );
561
+ }
562
+ }
563
+ delay(attempt, retryAfterSec) {
564
+ if (retryAfterSec != null) return retryAfterSec * 1e3;
565
+ const window = Math.min(this.backoffCapMs, this.backoffBaseMs * 2 ** attempt);
566
+ return Math.random() * window;
567
+ }
568
+ async request(options) {
569
+ const url = `${this.baseUrl}${options.path}`;
570
+ let lastError;
571
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
572
+ const controller = new AbortController();
573
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
574
+ const headers = {
575
+ "User-Agent": this.userAgent,
576
+ Accept: "application/json",
577
+ ...await this.auth.headers(),
578
+ ...options.headers
579
+ };
580
+ if (this.workspaceId) {
581
+ headers["X-InfoLang-Workspace-Id"] = this.workspaceId;
582
+ }
583
+ if (options.body !== void 0) headers["Content-Type"] = "application/json";
584
+ let response;
585
+ try {
586
+ response = await this.fetchImpl(url, {
587
+ method: options.method,
588
+ headers,
589
+ body: options.body !== void 0 ? JSON.stringify(options.body) : void 0,
590
+ signal: controller.signal
591
+ });
592
+ } catch (err) {
593
+ lastError = err;
594
+ clearTimeout(timer);
595
+ if (attempt >= this.maxRetries) {
596
+ throw new InfoLangConnectionError(
597
+ err instanceof Error ? err.message : "request failed"
598
+ );
599
+ }
600
+ await sleep(this.delay(attempt));
601
+ continue;
602
+ } finally {
603
+ clearTimeout(timer);
604
+ }
605
+ if (RETRY_STATUSES.has(response.status) && attempt < this.maxRetries) {
606
+ await sleep(this.delay(attempt, retryAfter(response.headers)));
607
+ continue;
608
+ }
609
+ return this.finish(response);
610
+ }
611
+ throw new InfoLangConnectionError(
612
+ lastError instanceof Error ? lastError.message : "request failed after retries"
613
+ );
614
+ }
615
+ async finish(response) {
616
+ const metering = parseMetering(response.headers);
617
+ const text = await response.text();
618
+ let data = text;
619
+ if (text) {
620
+ try {
621
+ data = JSON.parse(text);
622
+ } catch {
623
+ data = text;
624
+ }
625
+ }
626
+ if (response.ok) return { data, metering };
627
+ throw errorFromResponse({
628
+ status: response.status,
629
+ body: data,
630
+ requestId: metering.requestId,
631
+ retryAfter: retryAfter(response.headers)
632
+ });
633
+ }
634
+ };
635
+
636
+ // src/version.ts
637
+ var version = "0.2.0";
638
+
639
+ // src/client.ts
640
+ var CLOUD_BASE_URL = "https://api.infolang.ai";
641
+ var DIRECT_BASE_URL = "http://127.0.0.1:8766";
642
+ function resolveAuth(options) {
643
+ if (options.auth) return options.auth;
644
+ if (options.apiKey) return new ApiKeyAuth(options.apiKey);
645
+ if (options.devKey) return new DevKeyAuth(options.devKey);
646
+ const envKey = globalThis.process?.env?.INFOLANG_API_KEY;
647
+ if (envKey) return new ApiKeyAuth(envKey);
648
+ const envDev = globalThis.process?.env?.INFOLANG_DEV_KEY;
649
+ if (envDev) return new DevKeyAuth(envDev);
650
+ throw new InfoLangConfigError(
651
+ "No credentials. Pass apiKey, devKey, or auth, set INFOLANG_API_KEY, or use InfoLang.fromSessionFile()."
652
+ );
653
+ }
654
+ function resolveBaseUrl(options, auth) {
655
+ if (options.baseUrl) return options.baseUrl;
656
+ const envUrl = globalThis.process?.env?.INFOLANG_BASE_URL;
657
+ if (envUrl) return envUrl;
658
+ return auth instanceof DevKeyAuth ? DIRECT_BASE_URL : CLOUD_BASE_URL;
659
+ }
660
+ function resolveNamespace(options, auth) {
661
+ if (options.namespace) return options.namespace;
662
+ if (auth instanceof DevKeyAuth) return auth.namespace;
663
+ return globalThis.process?.env?.INFOLANG_NAMESPACE;
664
+ }
665
+ function resolveWorkspace(options) {
666
+ if (options.workspace) return options.workspace;
667
+ return globalThis.process?.env?.INFOLANG_WORKSPACE ?? globalThis.process?.env?.INFOLANG_WORKSPACE_ID;
668
+ }
669
+ var InfoLang = class _InfoLang {
670
+ namespace;
671
+ workspace;
672
+ baseUrl;
673
+ memory;
674
+ context;
675
+ health;
676
+ constructor(options = {}) {
677
+ const auth = resolveAuth(options);
678
+ this.baseUrl = resolveBaseUrl(options, auth);
679
+ this.namespace = resolveNamespace(options, auth);
680
+ this.workspace = resolveWorkspace(options);
681
+ const transport = new Transport({
682
+ baseUrl: this.baseUrl,
683
+ auth,
684
+ fetch: options.fetch,
685
+ timeoutMs: options.timeoutMs,
686
+ maxRetries: options.maxRetries,
687
+ userAgent: `infolang-typescript/${version}`,
688
+ workspaceId: this.workspace
689
+ });
690
+ this.memory = new MemoryResource(transport, this.namespace);
691
+ this.context = new ContextResource(transport, this.namespace);
692
+ this.health = new HealthResource(transport);
693
+ }
694
+ // --- constructors ---------------------------------------------------
695
+ static fromApiKey(apiKey, options = {}) {
696
+ return new _InfoLang({ ...options, apiKey });
697
+ }
698
+ static fromDevKey(devKey, options = {}) {
699
+ return new _InfoLang({ ...options, devKey });
700
+ }
701
+ static fromSessionFile(path, options = {}) {
702
+ return new _InfoLang({ ...options, auth: new SessionFileAuth(path) });
703
+ }
704
+ // --- top-level aliases ----------------------------------------------
705
+ recall(query, options) {
706
+ return this.memory.recall(query, options);
707
+ }
708
+ investigate(query, options) {
709
+ return this.memory.investigate(query, options);
710
+ }
711
+ remember(text, options) {
712
+ return this.memory.remember(text, options);
713
+ }
714
+ memorize(content, options) {
715
+ return this.memory.memorize(content, options);
716
+ }
717
+ forget(memoryId, options) {
718
+ return this.memory.forget(memoryId, options);
719
+ }
720
+ listBanks() {
721
+ return this.memory.listBanks();
722
+ }
723
+ listRecent(options) {
724
+ return this.memory.listRecent(options);
725
+ }
726
+ recallHybrid(query, options) {
727
+ return this.memory.recallHybrid(query, options);
728
+ }
729
+ rememberBatch(items, options) {
730
+ return this.memory.rememberBatch(items, options);
731
+ }
732
+ resetNamespace(namespace, options) {
733
+ return this.memory.resetNamespace(namespace, options);
734
+ }
735
+ contextPack(query, options) {
736
+ return this.context.contextPack(query, options);
737
+ }
738
+ ingestRepo(namespace, options) {
739
+ return this.context.ingestRepo(namespace, options);
740
+ }
741
+ execute(operations) {
742
+ return this.context.execute(operations);
743
+ }
744
+ };
745
+
746
+ export { ApiKeyAuth, AuthenticationError, CLOUD_BASE_URL, DEFAULT_SESSION_PATH, DIRECT_BASE_URL, DevKeyAuth, InfoLang, InfoLangAPIError, InfoLangConfigError, InfoLangConnectionError, InfoLangError, NotFoundError, OriginAuth, RateLimitError, ServerError, SessionFileAuth, ValidationError, version };
747
+ //# sourceMappingURL=index.js.map
748
+ //# sourceMappingURL=index.js.map