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.
Files changed (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/dist/adapters/inline.d.ts +27 -0
  4. package/dist/adapters/inline.d.ts.map +1 -0
  5. package/dist/adapters/inline.js +41 -0
  6. package/dist/adapters/inline.js.map +1 -0
  7. package/dist/adapters/memory.d.ts +74 -0
  8. package/dist/adapters/memory.d.ts.map +1 -0
  9. package/dist/adapters/memory.js +194 -0
  10. package/dist/adapters/memory.js.map +1 -0
  11. package/dist/adapters/prisma.d.ts +176 -0
  12. package/dist/adapters/prisma.d.ts.map +1 -0
  13. package/dist/adapters/prisma.js +107 -0
  14. package/dist/adapters/prisma.js.map +1 -0
  15. package/dist/adapters/qstash.d.ts +36 -0
  16. package/dist/adapters/qstash.d.ts.map +1 -0
  17. package/dist/adapters/qstash.js +26 -0
  18. package/dist/adapters/qstash.js.map +1 -0
  19. package/dist/adapters/redis.d.ts +49 -0
  20. package/dist/adapters/redis.d.ts.map +1 -0
  21. package/dist/adapters/redis.js +60 -0
  22. package/dist/adapters/redis.js.map +1 -0
  23. package/dist/adapters/sqlite.d.ts +67 -0
  24. package/dist/adapters/sqlite.d.ts.map +1 -0
  25. package/dist/adapters/sqlite.js +199 -0
  26. package/dist/adapters/sqlite.js.map +1 -0
  27. package/dist/adapters/upstash.d.ts +48 -0
  28. package/dist/adapters/upstash.d.ts.map +1 -0
  29. package/dist/adapters/upstash.js +46 -0
  30. package/dist/adapters/upstash.js.map +1 -0
  31. package/dist/admin/default.d.ts +15 -0
  32. package/dist/admin/default.d.ts.map +1 -0
  33. package/dist/admin/default.js +22 -0
  34. package/dist/admin/default.js.map +1 -0
  35. package/dist/admin/memory.d.ts +29 -0
  36. package/dist/admin/memory.d.ts.map +1 -0
  37. package/dist/admin/memory.js +83 -0
  38. package/dist/admin/memory.js.map +1 -0
  39. package/dist/admin/postgres.d.ts +43 -0
  40. package/dist/admin/postgres.d.ts.map +1 -0
  41. package/dist/admin/postgres.js +201 -0
  42. package/dist/admin/postgres.js.map +1 -0
  43. package/dist/admin/sqlite.d.ts +35 -0
  44. package/dist/admin/sqlite.d.ts.map +1 -0
  45. package/dist/admin/sqlite.js +187 -0
  46. package/dist/admin/sqlite.js.map +1 -0
  47. package/dist/core/admin.d.ts +88 -0
  48. package/dist/core/admin.d.ts.map +1 -0
  49. package/dist/core/admin.js +147 -0
  50. package/dist/core/admin.js.map +1 -0
  51. package/dist/core/agent.d.ts +29 -0
  52. package/dist/core/agent.d.ts.map +1 -0
  53. package/dist/core/agent.js +41 -0
  54. package/dist/core/agent.js.map +1 -0
  55. package/dist/core/cache.d.ts +37 -0
  56. package/dist/core/cache.d.ts.map +1 -0
  57. package/dist/core/cache.js +68 -0
  58. package/dist/core/cache.js.map +1 -0
  59. package/dist/core/context.d.ts +13 -0
  60. package/dist/core/context.d.ts.map +1 -0
  61. package/dist/core/context.js +87 -0
  62. package/dist/core/context.js.map +1 -0
  63. package/dist/core/deleteThread.d.ts +14 -0
  64. package/dist/core/deleteThread.d.ts.map +1 -0
  65. package/dist/core/deleteThread.js +34 -0
  66. package/dist/core/deleteThread.js.map +1 -0
  67. package/dist/core/engine.d.ts +79 -0
  68. package/dist/core/engine.d.ts.map +1 -0
  69. package/dist/core/engine.js +489 -0
  70. package/dist/core/engine.js.map +1 -0
  71. package/dist/core/follow.d.ts +50 -0
  72. package/dist/core/follow.d.ts.map +1 -0
  73. package/dist/core/follow.js +153 -0
  74. package/dist/core/follow.js.map +1 -0
  75. package/dist/core/hitl.d.ts +98 -0
  76. package/dist/core/hitl.d.ts.map +1 -0
  77. package/dist/core/hitl.js +199 -0
  78. package/dist/core/hitl.js.map +1 -0
  79. package/dist/core/keys.d.ts +26 -0
  80. package/dist/core/keys.d.ts.map +1 -0
  81. package/dist/core/keys.js +32 -0
  82. package/dist/core/keys.js.map +1 -0
  83. package/dist/core/loop.d.ts +105 -0
  84. package/dist/core/loop.d.ts.map +1 -0
  85. package/dist/core/loop.js +234 -0
  86. package/dist/core/loop.js.map +1 -0
  87. package/dist/core/publish.d.ts +18 -0
  88. package/dist/core/publish.d.ts.map +1 -0
  89. package/dist/core/publish.js +34 -0
  90. package/dist/core/publish.js.map +1 -0
  91. package/dist/core/reclaim.d.ts +20 -0
  92. package/dist/core/reclaim.d.ts.map +1 -0
  93. package/dist/core/reclaim.js +56 -0
  94. package/dist/core/reclaim.js.map +1 -0
  95. package/dist/core/run.d.ts +8 -0
  96. package/dist/core/run.d.ts.map +1 -0
  97. package/dist/core/run.js +102 -0
  98. package/dist/core/run.js.map +1 -0
  99. package/dist/core/state.d.ts +50 -0
  100. package/dist/core/state.d.ts.map +1 -0
  101. package/dist/core/state.js +39 -0
  102. package/dist/core/state.js.map +1 -0
  103. package/dist/core/stop.d.ts +7 -0
  104. package/dist/core/stop.d.ts.map +1 -0
  105. package/dist/core/stop.js +15 -0
  106. package/dist/core/stop.js.map +1 -0
  107. package/dist/core/stream.d.ts +12 -0
  108. package/dist/core/stream.d.ts.map +1 -0
  109. package/dist/core/stream.js +21 -0
  110. package/dist/core/stream.js.map +1 -0
  111. package/dist/core/subagent.d.ts +77 -0
  112. package/dist/core/subagent.d.ts.map +1 -0
  113. package/dist/core/subagent.js +261 -0
  114. package/dist/core/subagent.js.map +1 -0
  115. package/dist/core/tools.d.ts +36 -0
  116. package/dist/core/tools.d.ts.map +1 -0
  117. package/dist/core/tools.js +22 -0
  118. package/dist/core/tools.js.map +1 -0
  119. package/dist/core/types.d.ts +286 -0
  120. package/dist/core/types.d.ts.map +1 -0
  121. package/dist/core/types.js +49 -0
  122. package/dist/core/types.js.map +1 -0
  123. package/dist/core/usage.d.ts +40 -0
  124. package/dist/core/usage.d.ts.map +1 -0
  125. package/dist/core/usage.js +43 -0
  126. package/dist/core/usage.js.map +1 -0
  127. package/dist/index.d.ts +25 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +23 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/ports/admin.d.ts +102 -0
  132. package/dist/ports/admin.d.ts.map +1 -0
  133. package/dist/ports/admin.js +2 -0
  134. package/dist/ports/admin.js.map +1 -0
  135. package/dist/ports/bus.d.ts +13 -0
  136. package/dist/ports/bus.d.ts.map +1 -0
  137. package/dist/ports/bus.js +2 -0
  138. package/dist/ports/bus.js.map +1 -0
  139. package/dist/ports/kv.d.ts +16 -0
  140. package/dist/ports/kv.d.ts.map +1 -0
  141. package/dist/ports/kv.js +2 -0
  142. package/dist/ports/kv.js.map +1 -0
  143. package/dist/ports/queue.d.ts +18 -0
  144. package/dist/ports/queue.d.ts.map +1 -0
  145. package/dist/ports/queue.js +2 -0
  146. package/dist/ports/queue.js.map +1 -0
  147. package/dist/ports/runtime.d.ts +260 -0
  148. package/dist/ports/runtime.d.ts.map +1 -0
  149. package/dist/ports/runtime.js +2 -0
  150. package/dist/ports/runtime.js.map +1 -0
  151. package/dist/ports/storage.d.ts +72 -0
  152. package/dist/ports/storage.d.ts.map +1 -0
  153. package/dist/ports/storage.js +2 -0
  154. package/dist/ports/storage.js.map +1 -0
  155. package/dist/runtime.d.ts +5 -0
  156. package/dist/runtime.d.ts.map +1 -0
  157. package/dist/runtime.js +177 -0
  158. package/dist/runtime.js.map +1 -0
  159. 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"}