agentenkit 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 +21 -0
- package/README.md +226 -0
- package/dist/adapters/inline.d.ts +27 -0
- package/dist/adapters/inline.d.ts.map +1 -0
- package/dist/adapters/inline.js +41 -0
- package/dist/adapters/inline.js.map +1 -0
- package/dist/adapters/memory.d.ts +74 -0
- package/dist/adapters/memory.d.ts.map +1 -0
- package/dist/adapters/memory.js +194 -0
- package/dist/adapters/memory.js.map +1 -0
- package/dist/adapters/prisma.d.ts +176 -0
- package/dist/adapters/prisma.d.ts.map +1 -0
- package/dist/adapters/prisma.js +107 -0
- package/dist/adapters/prisma.js.map +1 -0
- package/dist/adapters/qstash.d.ts +36 -0
- package/dist/adapters/qstash.d.ts.map +1 -0
- package/dist/adapters/qstash.js +26 -0
- package/dist/adapters/qstash.js.map +1 -0
- package/dist/adapters/redis.d.ts +49 -0
- package/dist/adapters/redis.d.ts.map +1 -0
- package/dist/adapters/redis.js +60 -0
- package/dist/adapters/redis.js.map +1 -0
- package/dist/adapters/sqlite.d.ts +67 -0
- package/dist/adapters/sqlite.d.ts.map +1 -0
- package/dist/adapters/sqlite.js +199 -0
- package/dist/adapters/sqlite.js.map +1 -0
- package/dist/adapters/upstash.d.ts +48 -0
- package/dist/adapters/upstash.d.ts.map +1 -0
- package/dist/adapters/upstash.js +46 -0
- package/dist/adapters/upstash.js.map +1 -0
- package/dist/admin/default.d.ts +15 -0
- package/dist/admin/default.d.ts.map +1 -0
- package/dist/admin/default.js +22 -0
- package/dist/admin/default.js.map +1 -0
- package/dist/admin/memory.d.ts +29 -0
- package/dist/admin/memory.d.ts.map +1 -0
- package/dist/admin/memory.js +83 -0
- package/dist/admin/memory.js.map +1 -0
- package/dist/admin/postgres.d.ts +43 -0
- package/dist/admin/postgres.d.ts.map +1 -0
- package/dist/admin/postgres.js +201 -0
- package/dist/admin/postgres.js.map +1 -0
- package/dist/admin/sqlite.d.ts +35 -0
- package/dist/admin/sqlite.d.ts.map +1 -0
- package/dist/admin/sqlite.js +187 -0
- package/dist/admin/sqlite.js.map +1 -0
- package/dist/core/admin.d.ts +88 -0
- package/dist/core/admin.d.ts.map +1 -0
- package/dist/core/admin.js +147 -0
- package/dist/core/admin.js.map +1 -0
- package/dist/core/agent.d.ts +29 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +41 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/cache.d.ts +37 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +68 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/context.d.ts +13 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +87 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/deleteThread.d.ts +14 -0
- package/dist/core/deleteThread.d.ts.map +1 -0
- package/dist/core/deleteThread.js +34 -0
- package/dist/core/deleteThread.js.map +1 -0
- package/dist/core/engine.d.ts +79 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +489 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/follow.d.ts +50 -0
- package/dist/core/follow.d.ts.map +1 -0
- package/dist/core/follow.js +153 -0
- package/dist/core/follow.js.map +1 -0
- package/dist/core/hitl.d.ts +98 -0
- package/dist/core/hitl.d.ts.map +1 -0
- package/dist/core/hitl.js +199 -0
- package/dist/core/hitl.js.map +1 -0
- package/dist/core/keys.d.ts +26 -0
- package/dist/core/keys.d.ts.map +1 -0
- package/dist/core/keys.js +32 -0
- package/dist/core/keys.js.map +1 -0
- package/dist/core/loop.d.ts +105 -0
- package/dist/core/loop.d.ts.map +1 -0
- package/dist/core/loop.js +234 -0
- package/dist/core/loop.js.map +1 -0
- package/dist/core/publish.d.ts +18 -0
- package/dist/core/publish.d.ts.map +1 -0
- package/dist/core/publish.js +34 -0
- package/dist/core/publish.js.map +1 -0
- package/dist/core/reclaim.d.ts +20 -0
- package/dist/core/reclaim.d.ts.map +1 -0
- package/dist/core/reclaim.js +56 -0
- package/dist/core/reclaim.js.map +1 -0
- package/dist/core/run.d.ts +8 -0
- package/dist/core/run.d.ts.map +1 -0
- package/dist/core/run.js +102 -0
- package/dist/core/run.js.map +1 -0
- package/dist/core/state.d.ts +50 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +39 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/stop.d.ts +7 -0
- package/dist/core/stop.d.ts.map +1 -0
- package/dist/core/stop.js +15 -0
- package/dist/core/stop.js.map +1 -0
- package/dist/core/stream.d.ts +12 -0
- package/dist/core/stream.d.ts.map +1 -0
- package/dist/core/stream.js +21 -0
- package/dist/core/stream.js.map +1 -0
- package/dist/core/subagent.d.ts +77 -0
- package/dist/core/subagent.d.ts.map +1 -0
- package/dist/core/subagent.js +261 -0
- package/dist/core/subagent.js.map +1 -0
- package/dist/core/tools.d.ts +36 -0
- package/dist/core/tools.d.ts.map +1 -0
- package/dist/core/tools.js +22 -0
- package/dist/core/tools.js.map +1 -0
- package/dist/core/types.d.ts +286 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +49 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/usage.d.ts +40 -0
- package/dist/core/usage.d.ts.map +1 -0
- package/dist/core/usage.js +43 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/ports/admin.d.ts +102 -0
- package/dist/ports/admin.d.ts.map +1 -0
- package/dist/ports/admin.js +2 -0
- package/dist/ports/admin.js.map +1 -0
- package/dist/ports/bus.d.ts +13 -0
- package/dist/ports/bus.d.ts.map +1 -0
- package/dist/ports/bus.js +2 -0
- package/dist/ports/bus.js.map +1 -0
- package/dist/ports/kv.d.ts +16 -0
- package/dist/ports/kv.d.ts.map +1 -0
- package/dist/ports/kv.js +2 -0
- package/dist/ports/kv.js.map +1 -0
- package/dist/ports/queue.d.ts +18 -0
- package/dist/ports/queue.d.ts.map +1 -0
- package/dist/ports/queue.js +2 -0
- package/dist/ports/queue.js.map +1 -0
- package/dist/ports/runtime.d.ts +260 -0
- package/dist/ports/runtime.d.ts.map +1 -0
- package/dist/ports/runtime.js +2 -0
- package/dist/ports/runtime.js.map +1 -0
- package/dist/ports/storage.d.ts +72 -0
- package/dist/ports/storage.d.ts.map +1 -0
- package/dist/ports/storage.js +2 -0
- package/dist/ports/storage.js.map +1 -0
- package/dist/runtime.d.ts +5 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +177 -0
- package/dist/runtime.js.map +1 -0
- package/package.json +126 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import type { AgentEvent, ExecutionState, NewMessage, NewUsage, ThreadDTO, UsageTotals } from '../core/types.js';
|
|
2
|
+
import type { Storage } from '../ports/storage.js';
|
|
3
|
+
/** Minimal structural type of the Prisma client surface we use. The real
|
|
4
|
+
* `PrismaClient` satisfies it — no SDK import needed in the package. */
|
|
5
|
+
export interface PrismaLike {
|
|
6
|
+
thread: {
|
|
7
|
+
findUnique(a: {
|
|
8
|
+
where: {
|
|
9
|
+
id: string;
|
|
10
|
+
};
|
|
11
|
+
}): Promise<(Omit<ThreadDTO, 'createdAt' | 'updatedAt'> & {
|
|
12
|
+
createdAt: Date;
|
|
13
|
+
updatedAt: Date;
|
|
14
|
+
}) | null>;
|
|
15
|
+
findMany(a: {
|
|
16
|
+
orderBy: {
|
|
17
|
+
updatedAt: 'desc';
|
|
18
|
+
};
|
|
19
|
+
}): Promise<ThreadDTO[]>;
|
|
20
|
+
create(a: {
|
|
21
|
+
data: {
|
|
22
|
+
model?: string;
|
|
23
|
+
};
|
|
24
|
+
}): Promise<ThreadDTO>;
|
|
25
|
+
update(a: {
|
|
26
|
+
where: {
|
|
27
|
+
id: string;
|
|
28
|
+
};
|
|
29
|
+
data: {
|
|
30
|
+
state: ExecutionState;
|
|
31
|
+
};
|
|
32
|
+
}): Promise<unknown>;
|
|
33
|
+
updateMany(a: {
|
|
34
|
+
where: {
|
|
35
|
+
id: string;
|
|
36
|
+
state: ExecutionState;
|
|
37
|
+
};
|
|
38
|
+
data: {
|
|
39
|
+
state: ExecutionState;
|
|
40
|
+
};
|
|
41
|
+
}): Promise<{
|
|
42
|
+
count: number;
|
|
43
|
+
}>;
|
|
44
|
+
delete(a: {
|
|
45
|
+
where: {
|
|
46
|
+
id: string;
|
|
47
|
+
};
|
|
48
|
+
}): Promise<unknown>;
|
|
49
|
+
groupBy(a: {
|
|
50
|
+
by: ['state'];
|
|
51
|
+
_count: {
|
|
52
|
+
_all: true;
|
|
53
|
+
};
|
|
54
|
+
}): Promise<Array<{
|
|
55
|
+
state: ExecutionState;
|
|
56
|
+
_count: {
|
|
57
|
+
_all: number;
|
|
58
|
+
};
|
|
59
|
+
}>>;
|
|
60
|
+
};
|
|
61
|
+
message: {
|
|
62
|
+
create(a: {
|
|
63
|
+
data: {
|
|
64
|
+
threadId: string;
|
|
65
|
+
agentId?: string | null;
|
|
66
|
+
role: string;
|
|
67
|
+
content: any;
|
|
68
|
+
};
|
|
69
|
+
}): Promise<any>;
|
|
70
|
+
findMany(a: {
|
|
71
|
+
where: {
|
|
72
|
+
threadId: string;
|
|
73
|
+
agentId?: string | null;
|
|
74
|
+
};
|
|
75
|
+
orderBy: {
|
|
76
|
+
createdAt: 'asc';
|
|
77
|
+
};
|
|
78
|
+
}): Promise<any[]>;
|
|
79
|
+
deleteMany(a: {
|
|
80
|
+
where: {
|
|
81
|
+
id: {
|
|
82
|
+
in: string[];
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
}): Promise<{
|
|
86
|
+
count: number;
|
|
87
|
+
}>;
|
|
88
|
+
};
|
|
89
|
+
agentEvent: {
|
|
90
|
+
create(a: {
|
|
91
|
+
data: {
|
|
92
|
+
threadId: string;
|
|
93
|
+
seq: number;
|
|
94
|
+
type: string;
|
|
95
|
+
payload: any;
|
|
96
|
+
};
|
|
97
|
+
}): Promise<unknown>;
|
|
98
|
+
findMany(a: {
|
|
99
|
+
where: {
|
|
100
|
+
threadId: string;
|
|
101
|
+
seq?: {
|
|
102
|
+
gt: number;
|
|
103
|
+
};
|
|
104
|
+
type?: string;
|
|
105
|
+
};
|
|
106
|
+
orderBy: {
|
|
107
|
+
seq: 'asc';
|
|
108
|
+
};
|
|
109
|
+
}): Promise<AgentEvent[]>;
|
|
110
|
+
findFirst(a: {
|
|
111
|
+
where: {
|
|
112
|
+
threadId: string;
|
|
113
|
+
type: string;
|
|
114
|
+
};
|
|
115
|
+
orderBy: {
|
|
116
|
+
seq: 'desc';
|
|
117
|
+
};
|
|
118
|
+
}): Promise<AgentEvent | null>;
|
|
119
|
+
};
|
|
120
|
+
tokenUsage: {
|
|
121
|
+
create(a: {
|
|
122
|
+
data: NewUsage & {
|
|
123
|
+
threadId: string;
|
|
124
|
+
};
|
|
125
|
+
}): Promise<unknown>;
|
|
126
|
+
aggregate(a: {
|
|
127
|
+
where: {
|
|
128
|
+
threadId: string;
|
|
129
|
+
};
|
|
130
|
+
_sum: {
|
|
131
|
+
inputTokens: true;
|
|
132
|
+
cachedInputTokens: true;
|
|
133
|
+
outputTokens: true;
|
|
134
|
+
totalTokens: true;
|
|
135
|
+
};
|
|
136
|
+
}): Promise<{
|
|
137
|
+
_sum: Partial<Record<keyof UsageTotals, number | null>>;
|
|
138
|
+
}>;
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/** Reference Storage adapter over PostgreSQL/Prisma (schema in the README / spec §2.4). */
|
|
142
|
+
export declare class PrismaStorage implements Storage {
|
|
143
|
+
private readonly prisma;
|
|
144
|
+
constructor(prisma: PrismaLike);
|
|
145
|
+
threads: {
|
|
146
|
+
get: (threadId: string) => Promise<(Omit<ThreadDTO, "updatedAt" | "createdAt"> & {
|
|
147
|
+
createdAt: Date;
|
|
148
|
+
updatedAt: Date;
|
|
149
|
+
}) | null>;
|
|
150
|
+
create: (init?: {
|
|
151
|
+
model?: string;
|
|
152
|
+
}) => Promise<ThreadDTO>;
|
|
153
|
+
list: () => Promise<ThreadDTO[]>;
|
|
154
|
+
setState: (threadId: string, state: ExecutionState) => Promise<void>;
|
|
155
|
+
claimState: (threadId: string, from: ExecutionState, to: ExecutionState) => Promise<boolean>;
|
|
156
|
+
delete: (threadId: string) => Promise<undefined>;
|
|
157
|
+
};
|
|
158
|
+
messages: {
|
|
159
|
+
append: (threadId: string, m: NewMessage) => Promise<any>;
|
|
160
|
+
list: (threadId: string, opts?: {
|
|
161
|
+
agentId?: string | null;
|
|
162
|
+
}) => Promise<any[]>;
|
|
163
|
+
deleteFrom: (threadId: string, messageId: string) => Promise<number>;
|
|
164
|
+
};
|
|
165
|
+
events: {
|
|
166
|
+
append: (threadId: string, event: AgentEvent) => Promise<void>;
|
|
167
|
+
listSince: (threadId: string, sinceSeq: number) => Promise<AgentEvent[]>;
|
|
168
|
+
latest: (threadId: string, type: string) => Promise<AgentEvent | null>;
|
|
169
|
+
listByType: (threadId: string, type: string) => Promise<AgentEvent[]>;
|
|
170
|
+
};
|
|
171
|
+
usage: {
|
|
172
|
+
total: (threadId: string) => Promise<UsageTotals>;
|
|
173
|
+
record: (threadId: string, usage: NewUsage) => Promise<void>;
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=prisma.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/adapters/prisma.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/** Reference Storage adapter over PostgreSQL/Prisma (schema in the README / spec §2.4). */
|
|
2
|
+
export class PrismaStorage {
|
|
3
|
+
prisma;
|
|
4
|
+
constructor(prisma) {
|
|
5
|
+
this.prisma = prisma;
|
|
6
|
+
}
|
|
7
|
+
threads = {
|
|
8
|
+
get: (threadId) => this.prisma.thread.findUnique({ where: { id: threadId } }),
|
|
9
|
+
create: (init) => this.prisma.thread.create({ data: { model: init?.model } }),
|
|
10
|
+
list: () => this.prisma.thread.findMany({ orderBy: { updatedAt: 'desc' } }),
|
|
11
|
+
setState: async (threadId, state) => {
|
|
12
|
+
await this.prisma.thread.update({ where: { id: threadId }, data: { state } });
|
|
13
|
+
},
|
|
14
|
+
claimState: async (threadId, from, to) => {
|
|
15
|
+
// Single conditional UPDATE — the atomicity contract (§3.4)
|
|
16
|
+
const res = await this.prisma.thread.updateMany({
|
|
17
|
+
where: { id: threadId, state: from },
|
|
18
|
+
data: { state: to },
|
|
19
|
+
});
|
|
20
|
+
return res.count > 0;
|
|
21
|
+
},
|
|
22
|
+
delete: (threadId) =>
|
|
23
|
+
// One delete — the reference schema cascades to Message, AgentEvent,
|
|
24
|
+
// TokenUsage and SubagentRun via `onDelete: Cascade` (spec §2.4)
|
|
25
|
+
this.prisma.thread.delete({ where: { id: threadId } }).then(() => undefined),
|
|
26
|
+
};
|
|
27
|
+
messages = {
|
|
28
|
+
append: (threadId, m) => this.prisma.message.create({
|
|
29
|
+
data: { threadId, agentId: m.agentId ?? null, role: m.role, content: m.content },
|
|
30
|
+
}),
|
|
31
|
+
list: (threadId, opts) => this.prisma.message.findMany({
|
|
32
|
+
// `agentId: null` is a real filter (IS NULL), not an absent one — the
|
|
33
|
+
// scope is only dropped when the caller omits it entirely.
|
|
34
|
+
where: {
|
|
35
|
+
threadId,
|
|
36
|
+
...(opts && 'agentId' in opts ? { agentId: opts.agentId } : {}),
|
|
37
|
+
},
|
|
38
|
+
orderBy: { createdAt: 'asc' },
|
|
39
|
+
}),
|
|
40
|
+
deleteFrom: async (threadId, messageId) => {
|
|
41
|
+
// Delete by id over the same ordering `list` uses, rather than a
|
|
42
|
+
// `createdAt >=` range: a run appends several messages inside one
|
|
43
|
+
// millisecond, and a range would take neighbours with it.
|
|
44
|
+
const rows = await this.prisma.message.findMany({
|
|
45
|
+
where: { threadId },
|
|
46
|
+
orderBy: { createdAt: 'asc' },
|
|
47
|
+
});
|
|
48
|
+
const from = rows.findIndex((m) => m.id === messageId);
|
|
49
|
+
if (from === -1)
|
|
50
|
+
return 0;
|
|
51
|
+
const { count } = await this.prisma.message.deleteMany({
|
|
52
|
+
where: { id: { in: rows.slice(from).map((m) => m.id) } },
|
|
53
|
+
});
|
|
54
|
+
return count;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
events = {
|
|
58
|
+
append: async (threadId, event) => {
|
|
59
|
+
await this.prisma.agentEvent.create({
|
|
60
|
+
data: { threadId, seq: event.seq, type: event.type, payload: event.payload },
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
listSince: (threadId, sinceSeq) => this.prisma.agentEvent.findMany({
|
|
64
|
+
where: { threadId, seq: { gt: sinceSeq } },
|
|
65
|
+
orderBy: { seq: 'asc' },
|
|
66
|
+
}),
|
|
67
|
+
latest: (threadId, type) => this.prisma.agentEvent.findFirst({
|
|
68
|
+
where: { threadId, type },
|
|
69
|
+
orderBy: { seq: 'desc' },
|
|
70
|
+
}),
|
|
71
|
+
listByType: (threadId, type) => this.prisma.agentEvent.findMany({ where: { threadId, type }, orderBy: { seq: 'asc' } }),
|
|
72
|
+
};
|
|
73
|
+
usage = {
|
|
74
|
+
total: async (threadId) => {
|
|
75
|
+
// One aggregate rather than reading every row: a long thread can hold a
|
|
76
|
+
// usage row per run segment (§4).
|
|
77
|
+
const { _sum } = await this.prisma.tokenUsage.aggregate({
|
|
78
|
+
where: { threadId },
|
|
79
|
+
_sum: {
|
|
80
|
+
inputTokens: true,
|
|
81
|
+
cachedInputTokens: true,
|
|
82
|
+
outputTokens: true,
|
|
83
|
+
totalTokens: true,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
inputTokens: _sum.inputTokens ?? 0,
|
|
88
|
+
cachedInputTokens: _sum.cachedInputTokens ?? 0,
|
|
89
|
+
outputTokens: _sum.outputTokens ?? 0,
|
|
90
|
+
totalTokens: _sum.totalTokens ?? 0,
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
record: async (threadId, usage) => {
|
|
94
|
+
await this.prisma.tokenUsage.create({
|
|
95
|
+
data: {
|
|
96
|
+
threadId,
|
|
97
|
+
agentId: usage.agentId ?? null,
|
|
98
|
+
inputTokens: usage.inputTokens,
|
|
99
|
+
cachedInputTokens: usage.cachedInputTokens,
|
|
100
|
+
outputTokens: usage.outputTokens,
|
|
101
|
+
totalTokens: usage.totalTokens,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=prisma.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/adapters/prisma.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { EnqueueOptions, Queue } from '../ports/queue.js';
|
|
2
|
+
import type { RunJob } from '../core/types.js';
|
|
3
|
+
/** Minimal structural type of the @upstash/qstash (v2) client we use. */
|
|
4
|
+
export interface QStashLike {
|
|
5
|
+
queue(a: {
|
|
6
|
+
queueName: string;
|
|
7
|
+
}): {
|
|
8
|
+
enqueueJSON(a: {
|
|
9
|
+
url: string;
|
|
10
|
+
body: unknown;
|
|
11
|
+
}): Promise<unknown>;
|
|
12
|
+
};
|
|
13
|
+
/** `delay` is in seconds. QStash supports it on publish only — an enqueue
|
|
14
|
+
* carrying Upstash-Delay is REJECTED outright ("Upstash-Not-Before/
|
|
15
|
+
* Upstash-Delay can not be used with enqueue"), so a delayed dispatch has
|
|
16
|
+
* to be published instead. */
|
|
17
|
+
publishJSON(a: {
|
|
18
|
+
url: string;
|
|
19
|
+
body: unknown;
|
|
20
|
+
delay?: number;
|
|
21
|
+
}): Promise<unknown>;
|
|
22
|
+
}
|
|
23
|
+
export interface QStashQueueOptions {
|
|
24
|
+
/** Fully-qualified consumer URL, e.g. https://app.example.com/api/queue/agent-run */
|
|
25
|
+
url: string;
|
|
26
|
+
/** Queue name for flow control (§2.8). Defaults to `agent-runs`. */
|
|
27
|
+
queueName?: string;
|
|
28
|
+
}
|
|
29
|
+
/** Reference Queue adapter over Upstash QStash HTTP queues. */
|
|
30
|
+
export declare class QStashQueue implements Queue {
|
|
31
|
+
private readonly client;
|
|
32
|
+
private readonly opts;
|
|
33
|
+
constructor(client: QStashLike, opts: QStashQueueOptions);
|
|
34
|
+
enqueue(job: RunJob, opts?: EnqueueOptions): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=qstash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qstash.d.ts","sourceRoot":"","sources":["../../src/adapters/qstash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,yEAAyE;AACzE,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG;QAC/B,WAAW,CAAC,CAAC,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAClE,CAAC;IACF;;;mCAG+B;IAC/B,WAAW,CAAC,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAClF;AAED,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,GAAG,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,+DAA+D;AAC/D,qBAAa,WAAY,YAAW,KAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAc,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAzC,MAAM,EAAE,UAAU,EAAmB,IAAI,EAAE,kBAAkB;IAE1F,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB3D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Reference Queue adapter over Upstash QStash HTTP queues. */
|
|
2
|
+
export class QStashQueue {
|
|
3
|
+
client;
|
|
4
|
+
opts;
|
|
5
|
+
constructor(client, opts) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
this.opts = opts;
|
|
8
|
+
}
|
|
9
|
+
enqueue(job, opts) {
|
|
10
|
+
// A delayed job goes out as a published message rather than a queued one:
|
|
11
|
+
// QStash rejects Upstash-Delay on enqueue. The trade is that this one
|
|
12
|
+
// message skips the queue's flow control — acceptable for the two things
|
|
13
|
+
// that ask for a delay (a HITL expiry and a blocked job's redrive), since
|
|
14
|
+
// both are single messages the run lock already serializes.
|
|
15
|
+
if (opts?.delaySeconds) {
|
|
16
|
+
return this.client
|
|
17
|
+
.publishJSON({ url: this.opts.url, body: job, delay: opts.delaySeconds })
|
|
18
|
+
.then(() => undefined);
|
|
19
|
+
}
|
|
20
|
+
return this.client
|
|
21
|
+
.queue({ queueName: this.opts.queueName ?? 'agent-runs' })
|
|
22
|
+
.enqueueJSON({ url: this.opts.url, body: job })
|
|
23
|
+
.then(() => undefined);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=qstash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qstash.js","sourceRoot":"","sources":["../../src/adapters/qstash.ts"],"names":[],"mappings":"AAsBA,+DAA+D;AAC/D,MAAM,OAAO,WAAW;IACO;IAAqC;IAAlE,YAA6B,MAAkB,EAAmB,IAAwB;QAA7D,WAAM,GAAN,MAAM,CAAY;QAAmB,SAAI,GAAJ,IAAI,CAAoB;IAAG,CAAC;IAE9F,OAAO,CAAC,GAAW,EAAE,IAAqB;QACxC,0EAA0E;QAC1E,sEAAsE;QACtE,yEAAyE;QACzE,0EAA0E;QAC1E,4DAA4D;QAC5D,IAAI,IAAI,EAAE,YAAY,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,MAAM;iBACf,WAAW,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;iBACxE,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;QAED,OAAO,IAAI,CAAC,MAAM;aACf,KAAK,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,YAAY,EAAE,CAAC;aACzD,WAAW,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;aAC9C,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { AgentEvent } from '../core/types.js';
|
|
2
|
+
import type { Kv } from '../ports/kv.js';
|
|
3
|
+
import type { EventBus } from '../ports/bus.js';
|
|
4
|
+
/** Minimal structural type of a node-redis (v4) client — the real client
|
|
5
|
+
* satisfies it without importing the SDK here. Works against any Redis:
|
|
6
|
+
* local Docker, self-hosted, or managed. */
|
|
7
|
+
export interface RedisClientLike {
|
|
8
|
+
connect(): Promise<unknown>;
|
|
9
|
+
get: any;
|
|
10
|
+
set: any;
|
|
11
|
+
del: any;
|
|
12
|
+
incr: any;
|
|
13
|
+
publish: any;
|
|
14
|
+
duplicate(): any;
|
|
15
|
+
}
|
|
16
|
+
/** A dedicated connection for subscriptions (node-redis `client.duplicate()`). */
|
|
17
|
+
export interface RedisSubscriberLike {
|
|
18
|
+
connect(): Promise<unknown>;
|
|
19
|
+
subscribe: any;
|
|
20
|
+
unsubscribe: any;
|
|
21
|
+
quit: any;
|
|
22
|
+
on: any;
|
|
23
|
+
}
|
|
24
|
+
/** Reference Kv adapter over plain Redis (node-redis). */
|
|
25
|
+
export declare class RedisKv implements Kv {
|
|
26
|
+
private readonly redis;
|
|
27
|
+
constructor(redis: RedisClientLike);
|
|
28
|
+
get(key: string): any;
|
|
29
|
+
set(key: string, value: string, opts?: {
|
|
30
|
+
exSeconds?: number;
|
|
31
|
+
onlyIfNotExists?: boolean;
|
|
32
|
+
}): Promise<boolean>;
|
|
33
|
+
del(key: string): any;
|
|
34
|
+
incr(key: string): any;
|
|
35
|
+
}
|
|
36
|
+
/** Reference EventBus adapter over plain Redis Pub/Sub (node-redis).
|
|
37
|
+
*
|
|
38
|
+
* While subscribed, emits a bus-only `HEARTBEAT` notice (seq 0, never
|
|
39
|
+
* persisted) every heartbeatMs — the §2.5 watchdog pattern: pub/sub is
|
|
40
|
+
* at-most-once, so the SSE distributor treats heartbeats as a trigger to
|
|
41
|
+
* re-check for orphaned HITL waits. */
|
|
42
|
+
export declare class RedisBus implements EventBus {
|
|
43
|
+
private readonly client;
|
|
44
|
+
private readonly heartbeatMs;
|
|
45
|
+
constructor(client: RedisClientLike, heartbeatMs?: number);
|
|
46
|
+
publish(threadId: string, event: AgentEvent): Promise<void>;
|
|
47
|
+
subscribe(threadId: string, handler: (event: AgentEvent) => void): Promise<() => Promise<void>>;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=redis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/adapters/redis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;6CAE6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAG5B,GAAG,EAAE,GAAG,CAAC;IACT,GAAG,EAAE,GAAG,CAAC;IACT,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,GAAG,CAAC;IACV,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,IAAI,GAAG,CAAC;CAClB;AAED,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,SAAS,EAAE,GAAG,CAAC;IACf,WAAW,EAAE,GAAG,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC;IACV,EAAE,EAAE,GAAG,CAAC;CACT;AAED,0DAA0D;AAC1D,qBAAa,OAAQ,YAAW,EAAE;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,eAAe;IAEnD,GAAG,CAAC,GAAG,EAAE,MAAM;IACT,GAAG,CACP,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACvD,OAAO,CAAC,OAAO,CAAC;IAanB,GAAG,CAAC,GAAG,EAAE,MAAM;IACf,IAAI,CAAC,GAAG,EAAE,MAAM;CACjB;AAED;;;;;wCAKwC;AACxC,qBAAa,QAAS,YAAW,QAAQ;IAErC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBADX,MAAM,EAAE,eAAe,EACvB,WAAW,SAAS;IAGjC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU;IAI3C,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;CAuBvE"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { THREAD_CHANNEL } from './upstash.js';
|
|
2
|
+
/** Reference Kv adapter over plain Redis (node-redis). */
|
|
3
|
+
export class RedisKv {
|
|
4
|
+
redis;
|
|
5
|
+
constructor(redis) {
|
|
6
|
+
this.redis = redis;
|
|
7
|
+
}
|
|
8
|
+
get(key) { return this.redis.get(key); }
|
|
9
|
+
async set(key, value, opts) {
|
|
10
|
+
const res = await this.redis.set(key, value, opts?.onlyIfNotExists
|
|
11
|
+
? { NX: true, EX: opts.exSeconds }
|
|
12
|
+
: opts?.exSeconds
|
|
13
|
+
? { EX: opts.exSeconds }
|
|
14
|
+
: undefined);
|
|
15
|
+
// SET NX returns 'OK' on success, null when the key exists
|
|
16
|
+
return opts?.onlyIfNotExists ? res === 'OK' : true;
|
|
17
|
+
}
|
|
18
|
+
del(key) { return this.redis.del(key).then(() => undefined); }
|
|
19
|
+
incr(key) { return this.redis.incr(key); }
|
|
20
|
+
}
|
|
21
|
+
/** Reference EventBus adapter over plain Redis Pub/Sub (node-redis).
|
|
22
|
+
*
|
|
23
|
+
* While subscribed, emits a bus-only `HEARTBEAT` notice (seq 0, never
|
|
24
|
+
* persisted) every heartbeatMs — the §2.5 watchdog pattern: pub/sub is
|
|
25
|
+
* at-most-once, so the SSE distributor treats heartbeats as a trigger to
|
|
26
|
+
* re-check for orphaned HITL waits. */
|
|
27
|
+
export class RedisBus {
|
|
28
|
+
client;
|
|
29
|
+
heartbeatMs;
|
|
30
|
+
constructor(client, heartbeatMs = 60_000) {
|
|
31
|
+
this.client = client;
|
|
32
|
+
this.heartbeatMs = heartbeatMs;
|
|
33
|
+
}
|
|
34
|
+
async publish(threadId, event) {
|
|
35
|
+
await this.client.publish(THREAD_CHANNEL(threadId), JSON.stringify(event));
|
|
36
|
+
}
|
|
37
|
+
async subscribe(threadId, handler) {
|
|
38
|
+
const sub = this.client.duplicate();
|
|
39
|
+
await sub.connect();
|
|
40
|
+
await sub.subscribe(THREAD_CHANNEL(threadId), (message) => {
|
|
41
|
+
try {
|
|
42
|
+
handler(JSON.parse(message));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// malformed frame — never kill the subscription
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const heartbeat = setInterval(() => {
|
|
49
|
+
handler({
|
|
50
|
+
threadId, seq: 0, type: 'HEARTBEAT', payload: null, createdAt: new Date(),
|
|
51
|
+
});
|
|
52
|
+
}, this.heartbeatMs);
|
|
53
|
+
return async () => {
|
|
54
|
+
clearInterval(heartbeat);
|
|
55
|
+
await sub.unsubscribe(THREAD_CHANNEL(threadId)).catch(() => undefined);
|
|
56
|
+
await sub.quit().catch(() => undefined);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=redis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/adapters/redis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { AgentEvent, ExecutionState, MessageDTO, NewMessage, NewUsage, ThreadDTO, UsageTotals } from '../core/types.js';
|
|
2
|
+
import type { Storage } from '../ports/storage.js';
|
|
3
|
+
/** Minimal structural type over a synchronous SQLite handle — `bun:sqlite`'s
|
|
4
|
+
* `Database` satisfies it. Kept structural for the same reason every other
|
|
5
|
+
* adapter is: the package never imports a driver itself (§3.4), so a caller
|
|
6
|
+
* can hand in their own handle (an in-memory one for tests, a tuned one for
|
|
7
|
+
* production). */
|
|
8
|
+
export interface SqliteLike {
|
|
9
|
+
prepare(sql: string): SqliteStatementLike;
|
|
10
|
+
exec?(sql: string): unknown;
|
|
11
|
+
run?(sql: string): unknown;
|
|
12
|
+
}
|
|
13
|
+
export interface SqliteStatementLike {
|
|
14
|
+
all(...params: unknown[]): unknown[];
|
|
15
|
+
get?(...params: unknown[]): unknown;
|
|
16
|
+
run(...params: unknown[]): unknown;
|
|
17
|
+
}
|
|
18
|
+
/** Open a SQLite handle with whichever driver the process has: `bun:sqlite`
|
|
19
|
+
* first, then `node:sqlite`. Preferring one and requiring it are different
|
|
20
|
+
* things — a Next.js server runs on Node even inside a Bun workspace, which
|
|
21
|
+
* is exactly where a bun-only store fails. Pass ':memory:' for a database
|
|
22
|
+
* that lives only as long as the process.
|
|
23
|
+
*
|
|
24
|
+
* Imported dynamically so neither driver enters the module graph until asked
|
|
25
|
+
* for: importing this file is safe anywhere, only calling this needs one. */
|
|
26
|
+
export declare function openSqlite(filename?: string): Promise<SqliteLike>;
|
|
27
|
+
/** A complete Storage over SQLite (§3.2) — every table the platform needs,
|
|
28
|
+
* created on construction. This is what `dev: true` wires up: a working
|
|
29
|
+
* agent platform with no infrastructure to stand up first. */
|
|
30
|
+
export declare class SqliteStorage implements Storage {
|
|
31
|
+
private readonly db;
|
|
32
|
+
constructor(db: SqliteLike);
|
|
33
|
+
private all;
|
|
34
|
+
private one;
|
|
35
|
+
private write;
|
|
36
|
+
private toThread;
|
|
37
|
+
private toMessage;
|
|
38
|
+
private toEvent;
|
|
39
|
+
threads: {
|
|
40
|
+
get: (threadId: string) => Promise<ThreadDTO | null>;
|
|
41
|
+
create: (init?: {
|
|
42
|
+
model?: string;
|
|
43
|
+
}) => Promise<ThreadDTO>;
|
|
44
|
+
list: () => Promise<ThreadDTO[]>;
|
|
45
|
+
setState: (threadId: string, state: ExecutionState) => Promise<void>;
|
|
46
|
+
delete: (threadId: string) => Promise<void>;
|
|
47
|
+
claimState: (threadId: string, from: ExecutionState, to: ExecutionState) => Promise<boolean>;
|
|
48
|
+
};
|
|
49
|
+
messages: {
|
|
50
|
+
append: (threadId: string, m: NewMessage) => Promise<MessageDTO>;
|
|
51
|
+
list: (threadId: string, opts?: {
|
|
52
|
+
agentId?: string | null;
|
|
53
|
+
}) => Promise<MessageDTO[]>;
|
|
54
|
+
deleteFrom: (threadId: string, messageId: string) => Promise<number>;
|
|
55
|
+
};
|
|
56
|
+
events: {
|
|
57
|
+
append: (threadId: string, e: AgentEvent) => Promise<void>;
|
|
58
|
+
listSince: (threadId: string, sinceSeq: number) => Promise<AgentEvent[]>;
|
|
59
|
+
latest: (threadId: string, type: string) => Promise<AgentEvent | null>;
|
|
60
|
+
listByType: (threadId: string, type: string) => Promise<AgentEvent[]>;
|
|
61
|
+
};
|
|
62
|
+
usage: {
|
|
63
|
+
record: (threadId: string, u: NewUsage) => Promise<void>;
|
|
64
|
+
total: (threadId: string) => Promise<UsageTotals>;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/adapters/sqlite.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EACrF,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;mBAImB;AACnB,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAAC;IAC1C,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IACrC,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACpC,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;CACpC;AAED;;;;;;;8EAO8E;AAC9E,wBAAsB,UAAU,CAAC,QAAQ,SAAuB,GAAG,OAAO,CAAC,UAAU,CAAC,CAmBrF;AA+CD;;+DAE+D;AAC/D,qBAAa,aAAc,YAAW,OAAO;IAC/B,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,UAAU;IAO3C,OAAO,CAAC,GAAG;IAGX,OAAO,CAAC,GAAG;IAGX,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,QAAQ,CAGb;IACH,OAAO,CAAC,SAAS,CAGd;IACH,OAAO,CAAC,OAAO,CAGE;IACjB,OAAO;wBACiB,MAAM;wBAIN;YAAE,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE;;6BAab,MAAM,SAAS,cAAc;2BAI/B,MAAM;+BAQF,MAAM,QAAQ,cAAc,MAAM,cAAc;MAU7E;IAEF,QAAQ;2BACmB,MAAM,KAAK,UAAU;yBAiBvB,MAAM,SAAS;YAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE;+BAYpC,MAAM,aAAa,MAAM;MAStD;IAEF,MAAM;2BACqB,MAAM,KAAK,UAAU;8BAIlB,MAAM,YAAY,MAAM;2BAG3B,MAAM,QAAQ,MAAM;+BAMhB,MAAM,QAAQ,MAAM;MAGjD;IAEF,KAAK;2BACsB,MAAM,KAAK,QAAQ;0BAOpB,MAAM,KAAG,OAAO,CAAC,WAAW,CAAC;MAUrD;CAIH"}
|