@deepstrike/sdk 0.2.3 → 0.2.5
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 +287 -70
- package/dist/collaboration/modes/creator-verifier.d.ts +0 -3
- package/dist/collaboration/modes/creator-verifier.js +2 -6
- package/dist/governance.d.ts +36 -0
- package/dist/governance.js +22 -0
- package/dist/index.d.ts +11 -5
- package/dist/index.js +5 -1
- package/dist/memory/agent.d.ts +111 -0
- package/dist/memory/agent.js +151 -0
- package/dist/memory/protocols.d.ts +56 -0
- package/dist/providers/deepseek.js +13 -1
- package/dist/runtime/execution-plane.d.ts +6 -9
- package/dist/runtime/execution-plane.js +53 -25
- package/dist/runtime/kernel-event-log.d.ts +26 -0
- package/dist/runtime/kernel-event-log.js +220 -0
- package/dist/runtime/kernel-primitives-dashboard.d.ts +44 -0
- package/dist/runtime/kernel-primitives-dashboard.js +135 -0
- package/dist/runtime/kernel-step.d.ts +25 -1
- package/dist/runtime/kernel-step.js +12 -3
- package/dist/runtime/large-result-spool.d.ts +84 -0
- package/dist/runtime/large-result-spool.js +167 -0
- package/dist/runtime/os-profile.d.ts +18 -0
- package/dist/runtime/os-profile.js +47 -0
- package/dist/runtime/os-snapshot.d.ts +35 -0
- package/dist/runtime/os-snapshot.js +128 -0
- package/dist/runtime/runner.d.ts +62 -9
- package/dist/runtime/runner.js +425 -135
- package/dist/runtime/session-log.d.ts +118 -4
- package/dist/runtime/session-log.js +15 -4
- package/dist/runtime/sub-agent-orchestrator.d.ts +2 -2
- package/dist/runtime/sub-agent-orchestrator.js +14 -23
- package/dist/types/agent.d.ts +12 -3
- package/dist/types/agent.js +18 -0
- package/dist/types.d.ts +22 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { RuntimeRunner, collectText } from "./runtime/runner.js";
|
|
2
2
|
export type { RuntimeOptions } from "./runtime/runner.js";
|
|
3
|
+
export { KernelPrimitivesDashboard } from "./runtime/kernel-primitives-dashboard.js";
|
|
3
4
|
export { FilteredExecutionPlane } from "./runtime/filtered-plane.js";
|
|
4
5
|
export { SubAgentOrchestrator, defaultSubAgentOrchestrator, spawnStandalone } from "./runtime/sub-agent-orchestrator.js";
|
|
5
6
|
export type { SubAgentRunContext } from "./runtime/sub-agent-orchestrator.js";
|
|
@@ -7,6 +8,11 @@ export { LocalExecutionPlane } from "./runtime/execution-plane.js";
|
|
|
7
8
|
export type { ExecutionPlane, RunContext } from "./runtime/execution-plane.js";
|
|
8
9
|
export { InMemorySessionLog, FileSessionLog } from "./runtime/session-log.js";
|
|
9
10
|
export type { SessionLog, SessionEvent } from "./runtime/session-log.js";
|
|
11
|
+
export { DEFAULT_NATIVE_ATTENTION_POLICY, DEFAULT_NATIVE_GOVERNANCE_POLICY, } from "./runtime/os-profile.js";
|
|
12
|
+
export { rebuildOsSnapshotFromSessionEvents, sessionLogHasRequiredCategories, } from "./runtime/os-snapshot.js";
|
|
13
|
+
export type { OsSnapshot } from "./runtime/os-snapshot.js";
|
|
14
|
+
export { categoryForKind, kernelObservationToSessionEvent } from "./runtime/kernel-event-log.js";
|
|
15
|
+
export type { KernelEventCategory } from "./runtime/kernel-event-log.js";
|
|
10
16
|
export { NullArchiveStore, FileArchiveStore } from "./runtime/archive.js";
|
|
11
17
|
export type { ArchiveStore } from "./runtime/archive.js";
|
|
12
18
|
export { EnvCredentialVault, InMemoryCredentialVault, ChainedCredentialVault } from "./runtime/credential-vault.js";
|
|
@@ -38,19 +44,19 @@ export type { RegisteredTool } from "./tools/index.js";
|
|
|
38
44
|
export { scanSkillDir, readSkillFile } from "./skills/loader.js";
|
|
39
45
|
export type { SkillMetadata } from "./skills/loader.js";
|
|
40
46
|
export { WorkingMemory } from "./memory/working.js";
|
|
41
|
-
export type { DreamStore, DreamResult, SessionData, SessionMessage, MemoryEntry, CurationResult, CurationStats, } from "./memory/protocols.js";
|
|
47
|
+
export type { DreamStore, DreamResult, SessionData, SessionMessage, MemoryEntry, CurationResult, CurationStats, MemoryWriteRequest, MemoryQuery, MemoryRetrieval, MemoryMetadata, MemoryKind, } from "./memory/protocols.js";
|
|
42
48
|
export type { KnowledgeSource } from "./knowledge/source.js";
|
|
43
49
|
export { ScheduledPrompt } from "./signals/scheduled.js";
|
|
44
50
|
export { SignalGateway } from "./signals/gateway.js";
|
|
45
51
|
export type { RuntimeSignal, SignalSource } from "./signals/types.js";
|
|
46
52
|
export { PermissionManager, PermissionMode } from "./safety/permissions.js";
|
|
47
53
|
export type { PermissionDecision, Permission } from "./safety/permissions.js";
|
|
48
|
-
export { Governance } from "./governance.js";
|
|
49
|
-
export type { GovernanceVerdict } from "./governance.js";
|
|
54
|
+
export { Governance, governancePolicyToKernelEvent } from "./governance.js";
|
|
55
|
+
export type { GovernanceVerdict, GovernancePolicy, GovernanceConstraint } from "./governance.js";
|
|
50
56
|
export { SinglePassHarness, EvalLoopHarness, HarnessLoop } from "./harness/harness.js";
|
|
51
57
|
export type { HarnessRequest, HarnessOutcome, HarnessLoopOptions, QualityGate } from "./harness/harness.js";
|
|
52
|
-
export type { Message, ToolCall, ToolResult, ToolSchema, ContentPart, TextPart, ImagePart, AudioPart, StreamEvent, TextDelta, ThinkingDelta, ToolCallEvent, ToolChunk, ToolDeltaEvent, ToolSuspendEvent, ToolResultEvent, DoneEvent, ErrorEvent, PermissionRequestEvent, LLMProvider, RetryConfig, TokenUsage, ProviderToolSpec, ProviderRunState, ProviderReplay, RenderedContext, } from "./types.js";
|
|
53
|
-
export type { AgentCapabilityFilter, AgentIdentity, AgentIsolation, AgentRunSpec,
|
|
58
|
+
export type { Message, ToolCall, ToolResult, ToolSchema, ContentPart, TextPart, ImagePart, AudioPart, StreamEvent, TextDelta, ThinkingDelta, ToolCallEvent, ToolChunk, ToolDeltaEvent, ToolSuspendEvent, ToolResultEvent, DoneEvent, ErrorEvent, PermissionRequestEvent, PermissionResolvedEvent, PermissionResponse, LLMProvider, RetryConfig, TokenUsage, ProviderToolSpec, ProviderRunState, ProviderReplay, RenderedContext, } from "./types.js";
|
|
59
|
+
export type { AgentCapabilityFilter, AgentIdentity, AgentIsolation, AgentRunSpec, AgentProcessChangedObservation, ContextInheritance, KernelAgentRole, LoopResult, MilestoneCheckResult, MilestoneContract, MilestonePhase, MilestonePolicy, SubAgentResult, TerminationReason, } from "./types/agent.js";
|
|
54
60
|
export { agentIdentitySub, agentRunSpecToKernel, milestoneCheckFail, milestoneCheckPass, milestoneCheckResultToKernel, subAgentResultToKernel, } from "./types/agent.js";
|
|
55
61
|
export type { AcceptanceCriterion, VerificationContract, ContractCheckResult, } from "./collaboration/contract.js";
|
|
56
62
|
export { ContractBuilder, formatContractForSystemPrompt, contractToCriteriaStrings, } from "./collaboration/contract.js";
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
// ── Runtime (Layer 1.5) ────────────────────────────────────────────────────
|
|
2
2
|
export { RuntimeRunner, collectText } from "./runtime/runner.js";
|
|
3
|
+
export { KernelPrimitivesDashboard } from "./runtime/kernel-primitives-dashboard.js";
|
|
3
4
|
export { FilteredExecutionPlane } from "./runtime/filtered-plane.js";
|
|
4
5
|
export { SubAgentOrchestrator, defaultSubAgentOrchestrator, spawnStandalone } from "./runtime/sub-agent-orchestrator.js";
|
|
5
6
|
export { LocalExecutionPlane } from "./runtime/execution-plane.js";
|
|
6
7
|
export { InMemorySessionLog, FileSessionLog } from "./runtime/session-log.js";
|
|
8
|
+
export { DEFAULT_NATIVE_ATTENTION_POLICY, DEFAULT_NATIVE_GOVERNANCE_POLICY, } from "./runtime/os-profile.js";
|
|
9
|
+
export { rebuildOsSnapshotFromSessionEvents, sessionLogHasRequiredCategories, } from "./runtime/os-snapshot.js";
|
|
10
|
+
export { categoryForKind, kernelObservationToSessionEvent } from "./runtime/kernel-event-log.js";
|
|
7
11
|
export { NullArchiveStore, FileArchiveStore } from "./runtime/archive.js";
|
|
8
12
|
export { EnvCredentialVault, InMemoryCredentialVault, ChainedCredentialVault } from "./runtime/credential-vault.js";
|
|
9
13
|
export { ProcessSandboxPlane } from "./runtime/process-sandbox-plane.js";
|
|
@@ -32,7 +36,7 @@ export { ScheduledPrompt } from "./signals/scheduled.js";
|
|
|
32
36
|
export { SignalGateway } from "./signals/gateway.js";
|
|
33
37
|
// ── Safety & Governance ────────────────────────────────────────────────────
|
|
34
38
|
export { PermissionManager, PermissionMode } from "./safety/permissions.js";
|
|
35
|
-
export { Governance } from "./governance.js";
|
|
39
|
+
export { Governance, governancePolicyToKernelEvent } from "./governance.js";
|
|
36
40
|
// ── Harness ────────────────────────────────────────────────────────────────
|
|
37
41
|
export { SinglePassHarness, EvalLoopHarness, HarnessLoop } from "./harness/harness.js";
|
|
38
42
|
export { agentIdentitySub, agentRunSpecToKernel, milestoneCheckFail, milestoneCheckPass, milestoneCheckResultToKernel, subAgentResultToKernel, } from "./types/agent.js";
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Long-term memory agent implementation (Phase 7).
|
|
3
|
+
*
|
|
4
|
+
* Provides two main capabilities:
|
|
5
|
+
* 1. Extract memories from conversation transcripts (后台代理)
|
|
6
|
+
* 2. Select relevant memories for current context (LLM选择器)
|
|
7
|
+
*
|
|
8
|
+
* Design principles:
|
|
9
|
+
* - Kernel defines memory types and validation rules
|
|
10
|
+
* - SDK performs I/O and selection
|
|
11
|
+
* - LLM (Sonnet) acts as selector, not vector similarity
|
|
12
|
+
*/
|
|
13
|
+
import type { SessionData, MemoryEntry } from "./protocols.js";
|
|
14
|
+
/**
|
|
15
|
+
* Memory metadata (matches kernel MemoryMetadata structure).
|
|
16
|
+
*/
|
|
17
|
+
export interface MemoryMetadata {
|
|
18
|
+
name: string;
|
|
19
|
+
description: string;
|
|
20
|
+
kind?: MemoryKind;
|
|
21
|
+
created_at: number;
|
|
22
|
+
updated_at: number;
|
|
23
|
+
session_id?: string;
|
|
24
|
+
user_role?: string;
|
|
25
|
+
expertise_level?: string;
|
|
26
|
+
preference_rule?: string;
|
|
27
|
+
approved_pattern?: string;
|
|
28
|
+
project_phase?: string;
|
|
29
|
+
relative_date?: string;
|
|
30
|
+
external_url?: string;
|
|
31
|
+
ticket_ref?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Memory kind (4 types, mirroring Claude Code).
|
|
35
|
+
*/
|
|
36
|
+
export type MemoryKind = "user" | "feedback" | "project" | "reference";
|
|
37
|
+
/**
|
|
38
|
+
* Memory write request (SDK → kernel).
|
|
39
|
+
*/
|
|
40
|
+
export interface MemoryWriteRequest {
|
|
41
|
+
metadata: MemoryMetadata;
|
|
42
|
+
content: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Memory query request (kernel → SDK).
|
|
46
|
+
*/
|
|
47
|
+
export interface MemoryQuery {
|
|
48
|
+
current_context: string;
|
|
49
|
+
active_tools: string[];
|
|
50
|
+
already_surfaced: string[];
|
|
51
|
+
top_k: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Memory retrieval response (SDK → kernel).
|
|
55
|
+
*/
|
|
56
|
+
export interface MemoryRetrieval {
|
|
57
|
+
selected_memory_ids: string[];
|
|
58
|
+
selection_rationale: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Memory index entry (from MEMORY.md).
|
|
62
|
+
*/
|
|
63
|
+
export interface MemoryIndexEntry {
|
|
64
|
+
name: string;
|
|
65
|
+
description: string;
|
|
66
|
+
kind?: MemoryKind;
|
|
67
|
+
file: string;
|
|
68
|
+
updated_at: number;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Extract memories from a completed session.
|
|
72
|
+
*
|
|
73
|
+
* This is typically called by a background agent after a session completes.
|
|
74
|
+
* It analyzes the conversation and generates new memory write requests.
|
|
75
|
+
*
|
|
76
|
+
* @param sessionData - The completed session data
|
|
77
|
+
* @param existingMemories - Existing memories to avoid duplicates
|
|
78
|
+
* @returns Array of memory write requests
|
|
79
|
+
*/
|
|
80
|
+
export declare function extractMemories(sessionData: SessionData, existingMemories: MemoryEntry[]): Promise<MemoryWriteRequest[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Select relevant memories for the current context.
|
|
83
|
+
*
|
|
84
|
+
* This uses an LLM (Sonnet) as a selector, not vector similarity.
|
|
85
|
+
* The process:
|
|
86
|
+
* 1. Read memory index (name + description for each memory)
|
|
87
|
+
* 2. Filter out already_surfaced and recentTools
|
|
88
|
+
* 3. Send the filtered list to LLM with current context
|
|
89
|
+
* 4. LLM returns top-5 most relevant memory IDs
|
|
90
|
+
*
|
|
91
|
+
* @param query - Memory query from kernel
|
|
92
|
+
* @param memoryIndex - Memory index entries
|
|
93
|
+
* @param model - Optional model name (default: claude-sonnet-4-20250514)
|
|
94
|
+
* @returns Memory retrieval result
|
|
95
|
+
*/
|
|
96
|
+
export declare function selectMemories(query: MemoryQuery, memoryIndex: MemoryIndexEntry[], model?: string): Promise<MemoryRetrieval>;
|
|
97
|
+
/**
|
|
98
|
+
* Validate memory before writing (kernel-side validation mirror).
|
|
99
|
+
*
|
|
100
|
+
* This SDK-side validation provides early feedback before sending to kernel.
|
|
101
|
+
*/
|
|
102
|
+
export declare function validateMemory(request: MemoryWriteRequest): {
|
|
103
|
+
valid: boolean;
|
|
104
|
+
error?: string;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Infer memory kind from metadata (mirrors kernel logic).
|
|
108
|
+
*/
|
|
109
|
+
export declare function inferMemoryKind(metadata: MemoryMetadata): MemoryKind;
|
|
110
|
+
/** Build a memory index from DreamStore entries for {@link selectMemories}. */
|
|
111
|
+
export declare function memoriesToIndex(entries: MemoryEntry[]): MemoryIndexEntry[];
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Long-term memory agent implementation (Phase 7).
|
|
3
|
+
*
|
|
4
|
+
* Provides two main capabilities:
|
|
5
|
+
* 1. Extract memories from conversation transcripts (后台代理)
|
|
6
|
+
* 2. Select relevant memories for current context (LLM选择器)
|
|
7
|
+
*
|
|
8
|
+
* Design principles:
|
|
9
|
+
* - Kernel defines memory types and validation rules
|
|
10
|
+
* - SDK performs I/O and selection
|
|
11
|
+
* - LLM (Sonnet) acts as selector, not vector similarity
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Extract memories from a completed session.
|
|
15
|
+
*
|
|
16
|
+
* This is typically called by a background agent after a session completes.
|
|
17
|
+
* It analyzes the conversation and generates new memory write requests.
|
|
18
|
+
*
|
|
19
|
+
* @param sessionData - The completed session data
|
|
20
|
+
* @param existingMemories - Existing memories to avoid duplicates
|
|
21
|
+
* @returns Array of memory write requests
|
|
22
|
+
*/
|
|
23
|
+
export async function extractMemories(sessionData, existingMemories) {
|
|
24
|
+
// In a real implementation, this would:
|
|
25
|
+
// 1. Use an LLM to analyze the session transcript
|
|
26
|
+
// 2. Identify new insights, preferences, and context
|
|
27
|
+
// 3. Generate memory write requests with proper classification
|
|
28
|
+
// 4. Check for duplicates against existing memories
|
|
29
|
+
// For now, return a stub implementation
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Select relevant memories for the current context.
|
|
34
|
+
*
|
|
35
|
+
* This uses an LLM (Sonnet) as a selector, not vector similarity.
|
|
36
|
+
* The process:
|
|
37
|
+
* 1. Read memory index (name + description for each memory)
|
|
38
|
+
* 2. Filter out already_surfaced and recentTools
|
|
39
|
+
* 3. Send the filtered list to LLM with current context
|
|
40
|
+
* 4. LLM returns top-5 most relevant memory IDs
|
|
41
|
+
*
|
|
42
|
+
* @param query - Memory query from kernel
|
|
43
|
+
* @param memoryIndex - Memory index entries
|
|
44
|
+
* @param model - Optional model name (default: claude-sonnet-4-20250514)
|
|
45
|
+
* @returns Memory retrieval result
|
|
46
|
+
*/
|
|
47
|
+
export async function selectMemories(query, memoryIndex, model = "claude-sonnet-4-20250514") {
|
|
48
|
+
// 1. Filter out already surfaced and tool-related memories
|
|
49
|
+
const filterOut = new Set([
|
|
50
|
+
...query.already_surfaced,
|
|
51
|
+
...query.active_tools,
|
|
52
|
+
]);
|
|
53
|
+
const candidates = memoryIndex.filter((entry) => !filterOut.has(entry.name) && !isToolMemory(entry));
|
|
54
|
+
// 2. If no candidates, return empty
|
|
55
|
+
if (candidates.length === 0) {
|
|
56
|
+
return {
|
|
57
|
+
selected_memory_ids: [],
|
|
58
|
+
selection_rationale: "No candidates after filtering",
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// 3. In a real implementation, this would:
|
|
62
|
+
// - Construct a prompt with current context and memory descriptions
|
|
63
|
+
// - Call the LLM API
|
|
64
|
+
// - Parse the response to extract selected memory IDs
|
|
65
|
+
// For now, return a stub implementation
|
|
66
|
+
return {
|
|
67
|
+
selected_memory_ids: candidates.slice(0, query.top_k).map((c) => c.name),
|
|
68
|
+
selection_rationale: "Stub implementation",
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if a memory is tool-related (should be filtered from recentTools).
|
|
73
|
+
*/
|
|
74
|
+
function isToolMemory(entry) {
|
|
75
|
+
const toolKeywords = ["usage", "how to use", "example", "syntax", "api"];
|
|
76
|
+
const lowerDesc = entry.description.toLowerCase();
|
|
77
|
+
const lowerName = entry.name.toLowerCase();
|
|
78
|
+
// Filter out usage docs, but keep warnings/caveats
|
|
79
|
+
const isUsage = toolKeywords.some((kw) => lowerDesc.includes(kw) || lowerName.includes(kw));
|
|
80
|
+
const isWarning = lowerDesc.includes("warning") || lowerDesc.includes("caveat") || lowerDesc.includes("bug");
|
|
81
|
+
return isUsage && !isWarning;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Validate memory before writing (kernel-side validation mirror).
|
|
85
|
+
*
|
|
86
|
+
* This SDK-side validation provides early feedback before sending to kernel.
|
|
87
|
+
*/
|
|
88
|
+
export function validateMemory(request) {
|
|
89
|
+
// Check required fields
|
|
90
|
+
if (!request.metadata.name || request.metadata.name.trim().length === 0) {
|
|
91
|
+
return { valid: false, error: "Missing required field: name" };
|
|
92
|
+
}
|
|
93
|
+
if (!request.metadata.description || request.metadata.description.trim().length === 0) {
|
|
94
|
+
return { valid: false, error: "Missing required field: description" };
|
|
95
|
+
}
|
|
96
|
+
// Check name length
|
|
97
|
+
if (request.metadata.name.length > 100) {
|
|
98
|
+
return { valid: false, error: `Name too long: ${request.metadata.name.length} chars (limit: 100)` };
|
|
99
|
+
}
|
|
100
|
+
// Check content size
|
|
101
|
+
if (request.content.length > 10_000) {
|
|
102
|
+
return { valid: false, error: `Content too large: ${request.content.length} bytes (limit: 10000)` };
|
|
103
|
+
}
|
|
104
|
+
// Check forbidden patterns
|
|
105
|
+
const forbiddenPatterns = [
|
|
106
|
+
{ pattern: "代码模式:", reason: "应从代码推,不应存储" },
|
|
107
|
+
{ pattern: "文件路径:", reason: "应从git推,不应存储" },
|
|
108
|
+
{ pattern: "架构:", reason: "应从实际代码推" },
|
|
109
|
+
{ pattern: "git历史:", reason: "git log是权威" },
|
|
110
|
+
{ pattern: "CLAUDE.md:", reason: "已在文档中" },
|
|
111
|
+
{ pattern: "TODO:", reason: "临时任务不应进记忆" },
|
|
112
|
+
];
|
|
113
|
+
for (const { pattern, reason } of forbiddenPatterns) {
|
|
114
|
+
if (request.content.includes(pattern)) {
|
|
115
|
+
return { valid: false, error: `Forbidden pattern '${pattern}': ${reason}` };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return { valid: true };
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Infer memory kind from metadata (mirrors kernel logic).
|
|
122
|
+
*/
|
|
123
|
+
export function inferMemoryKind(metadata) {
|
|
124
|
+
if (metadata.user_role || metadata.expertise_level) {
|
|
125
|
+
return "user";
|
|
126
|
+
}
|
|
127
|
+
if (metadata.preference_rule || metadata.approved_pattern) {
|
|
128
|
+
return "feedback";
|
|
129
|
+
}
|
|
130
|
+
if (metadata.project_phase || metadata.relative_date) {
|
|
131
|
+
return "project";
|
|
132
|
+
}
|
|
133
|
+
if (metadata.external_url || metadata.ticket_ref) {
|
|
134
|
+
return "reference";
|
|
135
|
+
}
|
|
136
|
+
// Default: feedback (most common)
|
|
137
|
+
return "feedback";
|
|
138
|
+
}
|
|
139
|
+
/** Build a memory index from DreamStore entries for {@link selectMemories}. */
|
|
140
|
+
export function memoriesToIndex(entries) {
|
|
141
|
+
return entries.map(entry => {
|
|
142
|
+
const meta = (entry.metadata ?? {});
|
|
143
|
+
return {
|
|
144
|
+
name: String(meta.name ?? entry.text.slice(0, 40)),
|
|
145
|
+
description: String(meta.description ?? entry.text.slice(0, 120)),
|
|
146
|
+
kind: meta.kind,
|
|
147
|
+
file: String(meta.file ?? ""),
|
|
148
|
+
updated_at: Number(meta.updated_at ?? 0),
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
}
|
|
@@ -45,6 +45,62 @@ export interface DreamStore {
|
|
|
45
45
|
/** Persist a completed session for future consolidation via `Agent.dream()`. */
|
|
46
46
|
saveSession(data: SessionData): Promise<void>;
|
|
47
47
|
}
|
|
48
|
+
/** Memory kind (4 types, mirroring Claude Code). */
|
|
49
|
+
export type MemoryKind = "user" | "feedback" | "project" | "reference";
|
|
50
|
+
/** Memory metadata (kernel stores, SDK provides full content). */
|
|
51
|
+
export interface MemoryMetadata {
|
|
52
|
+
name: string;
|
|
53
|
+
description: string;
|
|
54
|
+
kind?: MemoryKind;
|
|
55
|
+
created_at: number;
|
|
56
|
+
updated_at: number;
|
|
57
|
+
session_id?: string;
|
|
58
|
+
user_role?: string;
|
|
59
|
+
expertise_level?: string;
|
|
60
|
+
preference_rule?: string;
|
|
61
|
+
approved_pattern?: string;
|
|
62
|
+
project_phase?: string;
|
|
63
|
+
relative_date?: string;
|
|
64
|
+
external_url?: string;
|
|
65
|
+
ticket_ref?: string;
|
|
66
|
+
}
|
|
67
|
+
/** Memory write request (SDK → kernel). */
|
|
68
|
+
export interface MemoryWriteRequest {
|
|
69
|
+
metadata: MemoryMetadata;
|
|
70
|
+
content: string;
|
|
71
|
+
}
|
|
72
|
+
/** Memory query request (kernel → SDK). */
|
|
73
|
+
export interface MemoryQuery {
|
|
74
|
+
current_context: string;
|
|
75
|
+
active_tools: string[];
|
|
76
|
+
already_surfaced: string[];
|
|
77
|
+
top_k: number;
|
|
78
|
+
}
|
|
79
|
+
/** Memory retrieval response (SDK → kernel). */
|
|
80
|
+
export interface MemoryRetrieval {
|
|
81
|
+
selected_memory_ids: string[];
|
|
82
|
+
selection_rationale: string;
|
|
83
|
+
}
|
|
84
|
+
/** Memory validation error (mirroring kernel MemoryValidationError). */
|
|
85
|
+
export type MemoryValidationError = {
|
|
86
|
+
error_kind: "missing_required_field";
|
|
87
|
+
field: string;
|
|
88
|
+
} | {
|
|
89
|
+
error_kind: "content_too_large";
|
|
90
|
+
size: number;
|
|
91
|
+
limit: number;
|
|
92
|
+
} | {
|
|
93
|
+
error_kind: "forbidden_pattern";
|
|
94
|
+
pattern: string;
|
|
95
|
+
reason: string;
|
|
96
|
+
} | {
|
|
97
|
+
error_kind: "invalid_kind";
|
|
98
|
+
kind: string;
|
|
99
|
+
} | {
|
|
100
|
+
error_kind: "name_too_long";
|
|
101
|
+
length: number;
|
|
102
|
+
limit: number;
|
|
103
|
+
};
|
|
48
104
|
/** Durable transcript storage for same-session conversational continuity. */
|
|
49
105
|
export interface DreamResult {
|
|
50
106
|
sessionsProcessed: number;
|
|
@@ -35,17 +35,27 @@ export class DeepSeekProvider extends OpenAIChatProvider {
|
|
|
35
35
|
let finalText = "";
|
|
36
36
|
const stream = await this.client.chat.completions.create({
|
|
37
37
|
...omitExtensionKeys(extensions, [
|
|
38
|
-
"model", "messages", "tools", "stream", "extra_body", "reasoning_effort",
|
|
38
|
+
"model", "messages", "tools", "stream", "stream_options", "extra_body", "reasoning_effort",
|
|
39
39
|
"exposeReasoning", "thinking", "reasoningEffort",
|
|
40
40
|
]),
|
|
41
41
|
model: this.model,
|
|
42
42
|
messages: msgs,
|
|
43
43
|
...(tools.length ? { tools: this.chat.buildTools(tools) } : {}),
|
|
44
44
|
stream: true,
|
|
45
|
+
stream_options: { include_usage: true },
|
|
45
46
|
reasoning_effort: reasoningEffort,
|
|
46
47
|
extra_body: { thinking: { type: thinking } },
|
|
47
48
|
});
|
|
49
|
+
let totalTokens = 0;
|
|
50
|
+
let inputTokens = 0;
|
|
51
|
+
let outputTokens = 0;
|
|
48
52
|
for await (const chunk of stream) {
|
|
53
|
+
if (chunk.usage) {
|
|
54
|
+
totalTokens = chunk.usage.total_tokens;
|
|
55
|
+
inputTokens = chunk.usage.prompt_tokens ?? 0;
|
|
56
|
+
outputTokens = chunk.usage.completion_tokens ?? 0;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
49
59
|
const choice = chunk.choices[0];
|
|
50
60
|
if (!choice)
|
|
51
61
|
continue;
|
|
@@ -110,5 +120,7 @@ export class DeepSeekProvider extends OpenAIChatProvider {
|
|
|
110
120
|
emittedToolCallIndexes.add(idx);
|
|
111
121
|
yield { type: "tool_call", id: tb.id, name: tb.name, arguments: args };
|
|
112
122
|
}
|
|
123
|
+
if (totalTokens > 0)
|
|
124
|
+
yield { type: "usage", totalTokens, inputTokens, outputTokens };
|
|
113
125
|
}
|
|
114
126
|
}
|
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
import type { ToolCall, ToolSchema, StreamEvent, ToolSuspendEvent } from "../types.js";
|
|
1
|
+
import type { ToolCall, ToolSchema, StreamEvent, ToolSuspendEvent, PermissionRequestEvent, PermissionResponse } from "../types.js";
|
|
2
2
|
import type { RegisteredTool } from "../tools/index.js";
|
|
3
3
|
import type { DreamStore } from "../memory/protocols.js";
|
|
4
4
|
import type { KnowledgeSource } from "../knowledge/source.js";
|
|
5
|
+
import { LargeResultSpool } from "./large-result-spool.js";
|
|
5
6
|
export interface RunContext {
|
|
6
7
|
agentId?: string;
|
|
7
8
|
skillDir?: string;
|
|
8
9
|
dreamStore?: DreamStore;
|
|
9
10
|
knowledgeSource?: KnowledgeSource;
|
|
10
|
-
governance?: {
|
|
11
|
-
setTime?(nowMs: bigint): void;
|
|
12
|
-
evaluate(name: string, argsJson: string): {
|
|
13
|
-
kind: string;
|
|
14
|
-
reason?: string;
|
|
15
|
-
retryAfterMs?: number;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
11
|
onToolSuspend?: (event: ToolSuspendEvent) => Promise<unknown> | unknown;
|
|
12
|
+
onPermissionRequest?: (event: PermissionRequestEvent) => Promise<PermissionResponse | boolean> | PermissionResponse | boolean;
|
|
13
|
+
resultSpool?: LargeResultSpool;
|
|
19
14
|
}
|
|
20
15
|
export interface ExecutionPlane {
|
|
21
16
|
register(...tools: RegisteredTool[]): this;
|
|
@@ -34,5 +29,7 @@ export declare class LocalExecutionPlane implements ExecutionPlane {
|
|
|
34
29
|
unregister(name: string): this;
|
|
35
30
|
schemas(): ToolSchema[];
|
|
36
31
|
executeAll(calls: ToolCall[], ctx: RunContext): AsyncIterable<StreamEvent>;
|
|
32
|
+
private tryReadSpooledArgument;
|
|
37
33
|
private executeSingle;
|
|
38
34
|
}
|
|
35
|
+
export declare function resolvePermissionRequest(request: PermissionRequestEvent, ctx: RunContext): Promise<PermissionResponse>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isAsyncIterable, normalizeToolChunk, toolChunkText, validateToolArguments } from "../tools/index.js";
|
|
2
2
|
import { readSkillFile } from "../skills/loader.js";
|
|
3
|
+
import { LargeResultSpool } from "./large-result-spool.js";
|
|
3
4
|
export class LocalExecutionPlane {
|
|
4
5
|
tools = new Map();
|
|
5
6
|
register(...tools) {
|
|
@@ -15,31 +16,7 @@ export class LocalExecutionPlane {
|
|
|
15
16
|
return Array.from(this.tools.values()).map(t => t.schema);
|
|
16
17
|
}
|
|
17
18
|
async *executeAll(calls, ctx) {
|
|
18
|
-
|
|
19
|
-
// receives a result for every call it dispatched.
|
|
20
|
-
const permitted = [];
|
|
21
|
-
for (const c of calls) {
|
|
22
|
-
if (ctx.governance) {
|
|
23
|
-
ctx.governance.setTime?.(BigInt(Date.now()));
|
|
24
|
-
const v = ctx.governance.evaluate(c.name, c.arguments);
|
|
25
|
-
if (v.kind === "deny") {
|
|
26
|
-
yield { type: "tool_denied", callId: c.id, toolName: c.name, reason: v.reason ?? "" };
|
|
27
|
-
yield { type: "tool_result", callId: c.id, name: c.name, content: `permission denied: ${v.reason ?? ""}`, isError: true };
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
if (v.kind === "rate_limited") {
|
|
31
|
-
yield { type: "error", message: `rate limited: ${c.name}` };
|
|
32
|
-
yield { type: "tool_result", callId: c.id, name: c.name, content: "rate limited", isError: true };
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
if (v.kind === "ask_user") {
|
|
36
|
-
yield { type: "permission_request", callId: c.id, toolName: c.name, arguments: c.arguments, reason: v.reason ?? "" };
|
|
37
|
-
yield { type: "tool_result", callId: c.id, name: c.name, content: "awaiting user approval", isError: true };
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
permitted.push(c);
|
|
42
|
-
}
|
|
19
|
+
const permitted = calls;
|
|
43
20
|
const skillCalls = permitted.filter(c => c.name === "skill");
|
|
44
21
|
const memoryCalls = permitted.filter(c => c.name === "memory");
|
|
45
22
|
const knowledgeCalls = permitted.filter(c => c.name === "knowledge");
|
|
@@ -98,7 +75,30 @@ export class LocalExecutionPlane {
|
|
|
98
75
|
}
|
|
99
76
|
}
|
|
100
77
|
}
|
|
78
|
+
async tryReadSpooledArgument(call, ctx) {
|
|
79
|
+
const isReadTool = ["read", "read_file", "view_file", "read_spooled_result"].includes(call.name);
|
|
80
|
+
if (!isReadTool)
|
|
81
|
+
return null;
|
|
82
|
+
try {
|
|
83
|
+
const args = JSON.parse(call.arguments || "{}");
|
|
84
|
+
for (const val of Object.values(args)) {
|
|
85
|
+
if (typeof val === "string" && (val.startsWith(".spool/") || val.includes("/.spool/"))) {
|
|
86
|
+
const spool = ctx.resultSpool ?? new LargeResultSpool();
|
|
87
|
+
const content = await spool.readSpooledResult(val);
|
|
88
|
+
return content;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Ignore errors
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
101
97
|
async *executeSingle(call, ctx) {
|
|
98
|
+
const spooledContent = await this.tryReadSpooledArgument(call, ctx);
|
|
99
|
+
if (spooledContent !== null) {
|
|
100
|
+
return { callId: call.id, output: spooledContent, isError: false };
|
|
101
|
+
}
|
|
102
102
|
const registered = this.tools.get(call.name);
|
|
103
103
|
if (!registered)
|
|
104
104
|
return { callId: call.id, output: `unknown tool: ${call.name}`, isError: true };
|
|
@@ -168,3 +168,31 @@ function tryParseJson(s) {
|
|
|
168
168
|
return null;
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
|
+
export async function resolvePermissionRequest(request, ctx) {
|
|
172
|
+
if (!ctx.onPermissionRequest) {
|
|
173
|
+
return {
|
|
174
|
+
approved: false,
|
|
175
|
+
responder: "policy_gate",
|
|
176
|
+
reason: "no permission handler configured",
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
return normalizePermissionDecision(await ctx.onPermissionRequest(request));
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
return {
|
|
184
|
+
approved: false,
|
|
185
|
+
responder: "permission_handler",
|
|
186
|
+
reason: `permission handler failed: ${String(err)}`,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function normalizePermissionDecision(value) {
|
|
191
|
+
if (typeof value === "boolean")
|
|
192
|
+
return { approved: value, responder: "host" };
|
|
193
|
+
return {
|
|
194
|
+
approved: Boolean(value.approved),
|
|
195
|
+
responder: value.responder ?? "host",
|
|
196
|
+
...(value.reason ? { reason: value.reason } : {}),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { KernelObservation } from "./kernel-step.js";
|
|
2
|
+
import type { SessionEvent } from "./session-log.js";
|
|
3
|
+
/** Agent OS kernel event category (Phase 5). */
|
|
4
|
+
export type KernelEventCategory = "syscall" | "sched" | "mm" | "proc" | "ipc";
|
|
5
|
+
export declare function categoryForKind(kind: string): KernelEventCategory;
|
|
6
|
+
export declare function withCategory<T extends {
|
|
7
|
+
kind: string;
|
|
8
|
+
}>(event: T): T & {
|
|
9
|
+
category: KernelEventCategory;
|
|
10
|
+
primitive: KernelPrimitive;
|
|
11
|
+
};
|
|
12
|
+
type CompressionAction = Extract<SessionEvent, {
|
|
13
|
+
kind: "compressed";
|
|
14
|
+
}>["action"];
|
|
15
|
+
export declare function kernelObservationToSessionEvent(obs: KernelObservation, turn: number, opts?: {
|
|
16
|
+
nextArchiveStart?: number;
|
|
17
|
+
latestSeq?: number;
|
|
18
|
+
archiveRef?: string;
|
|
19
|
+
preservedRefs?: string[];
|
|
20
|
+
compressionAction?: (action?: string) => CompressionAction;
|
|
21
|
+
spoolRef?: string;
|
|
22
|
+
}): SessionEvent | null;
|
|
23
|
+
export type KernelPrimitive = "syscall" | "sched" | "mm";
|
|
24
|
+
export declare function primitiveForCategory(category: KernelEventCategory): KernelPrimitive;
|
|
25
|
+
export declare function primitiveForKind(kind: string): KernelPrimitive;
|
|
26
|
+
export {};
|