@tenet-ai/sdk 0.1.0 → 0.1.1
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 +357 -0
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
# @tenet-ai/sdk
|
|
2
|
+
|
|
3
|
+
**Git for AI Agent Decisions** - Complete audit trail, replay, and drift detection for enterprise AI agents.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@tenet-ai/sdk)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
## Why Tenet AI?
|
|
10
|
+
|
|
11
|
+
When your AI agent approves a $10,000 refund or denies a loan application, can you answer:
|
|
12
|
+
|
|
13
|
+
- **Why** did the agent make that decision?
|
|
14
|
+
- **What context** did it have at the time?
|
|
15
|
+
- **Would it decide the same way** if we ran it again?
|
|
16
|
+
- **Who overrode** the agent's recommendation?
|
|
17
|
+
|
|
18
|
+
Tenet AI captures every decision your agent makes with full context, enabling **audit trails**, **replay verification**, and **drift detection**.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @tenet-ai/sdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### High-Level: `trace()`
|
|
33
|
+
|
|
34
|
+
Wrap any agent function call in a single line:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { Tenet } from "@tenet-ai/sdk";
|
|
38
|
+
|
|
39
|
+
const tenet = new Tenet({ apiKey: "tnt_your_key" });
|
|
40
|
+
|
|
41
|
+
const result = await tenet.trace({
|
|
42
|
+
agentId: "support-agent",
|
|
43
|
+
fn: async () => {
|
|
44
|
+
// Your agent logic here
|
|
45
|
+
return { action: "approve_refund", amount: 149.99 };
|
|
46
|
+
},
|
|
47
|
+
tags: ["production", "refunds"],
|
|
48
|
+
metadata: { customer_id: "C-123" },
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
console.log(result.executionId); // Stored in Tenet for audit
|
|
52
|
+
console.log(result.output); // { action: "approve_refund", amount: 149.99 }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Low-Level: Full Control
|
|
56
|
+
|
|
57
|
+
For fine-grained tracking with context, decisions, and executions:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { Tenet, ResultType, ActorType } from "@tenet-ai/sdk";
|
|
61
|
+
|
|
62
|
+
const tenet = new Tenet({ apiKey: "tnt_your_key" });
|
|
63
|
+
|
|
64
|
+
// 1. Create an intent
|
|
65
|
+
const intent = await tenet.createIntent({
|
|
66
|
+
goal: "Process refund request",
|
|
67
|
+
agentId: "support-agent",
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// 2. Capture what the agent saw
|
|
71
|
+
await intent.snapshotContext({
|
|
72
|
+
customer_tier: "gold",
|
|
73
|
+
order_amount: 149.99,
|
|
74
|
+
days_since_delivery: 5,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// 3. Record the decision with options considered
|
|
78
|
+
await intent.decide({
|
|
79
|
+
options: [
|
|
80
|
+
{ action: "approve_refund", score: 0.95, reason: "Gold customer, within policy" },
|
|
81
|
+
{ action: "deny_refund", score: 0.05, reason: "N/A" },
|
|
82
|
+
],
|
|
83
|
+
chosenAction: "approve_refund",
|
|
84
|
+
confidence: 0.95,
|
|
85
|
+
reasoning: "Customer eligible per 30-day return policy",
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// 4. Record execution
|
|
89
|
+
const executionId = await intent.execute({
|
|
90
|
+
action: "approve_refund",
|
|
91
|
+
target: { order_id: "ORD-123" },
|
|
92
|
+
result: ResultType.SUCCESS,
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Key Features
|
|
99
|
+
|
|
100
|
+
### Decision Replay with Drift Detection
|
|
101
|
+
|
|
102
|
+
Store the prompt and re-run decisions to verify consistency:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const intent = await tenet.createIntent({
|
|
106
|
+
goal: "Handle support ticket",
|
|
107
|
+
agentId: "support-agent",
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
await intent.snapshotContext({ ticket_id: "T-123", priority: "high" });
|
|
111
|
+
|
|
112
|
+
await intent.decide({
|
|
113
|
+
options: [{ action: "escalate", score: 0.9 }],
|
|
114
|
+
chosenAction: "escalate",
|
|
115
|
+
confidence: 0.9,
|
|
116
|
+
reasoning: "High priority ticket requires escalation",
|
|
117
|
+
replayPrompt: "You are a support agent. Ticket: high priority. Action?",
|
|
118
|
+
replayConfig: { model: "gpt-4o-mini", temperature: 0.0 },
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const execId = await intent.execute({
|
|
122
|
+
action: "escalate",
|
|
123
|
+
target: { ticket_id: "T-123" },
|
|
124
|
+
result: ResultType.SUCCESS,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Later: verify the decision is still consistent
|
|
128
|
+
const replay = await tenet.replay({ executionId: execId });
|
|
129
|
+
|
|
130
|
+
console.log(replay.drift_score); // 0.0 = identical, 1.0 = fully diverged
|
|
131
|
+
if (replay.diverged) {
|
|
132
|
+
console.log("WARNING: Model behavior changed!");
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Multi-Agent Tracking (Parent-Child Intents)
|
|
137
|
+
|
|
138
|
+
Track complex workflows with multiple agents or MCP tool calls:
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
const parent = await tenet.createIntent({
|
|
142
|
+
goal: "Process customer request",
|
|
143
|
+
agentId: "orchestrator",
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
await parent.snapshotContext({ request: "refund for order 123" });
|
|
147
|
+
|
|
148
|
+
// Spawn child intent for sub-agent
|
|
149
|
+
const child = await parent.childIntent({
|
|
150
|
+
goal: "Search order history",
|
|
151
|
+
mcpServer: "database",
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
await child.snapshotContext({ query: "order 123" });
|
|
155
|
+
await child.decide({
|
|
156
|
+
options: [{ action: "query_db", score: 1.0 }],
|
|
157
|
+
chosenAction: "query_db",
|
|
158
|
+
confidence: 1.0,
|
|
159
|
+
});
|
|
160
|
+
await child.execute({
|
|
161
|
+
action: "query_db",
|
|
162
|
+
target: { order_id: "123" },
|
|
163
|
+
result: ResultType.SUCCESS,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Parent continues with child's result
|
|
167
|
+
await parent.decide({
|
|
168
|
+
options: [
|
|
169
|
+
{ action: "approve_refund", score: 0.9, reason: "Order found, within policy" },
|
|
170
|
+
],
|
|
171
|
+
chosenAction: "approve_refund",
|
|
172
|
+
confidence: 0.9,
|
|
173
|
+
});
|
|
174
|
+
await parent.execute({
|
|
175
|
+
action: "approve_refund",
|
|
176
|
+
target: { order_id: "123" },
|
|
177
|
+
result: ResultType.SUCCESS,
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Human Override Tracking
|
|
182
|
+
|
|
183
|
+
When humans override agent decisions:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
await intent.execute({
|
|
187
|
+
action: "deny_refund", // Human chose differently
|
|
188
|
+
target: { order_id: "123" },
|
|
189
|
+
result: ResultType.SUCCESS,
|
|
190
|
+
actor: ActorType.HUMAN,
|
|
191
|
+
overrideReason: "Customer has history of fraud",
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Framework Integrations
|
|
198
|
+
|
|
199
|
+
### LangChain.js
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
import { Tenet } from "@tenet-ai/sdk";
|
|
203
|
+
import { TenetCallbackHandler } from "@tenet-ai/sdk/integrations/langchain";
|
|
204
|
+
|
|
205
|
+
const tenet = new Tenet({ apiKey: "tnt_your_key" });
|
|
206
|
+
const handler = new TenetCallbackHandler({
|
|
207
|
+
client: tenet,
|
|
208
|
+
agentId: "langchain-agent",
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Pass as a callback to any LangChain.js chain or agent
|
|
212
|
+
const result = await chain.invoke({ input: "Process refund" }, { callbacks: [handler] });
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### OpenAI Node SDK
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
import OpenAI from "openai";
|
|
219
|
+
import { Tenet } from "@tenet-ai/sdk";
|
|
220
|
+
import { TenetOpenAITracker } from "@tenet-ai/sdk/integrations/openai";
|
|
221
|
+
|
|
222
|
+
const openai = new OpenAI();
|
|
223
|
+
const tenet = new Tenet({ apiKey: "tnt_your_key" });
|
|
224
|
+
const tracker = new TenetOpenAITracker({
|
|
225
|
+
client: tenet,
|
|
226
|
+
agentId: "openai-agent",
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Wrap the OpenAI client — all chat completions are tracked automatically
|
|
230
|
+
const tracked = tracker.wrap(openai);
|
|
231
|
+
const response = await tracked.chat.completions.create({
|
|
232
|
+
model: "gpt-4o",
|
|
233
|
+
messages: [{ role: "user", content: "Process this refund" }],
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Vercel AI SDK
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
import { generateText } from "ai";
|
|
241
|
+
import { Tenet } from "@tenet-ai/sdk";
|
|
242
|
+
import { TenetVercelAITracker } from "@tenet-ai/sdk/integrations/vercel-ai";
|
|
243
|
+
|
|
244
|
+
const tenet = new Tenet({ apiKey: "tnt_your_key" });
|
|
245
|
+
const tracker = new TenetVercelAITracker({
|
|
246
|
+
client: tenet,
|
|
247
|
+
agentId: "vercel-agent",
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// Wrap generateText — all calls are tracked automatically
|
|
251
|
+
const trackedGenerateText = tracker.wrapGenerateText(generateText);
|
|
252
|
+
const result = await trackedGenerateText({
|
|
253
|
+
model: yourModel,
|
|
254
|
+
prompt: "Process this refund",
|
|
255
|
+
});
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## API Reference
|
|
261
|
+
|
|
262
|
+
### Constructor
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
const tenet = new Tenet({
|
|
266
|
+
apiKey: "tnt_your_key", // Required
|
|
267
|
+
endpoint: "https://tenet-backend.onrender.com", // Optional (default: production)
|
|
268
|
+
environment: "production", // Optional
|
|
269
|
+
timeout: 30000, // Optional (ms)
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### High-Level Methods
|
|
274
|
+
|
|
275
|
+
| Method | Description |
|
|
276
|
+
|--------|-------------|
|
|
277
|
+
| `tenet.trace({ agentId, fn, ... })` | Wrap a function call with automatic audit trail |
|
|
278
|
+
| `tenet.replay({ executionId })` | Replay a past decision and detect drift |
|
|
279
|
+
|
|
280
|
+
### Low-Level Methods
|
|
281
|
+
|
|
282
|
+
| Method | Description |
|
|
283
|
+
|--------|-------------|
|
|
284
|
+
| `tenet.createIntent({ goal, agentId })` | Create an intent, returns `IntentHandle` |
|
|
285
|
+
| `intent.snapshotContext(inputs)` | Capture what the agent sees |
|
|
286
|
+
| `intent.decide({ options, chosenAction, confidence })` | Record a decision |
|
|
287
|
+
| `intent.execute({ action, target, result })` | Record execution |
|
|
288
|
+
| `intent.childIntent({ goal, mcpServer })` | Create a child intent (multi-agent) |
|
|
289
|
+
|
|
290
|
+
### Read Methods
|
|
291
|
+
|
|
292
|
+
| Method | Description |
|
|
293
|
+
|--------|-------------|
|
|
294
|
+
| `tenet.getIntent(id)` | Get intent details |
|
|
295
|
+
| `tenet.getIntentChildren(id)` | Get child intents |
|
|
296
|
+
| `tenet.getIntentHierarchy(id)` | Get parent chain (breadcrumbs) |
|
|
297
|
+
| `tenet.getIntentTree(id)` | Get full descendant tree |
|
|
298
|
+
| `tenet.getDecision(id)` | Get decision details |
|
|
299
|
+
| `tenet.listDecisions({ agentId, tags, ... })` | List and filter decisions |
|
|
300
|
+
| `tenet.getExecution(id)` | Get execution details |
|
|
301
|
+
| `tenet.getSessionTimeline(sessionId)` | Get full session timeline |
|
|
302
|
+
|
|
303
|
+
### Advanced
|
|
304
|
+
|
|
305
|
+
| Method | Description |
|
|
306
|
+
|--------|-------------|
|
|
307
|
+
| `tenet.checkDrift({ sampleSize, timeWindowHours })` | Batch drift detection |
|
|
308
|
+
| `tenet.generateComplianceReport({ regulation })` | Generate compliance report |
|
|
309
|
+
| `tenet.revert({ executionId, reason })` | Revert an execution |
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Getting Started
|
|
314
|
+
|
|
315
|
+
### 1. Create an Account
|
|
316
|
+
|
|
317
|
+
Go to [tenetai.dev](https://tenetai.dev) and sign in with Google.
|
|
318
|
+
|
|
319
|
+
### 2. Create a Workspace
|
|
320
|
+
|
|
321
|
+
After signing in, create a workspace (e.g., "Production Agents").
|
|
322
|
+
|
|
323
|
+
### 3. Generate an API Key
|
|
324
|
+
|
|
325
|
+
Navigate to **API Keys** > **Create API Key** > Copy your key (`tnt_xxxx...`).
|
|
326
|
+
|
|
327
|
+
### 4. Install the SDK
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
npm install @tenet-ai/sdk
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Use Cases
|
|
336
|
+
|
|
337
|
+
| Industry | Use Case |
|
|
338
|
+
|----------|----------|
|
|
339
|
+
| **FinTech** | Audit loan decisions, fraud detection reasoning |
|
|
340
|
+
| **Healthcare** | Track triage recommendations, document clinical AI decisions |
|
|
341
|
+
| **E-commerce** | Refund approvals, pricing decisions, inventory management |
|
|
342
|
+
| **Legal** | Contract analysis decisions, compliance checking |
|
|
343
|
+
| **HR** | Resume screening, candidate ranking explanations |
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## License
|
|
348
|
+
|
|
349
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Links
|
|
354
|
+
|
|
355
|
+
- **Dashboard**: [tenetai.dev](https://tenetai.dev)
|
|
356
|
+
- **npm**: [npmjs.com/package/@tenet-ai/sdk](https://www.npmjs.com/package/@tenet-ai/sdk)
|
|
357
|
+
- **Python SDK**: [pypi.org/project/tenet-ai](https://pypi.org/project/tenet-ai/)
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tenet-ai/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Node.js SDK for Tenet AI - Audit trail and replay for AI agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
|
-
"dist"
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
9
10
|
],
|
|
10
11
|
"scripts": {
|
|
11
12
|
"build": "tsc",
|