@albalink/agent 1.0.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.
Files changed (67) hide show
  1. package/README.md +91 -0
  2. package/bin/albacli +31 -0
  3. package/dist/api/ExtensionAPI.d.ts +103 -0
  4. package/dist/api/ExtensionAPI.js +15 -0
  5. package/dist/api/Registry.d.ts +54 -0
  6. package/dist/api/Registry.js +103 -0
  7. package/dist/cli.d.ts +6 -0
  8. package/dist/cli.js +230 -0
  9. package/dist/index.d.ts +41 -0
  10. package/dist/index.js +41 -0
  11. package/dist/loader.d.ts +16 -0
  12. package/dist/loader.js +89 -0
  13. package/dist/mcp/entry.d.ts +2 -0
  14. package/dist/mcp/entry.js +71 -0
  15. package/dist/mcp/server.d.ts +31 -0
  16. package/dist/mcp/server.js +128 -0
  17. package/dist/models/CostTracker.d.ts +67 -0
  18. package/dist/models/CostTracker.js +151 -0
  19. package/dist/models/ModelRegistry.d.ts +159 -0
  20. package/dist/models/ModelRegistry.js +500 -0
  21. package/dist/models/index.d.ts +5 -0
  22. package/dist/models/index.js +3 -0
  23. package/dist/runner/AgentRunner.d.ts +88 -0
  24. package/dist/runner/AgentRunner.js +473 -0
  25. package/dist/runner/ModelClient.d.ts +97 -0
  26. package/dist/runner/ModelClient.js +350 -0
  27. package/dist/runner/SwarmRouter.d.ts +64 -0
  28. package/dist/runner/SwarmRouter.js +216 -0
  29. package/dist/runner/ToolDispatcher.d.ts +29 -0
  30. package/dist/runner/ToolDispatcher.js +168 -0
  31. package/dist/scheduler/AgentScheduler.d.ts +119 -0
  32. package/dist/scheduler/AgentScheduler.js +263 -0
  33. package/dist/server-entry.d.ts +11 -0
  34. package/dist/server-entry.js +15 -0
  35. package/dist/session/ContextStore.d.ts +96 -0
  36. package/dist/session/ContextStore.js +207 -0
  37. package/dist/session/GoalManager.d.ts +101 -0
  38. package/dist/session/GoalManager.js +167 -0
  39. package/dist/session/MemoryStore.d.ts +48 -0
  40. package/dist/session/MemoryStore.js +167 -0
  41. package/dist/session/SessionManager.d.ts +64 -0
  42. package/dist/session/SessionManager.js +193 -0
  43. package/dist/telemetry/Tracer.d.ts +48 -0
  44. package/dist/telemetry/Tracer.js +102 -0
  45. package/dist/tools/MarketSentiment.d.ts +166 -0
  46. package/dist/tools/MarketSentiment.js +209 -0
  47. package/dist/tools/NewsSentiment.d.ts +67 -0
  48. package/dist/tools/NewsSentiment.js +226 -0
  49. package/dist/tools/PriceFeed.d.ts +105 -0
  50. package/dist/tools/PriceFeed.js +282 -0
  51. package/dist/tools/TechnicalAnalysis.d.ts +110 -0
  52. package/dist/tools/TechnicalAnalysis.js +357 -0
  53. package/dist/tools/index.d.ts +7 -0
  54. package/dist/tools/index.js +4 -0
  55. package/dist/tui/App.d.ts +17 -0
  56. package/dist/tui/App.js +225 -0
  57. package/dist/tui/ModelSelector.d.ts +12 -0
  58. package/dist/tui/ModelSelector.js +87 -0
  59. package/dist/tui/REPL.d.ts +24 -0
  60. package/dist/tui/REPL.js +51 -0
  61. package/dist/tui/StatusBar.d.ts +14 -0
  62. package/dist/tui/StatusBar.js +14 -0
  63. package/dist/tui/theme.d.ts +30 -0
  64. package/dist/tui/theme.js +41 -0
  65. package/dist/util/safeLog.d.ts +3 -0
  66. package/dist/util/safeLog.js +21 -0
  67. package/package.json +67 -0
@@ -0,0 +1,64 @@
1
+ /**
2
+ * SessionManager — manages conversation history, compaction, and persistence.
3
+ *
4
+ * Compaction is done in atomic turn pairs so tool_call_id references are
5
+ * never orphaned (which causes 400 errors from every provider).
6
+ *
7
+ * Three compaction tiers:
8
+ * Tier 1 (>70%): trim long tool results to 1-line summaries
9
+ * Tier 2 (>85%): drop oldest complete turns (atomic pairs only)
10
+ * Tier 3 (>95%): hard reset keeping only last KEEP_TURNS turns
11
+ */
12
+ import type { Message } from "../runner/ModelClient.js";
13
+ /** Context pressure levels for UI display and swarm gating */
14
+ export interface ContextPressure {
15
+ chars: number;
16
+ pct: number;
17
+ level: "green" | "yellow" | "red" | "critical";
18
+ turboReady: boolean;
19
+ }
20
+ export declare class SessionManager {
21
+ private history;
22
+ private systemPrompt;
23
+ setSystemPrompt(prompt: string): void;
24
+ getSystemPrompt(): string;
25
+ addMessage(msg: Message): void;
26
+ addMessages(msgs: Message[]): void;
27
+ /** Returns messages ready to send to the model — system prompt prepended */
28
+ getMessages(): Message[];
29
+ /** Full raw history (no system prompt) */
30
+ getHistory(): Message[];
31
+ clear(): void;
32
+ charCount(): number;
33
+ getContextPressure(): ContextPressure;
34
+ private buildSystemContent;
35
+ /**
36
+ * Split history into atomic turns.
37
+ * A turn = [user_msg, assistant_msg, ...tool_result_msgs]
38
+ * Keeping turns atomic prevents orphaned tool_call_id errors.
39
+ */
40
+ private splitIntoTurns;
41
+ /**
42
+ * Tier 1: Trim long tool results in-place. No messages dropped.
43
+ * Replaces content >TOOL_RESULT_CAP chars with a 1-line summary.
44
+ */
45
+ private trimToolResults;
46
+ /**
47
+ * Tier 2: Drop oldest turns, but ANCHOR high-value messages (prices, signals,
48
+ * decisions) so they survive compaction. (#36 semantic anchor compaction)
49
+ */
50
+ private dropOldTurns;
51
+ /** #36: Score a message's semantic importance (0-10) */
52
+ private messageWeight;
53
+ maybeCompact(): void;
54
+ /** Force compaction */
55
+ forceCompact(): void;
56
+ /**
57
+ * #32: Tier-2 summarization via a cheap model.
58
+ * Compresses the oldest 40% of turns into a single summary message.
59
+ * Call this when pct is between 70-90 to reclaim space gracefully.
60
+ * @param summarizeCallback — provided by AgentRunner which has model access
61
+ */
62
+ summarizeOldTurns(summarizeCallback: (messages: Message[]) => Promise<string>): Promise<void>;
63
+ }
64
+ //# sourceMappingURL=SessionManager.d.ts.map
@@ -0,0 +1,193 @@
1
+ /**
2
+ * SessionManager — manages conversation history, compaction, and persistence.
3
+ *
4
+ * Compaction is done in atomic turn pairs so tool_call_id references are
5
+ * never orphaned (which causes 400 errors from every provider).
6
+ *
7
+ * Three compaction tiers:
8
+ * Tier 1 (>70%): trim long tool results to 1-line summaries
9
+ * Tier 2 (>85%): drop oldest complete turns (atomic pairs only)
10
+ * Tier 3 (>95%): hard reset keeping only last KEEP_TURNS turns
11
+ */
12
+ const MAX_HISTORY_CHARS = 80_000; // ~20k tokens rough estimate
13
+ const KEEP_TURNS = 8; // complete turns to keep on hard reset
14
+ const TOOL_RESULT_CAP = 500; // trim tool results longer than this
15
+ export class SessionManager {
16
+ history = [];
17
+ systemPrompt = "";
18
+ setSystemPrompt(prompt) {
19
+ this.systemPrompt = prompt;
20
+ }
21
+ getSystemPrompt() {
22
+ return this.systemPrompt;
23
+ }
24
+ addMessage(msg) {
25
+ this.history.push(msg);
26
+ this.maybeCompact();
27
+ }
28
+ addMessages(msgs) {
29
+ for (const m of msgs)
30
+ this.history.push(m);
31
+ this.maybeCompact();
32
+ }
33
+ /** Returns messages ready to send to the model — system prompt prepended */
34
+ getMessages() {
35
+ const sys = { role: "system", content: this.buildSystemContent() };
36
+ return [sys, ...this.history];
37
+ }
38
+ /** Full raw history (no system prompt) */
39
+ getHistory() {
40
+ return [...this.history];
41
+ }
42
+ clear() {
43
+ this.history = [];
44
+ }
45
+ charCount() {
46
+ return this.history.reduce((n, m) => n + (typeof m.content === "string" ? m.content.length : 0), 0);
47
+ }
48
+ getContextPressure() {
49
+ const chars = this.charCount();
50
+ const pct = Math.min(100, Math.round(chars / MAX_HISTORY_CHARS * 100));
51
+ return {
52
+ chars,
53
+ pct,
54
+ level: pct < 50 ? "green" : pct < 70 ? "yellow" : pct < 90 ? "red" : "critical",
55
+ turboReady: pct < 70, // keep 30% free for swarm sub-agent outputs
56
+ };
57
+ }
58
+ buildSystemContent() {
59
+ return this.systemPrompt || "You are ALBA, an AI trading agent.";
60
+ }
61
+ /**
62
+ * Split history into atomic turns.
63
+ * A turn = [user_msg, assistant_msg, ...tool_result_msgs]
64
+ * Keeping turns atomic prevents orphaned tool_call_id errors.
65
+ */
66
+ splitIntoTurns() {
67
+ const turns = [];
68
+ let current = [];
69
+ for (const msg of this.history) {
70
+ // New user message starts a new turn (unless history starts with assistant)
71
+ if (msg.role === "user" && current.length > 0) {
72
+ turns.push(current);
73
+ current = [];
74
+ }
75
+ current.push(msg);
76
+ }
77
+ if (current.length > 0)
78
+ turns.push(current);
79
+ return turns;
80
+ }
81
+ /**
82
+ * Tier 1: Trim long tool results in-place. No messages dropped.
83
+ * Replaces content >TOOL_RESULT_CAP chars with a 1-line summary.
84
+ */
85
+ trimToolResults() {
86
+ for (const msg of this.history) {
87
+ if (msg.role === "tool" && typeof msg.content === "string" &&
88
+ msg.content.length > TOOL_RESULT_CAP) {
89
+ const firstLine = msg.content.split("\n")[0] ?? msg.content.slice(0, 120);
90
+ msg.content = `${firstLine} … [trimmed, ${msg.content.length} chars]`;
91
+ }
92
+ }
93
+ }
94
+ /**
95
+ * Tier 2: Drop oldest turns, but ANCHOR high-value messages (prices, signals,
96
+ * decisions) so they survive compaction. (#36 semantic anchor compaction)
97
+ */
98
+ dropOldTurns() {
99
+ const turns = this.splitIntoTurns();
100
+ if (turns.length <= KEEP_TURNS)
101
+ return;
102
+ const recentTurns = turns.slice(-KEEP_TURNS);
103
+ const olderTurns = turns.slice(0, -KEEP_TURNS);
104
+ // #36: From older turns, extract high-weight messages as anchors
105
+ const anchors = [];
106
+ for (const turn of olderTurns) {
107
+ for (const msg of turn) {
108
+ if (this.messageWeight(msg) >= 7)
109
+ anchors.push(msg);
110
+ }
111
+ }
112
+ // Prepend anchors (deduped) before the recent window
113
+ const anchorIds = new Set(anchors.map(m => `${m.role}:${String(m.content).slice(0, 50)}`));
114
+ const recentFlat = recentTurns.flat();
115
+ // Remove any anchors already in recent window
116
+ const recentIds = new Set(recentFlat.map(m => `${m.role}:${String(m.content).slice(0, 50)}`));
117
+ const dedupedAnchors = anchors.filter(m => !recentIds.has(`${m.role}:${String(m.content).slice(0, 50)}`));
118
+ this.history = [...dedupedAnchors, ...recentFlat];
119
+ void anchorIds; // suppress unused warning
120
+ }
121
+ /** #36: Score a message's semantic importance (0-10) */
122
+ messageWeight(msg) {
123
+ if (msg.role === "system")
124
+ return 10;
125
+ const content = typeof msg.content === "string" ? msg.content.toLowerCase() : "";
126
+ if (msg.role === "tool") {
127
+ // High value: price data, signals, positions, goals
128
+ if (/\$[\d,]+|\d+%|signal|buy|sell|position|goal|rsi|macd/.test(content))
129
+ return 8;
130
+ if (/news|sentiment|bullish|bearish|tvl|funding/.test(content))
131
+ return 6;
132
+ return 2; // generic tool result — expendable
133
+ }
134
+ if (msg.role === "user")
135
+ return 3;
136
+ if (msg.role === "assistant") {
137
+ // Keep assistant messages with decisions/recommendations
138
+ if (/recommend|suggest|should|will|plan|strategy|target|stop/.test(content))
139
+ return 7;
140
+ return 4;
141
+ }
142
+ return 1;
143
+ }
144
+ maybeCompact() {
145
+ const pct = this.getContextPressure().pct;
146
+ if (pct < 70)
147
+ return;
148
+ if (pct < 85) {
149
+ this.trimToolResults();
150
+ return;
151
+ } // Tier 1: trim verbose tool results
152
+ if (pct < 95) {
153
+ this.trimToolResults();
154
+ this.dropOldTurns();
155
+ return;
156
+ } // Tier 2: drop turns
157
+ // Tier 3: hard reset — emergency
158
+ this.trimToolResults();
159
+ this.dropOldTurns();
160
+ if (this.getContextPressure().pct >= 95) {
161
+ const turns = this.splitIntoTurns();
162
+ this.history = turns.slice(-4).flat();
163
+ }
164
+ }
165
+ /** Force compaction */
166
+ forceCompact() {
167
+ this.trimToolResults();
168
+ this.dropOldTurns();
169
+ }
170
+ /**
171
+ * #32: Tier-2 summarization via a cheap model.
172
+ * Compresses the oldest 40% of turns into a single summary message.
173
+ * Call this when pct is between 70-90 to reclaim space gracefully.
174
+ * @param summarizeCallback — provided by AgentRunner which has model access
175
+ */
176
+ async summarizeOldTurns(summarizeCallback) {
177
+ const turns = this.splitIntoTurns();
178
+ if (turns.length < 4)
179
+ return; // not enough history to summarize
180
+ const splitAt = Math.floor(turns.length * 0.4);
181
+ const toSummarize = turns.slice(0, splitAt).flat();
182
+ const toKeep = turns.slice(splitAt).flat();
183
+ const summary = await summarizeCallback(toSummarize);
184
+ this.history = [
185
+ {
186
+ role: "system",
187
+ content: `[CONVERSATION SUMMARY — ${toSummarize.length} earlier messages compressed]\n${summary}`,
188
+ },
189
+ ...toKeep,
190
+ ];
191
+ }
192
+ }
193
+ //# sourceMappingURL=SessionManager.js.map
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Tracer — lightweight JSONL span tracing for agent observability. (#30)
3
+ *
4
+ * Zero external dependencies. Writes structured traces to ~/.alba/traces.jsonl.
5
+ * Each trace covers one user turn and records all model calls, tool dispatches,
6
+ * and swarm sub-tasks with timing and status.
7
+ *
8
+ * View traces: cat ~/.alba/traces.jsonl | jq
9
+ * Last 5 traces: tail -5 ~/.alba/traces.jsonl | jq
10
+ * /traces command in REPL shows a formatted summary.
11
+ */
12
+ export interface Span {
13
+ spanId: string;
14
+ name: string;
15
+ startMs: number;
16
+ durationMs?: number;
17
+ status: "ok" | "error" | "aborted";
18
+ attrs: Record<string, unknown>;
19
+ }
20
+ export interface Trace {
21
+ traceId: string;
22
+ sessionId: string;
23
+ prompt: string;
24
+ startMs: number;
25
+ durationMs?: number;
26
+ spans: Span[];
27
+ totalCost?: number;
28
+ modelUsed?: string;
29
+ }
30
+ export declare class Tracer {
31
+ /** @internal exposed for AgentRunner span lookup */
32
+ readonly trace: Trace;
33
+ constructor(sessionId: string, prompt: string);
34
+ /** Start a named span, returns spanId */
35
+ startSpan(name: string, attrs?: Record<string, unknown>): string;
36
+ /** End a span by ID */
37
+ endSpan(spanId: string, status?: "ok" | "error" | "aborted", attrs?: Record<string, unknown>): void;
38
+ /** Record model call details */
39
+ recordModel(spanId: string, model: string, promptTokens: number, completionTokens: number, costNano: number): void;
40
+ /** Flush trace to disk */
41
+ flush(status?: "ok" | "error" | "aborted"): void;
42
+ get traceId(): string;
43
+ /** Read last N traces from disk for /traces command */
44
+ static readRecent(limit?: number): Trace[];
45
+ /** Format traces for REPL display */
46
+ static formatSummary(traces: Trace[]): string;
47
+ }
48
+ //# sourceMappingURL=Tracer.d.ts.map
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Tracer — lightweight JSONL span tracing for agent observability. (#30)
3
+ *
4
+ * Zero external dependencies. Writes structured traces to ~/.alba/traces.jsonl.
5
+ * Each trace covers one user turn and records all model calls, tool dispatches,
6
+ * and swarm sub-tasks with timing and status.
7
+ *
8
+ * View traces: cat ~/.alba/traces.jsonl | jq
9
+ * Last 5 traces: tail -5 ~/.alba/traces.jsonl | jq
10
+ * /traces command in REPL shows a formatted summary.
11
+ */
12
+ import { appendFileSync, existsSync, readFileSync, mkdirSync } from "node:fs";
13
+ import { join } from "node:path";
14
+ import { homedir } from "node:os";
15
+ import { randomUUID } from "node:crypto";
16
+ const ALBA_HOME = process.env.ALBA_HOME ?? join(homedir(), ".alba");
17
+ const TRACES_FILE = join(ALBA_HOME, "traces.jsonl");
18
+ export class Tracer {
19
+ /** @internal exposed for AgentRunner span lookup */
20
+ trace;
21
+ constructor(sessionId, prompt) {
22
+ this.trace = {
23
+ traceId: randomUUID().slice(0, 12),
24
+ sessionId,
25
+ prompt: prompt.slice(0, 200),
26
+ startMs: Date.now(),
27
+ spans: [],
28
+ };
29
+ }
30
+ /** Start a named span, returns spanId */
31
+ startSpan(name, attrs = {}) {
32
+ const spanId = randomUUID().slice(0, 8);
33
+ this.trace.spans.push({ spanId, name, startMs: Date.now(), status: "ok", attrs });
34
+ return spanId;
35
+ }
36
+ /** End a span by ID */
37
+ endSpan(spanId, status = "ok", attrs = {}) {
38
+ const span = this.trace.spans.find(s => s.spanId === spanId);
39
+ if (!span)
40
+ return;
41
+ span.durationMs = Date.now() - span.startMs;
42
+ span.status = status;
43
+ Object.assign(span.attrs, attrs);
44
+ }
45
+ /** Record model call details */
46
+ recordModel(spanId, model, promptTokens, completionTokens, costNano) {
47
+ this.endSpan(spanId, "ok", { model, promptTokens, completionTokens, costNano });
48
+ this.trace.modelUsed = model;
49
+ this.trace.totalCost = (this.trace.totalCost ?? 0) + costNano;
50
+ }
51
+ /** Flush trace to disk */
52
+ flush(status = "ok") {
53
+ this.trace.durationMs = Date.now() - this.trace.startMs;
54
+ try {
55
+ mkdirSync(ALBA_HOME, { recursive: true });
56
+ appendFileSync(TRACES_FILE, JSON.stringify({ ...this.trace, status, ts: Date.now() }) + "\n", "utf-8");
57
+ }
58
+ catch { /* best effort — tracing should never crash the agent */ }
59
+ }
60
+ get traceId() { return this.trace.traceId; }
61
+ // ── Static helpers ────────────────────────────────────────────────────────
62
+ /** Read last N traces from disk for /traces command */
63
+ static readRecent(limit = 5) {
64
+ try {
65
+ if (!existsSync(TRACES_FILE))
66
+ return [];
67
+ const lines = readFileSync(TRACES_FILE, "utf-8")
68
+ .trim().split("\n").filter(Boolean);
69
+ return lines.slice(-limit).map(l => JSON.parse(l)).reverse();
70
+ }
71
+ catch {
72
+ return [];
73
+ }
74
+ }
75
+ /** Format traces for REPL display */
76
+ static formatSummary(traces) {
77
+ if (traces.length === 0)
78
+ return "No traces recorded yet.";
79
+ return traces.map(t => {
80
+ const duration = t.durationMs ? `${(t.durationMs / 1000).toFixed(1)}s` : "?s";
81
+ const model = t.modelUsed?.split("/").pop()?.slice(0, 20) ?? "?";
82
+ const spans = t.spans.length;
83
+ const tools = t.spans.filter(s => s.name.startsWith("tool:")).length;
84
+ const cost = t.totalCost ? `$${(t.totalCost / 1_000_000_000).toFixed(4)}` : "?";
85
+ const prompt = t.prompt.slice(0, 60);
86
+ const errors = t.spans.filter(s => s.status === "error").length;
87
+ const lines = [
88
+ `[${t.traceId}] ${new Date(t.startMs).toLocaleTimeString()} — ${duration} · ${model} · ${cost}`,
89
+ ` Prompt: "${prompt}"`,
90
+ ` Spans: ${spans} total, ${tools} tool calls${errors > 0 ? `, ${errors} errors` : ""}`,
91
+ ];
92
+ // Show tool spans
93
+ for (const span of t.spans.filter(s => s.name.startsWith("tool:"))) {
94
+ const icon = span.status === "ok" ? "✓" : "✗";
95
+ const dur = span.durationMs ? `${span.durationMs}ms` : "?";
96
+ lines.push(` ${icon} ${span.name.slice(5)} (${dur})`);
97
+ }
98
+ return lines.join("\n");
99
+ }).join("\n\n");
100
+ }
101
+ }
102
+ //# sourceMappingURL=Tracer.js.map
@@ -0,0 +1,166 @@
1
+ /**
2
+ * MarketSentiment — free, no-key market data tools.
3
+ *
4
+ * #20: Fear & Greed Index (alternative.me)
5
+ * #19: BTC Mempool stats (mempool.space — free, no key)
6
+ * #19: ETH / EVM Gas prices (blocknative public — free)
7
+ * #19: Solana TPS (public RPC — no key)
8
+ * #19: DeFi TVL by chain (DeFiLlama — free, no key)
9
+ * #20: Binance perp funding rates (public endpoint — no key)
10
+ */
11
+ import { type Static } from "@sinclair/typebox";
12
+ export declare const fearGreedParams: import("@sinclair/typebox").TObject<{
13
+ days: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
14
+ }>;
15
+ export declare function getFearGreedTool(_id: string, params: Static<typeof fearGreedParams>): Promise<{
16
+ content: {
17
+ type: "text";
18
+ text: string;
19
+ }[];
20
+ details: {
21
+ current: number;
22
+ classification: string;
23
+ avg7: number;
24
+ trend: number[];
25
+ direction: string;
26
+ };
27
+ } | {
28
+ content: {
29
+ type: "text";
30
+ text: string;
31
+ }[];
32
+ details: {
33
+ current?: undefined;
34
+ classification?: undefined;
35
+ avg7?: undefined;
36
+ trend?: undefined;
37
+ direction?: undefined;
38
+ };
39
+ }>;
40
+ export declare const fundingRatesParams: import("@sinclair/typebox").TObject<{
41
+ symbol: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
42
+ limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
43
+ }>;
44
+ export declare function getFundingRatesTool(_id: string, params: Static<typeof fundingRatesParams>): Promise<{
45
+ content: {
46
+ type: "text";
47
+ text: string;
48
+ }[];
49
+ details: {
50
+ symbol: string;
51
+ currentRate: number;
52
+ annualizedPct: number;
53
+ sentiment: string;
54
+ history: {
55
+ fundingRate: string;
56
+ fundingTime: number;
57
+ }[];
58
+ };
59
+ } | {
60
+ content: {
61
+ type: "text";
62
+ text: string;
63
+ }[];
64
+ details: {
65
+ symbol?: undefined;
66
+ currentRate?: undefined;
67
+ annualizedPct?: undefined;
68
+ sentiment?: undefined;
69
+ history?: undefined;
70
+ };
71
+ }>;
72
+ export declare const btcMempoolParams: import("@sinclair/typebox").TObject<{}>;
73
+ export declare function getBtcMempoolTool(): Promise<{
74
+ content: {
75
+ type: "text";
76
+ text: string;
77
+ }[];
78
+ details: {
79
+ pendingTxs: number;
80
+ vsizeMB: number;
81
+ fees: {
82
+ fastestFee: number;
83
+ halfHourFee: number;
84
+ hourFee: number;
85
+ economyFee: number;
86
+ };
87
+ };
88
+ } | {
89
+ content: {
90
+ type: "text";
91
+ text: string;
92
+ }[];
93
+ details: {
94
+ pendingTxs?: undefined;
95
+ vsizeMB?: undefined;
96
+ fees?: undefined;
97
+ };
98
+ }>;
99
+ export declare const defiTvlParams: import("@sinclair/typebox").TObject<{
100
+ chain: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
101
+ }>;
102
+ export declare function getDefiTvlTool(_id: string, params: Static<typeof defiTvlParams>): Promise<{
103
+ content: {
104
+ type: "text";
105
+ text: string;
106
+ }[];
107
+ details: {
108
+ chain: string;
109
+ tvl: number;
110
+ change7d: string | null;
111
+ chains?: undefined;
112
+ totalTvl?: undefined;
113
+ };
114
+ } | {
115
+ content: {
116
+ type: "text";
117
+ text: string;
118
+ }[];
119
+ details: {
120
+ chains: {
121
+ name: string;
122
+ tvl: number;
123
+ }[];
124
+ totalTvl: number;
125
+ chain?: undefined;
126
+ tvl?: undefined;
127
+ change7d?: undefined;
128
+ };
129
+ } | {
130
+ content: {
131
+ type: "text";
132
+ text: string;
133
+ }[];
134
+ details: {
135
+ chain?: undefined;
136
+ tvl?: undefined;
137
+ change7d?: undefined;
138
+ chains?: undefined;
139
+ totalTvl?: undefined;
140
+ };
141
+ }>;
142
+ export declare const solanaStatsParams: import("@sinclair/typebox").TObject<{}>;
143
+ export declare function getSolanaStatsTool(): Promise<{
144
+ content: {
145
+ type: "text";
146
+ text: string;
147
+ }[];
148
+ details: {
149
+ avgTps: number;
150
+ maxTps: number;
151
+ latestSlot: number;
152
+ samples: number[];
153
+ };
154
+ } | {
155
+ content: {
156
+ type: "text";
157
+ text: string;
158
+ }[];
159
+ details: {
160
+ avgTps?: undefined;
161
+ maxTps?: undefined;
162
+ latestSlot?: undefined;
163
+ samples?: undefined;
164
+ };
165
+ }>;
166
+ //# sourceMappingURL=MarketSentiment.d.ts.map