@anuma/sdk 3.6.2 → 3.7.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.
Files changed (27) hide show
  1. package/dist/expo/{chunk-7TATXBC5.mjs → chunk-AAB7OG7Q.mjs} +810 -4
  2. package/dist/{react/chunk-DFVCS3QQ.mjs → expo/chunk-BOY27A2C.mjs} +30 -3
  3. package/dist/expo/{consolidate-3QQPUWD6.mjs → consolidate-J5PHQKKY.mjs} +1 -1
  4. package/dist/expo/index.cjs +931 -825
  5. package/dist/expo/index.d.mts +9 -0
  6. package/dist/expo/index.d.ts +9 -0
  7. package/dist/expo/index.mjs +14 -817
  8. package/dist/{react/recall-OPKHWKZX.mjs → expo/recall-YVU7OSSJ.mjs} +2 -2
  9. package/dist/react/{chunk-DDHTJGZN.mjs → chunk-3VPEZDYL.mjs} +896 -4
  10. package/dist/{expo/chunk-DFVCS3QQ.mjs → react/chunk-BOY27A2C.mjs} +30 -3
  11. package/dist/react/{consolidate-3MXZV3G7.mjs → consolidate-PWJCAPZA.mjs} +1 -1
  12. package/dist/react/index.cjs +2021 -1907
  13. package/dist/react/index.d.mts +9 -0
  14. package/dist/react/index.d.ts +9 -0
  15. package/dist/react/index.mjs +29 -888
  16. package/dist/{expo/recall-IO4KJ5W7.mjs → react/recall-Z7BWJ67X.mjs} +2 -2
  17. package/dist/server/{chunk-V7SVKIXQ.mjs → chunk-LSKFJNLF.mjs} +795 -4
  18. package/dist/server/{chunk-AHJT66EO.mjs → chunk-MIXEASUP.mjs} +30 -3
  19. package/dist/server/{consolidate-CN2GQV4D.mjs → consolidate-PCHO3D3G.mjs} +1 -1
  20. package/dist/server/index.cjs +925 -163
  21. package/dist/server/index.d.mts +36 -0
  22. package/dist/server/index.d.ts +36 -0
  23. package/dist/server/index.mjs +9 -147
  24. package/dist/server/{recall-IWY2MYHR.mjs → recall-XEOLXA6P.mjs} +2 -2
  25. package/dist/tools/selection/index.cjs +793 -3
  26. package/dist/tools/selection/index.mjs +791 -3
  27. package/package.json +2 -2
@@ -2516,6 +2516,33 @@ type StreamingTransportResult = {
2516
2516
  * transport both honor this contract.
2517
2517
  */
2518
2518
  type StreamingTransport = (options: StreamingTransportOptions) => StreamingTransportResult;
2519
+ /**
2520
+ * Framework-agnostic tool execution loop.
2521
+ *
2522
+ * Sends a streaming completion request, auto-executes tools that have executors,
2523
+ * feeds results back to the model, and repeats until the model stops emitting
2524
+ * tool calls or hits the iteration limit.
2525
+ *
2526
+ * This is the same loop that powers `useChat` in the React SDK, extracted so
2527
+ * it can be used from Node.js servers, CLI tools, and background workers.
2528
+ *
2529
+ * @example
2530
+ * ```ts
2531
+ * import { runToolLoop } from "@anuma/sdk/server";
2532
+ *
2533
+ * const result = await runToolLoop({
2534
+ * messages: [{ role: "user", content: [{ type: "text", text: "What's the weather?" }] }],
2535
+ * model: "fireworks/accounts/fireworks/models/kimi-k2p5",
2536
+ * token: "my-api-token",
2537
+ * tools: [{
2538
+ * type: "function",
2539
+ * function: { name: "get_weather", parameters: { type: "object", properties: { city: { type: "string" } } } },
2540
+ * executor: async ({ city }) => fetchWeather(city),
2541
+ * }],
2542
+ * onData: (chunk) => process.stdout.write(chunk),
2543
+ * });
2544
+ * ```
2545
+ */
2519
2546
  declare function runToolLoop(options: RunToolLoopOptions): Promise<RunToolLoopResult>;
2520
2547
 
2521
2548
  /**
@@ -8146,6 +8173,15 @@ interface TopicExtractionInput {
8146
8173
  */
8147
8174
  interface TopicExtractOptions extends PortalLlmAuth {
8148
8175
  baseUrl?: string;
8176
+ /**
8177
+ * Optional per-call request path override, forwarded to
8178
+ * {@link callPortalJsonCompletion}. When set, topic extraction POSTs to
8179
+ * `baseUrl + endpointOverride` instead of the default
8180
+ * `/api/v1/chat/completions` — path only, body unchanged. Lets callers route
8181
+ * this internal-utility pass to a dedicated endpoint. Invalid values throw at
8182
+ * call time (see {@link validateEndpointOverride}).
8183
+ */
8184
+ endpointOverride?: string;
8149
8185
  /** Defaults to {@link DEFAULT_EXTRACTION_MODEL} — the sanctioned extraction
8150
8186
  * model. Don't point this at a second model without an eval. */
8151
8187
  model?: string;
@@ -2516,6 +2516,33 @@ type StreamingTransportResult = {
2516
2516
  * transport both honor this contract.
2517
2517
  */
2518
2518
  type StreamingTransport = (options: StreamingTransportOptions) => StreamingTransportResult;
2519
+ /**
2520
+ * Framework-agnostic tool execution loop.
2521
+ *
2522
+ * Sends a streaming completion request, auto-executes tools that have executors,
2523
+ * feeds results back to the model, and repeats until the model stops emitting
2524
+ * tool calls or hits the iteration limit.
2525
+ *
2526
+ * This is the same loop that powers `useChat` in the React SDK, extracted so
2527
+ * it can be used from Node.js servers, CLI tools, and background workers.
2528
+ *
2529
+ * @example
2530
+ * ```ts
2531
+ * import { runToolLoop } from "@anuma/sdk/server";
2532
+ *
2533
+ * const result = await runToolLoop({
2534
+ * messages: [{ role: "user", content: [{ type: "text", text: "What's the weather?" }] }],
2535
+ * model: "fireworks/accounts/fireworks/models/kimi-k2p5",
2536
+ * token: "my-api-token",
2537
+ * tools: [{
2538
+ * type: "function",
2539
+ * function: { name: "get_weather", parameters: { type: "object", properties: { city: { type: "string" } } } },
2540
+ * executor: async ({ city }) => fetchWeather(city),
2541
+ * }],
2542
+ * onData: (chunk) => process.stdout.write(chunk),
2543
+ * });
2544
+ * ```
2545
+ */
2519
2546
  declare function runToolLoop(options: RunToolLoopOptions): Promise<RunToolLoopResult>;
2520
2547
 
2521
2548
  /**
@@ -8146,6 +8173,15 @@ interface TopicExtractionInput {
8146
8173
  */
8147
8174
  interface TopicExtractOptions extends PortalLlmAuth {
8148
8175
  baseUrl?: string;
8176
+ /**
8177
+ * Optional per-call request path override, forwarded to
8178
+ * {@link callPortalJsonCompletion}. When set, topic extraction POSTs to
8179
+ * `baseUrl + endpointOverride` instead of the default
8180
+ * `/api/v1/chat/completions` — path only, body unchanged. Lets callers route
8181
+ * this internal-utility pass to a dedicated endpoint. Invalid values throw at
8182
+ * call time (see {@link validateEndpointOverride}).
8183
+ */
8184
+ endpointOverride?: string;
8149
8185
  /** Defaults to {@link DEFAULT_EXTRACTION_MODEL} — the sanctioned extraction
8150
8186
  * model. Don't point this at a second model without an eval. */
8151
8187
  model?: string;
@@ -33,6 +33,7 @@ import {
33
33
  createLlmNeighborRefiner,
34
34
  createMemoryVaultSearchTool,
35
35
  createMessageOp,
36
+ createSseClient,
36
37
  createSupersedingMemoryOp,
37
38
  createVaultEmbeddingCache,
38
39
  createVaultMemoriesBatchOp,
@@ -124,7 +125,7 @@ import {
124
125
  updateVaultMemoryOp,
125
126
  upsertMessageOp,
126
127
  vaultMemoryToStored
127
- } from "./chunk-V7SVKIXQ.mjs";
128
+ } from "./chunk-LSKFJNLF.mjs";
128
129
  import {
129
130
  createStreamingDeAnonymizer,
130
131
  resolvePiiRedactor
@@ -134,8 +135,9 @@ import {
134
135
  extractJsonCandidate,
135
136
  getLogger,
136
137
  resolvePortalAuthHeaders,
137
- supportsResponseFormat
138
- } from "./chunk-AHJT66EO.mjs";
138
+ supportsResponseFormat,
139
+ validateEndpointOverride
140
+ } from "./chunk-MIXEASUP.mjs";
139
141
  import {
140
142
  BASE_URL,
141
143
  __commonJS,
@@ -5314,7 +5316,7 @@ async function tryConsolidate(trimmed, ctx, options) {
5314
5316
  content: m.content,
5315
5317
  similarity: m.similarity
5316
5318
  }));
5317
- const { consolidateMemory: doConsolidate } = await import("./consolidate-CN2GQV4D.mjs");
5319
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-PCHO3D3G.mjs");
5318
5320
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
5319
5321
  if (decision.action === "create") return null;
5320
5322
  if (decision.action === "supersede" && decision.targetId && decision.content) {
@@ -7057,6 +7059,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
7057
7059
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
7058
7060
  ...options.getToken !== void 0 && { getToken: options.getToken },
7059
7061
  ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
7062
+ ...options.endpointOverride !== void 0 && {
7063
+ endpointOverride: options.endpointOverride
7064
+ },
7060
7065
  model: options.model ?? DEFAULT_EXTRACTION_MODEL,
7061
7066
  systemPrompt: SYSTEM_PROMPT4,
7062
7067
  userMessage: `${vocabularyNote}Memories:
@@ -9177,133 +9182,6 @@ function createCryptoPricePreProcessor(options = {}) {
9177
9182
  };
9178
9183
  }
9179
9184
 
9180
- // src/client/core/serverSentEvents.gen.ts
9181
- function createSseClient({
9182
- onRequest,
9183
- onSseError,
9184
- onSseEvent,
9185
- responseTransformer,
9186
- responseValidator,
9187
- sseDefaultRetryDelay,
9188
- sseMaxRetryAttempts,
9189
- sseMaxRetryDelay,
9190
- sseSleepFn,
9191
- url,
9192
- ...options
9193
- }) {
9194
- let lastEventId;
9195
- const sleep3 = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
9196
- const createStream = async function* () {
9197
- let retryDelay = sseDefaultRetryDelay ?? 3e3;
9198
- let attempt = 0;
9199
- const signal = options.signal ?? new AbortController().signal;
9200
- while (true) {
9201
- if (signal.aborted) break;
9202
- attempt++;
9203
- const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
9204
- if (lastEventId !== void 0) {
9205
- headers.set("Last-Event-ID", lastEventId);
9206
- }
9207
- try {
9208
- const requestInit = {
9209
- redirect: "follow",
9210
- ...options,
9211
- body: options.serializedBody,
9212
- headers,
9213
- signal
9214
- };
9215
- let request = new Request(url, requestInit);
9216
- if (onRequest) {
9217
- request = await onRequest(url, requestInit);
9218
- }
9219
- const _fetch = options.fetch ?? globalThis.fetch;
9220
- const response = await _fetch(request);
9221
- if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`);
9222
- if (!response.body) throw new Error("No body in SSE response");
9223
- const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
9224
- let buffer = "";
9225
- const abortHandler = () => {
9226
- try {
9227
- reader.cancel();
9228
- } catch {
9229
- }
9230
- };
9231
- signal.addEventListener("abort", abortHandler);
9232
- try {
9233
- while (true) {
9234
- const { done, value } = await reader.read();
9235
- if (done) break;
9236
- buffer += value;
9237
- buffer = buffer.replace(/\r\n?/g, "\n");
9238
- const chunks = buffer.split("\n\n");
9239
- buffer = chunks.pop() ?? "";
9240
- for (const chunk of chunks) {
9241
- const lines = chunk.split("\n");
9242
- const dataLines = [];
9243
- let eventName;
9244
- for (const line of lines) {
9245
- if (line.startsWith("data:")) {
9246
- dataLines.push(line.replace(/^data:\s*/, ""));
9247
- } else if (line.startsWith("event:")) {
9248
- eventName = line.replace(/^event:\s*/, "");
9249
- } else if (line.startsWith("id:")) {
9250
- lastEventId = line.replace(/^id:\s*/, "");
9251
- } else if (line.startsWith("retry:")) {
9252
- const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10);
9253
- if (!Number.isNaN(parsed)) {
9254
- retryDelay = parsed;
9255
- }
9256
- }
9257
- }
9258
- let data;
9259
- let parsedJson = false;
9260
- if (dataLines.length) {
9261
- const rawData = dataLines.join("\n");
9262
- try {
9263
- data = JSON.parse(rawData);
9264
- parsedJson = true;
9265
- } catch {
9266
- data = rawData;
9267
- }
9268
- }
9269
- if (parsedJson) {
9270
- if (responseValidator) {
9271
- await responseValidator(data);
9272
- }
9273
- if (responseTransformer) {
9274
- data = await responseTransformer(data);
9275
- }
9276
- }
9277
- onSseEvent?.({
9278
- data,
9279
- event: eventName,
9280
- id: lastEventId,
9281
- retry: retryDelay
9282
- });
9283
- if (dataLines.length) {
9284
- yield data;
9285
- }
9286
- }
9287
- }
9288
- } finally {
9289
- signal.removeEventListener("abort", abortHandler);
9290
- reader.releaseLock();
9291
- }
9292
- break;
9293
- } catch (error) {
9294
- onSseError?.(error);
9295
- if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
9296
- break;
9297
- }
9298
- const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 3e4);
9299
- await sleep3(backoff);
9300
- }
9301
- }
9302
- };
9303
- const stream = createStream();
9304
- return { stream };
9305
- }
9306
-
9307
9185
  // src/lib/chat/runHooks.ts
9308
9186
  function composeHooks(hooks) {
9309
9187
  const handlers = hooks.filter((h) => h !== void 0 && h !== null);
@@ -11452,22 +11330,6 @@ function linkAbortSignals(a, b) {
11452
11330
  }
11453
11331
  };
11454
11332
  }
11455
- function validateEndpointOverride(override) {
11456
- const trimmed = override.trim();
11457
- if (trimmed === "") {
11458
- return {
11459
- valid: false,
11460
- message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
11461
- };
11462
- }
11463
- if (trimmed.startsWith("//") || trimmed.includes("://")) {
11464
- return {
11465
- valid: false,
11466
- message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
11467
- };
11468
- }
11469
- return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
11470
- }
11471
11333
  async function runToolLoop(options) {
11472
11334
  const {
11473
11335
  model,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-V7SVKIXQ.mjs";
4
- import "./chunk-AHJT66EO.mjs";
3
+ } from "./chunk-LSKFJNLF.mjs";
4
+ import "./chunk-MIXEASUP.mjs";
5
5
  import "./chunk-3RPGXXPZ.mjs";
6
6
  export {
7
7
  recall