@pentatonic-ai/ai-agent-sdk 0.4.2 → 0.4.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 +1 -1
- package/bin/cli.js +1 -1
- package/dist/index.cjs +25 -9
- package/dist/index.js +25 -9
- package/package.json +3 -2
- package/packages/memory/openclaw-plugin/README.md +60 -0
- package/packages/memory/openclaw-plugin/index.js +580 -0
- package/packages/memory/openclaw-plugin/openclaw.plugin.json +69 -0
- package/packages/memory/openclaw-plugin/package.json +31 -0
- package/packages/memory/src/openclaw/index.js +105 -335
- package/packages/memory/src/openclaw/package.json +1 -1
- package/packages/memory/src/search.js +17 -0
- package/src/transport.js +29 -13
package/README.md
CHANGED
|
@@ -171,7 +171,7 @@ Works with both local and hosted setups. Just tell OpenClaw to set it up.
|
|
|
171
171
|
### Install
|
|
172
172
|
|
|
173
173
|
```bash
|
|
174
|
-
openclaw plugins install @pentatonic-ai/
|
|
174
|
+
openclaw plugins install @pentatonic-ai/openclaw-memory-plugin
|
|
175
175
|
```
|
|
176
176
|
|
|
177
177
|
### Set up
|
package/bin/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { createInterface } from "readline";
|
|
4
4
|
import { execFileSync } from "child_process";
|
|
5
|
-
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
6
6
|
import { join } from "path";
|
|
7
7
|
import { homedir } from "os";
|
|
8
8
|
|
package/dist/index.cjs
CHANGED
|
@@ -120,18 +120,36 @@ function parseArgs(args) {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
// src/transport.js
|
|
123
|
-
var
|
|
124
|
-
mutation
|
|
125
|
-
|
|
123
|
+
var CREATE_MODULE_EVENT_MUTATION = `
|
|
124
|
+
mutation CreateModuleEvent($moduleId: String!, $input: ModuleEventInput!) {
|
|
125
|
+
createModuleEvent(moduleId: $moduleId, input: $input) {
|
|
126
126
|
success
|
|
127
127
|
eventId
|
|
128
|
-
message
|
|
129
128
|
}
|
|
130
129
|
}
|
|
131
130
|
`;
|
|
131
|
+
function getModuleId(eventType) {
|
|
132
|
+
if (["STORE_MEMORY", "SESSION_START", "SESSION_END"].includes(eventType)) {
|
|
133
|
+
return "deep-memory";
|
|
134
|
+
}
|
|
135
|
+
return "conversation-analytics";
|
|
136
|
+
}
|
|
132
137
|
async function sendEvent({ endpoint, apiKey, clientId, userId, headers }, input, fetchFn) {
|
|
133
138
|
const f = fetchFn || globalThis.fetch;
|
|
134
139
|
const authHeaders = apiKey.startsWith("tes_") ? { Authorization: `Bearer ${apiKey}` } : { "x-service-key": apiKey };
|
|
140
|
+
const moduleId = getModuleId(input.eventType);
|
|
141
|
+
const attributes = {
|
|
142
|
+
...input.data?.attributes,
|
|
143
|
+
clientId,
|
|
144
|
+
...userId ? { userId } : {}
|
|
145
|
+
};
|
|
146
|
+
const moduleInput = {
|
|
147
|
+
eventType: input.eventType,
|
|
148
|
+
data: {
|
|
149
|
+
entity_id: input.data?.entity_id || input.entityId || "",
|
|
150
|
+
attributes
|
|
151
|
+
}
|
|
152
|
+
};
|
|
135
153
|
const response = await f(`${endpoint}/api/graphql`, {
|
|
136
154
|
method: "POST",
|
|
137
155
|
headers: {
|
|
@@ -141,10 +159,8 @@ async function sendEvent({ endpoint, apiKey, clientId, userId, headers }, input,
|
|
|
141
159
|
...authHeaders
|
|
142
160
|
},
|
|
143
161
|
body: JSON.stringify({
|
|
144
|
-
query:
|
|
145
|
-
variables: {
|
|
146
|
-
input: userId ? { ...input, data: { ...input.data, attributes: { ...input.data?.attributes, userId } } } : input
|
|
147
|
-
}
|
|
162
|
+
query: CREATE_MODULE_EVENT_MUTATION,
|
|
163
|
+
variables: { moduleId, input: moduleInput }
|
|
148
164
|
})
|
|
149
165
|
});
|
|
150
166
|
if (!response.ok) {
|
|
@@ -154,7 +170,7 @@ async function sendEvent({ endpoint, apiKey, clientId, userId, headers }, input,
|
|
|
154
170
|
if (json.errors?.length) {
|
|
155
171
|
throw new Error(`TES GraphQL error: ${json.errors[0].message}`);
|
|
156
172
|
}
|
|
157
|
-
return json.data.
|
|
173
|
+
return json.data.createModuleEvent;
|
|
158
174
|
}
|
|
159
175
|
|
|
160
176
|
// src/tracking.js
|
package/dist/index.js
CHANGED
|
@@ -89,18 +89,36 @@ function parseArgs(args) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
// src/transport.js
|
|
92
|
-
var
|
|
93
|
-
mutation
|
|
94
|
-
|
|
92
|
+
var CREATE_MODULE_EVENT_MUTATION = `
|
|
93
|
+
mutation CreateModuleEvent($moduleId: String!, $input: ModuleEventInput!) {
|
|
94
|
+
createModuleEvent(moduleId: $moduleId, input: $input) {
|
|
95
95
|
success
|
|
96
96
|
eventId
|
|
97
|
-
message
|
|
98
97
|
}
|
|
99
98
|
}
|
|
100
99
|
`;
|
|
100
|
+
function getModuleId(eventType) {
|
|
101
|
+
if (["STORE_MEMORY", "SESSION_START", "SESSION_END"].includes(eventType)) {
|
|
102
|
+
return "deep-memory";
|
|
103
|
+
}
|
|
104
|
+
return "conversation-analytics";
|
|
105
|
+
}
|
|
101
106
|
async function sendEvent({ endpoint, apiKey, clientId, userId, headers }, input, fetchFn) {
|
|
102
107
|
const f = fetchFn || globalThis.fetch;
|
|
103
108
|
const authHeaders = apiKey.startsWith("tes_") ? { Authorization: `Bearer ${apiKey}` } : { "x-service-key": apiKey };
|
|
109
|
+
const moduleId = getModuleId(input.eventType);
|
|
110
|
+
const attributes = {
|
|
111
|
+
...input.data?.attributes,
|
|
112
|
+
clientId,
|
|
113
|
+
...userId ? { userId } : {}
|
|
114
|
+
};
|
|
115
|
+
const moduleInput = {
|
|
116
|
+
eventType: input.eventType,
|
|
117
|
+
data: {
|
|
118
|
+
entity_id: input.data?.entity_id || input.entityId || "",
|
|
119
|
+
attributes
|
|
120
|
+
}
|
|
121
|
+
};
|
|
104
122
|
const response = await f(`${endpoint}/api/graphql`, {
|
|
105
123
|
method: "POST",
|
|
106
124
|
headers: {
|
|
@@ -110,10 +128,8 @@ async function sendEvent({ endpoint, apiKey, clientId, userId, headers }, input,
|
|
|
110
128
|
...authHeaders
|
|
111
129
|
},
|
|
112
130
|
body: JSON.stringify({
|
|
113
|
-
query:
|
|
114
|
-
variables: {
|
|
115
|
-
input: userId ? { ...input, data: { ...input.data, attributes: { ...input.data?.attributes, userId } } } : input
|
|
116
|
-
}
|
|
131
|
+
query: CREATE_MODULE_EVENT_MUTATION,
|
|
132
|
+
variables: { moduleId, input: moduleInput }
|
|
117
133
|
})
|
|
118
134
|
});
|
|
119
135
|
if (!response.ok) {
|
|
@@ -123,7 +139,7 @@ async function sendEvent({ endpoint, apiKey, clientId, userId, headers }, input,
|
|
|
123
139
|
if (json.errors?.length) {
|
|
124
140
|
throw new Error(`TES GraphQL error: ${json.errors[0].message}`);
|
|
125
141
|
}
|
|
126
|
-
return json.data.
|
|
142
|
+
return json.data.createModuleEvent;
|
|
127
143
|
}
|
|
128
144
|
|
|
129
145
|
// src/tracking.js
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pentatonic-ai/ai-agent-sdk",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "TES SDK — LLM observability and lifecycle tracking via Pentatonic Thing Event System. Track token usage, tool calls, and conversations. Manage things through event-sourced lifecycle stages with AI enrichment and vector search.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -52,7 +52,8 @@
|
|
|
52
52
|
"model-context-protocol"
|
|
53
53
|
],
|
|
54
54
|
"openclaw": {
|
|
55
|
-
"extensions": ["./packages/memory/src/openclaw/index.js"]
|
|
55
|
+
"extensions": ["./packages/memory/src/openclaw/index.js"],
|
|
56
|
+
"hooks": {}
|
|
56
57
|
},
|
|
57
58
|
"license": "MIT",
|
|
58
59
|
"homepage": "https://thingeventsystem.ai",
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# @pentatonic-ai/openclaw-memory-plugin
|
|
2
|
+
|
|
3
|
+
Persistent, searchable memory for OpenClaw. Local (Docker + Ollama) or hosted (Pentatonic TES).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
openclaw plugins install @pentatonic-ai/openclaw-memory-plugin
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
Tell OpenClaw:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Set up pentatonic memory
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or configure manually in `openclaw.json`:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"plugins": {
|
|
24
|
+
"slots": { "contextEngine": "pentatonic-memory" },
|
|
25
|
+
"entries": {
|
|
26
|
+
"pentatonic-memory": {
|
|
27
|
+
"enabled": true,
|
|
28
|
+
"config": {
|
|
29
|
+
"database_url": "postgres://memory:memory@localhost:5433/memory",
|
|
30
|
+
"embedding_url": "http://localhost:11435/v1",
|
|
31
|
+
"embedding_model": "nomic-embed-text",
|
|
32
|
+
"llm_url": "http://localhost:11435/v1",
|
|
33
|
+
"llm_model": "llama3.2:3b"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## What it does
|
|
42
|
+
|
|
43
|
+
Every lifecycle event is handled automatically:
|
|
44
|
+
|
|
45
|
+
- **Ingest** — every message stored with embeddings + HyDE query expansion
|
|
46
|
+
- **Assemble** — relevant memories injected as context before every prompt
|
|
47
|
+
- **Compact** — decay cycle when context window fills
|
|
48
|
+
- **After turn** — high-access memories consolidated to semantic layer
|
|
49
|
+
|
|
50
|
+
Plus tools: `memory_search`, `memory_store`, `memory_layers`
|
|
51
|
+
|
|
52
|
+
## Local vs Hosted
|
|
53
|
+
|
|
54
|
+
**Local**: Fully private. Requires Docker (Postgres + pgvector + Ollama). Run `npx @pentatonic-ai/ai-agent-sdk memory` to set up.
|
|
55
|
+
|
|
56
|
+
**Hosted**: Connect to Pentatonic TES for higher-dimensional embeddings, team memory, and analytics. Run `npx @pentatonic-ai/ai-agent-sdk init`.
|
|
57
|
+
|
|
58
|
+
## License
|
|
59
|
+
|
|
60
|
+
MIT
|