@t2000/engine 1.18.0 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -5,6 +5,54 @@ import { Tool as Tool$1 } from '@modelcontextprotocol/sdk/types.js';
5
5
  import * as _t2000_sdk from '@t2000/sdk';
6
6
  import { T2000 } from '@t2000/sdk';
7
7
 
8
+ type ProactiveType = 'idle_balance' | 'hf_warning' | 'apy_drift' | 'goal_progress';
9
+ interface ProactiveMarker {
10
+ /** Allow-listed insight category (drives host icon/lockup variant). */
11
+ proactiveType: ProactiveType;
12
+ /** Stable per-subject key — engine uses (proactiveType, subjectKey) for cooldown. */
13
+ subjectKey: string;
14
+ /** Marker body with the wrapping tags stripped, trimmed of leading/trailing whitespace. */
15
+ body: string;
16
+ /** Total marker count detected — >1 indicates an LLM compliance violation. */
17
+ markerCount: number;
18
+ }
19
+ /**
20
+ * Scan completed final-text for one or more `<proactive>` markers.
21
+ *
22
+ * Returns null when no parseable marker exists. When at least one valid
23
+ * marker is found, returns the FIRST marker's payload + the total count
24
+ * (so the engine can emit `proactiveMarkerViolationsCount` telemetry
25
+ * when the LLM emitted >1 — the contract is at-most-one per turn).
26
+ *
27
+ * Pure function — safe to call per-text-block at content_block_stop.
28
+ */
29
+ declare function parseProactiveMarker(text: string): ProactiveMarker | null;
30
+ /**
31
+ * Strip every `<proactive ...>...</proactive>` wrapper from a text, leaving
32
+ * the body. Used by the engine's cooldown-suppression path: when the
33
+ * `(type, subjectKey)` was already seen in this session, the marker stays
34
+ * out of the rendered text but the body still reads cleanly.
35
+ *
36
+ * Idempotent — safe to call on text without markers.
37
+ */
38
+ declare function stripProactiveMarkers(text: string): string;
39
+ /**
40
+ * [SPEC 9 v0.1.1 P9.2 / R3] Yield every `(proactiveType, subjectKey)` pair
41
+ * present in `text`, in document order, regardless of whether the type is
42
+ * in the allow-list. Used by the engine's rehydration path on
43
+ * `loadMessages` to seed the per-session cooldown set from prior assistant
44
+ * blocks. Lenient (no `VALID_TYPES` filter) by design: extra cooldown
45
+ * entries for invalid types are inert because future valid emissions will
46
+ * never share the key, so seeding them costs nothing and keeps this helper
47
+ * decoupled from the emit-side validation policy.
48
+ *
49
+ * Returns `subjectKey` un-trimmed — caller is responsible for normalising.
50
+ */
51
+ declare function extractAllProactiveMarkers(text: string): Array<{
52
+ proactiveType: string;
53
+ subjectKey: string;
54
+ }>;
55
+
8
56
  /** Rough token count for a message array. */
9
57
  declare function estimateTokens(messages: Message[]): number;
10
58
  interface CompactOptions {
@@ -153,6 +201,118 @@ declare function loadRecipes(yamlDir: string): Recipe[];
153
201
  */
154
202
  declare function parseRecipe(yamlContent: string): Recipe;
155
203
 
204
+ /**
205
+ * Discriminator for the typed form-field kinds the host renderer supports.
206
+ * Closed list — adding a new kind requires a coordinated host-renderer +
207
+ * engine MINOR version bump.
208
+ */
209
+ type FormFieldKind = 'text' | 'sui-recipient' | 'number' | 'usd' | 'select' | 'date';
210
+ /**
211
+ * One row in a `pending_input` form. The host renderer keys on `kind` to
212
+ * pick the right input component.
213
+ */
214
+ interface FormField {
215
+ /** Input key on the resumed-tool input object (e.g. `name`, `identifier`). */
216
+ name: string;
217
+ /** User-facing label rendered above the input. */
218
+ label: string;
219
+ /** Renderer discriminator — see `FormFieldKind` for the closed list. */
220
+ kind: FormFieldKind;
221
+ /** When true, the host blocks submit while the value is empty/null. */
222
+ required: boolean;
223
+ /** Optional grey-text guidance shown inside the empty input. */
224
+ placeholder?: string;
225
+ /** Optional help text rendered below the input (small font). */
226
+ helpText?: string;
227
+ /**
228
+ * Required for `kind: 'select'` — closed-set choices the user can pick.
229
+ * `value` is what gets sent back; `label` is what's rendered.
230
+ * Omitted (or empty) for non-select kinds — the host renderer ignores it.
231
+ */
232
+ options?: Array<{
233
+ value: string;
234
+ label: string;
235
+ }>;
236
+ }
237
+ /**
238
+ * Top-level form payload carried on `pending_input`.
239
+ */
240
+ interface FormSchema {
241
+ /** Ordered list of fields the form renders top-to-bottom. */
242
+ fields: FormField[];
243
+ }
244
+ /**
245
+ * Engine-side state for a paused tool call awaiting user input. Stored on
246
+ * the QueryEngine instance keyed by `inputId` so the resume entry point
247
+ * can look up which tool to feed the values back into.
248
+ *
249
+ * Mirrors the (private) book-keeping the engine does for `pending_action`,
250
+ * but for the input-collection pause case rather than the user-confirm case.
251
+ *
252
+ * Identical shape to `PendingInput` (the wire payload) — alias kept for
253
+ * symmetry with `PendingAction` / "ActionState" naming elsewhere.
254
+ */
255
+ type PendingInputState = PendingInput;
256
+ /**
257
+ * Wire + state payload for a paused tool call awaiting user input.
258
+ *
259
+ * Carries BOTH the form-rendering fields (`inputId`, `schema`, etc) AND
260
+ * the conversation round-trip fields (`assistantContent`, `completedResults`)
261
+ * that the engine needs to atomically reconstruct the turn on resume.
262
+ *
263
+ * Hosts that store sessions across HTTP requests (e.g. audric) MUST
264
+ * persist the entire `PendingInput` payload — not just `inputId` — and
265
+ * pass it back as the first argument to `engine.resumeWithInput()`.
266
+ * Pattern mirrors `PendingAction.assistantContent` / `.completedResults`
267
+ * round-trip exactly.
268
+ *
269
+ * Why include the round-trip fields on the same payload:
270
+ * - Host's session schema only adds ONE new column for `pendingInput`
271
+ * (instead of two: one for the wire fields + one for round-trip state).
272
+ * - The engine API surface stays small — `resumeWithInput(pendingInput, values)`.
273
+ * - Audric's existing pattern for `pendingAction` is the same shape, so
274
+ * the reviewer can pattern-match.
275
+ *
276
+ * The host renderer ignores `assistantContent` / `completedResults` —
277
+ * they're opaque to the form UI. Only the engine reads them on resume.
278
+ */
279
+ interface PendingInput {
280
+ /** UUID v4 stamped per-emit. Host posts back keyed on this. */
281
+ inputId: string;
282
+ /** Tool that requested the input. Useful for host debug logs / fallback caption. */
283
+ toolName: string;
284
+ /** Original `tool_use_id` from the LLM's call — the resumed tool_result block uses this id. */
285
+ toolUseId: string;
286
+ /** Typed form schema — host renderer keys on `field.kind` per row. */
287
+ schema: FormSchema;
288
+ /** Optional human-readable description rendered above the form (e.g. "Add a new contact"). */
289
+ description?: string;
290
+ /**
291
+ * Assistant message blocks captured at pause time — the LLM's
292
+ * `tool_use` blocks (including the one that triggered this pause) plus
293
+ * any thinking / text blocks from the same turn. Pushed back to
294
+ * `messages` atomically on `resumeWithInput` so the conversation stays
295
+ * well-formed (no orphan tool_use blocks in the persisted history).
296
+ *
297
+ * Typed as `unknown[]` here to avoid pulling `ContentBlock` into
298
+ * `pending-input.ts` and creating a type-import cycle through `types.ts`.
299
+ * The engine casts to `ContentBlock[]` on resume; hosts treat as opaque.
300
+ */
301
+ assistantContent: unknown[];
302
+ /**
303
+ * Tool results from reads that completed BEFORE the paused tool call
304
+ * (same turn). On resume the engine merges these with the resumed
305
+ * tool's result into ONE `user`-role message — keeps Anthropic's
306
+ * "every tool_use must have a tool_result in the next user message"
307
+ * invariant satisfied.
308
+ */
309
+ completedResults: Array<{
310
+ toolUseId: string;
311
+ content: string;
312
+ isError: boolean;
313
+ }>;
314
+ }
315
+
156
316
  interface PendingToolCall {
157
317
  id: string;
158
318
  name: string;
@@ -192,6 +352,18 @@ interface GuardCheckResult {
192
352
  blockGate?: string;
193
353
  injections: GuardInjection[];
194
354
  events: GuardEvent[];
355
+ /**
356
+ * [SPEC 9 v0.1.3 P9.4] Set when the tool's preflight returned
357
+ * `needsInput` instead of either valid or error. The engine consults
358
+ * this BEFORE checking `blocked`: if present, the engine yields a
359
+ * `pending_input` event and pauses the turn. Distinct from `blocked`
360
+ * because the engine should NOT push a tool_result error back to the
361
+ * LLM — the turn is intentionally paused, not failed.
362
+ */
363
+ needsInput?: {
364
+ schema: FormSchema;
365
+ description?: string;
366
+ };
195
367
  }
196
368
  interface GuardEvent {
197
369
  timestamp: number;
@@ -786,6 +958,39 @@ type EngineEvent =
786
958
  | {
787
959
  type: 'compaction';
788
960
  }
961
+ /**
962
+ * [SPEC 9 v0.1.1 P9.2] Proactive insight emitted by the LLM via a
963
+ * `<proactive type="..." subjectKey="...">BODY</proactive>` wrapper in
964
+ * the final-text block. Engine fires this event AFTER the matching
965
+ * text_delta stream has finished, once `parseProactiveMarker` has
966
+ * extracted the marker at content_block_stop on the text block AND
967
+ * the per-session cooldown check has run.
968
+ *
969
+ * `suppressed === false` (cold marker, first time seen this session)
970
+ * → host applies the `✦ ADDED BY AUDRIC` lockup styling on the matching
971
+ * `text` TimelineBlock (italic body, dim border-left accent).
972
+ * `suppressed === true` (cooldown hit, same `(type, subjectKey)` already
973
+ * fired this session) → host strips the wrapper from the displayed
974
+ * text and renders as a regular text block — narrative still flows,
975
+ * the visual lockup just doesn't fire twice.
976
+ *
977
+ * In both cases the streamed `text_delta` events still contain the raw
978
+ * marker chars (the engine doesn't buffer-and-rewrite mid-stream); the
979
+ * host applies marker stripping post-hoc using `body` from this event.
980
+ * Hosts that ignore this event render markers visibly — acceptable for
981
+ * legacy hosts as a graceful fallback.
982
+ */
983
+ | {
984
+ type: 'proactive_text';
985
+ proactiveType: 'idle_balance' | 'hf_warning' | 'apy_drift' | 'goal_progress';
986
+ subjectKey: string;
987
+ /** Marker body, trimmed. Host renders this inside the lockup (or as plain text when suppressed). */
988
+ body: string;
989
+ /** True when (proactiveType, subjectKey) was already seen this session — host skips the lockup. */
990
+ suppressed: boolean;
991
+ /** Total marker count detected in the text. >1 = LLM violation; counted by the host telemetry. */
992
+ markerCount: number;
993
+ }
789
994
  /**
790
995
  * [SPEC 8 v0.5.1] Side-channel event paired to every `update_todo` tool
791
996
  * call. Hosts render the persistent todo card from this event (NOT from
@@ -823,21 +1028,62 @@ type EngineEvent =
823
1028
  pct?: number;
824
1029
  }
825
1030
  /**
826
- * [SPEC 8 v0.5.1, D2] Inline-form structured input event reserved for
827
- * SPEC 9 v0.1.2 (`pending_input` form primitive). The engine does NOT
828
- * emit this event under SPEC 8 — the type is reserved so legacy hosts
829
- * can add a no-op handler now and avoid crashing when SPEC 9 ships
830
- * `pending_input` emission. See SPEC 8 § "v0.5 cross-spec coupling
831
- * fixes" gap D2 for the forward-compat rationale.
1031
+ * [SPEC 9 v0.1.3 P9.4] Inline-form structured input event. Emitted when a
1032
+ * tool's preflight returns `needsInput` the engine pauses the turn,
1033
+ * stores the pending state on the QueryEngine instance keyed by `inputId`,
1034
+ * and waits for the host to call `engine.resumeWithInput(inputId, values)`
1035
+ * with the user's submitted form values. The schema is the typed shape
1036
+ * defined in `pending-input.ts` (closed list of field kinds).
1037
+ *
1038
+ * Upgraded from the SPEC 8 v0.5.1 D2 forward-compat reservation (which
1039
+ * carried `schema: unknown` + a `prompt?: string` placeholder). The
1040
+ * upgrade is wire-compatible: the new shape is a SUPERSET of the
1041
+ * reservation — `schema` narrows from `unknown` to `FormSchema`, and the
1042
+ * additional `toolName` / `toolUseId` / `description` fields are new.
1043
+ * Legacy hosts that no-op on `pending_input` keep working.
832
1044
  */
833
1045
  | {
834
1046
  type: 'pending_input';
835
- /** Form schema (shape locked in SPEC 9 v0.1.2; engine treats it opaquely). */
836
- schema: unknown;
837
- /** Engine round-trip identifier — host posts the answer back keyed on this. */
1047
+ /** UUID v4 stamped per-emit. Host posts back keyed on this. */
838
1048
  inputId: string;
839
- /** Optional human-readable prompt the LLM wants the host to display above the form. */
840
- prompt?: string;
1049
+ /** Tool that requested the input useful for host debug logs + fallback caption. */
1050
+ toolName: string;
1051
+ /** Original `tool_use_id` from the LLM's call — preserved for the resumed tool_result. */
1052
+ toolUseId: string;
1053
+ /** Form schema (typed — see `pending-input.ts`). */
1054
+ schema: FormSchema;
1055
+ /** Optional human-readable description rendered above the form (e.g. "Add a new contact"). */
1056
+ description?: string;
1057
+ /**
1058
+ * Assistant message blocks captured at pause time. Hosts that
1059
+ * re-instantiate `QueryEngine` per-request (e.g. audric) MUST
1060
+ * persist these alongside the rest of the `PendingInput` payload
1061
+ * and echo them back on `resumeWithInput` so the conversation
1062
+ * stays well-formed.
1063
+ *
1064
+ * Mirrors `pending_action.action.assistantContent` — same
1065
+ * round-trip pattern. In-process hosts can ignore the field
1066
+ * (the engine also stashes the state on `this.pendingInputs`
1067
+ * keyed by `inputId`).
1068
+ *
1069
+ * Typed as `unknown[]` to avoid pulling `ContentBlock` into
1070
+ * `pending-input.ts` and creating a type-import cycle.
1071
+ */
1072
+ assistantContent: unknown[];
1073
+ /**
1074
+ * Tool results from reads that completed BEFORE the paused tool
1075
+ * call (same turn). On resume the engine merges these with the
1076
+ * resumed tool's result into ONE `user`-role message — keeps
1077
+ * Anthropic's "every tool_use must have a tool_result in the next
1078
+ * user message" invariant satisfied.
1079
+ *
1080
+ * Mirrors the round-trip half of `PendingAction.completedResults`.
1081
+ */
1082
+ completedResults: Array<{
1083
+ toolUseId: string;
1084
+ content: string;
1085
+ isError: boolean;
1086
+ }>;
841
1087
  }
842
1088
  /**
843
1089
  * [SPEC 8 v0.5.1 B3.2] One-shot per-turn declaration of which adaptive
@@ -888,11 +1134,17 @@ declare function harnessShapeForEffort(effort: ThinkingEffort): HarnessShape;
888
1134
  * [SPEC 8 v0.5.1] One row in an `update_todo` payload. Mirrored from
889
1135
  * `packages/engine/src/tools/update-todo.ts`. Kept here so hosts that
890
1136
  * consume `EngineEvent` don't need to depend on the tool module.
1137
+ *
1138
+ * [SPEC 9 v0.1.3 P9.3] `persist?: boolean` — when true, hosts wired
1139
+ * for goal storage (audric) write a long-lived `Goal` row from this
1140
+ * item. Engine is unaware of how the host persists; this flag just
1141
+ * passes through on the `todo_update` side-channel event.
891
1142
  */
892
1143
  interface TodoItem$1 {
893
1144
  id: string;
894
1145
  label: string;
895
1146
  status: 'pending' | 'in_progress' | 'completed';
1147
+ persist?: boolean;
896
1148
  }
897
1149
  type StopReason = 'end_turn' | 'tool_use' | 'max_tokens' | 'max_turns' | 'error';
898
1150
  /**
@@ -1226,6 +1478,12 @@ type PreflightResult = {
1226
1478
  } | {
1227
1479
  valid: false;
1228
1480
  error: string;
1481
+ } | {
1482
+ valid: false;
1483
+ needsInput: {
1484
+ schema: FormSchema;
1485
+ description?: string;
1486
+ };
1229
1487
  };
1230
1488
  interface Tool<TInput = unknown, TOutput = unknown> {
1231
1489
  name: string;
@@ -1487,6 +1745,23 @@ type ProviderEvent = {
1487
1745
  } | {
1488
1746
  type: 'text_delta';
1489
1747
  text: string;
1748
+ }
1749
+ /**
1750
+ * [SPEC 9 v0.1.1 P9.2] Fired by the provider at content_block_stop on
1751
+ * a TEXT block when a `<proactive>` marker was detected in the
1752
+ * accumulated text. Carries the parsed marker payload so the engine
1753
+ * can run cooldown logic (per-session dedup) and emit the public
1754
+ * `proactive_text` engine event. Absent when no marker was found —
1755
+ * regular text turns don't pay the cost.
1756
+ *
1757
+ * The provider does NOT do the cooldown check (that's engine state);
1758
+ * it just parses + forwards. Pre-SPEC-9 hosts that handle provider
1759
+ * events directly will silently no-op on this event; the engine's
1760
+ * `handleProviderEvent` is the only consumer in production.
1761
+ */
1762
+ | {
1763
+ type: 'text_done';
1764
+ proactiveMarker?: ProactiveMarker;
1490
1765
  } | {
1491
1766
  type: 'tool_use_start';
1492
1767
  id: string;
@@ -1584,6 +1859,8 @@ declare class QueryEngine {
1584
1859
  private guardEvents;
1585
1860
  private readonly turnReadCache;
1586
1861
  private turnPaused;
1862
+ private readonly proactiveCooldown;
1863
+ private readonly pendingInputs;
1587
1864
  constructor(config: EngineConfig);
1588
1865
  /**
1589
1866
  * Submit a user message and stream engine events.
@@ -1613,6 +1890,37 @@ declare class QueryEngine {
1613
1890
  * This is a separate HTTP request — no persistent connection from submitMessage.
1614
1891
  */
1615
1892
  resumeWithToolResult(action: PendingAction, response: PermissionResponse): AsyncGenerator<EngineEvent>;
1893
+ /**
1894
+ * [SPEC 9 v0.1.3 P9.4] Resume a turn that paused on `pending_input`.
1895
+ *
1896
+ * Called by the host after the user submitted the inline form. The
1897
+ * `pendingInput` argument is the EXACT payload that was yielded as
1898
+ * `pending_input` (host stored it in session storage); `values` is the
1899
+ * `{ fieldName: value }` map the user submitted, post-host-validation
1900
+ * against `pendingInput.schema`.
1901
+ *
1902
+ * Engine responsibilities (in order):
1903
+ * 1. Push the captured `assistantContent` (assistant blocks from the
1904
+ * paused turn — includes the tool_use that triggered this pause).
1905
+ * 2. Run the paused tool's `call()` with `values` as input. Re-runs
1906
+ * preflight first as a defense-in-depth gate (host SHOULD have
1907
+ * validated against the schema, but malformed input would otherwise
1908
+ * poison the conversation history with an orphan tool_use).
1909
+ * 3. Combine `completedResults` (read tool_results that already ran in
1910
+ * the same turn before the pause) with the new tool_result into ONE
1911
+ * user-role message. Anthropic's API requires every tool_use to have
1912
+ * a tool_result in the immediately-following user message — splitting
1913
+ * them would produce two consecutive user messages, which the API
1914
+ * rejects.
1915
+ * 4. Yield `tool_result` for the host's timeline + run `agentLoop` to
1916
+ * continue the turn (LLM gets the resumed result and narrates).
1917
+ *
1918
+ * Mirrors `resumeWithToolResult` for the user-confirm case but feeds
1919
+ * the values back as the tool's INPUT (the call() runs here for the
1920
+ * first time) instead of as the tool's OUTPUT (the call() ran on the
1921
+ * client side via sponsored-tx for pending_action).
1922
+ */
1923
+ resumeWithInput(pendingInput: PendingInputState, values: Record<string, unknown>): AsyncGenerator<EngineEvent>;
1616
1924
  /**
1617
1925
  * [v1.5] Auto-run configured read tools after a successful write,
1618
1926
  * push their results into the conversation, and yield `tool_result`
@@ -1638,6 +1946,13 @@ declare class QueryEngine {
1638
1946
  reset(): void;
1639
1947
  getGuardEvents(): readonly GuardEvent[];
1640
1948
  loadMessages(messages: Message[]): void;
1949
+ /**
1950
+ * [SPEC 9 v0.1.1 P9.2 / R3] Walk loaded assistant text blocks and seed the
1951
+ * cooldown set with every parseable `(proactiveType, subjectKey)` tuple.
1952
+ * Called automatically from `loadMessages`. Idempotent — safe to call on
1953
+ * an already-populated set; duplicates are absorbed by Set semantics.
1954
+ */
1955
+ private rehydrateProactiveCooldown;
1641
1956
  /**
1642
1957
  * [v0.46.7] Run a read-only tool out-of-band, using the engine's tool
1643
1958
  * registry and ToolContext. Used by hosts to deterministically pre-dispatch
@@ -2038,6 +2353,22 @@ interface BuildToolOptions<TInput, TOutput> {
2038
2353
  jsonSchema: ToolJsonSchema;
2039
2354
  call: (input: TInput, context: ToolContext) => Promise<ToolResult<TOutput>>;
2040
2355
  isReadOnly?: boolean;
2356
+ /**
2357
+ * [SPEC 9 v0.1.3 P9.4] When `false`, the tool opts out of mid-stream
2358
+ * `EarlyToolDispatcher` execution and is forced through the post-stream
2359
+ * guard loop where `tool.preflight` runs (Tier 0 of `runGuards`).
2360
+ *
2361
+ * Default: `isReadOnly` (mirrors v1 behavior — read-only tools are
2362
+ * considered concurrency-safe by default).
2363
+ *
2364
+ * Set to `false` for read-only tools that need preflight before
2365
+ * executing. Notable example: `add_recipient` returns `needsInput`
2366
+ * from preflight to pause the turn for an inline form. If it ran
2367
+ * via early-dispatch, the tool's `call()` would fire BEFORE preflight
2368
+ * is consulted (early-dispatch skips the guard loop), and the form
2369
+ * pause path would be unreachable.
2370
+ */
2371
+ isConcurrencySafe?: boolean;
2041
2372
  permissionLevel?: PermissionLevel;
2042
2373
  flags?: ToolFlags;
2043
2374
  preflight?: (input: TInput) => PreflightResult;
@@ -2118,9 +2449,24 @@ type SSEEvent = {
2118
2449
  pct?: number;
2119
2450
  } | {
2120
2451
  type: 'pending_input';
2121
- schema: unknown;
2122
2452
  inputId: string;
2123
- prompt?: string;
2453
+ toolName: string;
2454
+ toolUseId: string;
2455
+ schema: FormSchema;
2456
+ description?: string;
2457
+ assistantContent: unknown[];
2458
+ completedResults: Array<{
2459
+ toolUseId: string;
2460
+ content: string;
2461
+ isError: boolean;
2462
+ }>;
2463
+ } | {
2464
+ type: 'proactive_text';
2465
+ proactiveType: ProactiveType;
2466
+ subjectKey: string;
2467
+ body: string;
2468
+ suppressed: boolean;
2469
+ markerCount: number;
2124
2470
  } | {
2125
2471
  type: 'harness_shape';
2126
2472
  shape: HarnessShape;
@@ -2940,9 +3286,9 @@ declare const ratesInfoTool: Tool<{
2940
3286
  }, RateMap>;
2941
3287
 
2942
3288
  declare const transactionHistoryTool: Tool<{
3289
+ date?: string | undefined;
2943
3290
  action?: "send" | "swap" | "transaction" | "lending" | undefined;
2944
3291
  address?: string | undefined;
2945
- date?: string | undefined;
2946
3292
  limit?: number | undefined;
2947
3293
  direction?: "out" | "in" | undefined;
2948
3294
  counterparty?: string | undefined;
@@ -3283,40 +3629,48 @@ declare const todoItemSchema: z.ZodObject<{
3283
3629
  id: z.ZodString;
3284
3630
  label: z.ZodString;
3285
3631
  status: z.ZodEnum<["pending", "in_progress", "completed"]>;
3632
+ persist: z.ZodOptional<z.ZodBoolean>;
3286
3633
  }, "strip", z.ZodTypeAny, {
3287
3634
  label: string;
3288
3635
  status: "pending" | "in_progress" | "completed";
3289
3636
  id: string;
3637
+ persist?: boolean | undefined;
3290
3638
  }, {
3291
3639
  label: string;
3292
3640
  status: "pending" | "in_progress" | "completed";
3293
3641
  id: string;
3642
+ persist?: boolean | undefined;
3294
3643
  }>;
3295
3644
  declare const inputSchema: z.ZodObject<{
3296
3645
  items: z.ZodArray<z.ZodObject<{
3297
3646
  id: z.ZodString;
3298
3647
  label: z.ZodString;
3299
3648
  status: z.ZodEnum<["pending", "in_progress", "completed"]>;
3649
+ persist: z.ZodOptional<z.ZodBoolean>;
3300
3650
  }, "strip", z.ZodTypeAny, {
3301
3651
  label: string;
3302
3652
  status: "pending" | "in_progress" | "completed";
3303
3653
  id: string;
3654
+ persist?: boolean | undefined;
3304
3655
  }, {
3305
3656
  label: string;
3306
3657
  status: "pending" | "in_progress" | "completed";
3307
3658
  id: string;
3659
+ persist?: boolean | undefined;
3308
3660
  }>, "many">;
3309
3661
  }, "strip", z.ZodTypeAny, {
3310
3662
  items: {
3311
3663
  label: string;
3312
3664
  status: "pending" | "in_progress" | "completed";
3313
3665
  id: string;
3666
+ persist?: boolean | undefined;
3314
3667
  }[];
3315
3668
  }, {
3316
3669
  items: {
3317
3670
  label: string;
3318
3671
  status: "pending" | "in_progress" | "completed";
3319
3672
  id: string;
3673
+ persist?: boolean | undefined;
3320
3674
  }[];
3321
3675
  }>;
3322
3676
  type TodoItem = z.infer<typeof todoItemSchema>;
@@ -3326,6 +3680,7 @@ declare const updateTodoTool: Tool<{
3326
3680
  label: string;
3327
3681
  status: "pending" | "in_progress" | "completed";
3328
3682
  id: string;
3683
+ persist?: boolean | undefined;
3329
3684
  }[];
3330
3685
  }, {
3331
3686
  __todoUpdate: boolean;
@@ -3333,9 +3688,19 @@ declare const updateTodoTool: Tool<{
3333
3688
  label: string;
3334
3689
  status: "pending" | "in_progress" | "completed";
3335
3690
  id: string;
3691
+ persist?: boolean | undefined;
3336
3692
  }[];
3337
3693
  }>;
3338
3694
 
3695
+ declare const addRecipientTool: Tool<{
3696
+ name?: string | undefined;
3697
+ identifier?: string | undefined;
3698
+ }, {
3699
+ saved: boolean;
3700
+ name: string;
3701
+ identifier: string;
3702
+ }>;
3703
+
3339
3704
  declare const tokenPricesTool: Tool<{
3340
3705
  coinTypes: string[];
3341
3706
  include24hChange?: boolean | undefined;
@@ -3838,7 +4203,7 @@ declare function fetchAudricHistory(address: string, opts: {
3838
4203
  limit?: number;
3839
4204
  }, env?: Record<string, string>, signal?: AbortSignal): Promise<AudricHistoryRecord[] | null>;
3840
4205
 
3841
- declare const DEFAULT_SYSTEM_PROMPT = "You are Audric \u2014 a financial agent on Sui. Audric is exactly five products: Audric Passport (the trust layer \u2014 Google sign-in, non-custodial wallet, tap-to-confirm consent, sponsored gas \u2014 wraps every other product), Audric Intelligence (you \u2014 the 5-system brain: Agent Harness with 34 tools, Reasoning Engine with 14 guards and 6 skill recipes, Silent Profile, Chain Memory, AdviceLog), Audric Finance (manage money on Sui \u2014 Save via NAVI lending at 3-8% APY USDC, Credit via NAVI borrowing with health factor, Swap via Cetus aggregator across 20+ DEXs at 0.1% fee, Charts for yield/health/portfolio viz), Audric Pay (move money \u2014 send USDC, receive via payment links / invoices / QR; free, global, instant on Sui), and Audric Store (creator marketplace, ships Phase 5 \u2014 say \"coming soon\" if asked). Save, swap, borrow, repay, withdraw, charts \u2192 Audric Finance. Send, receive, payment-link, invoice, QR \u2192 Audric Pay. Your silent context (profile, memory, chain facts, advice log) shapes your replies but never surfaces as a notification \u2014 you act only when the user asks, and every write waits on their tap-to-confirm via Passport. You can also call 41 paid APIs (music, image, research, translation, weather, fulfilment) via MPP micropayments using the pay_api tool \u2014 this is an internal capability, not a promoted product, so only mention it when the user asks for something that needs it.\n\n## Response rules\n- 1-2 sentences max. No bullet lists unless asked. No preambles.\n- Never say \"Would you like me to...\", \"Sure!\", \"Great question!\", \"Absolutely!\" \u2014 just do it or say you can't.\n- Present amounts as $1,234.56 and rates as X.XX% APY.\n- Show top 3 results unless asked for more. Summarize totals in one line.\n\n## Caption rules (after tool calls)\n- **When a canvas was rendered (`render_canvas` was called, or any tool that auto-renders a card like balance_check / portfolio_analysis / savings_info / health_check / transaction_history): the canvas IS the answer.** Your chat message must NOT restate wallet, savings, debt, holdings, or net-worth numbers \u2014 they are already on screen. Add at most ONE sentence of context, advice, or next step (e.g. \"Your USDC is idle \u2014 consider depositing for ~4.5% APY\"), or say nothing.\n- **When NO canvas was rendered:** lead with the result and quote the actual numbers from the tool. One sentence.\n- **NEVER describe a position as \"no\", \"none\", \"minimal\", \"zero\", or \"inactive\" if the tool result contains a positive value for that field.** The tool result is the source of truth \u2014 never your interior summary. If the canvas shows $100 in savings, you cannot say \"no active savings\" in the caption.\n- **NEVER claim \"no DeFi positions\" when the tool result says the DeFi slice is UNAVAILABLE.** When `balance_check` displayText contains \"DeFi positions: UNAVAILABLE\" or \"DeFi data source unreachable\", the slice is unknown \u2014 say \"DeFi data is currently unavailable\" or omit the mention. Only claim \"no DeFi positions\" when the displayText explicitly omits any DeFi line (i.e. the fetch succeeded with $0 across every covered protocol).\n\n## Execution rule\nOnly offer to execute actions you have tools for. If you retrieved a quote, data, or information but have no tool to act on it, give the user the result and tell them where to execute manually \u2014 in one sentence. Never say \"Would you like me to proceed?\" unless you have a tool that can actually proceed.\n\n## Before acting\n- ALWAYS call a read tool first before any write tool \u2014 balance_check before save/send/borrow, savings_info before withdraw.\n- Show real numbers from tools \u2014 never fabricate rates, amounts, or balances.\n- When user says \"all\" or an imprecise amount, call the read tool first to get the exact number.\n\n## Tool usage\n- Use tools proactively \u2014 don't refuse requests you can handle.\n- For real-world questions (weather, search, news, prices), use pay_api. Tell the user the cost first.\n- For NAVI lending APYs, use rates_info; for VOLO liquid staking stats, use volo_stats; for spot token prices, use token_prices.\n- For protocol-level due diligence (TVL, fees, audits, safety) on Sui DeFi protocols, use protocol_deep_dive with the slug.\n- Run multiple read-only tools in parallel when you need several data points.\n- If a tool errors, say what went wrong and what to try instead. One sentence.\n\n## Savings = USDC or USDsui (critical)\n- save_deposit and borrow accept ONLY USDC or USDsui. No other token can be deposited or borrowed.\n- USDC is the canonical default. USDsui is permitted because it has a productive NAVI pool (often a higher APY than USDC). All other holdings (GOLD, SUI, USDT, USDe, ETH, NAVX, WAL) are NOT saveable.\n- When asked \"how much can I save?\":\n - Report saveableUsdc from balance_check (the user's USDC wallet balance \u2014 canonical saveable).\n - If the user also holds USDsui in their wallet, report that separately as \"USDsui (saveable): X.XX\". Do NOT roll the two together \u2014 the LLM must keep the per-asset distinction so the user can pick.\n- When the user says \"save 10 USDC\" \u2192 call save_deposit with asset=\"USDC\". When they say \"save 10 USDsui\" \u2192 call with asset=\"USDsui\". Never silently substitute.\n- When the user says \"save 10\" (no asset) \u2192 call balance_check first and ask which stable they want, OR pick whichever they hold more of with a one-line explanation.\n- \"Best stable to save right now?\" \u2192 call rates_info to compare USDC vs USDsui APY on NAVI; let the user pick.\n- NEVER say a non-saveable token (GOLD, SUI, USDT, etc.) is \"in savings\" or \"earning APY in savings\". Wallet holdings \u2260 savings positions, even for stables we don't accept.\n- If user wants to save a non-saveable token, tell them to swap to USDC or USDsui first. Do NOT auto-chain swap + deposit.\n- Repay symmetry: a USDsui debt MUST be repaid with USDsui (and USDC debt with USDC). When calling repay_debt, pass asset=\"USDsui\" if the borrow is USDsui. If the user asks \"repay my debt\" and savings_info shows borrows in BOTH stables, list both and ask which to repay first. If the user holds the wrong stable, tell them to swap manually \u2014 do NOT auto-chain swap + repay.\n\n## Fees (critical \u2014 never deny having fees)\n- **Swap:** 0.1% Audric overlay fee on the output amount, taken by the aggregator and sent to the Audric treasury. The Cetus DEX fee (typically 0.01\u20130.25%) is separate and goes to the DEX. Both are shown on the swap card. Never say Audric takes no cut on swaps \u2014 it does.\n- **Save (deposit):** 0.1% Audric fee on the deposit amount, taken atomically in the same transaction.\n- **Borrow:** 0.05% Audric fee on the borrow amount, taken atomically in the same transaction.\n- **Withdraw / Repay / Send / Receive:** No Audric fee. Gas is sponsored (free to the user).\n- When a user asks about fees, quote the above. Do NOT say \"I don't take a cut\", \"fees are zero\", \"all your value stays with you\", or \"I'm here to execute, not extract\" \u2014 those are incorrect for swap, save, and borrow.\n\n## Multi-step flows\n- \"How much X for Y?\": swap_quote first, then swap_execute if user confirms.\n- \"Swap then save\": swap_execute \u2192 balance_check \u2192 save_deposit. Confirm each step.\n- \"Buy $X of token\": token_prices \u2192 calculate amount \u2192 swap_execute.\n- \"Best yield on SUI\": compare rates_info (NAVI lending) + volo_stats (vSUI liquid staking).\n- withdraw supports legacy positions: USDC, USDe, USDsui, SUI. Pass asset param to withdraw a specific token.\n- \"Deposit SUI to earn yield\": volo_stake for SUI liquid staking. save_deposit only accepts USDC or USDsui.\n- \"Is protocol X safe?\" / \"Tell me about NAVI\": protocol_deep_dive with the slug.\n- \"Full account report\" / \"account summary\" / \"give me everything\" / \"complete overview\": triggers the `account_report` recipe \u2014 when the recipe block appears, follow EVERY step including all six tool calls. Each step renders a distinct rich card; skipping a step means a missing card.\n\n## Safety\n- Never encourage risky financial behavior.\n- Warn when health factor < 1.5.\n- All amounts in USDC unless stated otherwise.";
4206
+ declare const DEFAULT_SYSTEM_PROMPT = "You are Audric \u2014 a financial agent on Sui. Audric is exactly five products: Audric Passport (the trust layer \u2014 Google sign-in, non-custodial wallet, tap-to-confirm consent, sponsored gas \u2014 wraps every other product), Audric Intelligence (you \u2014 the 5-system brain: Agent Harness with 34 tools, Reasoning Engine with 14 guards and 6 skill recipes, Silent Profile, Chain Memory, AdviceLog), Audric Finance (manage money on Sui \u2014 Save via NAVI lending at 3-8% APY USDC, Credit via NAVI borrowing with health factor, Swap via Cetus aggregator across 20+ DEXs at 0.1% fee, Charts for yield/health/portfolio viz), Audric Pay (move money \u2014 send USDC, receive via payment links / invoices / QR; free, global, instant on Sui), and Audric Store (creator marketplace, ships Phase 5 \u2014 say \"coming soon\" if asked). Save, swap, borrow, repay, withdraw, charts \u2192 Audric Finance. Send, receive, payment-link, invoice, QR \u2192 Audric Pay. Your silent context (profile, memory, chain facts, advice log) shapes your replies but never surfaces as a notification \u2014 you act only when the user asks, and every write waits on their tap-to-confirm via Passport. You can also call 41 paid APIs (music, image, research, translation, weather, fulfilment) via MPP micropayments using the pay_api tool \u2014 this is an internal capability, not a promoted product, so only mention it when the user asks for something that needs it.\n\n## Response rules\n- 1-2 sentences max. No bullet lists unless asked. No preambles.\n- Never say \"Would you like me to...\", \"Sure!\", \"Great question!\", \"Absolutely!\" \u2014 just do it or say you can't.\n- Present amounts as $1,234.56 and rates as X.XX% APY.\n- Show top 3 results unless asked for more. Summarize totals in one line.\n\n## Caption rules (after tool calls)\n- **When a canvas was rendered (`render_canvas` was called, or any tool that auto-renders a card like balance_check / portfolio_analysis / savings_info / health_check / transaction_history): the canvas IS the answer.** Your chat message must NOT restate wallet, savings, debt, holdings, or net-worth numbers \u2014 they are already on screen. Add at most ONE sentence of context, advice, or next step (e.g. \"Your USDC is idle \u2014 consider depositing for ~4.5% APY\"), or say nothing.\n- **When NO canvas was rendered:** lead with the result and quote the actual numbers from the tool. One sentence.\n- **NEVER describe a position as \"no\", \"none\", \"minimal\", \"zero\", or \"inactive\" if the tool result contains a positive value for that field.** The tool result is the source of truth \u2014 never your interior summary. If the canvas shows $100 in savings, you cannot say \"no active savings\" in the caption.\n- **NEVER claim \"no DeFi positions\" when the tool result says the DeFi slice is UNAVAILABLE.** When `balance_check` displayText contains \"DeFi positions: UNAVAILABLE\" or \"DeFi data source unreachable\", the slice is unknown \u2014 say \"DeFi data is currently unavailable\" or omit the mention. Only claim \"no DeFi positions\" when the displayText explicitly omits any DeFi line (i.e. the fetch succeeded with $0 across every covered protocol).\n\n## Execution rule\nOnly offer to execute actions you have tools for. If you retrieved a quote, data, or information but have no tool to act on it, give the user the result and tell them where to execute manually \u2014 in one sentence. Never say \"Would you like me to proceed?\" unless you have a tool that can actually proceed.\n\n## Before acting\n- ALWAYS call a read tool first before any write tool \u2014 balance_check before save/send/borrow, savings_info before withdraw.\n- Show real numbers from tools \u2014 never fabricate rates, amounts, or balances.\n- When user says \"all\" or an imprecise amount, call the read tool first to get the exact number.\n\n## Tool usage\n- Use tools proactively \u2014 don't refuse requests you can handle.\n- For real-world questions (weather, search, news, prices), use pay_api. Tell the user the cost first.\n- For NAVI lending APYs, use rates_info; for VOLO liquid staking stats, use volo_stats; for spot token prices, use token_prices.\n- For protocol-level due diligence (TVL, fees, audits, safety) on Sui DeFi protocols, use protocol_deep_dive with the slug.\n- Run multiple read-only tools in parallel when you need several data points.\n- If a tool errors, say what went wrong and what to try instead. One sentence.\n\n## Savings = USDC or USDsui (critical)\n- save_deposit and borrow accept ONLY USDC or USDsui. No other token can be deposited or borrowed.\n- USDC is the canonical default. USDsui is permitted because it has a productive NAVI pool (often a higher APY than USDC). All other holdings (GOLD, SUI, USDT, USDe, ETH, NAVX, WAL) are NOT saveable.\n- When asked \"how much can I save?\":\n - Report saveableUsdc from balance_check (the user's USDC wallet balance \u2014 canonical saveable).\n - If the user also holds USDsui in their wallet, report that separately as \"USDsui (saveable): X.XX\". Do NOT roll the two together \u2014 the LLM must keep the per-asset distinction so the user can pick.\n- When the user says \"save 10 USDC\" \u2192 call save_deposit with asset=\"USDC\". When they say \"save 10 USDsui\" \u2192 call with asset=\"USDsui\". Never silently substitute.\n- When the user says \"save 10\" (no asset) \u2192 call balance_check first and ask which stable they want, OR pick whichever they hold more of with a one-line explanation.\n- \"Best stable to save right now?\" \u2192 call rates_info to compare USDC vs USDsui APY on NAVI; let the user pick.\n- NEVER say a non-saveable token (GOLD, SUI, USDT, etc.) is \"in savings\" or \"earning APY in savings\". Wallet holdings \u2260 savings positions, even for stables we don't accept.\n- If user wants to save a non-saveable token, tell them to swap to USDC or USDsui first. Do NOT auto-chain swap + deposit.\n- Repay symmetry: a USDsui debt MUST be repaid with USDsui (and USDC debt with USDC). When calling repay_debt, pass asset=\"USDsui\" if the borrow is USDsui. If the user asks \"repay my debt\" and savings_info shows borrows in BOTH stables, list both and ask which to repay first. If the user holds the wrong stable, tell them to swap manually \u2014 do NOT auto-chain swap + repay.\n\n## Fees (critical \u2014 never deny having fees)\n- **Swap:** 0.1% Audric overlay fee on the output amount, taken by the aggregator and sent to the Audric treasury. The Cetus DEX fee (typically 0.01\u20130.25%) is separate and goes to the DEX. Both are shown on the swap card. Never say Audric takes no cut on swaps \u2014 it does.\n- **Save (deposit):** 0.1% Audric fee on the deposit amount, taken atomically in the same transaction.\n- **Borrow:** 0.05% Audric fee on the borrow amount, taken atomically in the same transaction.\n- **Withdraw / Repay / Send / Receive:** No Audric fee. Gas is sponsored (free to the user).\n- When a user asks about fees, quote the above. Do NOT say \"I don't take a cut\", \"fees are zero\", \"all your value stays with you\", or \"I'm here to execute, not extract\" \u2014 those are incorrect for swap, save, and borrow.\n\n## Multi-step flows\n- \"How much X for Y?\": swap_quote first, then swap_execute if user confirms.\n- \"Swap then save\": swap_execute \u2192 balance_check \u2192 save_deposit. Confirm each step.\n- \"Buy $X of token\": token_prices \u2192 calculate amount \u2192 swap_execute.\n- \"Best yield on SUI\": compare rates_info (NAVI lending) + volo_stats (vSUI liquid staking).\n- withdraw supports legacy positions: USDC, USDe, USDsui, SUI. Pass asset param to withdraw a specific token.\n- \"Deposit SUI to earn yield\": volo_stake for SUI liquid staking. save_deposit only accepts USDC or USDsui.\n- \"Is protocol X safe?\" / \"Tell me about NAVI\": protocol_deep_dive with the slug.\n- \"Full account report\" / \"account summary\" / \"give me everything\" / \"complete overview\": triggers the `account_report` recipe \u2014 when the recipe block appears, follow EVERY step including all six tool calls. Each step renders a distinct rich card; skipping a step means a missing card.\n\n## Safety\n- Never encourage risky financial behavior.\n- Warn when health factor < 1.5.\n- All amounts in USDC unless stated otherwise.\n\n## Proactive insights (only when there's a clear opportunity)\n- When you spot a financial insight worth surfacing \u2014 idle balance worth saving, health factor approaching the warning band, APY drift on a known position, progress against a saved goal \u2014 emit a `<proactive type=\"...\" subjectKey=\"...\">BODY</proactive>` block. ALWAYS use the wrapper \u2014 plain-text proactive prose without the wrapper renders as regular text and skips the engine's per-session cooldown (the same nudge will then re-fire every turn).\n- Two valid placements \u2014 pick whichever fits the turn:\n - **No user question** (or the question is unrelated to the insight): wrap your ENTIRE response in the `<proactive>` block.\n - **You're answering a user question AND have a related insight to add**: answer the question normally, then APPEND the `<proactive>` block at the end, separated by a line break. The \"after the answer\" form is also taught in detail under \u00A7 Proactive Awareness \u2014 same syntax, both placements valid.\n- The host renders the wrapped block with a distinct \"\u2726 ADDED BY AUDRIC\" lockup so the user knows this is your suggestion, not an answer.\n- Allowed types (closed list \u2014 anything else is dropped): `idle_balance` (cash sitting idle that could earn yield), `hf_warning` (debt position approaching liquidation), `apy_drift` (rate change on a position they hold), `goal_progress` (update on a saved goal).\n- `subjectKey` is a stable identifier for the SPECIFIC subject \u2014 examples: `USDC` for an idle-balance insight on USDC, `1.45` for a HF warning at that level, `save-500-by-may` for goal progress. Same (type, subjectKey) won't fire twice in one session \u2014 pick the same key for the same subject so the engine cooldown works.\n- Cap: at most ONE proactive block per turn.\n- Skip proactive blocks when nothing notable changed since the last turn, when the user is mid-flow on something else, or when you'd just be restating the financial-context block. Quality over quantity \u2014 a block ignored is worse than no block.";
3842
4207
 
3843
4208
  /** Cache entry shape. `cachedAt` is the wall-clock ms at write time. */
3844
4209
  interface NaviCacheEntry {
@@ -3921,4 +4286,4 @@ declare function getTelemetrySink(): TelemetrySink;
3921
4286
  /** Restore the default noop sink. Used by test teardowns. */
3922
4287
  declare function resetTelemetrySink(): void;
3923
4288
 
3924
- export { type AddressPortfolio, AnthropicProvider, type AnthropicProviderConfig, type AudricHistoryRecord, type AudricPortfolioResult, type AwaitOrFetchOpts, type BalancePrices, type BalanceResult, BalanceTracker, type BuildToolOptions, type BundleCompositionInput, CANVAS_TEMPLATES, type CanvasTemplate, type ChatParams, type CompactOptions, type ContentBlock, ContextBudget, type ContextBudgetConfig, type ConversationState, type ConversationStateStore, type CostSnapshot, CostTracker, type CostTrackerConfig, DEFAULT_GUARD_CONFIG, DEFAULT_LEASE_SEC, DEFAULT_PERMISSION_CONFIG, DEFAULT_POLL_BUDGET_MS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SYSTEM_PROMPT, DEFAULT_TOOL_TTL_MS, type DefiCacheEntry, type DefiCacheStore, type DefiProtocol, type DefiSummary, EFFORT_THINKING_BUDGET_CAPS, EarlyToolDispatcher, type EngineConfig, type EngineEvent, type EvalSummaryParseResult, type EvaluationItem, type EvaluationStatus, type FetchLock, type GuardCheckResult, type GuardConfig, type GuardEvent, type GuardInjection, type GuardResult, type GuardRunnerState, type GuardTier, type GuardVerdict, type HarnessShape, type HealthFactorResult, InMemoryDefiCacheStore, InMemoryFetchLock, InMemoryNaviCacheStore, InMemoryWalletCacheStore, InvalidAddressError, type LLMProvider, MAX_BUNDLE_OPS, type McpCallResult, McpClientManager, McpResponseCache, type McpServerConfig, type McpServerConnection, type McpToolAdapterConfig, type McpToolDescriptor, MemorySessionStore, type Message, NAVI_ADDR_TTL_SEC, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_RATES_TTL_SEC, NAVI_SERVER_NAME, type NaviCacheEntry, type NaviCacheStore, type NaviRawCoin, type NaviRawHealthFactor, type NaviRawPool, type NaviRawPosition, type NaviRawPositionsResponse, type NaviRawProtocolStats, type NaviRawRewardsResponse, type NaviReadOptions, NaviTools, type NormalizedAddress, type OutputConfig, PERMISSION_PRESETS, type PendingAction, type PendingActionModifiableField, type PendingActionStep, type PendingReward, type PendingToolCall, type PermissionLevel, type PermissionOperation, type PermissionResponse, type PermissionRule, type PortfolioCoin, type PositionEntry, type PreflightResult, type ProtocolStats, type ProviderEvent, QueryEngine, READ_TOOLS, REGENERATABLE_READ_TOOLS, type RatesResult, type Recipe, type RecipePrerequisite, RecipeRegistry, type RecipeStep, type RecipeStepOnError, type RegenerateFailure, type RegenerateResult, type RegenerateSuccess, type RegenerateTimelineEvent, RetryTracker, type SSEEvent, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, type SavingsResult, type ServerPositionData, type SessionData, type SessionStore, type StateType, type StopReason, type SuiCoinBalance, SuinsNotRegisteredError, SuinsRpcError, type SystemBlock, type SystemPrompt, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TOOL_TTL_MS, type TelemetrySink, type TelemetryTags, type ThinkingConfig, type ThinkingEffort, type TodoItem$1 as TodoItem, type Tool, type ToolChoice, type ToolContext, type ToolDefinition, type ToolFlags, type ToolJsonSchema, type ToolResult, TxMutex, type UpdateTodoInput, type TodoItem as UpdateTodoItem, type UserFinancialProfile, type UserPermissionConfig, VALID_PAIRS, WRITE_TOOLS, type WalletCacheEntry, type WalletCacheStore, type WalletCoin, _resetNaviCircuitBreaker, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, bundleShortestTtl, checkValidPair, claimRewardsTool, clampThinkingForEffort, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, composeBundleFromToolResults, computeRegenerateFields, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAddressDefiPortfolio, fetchAddressPortfolio, fetchAudricHistory, fetchAudricPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getAudricApiBase, getDefaultTools, getDefiCacheStore, getFetchLock, getMcpManager, getModifiableFields, getNaviCacheStore, getTelemetrySink, getToolFlags, getWalletAddress, getWalletCacheStore, guardArtifactPreview, guardStaleData, harnessShapeForEffort, hasNaviMcp, healthCheckTool, isBundleableTool, loadRecipes, looksLikeSuiNs, microcompact, mppServicesTool, naviKey, normalizeAddressInput, parseEvalSummary, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, regenerateBundle, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resetDefiCacheStore, resetFetchLock, resetNaviCacheStore, resetTelemetrySink, resetWalletCacheStore, resolveAddressToSuinsViaRpc, resolvePermissionTier, resolveSuinsTool, resolveSuinsViaRpc, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, setDefiCacheStore, setFetchLock, setNaviCacheStore, setTelemetrySink, setWalletCacheStore, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, updateTodoTool, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
4289
+ export { type AddressPortfolio, AnthropicProvider, type AnthropicProviderConfig, type AudricHistoryRecord, type AudricPortfolioResult, type AwaitOrFetchOpts, type BalancePrices, type BalanceResult, BalanceTracker, type BuildToolOptions, type BundleCompositionInput, CANVAS_TEMPLATES, type CanvasTemplate, type ChatParams, type CompactOptions, type ContentBlock, ContextBudget, type ContextBudgetConfig, type ConversationState, type ConversationStateStore, type CostSnapshot, CostTracker, type CostTrackerConfig, DEFAULT_GUARD_CONFIG, DEFAULT_LEASE_SEC, DEFAULT_PERMISSION_CONFIG, DEFAULT_POLL_BUDGET_MS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SYSTEM_PROMPT, DEFAULT_TOOL_TTL_MS, type DefiCacheEntry, type DefiCacheStore, type DefiProtocol, type DefiSummary, EFFORT_THINKING_BUDGET_CAPS, EarlyToolDispatcher, type EngineConfig, type EngineEvent, type EvalSummaryParseResult, type EvaluationItem, type EvaluationStatus, type FetchLock, type FormField, type FormFieldKind, type FormSchema, type GuardCheckResult, type GuardConfig, type GuardEvent, type GuardInjection, type GuardResult, type GuardRunnerState, type GuardTier, type GuardVerdict, type HarnessShape, type HealthFactorResult, InMemoryDefiCacheStore, InMemoryFetchLock, InMemoryNaviCacheStore, InMemoryWalletCacheStore, InvalidAddressError, type LLMProvider, MAX_BUNDLE_OPS, type McpCallResult, McpClientManager, McpResponseCache, type McpServerConfig, type McpServerConnection, type McpToolAdapterConfig, type McpToolDescriptor, MemorySessionStore, type Message, NAVI_ADDR_TTL_SEC, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_RATES_TTL_SEC, NAVI_SERVER_NAME, type NaviCacheEntry, type NaviCacheStore, type NaviRawCoin, type NaviRawHealthFactor, type NaviRawPool, type NaviRawPosition, type NaviRawPositionsResponse, type NaviRawProtocolStats, type NaviRawRewardsResponse, type NaviReadOptions, NaviTools, type NormalizedAddress, type OutputConfig, PERMISSION_PRESETS, type PendingAction, type PendingActionModifiableField, type PendingActionStep, type PendingInput, type PendingInputState, type PendingReward, type PendingToolCall, type PermissionLevel, type PermissionOperation, type PermissionResponse, type PermissionRule, type PortfolioCoin, type PositionEntry, type PreflightResult, type ProactiveMarker, type ProactiveType, type ProtocolStats, type ProviderEvent, QueryEngine, READ_TOOLS, REGENERATABLE_READ_TOOLS, type RatesResult, type Recipe, type RecipePrerequisite, RecipeRegistry, type RecipeStep, type RecipeStepOnError, type RegenerateFailure, type RegenerateResult, type RegenerateSuccess, type RegenerateTimelineEvent, RetryTracker, type SSEEvent, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, type SavingsResult, type ServerPositionData, type SessionData, type SessionStore, type StateType, type StopReason, type SuiCoinBalance, SuinsNotRegisteredError, SuinsRpcError, type SystemBlock, type SystemPrompt, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TOOL_TTL_MS, type TelemetrySink, type TelemetryTags, type ThinkingConfig, type ThinkingEffort, type TodoItem$1 as TodoItem, type Tool, type ToolChoice, type ToolContext, type ToolDefinition, type ToolFlags, type ToolJsonSchema, type ToolResult, TxMutex, type UpdateTodoInput, type TodoItem as UpdateTodoItem, type UserFinancialProfile, type UserPermissionConfig, VALID_PAIRS, WRITE_TOOLS, type WalletCacheEntry, type WalletCacheStore, type WalletCoin, _resetNaviCircuitBreaker, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, addRecipientTool, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, bundleShortestTtl, checkValidPair, claimRewardsTool, clampThinkingForEffort, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, composeBundleFromToolResults, computeRegenerateFields, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractAllProactiveMarkers, extractConversationText, extractMcpText, fetchAddressDefiPortfolio, fetchAddressPortfolio, fetchAudricHistory, fetchAudricPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getAudricApiBase, getDefaultTools, getDefiCacheStore, getFetchLock, getMcpManager, getModifiableFields, getNaviCacheStore, getTelemetrySink, getToolFlags, getWalletAddress, getWalletCacheStore, guardArtifactPreview, guardStaleData, harnessShapeForEffort, hasNaviMcp, healthCheckTool, isBundleableTool, loadRecipes, looksLikeSuiNs, microcompact, mppServicesTool, naviKey, normalizeAddressInput, parseEvalSummary, parseMcpJson, parseProactiveMarker, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, regenerateBundle, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resetDefiCacheStore, resetFetchLock, resetNaviCacheStore, resetTelemetrySink, resetWalletCacheStore, resolveAddressToSuinsViaRpc, resolvePermissionTier, resolveSuinsTool, resolveSuinsViaRpc, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, setDefiCacheStore, setFetchLock, setNaviCacheStore, setTelemetrySink, setWalletCacheStore, spendingAnalyticsTool, stripProactiveMarkers, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, updateTodoTool, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };