@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 +381 -16
- package/dist/index.js +469 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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
|
|
827
|
-
*
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
*
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
840
|
-
|
|
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
|
-
|
|
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 };
|