agents 0.21.0 → 0.23.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/README.md +21 -1
- package/dist/{agent-tool-types-CzGGB-20.d.ts → agent-routing-DE5zmCQ8.d.ts} +1844 -1336
- package/dist/agent-routing.d.ts +14 -0
- package/dist/agent-routing.js +187 -0
- package/dist/agent-routing.js.map +1 -0
- package/dist/agent-tool-types.d.ts +26 -26
- package/dist/{agent-tools-zR2d5uij.d.ts → agent-tools-DtXMTDGM.d.ts} +7 -7
- package/dist/agent-tools.d.ts +21 -21
- package/dist/agent-tools.js +2 -1
- package/dist/agent-tools.js.map +1 -1
- package/dist/browser/ai.js +6 -2
- package/dist/browser/ai.js.map +1 -1
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
- package/dist/callable-decorator.d.ts +18 -0
- package/dist/callable-decorator.js +71 -0
- package/dist/callable-decorator.js.map +1 -0
- package/dist/capability-BjSKYpzg.js +42 -0
- package/dist/capability-BjSKYpzg.js.map +1 -0
- package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
- package/dist/channel-Bnm4S7T2.d.ts +491 -0
- package/dist/channels/ai-sdk.d.ts +46 -0
- package/dist/channels/ai-sdk.js +120 -0
- package/dist/channels/ai-sdk.js.map +1 -0
- package/dist/channels/email.d.ts +95 -0
- package/dist/channels/email.js +323 -0
- package/dist/channels/email.js.map +1 -0
- package/dist/channels/index.d.ts +233 -0
- package/dist/channels/index.js +608 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/slack.d.ts +140 -0
- package/dist/channels/slack.js +614 -0
- package/dist/channels/slack.js.map +1 -0
- package/dist/channels/tanstack-ai.d.ts +39 -0
- package/dist/channels/tanstack-ai.js +17 -0
- package/dist/channels/tanstack-ai.js.map +1 -0
- package/dist/channels/telegram.d.ts +106 -0
- package/dist/channels/telegram.js +427 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/voice.d.ts +45 -0
- package/dist/channels/voice.js +122 -0
- package/dist/channels/voice.js.map +1 -0
- package/dist/chat/index.d.ts +2328 -2015
- package/dist/chat/index.js +891 -521
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +14 -1
- package/dist/chat/react.js +82 -52
- package/dist/chat/react.js.map +1 -1
- package/dist/chat/transport.js +1 -1
- package/dist/chat-sdk/index.d.ts +7 -7
- package/dist/chat-sdk/index.js +1 -1
- package/dist/{client-zqKcsyFa.js → client-jagG8a9_.js} +129 -37
- package/dist/client-jagG8a9_.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/{cloudflare-BduZwmYK.js → cloudflare-Dzvc7V2N.js} +10 -3
- package/dist/{cloudflare-BduZwmYK.js.map → cloudflare-Dzvc7V2N.js.map} +1 -1
- package/dist/context/index.d.ts +216 -0
- package/dist/context/index.js +454 -0
- package/dist/context/index.js.map +1 -0
- package/dist/current-agent-Da_C9a3b.d.ts +266 -0
- package/dist/current-agent-DhoDkSnH.js +51 -0
- package/dist/current-agent-DhoDkSnH.js.map +1 -0
- package/dist/diagnostics-BzvaX2UT.js +45 -0
- package/dist/diagnostics-BzvaX2UT.js.map +1 -0
- package/dist/diagnostics-C4jcz3VK.js +360 -0
- package/dist/diagnostics-C4jcz3VK.js.map +1 -0
- package/dist/{do-oauth-client-provider-VTZj2VtM.d.ts → do-oauth-client-provider-Tmf1vgKz.d.ts} +2 -2
- package/dist/{email-CL27preh.d.ts → email-7TatiTnl.d.ts} +38 -9
- package/dist/email-send.d.ts +15 -0
- package/dist/email-send.js +32 -0
- package/dist/email-send.js.map +1 -0
- package/dist/email.d.ts +14 -10
- package/dist/email.js.map +1 -1
- package/dist/{handler-stateless-C_bo-Ytq.d.ts → handler-stateless-DxYpJ_XF.d.ts} +3 -3
- package/dist/{handler-stateless-CIkKPETH.js → handler-stateless-VvrWSAVA.js} +5 -5
- package/dist/handler-stateless-VvrWSAVA.js.map +1 -0
- package/dist/index-BB0kqhIz.d.ts +101 -0
- package/dist/index-XDkuQ7zm.d.ts +89 -0
- package/dist/{index-BRnybD6X.d.ts → index-YSKgfgg9.d.ts} +21 -31
- package/dist/index.d.ts +113 -101
- package/dist/index.js +11 -7234
- package/dist/ingress-BfetZbMO.js +83 -0
- package/dist/ingress-BfetZbMO.js.map +1 -0
- package/dist/internal-CYlgHl1l.js +59 -0
- package/dist/internal-CYlgHl1l.js.map +1 -0
- package/dist/internal_context-BlxFEWfn.d.ts +19 -0
- package/dist/internal_context.d.ts +10 -4
- package/dist/internal_context.js +1 -10
- package/dist/{client-invoker-BNSZxAkv.d.ts → invoker-CG0_p_Wq.d.ts} +2 -2
- package/dist/{client-invoker-VNZ7X0nn.js → invoker-CHMnoxIA.js} +2 -2
- package/dist/invoker-CHMnoxIA.js.map +1 -0
- package/dist/lifecycle/index.d.ts +66 -0
- package/dist/lifecycle/index.js +4 -0
- package/dist/lifecycle-CMRGjZdw.js +1299 -0
- package/dist/lifecycle-CMRGjZdw.js.map +1 -0
- package/dist/mcp/{do-oauth-client-provider.d.ts → client/do-oauth-client-provider.d.ts} +1 -1
- package/dist/mcp/{do-oauth-client-provider.js → client/do-oauth-client-provider.js} +1 -1
- package/dist/mcp/client/do-oauth-client-provider.js.map +1 -0
- package/dist/mcp/client/index.d.ts +42 -0
- package/dist/mcp/{client.js → client/index.js} +1 -1
- package/dist/mcp/{x402.d.ts → client/x402.d.ts} +2 -2
- package/dist/mcp/{x402.js → client/x402.js} +2 -2
- package/dist/mcp/client/x402.js.map +1 -0
- package/dist/mcp/index.d.ts +36 -36
- package/dist/mcp/index.js +14 -16
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/{server.d.ts → server/index.d.ts} +1 -1
- package/dist/mcp/{server.js → server/index.js} +1 -1
- package/dist/observability/ai/index.js +50 -35
- package/dist/observability/ai/index.js.map +1 -1
- package/dist/observability/index.d.ts +4 -4
- package/dist/observability/index.js +3 -50
- package/dist/observability/index.js.map +1 -1
- package/dist/{protocol-Dqc2MQxo.js → protocol-B0nh6KNf.js} +19 -21
- package/dist/protocol-B0nh6KNf.js.map +1 -0
- package/dist/react.d.ts +4 -4
- package/dist/react.js +1 -1
- package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
- package/dist/retries.d.ts +8 -6
- package/dist/retries.js +13 -1
- package/dist/retries.js.map +1 -1
- package/dist/routing/index.d.ts +137 -0
- package/dist/routing/index.js +244 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/sanitize-D9TujEK8.js +79 -0
- package/dist/sanitize-D9TujEK8.js.map +1 -0
- package/dist/schedule.d.ts +25 -94
- package/dist/schedule.js +1 -98
- package/dist/schedule.js.map +1 -1
- package/dist/scheduler-DD9NdYbF.js +665 -0
- package/dist/scheduler-DD9NdYbF.js.map +1 -0
- package/dist/scheduler-Dwh85ZGl.d.ts +223 -0
- package/dist/schedules/index.d.ts +22 -0
- package/dist/schedules/index.js +2 -0
- package/dist/schedules/parser.d.ts +79 -0
- package/dist/schedules/parser.js +103 -0
- package/dist/schedules/parser.js.map +1 -0
- package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
- package/dist/serializable.d.ts +1 -1
- package/dist/sessions/index.d.ts +441 -0
- package/dist/sessions/index.js +2063 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/skills/index.d.ts +99 -0
- package/dist/skills/index.js +254 -5
- package/dist/skills/index.js.map +1 -1
- package/dist/sql-error-CPY-GXyI.d.ts +12 -0
- package/dist/sql-error.d.ts +2 -0
- package/dist/sql-error.js +16 -0
- package/dist/sql-error.js.map +1 -0
- package/dist/src-DlSHshb2.js +6963 -0
- package/dist/src-DlSHshb2.js.map +1 -0
- package/dist/streams/index.d.ts +120 -0
- package/dist/streams/index.js +107 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams-D6tJ0NN9.d.ts +370 -0
- package/dist/streams-DZKgAj9b.js +709 -0
- package/dist/streams-DZKgAj9b.js.map +1 -0
- package/dist/sub-routing.d.ts +12 -12
- package/dist/surface-bZZJqBka.js +17 -0
- package/dist/surface-bZZJqBka.js.map +1 -0
- package/dist/tasks/index.d.ts +64 -0
- package/dist/tasks/index.js +2 -0
- package/dist/tasks-BRJ5zgya.d.ts +517 -0
- package/dist/tasks-ylZgBjhj.js +1656 -0
- package/dist/tasks-ylZgBjhj.js.map +1 -0
- package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
- package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
- package/dist/text-stream-CpdiKrJB.js +272 -0
- package/dist/text-stream-CpdiKrJB.js.map +1 -0
- package/dist/tokens-nHAKcN6M.js +52 -0
- package/dist/tokens-nHAKcN6M.js.map +1 -0
- package/dist/tool-schema-CBjGPrsQ.js +31 -0
- package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
- package/dist/types-B7LojTe4.d.ts +202 -0
- package/dist/types-_Faxb570.d.ts +439 -0
- package/dist/voice/client.d.ts +226 -0
- package/dist/voice/client.js +932 -0
- package/dist/voice/client.js.map +1 -0
- package/dist/voice/errors.d.ts +43 -0
- package/dist/voice/errors.js +41 -0
- package/dist/voice/errors.js.map +1 -0
- package/dist/voice/index.d.ts +271 -0
- package/dist/voice/index.js +1812 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/react.d.ts +167 -0
- package/dist/voice/react.js +234 -0
- package/dist/voice/react.js.map +1 -0
- package/dist/voice/sfu.d.ts +71 -0
- package/dist/voice/sfu.js +157 -0
- package/dist/voice/sfu.js.map +1 -0
- package/dist/voice/text.d.ts +6 -0
- package/dist/voice/text.js +2 -0
- package/dist/voice/types.d.ts +58 -0
- package/dist/voice/types.js +18 -0
- package/dist/voice/types.js.map +1 -0
- package/dist/voice/workers-ai.d.ts +136 -0
- package/dist/voice/workers-ai.js +568 -0
- package/dist/voice/workers-ai.js.map +1 -0
- package/dist/websockets/index.d.ts +192 -0
- package/dist/websockets/index.js +2 -0
- package/dist/websockets-DUfRHPRq.js +502 -0
- package/dist/websockets-DUfRHPRq.js.map +1 -0
- package/dist/workflow-types.d.ts +25 -25
- package/dist/workflows.d.ts +22 -22
- package/dist/workflows.js +2 -1
- package/dist/workflows.js.map +1 -1
- package/dist/{ws-chat-transport-CIoOBbO7.js → ws-chat-transport-rWwta645.js} +152 -15
- package/dist/ws-chat-transport-rWwta645.js.map +1 -0
- package/docs/agent-class.md +29 -87
- package/docs/agent-tools.md +2 -1
- package/docs/channels.md +323 -0
- package/docs/chat-agents.md +19 -25
- package/docs/context.md +131 -0
- package/docs/durable-execution.md +1 -1
- package/docs/http-websockets.md +1 -11
- package/docs/human-in-the-loop.md +1 -1
- package/docs/index.md +16 -12
- package/docs/lifecycle.md +370 -0
- package/docs/long-running-agents.md +4 -6
- package/docs/mcp-client.md +55 -0
- package/docs/mcp-servers.md +5 -1
- package/docs/observability.md +11 -11
- package/docs/resumable-streaming.md +2 -2
- package/docs/routing.md +105 -0
- package/docs/scheduling.md +175 -15
- package/docs/server-driven-messages.md +1 -1
- package/docs/sessions.md +237 -871
- package/docs/streams.md +213 -0
- package/docs/sub-agents.md +185 -125
- package/docs/tasks.md +246 -0
- package/docs/voice.md +745 -0
- package/package.json +144 -33
- package/dist/cli/index.js +0 -26
- package/dist/cli/index.js.map +0 -1
- package/dist/client-invoker-VNZ7X0nn.js.map +0 -1
- package/dist/client-zqKcsyFa.js.map +0 -1
- package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
- package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
- package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
- package/dist/experimental/memory/session/index.d.ts +0 -670
- package/dist/experimental/memory/session/index.js +0 -2374
- package/dist/experimental/memory/session/index.js.map +0 -1
- package/dist/experimental/memory/utils/index.d.ts +0 -96
- package/dist/experimental/memory/utils/index.js +0 -79
- package/dist/experimental/memory/utils/index.js.map +0 -1
- package/dist/handler-stateless-CIkKPETH.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/internal_context-Dg4Cgjcu.d.ts +0 -37
- package/dist/internal_context.js.map +0 -1
- package/dist/mcp/client.d.ts +0 -42
- package/dist/mcp/do-oauth-client-provider.js.map +0 -1
- package/dist/mcp/x402.js.map +0 -1
- package/dist/protocol-Dqc2MQxo.js.map +0 -1
- package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
- package/dist/tool-output-truncation-CNnnGZQ3.js.map +0 -1
- package/dist/ws-chat-transport-CIoOBbO7.js.map +0 -1
- /package/dist/{cli/index.d.ts → index-BVVgDSdq.d.ts} +0 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { ToolSet } from "ai";
|
|
2
|
+
|
|
3
|
+
//#region src/context/sqlite-provider.d.ts
|
|
4
|
+
/** Minimal tagged-template SQL surface used by SQLite context providers. */
|
|
5
|
+
interface SqlProvider {
|
|
6
|
+
sql<T = Record<string, string | number | boolean | null>>(
|
|
7
|
+
strings: TemplateStringsArray,
|
|
8
|
+
...values: (string | number | boolean | null)[]
|
|
9
|
+
): T[];
|
|
10
|
+
}
|
|
11
|
+
/** SQLite-backed writable context block provider. */
|
|
12
|
+
declare class AgentContextProvider implements WritableContextProvider {
|
|
13
|
+
private agent;
|
|
14
|
+
private label;
|
|
15
|
+
private initialized;
|
|
16
|
+
constructor(agent: SqlProvider, label?: string);
|
|
17
|
+
init(label: string): void;
|
|
18
|
+
private ensureTable;
|
|
19
|
+
get(): Promise<string | null>;
|
|
20
|
+
set(content: string): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/context/search.d.ts
|
|
24
|
+
/**
|
|
25
|
+
* Storage interface for searchable context.
|
|
26
|
+
*
|
|
27
|
+
* - `get()` returns a summary of indexed content (rendered into system prompt)
|
|
28
|
+
* - `search(query)` full-text search (via search_context tool)
|
|
29
|
+
* - `set(key, content)` indexes content under a key (via set_context tool)
|
|
30
|
+
*/
|
|
31
|
+
interface SearchProvider extends ContextProvider {
|
|
32
|
+
search(query: string): Promise<string | null>;
|
|
33
|
+
set?(key: string, content: string): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* SearchProvider backed by Durable Object SQLite with FTS5.
|
|
37
|
+
*
|
|
38
|
+
* - `get()` returns a count of indexed entries
|
|
39
|
+
* - `search(query)` full-text search using FTS5
|
|
40
|
+
* - `set(key, content)` indexes or replaces content under a key
|
|
41
|
+
*
|
|
42
|
+
* Entries live in one namespaced FTS5 table, separate from the session
|
|
43
|
+
* message index.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const context = new ContextBlocks([
|
|
48
|
+
* { label: "knowledge", provider: new AgentSearchProvider(this) }
|
|
49
|
+
* ]);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare class AgentSearchProvider implements SearchProvider {
|
|
53
|
+
private agent;
|
|
54
|
+
private label;
|
|
55
|
+
private initialized;
|
|
56
|
+
constructor(agent: SqlProvider);
|
|
57
|
+
init(label: string): void;
|
|
58
|
+
private ensureTable;
|
|
59
|
+
get(): Promise<string | null>;
|
|
60
|
+
search(query: string): Promise<string | null>;
|
|
61
|
+
set(key: string, content: string): Promise<void>;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/context/blocks.d.ts
|
|
65
|
+
/**
|
|
66
|
+
* Base storage interface for a context block.
|
|
67
|
+
* A provider with only `get()` is readonly.
|
|
68
|
+
*/
|
|
69
|
+
interface ContextProvider {
|
|
70
|
+
get(): Promise<string | null>;
|
|
71
|
+
/** Called by the context system to provide the block label before first use. */
|
|
72
|
+
init?(label: string): void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Writable context provider — extends ContextProvider with `set()`.
|
|
76
|
+
* Blocks backed by this provider are writable via the `set_context` tool.
|
|
77
|
+
*/
|
|
78
|
+
interface WritableContextProvider extends ContextProvider {
|
|
79
|
+
set(content: string): Promise<void>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Configuration for a context block.
|
|
83
|
+
*/
|
|
84
|
+
interface ContextConfig {
|
|
85
|
+
/** Block label — used as key and in tool descriptions */
|
|
86
|
+
label: string;
|
|
87
|
+
/** Human-readable description (shown to AI in tool) */
|
|
88
|
+
description?: string;
|
|
89
|
+
/** Maximum tokens allowed. Enforced on set. */
|
|
90
|
+
maxTokens?: number;
|
|
91
|
+
/** Storage provider. Determines block behavior:
|
|
92
|
+
* - ContextProvider (get only) → readonly
|
|
93
|
+
* - WritableContextProvider (get+set) → writable via set_context
|
|
94
|
+
* - SearchProvider (get+search+set?) → searchable via search_context
|
|
95
|
+
* If omitted, auto-wired to writable SQLite when using builder. */
|
|
96
|
+
provider?: ContextProvider | WritableContextProvider | SearchProvider;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A loaded context block with computed token count.
|
|
100
|
+
*/
|
|
101
|
+
interface ContextBlock {
|
|
102
|
+
label: string;
|
|
103
|
+
description?: string;
|
|
104
|
+
content: string;
|
|
105
|
+
tokens: number;
|
|
106
|
+
maxTokens?: number;
|
|
107
|
+
/** True if provider is writable (has set) */
|
|
108
|
+
writable: boolean;
|
|
109
|
+
/** True if backed by a SearchProvider */
|
|
110
|
+
isSearchable: boolean;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Manages context blocks with frozen snapshot support.
|
|
114
|
+
*/
|
|
115
|
+
declare class ContextBlocks {
|
|
116
|
+
private configs;
|
|
117
|
+
private blocks;
|
|
118
|
+
private snapshot;
|
|
119
|
+
private loaded;
|
|
120
|
+
private promptStore;
|
|
121
|
+
private defaultProvider;
|
|
122
|
+
/**
|
|
123
|
+
* @param configs Blocks to load on first use.
|
|
124
|
+
* @param promptStore Persists the frozen system prompt, keeping the
|
|
125
|
+
* provider's prefix cache warm across wakes.
|
|
126
|
+
* @param defaultProvider Supplies storage for blocks declared without a
|
|
127
|
+
* provider, so a host can offer durable writable blocks by label alone.
|
|
128
|
+
*/
|
|
129
|
+
constructor(
|
|
130
|
+
configs: ContextConfig[],
|
|
131
|
+
promptStore?: WritableContextProvider,
|
|
132
|
+
defaultProvider?: (label: string) => ContextProvider
|
|
133
|
+
);
|
|
134
|
+
/** Fill in the host's storage for a block declared without a provider. */
|
|
135
|
+
private withDefaultProvider;
|
|
136
|
+
/**
|
|
137
|
+
* Load all blocks from their providers. Hosts call this once at startup;
|
|
138
|
+
* every other entry point loads lazily.
|
|
139
|
+
*/
|
|
140
|
+
load(): Promise<void>;
|
|
141
|
+
/** Initialize a block's provider and read its current content. */
|
|
142
|
+
private loadBlock;
|
|
143
|
+
/**
|
|
144
|
+
* Dynamically register a new context block after initialization.
|
|
145
|
+
* Used by extensions to contribute context at runtime.
|
|
146
|
+
*
|
|
147
|
+
* If blocks have already been loaded, the new block's provider is
|
|
148
|
+
* initialized and loaded immediately. The snapshot is NOT updated
|
|
149
|
+
* automatically — call `refreshSystemPrompt()` to rebuild.
|
|
150
|
+
*/
|
|
151
|
+
addBlock(input: ContextConfig): Promise<ContextBlock>;
|
|
152
|
+
/**
|
|
153
|
+
* Remove a dynamically registered context block.
|
|
154
|
+
* Used during extension unload cleanup.
|
|
155
|
+
*
|
|
156
|
+
* Returns true if the block existed and was removed.
|
|
157
|
+
* The snapshot is NOT updated automatically — call
|
|
158
|
+
* `refreshSystemPrompt()` to rebuild.
|
|
159
|
+
*/
|
|
160
|
+
removeBlock(label: string): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Get a block by label.
|
|
163
|
+
*/
|
|
164
|
+
getBlock(label: string): ContextBlock | null;
|
|
165
|
+
/**
|
|
166
|
+
* Get all blocks.
|
|
167
|
+
*/
|
|
168
|
+
getBlocks(): ContextBlock[];
|
|
169
|
+
/**
|
|
170
|
+
* Set block content. Writes to provider immediately.
|
|
171
|
+
* Does NOT update the frozen snapshot.
|
|
172
|
+
*/
|
|
173
|
+
setBlock(label: string, content: string): Promise<ContextBlock>;
|
|
174
|
+
/** Index a search entry within a searchable block. */
|
|
175
|
+
private setSearchEntry;
|
|
176
|
+
/** Search a searchable block. */
|
|
177
|
+
private searchContext;
|
|
178
|
+
/**
|
|
179
|
+
* Append content to a block.
|
|
180
|
+
*/
|
|
181
|
+
appendToBlock(label: string, content: string): Promise<ContextBlock>;
|
|
182
|
+
private renderPrompt;
|
|
183
|
+
/**
|
|
184
|
+
* The frozen system prompt. The first call renders the blocks and stores
|
|
185
|
+
* the result; every later call returns that same string, so the model
|
|
186
|
+
* provider's prefix cache stays warm. Block edits do not change it until
|
|
187
|
+
* `refreshSystemPrompt()` is called.
|
|
188
|
+
*/
|
|
189
|
+
freezeSystemPrompt(): Promise<string>;
|
|
190
|
+
/**
|
|
191
|
+
* Reload every block from its provider, re-render the system prompt, and
|
|
192
|
+
* persist it. Use this after block content has changed.
|
|
193
|
+
*/
|
|
194
|
+
refreshSystemPrompt(): Promise<string>;
|
|
195
|
+
/**
|
|
196
|
+
* AI tools for context blocks.
|
|
197
|
+
*
|
|
198
|
+
* Auto-wired based on provider capabilities:
|
|
199
|
+
* - `set_context` — when any block is writable
|
|
200
|
+
* - `search_context` — when any block is a search provider
|
|
201
|
+
*/
|
|
202
|
+
tools(): Promise<ToolSet>;
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
205
|
+
export {
|
|
206
|
+
AgentContextProvider,
|
|
207
|
+
AgentSearchProvider,
|
|
208
|
+
type ContextBlock,
|
|
209
|
+
ContextBlocks,
|
|
210
|
+
type ContextConfig,
|
|
211
|
+
type ContextProvider,
|
|
212
|
+
type SearchProvider,
|
|
213
|
+
type SqlProvider,
|
|
214
|
+
type WritableContextProvider
|
|
215
|
+
};
|
|
216
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import { r as estimateStringTokens } from "../tokens-nHAKcN6M.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/context/search.ts
|
|
4
|
+
/**
|
|
5
|
+
* Check if a provider is a SearchProvider (has a `search` method).
|
|
6
|
+
*/
|
|
7
|
+
function isSearchProvider(provider) {
|
|
8
|
+
return typeof provider === "object" && provider !== null && "search" in provider && typeof provider.search === "function";
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* SearchProvider backed by Durable Object SQLite with FTS5.
|
|
12
|
+
*
|
|
13
|
+
* - `get()` returns a count of indexed entries
|
|
14
|
+
* - `search(query)` full-text search using FTS5
|
|
15
|
+
* - `set(key, content)` indexes or replaces content under a key
|
|
16
|
+
*
|
|
17
|
+
* Entries live in one namespaced FTS5 table, separate from the session
|
|
18
|
+
* message index.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const context = new ContextBlocks([
|
|
23
|
+
* { label: "knowledge", provider: new AgentSearchProvider(this) }
|
|
24
|
+
* ]);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
var AgentSearchProvider = class {
|
|
28
|
+
constructor(agent) {
|
|
29
|
+
this.label = "";
|
|
30
|
+
this.initialized = false;
|
|
31
|
+
this.agent = agent;
|
|
32
|
+
}
|
|
33
|
+
init(label) {
|
|
34
|
+
this.label = label;
|
|
35
|
+
}
|
|
36
|
+
ensureTable() {
|
|
37
|
+
if (this.initialized) return;
|
|
38
|
+
this.agent.sql`
|
|
39
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS cf_agents_search_fts
|
|
40
|
+
USING fts5(
|
|
41
|
+
label UNINDEXED,
|
|
42
|
+
key UNINDEXED,
|
|
43
|
+
content,
|
|
44
|
+
tokenize='porter unicode61'
|
|
45
|
+
)
|
|
46
|
+
`;
|
|
47
|
+
this.agent.sql`DROP TABLE IF EXISTS cf_agents_search_entries`;
|
|
48
|
+
this.initialized = true;
|
|
49
|
+
}
|
|
50
|
+
async get() {
|
|
51
|
+
this.ensureTable();
|
|
52
|
+
const count = this.agent.sql`
|
|
53
|
+
SELECT COUNT(*) as count FROM cf_agents_search_fts
|
|
54
|
+
WHERE label = ${this.label}
|
|
55
|
+
`[0]?.count ?? 0;
|
|
56
|
+
if (count === 0) return null;
|
|
57
|
+
return `${count} entries indexed.`;
|
|
58
|
+
}
|
|
59
|
+
async search(query) {
|
|
60
|
+
this.ensureTable();
|
|
61
|
+
const sanitized = query.split(/\s+/).filter(Boolean).map((w) => `"${w.replace(/"/g, "\"\"")}"`).join(" ");
|
|
62
|
+
if (!sanitized) return null;
|
|
63
|
+
try {
|
|
64
|
+
const rows = this.agent.sql`
|
|
65
|
+
SELECT f.key, f.content
|
|
66
|
+
FROM cf_agents_search_fts f
|
|
67
|
+
WHERE cf_agents_search_fts MATCH ${sanitized}
|
|
68
|
+
AND f.label = ${this.label}
|
|
69
|
+
ORDER BY rank
|
|
70
|
+
LIMIT 10
|
|
71
|
+
`;
|
|
72
|
+
if (rows.length === 0) return null;
|
|
73
|
+
return rows.map((r) => `[${r.key}]\n${r.content}`).join("\n\n");
|
|
74
|
+
} catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async set(key, content) {
|
|
79
|
+
this.ensureTable();
|
|
80
|
+
this.agent.sql`
|
|
81
|
+
DELETE FROM cf_agents_search_fts
|
|
82
|
+
WHERE label = ${this.label} AND key = ${key}
|
|
83
|
+
`;
|
|
84
|
+
this.agent.sql`
|
|
85
|
+
INSERT INTO cf_agents_search_fts (label, key, content)
|
|
86
|
+
VALUES (${this.label}, ${key}, ${content})
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/context/blocks.ts
|
|
92
|
+
function slugify(text) {
|
|
93
|
+
return text.slice(0, 60).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
94
|
+
}
|
|
95
|
+
function stableHash(text) {
|
|
96
|
+
let hash = 2166136261;
|
|
97
|
+
for (let i = 0; i < text.length; i++) {
|
|
98
|
+
hash ^= text.charCodeAt(i);
|
|
99
|
+
hash = Math.imul(hash, 16777619);
|
|
100
|
+
}
|
|
101
|
+
return (hash >>> 0).toString(36);
|
|
102
|
+
}
|
|
103
|
+
function contextEntryKey(metadataTitle, content) {
|
|
104
|
+
if (metadataTitle?.trim()) return slugify(metadataTitle) || `entry-${stableHash(metadataTitle)}`;
|
|
105
|
+
return `${slugify(content) || "entry"}-${stableHash(content)}`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if a provider is writable (has a `set` method).
|
|
109
|
+
*/
|
|
110
|
+
function isWritableProvider(provider) {
|
|
111
|
+
return typeof provider === "object" && provider !== null && "set" in provider && typeof provider.set === "function";
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Manages context blocks with frozen snapshot support.
|
|
115
|
+
*/
|
|
116
|
+
var ContextBlocks = class {
|
|
117
|
+
/**
|
|
118
|
+
* @param configs Blocks to load on first use.
|
|
119
|
+
* @param promptStore Persists the frozen system prompt, keeping the
|
|
120
|
+
* provider's prefix cache warm across wakes.
|
|
121
|
+
* @param defaultProvider Supplies storage for blocks declared without a
|
|
122
|
+
* provider, so a host can offer durable writable blocks by label alone.
|
|
123
|
+
*/
|
|
124
|
+
constructor(configs, promptStore, defaultProvider) {
|
|
125
|
+
this.blocks = /* @__PURE__ */ new Map();
|
|
126
|
+
this.snapshot = null;
|
|
127
|
+
this.loaded = false;
|
|
128
|
+
this.configs = configs;
|
|
129
|
+
this.promptStore = promptStore ?? null;
|
|
130
|
+
this.defaultProvider = defaultProvider ?? null;
|
|
131
|
+
}
|
|
132
|
+
/** Fill in the host's storage for a block declared without a provider. */
|
|
133
|
+
withDefaultProvider(config) {
|
|
134
|
+
if (config.provider || !this.defaultProvider) return config;
|
|
135
|
+
return {
|
|
136
|
+
...config,
|
|
137
|
+
provider: this.defaultProvider(config.label)
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Load all blocks from their providers. Hosts call this once at startup;
|
|
142
|
+
* every other entry point loads lazily.
|
|
143
|
+
*/
|
|
144
|
+
async load() {
|
|
145
|
+
this.configs = this.configs.map((config) => this.withDefaultProvider(config));
|
|
146
|
+
for (const config of this.configs) this.blocks.set(config.label, await this.loadBlock(config));
|
|
147
|
+
this.loaded = true;
|
|
148
|
+
}
|
|
149
|
+
/** Initialize a block's provider and read its current content. */
|
|
150
|
+
async loadBlock(config) {
|
|
151
|
+
const provider = config.provider;
|
|
152
|
+
provider?.init?.(config.label);
|
|
153
|
+
const content = provider ? await provider.get() ?? "" : "";
|
|
154
|
+
const searchable = isSearchProvider(provider);
|
|
155
|
+
return {
|
|
156
|
+
label: config.label,
|
|
157
|
+
description: config.description,
|
|
158
|
+
content,
|
|
159
|
+
tokens: estimateStringTokens(content),
|
|
160
|
+
maxTokens: config.maxTokens,
|
|
161
|
+
writable: isWritableProvider(provider) || searchable && !!provider?.set,
|
|
162
|
+
isSearchable: searchable
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Dynamically register a new context block after initialization.
|
|
167
|
+
* Used by extensions to contribute context at runtime.
|
|
168
|
+
*
|
|
169
|
+
* If blocks have already been loaded, the new block's provider is
|
|
170
|
+
* initialized and loaded immediately. The snapshot is NOT updated
|
|
171
|
+
* automatically — call `refreshSystemPrompt()` to rebuild.
|
|
172
|
+
*/
|
|
173
|
+
async addBlock(input) {
|
|
174
|
+
if (!this.loaded) await this.load();
|
|
175
|
+
if (this.configs.some((c) => c.label === input.label)) throw new Error(`Block "${input.label}" already exists`);
|
|
176
|
+
const config = this.withDefaultProvider(input);
|
|
177
|
+
this.configs.push(config);
|
|
178
|
+
const block = await this.loadBlock(config);
|
|
179
|
+
this.blocks.set(config.label, block);
|
|
180
|
+
return block;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Remove a dynamically registered context block.
|
|
184
|
+
* Used during extension unload cleanup.
|
|
185
|
+
*
|
|
186
|
+
* Returns true if the block existed and was removed.
|
|
187
|
+
* The snapshot is NOT updated automatically — call
|
|
188
|
+
* `refreshSystemPrompt()` to rebuild.
|
|
189
|
+
*/
|
|
190
|
+
removeBlock(label) {
|
|
191
|
+
const idx = this.configs.findIndex((c) => c.label === label);
|
|
192
|
+
if (idx === -1) return false;
|
|
193
|
+
this.configs.splice(idx, 1);
|
|
194
|
+
this.blocks.delete(label);
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Get a block by label.
|
|
199
|
+
*/
|
|
200
|
+
getBlock(label) {
|
|
201
|
+
return this.blocks.get(label) ?? null;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get all blocks.
|
|
205
|
+
*/
|
|
206
|
+
getBlocks() {
|
|
207
|
+
return Array.from(this.blocks.values());
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Set block content. Writes to provider immediately.
|
|
211
|
+
* Does NOT update the frozen snapshot.
|
|
212
|
+
*/
|
|
213
|
+
async setBlock(label, content) {
|
|
214
|
+
if (!this.loaded) await this.load();
|
|
215
|
+
const config = this.configs.find((c) => c.label === label);
|
|
216
|
+
const existing = this.blocks.get(label);
|
|
217
|
+
if (!existing?.writable) throw new Error(`Block "${label}" is readonly`);
|
|
218
|
+
if (existing.isSearchable) throw new Error(`Block "${label}" is a keyed provider. Use setSearchEntry() instead.`);
|
|
219
|
+
const tokens = estimateStringTokens(content);
|
|
220
|
+
const maxTokens = config?.maxTokens ?? existing?.maxTokens;
|
|
221
|
+
if (maxTokens !== void 0 && tokens > maxTokens) throw new Error(`Block "${label}" exceeds maxTokens: ${tokens} > ${maxTokens}`);
|
|
222
|
+
const block = {
|
|
223
|
+
label,
|
|
224
|
+
description: config?.description ?? existing?.description,
|
|
225
|
+
content,
|
|
226
|
+
tokens,
|
|
227
|
+
maxTokens,
|
|
228
|
+
writable: true,
|
|
229
|
+
isSearchable: false
|
|
230
|
+
};
|
|
231
|
+
this.blocks.set(label, block);
|
|
232
|
+
if (config?.provider && isWritableProvider(config.provider)) await config.provider.set(content);
|
|
233
|
+
return block;
|
|
234
|
+
}
|
|
235
|
+
/** Index a search entry within a searchable block. */
|
|
236
|
+
async setSearchEntry(label, key, content) {
|
|
237
|
+
if (!this.loaded) await this.load();
|
|
238
|
+
const config = this.configs.find((c) => c.label === label);
|
|
239
|
+
const existing = this.blocks.get(label);
|
|
240
|
+
if (!existing?.isSearchable) throw new Error(`Block "${label}" is not a search provider`);
|
|
241
|
+
const provider = config?.provider;
|
|
242
|
+
if (!provider || !isSearchProvider(provider) || !provider.set) throw new Error(`Block "${label}" does not support writes`);
|
|
243
|
+
await provider.set(key, content);
|
|
244
|
+
existing.content = await provider.get() ?? "";
|
|
245
|
+
existing.tokens = estimateStringTokens(existing.content);
|
|
246
|
+
}
|
|
247
|
+
/** Search a searchable block. */
|
|
248
|
+
async searchContext(label, query) {
|
|
249
|
+
if (!this.loaded) await this.load();
|
|
250
|
+
const config = this.configs.find((c) => c.label === label);
|
|
251
|
+
if (!config?.provider || !isSearchProvider(config.provider)) throw new Error(`Block "${label}" is not a search provider`);
|
|
252
|
+
return config.provider.search(query);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Append content to a block.
|
|
256
|
+
*/
|
|
257
|
+
async appendToBlock(label, content) {
|
|
258
|
+
if (!this.loaded) await this.load();
|
|
259
|
+
const existing = this.blocks.get(label);
|
|
260
|
+
if (!existing) throw new Error(`Block "${label}" not found`);
|
|
261
|
+
const needsSep = existing.content.length > 0 && !content.startsWith("\n");
|
|
262
|
+
return this.setBlock(label, existing.content + (needsSep ? "\n" : "") + content);
|
|
263
|
+
}
|
|
264
|
+
renderPrompt() {
|
|
265
|
+
const parts = [];
|
|
266
|
+
const sep = "═".repeat(46);
|
|
267
|
+
for (const block of this.blocks.values()) {
|
|
268
|
+
if (!block.content && !block.writable && !block.isSearchable) continue;
|
|
269
|
+
let header = block.label.toUpperCase();
|
|
270
|
+
if (block.description) header += ` (${block.description})`;
|
|
271
|
+
if (block.maxTokens) {
|
|
272
|
+
const pct = Math.round(block.tokens / block.maxTokens * 100);
|
|
273
|
+
header += ` [${pct}% — ${block.tokens}/${block.maxTokens} tokens]`;
|
|
274
|
+
}
|
|
275
|
+
if (block.isSearchable) header += " [searchable]";
|
|
276
|
+
else if (!block.writable) header += " [readonly]";
|
|
277
|
+
else header += " [writable]";
|
|
278
|
+
parts.push(`${sep}\n${header}\n${sep}\n${block.content}`);
|
|
279
|
+
}
|
|
280
|
+
return parts.join("\n\n");
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* The frozen system prompt. The first call renders the blocks and stores
|
|
284
|
+
* the result; every later call returns that same string, so the model
|
|
285
|
+
* provider's prefix cache stays warm. Block edits do not change it until
|
|
286
|
+
* `refreshSystemPrompt()` is called.
|
|
287
|
+
*/
|
|
288
|
+
async freezeSystemPrompt() {
|
|
289
|
+
if (this.promptStore) {
|
|
290
|
+
const stored = await this.promptStore.get();
|
|
291
|
+
if (stored !== null) return stored;
|
|
292
|
+
}
|
|
293
|
+
if (this.snapshot !== null) return this.snapshot;
|
|
294
|
+
if (!this.loaded) await this.load();
|
|
295
|
+
this.snapshot = this.renderPrompt();
|
|
296
|
+
await this.promptStore?.set(this.snapshot);
|
|
297
|
+
return this.snapshot;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Reload every block from its provider, re-render the system prompt, and
|
|
301
|
+
* persist it. Use this after block content has changed.
|
|
302
|
+
*/
|
|
303
|
+
async refreshSystemPrompt() {
|
|
304
|
+
this.loaded = false;
|
|
305
|
+
await this.load();
|
|
306
|
+
this.snapshot = this.renderPrompt();
|
|
307
|
+
await this.promptStore?.set(this.snapshot);
|
|
308
|
+
return this.snapshot;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* AI tools for context blocks.
|
|
312
|
+
*
|
|
313
|
+
* Auto-wired based on provider capabilities:
|
|
314
|
+
* - `set_context` — when any block is writable
|
|
315
|
+
* - `search_context` — when any block is a search provider
|
|
316
|
+
*/
|
|
317
|
+
async tools() {
|
|
318
|
+
if (!this.loaded) await this.load();
|
|
319
|
+
const blocks = Array.from(this.blocks.values());
|
|
320
|
+
const writable = blocks.filter((b) => b.writable);
|
|
321
|
+
const searchLabels = blocks.filter((b) => b.isSearchable).map((b) => b.label);
|
|
322
|
+
const toolSet = {};
|
|
323
|
+
if (writable.length > 0) {
|
|
324
|
+
const blockDescriptions = writable.map((b) => {
|
|
325
|
+
const kind = b.isSearchable ? "searchable, keyed entries" : "writable";
|
|
326
|
+
return `- "${b.label}" (${kind}): ${b.description ?? "no description"}`;
|
|
327
|
+
});
|
|
328
|
+
const keyedBlocks = writable.filter((b) => b.isSearchable);
|
|
329
|
+
const properties = {
|
|
330
|
+
label: {
|
|
331
|
+
type: "string",
|
|
332
|
+
enum: writable.map((b) => b.label),
|
|
333
|
+
description: "Block label to write to"
|
|
334
|
+
},
|
|
335
|
+
content: {
|
|
336
|
+
type: "string",
|
|
337
|
+
description: "The main content to write to the block."
|
|
338
|
+
},
|
|
339
|
+
action: {
|
|
340
|
+
type: "string",
|
|
341
|
+
enum: ["replace", "append"],
|
|
342
|
+
description: "replace (default) or append"
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
if (keyedBlocks.length > 0) properties.metadata = {
|
|
346
|
+
type: "object",
|
|
347
|
+
description: "Optional metadata for keyed entries (searchable blocks: " + keyedBlocks.map((b) => `"${b.label}"`).join(", ") + "). A title keeps updates stable; a description helps the model pick the right entry.",
|
|
348
|
+
properties: {
|
|
349
|
+
title: {
|
|
350
|
+
type: "string",
|
|
351
|
+
description: "Short title. Used as a stable identifier — entries with the same title are updated in place, different titles create new entries."
|
|
352
|
+
},
|
|
353
|
+
description: {
|
|
354
|
+
type: "string",
|
|
355
|
+
description: "One-line summary shown alongside the title in the system prompt so the model can decide when to load the entry."
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
const metadataHint = keyedBlocks.length > 0 ? "\n\nFor searchable blocks, pass `metadata: { title, description }` — title stabilises updates, description helps the model pick entries. Metadata is optional." : "";
|
|
360
|
+
toolSet.set_context = {
|
|
361
|
+
description: `Write to a context block. Available blocks:\n${blockDescriptions.join("\n")}\n\nWrites are durable and persist across sessions.${metadataHint}`,
|
|
362
|
+
inputSchema: z.fromJSONSchema({
|
|
363
|
+
type: "object",
|
|
364
|
+
properties,
|
|
365
|
+
required: ["label", "content"]
|
|
366
|
+
}),
|
|
367
|
+
execute: async ({ label, content, metadata, action }) => {
|
|
368
|
+
try {
|
|
369
|
+
const block = this.blocks.get(label);
|
|
370
|
+
if (!block) return `Error: block "${label}" not found`;
|
|
371
|
+
if (block.isSearchable) {
|
|
372
|
+
const key = contextEntryKey(metadata?.title, content);
|
|
373
|
+
await this.setSearchEntry(label, key, content);
|
|
374
|
+
return `Indexed "${key}" in ${label}.`;
|
|
375
|
+
}
|
|
376
|
+
const updated = action === "append" ? await this.appendToBlock(label, content) : await this.setBlock(label, content);
|
|
377
|
+
return `Written to ${label}. Usage: ${updated.maxTokens ? `${Math.round(updated.tokens / updated.maxTokens * 100)}% (${updated.tokens}/${updated.maxTokens} tokens)` : `${updated.tokens} tokens`}`;
|
|
378
|
+
} catch (err) {
|
|
379
|
+
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
if (searchLabels.length > 0) toolSet.search_context = {
|
|
385
|
+
description: "Search for information in a searchable context block. ONLY these blocks are searchable: " + searchLabels.map((l) => `"${l}"`).join(", ") + ". Other blocks cannot be searched.",
|
|
386
|
+
inputSchema: z.fromJSONSchema({
|
|
387
|
+
type: "object",
|
|
388
|
+
properties: {
|
|
389
|
+
label: {
|
|
390
|
+
type: "string",
|
|
391
|
+
enum: searchLabels,
|
|
392
|
+
description: "Searchable block label"
|
|
393
|
+
},
|
|
394
|
+
query: {
|
|
395
|
+
type: "string",
|
|
396
|
+
description: "Search query"
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
required: ["label", "query"]
|
|
400
|
+
}),
|
|
401
|
+
execute: async ({ label, query }) => {
|
|
402
|
+
try {
|
|
403
|
+
if (!searchLabels.includes(label)) return `Error: "${label}" is not searchable. Searchable blocks: ${searchLabels.join(", ")}`;
|
|
404
|
+
return await this.searchContext(label, query) ?? "No results found.";
|
|
405
|
+
} catch (err) {
|
|
406
|
+
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
return toolSet;
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
//#endregion
|
|
414
|
+
//#region src/context/sqlite-provider.ts
|
|
415
|
+
/** SQLite-backed writable context block provider. */
|
|
416
|
+
var AgentContextProvider = class {
|
|
417
|
+
constructor(agent, label) {
|
|
418
|
+
this.initialized = false;
|
|
419
|
+
this.agent = agent;
|
|
420
|
+
this.label = label ?? "";
|
|
421
|
+
}
|
|
422
|
+
init(label) {
|
|
423
|
+
if (!this.label) this.label = label;
|
|
424
|
+
}
|
|
425
|
+
ensureTable() {
|
|
426
|
+
if (this.initialized) return;
|
|
427
|
+
this.agent.sql`
|
|
428
|
+
CREATE TABLE IF NOT EXISTS cf_agents_context_blocks (
|
|
429
|
+
label TEXT PRIMARY KEY,
|
|
430
|
+
content TEXT NOT NULL,
|
|
431
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
432
|
+
)
|
|
433
|
+
`;
|
|
434
|
+
this.initialized = true;
|
|
435
|
+
}
|
|
436
|
+
async get() {
|
|
437
|
+
this.ensureTable();
|
|
438
|
+
return this.agent.sql`
|
|
439
|
+
SELECT content FROM cf_agents_context_blocks WHERE label = ${this.label}
|
|
440
|
+
`[0]?.content ?? null;
|
|
441
|
+
}
|
|
442
|
+
async set(content) {
|
|
443
|
+
this.ensureTable();
|
|
444
|
+
this.agent.sql`
|
|
445
|
+
INSERT INTO cf_agents_context_blocks (label, content)
|
|
446
|
+
VALUES (${this.label}, ${content})
|
|
447
|
+
ON CONFLICT(label) DO UPDATE SET content = ${content}, updated_at = CURRENT_TIMESTAMP
|
|
448
|
+
`;
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
//#endregion
|
|
452
|
+
export { AgentContextProvider, AgentSearchProvider, ContextBlocks };
|
|
453
|
+
|
|
454
|
+
//# sourceMappingURL=index.js.map
|