@deepstrike/wasm 0.2.20 → 0.2.22
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 +2 -1
- package/dist/index.js +1 -0
- package/dist/memory/in-memory-store.d.ts +19 -0
- package/dist/memory/in-memory-store.js +43 -0
- package/dist/providers/anthropic.js +25 -12
- package/dist/types.d.ts +7 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export { OpenAIProvider, QwenProvider, DeepSeekProvider, MiniMaxProvider, KimiPr
|
|
|
14
14
|
export { tool, executeTools } from "./tools/index.js";
|
|
15
15
|
export type { RegisteredTool } from "./tools/index.js";
|
|
16
16
|
export { WorkingMemory } from "./memory/index.js";
|
|
17
|
+
export { InMemoryDreamStore } from "./memory/in-memory-store.js";
|
|
17
18
|
export type { DreamStore, DreamResult, SessionStore, SessionData, SessionMessage, MemoryEntry, CurationResult, CurationStats, } from "./memory/index.js";
|
|
18
19
|
export type { KnowledgeSource } from "./knowledge/index.js";
|
|
19
20
|
export { SinglePassHarness, HarnessLoop } from "./harness/index.js";
|
|
@@ -22,4 +23,4 @@ export { ScheduledPrompt } from "./signals/index.js";
|
|
|
22
23
|
export type { RuntimeSignal, SignalSource } from "./signals/index.js";
|
|
23
24
|
export { PermissionManager, PermissionMode } from "./safety/index.js";
|
|
24
25
|
export type { PermissionDecision } from "./safety/index.js";
|
|
25
|
-
export type { Message, ToolCall, ToolResult, ToolSchema, RenderedContext, ProviderRunState, StreamEvent, TextDelta, ThinkingDelta, ToolCallEvent, ToolResultEvent, DoneEvent, ErrorEvent, PermissionRequestEvent, PermissionResolvedEvent, PermissionResponse, LLMProvider, } from "./types.js";
|
|
26
|
+
export type { Message, ToolCall, ToolResult, ToolSchema, RenderedContext, ProviderRunState, StreamEvent, TextDelta, ThinkingDelta, ToolCallEvent, ToolResultEvent, DoneEvent, ErrorEvent, PermissionRequestEvent, PermissionResolvedEvent, PermissionResponse, LLMProvider, CacheBreakpointStrategy, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { AnthropicProvider } from "./providers/anthropic.js";
|
|
|
8
8
|
export { OpenAIProvider, QwenProvider, DeepSeekProvider, MiniMaxProvider, KimiProvider } from "./providers/openai.js";
|
|
9
9
|
export { tool, executeTools } from "./tools/index.js";
|
|
10
10
|
export { WorkingMemory } from "./memory/index.js";
|
|
11
|
+
export { InMemoryDreamStore } from "./memory/in-memory-store.js";
|
|
11
12
|
export { SinglePassHarness, HarnessLoop } from "./harness/index.js";
|
|
12
13
|
export { ScheduledPrompt } from "./signals/index.js";
|
|
13
14
|
export { PermissionManager, PermissionMode } from "./safety/index.js";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `InMemoryDreamStore` — a lightweight `DreamStore` implementation backed by per-agent `Map`s.
|
|
3
|
+
* WASM port of node/src/memory/in-memory-store.ts. See that file for the full design.
|
|
4
|
+
*/
|
|
5
|
+
import type { CurationResult, DreamStore, MemoryEntry, SessionData } from "./index.js";
|
|
6
|
+
export declare class InMemoryDreamStore implements DreamStore {
|
|
7
|
+
private readonly initialMemories;
|
|
8
|
+
private sessions;
|
|
9
|
+
private memories;
|
|
10
|
+
readonly savedSessions: SessionData[];
|
|
11
|
+
constructor(initialMemories?: MemoryEntry[]);
|
|
12
|
+
addSession(agentId: string, session: SessionData): void;
|
|
13
|
+
addMemories(agentId: string, entries: MemoryEntry[]): void;
|
|
14
|
+
loadSessions(agentId: string): Promise<SessionData[]>;
|
|
15
|
+
loadMemories(agentId: string): Promise<MemoryEntry[]>;
|
|
16
|
+
commit(agentId: string, result: CurationResult, existing: MemoryEntry[]): Promise<void>;
|
|
17
|
+
search(agentId: string, _query: string, topK?: number): Promise<MemoryEntry[]>;
|
|
18
|
+
saveSession(data: SessionData): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export class InMemoryDreamStore {
|
|
2
|
+
initialMemories;
|
|
3
|
+
sessions = new Map();
|
|
4
|
+
memories = new Map();
|
|
5
|
+
savedSessions = [];
|
|
6
|
+
constructor(initialMemories = []) {
|
|
7
|
+
this.initialMemories = initialMemories;
|
|
8
|
+
}
|
|
9
|
+
addSession(agentId, session) {
|
|
10
|
+
const list = this.sessions.get(agentId) ?? [];
|
|
11
|
+
list.push(session);
|
|
12
|
+
this.sessions.set(agentId, list);
|
|
13
|
+
}
|
|
14
|
+
addMemories(agentId, entries) {
|
|
15
|
+
this.memories.set(agentId, [...(this.memories.get(agentId) ?? []), ...entries]);
|
|
16
|
+
}
|
|
17
|
+
async loadSessions(agentId) {
|
|
18
|
+
return this.sessions.get(agentId) ?? [];
|
|
19
|
+
}
|
|
20
|
+
async loadMemories(agentId) {
|
|
21
|
+
if (this.memories.has(agentId))
|
|
22
|
+
return this.memories.get(agentId);
|
|
23
|
+
if (this.initialMemories.length > 0) {
|
|
24
|
+
this.memories.set(agentId, [...this.initialMemories]);
|
|
25
|
+
return this.memories.get(agentId);
|
|
26
|
+
}
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
async commit(agentId, result, existing) {
|
|
30
|
+
const kept = existing.filter((_, i) => !result.toRemoveIndices.includes(i));
|
|
31
|
+
this.memories.set(agentId, [...kept, ...result.toAdd]);
|
|
32
|
+
}
|
|
33
|
+
async search(agentId, _query, topK = 5) {
|
|
34
|
+
const all = await this.loadMemories(agentId);
|
|
35
|
+
return all.slice(0, topK);
|
|
36
|
+
}
|
|
37
|
+
async saveSession(data) {
|
|
38
|
+
this.savedSessions.push(data);
|
|
39
|
+
const list = this.sessions.get(data.agentId) ?? [];
|
|
40
|
+
list.push(data);
|
|
41
|
+
this.sessions.set(data.agentId, list);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -3,18 +3,26 @@ import { assistantReplayKey, collectStreamMessage, toAnthropicMessages } from ".
|
|
|
3
3
|
const MAX_CACHE_BREAKPOINTS = 4;
|
|
4
4
|
/** Rolling cache breakpoints reserved for the message history (system uses ≤2). */
|
|
5
5
|
const MESSAGE_CACHE_BREAKPOINTS = 2;
|
|
6
|
-
function buildAnthropicTools(tools, anchorCache) {
|
|
6
|
+
function buildAnthropicTools(tools, anchorCache, strategy) {
|
|
7
|
+
const emitOnLastTool = anchorCache && (strategy === "default" || strategy === "tools-only");
|
|
7
8
|
return tools.map((t, i) => ({
|
|
8
9
|
name: t.name,
|
|
9
10
|
description: t.description,
|
|
10
11
|
input_schema: JSON.parse(t.parameters),
|
|
11
|
-
|
|
12
|
-
// otherwise systemStable already caches the tools prefix (tools render
|
|
13
|
-
// first), and a redundant tool breakpoint would burn a slot the message
|
|
14
|
-
// history needs to stay within the 4-breakpoint budget.
|
|
15
|
-
...(anchorCache && i === tools.length - 1 ? { cache_control: { type: "ephemeral" } } : {}),
|
|
12
|
+
...(emitOnLastTool && i === tools.length - 1 ? { cache_control: { type: "ephemeral" } } : {}),
|
|
16
13
|
}));
|
|
17
14
|
}
|
|
15
|
+
/** Recognised values for the `cacheBreakpointStrategy` extension; unknown → "default". */
|
|
16
|
+
const CACHE_BREAKPOINT_STRATEGIES = new Set([
|
|
17
|
+
"default", "tools-only", "system-only", "frozen-prefix", "none",
|
|
18
|
+
]);
|
|
19
|
+
function resolveCacheBreakpointStrategy(extensions) {
|
|
20
|
+
const raw = extensions?.cacheBreakpointStrategy;
|
|
21
|
+
if (typeof raw === "string" && CACHE_BREAKPOINT_STRATEGIES.has(raw)) {
|
|
22
|
+
return raw;
|
|
23
|
+
}
|
|
24
|
+
return "default";
|
|
25
|
+
}
|
|
18
26
|
/**
|
|
19
27
|
* Roll cache breakpoints across the conversation tail so the message-history
|
|
20
28
|
* prefix is written once and re-read on later turns (without this the cached
|
|
@@ -27,14 +35,16 @@ function buildAnthropicTools(tools, anchorCache) {
|
|
|
27
35
|
* only the incremental `[frozen..tail]`. Otherwise fall back to the rolling
|
|
28
36
|
* pair: final message + nearest preceding user turn.
|
|
29
37
|
*/
|
|
30
|
-
function applyMessageCacheControl(msgs, frozenPrefixLen) {
|
|
38
|
+
function applyMessageCacheControl(msgs, frozenPrefixLen, strategy) {
|
|
31
39
|
if (!msgs.length)
|
|
32
40
|
return;
|
|
41
|
+
if (strategy === "tools-only" || strategy === "system-only" || strategy === "none")
|
|
42
|
+
return;
|
|
33
43
|
const targets = new Set([msgs.length - 1]);
|
|
34
44
|
if (typeof frozenPrefixLen === "number" && frozenPrefixLen >= 1 && frozenPrefixLen < msgs.length) {
|
|
35
45
|
targets.add(frozenPrefixLen - 1);
|
|
36
46
|
}
|
|
37
|
-
else {
|
|
47
|
+
else if (strategy === "default") {
|
|
38
48
|
for (let i = msgs.length - 2; i >= 0 && targets.size < MESSAGE_CACHE_BREAKPOINTS; i--) {
|
|
39
49
|
if (msgs[i].role === "user")
|
|
40
50
|
targets.add(i);
|
|
@@ -110,16 +120,19 @@ export class AnthropicProvider {
|
|
|
110
120
|
return collectStreamMessage(this.stream(context, tools, extensions));
|
|
111
121
|
}
|
|
112
122
|
async *stream(context, tools, extensions, _state, signal) {
|
|
123
|
+
const strategy = resolveCacheBreakpointStrategy(extensions);
|
|
124
|
+
const emitOnSystemBlocks = strategy === "default" || strategy === "system-only";
|
|
125
|
+
const cc = { type: "ephemeral" };
|
|
113
126
|
const systemBlocks = [];
|
|
114
127
|
if (context.systemStable) {
|
|
115
|
-
systemBlocks.push({ type: "text", text: context.systemStable,
|
|
128
|
+
systemBlocks.push({ type: "text", text: context.systemStable, ...(emitOnSystemBlocks ? { cache_control: cc } : {}) });
|
|
116
129
|
}
|
|
117
130
|
if (context.systemKnowledge) {
|
|
118
|
-
systemBlocks.push({ type: "text", text: context.systemKnowledge,
|
|
131
|
+
systemBlocks.push({ type: "text", text: context.systemKnowledge, ...(emitOnSystemBlocks ? { cache_control: cc } : {}) });
|
|
119
132
|
}
|
|
120
133
|
const system = systemBlocks.length ? systemBlocks : (context.systemText || undefined);
|
|
121
134
|
const msgs = toAnthropicMessages(context, message => this.nativeAssistantBlocks.get(assistantReplayKey(message)));
|
|
122
|
-
applyMessageCacheControl(msgs, context.frozenPrefixLen);
|
|
135
|
+
applyMessageCacheControl(msgs, context.frozenPrefixLen, strategy);
|
|
123
136
|
// Append the volatile State turn AFTER the cache breakpoints (uncached tail);
|
|
124
137
|
// absent on un-rebuilt bindings, where the state is already inside `turns`.
|
|
125
138
|
// Render through toAnthropicMessages so assistant tool_use blocks are
|
|
@@ -136,7 +149,7 @@ export class AnthropicProvider {
|
|
|
136
149
|
messages: msgs,
|
|
137
150
|
stream: true,
|
|
138
151
|
...(system ? { system } : {}),
|
|
139
|
-
...(tools.length ? { tools: buildAnthropicTools(tools, !Array.isArray(system)) } : {}),
|
|
152
|
+
...(tools.length ? { tools: buildAnthropicTools(tools, !Array.isArray(system), strategy) } : {}),
|
|
140
153
|
};
|
|
141
154
|
if (extensions?.enable_thinking) {
|
|
142
155
|
body.thinking = { type: "enabled", budget_tokens: 8000 };
|
package/dist/types.d.ts
CHANGED
|
@@ -144,6 +144,13 @@ export interface ToolArgumentRepairedEvent extends StreamEvent {
|
|
|
144
144
|
*/
|
|
145
145
|
export type ProviderRunState = Record<string, unknown>;
|
|
146
146
|
export type ProviderProtocol = "anthropic-messages" | "openai-chat" | "openai-responses" | "gemini";
|
|
147
|
+
/**
|
|
148
|
+
* Cache_control placement strategy for the Anthropic protocol. Pass via
|
|
149
|
+
* `extensions.cacheBreakpointStrategy` on any provider call (the runner threads
|
|
150
|
+
* `RuntimeOptions.extensions` through automatically). See the Node SDK's
|
|
151
|
+
* `CacheBreakpointStrategy` for the canonical documentation; this is the WASM mirror.
|
|
152
|
+
*/
|
|
153
|
+
export type CacheBreakpointStrategy = "default" | "tools-only" | "system-only" | "frozen-prefix" | "none";
|
|
147
154
|
export interface ProviderDescriptor {
|
|
148
155
|
provider: string;
|
|
149
156
|
protocol: ProviderProtocol;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepstrike/wasm",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.22",
|
|
4
4
|
"description": "DeepStrike WASM SDK — browser, Cloudflare Workers, Deno Deploy",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"test": "node --experimental-vm-modules node_modules/.bin/jest"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@deepstrike/wasm-kernel": "0.2.
|
|
18
|
+
"@deepstrike/wasm-kernel": "0.2.22"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/jest": "^30.0.0",
|