@anuma/sdk 6.33.0 → 6.33.2
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/design/index.cjs +0 -2
- package/dist/design/index.d.mts +0 -7
- package/dist/design/index.d.ts +0 -7
- package/dist/design/index.mjs +0 -2
- package/dist/expo/{chunk-XD6WOQ5I.mjs → chunk-GQBTAM6Y.mjs} +0 -70
- package/dist/expo/{consolidate-7DBUHQRK.mjs → consolidate-3H2WY3FU.mjs} +1 -8
- package/dist/expo/index.cjs +15401 -16279
- package/dist/expo/index.d.mts +5735 -6661
- package/dist/expo/index.d.ts +5735 -6661
- package/dist/expo/index.mjs +15238 -16035
- package/dist/index.cjs +2258 -2411
- package/dist/index.d.mts +914 -1054
- package/dist/index.d.ts +914 -1054
- package/dist/index.mjs +2258 -2409
- package/dist/memory/context.d.mts +0 -73
- package/dist/memory/context.d.ts +0 -73
- package/dist/next/index.cjs +1 -8
- package/dist/next/index.mjs +1 -8
- package/dist/pii/transformers.d.mts +0 -32
- package/dist/pii/transformers.d.ts +0 -32
- package/dist/react/{chunk-XNQRJBIH.mjs → chunk-UFO4W3JX.mjs} +0 -70
- package/dist/react/{consolidate-5DVINCUE.mjs → consolidate-RHIAUBT4.mjs} +1 -8
- package/dist/react/index.cjs +32429 -33403
- package/dist/react/index.d.mts +13355 -14554
- package/dist/react/index.d.ts +13355 -14554
- package/dist/react/index.mjs +32555 -33450
- package/dist/server/{chunk-KSYV7UO2.mjs → chunk-4RGGAOAJ.mjs} +835 -905
- package/dist/server/{consolidate-MCNBSUXD.mjs → consolidate-YEGACWLR.mjs} +1 -8
- package/dist/server/index.cjs +22308 -23109
- package/dist/server/index.d.mts +5355 -6302
- package/dist/server/index.d.ts +5355 -6302
- package/dist/server/index.mjs +20543 -21279
- package/dist/telemetry/index.cjs +0 -9
- package/dist/telemetry/index.d.mts +88 -198
- package/dist/telemetry/index.d.ts +88 -198
- package/dist/telemetry/index.mjs +0 -9
- package/dist/tools/index.cjs +13036 -13347
- package/dist/tools/index.d.mts +2434 -2729
- package/dist/tools/index.d.ts +2434 -2729
- package/dist/tools/index.mjs +13036 -13347
- package/dist/tools/selection/index.cjs +0 -116
- package/dist/tools/selection/index.d.mts +0 -159
- package/dist/tools/selection/index.d.ts +0 -159
- package/dist/tools/selection/index.mjs +0 -116
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,126 +1,396 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform primitive constants.
|
|
3
|
+
*
|
|
4
|
+
* This module is intentionally dependency-free and side-effect-free so it can
|
|
5
|
+
* be loaded by *any* consumer — including React Native / Hermes — without
|
|
6
|
+
* pulling in the rest of the SDK. It is published as the `@anuma/sdk/constants`
|
|
7
|
+
* subpath (which carries a `react-native` export condition); slim consumers
|
|
8
|
+
* such as the agent packages import values from here instead of the bare
|
|
9
|
+
* `@anuma/sdk` entry, whose Node/web bundle is not RN-safe.
|
|
10
|
+
*
|
|
11
|
+
* Only add genuinely pure, cross-platform constants here (numeric/string
|
|
12
|
+
* literals, default IDs, size caps). No classes, no runtime APIs, no imports.
|
|
13
|
+
*/
|
|
14
|
+
/** Character cap for multiline / textarea fields. Agent gateways (e.g. cf-tasks)
|
|
15
|
+
* truncate values to this length before interpolating them into prompt templates.
|
|
16
|
+
* Shared across all agent packages so a single change updates every journey
|
|
17
|
+
* declaration simultaneously. */
|
|
18
|
+
declare const MULTILINE_FIELD_MAX = 50000;
|
|
19
|
+
|
|
20
|
+
/** Runtime environment where the agent can execute. */
|
|
21
|
+
type AgentRuntime = "client" | "server";
|
|
22
|
+
/** Strategy a consumer should use to extract text from an uploaded file before
|
|
23
|
+
* feeding it into a skill journey field. The SDK only labels the strategy —
|
|
24
|
+
* the actual extraction (pdf.js, OCR, etc.) is the consumer's responsibility. */
|
|
25
|
+
type FileExtractionStrategy = "pdf-text" | "csv-text" | "image-ocr";
|
|
26
|
+
|
|
27
|
+
/** Configuration for a single agent skill (task template). */
|
|
28
|
+
interface SkillConfig {
|
|
29
|
+
/** Unique identifier. Convention: "domain.action" e.g. "housing.lease-review" */
|
|
30
|
+
id: string;
|
|
31
|
+
/** Human-readable name. */
|
|
32
|
+
name: string;
|
|
33
|
+
/** System prompt template with {{variable}} placeholders. */
|
|
34
|
+
promptTemplate: string;
|
|
3
35
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
36
|
+
* User-turn template, interpolated with the same {{variable}} placeholders
|
|
37
|
+
* as `promptTemplate`. Optional, but strongly recommended for skill-driven
|
|
38
|
+
* (non-freeform) flows so the model receives a proper user turn — most
|
|
39
|
+
* Anthropic models reject requests that contain only a system message.
|
|
7
40
|
*/
|
|
8
|
-
|
|
41
|
+
userTemplate?: string;
|
|
42
|
+
/** MCP tool names this skill requires. */
|
|
43
|
+
requiredTools?: string[];
|
|
44
|
+
/** Preferred model when the caller doesn't specify one. */
|
|
45
|
+
preferredModel?: string;
|
|
46
|
+
/** Max agentic loop steps for this skill. */
|
|
47
|
+
maxSteps?: number;
|
|
48
|
+
/** Variables the promptTemplate expects at runtime. */
|
|
49
|
+
requiredVariables?: string[];
|
|
9
50
|
/**
|
|
10
|
-
*
|
|
51
|
+
* SMS-friendly question prompts keyed by variable name. The Anuma text
|
|
52
|
+
* gateway sends each prompt to the user one at a time and treats the
|
|
53
|
+
* user's reply as the slot value. Missing entries fall back to a
|
|
54
|
+
* generic "Please provide {name}." question in the gateway.
|
|
11
55
|
*
|
|
12
|
-
*
|
|
56
|
+
* Order of questions follows requiredVariables[] order.
|
|
13
57
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
58
|
+
smsPrompts?: Record<string, string>;
|
|
59
|
+
/** Additional context appended after the prompt template. */
|
|
60
|
+
contextSuffix?: string;
|
|
61
|
+
/** Lucide icon identifier (e.g. "FileSearch") for renderers that draw a skill icon. */
|
|
62
|
+
iconName?: string;
|
|
63
|
+
/** One-line announcement string shown when the skill is launched (channel-neutral). */
|
|
64
|
+
launchMessage?: string;
|
|
65
|
+
/** Conversational preamble shown after the user picks this skill, before the field
|
|
66
|
+
* questions begin. Used by chat-native guided flows (web, mobile, SMS, voice). */
|
|
67
|
+
preamble?: string;
|
|
68
|
+
/** Closing line shown after the user finishes the last field and before the agent
|
|
69
|
+
* starts the tool loop. Used by chat-native guided flows. */
|
|
70
|
+
closing?: string;
|
|
71
|
+
/** Fallback nudge for any required field on this skill that doesn't define its own
|
|
72
|
+
* `requiredNudge` string. */
|
|
73
|
+
requiredNudgeDefault?: string;
|
|
17
74
|
}
|
|
18
|
-
|
|
19
|
-
interface
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
75
|
+
/** Public-safe manifest describing an agent (no prompt or tool details). */
|
|
76
|
+
interface AgentManifest {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
description: string;
|
|
80
|
+
runtimes: AgentRuntime[];
|
|
81
|
+
skills: Array<{
|
|
82
|
+
id: string;
|
|
83
|
+
name: string;
|
|
84
|
+
requiredVariables?: string[];
|
|
85
|
+
smsPrompts?: Record<string, string>;
|
|
86
|
+
}>;
|
|
25
87
|
}
|
|
26
|
-
|
|
27
|
-
type
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
[K in HttpMethod]: MethodFn;
|
|
55
|
-
} & ([SseFn] extends [never] ? {
|
|
56
|
-
sse?: never;
|
|
57
|
-
} : {
|
|
58
|
-
sse: {
|
|
59
|
-
[K in HttpMethod]: SseFn;
|
|
60
|
-
};
|
|
88
|
+
/** Allowed input types for skill journey form fields. */
|
|
89
|
+
type SkillJourneyFieldType = "text" | "textarea" | "select";
|
|
90
|
+
/** Properties shared by every skill journey field, regardless of input type. */
|
|
91
|
+
interface SkillJourneyFieldBase {
|
|
92
|
+
key: string;
|
|
93
|
+
label: string;
|
|
94
|
+
placeholder: string;
|
|
95
|
+
helper?: string;
|
|
96
|
+
required?: boolean;
|
|
97
|
+
/** Conversational ask used by chat-native guided flows (web, mobile, SMS, voice).
|
|
98
|
+
* Falls through to `label` when not set. */
|
|
99
|
+
chatPrompt?: string;
|
|
100
|
+
/** Skill-specific nudge shown when the user skips a required field. Falls through
|
|
101
|
+
* to `SkillConfig.requiredNudgeDefault` when not set. */
|
|
102
|
+
requiredNudge?: string;
|
|
103
|
+
/** Server-side sanitiser cap on the value's character length. Today's gateways
|
|
104
|
+
* truncate textarea fields at `MULTILINE_FIELD_MAX` characters. */
|
|
105
|
+
maxLength?: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* A single field in a skill journey intake form. Discriminated on `type`:
|
|
109
|
+
* `select` requires `options`; `text` / `textarea` cannot carry options.
|
|
110
|
+
*/
|
|
111
|
+
type SkillJourneyField = (SkillJourneyFieldBase & {
|
|
112
|
+
type: "text" | "textarea";
|
|
113
|
+
}) | (SkillJourneyFieldBase & {
|
|
114
|
+
type: "select";
|
|
115
|
+
options: string[];
|
|
61
116
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
*
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
* style, and reserved characters are percent-encoded.
|
|
90
|
-
*
|
|
91
|
-
* This method will have no effect if the native `paramsSerializer()` Axios
|
|
92
|
-
* API function is used.
|
|
93
|
-
*
|
|
94
|
-
* {@link https://swagger.io/docs/specification/serialization/#query View examples}
|
|
95
|
-
*/
|
|
96
|
-
querySerializer?: QuerySerializer | QuerySerializerOptions;
|
|
97
|
-
/**
|
|
98
|
-
* A function validating request data. This is useful if you want to ensure
|
|
99
|
-
* the request conforms to the desired shape, so it can be safely sent to
|
|
100
|
-
* the server.
|
|
101
|
-
*/
|
|
102
|
-
requestValidator?: (data: unknown) => Promise<unknown>;
|
|
103
|
-
/**
|
|
104
|
-
* A function transforming response data before it's returned. This is useful
|
|
105
|
-
* for post-processing data, e.g., converting ISO strings into Date objects.
|
|
106
|
-
*/
|
|
107
|
-
responseTransformer?: (data: unknown) => Promise<unknown>;
|
|
117
|
+
/** Full definition for rendering a skill intake form and building the prompt. */
|
|
118
|
+
interface SkillJourneyDefinition {
|
|
119
|
+
title: string;
|
|
120
|
+
description: string;
|
|
121
|
+
steps: string[];
|
|
122
|
+
/** When true, the journey renders a file upload step before the fields. */
|
|
123
|
+
acceptsFiles: boolean;
|
|
124
|
+
/** Label for the file upload step. Only meaningful when `acceptsFiles` is true. */
|
|
125
|
+
fileLabel?: string;
|
|
126
|
+
/** Helper text for the file upload step. Only meaningful when `acceptsFiles` is true. */
|
|
127
|
+
fileHint?: string;
|
|
128
|
+
/** Per-skill copy for the file upload step prompt. Only meaningful when `acceptsFiles` is true. */
|
|
129
|
+
filePrompt?: string;
|
|
130
|
+
/** How consumers should derive text from an attached file. Describes extraction
|
|
131
|
+
* only — it is **not** a file-type filter. Files outside the strategy's expected
|
|
132
|
+
* MIME type (e.g. photos when the strategy is `pdf-text`) are still uploaded and
|
|
133
|
+
* forwarded to the agent as attachments; they are simply not text-extracted.
|
|
134
|
+
* The extracted text is written to the variable named by `extractedTextTarget`.
|
|
135
|
+
* Only meaningful when `acceptsFiles` is true. */
|
|
136
|
+
fileExtractionStrategy?: FileExtractionStrategy;
|
|
137
|
+
/** Variable name to write extracted text into. May coincide with a field's `key`
|
|
138
|
+
* (the upload replaces typed input for that field, e.g. `lease_text`) or name a
|
|
139
|
+
* separate template variable not tied to any field (e.g. `rent_notice_text`,
|
|
140
|
+
* `supporting_document_text`). Only meaningful when `acceptsFiles` is true and
|
|
141
|
+
* `fileExtractionStrategy` is set. */
|
|
142
|
+
extractedTextTarget?: string;
|
|
143
|
+
fields: SkillJourneyField[];
|
|
108
144
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
145
|
+
* When true, the journey expects substantive input — at least one of an
|
|
146
|
+
* `acceptsFiles` upload or a text/textarea field — for the agent to act on.
|
|
147
|
+
* Consumers (form renderers and direct API callers alike) should enforce
|
|
148
|
+
* "file or text provided" before invoking the skill.
|
|
112
149
|
*/
|
|
113
|
-
|
|
150
|
+
requiresContext: boolean;
|
|
151
|
+
submitLabel: string;
|
|
152
|
+
promptTitle: string;
|
|
153
|
+
/** Extra system prompt context injected per-skill for structured output guidance. */
|
|
154
|
+
systemContext?: string;
|
|
114
155
|
}
|
|
115
|
-
|
|
116
|
-
type
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
156
|
+
/** Marketplace filter the agent should appear under in the picker UI. */
|
|
157
|
+
type AgentMarketplaceFamily = "text" | "lifestyle";
|
|
158
|
+
/** What kind of action the marketplace card's primary CTA performs. */
|
|
159
|
+
type AgentPrimaryActionKind = "text" | "group" | "guided";
|
|
160
|
+
/** Visual tone for a transcript section heading. */
|
|
161
|
+
type AgentTranscriptTone = "danger" | "warning" | "success";
|
|
162
|
+
/** A single bullet inside a marketplace analysis transcript section. */
|
|
163
|
+
interface AgentTranscriptItem {
|
|
164
|
+
title: string;
|
|
165
|
+
detail: string;
|
|
166
|
+
}
|
|
167
|
+
/** A grouped block of bullets in a marketplace analysis transcript. */
|
|
168
|
+
interface AgentAnalysisSection {
|
|
169
|
+
title: string;
|
|
170
|
+
tone: AgentTranscriptTone;
|
|
171
|
+
items: AgentTranscriptItem[];
|
|
172
|
+
}
|
|
173
|
+
/** A todo entry inside a marketplace agenda transcript. */
|
|
174
|
+
interface AgentAgendaItem {
|
|
175
|
+
title: string;
|
|
176
|
+
badge?: string;
|
|
177
|
+
badgeTone?: "warning" | "danger";
|
|
178
|
+
}
|
|
179
|
+
/** A schedule entry inside a marketplace agenda transcript. */
|
|
180
|
+
interface AgentScheduleItem {
|
|
181
|
+
title: string;
|
|
182
|
+
time: string;
|
|
183
|
+
}
|
|
184
|
+
/** Marketplace transcript shape for productivity / agenda style agents. */
|
|
185
|
+
interface AgentAgendaTranscript {
|
|
186
|
+
kind: "agenda";
|
|
187
|
+
userMessage: string;
|
|
188
|
+
intro: string;
|
|
189
|
+
todos: AgentAgendaItem[];
|
|
190
|
+
schedule: AgentScheduleItem[];
|
|
191
|
+
followUp: string;
|
|
192
|
+
actions: string[];
|
|
193
|
+
}
|
|
194
|
+
/** Marketplace transcript shape for analysis / dispute style agents. */
|
|
195
|
+
interface AgentAnalysisTranscript {
|
|
196
|
+
kind: "analysis";
|
|
197
|
+
userMessage: string;
|
|
198
|
+
intro: string;
|
|
199
|
+
sections: AgentAnalysisSection[];
|
|
200
|
+
followUp: string;
|
|
201
|
+
actions: string[];
|
|
202
|
+
}
|
|
203
|
+
/** A scripted marketplace conversation preview, discriminated on `kind`. */
|
|
204
|
+
type AgentMarketplaceTranscript = AgentAgendaTranscript | AgentAnalysisTranscript;
|
|
205
|
+
/** Marketplace card content for an agent — the data the picker UI renders. */
|
|
206
|
+
interface AgentMarketplaceContent {
|
|
207
|
+
family: AgentMarketplaceFamily;
|
|
208
|
+
roleLabel: string;
|
|
209
|
+
primaryActionLabel: string;
|
|
210
|
+
primaryActionKind: AgentPrimaryActionKind;
|
|
211
|
+
cardUseCases: string[];
|
|
212
|
+
cardKnowledge: string[];
|
|
213
|
+
quickPrompts: string[];
|
|
214
|
+
emptyStateDescription: string;
|
|
215
|
+
transcript: AgentMarketplaceTranscript;
|
|
216
|
+
}
|
|
217
|
+
/** A single (user, agent) example conversation entry, keyed by i18n string ids. */
|
|
218
|
+
interface AgentExampleConversation {
|
|
219
|
+
userKey: string;
|
|
220
|
+
agentKey: string;
|
|
221
|
+
}
|
|
222
|
+
/** UI metadata used by clients when the portal doesn't supply richer data. */
|
|
223
|
+
interface AgentUiMetadata {
|
|
224
|
+
/** Hex color used by the agent card and accents. */
|
|
225
|
+
color: string;
|
|
226
|
+
/** Lucide icon identifier (e.g. "users"). */
|
|
227
|
+
icon: string;
|
|
228
|
+
/** i18n keys for the per-agent feature bullets. */
|
|
229
|
+
features: string[];
|
|
230
|
+
/** i18n keys for the example conversation strings. */
|
|
231
|
+
exampleConversations: AgentExampleConversation[];
|
|
232
|
+
/** Memory folder names this agent typically uses. */
|
|
233
|
+
suggestedMemoryFolders?: string[];
|
|
234
|
+
}
|
|
235
|
+
/** Full agent configuration including prompt, skills, tools, and model settings. */
|
|
236
|
+
interface AgentConfig {
|
|
237
|
+
id: string;
|
|
238
|
+
runtimes: AgentRuntime[];
|
|
239
|
+
prompt: string;
|
|
240
|
+
skills: SkillConfig[];
|
|
241
|
+
/** Tool configs are agent-specific, so we keep this generic. */
|
|
242
|
+
tools: unknown[];
|
|
243
|
+
model: {
|
|
244
|
+
default: string;
|
|
245
|
+
allowed?: string[];
|
|
246
|
+
};
|
|
247
|
+
manifest: AgentManifest;
|
|
248
|
+
/** Form schemas for rendering skill intake forms on the client. */
|
|
249
|
+
skillJourneys?: Record<string, SkillJourneyDefinition>;
|
|
250
|
+
/** First assistant message shown when the agent is opened. Supports the
|
|
251
|
+
* `{{agent_name}}` placeholder so consumers can substitute the portal-display
|
|
252
|
+
* name without changing this string. */
|
|
253
|
+
greeting?: string;
|
|
254
|
+
/** Sub-copy shown under the agent picker / guided-flow header. Supports the
|
|
255
|
+
* `{{agent_name}}` placeholder, same as `greeting`. */
|
|
256
|
+
guidedFlowSubcopy?: string;
|
|
257
|
+
/** Marketplace card content rendered in the agent picker. */
|
|
258
|
+
marketplace?: AgentMarketplaceContent;
|
|
259
|
+
/** UI metadata (color, icon, example conversations) for renderer fallbacks. */
|
|
260
|
+
uiMetadata?: AgentUiMetadata;
|
|
261
|
+
/** One-time disclaimer shown in a popup the first time a user opens
|
|
262
|
+
* a chat with this agent. Plain text; consumers split on `\n\n` for paragraphs.
|
|
263
|
+
* May include `{{agent_name}}` placeholder. */
|
|
264
|
+
firstTimeDisclaimer?: string;
|
|
265
|
+
/** Persistent one-line disclaimer rendered under the chat input
|
|
266
|
+
* whenever this agent's chat is open. May include `{{agent_name}}`
|
|
267
|
+
* placeholder. */
|
|
268
|
+
persistentFooter?: string;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
type AuthToken = string | undefined;
|
|
272
|
+
interface Auth {
|
|
273
|
+
/**
|
|
274
|
+
* Which part of the request do we use to send the auth?
|
|
275
|
+
*
|
|
276
|
+
* @default 'header'
|
|
277
|
+
*/
|
|
278
|
+
in?: 'header' | 'query' | 'cookie';
|
|
279
|
+
/**
|
|
280
|
+
* Header or query parameter name.
|
|
281
|
+
*
|
|
282
|
+
* @default 'Authorization'
|
|
283
|
+
*/
|
|
284
|
+
name?: string;
|
|
285
|
+
scheme?: 'basic' | 'bearer';
|
|
286
|
+
type: 'apiKey' | 'http';
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
interface SerializerOptions<T> {
|
|
290
|
+
/**
|
|
291
|
+
* @default true
|
|
292
|
+
*/
|
|
293
|
+
explode: boolean;
|
|
294
|
+
style: T;
|
|
295
|
+
}
|
|
296
|
+
type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited';
|
|
297
|
+
type ObjectStyle = 'form' | 'deepObject';
|
|
298
|
+
|
|
299
|
+
type QuerySerializer = (query: Record<string, unknown>) => string;
|
|
300
|
+
type BodySerializer = (body: unknown) => unknown;
|
|
301
|
+
type QuerySerializerOptionsObject = {
|
|
302
|
+
allowReserved?: boolean;
|
|
303
|
+
array?: Partial<SerializerOptions<ArrayStyle>>;
|
|
304
|
+
object?: Partial<SerializerOptions<ObjectStyle>>;
|
|
305
|
+
};
|
|
306
|
+
type QuerySerializerOptions = QuerySerializerOptionsObject & {
|
|
307
|
+
/**
|
|
308
|
+
* Per-parameter serialization overrides. When provided, these settings
|
|
309
|
+
* override the global array/object settings for specific parameter names.
|
|
310
|
+
*/
|
|
311
|
+
parameters?: Record<string, QuerySerializerOptionsObject>;
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
type HttpMethod = 'connect' | 'delete' | 'get' | 'head' | 'options' | 'patch' | 'post' | 'put' | 'trace';
|
|
315
|
+
type Client$1<RequestFn = never, Config = unknown, MethodFn = never, BuildUrlFn = never, SseFn = never> = {
|
|
316
|
+
/**
|
|
317
|
+
* Returns the final request URL.
|
|
318
|
+
*/
|
|
319
|
+
buildUrl: BuildUrlFn;
|
|
320
|
+
getConfig: () => Config;
|
|
321
|
+
request: RequestFn;
|
|
322
|
+
setConfig: (config: Config) => Config;
|
|
323
|
+
} & {
|
|
324
|
+
[K in HttpMethod]: MethodFn;
|
|
325
|
+
} & ([SseFn] extends [never] ? {
|
|
326
|
+
sse?: never;
|
|
327
|
+
} : {
|
|
328
|
+
sse: {
|
|
329
|
+
[K in HttpMethod]: SseFn;
|
|
330
|
+
};
|
|
331
|
+
});
|
|
332
|
+
interface Config$1 {
|
|
333
|
+
/**
|
|
334
|
+
* Auth token or a function returning auth token. The resolved value will be
|
|
335
|
+
* added to the request payload as defined by its `security` array.
|
|
336
|
+
*/
|
|
337
|
+
auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken;
|
|
338
|
+
/**
|
|
339
|
+
* A function for serializing request body parameter. By default,
|
|
340
|
+
* {@link JSON.stringify()} will be used.
|
|
341
|
+
*/
|
|
342
|
+
bodySerializer?: BodySerializer | null;
|
|
343
|
+
/**
|
|
344
|
+
* An object containing any HTTP headers that you want to pre-populate your
|
|
345
|
+
* `Headers` object with.
|
|
346
|
+
*
|
|
347
|
+
* {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
|
|
348
|
+
*/
|
|
349
|
+
headers?: RequestInit['headers'] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined | unknown>;
|
|
350
|
+
/**
|
|
351
|
+
* The request method.
|
|
352
|
+
*
|
|
353
|
+
* {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
|
|
354
|
+
*/
|
|
355
|
+
method?: Uppercase<HttpMethod>;
|
|
356
|
+
/**
|
|
357
|
+
* A function for serializing request query parameters. By default, arrays
|
|
358
|
+
* will be exploded in form style, objects will be exploded in deepObject
|
|
359
|
+
* style, and reserved characters are percent-encoded.
|
|
360
|
+
*
|
|
361
|
+
* This method will have no effect if the native `paramsSerializer()` Axios
|
|
362
|
+
* API function is used.
|
|
363
|
+
*
|
|
364
|
+
* {@link https://swagger.io/docs/specification/serialization/#query View examples}
|
|
365
|
+
*/
|
|
366
|
+
querySerializer?: QuerySerializer | QuerySerializerOptions;
|
|
367
|
+
/**
|
|
368
|
+
* A function validating request data. This is useful if you want to ensure
|
|
369
|
+
* the request conforms to the desired shape, so it can be safely sent to
|
|
370
|
+
* the server.
|
|
371
|
+
*/
|
|
372
|
+
requestValidator?: (data: unknown) => Promise<unknown>;
|
|
373
|
+
/**
|
|
374
|
+
* A function transforming response data before it's returned. This is useful
|
|
375
|
+
* for post-processing data, e.g., converting ISO strings into Date objects.
|
|
376
|
+
*/
|
|
377
|
+
responseTransformer?: (data: unknown) => Promise<unknown>;
|
|
378
|
+
/**
|
|
379
|
+
* A function validating response data. This is useful if you want to ensure
|
|
380
|
+
* the response conforms to the desired shape, so it can be safely passed to
|
|
381
|
+
* the transformers and returned to the user.
|
|
382
|
+
*/
|
|
383
|
+
responseValidator?: (data: unknown) => Promise<unknown>;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
type ServerSentEventsOptions<TData = unknown> = Omit<RequestInit, 'method'> & Pick<Config$1, 'method' | 'responseTransformer' | 'responseValidator'> & {
|
|
387
|
+
/**
|
|
388
|
+
* Fetch API implementation. You can use this option to provide a custom
|
|
389
|
+
* fetch instance.
|
|
390
|
+
*
|
|
391
|
+
* @default globalThis.fetch
|
|
392
|
+
*/
|
|
393
|
+
fetch?: typeof fetch;
|
|
124
394
|
/**
|
|
125
395
|
* Implementing clients can call request interceptors inside this hook.
|
|
126
396
|
*/
|
|
@@ -7226,22 +7496,68 @@ type LlmapiChatCompletionResponse = Omit<LlmapiChatCompletionResponse$1, "usage"
|
|
|
7226
7496
|
};
|
|
7227
7497
|
|
|
7228
7498
|
/**
|
|
7229
|
-
*
|
|
7499
|
+
* True when a text part is the attachment-contents part built by {@link buildAttachedFilesText}.
|
|
7230
7500
|
*
|
|
7231
|
-
*
|
|
7232
|
-
*
|
|
7501
|
+
* Matches the whole generated shape — opening tag plus the fixed header line, and the closing
|
|
7502
|
+
* tag — not just the tag, so user text that merely starts with `<attached_files>` is still
|
|
7503
|
+
* treated as the user's prompt.
|
|
7233
7504
|
*/
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7505
|
+
declare function isAttachedFilesText(text: string | undefined | null): boolean;
|
|
7506
|
+
/**
|
|
7507
|
+
* Wrap a turn's extracted file contents (the `[Extracted content from <name>]`
|
|
7508
|
+
* blocks `preprocessFiles` emits) in the tagged part that rides on that turn's
|
|
7509
|
+
* user message.
|
|
7510
|
+
*/
|
|
7511
|
+
declare function buildAttachedFilesText(fileContext: string): string;
|
|
7512
|
+
/**
|
|
7513
|
+
* Put the current turn's extracted attachment contents on the last user
|
|
7514
|
+
* message, as a text part inserted right after that message's LAST text part:
|
|
7515
|
+
* after everything the user wrote, and before any parts that follow it
|
|
7516
|
+
* (typically images). With interleaved parts such as `[text, image, text,
|
|
7517
|
+
* image]` it lands between the second text and the second image.
|
|
7518
|
+
*
|
|
7519
|
+
* Why not a system message: a detached system message at the front of the
|
|
7520
|
+
* request ("the user has attached files to this conversation") is separated
|
|
7521
|
+
* from the words that refer to it by the whole system prompt, tool catalog and
|
|
7522
|
+
* history. In a long, multi-file conversation fast models stopped connecting
|
|
7523
|
+
* the two and told users the attachment was unreadable even though its text
|
|
7524
|
+
* was in the request. Keeping the contents on the turn that attached them is
|
|
7525
|
+
* how native file attachments work on every provider, and survives the auto
|
|
7526
|
+
* router switching models between turns.
|
|
7527
|
+
*
|
|
7528
|
+
* The part goes AFTER the user's own text because the portal's query
|
|
7529
|
+
* classifier routes on the first text part of the last user message — it must
|
|
7530
|
+
* keep reading the user's prompt, not the document.
|
|
7531
|
+
*
|
|
7532
|
+
* Returns a new array; the input is not mutated. When there is no user
|
|
7533
|
+
* message the messages are returned unchanged.
|
|
7534
|
+
*/
|
|
7535
|
+
declare function attachFileContextToLastUserMessage(messages: LlmapiMessage[], fileContext: string): LlmapiMessage[];
|
|
7536
|
+
|
|
7537
|
+
/**
|
|
7538
|
+
* Value of the `origin` column on a row the SDK synthesised for a turn's tool results (v44, #866).
|
|
7539
|
+
*
|
|
7540
|
+
* `satisfies MessageOrigin` so this constant and the column's union cannot drift apart silently.
|
|
7541
|
+
*/
|
|
7542
|
+
declare const TOOL_RESULT_ORIGIN = "tool_result";
|
|
7543
|
+
|
|
7544
|
+
/**
|
|
7545
|
+
* PII detection patterns for structured data types.
|
|
7546
|
+
*
|
|
7547
|
+
* Each pattern has a category (used for placeholder tags like [EMAIL_1]),
|
|
7548
|
+
* a regex, and an optional validator for reducing false positives.
|
|
7549
|
+
*/
|
|
7550
|
+
type PiiCategory = "EMAIL" | "PHONE" | "SSN" | "CREDIT_CARD" | "IP_ADDRESS" | "API_KEY" | "US_ADDRESS" | "DATE_OF_BIRTH";
|
|
7551
|
+
interface PiiPattern {
|
|
7552
|
+
/**
|
|
7553
|
+
* Placeholder tag prefix for matches. Built-ins use {@link PiiCategory};
|
|
7554
|
+
* custom patterns may use any string (e.g. "PASSPORT", "IBAN").
|
|
7555
|
+
*/
|
|
7556
|
+
category: PiiCategory | (string & {});
|
|
7557
|
+
regex: RegExp;
|
|
7558
|
+
/** Optional post-match validation to reduce false positives. */
|
|
7559
|
+
validate?: (match: string) => boolean;
|
|
7560
|
+
/**
|
|
7245
7561
|
* Optional context guard. When set, a match is only redacted if this regex
|
|
7246
7562
|
* matches the text immediately preceding it (a short window). Used to require
|
|
7247
7563
|
* a cue word — e.g. only treat a date as a date-of-birth when "DOB" / "born"
|
|
@@ -7263,23 +7579,6 @@ interface PiiPattern {
|
|
|
7263
7579
|
*/
|
|
7264
7580
|
declare const PII_PATTERNS: PiiPattern[];
|
|
7265
7581
|
|
|
7266
|
-
/**
|
|
7267
|
-
* NER detector contract for PII redaction.
|
|
7268
|
-
*
|
|
7269
|
-
* The regex layer in {@link ./patterns} handles *structured* PII (email, phone,
|
|
7270
|
-
* SSN, credit card, …). It cannot detect *unstructured* PII — person names,
|
|
7271
|
-
* locations, organizations — which need a named-entity-recognition model.
|
|
7272
|
-
*
|
|
7273
|
-
* Rather than bundle a model (and a runtime) into the SDK, we define a small
|
|
7274
|
-
* runtime-agnostic contract: a {@link NerDetector} takes text and returns the
|
|
7275
|
-
* spans it found. Consumers supply an implementation appropriate to their
|
|
7276
|
-
* platform — a Transformers.js model in the browser/Node (see
|
|
7277
|
-
* `./detectors/transformers`), an `onnxruntime-react-native` model on mobile,
|
|
7278
|
-
* a remote service, or a fake in tests. The SDK keeps detection *on-device* by
|
|
7279
|
-
* never calling out itself; it only consumes the spans a detector returns and
|
|
7280
|
-
* merges them into the existing placeholder map.
|
|
7281
|
-
*/
|
|
7282
|
-
|
|
7283
7582
|
/**
|
|
7284
7583
|
* A character-offset span of detected PII. `start`/`end` are indices into the
|
|
7285
7584
|
* text passed to {@link NerDetector.detect} (`end` exclusive). `category`
|
|
@@ -7308,17 +7607,6 @@ interface NerDetector {
|
|
|
7308
7607
|
detect(text: string): Promise<PiiSpan[]>;
|
|
7309
7608
|
}
|
|
7310
7609
|
|
|
7311
|
-
/**
|
|
7312
|
-
* PII redaction engine.
|
|
7313
|
-
*
|
|
7314
|
-
* Scans text for personally identifiable information, replaces matches with
|
|
7315
|
-
* tagged placeholders ([EMAIL_1], [PHONE_2], …), and maintains a mapping
|
|
7316
|
-
* table so the original values can be restored in LLM responses.
|
|
7317
|
-
*
|
|
7318
|
-
* One `PiiRedactor` instance should be used per conversation to keep
|
|
7319
|
-
* placeholder numbering consistent across turns.
|
|
7320
|
-
*/
|
|
7321
|
-
|
|
7322
7610
|
interface PiiMatch {
|
|
7323
7611
|
category: PiiCategory | (string & {});
|
|
7324
7612
|
original: string;
|
|
@@ -7604,36 +7892,6 @@ declare function createStreamingDeAnonymizer(redactor: PiiRedactor, emit: (chunk
|
|
|
7604
7892
|
flush: () => void;
|
|
7605
7893
|
};
|
|
7606
7894
|
|
|
7607
|
-
/**
|
|
7608
|
-
* Union type for API responses - raw pass-through from server.
|
|
7609
|
-
* Responses API returns LlmapiResponseResponse (with output[]).
|
|
7610
|
-
* Completions API returns LlmapiChatCompletionResponse (with choices[]).
|
|
7611
|
-
*/
|
|
7612
|
-
type ApiResponse = LlmapiResponseResponse | LlmapiChatCompletionResponse;
|
|
7613
|
-
/**
|
|
7614
|
-
* Portal-side fields live under `response.portal` for the Chat Completions API
|
|
7615
|
-
* (new OpenAI-compliant wire shape) and at the top level for the Responses API.
|
|
7616
|
-
*
|
|
7617
|
-
* The SDK's `buildFinalResponse` mirrors portal fields back onto the top level
|
|
7618
|
-
* (and into `usage`) for backwards compatibility, so for streaming chat
|
|
7619
|
-
* completions both paths carry the data. For non-streaming chat completions
|
|
7620
|
-
* the wire ships only the portal-nested form.
|
|
7621
|
-
*
|
|
7622
|
-
* Precedence is per *field*, not per object: `portal?.x ?? legacy.x` reads the
|
|
7623
|
-
* portal field when it is non-nullish and otherwise falls through to the legacy
|
|
7624
|
-
* location — so a present-but-partial `portal` (e.g. checksum set, cost unset)
|
|
7625
|
-
* still resolves each field from wherever it actually carries a value.
|
|
7626
|
-
*/
|
|
7627
|
-
declare function getToolCallEvents(r: ApiResponse): LlmapiToolCallEvent[] | undefined;
|
|
7628
|
-
declare function getCostMicroUsd(r: ApiResponse): number | undefined;
|
|
7629
|
-
declare function getCreditsUsed(r: ApiResponse): number | undefined;
|
|
7630
|
-
/**
|
|
7631
|
-
* Image model the portal resolved for the request (set when an image-generation
|
|
7632
|
-
* tool ran). Chat Completions ships it under `portal.image_model` with a legacy
|
|
7633
|
-
* top-level mirror; the Responses API keeps it at the top level.
|
|
7634
|
-
*/
|
|
7635
|
-
declare function getImageModel(r: ApiResponse): string | undefined;
|
|
7636
|
-
|
|
7637
7895
|
/**
|
|
7638
7896
|
* Tool executor function type
|
|
7639
7897
|
*/
|
|
@@ -7710,11 +7968,100 @@ type ToolConfig = LlmapiChatCompletionTool & {
|
|
|
7710
7968
|
};
|
|
7711
7969
|
|
|
7712
7970
|
/**
|
|
7713
|
-
*
|
|
7971
|
+
* Union type for API responses - raw pass-through from server.
|
|
7972
|
+
* Responses API returns LlmapiResponseResponse (with output[]).
|
|
7973
|
+
* Completions API returns LlmapiChatCompletionResponse (with choices[]).
|
|
7974
|
+
*/
|
|
7975
|
+
type ApiResponse = LlmapiResponseResponse | LlmapiChatCompletionResponse;
|
|
7976
|
+
/**
|
|
7977
|
+
* Portal-side fields live under `response.portal` for the Chat Completions API
|
|
7978
|
+
* (new OpenAI-compliant wire shape) and at the top level for the Responses API.
|
|
7979
|
+
*
|
|
7980
|
+
* The SDK's `buildFinalResponse` mirrors portal fields back onto the top level
|
|
7981
|
+
* (and into `usage`) for backwards compatibility, so for streaming chat
|
|
7982
|
+
* completions both paths carry the data. For non-streaming chat completions
|
|
7983
|
+
* the wire ships only the portal-nested form.
|
|
7984
|
+
*
|
|
7985
|
+
* Precedence is per *field*, not per object: `portal?.x ?? legacy.x` reads the
|
|
7986
|
+
* portal field when it is non-nullish and otherwise falls through to the legacy
|
|
7987
|
+
* location — so a present-but-partial `portal` (e.g. checksum set, cost unset)
|
|
7988
|
+
* still resolves each field from wherever it actually carries a value.
|
|
7989
|
+
*/
|
|
7990
|
+
declare function getToolCallEvents(r: ApiResponse): LlmapiToolCallEvent[] | undefined;
|
|
7991
|
+
declare function getCostMicroUsd(r: ApiResponse): number | undefined;
|
|
7992
|
+
declare function getCreditsUsed(r: ApiResponse): number | undefined;
|
|
7993
|
+
/**
|
|
7994
|
+
* Image model the portal resolved for the request (set when an image-generation
|
|
7995
|
+
* tool ran). Chat Completions ships it under `portal.image_model` with a legacy
|
|
7996
|
+
* top-level mirror; the Responses API keeps it at the top level.
|
|
7997
|
+
*/
|
|
7998
|
+
declare function getImageModel(r: ApiResponse): string | undefined;
|
|
7999
|
+
|
|
8000
|
+
/**
|
|
8001
|
+
* Drop every cached plaintext title and pending decrypt promise.
|
|
8002
|
+
*
|
|
8003
|
+
* Wired into `clearAllEncryptionState()` via the listener registry in
|
|
8004
|
+
* `useEncryption.ts`. Also exported so consumers can clear the cache
|
|
8005
|
+
* proactively (e.g. on wallet switch within a session before the
|
|
8006
|
+
* full encryption-state teardown lands).
|
|
8007
|
+
*/
|
|
8008
|
+
declare function clearLazyTitleCache(): void;
|
|
8009
|
+
/**
|
|
8010
|
+
* Decrypt a single conversation title on demand.
|
|
8011
|
+
*
|
|
8012
|
+
* Designed for the lazy display path: pair with `listConversationsLazy`
|
|
8013
|
+
* and call this once a row is actually visible.
|
|
8014
|
+
*
|
|
8015
|
+
* Behavior:
|
|
8016
|
+
* - Plaintext input (no `enc:` prefix) is returned unchanged. This
|
|
8017
|
+
* covers conversations created before encryption was enabled and
|
|
8018
|
+
* keeps the helper safe to call unconditionally from rendering
|
|
8019
|
+
* code that may receive a mix of encrypted and plaintext titles.
|
|
8020
|
+
* - Encrypted input is decrypted via `decryptField`, which uses the
|
|
8021
|
+
* same per-version cached `CryptoKey` as the eager path — no new
|
|
8022
|
+
* key derivations are triggered.
|
|
8023
|
+
* - Concurrent calls for the same `(address, encryptedTitle)` share
|
|
8024
|
+
* a single decrypt promise.
|
|
8025
|
+
* - The result is memoized in a 256-entry LRU.
|
|
8026
|
+
*
|
|
8027
|
+
* Throws if the encryption key for `address` isn't loaded. (The
|
|
8028
|
+
* underlying `decryptField` would otherwise silently return the
|
|
8029
|
+
* ciphertext, which would surface to the UI as a literal `enc:v3:...`
|
|
8030
|
+
* title — strictly worse than a thrown error the caller can catch.)
|
|
8031
|
+
*
|
|
8032
|
+
* @param encryptedTitle - The stored title. May be ciphertext or plaintext.
|
|
8033
|
+
* @param address - Wallet address that owns the encryption key.
|
|
8034
|
+
* @returns The decrypted plaintext title.
|
|
8035
|
+
*/
|
|
8036
|
+
declare function decryptConversationTitle(encryptedTitle: string, address: string): Promise<string>;
|
|
8037
|
+
|
|
8038
|
+
/**
|
|
8039
|
+
* Why a file was not (fully) read. Paired with {@link FileProcessingStatus}.
|
|
8040
|
+
*
|
|
8041
|
+
* - `too_large`: over `maxFileSizeBytes`
|
|
8042
|
+
* - `unsupported_type`: no processor handles the file's type
|
|
8043
|
+
* - `no_data`: the file has no URL/data to read
|
|
8044
|
+
* - `empty`: the file was read but contained no extractable content
|
|
8045
|
+
* - `timeout`: processing exceeded `timeoutMs`
|
|
8046
|
+
* - `error`: the processor threw (corrupt, password-protected, …)
|
|
8047
|
+
*/
|
|
8048
|
+
type FileProcessingReason = "too_large" | "unsupported_type" | "no_data" | "empty" | "timeout" | "error";
|
|
8049
|
+
/**
|
|
8050
|
+
* What happened to one attached file during preprocessing — so the app can tell the user
|
|
8051
|
+
* precisely which attachment the model could not read, and why.
|
|
7714
8052
|
*
|
|
7715
|
-
*
|
|
7716
|
-
*
|
|
8053
|
+
* - `extracted`: its full text reached the model
|
|
8054
|
+
* - `truncated`: part of it reached the model (a size/row/image budget cut the rest)
|
|
8055
|
+
* - `rendered_as_images`: some or all pages were sent as images (scanned PDF)
|
|
8056
|
+
* - `skipped`: not processed (see `reason`)
|
|
8057
|
+
* - `failed`: processing was attempted and failed (see `reason`)
|
|
7717
8058
|
*/
|
|
8059
|
+
interface FileProcessingStatus {
|
|
8060
|
+
fileId: string;
|
|
8061
|
+
fileName: string;
|
|
8062
|
+
status: "extracted" | "truncated" | "rendered_as_images" | "skipped" | "failed";
|
|
8063
|
+
reason?: FileProcessingReason;
|
|
8064
|
+
}
|
|
7718
8065
|
|
|
7719
8066
|
/**
|
|
7720
8067
|
* Server tool definition with parameters field.
|
|
@@ -7951,723 +8298,153 @@ declare function createServerToolsFilter(options?: CreateServerToolsFilterOption
|
|
|
7951
8298
|
*/
|
|
7952
8299
|
declare const DEFAULT_EXCLUDED_SERVER_TOOLS: readonly string[];
|
|
7953
8300
|
/** Default match options for the server-tools filter (limit 5, minSim 0.5). */
|
|
7954
|
-
declare const DEFAULT_SERVER_TOOLS_MATCH_OPTIONS: ToolMatchOptions;
|
|
7955
|
-
/**
|
|
7956
|
-
* Pre-configured server-tools filter ready to drop into `useChatStorage`'s
|
|
7957
|
-
* `serverTools` option. Semantic matching against the user prompt with the
|
|
7958
|
-
* default exclusion list applied, plus call-chain expansion via
|
|
7959
|
-
* {@link SERVER_TOOL_DEPENDENCY_SETS} so continuation tools (read-after-search,
|
|
7960
|
-
* geocode-before-weather) ride in with their entry tool.
|
|
7961
|
-
*
|
|
7962
|
-
* @example
|
|
7963
|
-
* ```ts
|
|
7964
|
-
* import { defaultServerToolsFilter, useChatStorage } from "@anuma/sdk/react";
|
|
7965
|
-
*
|
|
7966
|
-
* useChatStorage({
|
|
7967
|
-
* ...,
|
|
7968
|
-
* serverTools: defaultServerToolsFilter,
|
|
7969
|
-
* });
|
|
7970
|
-
* ```
|
|
7971
|
-
*
|
|
7972
|
-
* If you need to customize (extra excludes, different limits, opt into
|
|
7973
|
-
* tool-set expansion), call `createServerToolsFilter` directly.
|
|
7974
|
-
*/
|
|
7975
|
-
declare const defaultServerToolsFilter: ServerToolsFilterFunction;
|
|
7976
|
-
/**
|
|
7977
|
-
* Type for a server-tools filter — a function that takes prompt embeddings
|
|
7978
|
-
* and the full server tool catalog and returns the names of tools to keep.
|
|
7979
|
-
* Matches `useChatStorage`'s `serverTools` callback signature.
|
|
7980
|
-
*/
|
|
7981
|
-
type ServerToolsFilterFunction = ((embeddings: number[] | number[][], tools: ServerTool[]) => string[]) & {
|
|
7982
|
-
/**
|
|
7983
|
-
* The unconditional exclusions this filter applies, exposed by
|
|
7984
|
-
* {@link createServerToolsFilter} so defer-loading can honour them without the caller
|
|
7985
|
-
* repeating the list — see {@link resolveDeferredServerTools}. Absent on a hand-written
|
|
7986
|
-
* filter, or on one wrapped in a plain closure.
|
|
7987
|
-
*/
|
|
7988
|
-
readonly excludeTools?: readonly string[];
|
|
7989
|
-
};
|
|
7990
|
-
/**
|
|
7991
|
-
* Options for selectServerSideTools
|
|
7992
|
-
*/
|
|
7993
|
-
interface SelectServerSideToolsOptions {
|
|
7994
|
-
/** The user prompt to match tools against */
|
|
7995
|
-
prompt: string;
|
|
7996
|
-
/** Function to get auth token (uses Authorization: Bearer header) */
|
|
7997
|
-
getToken?: () => Promise<string | null>;
|
|
7998
|
-
/** Direct API key for server-side usage (uses X-API-Key header) */
|
|
7999
|
-
apiKey?: string;
|
|
8000
|
-
/** Base URL for the API */
|
|
8001
|
-
baseUrl?: string;
|
|
8002
|
-
/** Cache expiration in ms (default: 24h) */
|
|
8003
|
-
cacheExpirationMs?: number;
|
|
8004
|
-
/** Force refresh tools cache */
|
|
8005
|
-
forceRefresh?: boolean;
|
|
8006
|
-
/** Embedding model to use */
|
|
8007
|
-
embeddingModel?: string;
|
|
8008
|
-
/** Max tools to return (default: 10) */
|
|
8009
|
-
limit?: number;
|
|
8010
|
-
/** Minimum cosine similarity 0-1 (default: 0.3) */
|
|
8011
|
-
minSimilarity?: number;
|
|
8012
|
-
/** API format for returned tools (default: "responses") */
|
|
8013
|
-
apiType?: "responses" | "completions";
|
|
8014
|
-
}
|
|
8015
|
-
/**
|
|
8016
|
-
* Select server tools that are semantically relevant to a prompt.
|
|
8017
|
-
*
|
|
8018
|
-
* Fetches available tools (with caching), generates embeddings for the prompt,
|
|
8019
|
-
* runs cosine-similarity matching, and returns tool schemas in the requested
|
|
8020
|
-
* API format (Responses or Completions).
|
|
8021
|
-
*
|
|
8022
|
-
* @example
|
|
8023
|
-
* ```ts
|
|
8024
|
-
* import { selectServerSideTools } from "@anuma/sdk/tools";
|
|
8025
|
-
*
|
|
8026
|
-
* const tools = await selectServerSideTools({
|
|
8027
|
-
* prompt: "Draw me a cat",
|
|
8028
|
-
* getToken: async () => identityToken,
|
|
8029
|
-
* });
|
|
8030
|
-
*
|
|
8031
|
-
* const response = await postApiV1Responses({
|
|
8032
|
-
* body: {
|
|
8033
|
-
* messages: [{ role: "user", content: [{ type: "text", text: "Draw me a cat" }] }],
|
|
8034
|
-
* model: "fireworks/accounts/fireworks/models/kimi-k2p5",
|
|
8035
|
-
* tools,
|
|
8036
|
-
* },
|
|
8037
|
-
* headers: { Authorization: `Bearer ${identityToken}` },
|
|
8038
|
-
* });
|
|
8039
|
-
* ```
|
|
8040
|
-
*/
|
|
8041
|
-
declare function selectServerSideTools(options: SelectServerSideToolsOptions): Promise<Array<Record<string, unknown>>>;
|
|
8042
|
-
|
|
8043
|
-
/**
|
|
8044
|
-
* Connector tool catalog + denied-tools system-prompt rider.
|
|
8045
|
-
*
|
|
8046
|
-
* Granular connector access works by ALLOW/DENY-ing individual SDK tools.
|
|
8047
|
-
* Denying a tool means it's never handed to the model that turn, so it
|
|
8048
|
-
* physically can't be called — bypass-proof at the model layer.
|
|
8049
|
-
*
|
|
8050
|
-
* Consumer contract (this PR ships the foundation only — it does NOT wire
|
|
8051
|
-
* anything into runtime filtering or the client; those are later phases):
|
|
8052
|
-
*
|
|
8053
|
-
* 1. Hide the denied tools from the model — pass the denied tool names as
|
|
8054
|
-
* `createServerToolsFilter({ excludeTools })` so they're dropped from the
|
|
8055
|
-
* toolset before it reaches the LLM.
|
|
8056
|
-
* 2. Tell the user how to re-enable — append `buildDeniedToolsRider(denied)`
|
|
8057
|
-
* to the system prompt. Because the tool is absent, the model can't name
|
|
8058
|
-
* it on its own and would give a generic "I don't have access". The rider
|
|
8059
|
-
* gives it the specific capability names (grouped by connector) so it can
|
|
8060
|
-
* tell the user to re-enable that exact tool in Connected Apps settings.
|
|
8061
|
-
*
|
|
8062
|
-
* `TOOL_CATALOG` is the single source of truth for connector tool → friendly
|
|
8063
|
-
* label + provider. `provider` is the canonical logical-provider identifier the
|
|
8064
|
-
* portal and SDK already key on (matches `internal/oauth/providers.go` and the
|
|
8065
|
-
* `createConnectorTokenGetter` call sites) — Phase 2/3 use it to group and
|
|
8066
|
-
* persist per-tool denial. `connector` is the human-facing UI display string.
|
|
8067
|
-
* Consumers (portal, client) read this on a version bump rather than re-encoding
|
|
8068
|
-
* tool names. Labels are placeholders that will be refined later — keep them
|
|
8069
|
-
* sensible.
|
|
8070
|
-
*/
|
|
8071
|
-
|
|
8072
|
-
interface ToolCatalogEntry {
|
|
8073
|
-
label: string;
|
|
8074
|
-
/** Canonical logical-provider id (e.g. "gmail", "gcalendar", "gdrive"). */
|
|
8075
|
-
provider: string;
|
|
8076
|
-
/** Human-facing connector display name (UI label). */
|
|
8077
|
-
connector: string;
|
|
8078
|
-
}
|
|
8079
|
-
declare const TOOL_CATALOG: Record<string, ToolCatalogEntry>;
|
|
8080
|
-
/**
|
|
8081
|
-
* Build a system-prompt fragment telling the model which connector capabilities
|
|
8082
|
-
* the user has turned off, so it can give the specific "re-enable this tool"
|
|
8083
|
-
* message instead of a generic refusal.
|
|
8084
|
-
*
|
|
8085
|
-
* Unknown names (not in {@link TOOL_CATALOG}) are skipped. Returns `""` when the
|
|
8086
|
-
* input is empty or every name is unknown — callers append the result
|
|
8087
|
-
* conditionally, so an empty string is a no-op.
|
|
8088
|
-
*/
|
|
8089
|
-
declare function buildDeniedToolsRider(deniedToolNames: Iterable<string>): string;
|
|
8090
|
-
interface ConnectorGuidanceInput {
|
|
8091
|
-
/** The candidate tools for this turn (the final assembled set). */
|
|
8092
|
-
tools: ToolConfig[];
|
|
8093
|
-
/**
|
|
8094
|
-
* Logical provider codes connected for the user — the same codes used as
|
|
8095
|
-
* {@link TOOL_CATALOG} `provider` values (e.g. "gmail", "gcalendar",
|
|
8096
|
-
* "gdrive", "notion", "github", "dropbox").
|
|
8097
|
-
*/
|
|
8098
|
-
connectedProviders: string[];
|
|
8099
|
-
/** Exact SDK tool-name strings the user turned off ({@link TOOL_CATALOG} keys). */
|
|
8100
|
-
deniedToolNames: string[];
|
|
8101
|
-
}
|
|
8102
|
-
interface ConnectorGuidance {
|
|
8103
|
-
/** `input.tools` with any denied tool removed (the helper owns filtering). */
|
|
8104
|
-
tools: ToolConfig[];
|
|
8105
|
-
/** Compact system-prompt block, or "" when there's nothing actionable. */
|
|
8106
|
-
rider: string;
|
|
8107
|
-
}
|
|
8108
|
-
/**
|
|
8109
|
-
* Single helper both web and mobile use so neither re-implements connector
|
|
8110
|
-
* tool filtering or the accuracy messaging. It enforces denial (drops denied
|
|
8111
|
-
* tools from the turn's toolset) AND builds a compact rider letting the model
|
|
8112
|
-
* give an accurate message for each connector state instead of a generic
|
|
8113
|
-
* "I don't have access":
|
|
8114
|
-
*
|
|
8115
|
-
* 1. Toggled off — connected provider whose tool is denied → "turned off,
|
|
8116
|
-
* re-enable in Connected Apps".
|
|
8117
|
-
* 2a. Pruned / 2b. no tool — covered by a general line telling the model not to
|
|
8118
|
-
* claim no-access for a connected app. It rides along only when another
|
|
8119
|
-
* section is present (on its own it isn't actionable).
|
|
8120
|
-
* 3. Not connected — catalog provider absent from `connectedProviders` →
|
|
8121
|
-
* "connect it in Connected Apps".
|
|
8122
|
-
*
|
|
8123
|
-
* State 3 is derived from {@link TOOL_CATALOG}'s provider set — providers with
|
|
8124
|
-
* no tools (e.g. Disconnect-only Dropbox) aren't actionable via tools, so they
|
|
8125
|
-
* aren't surfaced here. Everything is sorted alphabetically for deterministic
|
|
8126
|
-
* output (no cache / snapshot churn). `rider` is "" when nothing is actionable
|
|
8127
|
-
* (every catalog provider connected and nothing denied).
|
|
8128
|
-
*/
|
|
8129
|
-
declare function buildConnectorGuidance(input: ConnectorGuidanceInput): ConnectorGuidance;
|
|
8130
|
-
|
|
8131
|
-
/**
|
|
8132
|
-
* Idle-keepalive wrapper for SSE streams produced by the generated
|
|
8133
|
-
* SSE client in `src/client/core/serverSentEvents.gen.ts`.
|
|
8134
|
-
*
|
|
8135
|
-
* The generated SSE client does not enforce an idle timeout, so if the
|
|
8136
|
-
* upstream server dies without sending `FIN`, a consumer can sit forever
|
|
8137
|
-
* on a half-open socket. This wrapper:
|
|
8138
|
-
*
|
|
8139
|
-
* - Tracks the timestamp of the last event yielded by the source.
|
|
8140
|
-
* - Starts an idle timer (default 60s, configurable via `idleMs`).
|
|
8141
|
-
* - Resets the timer on every event.
|
|
8142
|
-
* - Invokes `onIdle()` if the timer fires, and then closes the stream
|
|
8143
|
-
* by throwing a typed {@link SseIdleTimeoutError} out of the iterator.
|
|
8144
|
-
*
|
|
8145
|
-
* This file lives outside `src/client/` on purpose: `@hey-api/openapi-ts`
|
|
8146
|
-
* wipes its output directory on every regeneration, so anything inside
|
|
8147
|
-
* `src/client/` would be clobbered by `pnpm run generate`.
|
|
8148
|
-
*/
|
|
8149
|
-
/**
|
|
8150
|
-
* Options accepted by {@link withSseKeepalive}.
|
|
8151
|
-
*/
|
|
8152
|
-
interface SseKeepaliveOptions {
|
|
8153
|
-
/**
|
|
8154
|
-
* Idle window, in milliseconds. If no event is yielded by the source for
|
|
8155
|
-
* this long, the stream is considered dead and is torn down.
|
|
8156
|
-
*
|
|
8157
|
-
* Set to `0` or a negative number to disable the idle timer (in which
|
|
8158
|
-
* case the wrapper is a straight passthrough).
|
|
8159
|
-
*
|
|
8160
|
-
* @default 60000
|
|
8161
|
-
*/
|
|
8162
|
-
idleMs?: number;
|
|
8163
|
-
/**
|
|
8164
|
-
* Invoked when the idle timer fires. The callback runs before the
|
|
8165
|
-
* wrapper closes the stream, so consumers can log, emit metrics, or
|
|
8166
|
-
* attempt reconnects from here.
|
|
8167
|
-
*
|
|
8168
|
-
* The callback is best-effort — thrown errors are swallowed so they do
|
|
8169
|
-
* not mask the {@link SseIdleTimeoutError} that follows.
|
|
8170
|
-
*/
|
|
8171
|
-
onIdle?: (info: {
|
|
8172
|
-
idleMs: number;
|
|
8173
|
-
lastEventAt: number;
|
|
8174
|
-
}) => void;
|
|
8175
|
-
}
|
|
8176
|
-
/**
|
|
8177
|
-
* Thrown by {@link withSseKeepalive} when no event arrives within the
|
|
8178
|
-
* configured idle window. Callers can `instanceof`-check this to
|
|
8179
|
-
* distinguish idle timeouts from other stream errors.
|
|
8180
|
-
*/
|
|
8181
|
-
declare class SseIdleTimeoutError extends Error {
|
|
8182
|
-
readonly idleMs: number;
|
|
8183
|
-
readonly lastEventAt: number;
|
|
8184
|
-
constructor(idleMs: number, lastEventAt: number);
|
|
8185
|
-
}
|
|
8186
|
-
/**
|
|
8187
|
-
* Wrap an SSE-style async iterable with an idle timeout. If no value is
|
|
8188
|
-
* yielded by `source` within `idleMs`, `onIdle` fires and the wrapper
|
|
8189
|
-
* throws {@link SseIdleTimeoutError}, which propagates to the consumer's
|
|
8190
|
-
* `for await` loop and, via the iterator protocol, calls `source.return()`
|
|
8191
|
-
* so the underlying fetch/reader is cancelled.
|
|
8192
|
-
*
|
|
8193
|
-
* Typical usage with the generated SSE client:
|
|
8194
|
-
*
|
|
8195
|
-
* ```ts
|
|
8196
|
-
* import { createSseClient } from "@anuma/sdk/client/core/serverSentEvents.gen";
|
|
8197
|
-
* import { withSseKeepalive } from "@anuma/sdk";
|
|
8198
|
-
*
|
|
8199
|
-
* const { stream } = createSseClient({ url });
|
|
8200
|
-
* for await (const event of withSseKeepalive(stream, {
|
|
8201
|
-
* idleMs: 60_000,
|
|
8202
|
-
* onIdle: ({ idleMs }) => logger.warn(`SSE idle for ${idleMs}ms`),
|
|
8203
|
-
* })) {
|
|
8204
|
-
* // ...
|
|
8205
|
-
* }
|
|
8206
|
-
* ```
|
|
8207
|
-
*
|
|
8208
|
-
* The wrapper is a pure passthrough when `idleMs <= 0`.
|
|
8209
|
-
*/
|
|
8210
|
-
declare function withSseKeepalive<T>(source: AsyncIterable<T>, options?: SseKeepaliveOptions): AsyncGenerator<T, void, unknown>;
|
|
8211
|
-
|
|
8212
|
-
/**
|
|
8213
|
-
* Cross-platform primitive constants.
|
|
8214
|
-
*
|
|
8215
|
-
* This module is intentionally dependency-free and side-effect-free so it can
|
|
8216
|
-
* be loaded by *any* consumer — including React Native / Hermes — without
|
|
8217
|
-
* pulling in the rest of the SDK. It is published as the `@anuma/sdk/constants`
|
|
8218
|
-
* subpath (which carries a `react-native` export condition); slim consumers
|
|
8219
|
-
* such as the agent packages import values from here instead of the bare
|
|
8220
|
-
* `@anuma/sdk` entry, whose Node/web bundle is not RN-safe.
|
|
8221
|
-
*
|
|
8222
|
-
* Only add genuinely pure, cross-platform constants here (numeric/string
|
|
8223
|
-
* literals, default IDs, size caps). No classes, no runtime APIs, no imports.
|
|
8224
|
-
*/
|
|
8225
|
-
/** Character cap for multiline / textarea fields. Agent gateways (e.g. cf-tasks)
|
|
8226
|
-
* truncate values to this length before interpolating them into prompt templates.
|
|
8227
|
-
* Shared across all agent packages so a single change updates every journey
|
|
8228
|
-
* declaration simultaneously. */
|
|
8229
|
-
declare const MULTILINE_FIELD_MAX = 50000;
|
|
8230
|
-
|
|
8231
|
-
/** Runtime environment where the agent can execute. */
|
|
8232
|
-
type AgentRuntime = "client" | "server";
|
|
8233
|
-
/** Strategy a consumer should use to extract text from an uploaded file before
|
|
8234
|
-
* feeding it into a skill journey field. The SDK only labels the strategy —
|
|
8235
|
-
* the actual extraction (pdf.js, OCR, etc.) is the consumer's responsibility. */
|
|
8236
|
-
type FileExtractionStrategy = "pdf-text" | "csv-text" | "image-ocr";
|
|
8237
|
-
|
|
8238
|
-
/** Configuration for a single agent skill (task template). */
|
|
8239
|
-
interface SkillConfig {
|
|
8240
|
-
/** Unique identifier. Convention: "domain.action" e.g. "housing.lease-review" */
|
|
8241
|
-
id: string;
|
|
8242
|
-
/** Human-readable name. */
|
|
8243
|
-
name: string;
|
|
8244
|
-
/** System prompt template with {{variable}} placeholders. */
|
|
8245
|
-
promptTemplate: string;
|
|
8246
|
-
/**
|
|
8247
|
-
* User-turn template, interpolated with the same {{variable}} placeholders
|
|
8248
|
-
* as `promptTemplate`. Optional, but strongly recommended for skill-driven
|
|
8249
|
-
* (non-freeform) flows so the model receives a proper user turn — most
|
|
8250
|
-
* Anthropic models reject requests that contain only a system message.
|
|
8251
|
-
*/
|
|
8252
|
-
userTemplate?: string;
|
|
8253
|
-
/** MCP tool names this skill requires. */
|
|
8254
|
-
requiredTools?: string[];
|
|
8255
|
-
/** Preferred model when the caller doesn't specify one. */
|
|
8256
|
-
preferredModel?: string;
|
|
8257
|
-
/** Max agentic loop steps for this skill. */
|
|
8258
|
-
maxSteps?: number;
|
|
8259
|
-
/** Variables the promptTemplate expects at runtime. */
|
|
8260
|
-
requiredVariables?: string[];
|
|
8261
|
-
/**
|
|
8262
|
-
* SMS-friendly question prompts keyed by variable name. The Anuma text
|
|
8263
|
-
* gateway sends each prompt to the user one at a time and treats the
|
|
8264
|
-
* user's reply as the slot value. Missing entries fall back to a
|
|
8265
|
-
* generic "Please provide {name}." question in the gateway.
|
|
8266
|
-
*
|
|
8267
|
-
* Order of questions follows requiredVariables[] order.
|
|
8268
|
-
*/
|
|
8269
|
-
smsPrompts?: Record<string, string>;
|
|
8270
|
-
/** Additional context appended after the prompt template. */
|
|
8271
|
-
contextSuffix?: string;
|
|
8272
|
-
/** Lucide icon identifier (e.g. "FileSearch") for renderers that draw a skill icon. */
|
|
8273
|
-
iconName?: string;
|
|
8274
|
-
/** One-line announcement string shown when the skill is launched (channel-neutral). */
|
|
8275
|
-
launchMessage?: string;
|
|
8276
|
-
/** Conversational preamble shown after the user picks this skill, before the field
|
|
8277
|
-
* questions begin. Used by chat-native guided flows (web, mobile, SMS, voice). */
|
|
8278
|
-
preamble?: string;
|
|
8279
|
-
/** Closing line shown after the user finishes the last field and before the agent
|
|
8280
|
-
* starts the tool loop. Used by chat-native guided flows. */
|
|
8281
|
-
closing?: string;
|
|
8282
|
-
/** Fallback nudge for any required field on this skill that doesn't define its own
|
|
8283
|
-
* `requiredNudge` string. */
|
|
8284
|
-
requiredNudgeDefault?: string;
|
|
8285
|
-
}
|
|
8286
|
-
/** Public-safe manifest describing an agent (no prompt or tool details). */
|
|
8287
|
-
interface AgentManifest {
|
|
8288
|
-
id: string;
|
|
8289
|
-
name: string;
|
|
8290
|
-
description: string;
|
|
8291
|
-
runtimes: AgentRuntime[];
|
|
8292
|
-
skills: Array<{
|
|
8293
|
-
id: string;
|
|
8294
|
-
name: string;
|
|
8295
|
-
requiredVariables?: string[];
|
|
8296
|
-
smsPrompts?: Record<string, string>;
|
|
8297
|
-
}>;
|
|
8298
|
-
}
|
|
8299
|
-
/** Allowed input types for skill journey form fields. */
|
|
8300
|
-
type SkillJourneyFieldType = "text" | "textarea" | "select";
|
|
8301
|
-
/** Properties shared by every skill journey field, regardless of input type. */
|
|
8302
|
-
interface SkillJourneyFieldBase {
|
|
8303
|
-
key: string;
|
|
8304
|
-
label: string;
|
|
8305
|
-
placeholder: string;
|
|
8306
|
-
helper?: string;
|
|
8307
|
-
required?: boolean;
|
|
8308
|
-
/** Conversational ask used by chat-native guided flows (web, mobile, SMS, voice).
|
|
8309
|
-
* Falls through to `label` when not set. */
|
|
8310
|
-
chatPrompt?: string;
|
|
8311
|
-
/** Skill-specific nudge shown when the user skips a required field. Falls through
|
|
8312
|
-
* to `SkillConfig.requiredNudgeDefault` when not set. */
|
|
8313
|
-
requiredNudge?: string;
|
|
8314
|
-
/** Server-side sanitiser cap on the value's character length. Today's gateways
|
|
8315
|
-
* truncate textarea fields at `MULTILINE_FIELD_MAX` characters. */
|
|
8316
|
-
maxLength?: number;
|
|
8317
|
-
}
|
|
8318
|
-
/**
|
|
8319
|
-
* A single field in a skill journey intake form. Discriminated on `type`:
|
|
8320
|
-
* `select` requires `options`; `text` / `textarea` cannot carry options.
|
|
8321
|
-
*/
|
|
8322
|
-
type SkillJourneyField = (SkillJourneyFieldBase & {
|
|
8323
|
-
type: "text" | "textarea";
|
|
8324
|
-
}) | (SkillJourneyFieldBase & {
|
|
8325
|
-
type: "select";
|
|
8326
|
-
options: string[];
|
|
8327
|
-
});
|
|
8328
|
-
/** Full definition for rendering a skill intake form and building the prompt. */
|
|
8329
|
-
interface SkillJourneyDefinition {
|
|
8330
|
-
title: string;
|
|
8331
|
-
description: string;
|
|
8332
|
-
steps: string[];
|
|
8333
|
-
/** When true, the journey renders a file upload step before the fields. */
|
|
8334
|
-
acceptsFiles: boolean;
|
|
8335
|
-
/** Label for the file upload step. Only meaningful when `acceptsFiles` is true. */
|
|
8336
|
-
fileLabel?: string;
|
|
8337
|
-
/** Helper text for the file upload step. Only meaningful when `acceptsFiles` is true. */
|
|
8338
|
-
fileHint?: string;
|
|
8339
|
-
/** Per-skill copy for the file upload step prompt. Only meaningful when `acceptsFiles` is true. */
|
|
8340
|
-
filePrompt?: string;
|
|
8341
|
-
/** How consumers should derive text from an attached file. Describes extraction
|
|
8342
|
-
* only — it is **not** a file-type filter. Files outside the strategy's expected
|
|
8343
|
-
* MIME type (e.g. photos when the strategy is `pdf-text`) are still uploaded and
|
|
8344
|
-
* forwarded to the agent as attachments; they are simply not text-extracted.
|
|
8345
|
-
* The extracted text is written to the variable named by `extractedTextTarget`.
|
|
8346
|
-
* Only meaningful when `acceptsFiles` is true. */
|
|
8347
|
-
fileExtractionStrategy?: FileExtractionStrategy;
|
|
8348
|
-
/** Variable name to write extracted text into. May coincide with a field's `key`
|
|
8349
|
-
* (the upload replaces typed input for that field, e.g. `lease_text`) or name a
|
|
8350
|
-
* separate template variable not tied to any field (e.g. `rent_notice_text`,
|
|
8351
|
-
* `supporting_document_text`). Only meaningful when `acceptsFiles` is true and
|
|
8352
|
-
* `fileExtractionStrategy` is set. */
|
|
8353
|
-
extractedTextTarget?: string;
|
|
8354
|
-
fields: SkillJourneyField[];
|
|
8355
|
-
/**
|
|
8356
|
-
* When true, the journey expects substantive input — at least one of an
|
|
8357
|
-
* `acceptsFiles` upload or a text/textarea field — for the agent to act on.
|
|
8358
|
-
* Consumers (form renderers and direct API callers alike) should enforce
|
|
8359
|
-
* "file or text provided" before invoking the skill.
|
|
8360
|
-
*/
|
|
8361
|
-
requiresContext: boolean;
|
|
8362
|
-
submitLabel: string;
|
|
8363
|
-
promptTitle: string;
|
|
8364
|
-
/** Extra system prompt context injected per-skill for structured output guidance. */
|
|
8365
|
-
systemContext?: string;
|
|
8366
|
-
}
|
|
8367
|
-
/** Marketplace filter the agent should appear under in the picker UI. */
|
|
8368
|
-
type AgentMarketplaceFamily = "text" | "lifestyle";
|
|
8369
|
-
/** What kind of action the marketplace card's primary CTA performs. */
|
|
8370
|
-
type AgentPrimaryActionKind = "text" | "group" | "guided";
|
|
8371
|
-
/** Visual tone for a transcript section heading. */
|
|
8372
|
-
type AgentTranscriptTone = "danger" | "warning" | "success";
|
|
8373
|
-
/** A single bullet inside a marketplace analysis transcript section. */
|
|
8374
|
-
interface AgentTranscriptItem {
|
|
8375
|
-
title: string;
|
|
8376
|
-
detail: string;
|
|
8377
|
-
}
|
|
8378
|
-
/** A grouped block of bullets in a marketplace analysis transcript. */
|
|
8379
|
-
interface AgentAnalysisSection {
|
|
8380
|
-
title: string;
|
|
8381
|
-
tone: AgentTranscriptTone;
|
|
8382
|
-
items: AgentTranscriptItem[];
|
|
8383
|
-
}
|
|
8384
|
-
/** A todo entry inside a marketplace agenda transcript. */
|
|
8385
|
-
interface AgentAgendaItem {
|
|
8386
|
-
title: string;
|
|
8387
|
-
badge?: string;
|
|
8388
|
-
badgeTone?: "warning" | "danger";
|
|
8389
|
-
}
|
|
8390
|
-
/** A schedule entry inside a marketplace agenda transcript. */
|
|
8391
|
-
interface AgentScheduleItem {
|
|
8392
|
-
title: string;
|
|
8393
|
-
time: string;
|
|
8394
|
-
}
|
|
8395
|
-
/** Marketplace transcript shape for productivity / agenda style agents. */
|
|
8396
|
-
interface AgentAgendaTranscript {
|
|
8397
|
-
kind: "agenda";
|
|
8398
|
-
userMessage: string;
|
|
8399
|
-
intro: string;
|
|
8400
|
-
todos: AgentAgendaItem[];
|
|
8401
|
-
schedule: AgentScheduleItem[];
|
|
8402
|
-
followUp: string;
|
|
8403
|
-
actions: string[];
|
|
8404
|
-
}
|
|
8405
|
-
/** Marketplace transcript shape for analysis / dispute style agents. */
|
|
8406
|
-
interface AgentAnalysisTranscript {
|
|
8407
|
-
kind: "analysis";
|
|
8408
|
-
userMessage: string;
|
|
8409
|
-
intro: string;
|
|
8410
|
-
sections: AgentAnalysisSection[];
|
|
8411
|
-
followUp: string;
|
|
8412
|
-
actions: string[];
|
|
8413
|
-
}
|
|
8414
|
-
/** A scripted marketplace conversation preview, discriminated on `kind`. */
|
|
8415
|
-
type AgentMarketplaceTranscript = AgentAgendaTranscript | AgentAnalysisTranscript;
|
|
8416
|
-
/** Marketplace card content for an agent — the data the picker UI renders. */
|
|
8417
|
-
interface AgentMarketplaceContent {
|
|
8418
|
-
family: AgentMarketplaceFamily;
|
|
8419
|
-
roleLabel: string;
|
|
8420
|
-
primaryActionLabel: string;
|
|
8421
|
-
primaryActionKind: AgentPrimaryActionKind;
|
|
8422
|
-
cardUseCases: string[];
|
|
8423
|
-
cardKnowledge: string[];
|
|
8424
|
-
quickPrompts: string[];
|
|
8425
|
-
emptyStateDescription: string;
|
|
8426
|
-
transcript: AgentMarketplaceTranscript;
|
|
8427
|
-
}
|
|
8428
|
-
/** A single (user, agent) example conversation entry, keyed by i18n string ids. */
|
|
8429
|
-
interface AgentExampleConversation {
|
|
8430
|
-
userKey: string;
|
|
8431
|
-
agentKey: string;
|
|
8432
|
-
}
|
|
8433
|
-
/** UI metadata used by clients when the portal doesn't supply richer data. */
|
|
8434
|
-
interface AgentUiMetadata {
|
|
8435
|
-
/** Hex color used by the agent card and accents. */
|
|
8436
|
-
color: string;
|
|
8437
|
-
/** Lucide icon identifier (e.g. "users"). */
|
|
8438
|
-
icon: string;
|
|
8439
|
-
/** i18n keys for the per-agent feature bullets. */
|
|
8440
|
-
features: string[];
|
|
8441
|
-
/** i18n keys for the example conversation strings. */
|
|
8442
|
-
exampleConversations: AgentExampleConversation[];
|
|
8443
|
-
/** Memory folder names this agent typically uses. */
|
|
8444
|
-
suggestedMemoryFolders?: string[];
|
|
8445
|
-
}
|
|
8446
|
-
/** Full agent configuration including prompt, skills, tools, and model settings. */
|
|
8447
|
-
interface AgentConfig {
|
|
8448
|
-
id: string;
|
|
8449
|
-
runtimes: AgentRuntime[];
|
|
8450
|
-
prompt: string;
|
|
8451
|
-
skills: SkillConfig[];
|
|
8452
|
-
/** Tool configs are agent-specific, so we keep this generic. */
|
|
8453
|
-
tools: unknown[];
|
|
8454
|
-
model: {
|
|
8455
|
-
default: string;
|
|
8456
|
-
allowed?: string[];
|
|
8457
|
-
};
|
|
8458
|
-
manifest: AgentManifest;
|
|
8459
|
-
/** Form schemas for rendering skill intake forms on the client. */
|
|
8460
|
-
skillJourneys?: Record<string, SkillJourneyDefinition>;
|
|
8461
|
-
/** First assistant message shown when the agent is opened. Supports the
|
|
8462
|
-
* `{{agent_name}}` placeholder so consumers can substitute the portal-display
|
|
8463
|
-
* name without changing this string. */
|
|
8464
|
-
greeting?: string;
|
|
8465
|
-
/** Sub-copy shown under the agent picker / guided-flow header. Supports the
|
|
8466
|
-
* `{{agent_name}}` placeholder, same as `greeting`. */
|
|
8467
|
-
guidedFlowSubcopy?: string;
|
|
8468
|
-
/** Marketplace card content rendered in the agent picker. */
|
|
8469
|
-
marketplace?: AgentMarketplaceContent;
|
|
8470
|
-
/** UI metadata (color, icon, example conversations) for renderer fallbacks. */
|
|
8471
|
-
uiMetadata?: AgentUiMetadata;
|
|
8472
|
-
/** One-time disclaimer shown in a popup the first time a user opens
|
|
8473
|
-
* a chat with this agent. Plain text; consumers split on `\n\n` for paragraphs.
|
|
8474
|
-
* May include `{{agent_name}}` placeholder. */
|
|
8475
|
-
firstTimeDisclaimer?: string;
|
|
8476
|
-
/** Persistent one-line disclaimer rendered under the chat input
|
|
8477
|
-
* whenever this agent's chat is open. May include `{{agent_name}}`
|
|
8478
|
-
* placeholder. */
|
|
8479
|
-
persistentFooter?: string;
|
|
8480
|
-
}
|
|
8481
|
-
|
|
8482
|
-
/**
|
|
8483
|
-
* Pluggable logger for the Anuma SDK.
|
|
8484
|
-
*
|
|
8485
|
-
* By default all SDK logging goes to `console`. Call {@link setLogger} at app
|
|
8486
|
-
* init (or use `<LoggerProvider>` in React) to redirect output to your own
|
|
8487
|
-
* logging infrastructure (PostHog, Datadog, Sentry, etc.).
|
|
8488
|
-
*
|
|
8489
|
-
* @example
|
|
8490
|
-
* ```ts
|
|
8491
|
-
* import { setLogger, type Logger } from "@anuma/sdk";
|
|
8492
|
-
*
|
|
8493
|
-
* const myLogger: Logger = {
|
|
8494
|
-
* debug: () => {},
|
|
8495
|
-
* info: (...args) => posthog.capture("sdk_info", { message: args }),
|
|
8496
|
-
* warn: (...args) => console.warn("[SDK]", ...args),
|
|
8497
|
-
* error: (...args) => Sentry.captureMessage(args.join(" ")),
|
|
8498
|
-
* };
|
|
8499
|
-
*
|
|
8500
|
-
* setLogger(myLogger);
|
|
8501
|
-
* ```
|
|
8502
|
-
*/
|
|
8503
|
-
interface Logger {
|
|
8504
|
-
debug: (...args: unknown[]) => void;
|
|
8505
|
-
/** Used for outcomes that are noteworthy but expected — a consolidation
|
|
8506
|
-
* refusal that preserved a memory, for example. Keep genuinely-wrong things at
|
|
8507
|
-
* `warn` so the two stay distinguishable in a log search. */
|
|
8508
|
-
info: (...args: unknown[]) => void;
|
|
8509
|
-
warn: (...args: unknown[]) => void;
|
|
8510
|
-
error: (...args: unknown[]) => void;
|
|
8511
|
-
}
|
|
8512
|
-
/** Default logger that delegates to the global `console` object. */
|
|
8513
|
-
declare const consoleLogger: Logger;
|
|
8514
|
-
/** Silent logger that discards all output. */
|
|
8515
|
-
declare const noopLogger: Logger;
|
|
8516
|
-
/** Replace the active SDK logger. Pass {@link consoleLogger} to restore defaults. */
|
|
8517
|
-
declare function setLogger(logger: Logger): void;
|
|
8518
|
-
/** Return the active SDK logger. */
|
|
8519
|
-
declare function getLogger(): Logger;
|
|
8520
|
-
|
|
8521
|
-
/** A single section in the system prompt. */
|
|
8522
|
-
interface PromptSection {
|
|
8523
|
-
/** Unique identifier (used for disabling/overriding). */
|
|
8524
|
-
key: string;
|
|
8525
|
-
/** Lower priority = earlier in the prompt. Sections sort ascending. */
|
|
8526
|
-
priority: number;
|
|
8527
|
-
/** Return text to append, or null to skip this section. */
|
|
8528
|
-
render: (ctx: PromptContext) => string | null;
|
|
8529
|
-
}
|
|
8530
|
-
/** Context passed to every section renderer. */
|
|
8531
|
-
interface PromptContext {
|
|
8532
|
-
/** Base personality prompt (from PersonaConfig.prompt). */
|
|
8533
|
-
basePrompt: string;
|
|
8534
|
-
/** User-set "act as X" communication preference. */
|
|
8535
|
-
persona?: string | null;
|
|
8536
|
-
/** Analyzed user communication style profile. */
|
|
8537
|
-
styleProfile?: string | null;
|
|
8538
|
-
/** Detected user sentiment. */
|
|
8539
|
-
sentiment?: "frustrated" | "positive" | "neutral" | null;
|
|
8540
|
-
/** ISO 639-1 language code, 'other', or null for English/undetected. */
|
|
8541
|
-
preferredLanguage?: string | null;
|
|
8542
|
-
/** Platform-specific formatting instructions from PersonaConfig. */
|
|
8543
|
-
platformFormatting?: string | null;
|
|
8544
|
-
/** Available tools. */
|
|
8545
|
-
toolSummaries?: Array<{
|
|
8546
|
-
name: string;
|
|
8547
|
-
description: string;
|
|
8548
|
-
}>;
|
|
8549
|
-
/** Consumer-specific data for custom sections. */
|
|
8550
|
-
extra?: Record<string, unknown>;
|
|
8551
|
-
}
|
|
8552
|
-
/** Configurable template strings for built-in section renderers. */
|
|
8553
|
-
interface PromptTemplates {
|
|
8554
|
-
tools: string;
|
|
8555
|
-
persona: string;
|
|
8556
|
-
style: string;
|
|
8557
|
-
sentiment: {
|
|
8558
|
-
frustrated: string;
|
|
8559
|
-
positive: string;
|
|
8560
|
-
};
|
|
8561
|
-
language: string;
|
|
8562
|
-
languageGeneric: string;
|
|
8563
|
-
platformFormatting: string;
|
|
8564
|
-
}
|
|
8565
|
-
/** Options for buildSystemPrompt(). */
|
|
8566
|
-
interface BuildPromptOptions {
|
|
8567
|
-
/** Additional sections appended to defaults. */
|
|
8568
|
-
extraSections?: PromptSection[];
|
|
8569
|
-
/** Section keys to skip. */
|
|
8570
|
-
disabled?: string[];
|
|
8571
|
-
/** Max total prompt length in characters. 0 = unlimited. */
|
|
8572
|
-
maxLength?: number;
|
|
8573
|
-
/** Override default template strings. */
|
|
8574
|
-
templates?: Partial<PromptTemplates>;
|
|
8575
|
-
}
|
|
8576
|
-
/** Result of buildSystemPrompt(). */
|
|
8577
|
-
interface BuildPromptResult {
|
|
8578
|
-
/** The assembled prompt string. */
|
|
8579
|
-
prompt: string;
|
|
8580
|
-
/** Keys of sections that rendered (in order). */
|
|
8581
|
-
activeSections: string[];
|
|
8582
|
-
}
|
|
8583
|
-
/** Options for analyzeStyle(). */
|
|
8584
|
-
interface AnalyzeStyleOptions {
|
|
8585
|
-
/** Recent conversation messages. */
|
|
8586
|
-
messages: Array<{
|
|
8587
|
-
role: string;
|
|
8588
|
-
content: string;
|
|
8589
|
-
}>;
|
|
8590
|
-
/** Callback to send messages to an LLM and get a text response. */
|
|
8591
|
-
callLlm: (messages: Array<{
|
|
8592
|
-
role: string;
|
|
8593
|
-
content: string;
|
|
8594
|
-
}>) => Promise<string | null>;
|
|
8595
|
-
/** Max user messages to consider (default: 10). */
|
|
8596
|
-
maxInputMessages?: number;
|
|
8597
|
-
/** Minimum user messages required (default: 3). */
|
|
8598
|
-
minMessages?: number;
|
|
8599
|
-
/** Max profile length in characters (default: 200). */
|
|
8600
|
-
maxProfileLength?: number;
|
|
8601
|
-
/** Custom system prompt for the analysis model. */
|
|
8602
|
-
analysisPrompt?: string;
|
|
8603
|
-
/** Regex to filter out document-embedded messages. */
|
|
8604
|
-
documentPattern?: RegExp;
|
|
8605
|
-
}
|
|
8606
|
-
/** Result of analyzeStyle(). */
|
|
8607
|
-
interface AnalyzeStyleResult {
|
|
8608
|
-
/** The style profile string, or null if skipped/failed. */
|
|
8609
|
-
profile: string | null;
|
|
8610
|
-
}
|
|
8611
|
-
/** Input for shouldAnalyzeStyle(). */
|
|
8612
|
-
interface StyleAnalysisSchedule {
|
|
8613
|
-
/** Current message count for the user. */
|
|
8614
|
-
messageCount: number;
|
|
8615
|
-
/** Whether the user already has a style profile. */
|
|
8616
|
-
hasProfile: boolean;
|
|
8617
|
-
/** Whether analysis has ever run (updatedAt timestamp is set). */
|
|
8618
|
-
hasBeenAnalyzed: boolean;
|
|
8619
|
-
/** Whether the user opted out (updatedAt set but profile is null). */
|
|
8620
|
-
optedOut: boolean;
|
|
8621
|
-
/** Trigger analysis after this many messages (default: 5). */
|
|
8622
|
-
analyzeAfterMessages?: number;
|
|
8623
|
-
/** Re-analyze every N messages (default: 20). */
|
|
8624
|
-
refreshEveryMessages?: number;
|
|
8301
|
+
declare const DEFAULT_SERVER_TOOLS_MATCH_OPTIONS: ToolMatchOptions;
|
|
8302
|
+
/**
|
|
8303
|
+
* Pre-configured server-tools filter ready to drop into `useChatStorage`'s
|
|
8304
|
+
* `serverTools` option. Semantic matching against the user prompt with the
|
|
8305
|
+
* default exclusion list applied, plus call-chain expansion via
|
|
8306
|
+
* {@link SERVER_TOOL_DEPENDENCY_SETS} so continuation tools (read-after-search,
|
|
8307
|
+
* geocode-before-weather) ride in with their entry tool.
|
|
8308
|
+
*
|
|
8309
|
+
* @example
|
|
8310
|
+
* ```ts
|
|
8311
|
+
* import { defaultServerToolsFilter, useChatStorage } from "@anuma/sdk/react";
|
|
8312
|
+
*
|
|
8313
|
+
* useChatStorage({
|
|
8314
|
+
* ...,
|
|
8315
|
+
* serverTools: defaultServerToolsFilter,
|
|
8316
|
+
* });
|
|
8317
|
+
* ```
|
|
8318
|
+
*
|
|
8319
|
+
* If you need to customize (extra excludes, different limits, opt into
|
|
8320
|
+
* tool-set expansion), call `createServerToolsFilter` directly.
|
|
8321
|
+
*/
|
|
8322
|
+
declare const defaultServerToolsFilter: ServerToolsFilterFunction;
|
|
8323
|
+
/**
|
|
8324
|
+
* Type for a server-tools filter — a function that takes prompt embeddings
|
|
8325
|
+
* and the full server tool catalog and returns the names of tools to keep.
|
|
8326
|
+
* Matches `useChatStorage`'s `serverTools` callback signature.
|
|
8327
|
+
*/
|
|
8328
|
+
type ServerToolsFilterFunction = ((embeddings: number[] | number[][], tools: ServerTool[]) => string[]) & {
|
|
8329
|
+
/**
|
|
8330
|
+
* The unconditional exclusions this filter applies, exposed by
|
|
8331
|
+
* {@link createServerToolsFilter} so defer-loading can honour them without the caller
|
|
8332
|
+
* repeating the list — see {@link resolveDeferredServerTools}. Absent on a hand-written
|
|
8333
|
+
* filter, or on one wrapped in a plain closure.
|
|
8334
|
+
*/
|
|
8335
|
+
readonly excludeTools?: readonly string[];
|
|
8336
|
+
};
|
|
8337
|
+
/**
|
|
8338
|
+
* Options for selectServerSideTools
|
|
8339
|
+
*/
|
|
8340
|
+
interface SelectServerSideToolsOptions {
|
|
8341
|
+
/** The user prompt to match tools against */
|
|
8342
|
+
prompt: string;
|
|
8343
|
+
/** Function to get auth token (uses Authorization: Bearer header) */
|
|
8344
|
+
getToken?: () => Promise<string | null>;
|
|
8345
|
+
/** Direct API key for server-side usage (uses X-API-Key header) */
|
|
8346
|
+
apiKey?: string;
|
|
8347
|
+
/** Base URL for the API */
|
|
8348
|
+
baseUrl?: string;
|
|
8349
|
+
/** Cache expiration in ms (default: 24h) */
|
|
8350
|
+
cacheExpirationMs?: number;
|
|
8351
|
+
/** Force refresh tools cache */
|
|
8352
|
+
forceRefresh?: boolean;
|
|
8353
|
+
/** Embedding model to use */
|
|
8354
|
+
embeddingModel?: string;
|
|
8355
|
+
/** Max tools to return (default: 10) */
|
|
8356
|
+
limit?: number;
|
|
8357
|
+
/** Minimum cosine similarity 0-1 (default: 0.3) */
|
|
8358
|
+
minSimilarity?: number;
|
|
8359
|
+
/** API format for returned tools (default: "responses") */
|
|
8360
|
+
apiType?: "responses" | "completions";
|
|
8625
8361
|
}
|
|
8626
|
-
|
|
8627
|
-
declare const DEFAULT_ANALYSIS_PROMPT = "Analyze these user messages and describe their communication style in 1-2 concise sentences. Focus on: tone (formal/casual/playful), message length preference, vocabulary level, and any notable patterns. Output only the style description, nothing else.";
|
|
8628
|
-
declare const DEFAULT_MAX_INPUT_MESSAGES = 10;
|
|
8629
|
-
declare const DEFAULT_MIN_MESSAGES = 3;
|
|
8630
|
-
declare const DEFAULT_MAX_PROFILE_LENGTH = 200;
|
|
8631
|
-
declare const DEFAULT_ANALYZE_AFTER_MESSAGES = 5;
|
|
8632
|
-
declare const DEFAULT_REFRESH_EVERY_MESSAGES = 20;
|
|
8633
|
-
declare const DEFAULT_DOCUMENT_PATTERN: RegExp;
|
|
8634
|
-
declare function shouldAnalyzeStyle(schedule: StyleAnalysisSchedule): boolean;
|
|
8635
|
-
declare function analyzeStyle(options: AnalyzeStyleOptions): Promise<AnalyzeStyleResult>;
|
|
8636
|
-
|
|
8637
|
-
declare const DEFAULT_PROMPT_TEMPLATES: PromptTemplates;
|
|
8638
|
-
/** Collapse runs of 3+ double-quotes to a single quote to prevent prompt injection. */
|
|
8639
|
-
declare function sanitizeQuotes(s: string): string;
|
|
8640
|
-
/** Replace {content} in a template with sanitized value. Returns null if value is falsy. */
|
|
8641
|
-
declare function renderTemplate(value: string | null | undefined, template: string): string | null;
|
|
8642
|
-
declare function buildSystemPrompt(ctx: PromptContext, options?: BuildPromptOptions): BuildPromptResult;
|
|
8643
|
-
|
|
8644
8362
|
/**
|
|
8645
|
-
*
|
|
8363
|
+
* Select server tools that are semantically relevant to a prompt.
|
|
8646
8364
|
*
|
|
8647
|
-
*
|
|
8648
|
-
* -
|
|
8649
|
-
*
|
|
8650
|
-
*
|
|
8651
|
-
*
|
|
8652
|
-
*
|
|
8365
|
+
* Fetches available tools (with caching), generates embeddings for the prompt,
|
|
8366
|
+
* runs cosine-similarity matching, and returns tool schemas in the requested
|
|
8367
|
+
* API format (Responses or Completions).
|
|
8368
|
+
*
|
|
8369
|
+
* @example
|
|
8370
|
+
* ```ts
|
|
8371
|
+
* import { selectServerSideTools } from "@anuma/sdk/tools";
|
|
8372
|
+
*
|
|
8373
|
+
* const tools = await selectServerSideTools({
|
|
8374
|
+
* prompt: "Draw me a cat",
|
|
8375
|
+
* getToken: async () => identityToken,
|
|
8376
|
+
* });
|
|
8377
|
+
*
|
|
8378
|
+
* const response = await postApiV1Responses({
|
|
8379
|
+
* body: {
|
|
8380
|
+
* messages: [{ role: "user", content: [{ type: "text", text: "Draw me a cat" }] }],
|
|
8381
|
+
* model: "fireworks/accounts/fireworks/models/kimi-k2p5",
|
|
8382
|
+
* tools,
|
|
8383
|
+
* },
|
|
8384
|
+
* headers: { Authorization: `Bearer ${identityToken}` },
|
|
8385
|
+
* });
|
|
8386
|
+
* ```
|
|
8653
8387
|
*/
|
|
8654
|
-
|
|
8388
|
+
declare function selectServerSideTools(options: SelectServerSideToolsOptions): Promise<Array<Record<string, unknown>>>;
|
|
8389
|
+
|
|
8390
|
+
interface ToolCatalogEntry {
|
|
8391
|
+
label: string;
|
|
8392
|
+
/** Canonical logical-provider id (e.g. "gmail", "gcalendar", "gdrive"). */
|
|
8393
|
+
provider: string;
|
|
8394
|
+
/** Human-facing connector display name (UI label). */
|
|
8395
|
+
connector: string;
|
|
8396
|
+
}
|
|
8397
|
+
declare const TOOL_CATALOG: Record<string, ToolCatalogEntry>;
|
|
8655
8398
|
/**
|
|
8656
|
-
*
|
|
8657
|
-
*
|
|
8399
|
+
* Build a system-prompt fragment telling the model which connector capabilities
|
|
8400
|
+
* the user has turned off, so it can give the specific "re-enable this tool"
|
|
8401
|
+
* message instead of a generic refusal.
|
|
8658
8402
|
*
|
|
8659
|
-
*
|
|
8660
|
-
*
|
|
8661
|
-
*
|
|
8662
|
-
* - `skipped`: not processed (see `reason`)
|
|
8663
|
-
* - `failed`: processing was attempted and failed (see `reason`)
|
|
8403
|
+
* Unknown names (not in {@link TOOL_CATALOG}) are skipped. Returns `""` when the
|
|
8404
|
+
* input is empty or every name is unknown — callers append the result
|
|
8405
|
+
* conditionally, so an empty string is a no-op.
|
|
8664
8406
|
*/
|
|
8665
|
-
|
|
8666
|
-
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8407
|
+
declare function buildDeniedToolsRider(deniedToolNames: Iterable<string>): string;
|
|
8408
|
+
interface ConnectorGuidanceInput {
|
|
8409
|
+
/** The candidate tools for this turn (the final assembled set). */
|
|
8410
|
+
tools: ToolConfig[];
|
|
8411
|
+
/**
|
|
8412
|
+
* Logical provider codes connected for the user — the same codes used as
|
|
8413
|
+
* {@link TOOL_CATALOG} `provider` values (e.g. "gmail", "gcalendar",
|
|
8414
|
+
* "gdrive", "notion", "github", "dropbox").
|
|
8415
|
+
*/
|
|
8416
|
+
connectedProviders: string[];
|
|
8417
|
+
/** Exact SDK tool-name strings the user turned off ({@link TOOL_CATALOG} keys). */
|
|
8418
|
+
deniedToolNames: string[];
|
|
8419
|
+
}
|
|
8420
|
+
interface ConnectorGuidance {
|
|
8421
|
+
/** `input.tools` with any denied tool removed (the helper owns filtering). */
|
|
8422
|
+
tools: ToolConfig[];
|
|
8423
|
+
/** Compact system-prompt block, or "" when there's nothing actionable. */
|
|
8424
|
+
rider: string;
|
|
8670
8425
|
}
|
|
8426
|
+
/**
|
|
8427
|
+
* Single helper both web and mobile use so neither re-implements connector
|
|
8428
|
+
* tool filtering or the accuracy messaging. It enforces denial (drops denied
|
|
8429
|
+
* tools from the turn's toolset) AND builds a compact rider letting the model
|
|
8430
|
+
* give an accurate message for each connector state instead of a generic
|
|
8431
|
+
* "I don't have access":
|
|
8432
|
+
*
|
|
8433
|
+
* 1. Toggled off — connected provider whose tool is denied → "turned off,
|
|
8434
|
+
* re-enable in Connected Apps".
|
|
8435
|
+
* 2a. Pruned / 2b. no tool — covered by a general line telling the model not to
|
|
8436
|
+
* claim no-access for a connected app. It rides along only when another
|
|
8437
|
+
* section is present (on its own it isn't actionable).
|
|
8438
|
+
* 3. Not connected — catalog provider absent from `connectedProviders` →
|
|
8439
|
+
* "connect it in Connected Apps".
|
|
8440
|
+
*
|
|
8441
|
+
* State 3 is derived from {@link TOOL_CATALOG}'s provider set — providers with
|
|
8442
|
+
* no tools (e.g. Disconnect-only Dropbox) aren't actionable via tools, so they
|
|
8443
|
+
* aren't surfaced here. Everything is sorted alphabetically for deterministic
|
|
8444
|
+
* output (no cache / snapshot churn). `rider` is "" when nothing is actionable
|
|
8445
|
+
* (every catalog provider connected and nothing denied).
|
|
8446
|
+
*/
|
|
8447
|
+
declare function buildConnectorGuidance(input: ConnectorGuidanceInput): ConnectorGuidance;
|
|
8671
8448
|
|
|
8672
8449
|
interface StoredConversation {
|
|
8673
8450
|
uniqueId: string;
|
|
@@ -8707,15 +8484,43 @@ interface LazyStoredConversation extends Omit<StoredConversation, "title"> {
|
|
|
8707
8484
|
}
|
|
8708
8485
|
|
|
8709
8486
|
/**
|
|
8710
|
-
*
|
|
8487
|
+
* Pluggable logger for the Anuma SDK.
|
|
8488
|
+
*
|
|
8489
|
+
* By default all SDK logging goes to `console`. Call {@link setLogger} at app
|
|
8490
|
+
* init (or use `<LoggerProvider>` in React) to redirect output to your own
|
|
8491
|
+
* logging infrastructure (PostHog, Datadog, Sentry, etc.).
|
|
8492
|
+
*
|
|
8493
|
+
* @example
|
|
8494
|
+
* ```ts
|
|
8495
|
+
* import { setLogger, type Logger } from "@anuma/sdk";
|
|
8496
|
+
*
|
|
8497
|
+
* const myLogger: Logger = {
|
|
8498
|
+
* debug: () => {},
|
|
8499
|
+
* info: (...args) => posthog.capture("sdk_info", { message: args }),
|
|
8500
|
+
* warn: (...args) => console.warn("[SDK]", ...args),
|
|
8501
|
+
* error: (...args) => Sentry.captureMessage(args.join(" ")),
|
|
8502
|
+
* };
|
|
8711
8503
|
*
|
|
8712
|
-
*
|
|
8713
|
-
*
|
|
8714
|
-
* vectors/chunks back. The raw "text → embedding" calls live in `./generate`
|
|
8715
|
-
* (dependency-free so the tool-selection engine can import them without the DB
|
|
8716
|
-
* layer) and are re-exported here so existing importers of
|
|
8717
|
-
* `../memoryEngine/embeddings` and the `../memoryEngine` barrel keep working.
|
|
8504
|
+
* setLogger(myLogger);
|
|
8505
|
+
* ```
|
|
8718
8506
|
*/
|
|
8507
|
+
interface Logger {
|
|
8508
|
+
debug: (...args: unknown[]) => void;
|
|
8509
|
+
/** Used for outcomes that are noteworthy but expected — a consolidation
|
|
8510
|
+
* refusal that preserved a memory, for example. Keep genuinely-wrong things at
|
|
8511
|
+
* `warn` so the two stay distinguishable in a log search. */
|
|
8512
|
+
info: (...args: unknown[]) => void;
|
|
8513
|
+
warn: (...args: unknown[]) => void;
|
|
8514
|
+
error: (...args: unknown[]) => void;
|
|
8515
|
+
}
|
|
8516
|
+
/** Default logger that delegates to the global `console` object. */
|
|
8517
|
+
declare const consoleLogger: Logger;
|
|
8518
|
+
/** Silent logger that discards all output. */
|
|
8519
|
+
declare const noopLogger: Logger;
|
|
8520
|
+
/** Replace the active SDK logger. Pass {@link consoleLogger} to restore defaults. */
|
|
8521
|
+
declare function setLogger(logger: Logger): void;
|
|
8522
|
+
/** Return the active SDK logger. */
|
|
8523
|
+
declare function getLogger(): Logger;
|
|
8719
8524
|
|
|
8720
8525
|
/**
|
|
8721
8526
|
* An ordinary message whose chunk vectors were built over `enc:v3:` ciphertext
|
|
@@ -8824,42 +8629,6 @@ declare function dequantizeEmbedding({ data, scale }: QuantizedEmbedding): Float
|
|
|
8824
8629
|
*/
|
|
8825
8630
|
declare function cosineInt8(a: Int8Array, scaleA: number, b: Int8Array, scaleB: number): number;
|
|
8826
8631
|
|
|
8827
|
-
/**
|
|
8828
|
-
* Storage encoding for `MessageChunk.vector`.
|
|
8829
|
-
*
|
|
8830
|
-
* Chunk vectors are persisted inside the `chunks` column as JSON. Since #732
|
|
8831
|
-
* their values are canonically float32 — `generateEmbeddings` round-trips its
|
|
8832
|
-
* return value through a `Float32Array` so a cache hit and a cache miss agree —
|
|
8833
|
-
* which paradoxically made the JSON LONGER: `JSON.stringify` emits the shortest
|
|
8834
|
-
* decimal that round-trips to the float64, and a binary32-exact value needs ~17
|
|
8835
|
-
* significant digits. Measured at 4096 dims (`qwen/qwen3-embedding-8b`): 54.5 KB
|
|
8836
|
-
* of JSON before #732, 84.5 KB after.
|
|
8837
|
-
*
|
|
8838
|
-
* Base64-encoding the `Float32Array` stores the same bits as 4 bytes per value
|
|
8839
|
-
* instead of ~21 characters — 21.3 KB at 4096 dims. Because the data already IS
|
|
8840
|
-
* float32, the encoding is EXACTLY lossless, so the round-trip assertion is
|
|
8841
|
-
* equality and never a tolerance.
|
|
8842
|
-
*
|
|
8843
|
-
* Rollout (sdk#862). `decodeChunkVector` accepts both encodings and ships first;
|
|
8844
|
-
* `encodeChunkVector` is deliberately NOT wired into the write path yet. Every
|
|
8845
|
-
* stored chunk on every device is still a JSON array, and chat history syncs
|
|
8846
|
-
* those rows between devices verbatim — the backup push spreads the whole raw
|
|
8847
|
-
* row and the restore copies every column — so a device on an older build would
|
|
8848
|
-
* meet a base64 string where it expects `number[]`. It does not throw, and it
|
|
8849
|
-
* does not fall back: the row still HAS chunks, so the old build takes the chunk
|
|
8850
|
-
* branch and never reaches the whole-message one. `Float32Array.from` over the
|
|
8851
|
-
* string yields one NaN per character, `cosineSimilarity` returns 0 on the
|
|
8852
|
-
* dimension mismatch, and the default `minSimilarity` cuts it — the row leaves
|
|
8853
|
-
* search entirely. The old build then caches what it built: ~87 KB of NaN per
|
|
8854
|
-
* chunk, so ~54 MB resident for a 620-chunk row, on exactly the device this
|
|
8855
|
-
* sequencing exists to protect. The writer flips in a later release, once a
|
|
8856
|
-
* build that reads both encodings has saturated; the single flip site is
|
|
8857
|
-
* `updateMessageChunksOp`.
|
|
8858
|
-
*
|
|
8859
|
-
* Byte order is the platform's, since this reads the `Float32Array` bytes
|
|
8860
|
-
* directly. Every runtime the SDK targets (browsers, iOS, Android, Node on
|
|
8861
|
-
* x86/ARM) is little-endian.
|
|
8862
|
-
*/
|
|
8863
8632
|
/**
|
|
8864
8633
|
* Encode an embedding as base64 float32 for storage.
|
|
8865
8634
|
*
|
|
@@ -8867,73 +8636,150 @@ declare function cosineInt8(a: Int8Array, scaleA: number, b: Int8Array, scaleB:
|
|
|
8867
8636
|
* narrowed to float32 first, which is lossless for anything `generateEmbeddings`
|
|
8868
8637
|
* produced and is what makes the decode byte-exact.
|
|
8869
8638
|
*/
|
|
8870
|
-
declare function encodeChunkVector(vector: ArrayLike<number>): string;
|
|
8871
|
-
/**
|
|
8872
|
-
* Read a stored chunk vector in either encoding: a base64 float32 string, or the
|
|
8873
|
-
* legacy `number[]` that every row written before the writer flip still holds.
|
|
8874
|
-
*
|
|
8875
|
-
* Returns a zero-length `Float32Array` for a missing, empty, or unreadable
|
|
8876
|
-
* value, which callers already treat as "this chunk has no vector" — the same
|
|
8877
|
-
* degradation a malformed `chunks` JSON gets today, rather than a throw that
|
|
8878
|
-
* would take down a whole search pass over one bad row.
|
|
8879
|
-
*
|
|
8880
|
-
* That one return value covers two different situations, and a caller cannot
|
|
8881
|
-
* tell them apart: a chunk that legitimately has no vector, and a chunk whose
|
|
8882
|
-
* vector is corrupt. `onMalformed` separates them. It fires only on the corrupt
|
|
8883
|
-
* paths, never on an absent or empty value, so a caller can count corruption
|
|
8884
|
-
* without counting normal empties.
|
|
8885
|
-
*
|
|
8886
|
-
* Nothing is logged here. A corrupt row holds hundreds of chunks and this runs
|
|
8887
|
-
* once per chunk, so the caller aggregates and reports once per pass — the shape
|
|
8888
|
-
* `searchChunksOp` already uses for stale-model vectors.
|
|
8889
|
-
*/
|
|
8890
|
-
declare function decodeChunkVector(vector: number[] | string | null | undefined, onMalformed?: () => void): Float32Array<ArrayBuffer>;
|
|
8891
|
-
|
|
8892
|
-
/**
|
|
8893
|
-
* Value of the `origin` column on a row the SDK synthesised for a turn's tool results (v44, #866).
|
|
8894
|
-
*
|
|
8895
|
-
* `satisfies MessageOrigin` so this constant and the column's union cannot drift apart silently.
|
|
8896
|
-
*/
|
|
8897
|
-
declare const TOOL_RESULT_ORIGIN = "tool_result";
|
|
8898
|
-
|
|
8899
|
-
/**
|
|
8900
|
-
* True when a text part is the attachment-contents part built by {@link buildAttachedFilesText}.
|
|
8901
|
-
*
|
|
8902
|
-
* Matches the whole generated shape — opening tag plus the fixed header line, and the closing
|
|
8903
|
-
* tag — not just the tag, so user text that merely starts with `<attached_files>` is still
|
|
8904
|
-
* treated as the user's prompt.
|
|
8905
|
-
*/
|
|
8906
|
-
declare function isAttachedFilesText(text: string | undefined | null): boolean;
|
|
8907
|
-
/**
|
|
8908
|
-
* Wrap a turn's extracted file contents (the `[Extracted content from <name>]`
|
|
8909
|
-
* blocks `preprocessFiles` emits) in the tagged part that rides on that turn's
|
|
8910
|
-
* user message.
|
|
8911
|
-
*/
|
|
8912
|
-
declare function buildAttachedFilesText(fileContext: string): string;
|
|
8639
|
+
declare function encodeChunkVector(vector: ArrayLike<number>): string;
|
|
8913
8640
|
/**
|
|
8914
|
-
*
|
|
8915
|
-
*
|
|
8916
|
-
* after everything the user wrote, and before any parts that follow it
|
|
8917
|
-
* (typically images). With interleaved parts such as `[text, image, text,
|
|
8918
|
-
* image]` it lands between the second text and the second image.
|
|
8641
|
+
* Read a stored chunk vector in either encoding: a base64 float32 string, or the
|
|
8642
|
+
* legacy `number[]` that every row written before the writer flip still holds.
|
|
8919
8643
|
*
|
|
8920
|
-
*
|
|
8921
|
-
*
|
|
8922
|
-
*
|
|
8923
|
-
*
|
|
8924
|
-
* the two and told users the attachment was unreadable even though its text
|
|
8925
|
-
* was in the request. Keeping the contents on the turn that attached them is
|
|
8926
|
-
* how native file attachments work on every provider, and survives the auto
|
|
8927
|
-
* router switching models between turns.
|
|
8644
|
+
* Returns a zero-length `Float32Array` for a missing, empty, or unreadable
|
|
8645
|
+
* value, which callers already treat as "this chunk has no vector" — the same
|
|
8646
|
+
* degradation a malformed `chunks` JSON gets today, rather than a throw that
|
|
8647
|
+
* would take down a whole search pass over one bad row.
|
|
8928
8648
|
*
|
|
8929
|
-
*
|
|
8930
|
-
*
|
|
8931
|
-
*
|
|
8649
|
+
* That one return value covers two different situations, and a caller cannot
|
|
8650
|
+
* tell them apart: a chunk that legitimately has no vector, and a chunk whose
|
|
8651
|
+
* vector is corrupt. `onMalformed` separates them. It fires only on the corrupt
|
|
8652
|
+
* paths, never on an absent or empty value, so a caller can count corruption
|
|
8653
|
+
* without counting normal empties.
|
|
8932
8654
|
*
|
|
8933
|
-
*
|
|
8934
|
-
*
|
|
8655
|
+
* Nothing is logged here. A corrupt row holds hundreds of chunks and this runs
|
|
8656
|
+
* once per chunk, so the caller aggregates and reports once per pass — the shape
|
|
8657
|
+
* `searchChunksOp` already uses for stale-model vectors.
|
|
8935
8658
|
*/
|
|
8936
|
-
declare function
|
|
8659
|
+
declare function decodeChunkVector(vector: number[] | string | null | undefined, onMalformed?: () => void): Float32Array<ArrayBuffer>;
|
|
8660
|
+
|
|
8661
|
+
/** A single section in the system prompt. */
|
|
8662
|
+
interface PromptSection {
|
|
8663
|
+
/** Unique identifier (used for disabling/overriding). */
|
|
8664
|
+
key: string;
|
|
8665
|
+
/** Lower priority = earlier in the prompt. Sections sort ascending. */
|
|
8666
|
+
priority: number;
|
|
8667
|
+
/** Return text to append, or null to skip this section. */
|
|
8668
|
+
render: (ctx: PromptContext) => string | null;
|
|
8669
|
+
}
|
|
8670
|
+
/** Context passed to every section renderer. */
|
|
8671
|
+
interface PromptContext {
|
|
8672
|
+
/** Base personality prompt (from PersonaConfig.prompt). */
|
|
8673
|
+
basePrompt: string;
|
|
8674
|
+
/** User-set "act as X" communication preference. */
|
|
8675
|
+
persona?: string | null;
|
|
8676
|
+
/** Analyzed user communication style profile. */
|
|
8677
|
+
styleProfile?: string | null;
|
|
8678
|
+
/** Detected user sentiment. */
|
|
8679
|
+
sentiment?: "frustrated" | "positive" | "neutral" | null;
|
|
8680
|
+
/** ISO 639-1 language code, 'other', or null for English/undetected. */
|
|
8681
|
+
preferredLanguage?: string | null;
|
|
8682
|
+
/** Platform-specific formatting instructions from PersonaConfig. */
|
|
8683
|
+
platformFormatting?: string | null;
|
|
8684
|
+
/** Available tools. */
|
|
8685
|
+
toolSummaries?: Array<{
|
|
8686
|
+
name: string;
|
|
8687
|
+
description: string;
|
|
8688
|
+
}>;
|
|
8689
|
+
/** Consumer-specific data for custom sections. */
|
|
8690
|
+
extra?: Record<string, unknown>;
|
|
8691
|
+
}
|
|
8692
|
+
/** Configurable template strings for built-in section renderers. */
|
|
8693
|
+
interface PromptTemplates {
|
|
8694
|
+
tools: string;
|
|
8695
|
+
persona: string;
|
|
8696
|
+
style: string;
|
|
8697
|
+
sentiment: {
|
|
8698
|
+
frustrated: string;
|
|
8699
|
+
positive: string;
|
|
8700
|
+
};
|
|
8701
|
+
language: string;
|
|
8702
|
+
languageGeneric: string;
|
|
8703
|
+
platformFormatting: string;
|
|
8704
|
+
}
|
|
8705
|
+
/** Options for buildSystemPrompt(). */
|
|
8706
|
+
interface BuildPromptOptions {
|
|
8707
|
+
/** Additional sections appended to defaults. */
|
|
8708
|
+
extraSections?: PromptSection[];
|
|
8709
|
+
/** Section keys to skip. */
|
|
8710
|
+
disabled?: string[];
|
|
8711
|
+
/** Max total prompt length in characters. 0 = unlimited. */
|
|
8712
|
+
maxLength?: number;
|
|
8713
|
+
/** Override default template strings. */
|
|
8714
|
+
templates?: Partial<PromptTemplates>;
|
|
8715
|
+
}
|
|
8716
|
+
/** Result of buildSystemPrompt(). */
|
|
8717
|
+
interface BuildPromptResult {
|
|
8718
|
+
/** The assembled prompt string. */
|
|
8719
|
+
prompt: string;
|
|
8720
|
+
/** Keys of sections that rendered (in order). */
|
|
8721
|
+
activeSections: string[];
|
|
8722
|
+
}
|
|
8723
|
+
/** Options for analyzeStyle(). */
|
|
8724
|
+
interface AnalyzeStyleOptions {
|
|
8725
|
+
/** Recent conversation messages. */
|
|
8726
|
+
messages: Array<{
|
|
8727
|
+
role: string;
|
|
8728
|
+
content: string;
|
|
8729
|
+
}>;
|
|
8730
|
+
/** Callback to send messages to an LLM and get a text response. */
|
|
8731
|
+
callLlm: (messages: Array<{
|
|
8732
|
+
role: string;
|
|
8733
|
+
content: string;
|
|
8734
|
+
}>) => Promise<string | null>;
|
|
8735
|
+
/** Max user messages to consider (default: 10). */
|
|
8736
|
+
maxInputMessages?: number;
|
|
8737
|
+
/** Minimum user messages required (default: 3). */
|
|
8738
|
+
minMessages?: number;
|
|
8739
|
+
/** Max profile length in characters (default: 200). */
|
|
8740
|
+
maxProfileLength?: number;
|
|
8741
|
+
/** Custom system prompt for the analysis model. */
|
|
8742
|
+
analysisPrompt?: string;
|
|
8743
|
+
/** Regex to filter out document-embedded messages. */
|
|
8744
|
+
documentPattern?: RegExp;
|
|
8745
|
+
}
|
|
8746
|
+
/** Result of analyzeStyle(). */
|
|
8747
|
+
interface AnalyzeStyleResult {
|
|
8748
|
+
/** The style profile string, or null if skipped/failed. */
|
|
8749
|
+
profile: string | null;
|
|
8750
|
+
}
|
|
8751
|
+
/** Input for shouldAnalyzeStyle(). */
|
|
8752
|
+
interface StyleAnalysisSchedule {
|
|
8753
|
+
/** Current message count for the user. */
|
|
8754
|
+
messageCount: number;
|
|
8755
|
+
/** Whether the user already has a style profile. */
|
|
8756
|
+
hasProfile: boolean;
|
|
8757
|
+
/** Whether analysis has ever run (updatedAt timestamp is set). */
|
|
8758
|
+
hasBeenAnalyzed: boolean;
|
|
8759
|
+
/** Whether the user opted out (updatedAt set but profile is null). */
|
|
8760
|
+
optedOut: boolean;
|
|
8761
|
+
/** Trigger analysis after this many messages (default: 5). */
|
|
8762
|
+
analyzeAfterMessages?: number;
|
|
8763
|
+
/** Re-analyze every N messages (default: 20). */
|
|
8764
|
+
refreshEveryMessages?: number;
|
|
8765
|
+
}
|
|
8766
|
+
|
|
8767
|
+
declare const DEFAULT_ANALYSIS_PROMPT = "Analyze these user messages and describe their communication style in 1-2 concise sentences. Focus on: tone (formal/casual/playful), message length preference, vocabulary level, and any notable patterns. Output only the style description, nothing else.";
|
|
8768
|
+
declare const DEFAULT_MAX_INPUT_MESSAGES = 10;
|
|
8769
|
+
declare const DEFAULT_MIN_MESSAGES = 3;
|
|
8770
|
+
declare const DEFAULT_MAX_PROFILE_LENGTH = 200;
|
|
8771
|
+
declare const DEFAULT_ANALYZE_AFTER_MESSAGES = 5;
|
|
8772
|
+
declare const DEFAULT_REFRESH_EVERY_MESSAGES = 20;
|
|
8773
|
+
declare const DEFAULT_DOCUMENT_PATTERN: RegExp;
|
|
8774
|
+
declare function shouldAnalyzeStyle(schedule: StyleAnalysisSchedule): boolean;
|
|
8775
|
+
declare function analyzeStyle(options: AnalyzeStyleOptions): Promise<AnalyzeStyleResult>;
|
|
8776
|
+
|
|
8777
|
+
declare const DEFAULT_PROMPT_TEMPLATES: PromptTemplates;
|
|
8778
|
+
/** Collapse runs of 3+ double-quotes to a single quote to prevent prompt injection. */
|
|
8779
|
+
declare function sanitizeQuotes(s: string): string;
|
|
8780
|
+
/** Replace {content} in a template with sanitized value. Returns null if value is falsy. */
|
|
8781
|
+
declare function renderTemplate(value: string | null | undefined, template: string): string | null;
|
|
8782
|
+
declare function buildSystemPrompt(ctx: PromptContext, options?: BuildPromptOptions): BuildPromptResult;
|
|
8937
8783
|
|
|
8938
8784
|
/**
|
|
8939
8785
|
* One line per file the model did NOT get, saying why — e.g.
|
|
@@ -8948,71 +8794,85 @@ declare function formatFileProcessingNotes(statuses: FileProcessingStatus[], opt
|
|
|
8948
8794
|
}): string | null;
|
|
8949
8795
|
|
|
8950
8796
|
/**
|
|
8951
|
-
*
|
|
8952
|
-
*
|
|
8953
|
-
* Today the SDK eagerly decrypts every conversation title returned from
|
|
8954
|
-
* `getConversationsOp` so callers can render them immediately. For users
|
|
8955
|
-
* with hundreds or thousands of conversations this means hundreds of
|
|
8956
|
-
* plaintext title strings sitting in client RAM at all times — a
|
|
8957
|
-
* non-trivial memory cost on long-lived tabs, and an unnecessary one
|
|
8958
|
-
* since only the visible rows actually need plaintext.
|
|
8797
|
+
* Idle-keepalive wrapper for SSE streams produced by the generated
|
|
8798
|
+
* SSE client in `src/client/core/serverSentEvents.gen.ts`.
|
|
8959
8799
|
*
|
|
8960
|
-
*
|
|
8961
|
-
*
|
|
8962
|
-
*
|
|
8963
|
-
* (e.g. inside an IntersectionObserver callback or a virtualized list's
|
|
8964
|
-
* `renderItem`).
|
|
8800
|
+
* The generated SSE client does not enforce an idle timeout, so if the
|
|
8801
|
+
* upstream server dies without sending `FIN`, a consumer can sit forever
|
|
8802
|
+
* on a half-open socket. This wrapper:
|
|
8965
8803
|
*
|
|
8966
|
-
*
|
|
8967
|
-
* -
|
|
8968
|
-
*
|
|
8969
|
-
* -
|
|
8970
|
-
*
|
|
8971
|
-
* - a hard error when the encryption key isn't loaded — `decryptField`
|
|
8972
|
-
* itself silently returns the ciphertext on key-missing, which is
|
|
8973
|
-
* useful for backwards-compatible reads but actively misleading for
|
|
8974
|
-
* a lazy display path (the UI would render `enc:v3:...` as the title).
|
|
8804
|
+
* - Tracks the timestamp of the last event yielded by the source.
|
|
8805
|
+
* - Starts an idle timer (default 60s, configurable via `idleMs`).
|
|
8806
|
+
* - Resets the timer on every event.
|
|
8807
|
+
* - Invokes `onIdle()` if the timer fires, and then closes the stream
|
|
8808
|
+
* by throwing a typed {@link SseIdleTimeoutError} out of the iterator.
|
|
8975
8809
|
*
|
|
8976
|
-
*
|
|
8977
|
-
*
|
|
8810
|
+
* This file lives outside `src/client/` on purpose: `@hey-api/openapi-ts`
|
|
8811
|
+
* wipes its output directory on every regeneration, so anything inside
|
|
8812
|
+
* `src/client/` would be clobbered by `pnpm run generate`.
|
|
8978
8813
|
*/
|
|
8979
8814
|
/**
|
|
8980
|
-
*
|
|
8981
|
-
*
|
|
8982
|
-
* Wired into `clearAllEncryptionState()` via the listener registry in
|
|
8983
|
-
* `useEncryption.ts`. Also exported so consumers can clear the cache
|
|
8984
|
-
* proactively (e.g. on wallet switch within a session before the
|
|
8985
|
-
* full encryption-state teardown lands).
|
|
8815
|
+
* Options accepted by {@link withSseKeepalive}.
|
|
8986
8816
|
*/
|
|
8987
|
-
|
|
8817
|
+
interface SseKeepaliveOptions {
|
|
8818
|
+
/**
|
|
8819
|
+
* Idle window, in milliseconds. If no event is yielded by the source for
|
|
8820
|
+
* this long, the stream is considered dead and is torn down.
|
|
8821
|
+
*
|
|
8822
|
+
* Set to `0` or a negative number to disable the idle timer (in which
|
|
8823
|
+
* case the wrapper is a straight passthrough).
|
|
8824
|
+
*
|
|
8825
|
+
* @default 60000
|
|
8826
|
+
*/
|
|
8827
|
+
idleMs?: number;
|
|
8828
|
+
/**
|
|
8829
|
+
* Invoked when the idle timer fires. The callback runs before the
|
|
8830
|
+
* wrapper closes the stream, so consumers can log, emit metrics, or
|
|
8831
|
+
* attempt reconnects from here.
|
|
8832
|
+
*
|
|
8833
|
+
* The callback is best-effort — thrown errors are swallowed so they do
|
|
8834
|
+
* not mask the {@link SseIdleTimeoutError} that follows.
|
|
8835
|
+
*/
|
|
8836
|
+
onIdle?: (info: {
|
|
8837
|
+
idleMs: number;
|
|
8838
|
+
lastEventAt: number;
|
|
8839
|
+
}) => void;
|
|
8840
|
+
}
|
|
8988
8841
|
/**
|
|
8989
|
-
*
|
|
8842
|
+
* Thrown by {@link withSseKeepalive} when no event arrives within the
|
|
8843
|
+
* configured idle window. Callers can `instanceof`-check this to
|
|
8844
|
+
* distinguish idle timeouts from other stream errors.
|
|
8845
|
+
*/
|
|
8846
|
+
declare class SseIdleTimeoutError extends Error {
|
|
8847
|
+
readonly idleMs: number;
|
|
8848
|
+
readonly lastEventAt: number;
|
|
8849
|
+
constructor(idleMs: number, lastEventAt: number);
|
|
8850
|
+
}
|
|
8851
|
+
/**
|
|
8852
|
+
* Wrap an SSE-style async iterable with an idle timeout. If no value is
|
|
8853
|
+
* yielded by `source` within `idleMs`, `onIdle` fires and the wrapper
|
|
8854
|
+
* throws {@link SseIdleTimeoutError}, which propagates to the consumer's
|
|
8855
|
+
* `for await` loop and, via the iterator protocol, calls `source.return()`
|
|
8856
|
+
* so the underlying fetch/reader is cancelled.
|
|
8990
8857
|
*
|
|
8991
|
-
*
|
|
8992
|
-
* and call this once a row is actually visible.
|
|
8858
|
+
* Typical usage with the generated SSE client:
|
|
8993
8859
|
*
|
|
8994
|
-
*
|
|
8995
|
-
*
|
|
8996
|
-
*
|
|
8997
|
-
* keeps the helper safe to call unconditionally from rendering
|
|
8998
|
-
* code that may receive a mix of encrypted and plaintext titles.
|
|
8999
|
-
* - Encrypted input is decrypted via `decryptField`, which uses the
|
|
9000
|
-
* same per-version cached `CryptoKey` as the eager path — no new
|
|
9001
|
-
* key derivations are triggered.
|
|
9002
|
-
* - Concurrent calls for the same `(address, encryptedTitle)` share
|
|
9003
|
-
* a single decrypt promise.
|
|
9004
|
-
* - The result is memoized in a 256-entry LRU.
|
|
8860
|
+
* ```ts
|
|
8861
|
+
* import { createSseClient } from "@anuma/sdk/client/core/serverSentEvents.gen";
|
|
8862
|
+
* import { withSseKeepalive } from "@anuma/sdk";
|
|
9005
8863
|
*
|
|
9006
|
-
*
|
|
9007
|
-
*
|
|
9008
|
-
*
|
|
9009
|
-
*
|
|
8864
|
+
* const { stream } = createSseClient({ url });
|
|
8865
|
+
* for await (const event of withSseKeepalive(stream, {
|
|
8866
|
+
* idleMs: 60_000,
|
|
8867
|
+
* onIdle: ({ idleMs }) => logger.warn(`SSE idle for ${idleMs}ms`),
|
|
8868
|
+
* })) {
|
|
8869
|
+
* // ...
|
|
8870
|
+
* }
|
|
8871
|
+
* ```
|
|
9010
8872
|
*
|
|
9011
|
-
*
|
|
9012
|
-
* @param address - Wallet address that owns the encryption key.
|
|
9013
|
-
* @returns The decrypted plaintext title.
|
|
8873
|
+
* The wrapper is a pure passthrough when `idleMs <= 0`.
|
|
9014
8874
|
*/
|
|
9015
|
-
declare function
|
|
8875
|
+
declare function withSseKeepalive<T>(source: AsyncIterable<T>, options?: SseKeepaliveOptions): AsyncGenerator<T, void, unknown>;
|
|
9016
8876
|
|
|
9017
8877
|
/**
|
|
9018
8878
|
* Class-B task types — the vocabulary of the `X-Anuma-Task-Type` header.
|