@t2000/engine 0.32.0 → 0.33.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.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  import { resolveSymbol, getDecimalsForCoinType, assertAllowedAsset, getSwapQuote, SUI_TYPE } from '@t2000/sdk';
3
+ import { readdirSync, readFileSync } from 'fs';
4
+ import { join } from 'path';
5
+ import yaml from 'js-yaml';
3
6
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
4
7
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
5
8
  import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
@@ -3941,6 +3944,187 @@ function extractConversationText(messages) {
3941
3944
  };
3942
3945
  }
3943
3946
 
3947
+ // src/context.ts
3948
+ var CHARS_PER_TOKEN = 4;
3949
+ var DEFAULT_CONTEXT_LIMIT = 2e5;
3950
+ function estimateTokens(messages) {
3951
+ let chars = 0;
3952
+ for (const msg of messages) {
3953
+ for (const block of msg.content) {
3954
+ chars += blockCharCount(block);
3955
+ }
3956
+ }
3957
+ return Math.ceil(chars / CHARS_PER_TOKEN);
3958
+ }
3959
+ function blockCharCount(block) {
3960
+ switch (block.type) {
3961
+ case "text":
3962
+ return block.text.length;
3963
+ case "thinking":
3964
+ return block.thinking.length;
3965
+ case "redacted_thinking":
3966
+ return block.data.length;
3967
+ case "tool_use":
3968
+ return block.name.length + JSON.stringify(block.input).length;
3969
+ case "tool_result":
3970
+ return block.content.length;
3971
+ }
3972
+ }
3973
+ var ContextBudget = class {
3974
+ estimatedTokens = 0;
3975
+ contextLimit;
3976
+ compactThreshold;
3977
+ warnThreshold;
3978
+ constructor(config = {}) {
3979
+ this.contextLimit = config.contextLimit ?? DEFAULT_CONTEXT_LIMIT;
3980
+ this.compactThreshold = config.compactThreshold ?? 0.85;
3981
+ this.warnThreshold = config.warnThreshold ?? 0.7;
3982
+ }
3983
+ /** Update with actual input_tokens from the API usage event. */
3984
+ update(inputTokens) {
3985
+ this.estimatedTokens = inputTokens;
3986
+ }
3987
+ /** True when the session should be compacted (at 85% of context limit). */
3988
+ shouldCompact() {
3989
+ return this.estimatedTokens >= this.contextLimit * this.compactThreshold;
3990
+ }
3991
+ /** True when nearing the limit (at 70% of context limit). */
3992
+ shouldWarn() {
3993
+ return this.estimatedTokens >= this.contextLimit * this.warnThreshold;
3994
+ }
3995
+ /** Current token count. */
3996
+ get tokens() {
3997
+ return this.estimatedTokens;
3998
+ }
3999
+ /** Remaining tokens before compaction triggers. */
4000
+ get remaining() {
4001
+ return Math.max(0, Math.floor(this.contextLimit * this.compactThreshold) - this.estimatedTokens);
4002
+ }
4003
+ /** Usage ratio (0..1). */
4004
+ get usage() {
4005
+ return this.estimatedTokens / this.contextLimit;
4006
+ }
4007
+ reset() {
4008
+ this.estimatedTokens = 0;
4009
+ }
4010
+ };
4011
+ async function compactMessages(messages, opts = {}) {
4012
+ const maxTokens = opts.maxTokens ?? 1e5;
4013
+ const keepRecent = opts.keepRecentCount ?? 8;
4014
+ const systemTokens = opts.systemPromptTokens ?? 500;
4015
+ const budget = maxTokens - systemTokens;
4016
+ if (messages.length === 0) return [];
4017
+ const mutable = messages.map((m) => ({
4018
+ role: m.role,
4019
+ content: m.content.map((b) => ({ ...b }))
4020
+ }));
4021
+ if (estimateTokens(mutable) <= budget) return mutable;
4022
+ const splitIdx = Math.max(0, mutable.length - keepRecent);
4023
+ const oldMessages = mutable.slice(0, splitIdx);
4024
+ const recent = mutable.slice(splitIdx);
4025
+ if (opts.summarizer && oldMessages.length > 0) {
4026
+ const strippedOld = stripThinkingBlocks(oldMessages);
4027
+ try {
4028
+ const summary = await opts.summarizer(strippedOld);
4029
+ const summaryMessages = [
4030
+ { role: "user", content: [{ type: "text", text: `[Session summary: ${summary}]` }] },
4031
+ { role: "assistant", content: [{ type: "text", text: "Understood. I have the context from our earlier conversation." }] }
4032
+ ];
4033
+ const withSummary = [...summaryMessages, ...recent];
4034
+ if (estimateTokens(withSummary) <= budget) return sanitizeMessages(withSummary);
4035
+ } catch {
4036
+ }
4037
+ }
4038
+ for (let i = 0; i < splitIdx; i++) {
4039
+ mutable[i].content = mutable[i].content.map((block) => {
4040
+ if (block.type === "tool_result" && block.content.length > 200) {
4041
+ return {
4042
+ ...block,
4043
+ content: truncateToolResult(block.content)
4044
+ };
4045
+ }
4046
+ return block;
4047
+ });
4048
+ }
4049
+ for (let i = 0; i < splitIdx; i++) {
4050
+ mutable[i].content = mutable[i].content.filter(
4051
+ (b) => b.type !== "thinking" && b.type !== "redacted_thinking"
4052
+ );
4053
+ }
4054
+ if (estimateTokens(mutable) <= budget) return mutable;
4055
+ const first = mutable[0];
4056
+ const recentFromMutable = mutable.slice(splitIdx);
4057
+ const oldSection = mutable.slice(1, splitIdx);
4058
+ while (oldSection.length > 0 && estimateTokens([first, ...oldSection, ...recentFromMutable]) > budget) {
4059
+ oldSection.shift();
4060
+ }
4061
+ const compacted = [first, ...oldSection, ...recentFromMutable];
4062
+ if (estimateTokens(compacted) > budget) {
4063
+ for (const msg of compacted) {
4064
+ msg.content = msg.content.map((block) => {
4065
+ if (block.type === "tool_result" && block.content.length > 100) {
4066
+ return { ...block, content: truncateToolResult(block.content) };
4067
+ }
4068
+ return block;
4069
+ });
4070
+ }
4071
+ }
4072
+ return sanitizeMessages(compacted);
4073
+ }
4074
+ function stripThinkingBlocks(messages) {
4075
+ return messages.map((m) => ({
4076
+ ...m,
4077
+ content: m.content.filter(
4078
+ (b) => b.type !== "thinking" && b.type !== "redacted_thinking"
4079
+ )
4080
+ })).filter((m) => m.content.length > 0);
4081
+ }
4082
+ function sanitizeMessages(messages) {
4083
+ const toolUseIds = /* @__PURE__ */ new Set();
4084
+ const toolResultIds = /* @__PURE__ */ new Set();
4085
+ for (const msg of messages) {
4086
+ for (const block of msg.content) {
4087
+ if (block.type === "tool_use") toolUseIds.add(block.id);
4088
+ if (block.type === "tool_result") toolResultIds.add(block.toolUseId);
4089
+ }
4090
+ }
4091
+ return messages.map((msg) => {
4092
+ const filtered = msg.content.filter((block) => {
4093
+ if (block.type === "tool_result") return toolUseIds.has(block.toolUseId);
4094
+ if (block.type === "tool_use") return toolResultIds.has(block.id);
4095
+ return true;
4096
+ });
4097
+ if (filtered.length === 0) return null;
4098
+ return { ...msg, content: filtered };
4099
+ }).filter((m) => m !== null);
4100
+ }
4101
+ function truncateToolResult(content) {
4102
+ try {
4103
+ const parsed = JSON.parse(content);
4104
+ if (parsed.error) {
4105
+ return JSON.stringify({ error: parsed.error });
4106
+ }
4107
+ if (typeof parsed === "object" && parsed !== null) {
4108
+ const summary = {};
4109
+ for (const [key, value] of Object.entries(parsed)) {
4110
+ if (typeof value === "number" || typeof value === "boolean") {
4111
+ summary[key] = value;
4112
+ } else if (typeof value === "string") {
4113
+ summary[key] = value.length > 50 ? value.slice(0, 50) + "\u2026" : value;
4114
+ } else if (Array.isArray(value)) {
4115
+ summary[key] = `[${value.length} items]`;
4116
+ } else {
4117
+ summary[key] = "{\u2026}";
4118
+ }
4119
+ }
4120
+ return JSON.stringify(summary);
4121
+ }
4122
+ return content.slice(0, 100);
4123
+ } catch {
4124
+ return content.slice(0, 100);
4125
+ }
4126
+ }
4127
+
3944
4128
  // src/engine.ts
3945
4129
  var DEFAULT_MAX_TURNS = 10;
3946
4130
  var DEFAULT_MAX_TOKENS = 4096;
@@ -3966,6 +4150,10 @@ var QueryEngine = class {
3966
4150
  costTracker;
3967
4151
  guardConfig;
3968
4152
  guardState;
4153
+ recipes;
4154
+ contextBudget;
4155
+ contextSummarizer;
4156
+ matchedRecipe = null;
3969
4157
  messages = [];
3970
4158
  abortController = null;
3971
4159
  guardEvents = [];
@@ -3989,6 +4177,9 @@ var QueryEngine = class {
3989
4177
  this.costTracker = new CostTracker(config.costTracker);
3990
4178
  this.guardConfig = config.guards;
3991
4179
  this.guardState = createGuardRunnerState();
4180
+ this.recipes = config.recipes;
4181
+ this.contextBudget = new ContextBudget(config.contextBudget);
4182
+ this.contextSummarizer = config.contextSummarizer;
3992
4183
  this.tools = config.tools ?? (config.agent ? getDefaultTools() : []);
3993
4184
  }
3994
4185
  /**
@@ -4006,6 +4197,7 @@ var QueryEngine = class {
4006
4197
  }
4007
4198
  this.abortController = new AbortController();
4008
4199
  const signal = this.abortController.signal;
4200
+ this.matchedRecipe = this.recipes?.match(prompt) ?? null;
4009
4201
  this.messages.push({
4010
4202
  role: "user",
4011
4203
  content: [{ type: "text", text: prompt }]
@@ -4064,10 +4256,18 @@ var QueryEngine = class {
4064
4256
  getMessages() {
4065
4257
  return this.messages;
4066
4258
  }
4259
+ getMatchedRecipe() {
4260
+ return this.matchedRecipe;
4261
+ }
4262
+ getContextBudget() {
4263
+ return this.contextBudget;
4264
+ }
4067
4265
  reset() {
4068
4266
  this.messages = [];
4069
4267
  this.costTracker.reset();
4268
+ this.contextBudget.reset();
4070
4269
  this.guardEvents = [];
4270
+ this.matchedRecipe = null;
4071
4271
  }
4072
4272
  getGuardEvents() {
4073
4273
  return this.guardEvents;
@@ -4117,6 +4317,13 @@ var QueryEngine = class {
4117
4317
  pendingToolCalls: []
4118
4318
  };
4119
4319
  try {
4320
+ if (this.contextBudget.shouldCompact()) {
4321
+ this.messages = await compactMessages(this.messages, {
4322
+ maxTokens: 1e5,
4323
+ keepRecentCount: 8,
4324
+ summarizer: this.contextSummarizer
4325
+ });
4326
+ }
4120
4327
  this.messages = validateHistory(this.messages);
4121
4328
  if (process.env.NODE_ENV !== "test") {
4122
4329
  const summary = this.messages.map((m, idx) => {
@@ -4134,9 +4341,23 @@ ${summary.join("\n")}`);
4134
4341
  }
4135
4342
  const thinkingEnabled = this.thinking && this.thinking.type !== "disabled";
4136
4343
  const effectiveToolChoice = thinkingEnabled ? applyToolChoice && turns === 1 ? "auto" : void 0 : applyToolChoice && turns === 1 ? this.toolChoice : void 0;
4344
+ let effectivePrompt = this.systemPrompt;
4345
+ if (this.matchedRecipe && this.recipes) {
4346
+ const recipeCtx = this.recipes.toPromptContext(this.matchedRecipe);
4347
+ if (typeof effectivePrompt === "string") {
4348
+ effectivePrompt = `${effectivePrompt}
4349
+
4350
+ ${recipeCtx}`;
4351
+ } else if (Array.isArray(effectivePrompt)) {
4352
+ effectivePrompt = [
4353
+ ...effectivePrompt,
4354
+ { type: "text", text: recipeCtx }
4355
+ ];
4356
+ }
4357
+ }
4137
4358
  const stream = this.provider.chat({
4138
4359
  messages: this.messages,
4139
- systemPrompt: this.systemPrompt,
4360
+ systemPrompt: effectivePrompt,
4140
4361
  tools: toolDefs,
4141
4362
  model: this.model,
4142
4363
  maxTokens: this.maxTokens,
@@ -4418,6 +4639,7 @@ ${summary.join("\n")}`);
4418
4639
  event.cacheReadTokens,
4419
4640
  event.cacheWriteTokens
4420
4641
  );
4642
+ this.contextBudget.update(event.inputTokens);
4421
4643
  yield {
4422
4644
  type: "usage",
4423
4645
  inputTokens: event.inputTokens,
@@ -4634,6 +4856,148 @@ var MemorySessionStore = class {
4634
4856
  }
4635
4857
  }
4636
4858
  };
4859
+ var StepRequirementSchema = z.object({
4860
+ step: z.string().optional(),
4861
+ field: z.string().optional(),
4862
+ confirmation: z.boolean().optional()
4863
+ });
4864
+ var OnErrorSchema = z.object({
4865
+ action: z.enum(["abort", "refuse", "report", "retry"]),
4866
+ message: z.string(),
4867
+ suggest: z.string().optional()
4868
+ });
4869
+ var StepSchema = z.object({
4870
+ name: z.string().min(1),
4871
+ tool: z.string().optional(),
4872
+ service: z.string().optional(),
4873
+ purpose: z.string().min(1),
4874
+ cost: z.string().optional(),
4875
+ output: z.object({ type: z.string(), key: z.string() }).optional(),
4876
+ gate: z.enum(["none", "preview", "review", "estimate"]).optional(),
4877
+ gate_prompt: z.string().optional(),
4878
+ requires: z.array(StepRequirementSchema).optional(),
4879
+ rules: z.array(z.string()).optional(),
4880
+ condition: z.string().optional(),
4881
+ notes: z.string().optional(),
4882
+ flags: z.record(z.unknown()).optional(),
4883
+ on_error: OnErrorSchema.optional(),
4884
+ input_template: z.record(z.string()).optional(),
4885
+ cost_per_unit: z.string().optional()
4886
+ });
4887
+ var RecipeSchema = z.object({
4888
+ name: z.string().min(1),
4889
+ description: z.string().min(1),
4890
+ triggers: z.array(z.string().min(1)).min(1),
4891
+ services: z.array(z.string()).optional(),
4892
+ prerequisites: z.array(z.object({ field: z.string(), prompt: z.string() })).optional(),
4893
+ steps: z.array(StepSchema).min(1)
4894
+ }).refine(
4895
+ (r) => {
4896
+ const names = r.steps.map((s) => s.name);
4897
+ return new Set(names).size === names.length;
4898
+ },
4899
+ { message: "Step names must be unique within a recipe" }
4900
+ );
4901
+ function loadRecipes(yamlDir) {
4902
+ const files = readdirSync(yamlDir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
4903
+ const recipes = [];
4904
+ for (const file of files) {
4905
+ const content = readFileSync(join(yamlDir, file), "utf-8");
4906
+ const raw = yaml.load(content);
4907
+ const parsed = RecipeSchema.parse(raw);
4908
+ recipes.push(parsed);
4909
+ }
4910
+ return recipes;
4911
+ }
4912
+ function parseRecipe(yamlContent) {
4913
+ const raw = yaml.load(yamlContent);
4914
+ return RecipeSchema.parse(raw);
4915
+ }
4916
+
4917
+ // src/recipes/registry.ts
4918
+ var RecipeRegistry = class {
4919
+ recipes = [];
4920
+ /** Load all recipes from a directory of YAML files. */
4921
+ loadDir(yamlDir) {
4922
+ this.recipes.push(...loadRecipes(yamlDir));
4923
+ }
4924
+ /** Register a single recipe from a YAML string. */
4925
+ loadYaml(yamlContent) {
4926
+ this.recipes.push(parseRecipe(yamlContent));
4927
+ }
4928
+ /** Register a pre-parsed Recipe object. */
4929
+ register(recipe) {
4930
+ this.recipes.push(recipe);
4931
+ }
4932
+ /** All loaded recipes. */
4933
+ all() {
4934
+ return this.recipes;
4935
+ }
4936
+ /**
4937
+ * Match a user message to the most specific recipe.
4938
+ * Longest trigger phrase match wins. Returns null if no match.
4939
+ */
4940
+ match(userMessage) {
4941
+ const normalized = userMessage.toLowerCase().trim();
4942
+ let best = null;
4943
+ let bestLength = 0;
4944
+ for (const recipe of this.recipes) {
4945
+ for (const trigger of recipe.triggers) {
4946
+ const triggerLower = trigger.toLowerCase();
4947
+ if (normalized.includes(triggerLower) && triggerLower.length > bestLength) {
4948
+ best = recipe;
4949
+ bestLength = triggerLower.length;
4950
+ }
4951
+ }
4952
+ }
4953
+ return best;
4954
+ }
4955
+ /**
4956
+ * Format a matched recipe as a compact context block for the system prompt.
4957
+ * Injected dynamically — only when the recipe matches.
4958
+ */
4959
+ toPromptContext(recipe) {
4960
+ const lines = [
4961
+ `## Active Recipe: ${recipe.name}`,
4962
+ recipe.description,
4963
+ "Follow these steps:"
4964
+ ];
4965
+ for (let i = 0; i < recipe.steps.length; i++) {
4966
+ const step = recipe.steps[i];
4967
+ const num = i + 1;
4968
+ const toolNote = step.tool ? ` \u2192 ${step.tool}` : "";
4969
+ const serviceNote = step.service ? ` (${step.service})` : "";
4970
+ const costNote = step.cost ? ` \u2014 ${step.cost}` : "";
4971
+ const gateNote = step.gate && step.gate !== "none" ? ` [GATE: ${step.gate}]` : "";
4972
+ let line = `${num}. ${step.name}${toolNote}${serviceNote}${costNote}${gateNote}`;
4973
+ if (step.gate_prompt) {
4974
+ line += ` \u2014 "${step.gate_prompt}"`;
4975
+ }
4976
+ lines.push(line);
4977
+ if (step.rules?.length) {
4978
+ for (const rule of step.rules) {
4979
+ lines.push(` - ${rule}`);
4980
+ }
4981
+ }
4982
+ if (step.notes) {
4983
+ lines.push(` Note: ${step.notes}`);
4984
+ }
4985
+ if (step.on_error) {
4986
+ lines.push(` On error: ${step.on_error.action} \u2014 ${step.on_error.message}`);
4987
+ }
4988
+ if (step.condition) {
4989
+ lines.push(` Condition: ${step.condition}`);
4990
+ }
4991
+ }
4992
+ if (recipe.prerequisites?.length) {
4993
+ lines.push("Prerequisites (ask before starting):");
4994
+ for (const pre of recipe.prerequisites) {
4995
+ lines.push(`- ${pre.field}: "${pre.prompt}"`);
4996
+ }
4997
+ }
4998
+ return lines.join("\n");
4999
+ }
5000
+ };
4637
5001
 
4638
5002
  // src/classify-effort.ts
4639
5003
  function classifyEffort(model, userMessage, matchedRecipe, sessionWriteCount) {
@@ -4794,120 +5158,6 @@ function buildStateContext(state) {
4794
5158
  }
4795
5159
  }
4796
5160
 
4797
- // src/context.ts
4798
- var CHARS_PER_TOKEN = 4;
4799
- function estimateTokens(messages) {
4800
- let chars = 0;
4801
- for (const msg of messages) {
4802
- for (const block of msg.content) {
4803
- chars += blockCharCount(block);
4804
- }
4805
- }
4806
- return Math.ceil(chars / CHARS_PER_TOKEN);
4807
- }
4808
- function blockCharCount(block) {
4809
- switch (block.type) {
4810
- case "text":
4811
- return block.text.length;
4812
- case "thinking":
4813
- return block.thinking.length;
4814
- case "redacted_thinking":
4815
- return block.data.length;
4816
- case "tool_use":
4817
- return block.name.length + JSON.stringify(block.input).length;
4818
- case "tool_result":
4819
- return block.content.length;
4820
- }
4821
- }
4822
- function compactMessages(messages, opts = {}) {
4823
- const maxTokens = opts.maxTokens ?? 1e5;
4824
- const keepRecent = opts.keepRecentCount ?? 6;
4825
- const systemTokens = opts.systemPromptTokens ?? 500;
4826
- const budget = maxTokens - systemTokens;
4827
- if (messages.length === 0) return [];
4828
- const mutable = messages.map((m) => ({
4829
- role: m.role,
4830
- content: m.content.map((b) => ({ ...b }))
4831
- }));
4832
- if (estimateTokens(mutable) <= budget) return mutable;
4833
- const splitIdx = Math.max(0, mutable.length - keepRecent);
4834
- for (let i = 0; i < splitIdx; i++) {
4835
- mutable[i].content = mutable[i].content.map((block) => {
4836
- if (block.type === "tool_result" && block.content.length > 200) {
4837
- return {
4838
- ...block,
4839
- content: truncateToolResult(block.content)
4840
- };
4841
- }
4842
- return block;
4843
- });
4844
- }
4845
- if (estimateTokens(mutable) <= budget) return mutable;
4846
- const first = mutable[0];
4847
- const recent = mutable.slice(splitIdx);
4848
- const oldSection = mutable.slice(1, splitIdx);
4849
- while (oldSection.length > 0 && estimateTokens([first, ...oldSection, ...recent]) > budget) {
4850
- oldSection.shift();
4851
- }
4852
- const compacted = [first, ...oldSection, ...recent];
4853
- if (estimateTokens(compacted) > budget) {
4854
- for (const msg of compacted) {
4855
- msg.content = msg.content.map((block) => {
4856
- if (block.type === "tool_result" && block.content.length > 100) {
4857
- return { ...block, content: truncateToolResult(block.content) };
4858
- }
4859
- return block;
4860
- });
4861
- }
4862
- }
4863
- return sanitizeMessages(compacted);
4864
- }
4865
- function sanitizeMessages(messages) {
4866
- const toolUseIds = /* @__PURE__ */ new Set();
4867
- const toolResultIds = /* @__PURE__ */ new Set();
4868
- for (const msg of messages) {
4869
- for (const block of msg.content) {
4870
- if (block.type === "tool_use") toolUseIds.add(block.id);
4871
- if (block.type === "tool_result") toolResultIds.add(block.toolUseId);
4872
- }
4873
- }
4874
- return messages.map((msg) => {
4875
- const filtered = msg.content.filter((block) => {
4876
- if (block.type === "tool_result") return toolUseIds.has(block.toolUseId);
4877
- if (block.type === "tool_use") return toolResultIds.has(block.id);
4878
- return true;
4879
- });
4880
- if (filtered.length === 0) return null;
4881
- return { ...msg, content: filtered };
4882
- }).filter((m) => m !== null);
4883
- }
4884
- function truncateToolResult(content) {
4885
- try {
4886
- const parsed = JSON.parse(content);
4887
- if (parsed.error) {
4888
- return JSON.stringify({ error: parsed.error });
4889
- }
4890
- if (typeof parsed === "object" && parsed !== null) {
4891
- const summary = {};
4892
- for (const [key, value] of Object.entries(parsed)) {
4893
- if (typeof value === "number" || typeof value === "boolean") {
4894
- summary[key] = value;
4895
- } else if (typeof value === "string") {
4896
- summary[key] = value.length > 50 ? value.slice(0, 50) + "\u2026" : value;
4897
- } else if (Array.isArray(value)) {
4898
- summary[key] = `[${value.length} items]`;
4899
- } else {
4900
- summary[key] = "{\u2026}";
4901
- }
4902
- }
4903
- return JSON.stringify(summary);
4904
- }
4905
- return content.slice(0, 100);
4906
- } catch {
4907
- return content.slice(0, 100);
4908
- }
4909
- }
4910
-
4911
5161
  // src/mcp.ts
4912
5162
  function buildMcpTools(context, tools) {
4913
5163
  const engineTools = tools ?? getDefaultTools();
@@ -5475,6 +5725,6 @@ function sanitizeAnthropicMessages(messages) {
5475
5725
  return merged;
5476
5726
  }
5477
5727
 
5478
- export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_SYSTEM_PROMPT, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_SERVER_NAME, NaviTools, QueryEngine, READ_TOOLS, RetryTracker, TOOL_FLAGS, TxMutex, WRITE_TOOLS, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, balanceCheckTool, borrowTool, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, claimRewardsTool, classifyEffort, clearPriceCache, compactMessages, createGuardRunnerState, defillamaChainTvlTool, defillamaPriceChangeTool, defillamaProtocolFeesTool, defillamaProtocolInfoTool, defillamaSuiProtocolsTool, defillamaTokenPricesTool, defillamaYieldPoolsTool, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getDefaultTools, getMcpManager, getToolFlags, getWalletAddress, guardArtifactPreview, guardStaleData, hasNaviMcp, healthCheckTool, mppServicesTool, parseMcpJson, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
5728
+ export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_SYSTEM_PROMPT, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_SERVER_NAME, NaviTools, QueryEngine, READ_TOOLS, RecipeRegistry, RetryTracker, TOOL_FLAGS, TxMutex, WRITE_TOOLS, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, balanceCheckTool, borrowTool, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, claimRewardsTool, classifyEffort, clearPriceCache, compactMessages, createGuardRunnerState, defillamaChainTvlTool, defillamaPriceChangeTool, defillamaProtocolFeesTool, defillamaProtocolInfoTool, defillamaSuiProtocolsTool, defillamaTokenPricesTool, defillamaYieldPoolsTool, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getDefaultTools, getMcpManager, getToolFlags, getWalletAddress, guardArtifactPreview, guardStaleData, hasNaviMcp, healthCheckTool, loadRecipes, mppServicesTool, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
5479
5729
  //# sourceMappingURL=index.js.map
5480
5730
  //# sourceMappingURL=index.js.map