@ziggs-ai/agent-sdk 0.38.12 → 0.38.13
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/CHANGELOG.md +4 -0
- package/dist/Agent.d.ts +4 -3
- package/dist/Agent.js +7 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/memory/ArtifactMemoryStore.d.ts +61 -0
- package/dist/memory/ArtifactMemoryStore.js +109 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.38.13
|
|
4
|
+
|
|
5
|
+
- Notes kept with an operator key are agent-private artifacts, so they survive a restart and are not announced.
|
|
6
|
+
|
|
3
7
|
## Unreleased — agent vocabulary and lifecycle (breaking)
|
|
4
8
|
|
|
5
9
|
- `Agent` names the body returned by `createAgent`; decision engines are `ZiggsBrain` and `ClaudeBrain`. See the README migration table.
|
package/dist/Agent.d.ts
CHANGED
|
@@ -131,9 +131,10 @@ export interface AgentOptions {
|
|
|
131
131
|
/** Per-agent session keying. Defaults to `(n) => n.chatId`. */
|
|
132
132
|
sessionResolver?: SessionResolver;
|
|
133
133
|
/**
|
|
134
|
-
* Agent-private long-term memory.
|
|
135
|
-
*
|
|
136
|
-
*
|
|
134
|
+
* Agent-private long-term memory. With an operator key and agent id, the
|
|
135
|
+
* default is an agent-private artifact store, so a note survives a restart.
|
|
136
|
+
* Pass a store to keep notes somewhere else. Without credentials, the
|
|
137
|
+
* default is still an in-memory store.
|
|
137
138
|
* Each wake is given a hire-scoped view of this store; agent key shapes
|
|
138
139
|
* do not change.
|
|
139
140
|
*/
|
package/dist/Agent.js
CHANGED
|
@@ -24,7 +24,8 @@ import { createZiggsEffectHandler } from './platform/ZiggsEffectHandler.js';
|
|
|
24
24
|
import { normalizeIncomingEvent } from './ingress/normalizeIncoming.js';
|
|
25
25
|
import { PromptBuilder } from './runtime/PromptBuilder.js';
|
|
26
26
|
import { removeTaskBook } from './runtime/taskBookkeeping.js';
|
|
27
|
-
import {
|
|
27
|
+
import { hireIdsFromEvent, memorySectionForWake, partitionMemoryStore, uniqueHireIds, } from './memory/MemoryStore.js';
|
|
28
|
+
import { memoryStoreFor } from './memory/ArtifactMemoryStore.js';
|
|
28
29
|
import { ToolManager } from './tools/ToolManager.js';
|
|
29
30
|
import { toolName } from './tools/defineTool.js';
|
|
30
31
|
import { PROTOCOL_TOOLS } from './platform/tools/tier1/protocolTools.js';
|
|
@@ -270,7 +271,11 @@ export class Agent {
|
|
|
270
271
|
(isClaudeCognition(resolved.cognition)
|
|
271
272
|
? Number(process.env.CLAUDE_SDK_TICK_TIMEOUT_MS ?? 300_000)
|
|
272
273
|
: 120_000);
|
|
273
|
-
this.memory =
|
|
274
|
+
this.memory = memoryStoreFor({
|
|
275
|
+
memory: options.memory,
|
|
276
|
+
operatorKey: options.operatorKey,
|
|
277
|
+
agentId: options.agentId,
|
|
278
|
+
});
|
|
274
279
|
this.sessionStore = options.sessionStore ?? null;
|
|
275
280
|
this._validate();
|
|
276
281
|
this.pollRunner = createDeclaredPollRunner(this.options, {
|
package/dist/index.d.ts
CHANGED
|
@@ -72,6 +72,7 @@ export { CLAUDE_SDK_TOOLS } from './brain/claudeSdkTools.js';
|
|
|
72
72
|
export { hostedModelTools, isHostedDeferred, hostedToolLane } from './brain/hostedToolSurface.js';
|
|
73
73
|
export { PROTOCOL_TOOL_NAMES, PROTOCOL_TOOL_TO_OPERATION, mapProtocolToolToOperation, isProtocolToolName } from './tasks/protocolRegistry.js';
|
|
74
74
|
export { InMemoryStore, FileMemoryStore } from './memory/MemoryStore.js';
|
|
75
|
+
export { ArtifactMemoryStore, memoryStoreFor } from './memory/ArtifactMemoryStore.js';
|
|
75
76
|
export type { MemoryStore } from './memory/MemoryStore.js';
|
|
76
77
|
export type { SessionStore } from './Agent.js';
|
|
77
78
|
export { classifyIncomingEvent } from './context/classifyEnvelope.js';
|
package/dist/index.js
CHANGED
|
@@ -86,6 +86,7 @@ export { CLAUDE_SDK_TOOLS } from './brain/claudeSdkTools.js';
|
|
|
86
86
|
export { hostedModelTools, isHostedDeferred, hostedToolLane } from './brain/hostedToolSurface.js';
|
|
87
87
|
export { PROTOCOL_TOOL_NAMES, PROTOCOL_TOOL_TO_OPERATION, mapProtocolToolToOperation, isProtocolToolName } from './tasks/protocolRegistry.js';
|
|
88
88
|
export { InMemoryStore, FileMemoryStore } from './memory/MemoryStore.js';
|
|
89
|
+
export { ArtifactMemoryStore, memoryStoreFor } from './memory/ArtifactMemoryStore.js';
|
|
89
90
|
export { classifyIncomingEvent } from './context/classifyEnvelope.js';
|
|
90
91
|
export { buildContextUpdates, CONTEXT_RESET } from './context/applyEffects.js';
|
|
91
92
|
export { getBatchEvents, isTaskResultRelevantToAgent } from './context/batch.js';
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type MemoryStore } from './MemoryStore.js';
|
|
2
|
+
/**
|
|
3
|
+
* The artifact calls a note store makes. Production uses {@link ArtifactsClient}.
|
|
4
|
+
* Tests pass a fake. No chat, agreement, or task: a note is not a deliverable
|
|
5
|
+
* and is not announced.
|
|
6
|
+
*/
|
|
7
|
+
export interface NoteArtifactClient {
|
|
8
|
+
writeStrict(input: {
|
|
9
|
+
text: string;
|
|
10
|
+
name: string;
|
|
11
|
+
contentType: string;
|
|
12
|
+
visibility: 'agent-private';
|
|
13
|
+
}): Promise<{
|
|
14
|
+
artifactId?: string;
|
|
15
|
+
}>;
|
|
16
|
+
list(query: {
|
|
17
|
+
authoredBy: 'me';
|
|
18
|
+
}, opts?: {
|
|
19
|
+
after?: string;
|
|
20
|
+
limit?: number;
|
|
21
|
+
}): Promise<{
|
|
22
|
+
artifacts: Array<{
|
|
23
|
+
name?: string | null;
|
|
24
|
+
text: string;
|
|
25
|
+
timestamp: string;
|
|
26
|
+
contentType: string;
|
|
27
|
+
visibility: string;
|
|
28
|
+
}>;
|
|
29
|
+
latestSequence: string | null;
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Notes that survive a process restart.
|
|
34
|
+
*
|
|
35
|
+
* Each note is an agent-private artifact with no container. A later write of
|
|
36
|
+
* the same key stores a newer row; reads return that row. An agent cannot
|
|
37
|
+
* delete an artifact, so older rows stay and are not what a read returns.
|
|
38
|
+
* The artifact id never leaves this store.
|
|
39
|
+
*/
|
|
40
|
+
export declare class ArtifactMemoryStore implements MemoryStore {
|
|
41
|
+
private readonly client;
|
|
42
|
+
private loaded;
|
|
43
|
+
constructor(opts: {
|
|
44
|
+
operatorKey: string;
|
|
45
|
+
agentId: string;
|
|
46
|
+
client?: NoteArtifactClient;
|
|
47
|
+
});
|
|
48
|
+
get(key: string): Promise<unknown | undefined>;
|
|
49
|
+
put(key: string, value: unknown): Promise<void>;
|
|
50
|
+
list(prefix: string): Promise<{
|
|
51
|
+
key: string;
|
|
52
|
+
value: unknown;
|
|
53
|
+
}[]>;
|
|
54
|
+
private notes;
|
|
55
|
+
}
|
|
56
|
+
/** The store a host gets when the caller did not pass one. */
|
|
57
|
+
export declare function memoryStoreFor(options: {
|
|
58
|
+
memory?: MemoryStore;
|
|
59
|
+
operatorKey?: string;
|
|
60
|
+
agentId?: string;
|
|
61
|
+
}): MemoryStore;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { ArtifactsClient } from '@ziggs-ai/api-client';
|
|
3
|
+
import { InMemoryStore, } from './MemoryStore.js';
|
|
4
|
+
const NOTE_CONTENT_TYPE = 'agent-note';
|
|
5
|
+
const NOTE_NAME_PREFIX = 'mem:';
|
|
6
|
+
const PAGE_LIMIT = 100;
|
|
7
|
+
const MAX_PAGES = 30;
|
|
8
|
+
function noteName(key) {
|
|
9
|
+
const digest = createHash('sha256').update(key).digest('hex').slice(0, 32);
|
|
10
|
+
return `${NOTE_NAME_PREFIX}${digest}`;
|
|
11
|
+
}
|
|
12
|
+
function parseNote(text) {
|
|
13
|
+
try {
|
|
14
|
+
const parsed = JSON.parse(text);
|
|
15
|
+
if (typeof parsed?.key !== 'string')
|
|
16
|
+
return null;
|
|
17
|
+
return { key: parsed.key, value: parsed.value };
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Notes that survive a process restart.
|
|
25
|
+
*
|
|
26
|
+
* Each note is an agent-private artifact with no container. A later write of
|
|
27
|
+
* the same key stores a newer row; reads return that row. An agent cannot
|
|
28
|
+
* delete an artifact, so older rows stay and are not what a read returns.
|
|
29
|
+
* The artifact id never leaves this store.
|
|
30
|
+
*/
|
|
31
|
+
export class ArtifactMemoryStore {
|
|
32
|
+
client;
|
|
33
|
+
loaded = null;
|
|
34
|
+
constructor(opts) {
|
|
35
|
+
this.client =
|
|
36
|
+
opts.client ??
|
|
37
|
+
new ArtifactsClient(opts.operatorKey, opts.agentId);
|
|
38
|
+
}
|
|
39
|
+
async get(key) {
|
|
40
|
+
const notes = await this.notes();
|
|
41
|
+
return notes.get(key)?.value;
|
|
42
|
+
}
|
|
43
|
+
async put(key, value) {
|
|
44
|
+
const timestamp = new Date().toISOString();
|
|
45
|
+
await this.client.writeStrict({
|
|
46
|
+
text: JSON.stringify({ key, value }),
|
|
47
|
+
name: noteName(key),
|
|
48
|
+
contentType: NOTE_CONTENT_TYPE,
|
|
49
|
+
visibility: 'agent-private',
|
|
50
|
+
});
|
|
51
|
+
const notes = await this.notes();
|
|
52
|
+
notes.set(key, { key, value, timestamp });
|
|
53
|
+
}
|
|
54
|
+
async list(prefix) {
|
|
55
|
+
const notes = await this.notes();
|
|
56
|
+
const out = [];
|
|
57
|
+
for (const note of notes.values()) {
|
|
58
|
+
if (note.key.startsWith(prefix))
|
|
59
|
+
out.push({ key: note.key, value: note.value });
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
async notes() {
|
|
64
|
+
if (this.loaded)
|
|
65
|
+
return this.loaded;
|
|
66
|
+
const byKey = new Map();
|
|
67
|
+
let after;
|
|
68
|
+
for (let page = 0; page < MAX_PAGES; page++) {
|
|
69
|
+
const result = await this.client.list({ authoredBy: 'me' }, { after, limit: PAGE_LIMIT });
|
|
70
|
+
for (const row of result.artifacts) {
|
|
71
|
+
if (row.contentType !== NOTE_CONTENT_TYPE)
|
|
72
|
+
continue;
|
|
73
|
+
if (row.visibility !== 'agent-private')
|
|
74
|
+
continue;
|
|
75
|
+
if (!row.name?.startsWith(NOTE_NAME_PREFIX))
|
|
76
|
+
continue;
|
|
77
|
+
const parsed = parseNote(row.text);
|
|
78
|
+
if (!parsed)
|
|
79
|
+
continue;
|
|
80
|
+
const previous = byKey.get(parsed.key);
|
|
81
|
+
if (!previous || row.timestamp >= previous.timestamp) {
|
|
82
|
+
byKey.set(parsed.key, {
|
|
83
|
+
key: parsed.key,
|
|
84
|
+
value: parsed.value,
|
|
85
|
+
timestamp: row.timestamp,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (result.artifacts.length < PAGE_LIMIT || !result.latestSequence || result.latestSequence === after) {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
after = result.latestSequence;
|
|
93
|
+
}
|
|
94
|
+
this.loaded = byKey;
|
|
95
|
+
return byKey;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** The store a host gets when the caller did not pass one. */
|
|
99
|
+
export function memoryStoreFor(options) {
|
|
100
|
+
if (options.memory)
|
|
101
|
+
return options.memory;
|
|
102
|
+
if (options.operatorKey && options.agentId) {
|
|
103
|
+
return new ArtifactMemoryStore({
|
|
104
|
+
operatorKey: options.operatorKey,
|
|
105
|
+
agentId: options.agentId,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return new InMemoryStore();
|
|
109
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ziggs-ai/agent-sdk",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.13",
|
|
4
4
|
"description": "Agent framework SDK for building autonomous agents on the Ziggs platform",
|
|
5
5
|
"homepage": "https://ziggsai.com/docs",
|
|
6
6
|
"bugs": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@anthropic-ai/claude-agent-sdk": "^0.3.284",
|
|
31
31
|
"@anthropic-ai/sdk": "^0.110.0",
|
|
32
32
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
33
|
-
"@ziggs-ai/api-client": "0.37.
|
|
33
|
+
"@ziggs-ai/api-client": "0.37.16",
|
|
34
34
|
"@ziggs-ai/contracts": "^0.23.3",
|
|
35
35
|
"ajv": "^8.17.1",
|
|
36
36
|
"dotenv": "^17.2.3",
|