@nexalab/agent-sdk 0.1.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/LICENSE +15 -0
- package/README.md +518 -0
- package/bin/nexa.mjs +33 -0
- package/dist/advanced-memory.d.ts +32 -0
- package/dist/advanced-memory.d.ts.map +1 -0
- package/dist/advanced-memory.js +54 -0
- package/dist/advanced-memory.js.map +1 -0
- package/dist/agent-builder.d.ts +60 -0
- package/dist/agent-builder.d.ts.map +1 -0
- package/dist/agent-builder.js +141 -0
- package/dist/agent-builder.js.map +1 -0
- package/dist/approvals.d.ts +34 -0
- package/dist/approvals.d.ts.map +1 -0
- package/dist/approvals.js +54 -0
- package/dist/approvals.js.map +1 -0
- package/dist/artifacts.d.ts +13 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +13 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/cache.d.ts +17 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +29 -0
- package/dist/cache.js.map +1 -0
- package/dist/completion-gate.d.ts +5 -0
- package/dist/completion-gate.d.ts.map +1 -0
- package/dist/completion-gate.js +20 -0
- package/dist/completion-gate.js.map +1 -0
- package/dist/console-chat.d.ts +110 -0
- package/dist/console-chat.d.ts.map +1 -0
- package/dist/console-chat.js +284 -0
- package/dist/console-chat.js.map +1 -0
- package/dist/context.d.ts +45 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +92 -0
- package/dist/context.js.map +1 -0
- package/dist/evals.d.ts +38 -0
- package/dist/evals.d.ts.map +1 -0
- package/dist/evals.js +37 -0
- package/dist/evals.js.map +1 -0
- package/dist/event-bus.d.ts +28 -0
- package/dist/event-bus.d.ts.map +1 -0
- package/dist/event-bus.js +28 -0
- package/dist/event-bus.js.map +1 -0
- package/dist/file-storage.d.ts +25 -0
- package/dist/file-storage.d.ts.map +1 -0
- package/dist/file-storage.js +100 -0
- package/dist/file-storage.js.map +1 -0
- package/dist/guardrails.d.ts +44 -0
- package/dist/guardrails.d.ts.map +1 -0
- package/dist/guardrails.js +37 -0
- package/dist/guardrails.js.map +1 -0
- package/dist/harness.d.ts +26 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/harness.js +49 -0
- package/dist/harness.js.map +1 -0
- package/dist/hooks.d.ts +58 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +16 -0
- package/dist/hooks.js.map +1 -0
- package/dist/http-adapter.d.ts +13 -0
- package/dist/http-adapter.d.ts.map +1 -0
- package/dist/http-adapter.js +33 -0
- package/dist/http-adapter.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel.d.ts +90 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +251 -0
- package/dist/kernel.js.map +1 -0
- package/dist/knowledge.d.ts +35 -0
- package/dist/knowledge.d.ts.map +1 -0
- package/dist/knowledge.js +89 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/local-tool-executor.d.ts +26 -0
- package/dist/local-tool-executor.d.ts.map +1 -0
- package/dist/local-tool-executor.js +30 -0
- package/dist/local-tool-executor.js.map +1 -0
- package/dist/loop-guard.d.ts +15 -0
- package/dist/loop-guard.d.ts.map +1 -0
- package/dist/loop-guard.js +12 -0
- package/dist/loop-guard.js.map +1 -0
- package/dist/manifest.d.ts +43 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +31 -0
- package/dist/manifest.js.map +1 -0
- package/dist/mcp.d.ts +55 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +175 -0
- package/dist/mcp.js.map +1 -0
- package/dist/memory.d.ts +32 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +40 -0
- package/dist/memory.js.map +1 -0
- package/dist/mission-runtime.d.ts +106 -0
- package/dist/mission-runtime.d.ts.map +1 -0
- package/dist/mission-runtime.js +196 -0
- package/dist/mission-runtime.js.map +1 -0
- package/dist/model-harness.d.ts +23 -0
- package/dist/model-harness.d.ts.map +1 -0
- package/dist/model-harness.js +7 -0
- package/dist/model-harness.js.map +1 -0
- package/dist/model-router.d.ts +60 -0
- package/dist/model-router.d.ts.map +1 -0
- package/dist/model-router.js +90 -0
- package/dist/model-router.js.map +1 -0
- package/dist/multi-agent.d.ts +56 -0
- package/dist/multi-agent.d.ts.map +1 -0
- package/dist/multi-agent.js +69 -0
- package/dist/multi-agent.js.map +1 -0
- package/dist/native-tool-loop.d.ts +70 -0
- package/dist/native-tool-loop.d.ts.map +1 -0
- package/dist/native-tool-loop.js +92 -0
- package/dist/native-tool-loop.js.map +1 -0
- package/dist/openai-agent.d.ts +75 -0
- package/dist/openai-agent.d.ts.map +1 -0
- package/dist/openai-agent.js +190 -0
- package/dist/openai-agent.js.map +1 -0
- package/dist/openai-compatible.d.ts +117 -0
- package/dist/openai-compatible.d.ts.map +1 -0
- package/dist/openai-compatible.js +486 -0
- package/dist/openai-compatible.js.map +1 -0
- package/dist/otel.d.ts +12 -0
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +35 -0
- package/dist/otel.js.map +1 -0
- package/dist/permissions.d.ts +6 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +33 -0
- package/dist/permissions.js.map +1 -0
- package/dist/plan-validator.d.ts +9 -0
- package/dist/plan-validator.d.ts.map +1 -0
- package/dist/plan-validator.js +27 -0
- package/dist/plan-validator.js.map +1 -0
- package/dist/policy.d.ts +27 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +37 -0
- package/dist/policy.js.map +1 -0
- package/dist/postgres-storage.d.ts +33 -0
- package/dist/postgres-storage.d.ts.map +1 -0
- package/dist/postgres-storage.js +80 -0
- package/dist/postgres-storage.js.map +1 -0
- package/dist/provider-capabilities.d.ts +13 -0
- package/dist/provider-capabilities.d.ts.map +1 -0
- package/dist/provider-capabilities.js +19 -0
- package/dist/provider-capabilities.js.map +1 -0
- package/dist/providers.d.ts +14 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +69 -0
- package/dist/providers.js.map +1 -0
- package/dist/queue.d.ts +29 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +36 -0
- package/dist/queue.js.map +1 -0
- package/dist/redis-storage.d.ts +36 -0
- package/dist/redis-storage.d.ts.map +1 -0
- package/dist/redis-storage.js +68 -0
- package/dist/redis-storage.js.map +1 -0
- package/dist/replay.d.ts +13 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +32 -0
- package/dist/replay.js.map +1 -0
- package/dist/runtime.d.ts +54 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +218 -0
- package/dist/runtime.js.map +1 -0
- package/dist/sdk.d.ts +43 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +82 -0
- package/dist/sdk.js.map +1 -0
- package/dist/secrets.d.ts +9 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +23 -0
- package/dist/secrets.js.map +1 -0
- package/dist/sessions.d.ts +44 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +76 -0
- package/dist/sessions.js.map +1 -0
- package/dist/skills.d.ts +12 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +13 -0
- package/dist/skills.js.map +1 -0
- package/dist/smoke.d.ts +8 -0
- package/dist/smoke.d.ts.map +1 -0
- package/dist/smoke.js +5 -0
- package/dist/smoke.js.map +1 -0
- package/dist/sqlite-storage.d.ts +30 -0
- package/dist/sqlite-storage.d.ts.map +1 -0
- package/dist/sqlite-storage.js +52 -0
- package/dist/sqlite-storage.js.map +1 -0
- package/dist/storage.d.ts +74 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +83 -0
- package/dist/storage.js.map +1 -0
- package/dist/structured-output.d.ts +14 -0
- package/dist/structured-output.d.ts.map +1 -0
- package/dist/structured-output.js +24 -0
- package/dist/structured-output.js.map +1 -0
- package/dist/telemetry.d.ts +27 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +40 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/tenancy.d.ts +9 -0
- package/dist/tenancy.d.ts.map +1 -0
- package/dist/tenancy.js +8 -0
- package/dist/tenancy.js.map +1 -0
- package/dist/tool-factory.d.ts +25 -0
- package/dist/tool-factory.d.ts.map +1 -0
- package/dist/tool-factory.js +38 -0
- package/dist/tool-factory.js.map +1 -0
- package/dist/tool-orchestrator.d.ts +89 -0
- package/dist/tool-orchestrator.d.ts.map +1 -0
- package/dist/tool-orchestrator.js +102 -0
- package/dist/tool-orchestrator.js.map +1 -0
- package/dist/tool-registry.d.ts +52 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +19 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/types.d.ts +1020 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +115 -0
- package/dist/types.js.map +1 -0
- package/dist/vector-memory.d.ts +19 -0
- package/dist/vector-memory.d.ts.map +1 -0
- package/dist/vector-memory.js +58 -0
- package/dist/vector-memory.js.map +1 -0
- package/dist/workflow.d.ts +65 -0
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.js +102 -0
- package/dist/workflow.js.map +1 -0
- package/dist/workspace.d.ts +35 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +131 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +223 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
# Nexa Agent SDK
|
|
2
|
+
|
|
3
|
+
`@nexalab/agent-sdk` is a composable TypeScript SDK for building agentic assistants, workers, CLIs, app backends, durable workflows, and multi-agent systems.
|
|
4
|
+
|
|
5
|
+
It is designed around a small happy path for quick integration, plus production hooks for providers, tools, approvals, storage, telemetry, memory, evals, replay, routing, policy, and evidence-backed runs.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @nexalab/agent-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
For local workspace use:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@nexalab/agent-sdk": "workspace:*"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### Premium `agent({...})` Kernel API
|
|
26
|
+
|
|
27
|
+
Five minutes from `npm install` to a running agent, with a single config object. `model` accepts a `"provider:model"` string resolved against the built-in provider presets (API key read from the matching env var, e.g. `OPENAI_API_KEY`):
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { agent } from "@nexalab/agent-sdk";
|
|
31
|
+
import { z } from "zod";
|
|
32
|
+
|
|
33
|
+
const assistant = await agent({
|
|
34
|
+
name: "sales-agent",
|
|
35
|
+
model: "openai:gpt-4o-mini",
|
|
36
|
+
instructions: "Eres un agente comercial. Ayudas al cliente a cotizar productos.",
|
|
37
|
+
memory: true
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const result = await assistant.run("Cotizale 20 tanques a Abraham");
|
|
41
|
+
console.log(result.text);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Grows into the full Kernel surface without changing shape — context engine, guardrails, hooks, sessions, structured outputs, and tools all compose onto the same object:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const result = await assistant.run("Analiza este prospecto", {
|
|
48
|
+
outputSchema: z.object({ score: z.number(), reason: z.string(), nextAction: z.string() })
|
|
49
|
+
});
|
|
50
|
+
result.output; // typed { score, reason, nextAction }
|
|
51
|
+
|
|
52
|
+
const session = assistant.session("customer-38273");
|
|
53
|
+
await session.run("Hola");
|
|
54
|
+
await session.run("Recuerdas mi pedido?");
|
|
55
|
+
|
|
56
|
+
const asTool = assistant.asTool(); // callable from another agent's native tool loop
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
See [Public Modules](#public-modules) below (`context`, `sessions`, `guardrails`, `hooks`, `structured-output`, `kernel`) for the building blocks this composes.
|
|
60
|
+
|
|
61
|
+
### Builder API
|
|
62
|
+
|
|
63
|
+
The lower-level fluent builder remains fully supported for cases that need explicit control over provider wiring, storage, and tracing:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import {
|
|
67
|
+
createAgent,
|
|
68
|
+
defineSdkTool,
|
|
69
|
+
openaiProvider,
|
|
70
|
+
createInMemoryStorage,
|
|
71
|
+
createTelemetry
|
|
72
|
+
} from "@nexalab/agent-sdk";
|
|
73
|
+
import { z } from "zod";
|
|
74
|
+
|
|
75
|
+
const getTime = defineSdkTool({
|
|
76
|
+
id: "system.read_time",
|
|
77
|
+
capability: "system.time.read",
|
|
78
|
+
description: "Read the current system time.",
|
|
79
|
+
inputSchema: z.object({}),
|
|
80
|
+
handler: async () => ({
|
|
81
|
+
status: "ok",
|
|
82
|
+
output: { iso: new Date().toISOString() }
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const builderAgent = await createAgent()
|
|
87
|
+
.useProvider(openaiProvider({
|
|
88
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
89
|
+
model: "gpt-4o-mini"
|
|
90
|
+
}))
|
|
91
|
+
.useTool(getTime)
|
|
92
|
+
.useStorage(createInMemoryStorage())
|
|
93
|
+
.useTelemetry(createTelemetry())
|
|
94
|
+
.useConsoleTrace()
|
|
95
|
+
.build();
|
|
96
|
+
|
|
97
|
+
const result = await builderAgent.runMessage("puedes decirme que hora es?");
|
|
98
|
+
console.log(result.text);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Core Capabilities
|
|
102
|
+
|
|
103
|
+
- Agentic task/run runtime
|
|
104
|
+
- Mission runtime
|
|
105
|
+
- Goal interpretation contracts
|
|
106
|
+
- Success criteria and evidence model
|
|
107
|
+
- Executable plan model
|
|
108
|
+
- Plan validation
|
|
109
|
+
- Completion gate
|
|
110
|
+
- Loop guard
|
|
111
|
+
- Normalized runtime events
|
|
112
|
+
- Permission-aware tool registry
|
|
113
|
+
- Zod-friendly tool factory
|
|
114
|
+
- Local tool executor
|
|
115
|
+
- Approval manager
|
|
116
|
+
- Human-in-the-loop approval primitives
|
|
117
|
+
- Multi-round transparent tool loop
|
|
118
|
+
- Native model-requested tool-call loop
|
|
119
|
+
- Async `runStream(...)` event stream
|
|
120
|
+
- In-memory event bus
|
|
121
|
+
- In-memory memory store
|
|
122
|
+
- Advanced memory with dedupe, recency boost, and contextual retrieval
|
|
123
|
+
- Vector memory with pluggable embeddings
|
|
124
|
+
- JSON file storage
|
|
125
|
+
- SQLite storage adapter contract
|
|
126
|
+
- Postgres storage adapter contract
|
|
127
|
+
- Redis storage adapter contract
|
|
128
|
+
- Pluggable storage interfaces
|
|
129
|
+
- Queue adapter and in-memory queue
|
|
130
|
+
- OpenAI-compatible provider registry
|
|
131
|
+
- Provider presets for OpenAI, OpenRouter, Ollama, and custom OpenAI-compatible APIs
|
|
132
|
+
- OpenAI-compatible `/v1/models` lookup
|
|
133
|
+
- OpenAI-compatible chat completions and streaming
|
|
134
|
+
- Model routing and budget accounting
|
|
135
|
+
- Telemetry hooks for events, tool traces, and spans
|
|
136
|
+
- OpenTelemetry-compatible sink bridge
|
|
137
|
+
- Agent eval harness
|
|
138
|
+
- HTTP request handler
|
|
139
|
+
- Checkpointed workflow runtime
|
|
140
|
+
- Replay/debug timeline helpers
|
|
141
|
+
- Tool policy helpers for deny/approval rules
|
|
142
|
+
- Multi-agent coordinator and delegation helpers
|
|
143
|
+
- Premium `agent({...})` Kernel config API on top of the builder/runtime
|
|
144
|
+
- Context Engine (user/tenant/conversation/knowledge/dynamic sections, token budget, compression)
|
|
145
|
+
- Sessions/threads with history, compact, reset, and fork
|
|
146
|
+
- Structured outputs (real Zod -> JSON Schema conversion, typed `result.output`)
|
|
147
|
+
- Guardrails (declarative input/output checks, distinct from policy/approvals)
|
|
148
|
+
- Lifecycle hooks (beforeRun/afterRun/beforeModel/afterModel/beforeTool/afterTool/onError/...)
|
|
149
|
+
- Skills (instructions + tool subsets injected into an agent's context and native tool loop)
|
|
150
|
+
- Typed artifacts surfaced from tool evidence (`result.artifacts`)
|
|
151
|
+
- Multimodal message content (text/image/file parts) across OpenAI, Anthropic, and Gemini formats
|
|
152
|
+
- Native MCP client (stdio and streamable-HTTP transports, real JSON-RPC handshake and tool discovery)
|
|
153
|
+
- Agent-to-agent primitives: `agent.asTool()`, `agentAsTool()`, `handoffs`, and `createTeam()` (supervisor/router/parallel strategies)
|
|
154
|
+
- Knowledge/RAG (`createKnowledge`, text/file/directory sources, chunking, retrieval over the existing vector memory store)
|
|
155
|
+
- Provider capability registry (vision/tools/structuredOutputs/reasoning per provider) and adaptive model routing (`strategy: "adaptive"`)
|
|
156
|
+
- Pluggable response cache (`createInMemoryCache`) wired into `agent.run()`
|
|
157
|
+
- Execution guarantees: real per-step retries with backoff, `WAITING_FOR_APPROVAL`/`WAITING_FOR_RETRY` states, resumable runs that skip already-completed steps
|
|
158
|
+
- Secrets (`secret()` references resolved only inside tool execution, never placed into model-visible messages)
|
|
159
|
+
- Tenancy: `agent.run(text, { tenant: { tenantId, userId } })` namespaces memory/cache; `config.permissions` filters tools at agent construction
|
|
160
|
+
- Node-process-level workspace sandbox (`createWorkspace`, `workspaceTools`) — jailed fs root, timeout/output-capped `exec`, snapshot/restore
|
|
161
|
+
- YAML agent manifests (`loadAgentManifest`) and a `nexa` CLI (`nexa run <manifest.yaml> "message"`, `nexa inspect <manifest.yaml>`)
|
|
162
|
+
- `ModelHarness` — a public, overridable contract for the agent's model/tool-calling strategy (`basicHarness()` ships as the OSS reference; third parties can implement their own)
|
|
163
|
+
|
|
164
|
+
## Public Modules
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
import { createAgent, agent } from "@nexalab/agent-sdk";
|
|
168
|
+
import { openaiProvider, openRouterProvider, ollamaProvider, anthropicProvider, geminiProvider } from "@nexalab/agent-sdk/providers";
|
|
169
|
+
import { defineSdkTool, toOpenAIChatTool } from "@nexalab/agent-sdk/tools";
|
|
170
|
+
import { AgentRuntime } from "@nexalab/agent-sdk/runtime";
|
|
171
|
+
import { createInMemoryStorage } from "@nexalab/agent-sdk/storage";
|
|
172
|
+
import { createJsonFileStorage } from "@nexalab/agent-sdk/storage/file";
|
|
173
|
+
import { createSqliteStorage } from "@nexalab/agent-sdk/storage/sqlite";
|
|
174
|
+
import { createPostgresStorage } from "@nexalab/agent-sdk/storage/postgres";
|
|
175
|
+
import { createRedisStorage } from "@nexalab/agent-sdk/storage/redis";
|
|
176
|
+
import { createTelemetry } from "@nexalab/agent-sdk/telemetry";
|
|
177
|
+
import { createOpenTelemetrySink } from "@nexalab/agent-sdk/telemetry/otel";
|
|
178
|
+
import { runAgentEvals } from "@nexalab/agent-sdk/evals";
|
|
179
|
+
import { createAgentRequestHandler } from "@nexalab/agent-sdk/http";
|
|
180
|
+
import { runNativeToolLoop } from "@nexalab/agent-sdk/native-tool-loop";
|
|
181
|
+
import { createWorkflowRuntime } from "@nexalab/agent-sdk/workflow";
|
|
182
|
+
import { replayRun, replayEvents } from "@nexalab/agent-sdk/replay";
|
|
183
|
+
import { createToolPolicy } from "@nexalab/agent-sdk/policy";
|
|
184
|
+
import { createModelRouter } from "@nexalab/agent-sdk/model-router";
|
|
185
|
+
import { createMultiAgentCoordinator } from "@nexalab/agent-sdk/multi-agent";
|
|
186
|
+
import { createAdvancedMemoryStore } from "@nexalab/agent-sdk/advanced-memory";
|
|
187
|
+
import { createVectorMemoryStore } from "@nexalab/agent-sdk/vector-memory";
|
|
188
|
+
import { createInMemoryQueue } from "@nexalab/agent-sdk/queue";
|
|
189
|
+
import { runHarness } from "@nexalab/agent-sdk/harness";
|
|
190
|
+
import { agent, resolveModelString } from "@nexalab/agent-sdk/kernel";
|
|
191
|
+
import { createContextEngine } from "@nexalab/agent-sdk/context";
|
|
192
|
+
import { createSession, loadSession } from "@nexalab/agent-sdk/sessions";
|
|
193
|
+
import { defineGuardrail, runInputGuardrails, runOutputGuardrails } from "@nexalab/agent-sdk/guardrails";
|
|
194
|
+
import { createHookDispatcher } from "@nexalab/agent-sdk/hooks";
|
|
195
|
+
import { zodSchemaToJsonSchema, parseStructuredOutput } from "@nexalab/agent-sdk/structured-output";
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Agent Manifests + CLI
|
|
199
|
+
|
|
200
|
+
Agents can be declared as YAML and run without writing code for the identity/model/instructions surface:
|
|
201
|
+
|
|
202
|
+
```yaml
|
|
203
|
+
# agent.yaml
|
|
204
|
+
name: nexa
|
|
205
|
+
model: openai:gpt-4o-mini
|
|
206
|
+
instructions: Eres un agente comercial. Ayudas al cliente a cotizar productos.
|
|
207
|
+
memory: true
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
nexa run agent.yaml "Cotizale 20 tanques a Abraham"
|
|
212
|
+
nexa inspect agent.yaml
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Tools/skills/guardrails/storage are code objects, not YAML-expressible — wire them in via `loadAgentManifest(path, extend)`:
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
import { loadAgentManifest } from "@nexalab/agent-sdk/manifest";
|
|
219
|
+
|
|
220
|
+
const app = await loadAgentManifest("./agent.yaml", { tools: [myTool], guardrails: [myGuardrail] });
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Model Harness
|
|
224
|
+
|
|
225
|
+
`ModelHarness` is the pluggable strategy behind `agent.run()`'s tool-calling loop — how many rounds to run, when to stop, how to react to tool results:
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
import { agent } from "@nexalab/agent-sdk";
|
|
229
|
+
import { basicHarness, type ModelHarness } from "@nexalab/agent-sdk/model-harness";
|
|
230
|
+
|
|
231
|
+
const assistant = await agent({
|
|
232
|
+
model: "openai:gpt-4o-mini",
|
|
233
|
+
name: "assistant",
|
|
234
|
+
tools: [...],
|
|
235
|
+
harness: basicHarness() // default if omitted; wraps the built-in native tool loop unchanged
|
|
236
|
+
});
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Implement `ModelHarness` directly to swap in a custom orchestration strategy:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
class MyHarness implements ModelHarness {
|
|
243
|
+
async run(ctx) {
|
|
244
|
+
// ctx.client / ctx.messages / ctx.tools — same shape basicHarness() receives
|
|
245
|
+
return { text: "...", messages: ctx.messages, toolCalls: [], toolResults: [], rounds: 1 };
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Supplying any explicit harness (including `basicHarness()`) switches the loop to this Promise-based contract, which does not emit the granular `native-tool` events `agent.runStream()` emits by default — that streaming behavior is unchanged when no harness is configured. See [docs/architecture/open-core-target.md](./docs/architecture/open-core-target.md) for the design rationale.
|
|
251
|
+
|
|
252
|
+
**Not to be confused with** `src/harness.ts`'s `runHarness`/`assertHarness` — an unrelated CI/release-check runner (`pnpm harness`) used to smoke-test the package before publishing. Same word, two different concepts; see the architecture docs for why they aren't merged.
|
|
253
|
+
|
|
254
|
+
## Architecture
|
|
255
|
+
|
|
256
|
+
The SDK is adapter-driven:
|
|
257
|
+
|
|
258
|
+
- **Providers**: bring OpenAI, OpenRouter, Ollama, Anthropic, Gemini, local gateways, or any OpenAI-compatible API.
|
|
259
|
+
- **Tools**: define metadata, capability, schema, and handler independently.
|
|
260
|
+
- **Runtime**: create runs, plans, observations, evidence, completion decisions, and events.
|
|
261
|
+
- **Storage**: persist runs, events, memory, approvals, and workflow checkpoints.
|
|
262
|
+
- **Policy**: allow, deny, or require approval based on tool id/capability/name.
|
|
263
|
+
- **Telemetry**: capture events, tool traces, spans, and bridge them to OpenTelemetry.
|
|
264
|
+
- **Workflows**: run checkpointed DAGs for durable background jobs.
|
|
265
|
+
- **Evals**: regression-test agent behavior with simple or custom judges.
|
|
266
|
+
- **Replay**: turn stored run/events into a timeline for debugging and audit.
|
|
267
|
+
- **Multi-agent**: delegate tasks to specialized workers by capability.
|
|
268
|
+
- **Routing**: select models under priority, tag, input-size, and budget constraints.
|
|
269
|
+
|
|
270
|
+
## Native Tool Loop
|
|
271
|
+
|
|
272
|
+
When tools are registered, `runMessage(...)` can execute model-requested tool calls:
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
const result = await agent.runMessage("Read the time and answer in Spanish.");
|
|
276
|
+
|
|
277
|
+
console.log(result.nativeToolTurn?.toolCalls);
|
|
278
|
+
console.log(result.nativeToolTurn?.toolResults);
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
For UI and worker integrations, use the structured event stream:
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
for await (const event of agent.runStream("do the task")) {
|
|
285
|
+
if (event.type === "status") console.log(event.label, event.detail);
|
|
286
|
+
if (event.type === "token") process.stdout.write(event.token);
|
|
287
|
+
if (event.type === "native-tool") console.log(event.event.type);
|
|
288
|
+
if (event.type === "final") console.log(event.result.text);
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Provider Compatibility
|
|
293
|
+
|
|
294
|
+
The SDK supports three provider formats:
|
|
295
|
+
|
|
296
|
+
- `openai`: OpenAI-compatible chat-completions APIs such as OpenAI, OpenRouter, Groq, Ollama, LM Studio, and compatible gateways.
|
|
297
|
+
- `anthropic`: Anthropic Messages API, normalized into the SDK chat/tool-call result shape.
|
|
298
|
+
- `gemini`: Gemini `generateContent`, normalized into the SDK chat/tool-call result shape.
|
|
299
|
+
|
|
300
|
+
Use presets:
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
const openai = openaiProvider({ apiKey, model: "gpt-4o-mini" });
|
|
304
|
+
const anthropic = anthropicProvider({ apiKey, model: "claude-3-5-sonnet-latest" });
|
|
305
|
+
const gemini = geminiProvider({ apiKey, model: "gemini-1.5-pro" });
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
OpenAI-compatible providers support native SSE streaming. Anthropic and Gemini currently normalize non-streaming responses through the same `complete(...)` contract and expose a final stream chunk through `stream(...)`.
|
|
309
|
+
|
|
310
|
+
## Storage
|
|
311
|
+
|
|
312
|
+
In-memory storage is useful for tests and demos:
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
const storage = createInMemoryStorage();
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
JSON file storage is useful for local durable workers:
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
const storage = createJsonFileStorage("./.nexa");
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
SQLite is exposed as a driver adapter, so the SDK does not force a native dependency:
|
|
325
|
+
|
|
326
|
+
```ts
|
|
327
|
+
const storage = createSqliteStorage(db);
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Postgres and Redis are also exposed as driver adapters:
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
const postgresStorage = createPostgresStorage(pgClient);
|
|
334
|
+
await postgresStorage.migrate();
|
|
335
|
+
|
|
336
|
+
const redisStorage = createRedisStorage(redisClient, "my-app:nexa");
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Workflows
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
const workflow = createWorkflowRuntime({ storage });
|
|
343
|
+
|
|
344
|
+
const run = workflow.create({
|
|
345
|
+
name: "ship-report",
|
|
346
|
+
nodes: [
|
|
347
|
+
{ id: "collect", title: "Collect", run: () => ({ ok: true }) },
|
|
348
|
+
{ id: "verify", title: "Verify", dependsOn: ["collect"], run: () => ({ verified: true }) }
|
|
349
|
+
]
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
await workflow.run({ runId: run.id, nodes });
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## Policy And Approvals
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
const policy = createToolPolicy([
|
|
359
|
+
...requireApprovalForCapabilities(["filesystem.write"], "LOCAL_WRITE"),
|
|
360
|
+
...denyCapabilities(["system.delete"])
|
|
361
|
+
]);
|
|
362
|
+
|
|
363
|
+
const risk = policy.approvalRiskFor(tool);
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Evals
|
|
367
|
+
|
|
368
|
+
```ts
|
|
369
|
+
const report = await runAgentEvals({
|
|
370
|
+
agent,
|
|
371
|
+
cases: [
|
|
372
|
+
{ id: "time-es", input: "que hora es?", expected: ["hora"] }
|
|
373
|
+
]
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
## Model Routing
|
|
378
|
+
|
|
379
|
+
```ts
|
|
380
|
+
const router = createModelRouter([
|
|
381
|
+
{ id: "fast", providerId: "openai", model: "gpt-4o-mini", priority: 10, tags: ["fast"] },
|
|
382
|
+
{ id: "deep", providerId: "openai", model: "gpt-4.1", priority: 5, tags: ["deep"] }
|
|
383
|
+
], {
|
|
384
|
+
maxCalls: 100,
|
|
385
|
+
maxEstimatedCost: 5
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
const decision = router.select({ prompt: "summarize this", requiredTags: ["fast"] });
|
|
389
|
+
router.record(decision);
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Multi-Agent
|
|
393
|
+
|
|
394
|
+
```ts
|
|
395
|
+
const coordinator = createMultiAgentCoordinator([
|
|
396
|
+
{
|
|
397
|
+
id: "builder",
|
|
398
|
+
description: "Builds SDK integrations",
|
|
399
|
+
capabilities: ["code", "examples"],
|
|
400
|
+
run: async ({ task }) => agent.runMessage(task)
|
|
401
|
+
}
|
|
402
|
+
]);
|
|
403
|
+
|
|
404
|
+
const delegated = await coordinator.delegate({
|
|
405
|
+
task: "build an integration example",
|
|
406
|
+
requiredCapabilities: ["examples"]
|
|
407
|
+
});
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
## Examples
|
|
411
|
+
|
|
412
|
+
The examples are documented in `examples/README.md`.
|
|
413
|
+
|
|
414
|
+
Run the full offline frontier v3 tour:
|
|
415
|
+
|
|
416
|
+
```bash
|
|
417
|
+
pnpm demo:v3
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
That example walks through:
|
|
421
|
+
|
|
422
|
+
- JSON storage
|
|
423
|
+
- Telemetry
|
|
424
|
+
- Advanced memory
|
|
425
|
+
- Tool definitions
|
|
426
|
+
- Policy and approvals
|
|
427
|
+
- Checkpointed workflows
|
|
428
|
+
- Multi-agent coordination
|
|
429
|
+
- Model routing and budget accounting
|
|
430
|
+
- Evals
|
|
431
|
+
- HTTP adapter
|
|
432
|
+
- Replay/debug timeline
|
|
433
|
+
|
|
434
|
+
Other useful demos:
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
pnpm demo:message
|
|
438
|
+
pnpm demo:chain
|
|
439
|
+
pnpm demo:chat
|
|
440
|
+
pnpm demo:native-loop
|
|
441
|
+
pnpm demo:stream
|
|
442
|
+
pnpm demo:storage
|
|
443
|
+
pnpm demo:evals
|
|
444
|
+
pnpm demo:http
|
|
445
|
+
pnpm demo:workflow
|
|
446
|
+
pnpm demo:policy
|
|
447
|
+
pnpm demo:telemetry
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
## Environment
|
|
451
|
+
|
|
452
|
+
For real provider calls:
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
NEXA_BASE_URL=https://api.openai.com
|
|
456
|
+
NEXA_API_KEY=...
|
|
457
|
+
NEXA_MODEL=gpt-4o-mini
|
|
458
|
+
NEXA_TRACE=1
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
PowerShell example:
|
|
462
|
+
|
|
463
|
+
```powershell
|
|
464
|
+
$env:NEXA_BASE_URL="https://api.openai.com"
|
|
465
|
+
$env:NEXA_API_KEY="..."
|
|
466
|
+
$env:NEXA_MODEL="gpt-4o-mini"
|
|
467
|
+
pnpm demo:chat
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
OpenRouter example:
|
|
471
|
+
|
|
472
|
+
```powershell
|
|
473
|
+
$env:NEXA_BASE_URL="https://openrouter.ai/api"
|
|
474
|
+
$env:NEXA_API_KEY="..."
|
|
475
|
+
$env:NEXA_MODEL="openai/gpt-4o-mini"
|
|
476
|
+
pnpm demo:chat
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
## Current Status
|
|
480
|
+
|
|
481
|
+
This package currently targets Node.js `>=22.19.0`, TypeScript, ESM, and OpenAI-compatible chat APIs.
|
|
482
|
+
|
|
483
|
+
The package is designed to stay dependency-light. Optional production integrations such as SQLite drivers, OpenTelemetry SDKs, web frameworks, vector databases, and queues are expected to be provided by the host app through adapters.
|
|
484
|
+
|
|
485
|
+
## Production Checks
|
|
486
|
+
|
|
487
|
+
```bash
|
|
488
|
+
pnpm typecheck
|
|
489
|
+
pnpm test
|
|
490
|
+
pnpm build
|
|
491
|
+
pnpm smoke
|
|
492
|
+
pnpm harness
|
|
493
|
+
pnpm pack:check
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Recommended production wiring:
|
|
497
|
+
|
|
498
|
+
- Use `createPostgresStorage(...)` or `createRedisStorage(...)` for app backends.
|
|
499
|
+
- Use `createJsonFileStorage(...)` for local workers and desktop apps.
|
|
500
|
+
- Use `createOpenTelemetrySink(...)` for traces.
|
|
501
|
+
- Use `createToolPolicy(...)` plus `ApprovalManager` for risky tools.
|
|
502
|
+
- Use `runStream(...)` for UI or server-sent-event style integration.
|
|
503
|
+
- Use `runAgentEvals(...)` in CI for regression protection.
|
|
504
|
+
- Use `createVectorMemoryStore(...)` with your embedding provider for semantic memory.
|
|
505
|
+
- Use `pnpm harness` as the production readiness gate.
|
|
506
|
+
- Use `pnpm smoke` and `pnpm pack:check` before publishing.
|
|
507
|
+
|
|
508
|
+
## Is It Frontier?
|
|
509
|
+
|
|
510
|
+
Yes, this is now a frontier-style agent SDK architecture: native tool calling, structured streaming, durable storage adapters, policy/approvals, evals, telemetry, replay, workflows, routing, multi-agent coordination, vector memory, queue contracts, package smoke checks, and a production harness.
|
|
511
|
+
|
|
512
|
+
The SDK intentionally stays dependency-light. Production apps still provide their actual infrastructure drivers and deployment policy through adapters.
|
|
513
|
+
|
|
514
|
+
## Open-core architecture
|
|
515
|
+
|
|
516
|
+
This package is designed as the fully-capable public half of an open-core split — see [docs/architecture/open-core-audit.md](./docs/architecture/open-core-audit.md), [open-core-target.md](./docs/architecture/open-core-target.md), and [open-core-migration.md](./docs/architecture/open-core-migration.md) for the module-by-module classification, target architecture, and phased plan. In short: everything in this repository is public and production-capable; strategic/proprietary intelligence (e.g. a future `FrontierHarness`) is designed to live in a separate private repository that *implements* this SDK's public contracts (`ModelHarness`, `ModelRoute`, `ContextEngineConfig`, ...) rather than forking or being vendored into it.
|
|
517
|
+
|
|
518
|
+
`pnpm verify:boundaries`, `pnpm verify:secrets`, and `pnpm verify:publish-safety` (all folded into `pnpm prepublish:check`) guard against private code or secrets ever entering an npm-published tarball from this repo.
|
package/bin/nexa.mjs
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { loadAgentManifest } from "../dist/manifest.js";
|
|
4
|
+
|
|
5
|
+
const [, , command, manifestPath, ...rest] = process.argv;
|
|
6
|
+
|
|
7
|
+
function usage() {
|
|
8
|
+
console.error("Usage: nexa <run|inspect> <manifest.yaml> [message...]");
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (!command || !manifestPath || !["run", "inspect"].includes(command)) usage();
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
const agent = await loadAgentManifest(manifestPath);
|
|
16
|
+
|
|
17
|
+
if (command === "inspect") {
|
|
18
|
+
console.log(JSON.stringify({ name: agent.name, model: agent.underlying.model }, null, 2));
|
|
19
|
+
process.exit(0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const message = rest.join(" ");
|
|
23
|
+
if (!message) {
|
|
24
|
+
console.error("nexa run requires a message, e.g.: nexa run agent.yaml \"hola\"");
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const result = await agent.run(message);
|
|
29
|
+
console.log(result.text);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { MemoryStore, type MemoryKind, type MemoryRecord, type MemorySearchResult } from "./memory.js";
|
|
2
|
+
import type { JsonObject } from "./types.js";
|
|
3
|
+
export type AdvancedMemoryOptions = {
|
|
4
|
+
duplicateThreshold?: number;
|
|
5
|
+
decayHalfLifeDays?: number;
|
|
6
|
+
};
|
|
7
|
+
export declare class AdvancedMemoryStore extends MemoryStore {
|
|
8
|
+
private readonly advancedOptions;
|
|
9
|
+
constructor(advancedOptions?: AdvancedMemoryOptions);
|
|
10
|
+
writeUnique(input: {
|
|
11
|
+
kind: MemoryKind;
|
|
12
|
+
content: string;
|
|
13
|
+
source?: string;
|
|
14
|
+
tags?: string[];
|
|
15
|
+
confidence?: number;
|
|
16
|
+
importance?: number;
|
|
17
|
+
metadata?: JsonObject;
|
|
18
|
+
}): MemoryRecord;
|
|
19
|
+
contextualSearch(input: {
|
|
20
|
+
query: string;
|
|
21
|
+
tags?: string[];
|
|
22
|
+
kind?: MemoryKind;
|
|
23
|
+
limit?: number;
|
|
24
|
+
now?: Date;
|
|
25
|
+
}): MemorySearchResult[];
|
|
26
|
+
compact(input: {
|
|
27
|
+
maxRecords: number;
|
|
28
|
+
}): MemoryRecord[];
|
|
29
|
+
private findDuplicate;
|
|
30
|
+
}
|
|
31
|
+
export declare function createAdvancedMemoryStore(options?: AdvancedMemoryOptions): AdvancedMemoryStore;
|
|
32
|
+
//# sourceMappingURL=advanced-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advanced-memory.d.ts","sourceRoot":"","sources":["../src/advanced-memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACvG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,qBAAqB,GAAG;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,qBAAa,mBAAoB,SAAQ,WAAW;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAAf,eAAe,GAAE,qBAA0B;IAIxE,WAAW,CAAC,KAAK,EAAE;QACjB,IAAI,EAAE,UAAU,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,UAAU,CAAC;KACvB,GAAG,YAAY;IAMhB,gBAAgB,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,IAAI,CAAA;KAAE,GAAG,kBAAkB,EAAE;IAUhI,OAAO,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,YAAY,EAAE;IAOtD,OAAO,CAAC,aAAa;CAItB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,qBAA0B,GAAG,mBAAmB,CAElG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { MemoryStore } from "./memory.js";
|
|
2
|
+
export class AdvancedMemoryStore extends MemoryStore {
|
|
3
|
+
advancedOptions;
|
|
4
|
+
constructor(advancedOptions = {}) {
|
|
5
|
+
super();
|
|
6
|
+
this.advancedOptions = advancedOptions;
|
|
7
|
+
}
|
|
8
|
+
writeUnique(input) {
|
|
9
|
+
const duplicate = this.findDuplicate(input.content);
|
|
10
|
+
if (duplicate)
|
|
11
|
+
return duplicate;
|
|
12
|
+
return this.write(input);
|
|
13
|
+
}
|
|
14
|
+
contextualSearch(input) {
|
|
15
|
+
const now = input.now ?? new Date();
|
|
16
|
+
return this.search(input.query, Math.max(input.limit ?? 10, 25))
|
|
17
|
+
.filter((record) => !input.kind || record.kind === input.kind)
|
|
18
|
+
.filter((record) => !input.tags?.length || input.tags.every((tag) => record.tags.includes(tag)))
|
|
19
|
+
.map((record) => ({ ...record, score: record.score + record.importance + recencyBoost(record, now, this.advancedOptions.decayHalfLifeDays ?? 30) }))
|
|
20
|
+
.sort((a, b) => b.score - a.score)
|
|
21
|
+
.slice(0, input.limit ?? 10);
|
|
22
|
+
}
|
|
23
|
+
compact(input) {
|
|
24
|
+
const records = this.list()
|
|
25
|
+
.sort((a, b) => b.importance - a.importance || b.confidence - a.confidence)
|
|
26
|
+
.slice(0, input.maxRecords);
|
|
27
|
+
return records;
|
|
28
|
+
}
|
|
29
|
+
findDuplicate(content) {
|
|
30
|
+
const threshold = this.advancedOptions.duplicateThreshold ?? 0.9;
|
|
31
|
+
return this.list().find((record) => similarity(record.content, content) >= threshold);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function createAdvancedMemoryStore(options = {}) {
|
|
35
|
+
return new AdvancedMemoryStore(options);
|
|
36
|
+
}
|
|
37
|
+
function recencyBoost(record, now, halfLifeDays) {
|
|
38
|
+
const ageMs = Math.max(0, now.getTime() - new Date(record.createdAt).getTime());
|
|
39
|
+
const ageDays = ageMs / 86_400_000;
|
|
40
|
+
return Math.pow(0.5, ageDays / halfLifeDays);
|
|
41
|
+
}
|
|
42
|
+
function similarity(a, b) {
|
|
43
|
+
const left = new Set(tokens(a));
|
|
44
|
+
const right = new Set(tokens(b));
|
|
45
|
+
if (!left.size || !right.size)
|
|
46
|
+
return 0;
|
|
47
|
+
const intersection = [...left].filter((term) => right.has(term)).length;
|
|
48
|
+
const union = new Set([...left, ...right]).size;
|
|
49
|
+
return intersection / union;
|
|
50
|
+
}
|
|
51
|
+
function tokens(value) {
|
|
52
|
+
return value.toLowerCase().split(/[^a-z0-9_áéíóúñ]+/i).filter(Boolean);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=advanced-memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advanced-memory.js","sourceRoot":"","sources":["../src/advanced-memory.ts"],"names":[],"mappings":"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"}
|