@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.js
CHANGED
|
@@ -19,7 +19,7 @@ function buildTool(opts) {
|
|
|
19
19
|
jsonSchema: opts.jsonSchema,
|
|
20
20
|
call: opts.call,
|
|
21
21
|
isReadOnly,
|
|
22
|
-
isConcurrencySafe: isReadOnly,
|
|
22
|
+
isConcurrencySafe: opts.isConcurrencySafe ?? isReadOnly,
|
|
23
23
|
permissionLevel: opts.permissionLevel ?? (isReadOnly ? "auto" : "confirm"),
|
|
24
24
|
flags: opts.flags ?? {},
|
|
25
25
|
preflight: opts.preflight,
|
|
@@ -5171,14 +5171,22 @@ var todoStatusSchema = z.enum(["pending", "in_progress", "completed"]);
|
|
|
5171
5171
|
var todoItemSchema = z.object({
|
|
5172
5172
|
id: z.string().min(1, "id must be a non-empty string").max(40, "id must be \u226440 chars (use a slug, not a sentence)"),
|
|
5173
5173
|
label: z.string().min(1, "label must be a non-empty string").max(80, "label must be \u226480 chars (the whole point of this tool is concision)"),
|
|
5174
|
-
status: todoStatusSchema
|
|
5174
|
+
status: todoStatusSchema,
|
|
5175
|
+
// [SPEC 9 v0.1.3 P9.3] Per-item persistence flag — opt this todo item
|
|
5176
|
+
// into the long-lived `Goal` row surface. Hosts that wire goal storage
|
|
5177
|
+
// (audric) write a Goal row with `content: label`, `status: 'in_progress'`,
|
|
5178
|
+
// `sourceSessionId: <currentSession>` when this flag is true. Default
|
|
5179
|
+
// false — most turn-scoped items don't survive the turn. Engine is
|
|
5180
|
+
// unaware of how/where the host persists; it just passes the flag
|
|
5181
|
+
// through on the `todo_update` side-channel event.
|
|
5182
|
+
persist: z.boolean().optional()
|
|
5175
5183
|
});
|
|
5176
5184
|
var inputSchema6 = z.object({
|
|
5177
5185
|
items: z.array(todoItemSchema).min(1, "items must contain at least 1 entry").max(8, "items must contain at most 8 entries (SPEC 8 ceiling)")
|
|
5178
5186
|
});
|
|
5179
5187
|
var updateTodoTool = buildTool({
|
|
5180
5188
|
name: "update_todo",
|
|
5181
|
-
description: "Declare or replace your plan for the current turn as a structured todo list. Call this when the user's ask is multi-step (\u22653 tools, \u22652 reasoning hops) so the user can see what you're doing as you do it. Each call replaces the entire list \u2014 the tool is idempotent. \n\nRules: 1\u20138 items, each label \u226480 chars, exactly 1 item must be `in_progress`. Use stable `id`s across calls within the same turn so the UI can track item transitions (e.g. `id: 'check-balance'` first as `pending`, later as `completed`). \n\nDO NOT call this for single-step asks ('balance', 'rate') \u2014 it's wasted tokens. DO call it before kicking off long flows where the user benefits from seeing the plan unfold ('save my idle USDC' \u2192 check balance \u2192 check rates \u2192 compute split \u2192 propose). \n\nThis call doesn't count against your turn budget \u2014 re-narrating the plan as items move from pending \u2192 in_progress \u2192 completed is encouraged.",
|
|
5189
|
+
description: "Declare or replace your plan for the current turn as a structured todo list. Call this when the user's ask is multi-step (\u22653 tools, \u22652 reasoning hops) so the user can see what you're doing as you do it. Each call replaces the entire list \u2014 the tool is idempotent. \n\nRules: 1\u20138 items, each label \u226480 chars, exactly 1 item must be `in_progress`. Use stable `id`s across calls within the same turn so the UI can track item transitions (e.g. `id: 'check-balance'` first as `pending`, later as `completed`). \n\nDO NOT call this for single-step asks ('balance', 'rate') \u2014 it's wasted tokens. DO call it before kicking off long flows where the user benefits from seeing the plan unfold ('save my idle USDC' \u2192 check balance \u2192 check rates \u2192 compute split \u2192 propose). \n\nThis call doesn't count against your turn budget \u2014 re-narrating the plan as items move from pending \u2192 in_progress \u2192 completed is encouraged. \n\n[SPEC 9 v0.1.3] To promote an item into a long-lived goal that survives across sessions, set `persist: true` on that item. Reserve this for multi-week commitments the user explicitly wants remembered (e.g. \"save $500 by month-end\", \"track NAVI USDC APY weekly\"). DO NOT set persist on within-turn steps (\"check balance\", \"compute split\") \u2014 those vanish when the turn ends, which is what you want. Default behaviour (no persist field) is don't-persist.",
|
|
5182
5190
|
inputSchema: inputSchema6,
|
|
5183
5191
|
jsonSchema: {
|
|
5184
5192
|
type: "object",
|
|
@@ -5202,6 +5210,10 @@ var updateTodoTool = buildTool({
|
|
|
5202
5210
|
type: "string",
|
|
5203
5211
|
enum: ["pending", "in_progress", "completed"],
|
|
5204
5212
|
description: "Lifecycle state. Exactly one item must be `in_progress` per call."
|
|
5213
|
+
},
|
|
5214
|
+
persist: {
|
|
5215
|
+
type: "boolean",
|
|
5216
|
+
description: 'Set true to promote this item into a long-lived goal that survives across sessions (e.g. "save $500 by month-end"). Default false \u2014 only set true when the item represents a multi-week / multi-session commitment, not a within-turn step. When false or omitted, the item lives only for this turn.'
|
|
5205
5217
|
}
|
|
5206
5218
|
},
|
|
5207
5219
|
required: ["id", "label", "status"]
|
|
@@ -5268,6 +5280,92 @@ var updateTodoTool = buildTool({
|
|
|
5268
5280
|
};
|
|
5269
5281
|
}
|
|
5270
5282
|
});
|
|
5283
|
+
var ADD_RECIPIENT_FORM = {
|
|
5284
|
+
fields: [
|
|
5285
|
+
{
|
|
5286
|
+
name: "name",
|
|
5287
|
+
label: "Nickname",
|
|
5288
|
+
kind: "text",
|
|
5289
|
+
required: true,
|
|
5290
|
+
placeholder: "Mom",
|
|
5291
|
+
helpText: "How you'll refer to this contact in chat."
|
|
5292
|
+
},
|
|
5293
|
+
{
|
|
5294
|
+
name: "identifier",
|
|
5295
|
+
label: "Audric handle, SuiNS name, or wallet address",
|
|
5296
|
+
// [v0.1.3 R6] Polymorphic kind — accepts handles, names, and 0x.
|
|
5297
|
+
// The host renderer treats this as a single text input with
|
|
5298
|
+
// help-text guidance; server-side `normalizeAddressInput` does
|
|
5299
|
+
// the resolution.
|
|
5300
|
+
kind: "sui-recipient",
|
|
5301
|
+
required: true,
|
|
5302
|
+
placeholder: "mom.audric.sui / alex.sui / 0x40cd\u20263e62",
|
|
5303
|
+
helpText: "Type @alice for an Audric user, alex.sui for any SuiNS, or paste a 0x address. We'll resolve it to the canonical wallet automatically."
|
|
5304
|
+
}
|
|
5305
|
+
]
|
|
5306
|
+
};
|
|
5307
|
+
var addRecipientTool = buildTool({
|
|
5308
|
+
name: "add_recipient",
|
|
5309
|
+
description: `Add a new contact to the user's saved-recipients list. Call this when you (the LLM) need to reference a contact that isn't saved yet \u2014 e.g. the user said "send $10 to Mom" but no contact named "Mom" exists. The user will fill in the nickname + identifier (an Audric handle, SuiNS name, or wallet address) via an inline form. The contact is persisted before this tool returns; the resumed call returns confirmation only. Do NOT call when the user manually opens the contact-add UI from settings \u2014 that's a separate user-initiated flow that doesn't need the LLM. Only call when YOU need to add a contact mid-conversation to make a downstream action work.`,
|
|
5310
|
+
inputSchema: z.object({
|
|
5311
|
+
name: z.string().min(1).optional(),
|
|
5312
|
+
identifier: z.string().min(1).optional()
|
|
5313
|
+
}),
|
|
5314
|
+
jsonSchema: {
|
|
5315
|
+
type: "object",
|
|
5316
|
+
properties: {
|
|
5317
|
+
name: {
|
|
5318
|
+
type: "string",
|
|
5319
|
+
description: 'Optional nickname for the contact ("Mom"). Omit to let the user fill the form.'
|
|
5320
|
+
},
|
|
5321
|
+
identifier: {
|
|
5322
|
+
type: "string",
|
|
5323
|
+
description: "Optional polymorphic identifier (Audric handle, SuiNS name, or 0x address). Omit to let the user fill the form."
|
|
5324
|
+
}
|
|
5325
|
+
},
|
|
5326
|
+
required: []
|
|
5327
|
+
},
|
|
5328
|
+
// Permission: read-only from the engine's perspective. The HOST writes
|
|
5329
|
+
// the Contact row in the resume endpoint; the tool's call() body is a
|
|
5330
|
+
// thin confirmation message. Treating as read-only keeps the engine's
|
|
5331
|
+
// permission gate from yielding `pending_action` (which would conflict
|
|
5332
|
+
// with the `pending_input` flow — you'd get a form, then a confirm card,
|
|
5333
|
+
// for what's semantically one user action).
|
|
5334
|
+
isReadOnly: true,
|
|
5335
|
+
// [SPEC 9 v0.1.3 P9.4] Opt out of EarlyToolDispatcher. Early-dispatch
|
|
5336
|
+
// runs the tool's call() mid-stream BEFORE the post-stream guard loop
|
|
5337
|
+
// (where preflight is invoked). If add_recipient ran via early-dispatch,
|
|
5338
|
+
// call() would fire with name/identifier=undefined and "save" garbage
|
|
5339
|
+
// before the form pause path is even consulted. Forcing the tool
|
|
5340
|
+
// through the post-stream loop guarantees preflight runs first.
|
|
5341
|
+
isConcurrencySafe: false,
|
|
5342
|
+
permissionLevel: "auto",
|
|
5343
|
+
flags: {},
|
|
5344
|
+
preflight: (input) => {
|
|
5345
|
+
if (!input.name || !input.identifier) {
|
|
5346
|
+
return {
|
|
5347
|
+
valid: false,
|
|
5348
|
+
needsInput: {
|
|
5349
|
+
schema: ADD_RECIPIENT_FORM,
|
|
5350
|
+
description: "Add a new contact"
|
|
5351
|
+
}
|
|
5352
|
+
};
|
|
5353
|
+
}
|
|
5354
|
+
return { valid: true };
|
|
5355
|
+
},
|
|
5356
|
+
async call(input) {
|
|
5357
|
+
const name = input.name;
|
|
5358
|
+
const identifier = input.identifier;
|
|
5359
|
+
return {
|
|
5360
|
+
data: {
|
|
5361
|
+
saved: true,
|
|
5362
|
+
name,
|
|
5363
|
+
identifier
|
|
5364
|
+
},
|
|
5365
|
+
displayText: `Saved ${name} (${identifier}) to contacts.`
|
|
5366
|
+
};
|
|
5367
|
+
}
|
|
5368
|
+
});
|
|
5271
5369
|
var tokenPricesTool = buildTool({
|
|
5272
5370
|
name: "token_prices",
|
|
5273
5371
|
description: 'Get current USD prices for Sui tokens, with optional 24h change. Accepts full coin type strings (e.g. "0x2::sui::SUI"). Returns price per token and (when requested) 24h change percentage. Use for "what is X worth?" or "did Y move today?". For balance + portfolio rendering, prefer balance_check / portfolio_analysis instead \u2014 they bundle the same prices into the standard cards.',
|
|
@@ -5467,7 +5565,73 @@ Only offer to execute actions you have tools for. If you retrieved a quote, data
|
|
|
5467
5565
|
## Safety
|
|
5468
5566
|
- Never encourage risky financial behavior.
|
|
5469
5567
|
- Warn when health factor < 1.5.
|
|
5470
|
-
- All amounts in USDC unless stated otherwise
|
|
5568
|
+
- All amounts in USDC unless stated otherwise.
|
|
5569
|
+
|
|
5570
|
+
## Proactive insights (only when there's a clear opportunity)
|
|
5571
|
+
- 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).
|
|
5572
|
+
- Two valid placements \u2014 pick whichever fits the turn:
|
|
5573
|
+
- **No user question** (or the question is unrelated to the insight): wrap your ENTIRE response in the \`<proactive>\` block.
|
|
5574
|
+
- **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 \xA7 Proactive Awareness \u2014 same syntax, both placements valid.
|
|
5575
|
+
- 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.
|
|
5576
|
+
- 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).
|
|
5577
|
+
- \`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.
|
|
5578
|
+
- Cap: at most ONE proactive block per turn.
|
|
5579
|
+
- 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.`;
|
|
5580
|
+
|
|
5581
|
+
// src/proactive-marker.ts
|
|
5582
|
+
var VALID_TYPES = /* @__PURE__ */ new Set([
|
|
5583
|
+
"idle_balance",
|
|
5584
|
+
"hf_warning",
|
|
5585
|
+
"apy_drift",
|
|
5586
|
+
"goal_progress"
|
|
5587
|
+
]);
|
|
5588
|
+
var MARKER_REGEX = /<proactive\s+([^>]+)>([\s\S]*?)<\/proactive>/g;
|
|
5589
|
+
var ATTR_TYPE_REGEX = /\btype\s*=\s*"([^"]+)"/;
|
|
5590
|
+
var ATTR_SUBJECT_KEY_REGEX = /\bsubjectKey\s*=\s*"([^"]+)"/;
|
|
5591
|
+
function parseProactiveMarker(text) {
|
|
5592
|
+
if (!text.includes("<proactive")) return null;
|
|
5593
|
+
const matches = [];
|
|
5594
|
+
for (const match of text.matchAll(MARKER_REGEX)) {
|
|
5595
|
+
matches.push({ attrs: match[1] ?? "", body: match[2] ?? "" });
|
|
5596
|
+
}
|
|
5597
|
+
if (matches.length === 0) return null;
|
|
5598
|
+
for (const { attrs, body } of matches) {
|
|
5599
|
+
const typeMatch = attrs.match(ATTR_TYPE_REGEX);
|
|
5600
|
+
const subjectKeyMatch = attrs.match(ATTR_SUBJECT_KEY_REGEX);
|
|
5601
|
+
if (!typeMatch || !subjectKeyMatch) continue;
|
|
5602
|
+
const proactiveType = typeMatch[1];
|
|
5603
|
+
const subjectKey = subjectKeyMatch[1].trim();
|
|
5604
|
+
if (!VALID_TYPES.has(proactiveType)) continue;
|
|
5605
|
+
if (subjectKey.length === 0) continue;
|
|
5606
|
+
const trimmedBody = body.trim();
|
|
5607
|
+
if (trimmedBody.length === 0) continue;
|
|
5608
|
+
return {
|
|
5609
|
+
proactiveType,
|
|
5610
|
+
subjectKey,
|
|
5611
|
+
body: trimmedBody,
|
|
5612
|
+
markerCount: matches.length
|
|
5613
|
+
};
|
|
5614
|
+
}
|
|
5615
|
+
return null;
|
|
5616
|
+
}
|
|
5617
|
+
function stripProactiveMarkers(text) {
|
|
5618
|
+
if (!text.includes("<proactive")) return text;
|
|
5619
|
+
return text.replace(MARKER_REGEX, (_match, _attrs, body) => body);
|
|
5620
|
+
}
|
|
5621
|
+
function extractAllProactiveMarkers(text) {
|
|
5622
|
+
if (!text.includes("<proactive")) return [];
|
|
5623
|
+
const out = [];
|
|
5624
|
+
for (const match of text.matchAll(MARKER_REGEX)) {
|
|
5625
|
+
const attrs = match[1] ?? "";
|
|
5626
|
+
const typeMatch = attrs.match(ATTR_TYPE_REGEX);
|
|
5627
|
+
const subjectKeyMatch = attrs.match(ATTR_SUBJECT_KEY_REGEX);
|
|
5628
|
+
if (!typeMatch || !subjectKeyMatch) continue;
|
|
5629
|
+
const subjectKey = subjectKeyMatch[1].trim();
|
|
5630
|
+
if (subjectKey.length === 0) continue;
|
|
5631
|
+
out.push({ proactiveType: typeMatch[1], subjectKey });
|
|
5632
|
+
}
|
|
5633
|
+
return out;
|
|
5634
|
+
}
|
|
5471
5635
|
|
|
5472
5636
|
// src/cost.ts
|
|
5473
5637
|
var DEFAULT_INPUT_COST = 3 / 1e6;
|
|
@@ -6024,6 +6188,29 @@ function runGuards(tool, call, state, config, conversationContext, onGuardFired,
|
|
|
6024
6188
|
if (config.inputValidation !== false && tool.preflight) {
|
|
6025
6189
|
const check = tool.preflight(call.input);
|
|
6026
6190
|
if (!check.valid) {
|
|
6191
|
+
if ("needsInput" in check && check.needsInput) {
|
|
6192
|
+
const event2 = {
|
|
6193
|
+
timestamp: now,
|
|
6194
|
+
toolName: tool.name,
|
|
6195
|
+
toolUseId: call.id,
|
|
6196
|
+
gate: "input_validation",
|
|
6197
|
+
verdict: "pass",
|
|
6198
|
+
tier: "safety",
|
|
6199
|
+
message: check.needsInput.description
|
|
6200
|
+
};
|
|
6201
|
+
fire("pass", "safety", "input_validation", false);
|
|
6202
|
+
return {
|
|
6203
|
+
blocked: false,
|
|
6204
|
+
injections: [],
|
|
6205
|
+
events: [event2],
|
|
6206
|
+
needsInput: check.needsInput
|
|
6207
|
+
};
|
|
6208
|
+
}
|
|
6209
|
+
if (!("error" in check)) {
|
|
6210
|
+
throw new Error(
|
|
6211
|
+
`Preflight returned a non-needsInput, non-error invalid result for tool ${tool.name}`
|
|
6212
|
+
);
|
|
6213
|
+
}
|
|
6027
6214
|
const event = {
|
|
6028
6215
|
timestamp: now,
|
|
6029
6216
|
toolName: tool.name,
|
|
@@ -6945,6 +7132,26 @@ var QueryEngine = class {
|
|
|
6945
7132
|
// their `finally` block so they DON'T clear the cache mid-turn — the
|
|
6946
7133
|
// pending write may resume, and the cache should survive the pause.
|
|
6947
7134
|
turnPaused = false;
|
|
7135
|
+
// [SPEC 9 v0.1.1 P9.2 / R3] Per-engine-instance cooldown set for
|
|
7136
|
+
// proactive insight markers. Same `(proactiveType, subjectKey)` tuple
|
|
7137
|
+
// emitted twice in one session ⇒ second emission is suppressed (host
|
|
7138
|
+
// strips the wrapper, renders body as plain text). Cooldown is
|
|
7139
|
+
// per-session, not cross-session — a fresh QueryEngine on the next
|
|
7140
|
+
// user session starts with an empty set and may re-emit the same
|
|
7141
|
+
// tuple. Drops automatically when the engine is GC'd.
|
|
7142
|
+
//
|
|
7143
|
+
// Storage shape: serialised key `${type}:${subjectKey}` for cheap
|
|
7144
|
+
// Set membership without an extra hash function.
|
|
7145
|
+
proactiveCooldown = /* @__PURE__ */ new Set();
|
|
7146
|
+
// [SPEC 9 v0.1.3 P9.4] In-flight `pending_input` state, keyed by `inputId`.
|
|
7147
|
+
// Set when the agent loop hits a tool whose preflight returned `needsInput`;
|
|
7148
|
+
// consulted by `resumeWithInput()` to look up which paused tool call to
|
|
7149
|
+
// re-feed with the user's submitted values. Cleared on resume (whether
|
|
7150
|
+
// success or abandonment via a fresh `submitMessage`). Multiple concurrent
|
|
7151
|
+
// entries are allowed in principle (LLM could call two `add_recipient`s
|
|
7152
|
+
// in one turn) but in practice we yield + return on the FIRST hit, so
|
|
7153
|
+
// the map is almost always 0 or 1 entries deep.
|
|
7154
|
+
pendingInputs = /* @__PURE__ */ new Map();
|
|
6948
7155
|
constructor(config) {
|
|
6949
7156
|
this.provider = config.provider;
|
|
6950
7157
|
this.agent = config.agent;
|
|
@@ -7168,6 +7375,159 @@ var QueryEngine = class {
|
|
|
7168
7375
|
}
|
|
7169
7376
|
}
|
|
7170
7377
|
}
|
|
7378
|
+
/**
|
|
7379
|
+
* [SPEC 9 v0.1.3 P9.4] Resume a turn that paused on `pending_input`.
|
|
7380
|
+
*
|
|
7381
|
+
* Called by the host after the user submitted the inline form. The
|
|
7382
|
+
* `pendingInput` argument is the EXACT payload that was yielded as
|
|
7383
|
+
* `pending_input` (host stored it in session storage); `values` is the
|
|
7384
|
+
* `{ fieldName: value }` map the user submitted, post-host-validation
|
|
7385
|
+
* against `pendingInput.schema`.
|
|
7386
|
+
*
|
|
7387
|
+
* Engine responsibilities (in order):
|
|
7388
|
+
* 1. Push the captured `assistantContent` (assistant blocks from the
|
|
7389
|
+
* paused turn — includes the tool_use that triggered this pause).
|
|
7390
|
+
* 2. Run the paused tool's `call()` with `values` as input. Re-runs
|
|
7391
|
+
* preflight first as a defense-in-depth gate (host SHOULD have
|
|
7392
|
+
* validated against the schema, but malformed input would otherwise
|
|
7393
|
+
* poison the conversation history with an orphan tool_use).
|
|
7394
|
+
* 3. Combine `completedResults` (read tool_results that already ran in
|
|
7395
|
+
* the same turn before the pause) with the new tool_result into ONE
|
|
7396
|
+
* user-role message. Anthropic's API requires every tool_use to have
|
|
7397
|
+
* a tool_result in the immediately-following user message — splitting
|
|
7398
|
+
* them would produce two consecutive user messages, which the API
|
|
7399
|
+
* rejects.
|
|
7400
|
+
* 4. Yield `tool_result` for the host's timeline + run `agentLoop` to
|
|
7401
|
+
* continue the turn (LLM gets the resumed result and narrates).
|
|
7402
|
+
*
|
|
7403
|
+
* Mirrors `resumeWithToolResult` for the user-confirm case but feeds
|
|
7404
|
+
* the values back as the tool's INPUT (the call() runs here for the
|
|
7405
|
+
* first time) instead of as the tool's OUTPUT (the call() ran on the
|
|
7406
|
+
* client side via sponsored-tx for pending_action).
|
|
7407
|
+
*/
|
|
7408
|
+
async *resumeWithInput(pendingInput, values) {
|
|
7409
|
+
this.abortController = new AbortController();
|
|
7410
|
+
const signal = this.abortController.signal;
|
|
7411
|
+
if (pendingInput.assistantContent.length > 0) {
|
|
7412
|
+
this.messages.push({
|
|
7413
|
+
role: "assistant",
|
|
7414
|
+
content: pendingInput.assistantContent
|
|
7415
|
+
});
|
|
7416
|
+
}
|
|
7417
|
+
const tool = findTool(this.tools, pendingInput.toolName);
|
|
7418
|
+
let resumedToolResult;
|
|
7419
|
+
let toolResultEventPayload;
|
|
7420
|
+
if (!tool) {
|
|
7421
|
+
const errorPayload = {
|
|
7422
|
+
error: `Tool "${pendingInput.toolName}" not found on resume \u2014 engine may have been reconfigured between pause and resume.`,
|
|
7423
|
+
_hostBugMissingTool: true
|
|
7424
|
+
};
|
|
7425
|
+
resumedToolResult = {
|
|
7426
|
+
content: JSON.stringify(errorPayload),
|
|
7427
|
+
isError: true
|
|
7428
|
+
};
|
|
7429
|
+
toolResultEventPayload = { result: errorPayload, isError: true };
|
|
7430
|
+
} else {
|
|
7431
|
+
const preflightCheck = tool.preflight ? tool.preflight(values) : { valid: true };
|
|
7432
|
+
if (!preflightCheck.valid && "error" in preflightCheck) {
|
|
7433
|
+
const errorPayload = {
|
|
7434
|
+
error: `Form values failed re-validation: ${preflightCheck.error}`,
|
|
7435
|
+
_hostFormValidationFailed: true
|
|
7436
|
+
};
|
|
7437
|
+
resumedToolResult = {
|
|
7438
|
+
content: JSON.stringify(errorPayload),
|
|
7439
|
+
isError: true
|
|
7440
|
+
};
|
|
7441
|
+
toolResultEventPayload = { result: errorPayload, isError: true };
|
|
7442
|
+
} else if (!preflightCheck.valid && "needsInput" in preflightCheck) {
|
|
7443
|
+
const errorPayload = {
|
|
7444
|
+
error: "Tool requested another form on resume \u2014 multi-step forms are not supported in v0.1.3. Re-prompt the user with a fresh single-step request.",
|
|
7445
|
+
_multiStepFormUnsupported: true
|
|
7446
|
+
};
|
|
7447
|
+
resumedToolResult = {
|
|
7448
|
+
content: JSON.stringify(errorPayload),
|
|
7449
|
+
isError: true
|
|
7450
|
+
};
|
|
7451
|
+
toolResultEventPayload = { result: errorPayload, isError: true };
|
|
7452
|
+
} else {
|
|
7453
|
+
const parsed = tool.inputSchema.safeParse(values);
|
|
7454
|
+
if (!parsed.success) {
|
|
7455
|
+
const errorPayload = {
|
|
7456
|
+
error: `Invalid input on resume: ${parsed.error.issues.map((i) => i.message).join(", ")}`,
|
|
7457
|
+
_hostFormZodFailed: true
|
|
7458
|
+
};
|
|
7459
|
+
resumedToolResult = {
|
|
7460
|
+
content: JSON.stringify(errorPayload),
|
|
7461
|
+
isError: true
|
|
7462
|
+
};
|
|
7463
|
+
toolResultEventPayload = { result: errorPayload, isError: true };
|
|
7464
|
+
} else {
|
|
7465
|
+
const context = {
|
|
7466
|
+
agent: this.agent,
|
|
7467
|
+
mcpManager: this.mcpManager,
|
|
7468
|
+
walletAddress: this.walletAddress,
|
|
7469
|
+
suiRpcUrl: this.suiRpcUrl,
|
|
7470
|
+
serverPositions: this.serverPositions,
|
|
7471
|
+
positionFetcher: this.positionFetcher,
|
|
7472
|
+
env: this.env,
|
|
7473
|
+
signal,
|
|
7474
|
+
priceCache: this.priceCache,
|
|
7475
|
+
permissionConfig: this.permissionConfig,
|
|
7476
|
+
sessionSpendUsd: this.sessionSpendUsd,
|
|
7477
|
+
blockvisionApiKey: this.blockvisionApiKey,
|
|
7478
|
+
portfolioCache: this.portfolioCache
|
|
7479
|
+
};
|
|
7480
|
+
try {
|
|
7481
|
+
const callResult = await tool.call(parsed.data, context);
|
|
7482
|
+
resumedToolResult = {
|
|
7483
|
+
content: JSON.stringify(callResult.data),
|
|
7484
|
+
isError: false
|
|
7485
|
+
};
|
|
7486
|
+
toolResultEventPayload = { result: callResult.data, isError: false };
|
|
7487
|
+
} catch (err) {
|
|
7488
|
+
const message = err instanceof Error ? err.message : "Tool execution failed";
|
|
7489
|
+
const errorPayload = { error: message };
|
|
7490
|
+
resumedToolResult = {
|
|
7491
|
+
content: JSON.stringify(errorPayload),
|
|
7492
|
+
isError: true
|
|
7493
|
+
};
|
|
7494
|
+
toolResultEventPayload = { result: errorPayload, isError: true };
|
|
7495
|
+
}
|
|
7496
|
+
}
|
|
7497
|
+
}
|
|
7498
|
+
}
|
|
7499
|
+
const userMessageBlocks = [
|
|
7500
|
+
...pendingInput.completedResults.map((r) => ({
|
|
7501
|
+
type: "tool_result",
|
|
7502
|
+
toolUseId: r.toolUseId,
|
|
7503
|
+
content: r.content,
|
|
7504
|
+
isError: r.isError
|
|
7505
|
+
})),
|
|
7506
|
+
{
|
|
7507
|
+
type: "tool_result",
|
|
7508
|
+
toolUseId: pendingInput.toolUseId,
|
|
7509
|
+
content: resumedToolResult.content,
|
|
7510
|
+
isError: resumedToolResult.isError
|
|
7511
|
+
}
|
|
7512
|
+
];
|
|
7513
|
+
this.messages.push({ role: "user", content: userMessageBlocks });
|
|
7514
|
+
yield {
|
|
7515
|
+
type: "tool_result",
|
|
7516
|
+
toolName: pendingInput.toolName,
|
|
7517
|
+
toolUseId: pendingInput.toolUseId,
|
|
7518
|
+
result: toolResultEventPayload.result,
|
|
7519
|
+
isError: toolResultEventPayload.isError
|
|
7520
|
+
};
|
|
7521
|
+
this.pendingInputs.delete(pendingInput.inputId);
|
|
7522
|
+
this.turnPaused = false;
|
|
7523
|
+
try {
|
|
7524
|
+
yield* this.agentLoop(null, signal, false);
|
|
7525
|
+
} finally {
|
|
7526
|
+
if (!this.turnPaused) {
|
|
7527
|
+
this.turnReadCache.clear();
|
|
7528
|
+
}
|
|
7529
|
+
}
|
|
7530
|
+
}
|
|
7171
7531
|
/**
|
|
7172
7532
|
* [v1.5] Auto-run configured read tools after a successful write,
|
|
7173
7533
|
* push their results into the conversation, and yield `tool_result`
|
|
@@ -7338,6 +7698,25 @@ var QueryEngine = class {
|
|
|
7338
7698
|
}
|
|
7339
7699
|
loadMessages(messages) {
|
|
7340
7700
|
this.messages = [...messages];
|
|
7701
|
+
this.rehydrateProactiveCooldown();
|
|
7702
|
+
}
|
|
7703
|
+
/**
|
|
7704
|
+
* [SPEC 9 v0.1.1 P9.2 / R3] Walk loaded assistant text blocks and seed the
|
|
7705
|
+
* cooldown set with every parseable `(proactiveType, subjectKey)` tuple.
|
|
7706
|
+
* Called automatically from `loadMessages`. Idempotent — safe to call on
|
|
7707
|
+
* an already-populated set; duplicates are absorbed by Set semantics.
|
|
7708
|
+
*/
|
|
7709
|
+
rehydrateProactiveCooldown() {
|
|
7710
|
+
for (const message of this.messages) {
|
|
7711
|
+
if (message.role !== "assistant") continue;
|
|
7712
|
+
const blocks = Array.isArray(message.content) ? message.content : [];
|
|
7713
|
+
for (const block of blocks) {
|
|
7714
|
+
if (block.type !== "text" || typeof block.text !== "string") continue;
|
|
7715
|
+
for (const { proactiveType, subjectKey } of extractAllProactiveMarkers(block.text)) {
|
|
7716
|
+
this.proactiveCooldown.add(`${proactiveType}:${subjectKey}`);
|
|
7717
|
+
}
|
|
7718
|
+
}
|
|
7719
|
+
}
|
|
7341
7720
|
}
|
|
7342
7721
|
/**
|
|
7343
7722
|
* [v0.46.7] Run a read-only tool out-of-band, using the engine's tool
|
|
@@ -7745,6 +8124,45 @@ ${recipeCtx}`;
|
|
|
7745
8124
|
});
|
|
7746
8125
|
continue;
|
|
7747
8126
|
}
|
|
8127
|
+
if (check.needsInput) {
|
|
8128
|
+
const inputId = randomUUID();
|
|
8129
|
+
const pendingInput = {
|
|
8130
|
+
inputId,
|
|
8131
|
+
toolName: call.name,
|
|
8132
|
+
toolUseId: call.id,
|
|
8133
|
+
schema: check.needsInput.schema,
|
|
8134
|
+
description: check.needsInput.description,
|
|
8135
|
+
assistantContent: acc.assistantBlocks,
|
|
8136
|
+
completedResults: toolResultBlocks.map((b) => ({
|
|
8137
|
+
toolUseId: b.toolUseId,
|
|
8138
|
+
content: b.content,
|
|
8139
|
+
isError: b.isError ?? false
|
|
8140
|
+
}))
|
|
8141
|
+
};
|
|
8142
|
+
this.pendingInputs.set(inputId, pendingInput);
|
|
8143
|
+
this.turnPaused = true;
|
|
8144
|
+
getTelemetrySink().counter("engine.pending_input_emitted", {
|
|
8145
|
+
tool: call.name
|
|
8146
|
+
});
|
|
8147
|
+
yield {
|
|
8148
|
+
type: "pending_input",
|
|
8149
|
+
inputId,
|
|
8150
|
+
toolName: call.name,
|
|
8151
|
+
toolUseId: call.id,
|
|
8152
|
+
schema: check.needsInput.schema,
|
|
8153
|
+
description: check.needsInput.description,
|
|
8154
|
+
// [SPEC 9 v0.1.3 P9.4] Round-trip fields on the wire so
|
|
8155
|
+
// stateless hosts (audric — request-scoped engines) can
|
|
8156
|
+
// persist + echo back on resume. In-process hosts (CLI,
|
|
8157
|
+
// long-lived engine instances) can ignore — the engine
|
|
8158
|
+
// also stashes the state on `this.pendingInputs[inputId]`
|
|
8159
|
+
// for in-memory recall.
|
|
8160
|
+
assistantContent: pendingInput.assistantContent,
|
|
8161
|
+
completedResults: pendingInput.completedResults
|
|
8162
|
+
};
|
|
8163
|
+
recordTurnOutcome("pending_input");
|
|
8164
|
+
return;
|
|
8165
|
+
}
|
|
7748
8166
|
if (check.injections.length > 0) {
|
|
7749
8167
|
call._guardInjections = check.injections;
|
|
7750
8168
|
}
|
|
@@ -8081,6 +8499,32 @@ ${recipeCtx}`;
|
|
|
8081
8499
|
yield { type: "text_delta", text: event.text };
|
|
8082
8500
|
break;
|
|
8083
8501
|
}
|
|
8502
|
+
case "text_done": {
|
|
8503
|
+
if (event.proactiveMarker) {
|
|
8504
|
+
const { proactiveType, subjectKey, body, markerCount } = event.proactiveMarker;
|
|
8505
|
+
const dedupKey = `${proactiveType}:${subjectKey}`;
|
|
8506
|
+
const suppressed = this.proactiveCooldown.has(dedupKey);
|
|
8507
|
+
if (!suppressed) this.proactiveCooldown.add(dedupKey);
|
|
8508
|
+
const sink = getTelemetrySink();
|
|
8509
|
+
if (suppressed) {
|
|
8510
|
+
sink.counter("audric.harness.proactive_text_suppressed_count", { reason: "cooldown" }, 1);
|
|
8511
|
+
} else {
|
|
8512
|
+
sink.counter("audric.harness.proactive_text_emitted_count", { type: proactiveType }, 1);
|
|
8513
|
+
}
|
|
8514
|
+
if (markerCount > 1) {
|
|
8515
|
+
sink.counter("audric.harness.proactive_marker_violations_count", {}, 1);
|
|
8516
|
+
}
|
|
8517
|
+
yield {
|
|
8518
|
+
type: "proactive_text",
|
|
8519
|
+
proactiveType,
|
|
8520
|
+
subjectKey,
|
|
8521
|
+
body,
|
|
8522
|
+
suppressed,
|
|
8523
|
+
markerCount
|
|
8524
|
+
};
|
|
8525
|
+
}
|
|
8526
|
+
break;
|
|
8527
|
+
}
|
|
8084
8528
|
case "tool_use_done": {
|
|
8085
8529
|
if (acc.text) {
|
|
8086
8530
|
acc.assistantBlocks.push({ type: "text", text: acc.text });
|
|
@@ -8680,7 +9124,7 @@ function classifyEffort(model, userMessage, matchedRecipe, sessionWriteCount) {
|
|
|
8680
9124
|
}
|
|
8681
9125
|
|
|
8682
9126
|
// src/eval-summary.ts
|
|
8683
|
-
var
|
|
9127
|
+
var MARKER_REGEX2 = /<eval_summary>([\s\S]*?)<\/eval_summary>/g;
|
|
8684
9128
|
var VALID_STATUSES = /* @__PURE__ */ new Set([
|
|
8685
9129
|
"good",
|
|
8686
9130
|
"warning",
|
|
@@ -8690,7 +9134,7 @@ var VALID_STATUSES = /* @__PURE__ */ new Set([
|
|
|
8690
9134
|
function parseEvalSummary(thinkingText) {
|
|
8691
9135
|
if (!thinkingText.includes("<eval_summary>")) return null;
|
|
8692
9136
|
const matches = [];
|
|
8693
|
-
for (const match of thinkingText.matchAll(
|
|
9137
|
+
for (const match of thinkingText.matchAll(MARKER_REGEX2)) {
|
|
8694
9138
|
matches.push(match[1] ?? "");
|
|
8695
9139
|
}
|
|
8696
9140
|
if (matches.length === 0) return null;
|
|
@@ -8791,7 +9235,10 @@ context is worth mentioning. ${brevityGuidance}
|
|
|
8791
9235
|
- Would seem pushy or sales-y
|
|
8792
9236
|
|
|
8793
9237
|
${styleGuidance}
|
|
8794
|
-
Format: One sentence maximum,
|
|
9238
|
+
Format: One sentence maximum, AFTER your main response, separated by a line break, WRAPPED in a \`<proactive type="..." subjectKey="...">BODY</proactive>\` block. The host renders the wrapped block with the "\u2726 ADDED BY AUDRIC" lockup styling \u2014 without the wrapper the host shows only plain text and the engine's per-session cooldown won't deduplicate future repeats (so the same nudge re-fires every turn).
|
|
9239
|
+
Allowed types (closed list \u2014 anything else is dropped by the host): \`idle_balance\` (cash sitting idle that could earn yield), \`hf_warning\` (debt approaching liquidation), \`apy_drift\` (rate change on a position they hold), \`goal_progress\` (update on a saved goal).
|
|
9240
|
+
\`subjectKey\` is a stable identifier for the SPECIFIC subject (e.g. "USDC" for an idle-USDC insight, "1.45" for HF at that level, "tokyo-trip" for a saved goal). Same (type, subjectKey) won't fire twice in one session \u2014 pick the same key for the same subject so cooldown works.
|
|
9241
|
+
Example (post-answer suffix form): \`<proactive type="goal_progress" subjectKey="tokyo-trip">Your Tokyo goal is $80 behind pace.</proactive>\`
|
|
8795
9242
|
Frame as observation, not advice: "Your Tokyo goal is $80 behind pace." \u2014 not "You should deposit more."`;
|
|
8796
9243
|
}
|
|
8797
9244
|
function buildSelfEvaluationInstruction() {
|
|
@@ -9223,6 +9670,7 @@ var AnthropicProvider = class {
|
|
|
9223
9670
|
const stream = params.signal ? this.client.messages.stream(streamParams, { signal: params.signal }) : this.client.messages.stream(streamParams);
|
|
9224
9671
|
const toolInputBuffers = /* @__PURE__ */ new Map();
|
|
9225
9672
|
const thinkingBuffers = /* @__PURE__ */ new Map();
|
|
9673
|
+
const textBuffers = /* @__PURE__ */ new Map();
|
|
9226
9674
|
let outputTokensFromStart = 0;
|
|
9227
9675
|
try {
|
|
9228
9676
|
for await (const event of stream) {
|
|
@@ -9264,12 +9712,16 @@ var AnthropicProvider = class {
|
|
|
9264
9712
|
thinkingBuffers.set(event.index, { type: "thinking", text: "", signature: "" });
|
|
9265
9713
|
} else if (block.type === "redacted_thinking") {
|
|
9266
9714
|
thinkingBuffers.set(event.index, { type: "redacted_thinking", data: block.data ?? "" });
|
|
9715
|
+
} else if (block.type === "text") {
|
|
9716
|
+
textBuffers.set(event.index, { text: "" });
|
|
9267
9717
|
}
|
|
9268
9718
|
break;
|
|
9269
9719
|
}
|
|
9270
9720
|
case "content_block_delta": {
|
|
9271
9721
|
const delta = event.delta;
|
|
9272
9722
|
if (delta.type === "text_delta") {
|
|
9723
|
+
const buf = textBuffers.get(event.index);
|
|
9724
|
+
if (buf) buf.text += delta.text ?? "";
|
|
9273
9725
|
yield { type: "text_delta", text: delta.text };
|
|
9274
9726
|
} else if (delta.type === "input_json_delta") {
|
|
9275
9727
|
const buf = toolInputBuffers.get(event.index);
|
|
@@ -9323,6 +9775,15 @@ var AnthropicProvider = class {
|
|
|
9323
9775
|
yield { type: "redacted_thinking", data: thinkBuf.data };
|
|
9324
9776
|
thinkingBuffers.delete(event.index);
|
|
9325
9777
|
}
|
|
9778
|
+
const textBuf = textBuffers.get(event.index);
|
|
9779
|
+
if (textBuf) {
|
|
9780
|
+
const proactiveMarker = parseProactiveMarker(textBuf.text);
|
|
9781
|
+
yield {
|
|
9782
|
+
type: "text_done",
|
|
9783
|
+
...proactiveMarker ? { proactiveMarker } : {}
|
|
9784
|
+
};
|
|
9785
|
+
textBuffers.delete(event.index);
|
|
9786
|
+
}
|
|
9326
9787
|
break;
|
|
9327
9788
|
}
|
|
9328
9789
|
case "message_delta": {
|
|
@@ -9531,6 +9992,6 @@ function sanitizeAnthropicMessages(messages) {
|
|
|
9531
9992
|
return merged;
|
|
9532
9993
|
}
|
|
9533
9994
|
|
|
9534
|
-
export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_LEASE_SEC, DEFAULT_PERMISSION_CONFIG, DEFAULT_POLL_BUDGET_MS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SYSTEM_PROMPT, DEFAULT_TOOL_TTL_MS, EFFORT_THINKING_BUDGET_CAPS, EarlyToolDispatcher, InMemoryDefiCacheStore, InMemoryFetchLock, InMemoryNaviCacheStore, InMemoryWalletCacheStore, InvalidAddressError, MAX_BUNDLE_OPS, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_ADDR_TTL_SEC, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_RATES_TTL_SEC, NAVI_SERVER_NAME, NaviTools, PERMISSION_PRESETS, QueryEngine, READ_TOOLS, REGENERATABLE_READ_TOOLS, RecipeRegistry, RetryTracker, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SuinsNotRegisteredError, SuinsRpcError, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TOOL_TTL_MS, TxMutex, VALID_PAIRS, WRITE_TOOLS, _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 };
|
|
9995
|
+
export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_LEASE_SEC, DEFAULT_PERMISSION_CONFIG, DEFAULT_POLL_BUDGET_MS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SYSTEM_PROMPT, DEFAULT_TOOL_TTL_MS, EFFORT_THINKING_BUDGET_CAPS, EarlyToolDispatcher, InMemoryDefiCacheStore, InMemoryFetchLock, InMemoryNaviCacheStore, InMemoryWalletCacheStore, InvalidAddressError, MAX_BUNDLE_OPS, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_ADDR_TTL_SEC, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_RATES_TTL_SEC, NAVI_SERVER_NAME, NaviTools, PERMISSION_PRESETS, QueryEngine, READ_TOOLS, REGENERATABLE_READ_TOOLS, RecipeRegistry, RetryTracker, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SuinsNotRegisteredError, SuinsRpcError, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TOOL_TTL_MS, TxMutex, VALID_PAIRS, WRITE_TOOLS, _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 };
|
|
9535
9996
|
//# sourceMappingURL=index.js.map
|
|
9536
9997
|
//# sourceMappingURL=index.js.map
|