@honeybee-ai/incubator 1.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/README.md +586 -0
- package/dashboard/dist/assets/index-DFb8p7xI.js +9 -0
- package/dashboard/dist/assets/index-RKiEoHEo.css +1 -0
- package/dashboard/dist/index.html +13 -0
- package/dist/agent/acp/claim-manager.d.ts +24 -0
- package/dist/agent/acp/claim-manager.js +64 -0
- package/dist/agent/acp/claim-manager.js.map +1 -0
- package/dist/agent/acp/direct-runtime.d.ts +90 -0
- package/dist/agent/acp/direct-runtime.js +364 -0
- package/dist/agent/acp/direct-runtime.js.map +1 -0
- package/dist/agent/acp/event-client.d.ts +20 -0
- package/dist/agent/acp/event-client.js +60 -0
- package/dist/agent/acp/event-client.js.map +1 -0
- package/dist/agent/acp/event-matcher.d.ts +13 -0
- package/dist/agent/acp/event-matcher.js +31 -0
- package/dist/agent/acp/event-matcher.js.map +1 -0
- package/dist/agent/acp/progress.d.ts +23 -0
- package/dist/agent/acp/progress.js +54 -0
- package/dist/agent/acp/progress.js.map +1 -0
- package/dist/agent/acp/runtime.d.ts +156 -0
- package/dist/agent/acp/runtime.js +337 -0
- package/dist/agent/acp/runtime.js.map +1 -0
- package/dist/agent/acp/ws-event-client.d.ts +64 -0
- package/dist/agent/acp/ws-event-client.js +263 -0
- package/dist/agent/acp/ws-event-client.js.map +1 -0
- package/dist/agent/agent.d.ts +60 -0
- package/dist/agent/agent.js +121 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/cli.d.ts +2 -0
- package/dist/agent/cli.js +311 -0
- package/dist/agent/cli.js.map +1 -0
- package/dist/agent/mcp-client.d.ts +37 -0
- package/dist/agent/mcp-client.js +92 -0
- package/dist/agent/mcp-client.js.map +1 -0
- package/dist/agent/mock-runner.d.ts +14 -0
- package/dist/agent/mock-runner.js +159 -0
- package/dist/agent/mock-runner.js.map +1 -0
- package/dist/agent/native-client.d.ts +18 -0
- package/dist/agent/native-client.js +42 -0
- package/dist/agent/native-client.js.map +1 -0
- package/dist/agent/prompt.d.ts +45 -0
- package/dist/agent/prompt.js +115 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/agent/providers.d.ts +25 -0
- package/dist/agent/providers.js +696 -0
- package/dist/agent/providers.js.map +1 -0
- package/dist/agent/runner.d.ts +15 -0
- package/dist/agent/runner.js +625 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/agent/tool-client.d.ts +12 -0
- package/dist/agent/tool-client.js +2 -0
- package/dist/agent/tool-client.js.map +1 -0
- package/dist/agent/types.d.ts +116 -0
- package/dist/agent/types.js +2 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/agent-pool.d.ts +44 -0
- package/dist/agent-pool.js +228 -0
- package/dist/agent-pool.js.map +1 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +7 -0
- package/dist/bin.js.map +1 -0
- package/dist/bus.d.ts +24 -0
- package/dist/bus.js +79 -0
- package/dist/bus.js.map +1 -0
- package/dist/dances.d.ts +73 -0
- package/dist/dances.js +122 -0
- package/dist/dances.js.map +1 -0
- package/dist/guard.d.ts +52 -0
- package/dist/guard.js +210 -0
- package/dist/guard.js.map +1 -0
- package/dist/heartbeat.d.ts +41 -0
- package/dist/heartbeat.js +104 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/honeycomb.d.ts +63 -0
- package/dist/honeycomb.js +222 -0
- package/dist/honeycomb.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +601 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/config.d.ts +15 -0
- package/dist/integrations/config.js +62 -0
- package/dist/integrations/config.js.map +1 -0
- package/dist/integrations/index.d.ts +4 -0
- package/dist/integrations/index.js +4 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/loader.d.ts +8 -0
- package/dist/integrations/loader.js +27 -0
- package/dist/integrations/loader.js.map +1 -0
- package/dist/integrations/manager.d.ts +29 -0
- package/dist/integrations/manager.js +108 -0
- package/dist/integrations/manager.js.map +1 -0
- package/dist/log.d.ts +25 -0
- package/dist/log.js +67 -0
- package/dist/log.js.map +1 -0
- package/dist/namespaces.d.ts +28 -0
- package/dist/namespaces.js +100 -0
- package/dist/namespaces.js.map +1 -0
- package/dist/orchestrator.d.ts +119 -0
- package/dist/orchestrator.js +463 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/persistence.d.ts +7 -0
- package/dist/persistence.js +62 -0
- package/dist/persistence.js.map +1 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/loader.d.ts +12 -0
- package/dist/plugins/loader.js +122 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/manager.d.ts +76 -0
- package/dist/plugins/manager.js +238 -0
- package/dist/plugins/manager.js.map +1 -0
- package/dist/propolis/guard.d.ts +23 -0
- package/dist/propolis/guard.js +49 -0
- package/dist/propolis/guard.js.map +1 -0
- package/dist/propolis/tools/types.d.ts +9 -0
- package/dist/propolis/tools/types.js +9 -0
- package/dist/propolis/tools/types.js.map +1 -0
- package/dist/rest.d.ts +4 -0
- package/dist/rest.js +962 -0
- package/dist/rest.js.map +1 -0
- package/dist/run-watcher.d.ts +20 -0
- package/dist/run-watcher.js +74 -0
- package/dist/run-watcher.js.map +1 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.js +412 -0
- package/dist/server.js.map +1 -0
- package/dist/stores/backend.d.ts +15 -0
- package/dist/stores/backend.js +28 -0
- package/dist/stores/backend.js.map +1 -0
- package/dist/stores/claims.d.ts +14 -0
- package/dist/stores/claims.js +77 -0
- package/dist/stores/claims.js.map +1 -0
- package/dist/stores/conflicts.d.ts +10 -0
- package/dist/stores/conflicts.js +39 -0
- package/dist/stores/conflicts.js.map +1 -0
- package/dist/stores/control.d.ts +37 -0
- package/dist/stores/control.js +105 -0
- package/dist/stores/control.js.map +1 -0
- package/dist/stores/discoveries.d.ts +11 -0
- package/dist/stores/discoveries.js +45 -0
- package/dist/stores/discoveries.js.map +1 -0
- package/dist/stores/events.d.ts +14 -0
- package/dist/stores/events.js +42 -0
- package/dist/stores/events.js.map +1 -0
- package/dist/stores/help.d.ts +11 -0
- package/dist/stores/help.js +46 -0
- package/dist/stores/help.js.map +1 -0
- package/dist/stores/interfaces.d.ts +125 -0
- package/dist/stores/interfaces.js +2 -0
- package/dist/stores/interfaces.js.map +1 -0
- package/dist/stores/messages.d.ts +8 -0
- package/dist/stores/messages.js +29 -0
- package/dist/stores/messages.js.map +1 -0
- package/dist/stores/progress.d.ts +8 -0
- package/dist/stores/progress.js +21 -0
- package/dist/stores/progress.js.map +1 -0
- package/dist/stores/proposals.d.ts +11 -0
- package/dist/stores/proposals.js +46 -0
- package/dist/stores/proposals.js.map +1 -0
- package/dist/stores/redis/claims.d.ts +16 -0
- package/dist/stores/redis/claims.js +126 -0
- package/dist/stores/redis/claims.js.map +1 -0
- package/dist/stores/redis/db.d.ts +39 -0
- package/dist/stores/redis/db.js +34 -0
- package/dist/stores/redis/db.js.map +1 -0
- package/dist/stores/redis/discoveries.d.ts +13 -0
- package/dist/stores/redis/discoveries.js +54 -0
- package/dist/stores/redis/discoveries.js.map +1 -0
- package/dist/stores/redis/events.d.ts +17 -0
- package/dist/stores/redis/events.js +57 -0
- package/dist/stores/redis/events.js.map +1 -0
- package/dist/stores/redis/index.d.ts +3 -0
- package/dist/stores/redis/index.js +31 -0
- package/dist/stores/redis/index.js.map +1 -0
- package/dist/stores/redis/state.d.ts +14 -0
- package/dist/stores/redis/state.js +83 -0
- package/dist/stores/redis/state.js.map +1 -0
- package/dist/stores/reinforcements.d.ts +11 -0
- package/dist/stores/reinforcements.js +42 -0
- package/dist/stores/reinforcements.js.map +1 -0
- package/dist/stores/roles.d.ts +9 -0
- package/dist/stores/roles.js +22 -0
- package/dist/stores/roles.js.map +1 -0
- package/dist/stores/runs.d.ts +15 -0
- package/dist/stores/runs.js +50 -0
- package/dist/stores/runs.js.map +1 -0
- package/dist/stores/sqlite/claims.d.ts +17 -0
- package/dist/stores/sqlite/claims.js +121 -0
- package/dist/stores/sqlite/claims.js.map +1 -0
- package/dist/stores/sqlite/db.d.ts +16 -0
- package/dist/stores/sqlite/db.js +77 -0
- package/dist/stores/sqlite/db.js.map +1 -0
- package/dist/stores/sqlite/discoveries.d.ts +14 -0
- package/dist/stores/sqlite/discoveries.js +66 -0
- package/dist/stores/sqlite/discoveries.js.map +1 -0
- package/dist/stores/sqlite/events.d.ts +16 -0
- package/dist/stores/sqlite/events.js +75 -0
- package/dist/stores/sqlite/events.js.map +1 -0
- package/dist/stores/sqlite/index.d.ts +2 -0
- package/dist/stores/sqlite/index.js +33 -0
- package/dist/stores/sqlite/index.js.map +1 -0
- package/dist/stores/sqlite/state.d.ts +15 -0
- package/dist/stores/sqlite/state.js +99 -0
- package/dist/stores/sqlite/state.js.map +1 -0
- package/dist/stores/state.d.ts +11 -0
- package/dist/stores/state.js +67 -0
- package/dist/stores/state.js.map +1 -0
- package/dist/transports/broker.d.ts +20 -0
- package/dist/transports/broker.js +102 -0
- package/dist/transports/broker.js.map +1 -0
- package/dist/transports/index.d.ts +3 -0
- package/dist/transports/index.js +3 -0
- package/dist/transports/index.js.map +1 -0
- package/dist/transports/ipc.d.ts +26 -0
- package/dist/transports/ipc.js +93 -0
- package/dist/transports/ipc.js.map +1 -0
- package/dist/transports/types.d.ts +39 -0
- package/dist/transports/types.js +8 -0
- package/dist/transports/types.js.map +1 -0
- package/dist/types.d.ts +45 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +36 -0
- package/dist/utils.js.map +1 -0
- package/dist/waggle/client.d.ts +16 -0
- package/dist/waggle/client.js +28 -0
- package/dist/waggle/client.js.map +1 -0
- package/dist/waggle/compound.d.ts +22 -0
- package/dist/waggle/compound.js +194 -0
- package/dist/waggle/compound.js.map +1 -0
- package/dist/waggle/index.d.ts +25 -0
- package/dist/waggle/index.js +77 -0
- package/dist/waggle/index.js.map +1 -0
- package/dist/waggle/types.d.ts +54 -0
- package/dist/waggle/types.js +2 -0
- package/dist/waggle/types.js.map +1 -0
- package/dist/webhooks.d.ts +26 -0
- package/dist/webhooks.js +79 -0
- package/dist/webhooks.js.map +1 -0
- package/dist/ws.d.ts +33 -0
- package/dist/ws.js +195 -0
- package/dist/ws.js.map +1 -0
- package/package.json +122 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { StateEntry, Claim, IncubatorEvent, Discovery, ClaimResult, Message, HelpRequest, ProgressReport, Conflict, RoleAssignment, ReinforcementRequest, Proposal } from '../types.js';
|
|
2
|
+
import type { ControlStore } from './control.js';
|
|
3
|
+
export interface IStateStore {
|
|
4
|
+
get(key: string): Promise<StateEntry | null>;
|
|
5
|
+
set(key: string, value: unknown, agentId: string, category?: string, ttlMs?: number): Promise<StateEntry>;
|
|
6
|
+
delete(key: string): Promise<boolean>;
|
|
7
|
+
query(pattern?: string, category?: string): Promise<StateEntry[]>;
|
|
8
|
+
getAll(): Promise<StateEntry[]>;
|
|
9
|
+
load(entries: StateEntry[]): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export interface IEventStore {
|
|
12
|
+
publish(type: string, data: unknown, agentId: string): Promise<IncubatorEvent>;
|
|
13
|
+
getEvents(since?: number, type?: string): Promise<{
|
|
14
|
+
events: IncubatorEvent[];
|
|
15
|
+
cursor: number;
|
|
16
|
+
}>;
|
|
17
|
+
getCursor(): Promise<number>;
|
|
18
|
+
getAll(): Promise<IncubatorEvent[]>;
|
|
19
|
+
load(events: IncubatorEvent[], cursor: number): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export interface IClaimStore {
|
|
22
|
+
claim(resource: string, value: string, agentId: string, ttlMs?: number): Promise<ClaimResult>;
|
|
23
|
+
release(resource: string, agentId: string): Promise<Claim | null>;
|
|
24
|
+
check(resource: string): Promise<Claim | null>;
|
|
25
|
+
list(pattern?: string): Promise<Claim[]>;
|
|
26
|
+
getAll(): Promise<Claim[]>;
|
|
27
|
+
load(claims: Claim[]): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export interface IDiscoveryStore {
|
|
30
|
+
publish(topic: string, content: string, agentId: string, category?: string): Promise<Discovery>;
|
|
31
|
+
search(query?: string, category?: string): Promise<Discovery[]>;
|
|
32
|
+
getAll(): Promise<Discovery[]>;
|
|
33
|
+
load(discoveries: Discovery[]): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export interface IMessageStore {
|
|
36
|
+
send(from: string, to: string, content: string, replyTo?: string): Promise<Message>;
|
|
37
|
+
getFor(agentId: string, since?: string): Promise<Message[]>;
|
|
38
|
+
getAll(): Promise<Message[]>;
|
|
39
|
+
}
|
|
40
|
+
export interface IHelpStore {
|
|
41
|
+
request(from: string, problem: string, needs_capability?: string, urgency?: 'low' | 'normal' | 'high'): Promise<HelpRequest>;
|
|
42
|
+
claim(requestId: string, agentId: string): Promise<HelpRequest | null>;
|
|
43
|
+
resolve(requestId: string, agentId: string): Promise<HelpRequest | null>;
|
|
44
|
+
list(status?: string): Promise<HelpRequest[]>;
|
|
45
|
+
}
|
|
46
|
+
export interface IProgressStore {
|
|
47
|
+
report(claim: string, agentId: string, progress: number, note?: string): Promise<ProgressReport>;
|
|
48
|
+
get(claim: string): Promise<ProgressReport | null>;
|
|
49
|
+
list(): Promise<ProgressReport[]>;
|
|
50
|
+
}
|
|
51
|
+
export interface IConflictStore {
|
|
52
|
+
flag(agentId: string, discovery_a: string, discovery_b: string, reason: string): Promise<Conflict>;
|
|
53
|
+
resolve(conflictId: string, agentId: string, resolution: string): Promise<Conflict | null>;
|
|
54
|
+
list(status?: string): Promise<Conflict[]>;
|
|
55
|
+
}
|
|
56
|
+
export interface IRoleStore {
|
|
57
|
+
assign(agentId: string, role: string): Promise<RoleAssignment>;
|
|
58
|
+
getAssignments(): Promise<RoleAssignment[]>;
|
|
59
|
+
getByAgent(agentId: string): Promise<RoleAssignment | null>;
|
|
60
|
+
remove(agentId: string): Promise<boolean>;
|
|
61
|
+
}
|
|
62
|
+
export interface IProposalStore {
|
|
63
|
+
propose(agentId: string, action: string, detail?: string, quorum?: number): Promise<Proposal>;
|
|
64
|
+
endorse(proposalId: string, agentId: string): Promise<Proposal | null>;
|
|
65
|
+
list(status?: string): Promise<Proposal[]>;
|
|
66
|
+
get(proposalId: string): Promise<Proposal | null>;
|
|
67
|
+
}
|
|
68
|
+
export interface IReinforcementStore {
|
|
69
|
+
request(agentId: string, role: string, count: number, reason?: string): Promise<ReinforcementRequest>;
|
|
70
|
+
approve(requestId: string): Promise<ReinforcementRequest | null>;
|
|
71
|
+
deny(requestId: string, reason: string): Promise<ReinforcementRequest | null>;
|
|
72
|
+
list(): Promise<ReinforcementRequest[]>;
|
|
73
|
+
}
|
|
74
|
+
export interface IterationDetail {
|
|
75
|
+
index: number;
|
|
76
|
+
promptTokens: number;
|
|
77
|
+
completionTokens: number;
|
|
78
|
+
totalTokens: number;
|
|
79
|
+
timestamp: string;
|
|
80
|
+
}
|
|
81
|
+
export interface AgentRun {
|
|
82
|
+
agentId: string;
|
|
83
|
+
role: string;
|
|
84
|
+
status: 'running' | 'completed' | 'error' | 'halted';
|
|
85
|
+
startedAt: string;
|
|
86
|
+
completedAt?: string;
|
|
87
|
+
elapsed?: number;
|
|
88
|
+
iterations?: number;
|
|
89
|
+
usage?: {
|
|
90
|
+
promptTokens: number;
|
|
91
|
+
completionTokens: number;
|
|
92
|
+
totalTokens: number;
|
|
93
|
+
};
|
|
94
|
+
iterationDetails?: IterationDetail[];
|
|
95
|
+
summary?: string;
|
|
96
|
+
error?: string;
|
|
97
|
+
}
|
|
98
|
+
export interface IRunStore {
|
|
99
|
+
start(agentId: string, role: string): Promise<AgentRun>;
|
|
100
|
+
complete(agentId: string, data: Partial<AgentRun>): Promise<AgentRun | null>;
|
|
101
|
+
get(agentId: string): Promise<AgentRun | null>;
|
|
102
|
+
list(status?: string): Promise<AgentRun[]>;
|
|
103
|
+
summary(): Promise<{
|
|
104
|
+
agents: number;
|
|
105
|
+
completed: number;
|
|
106
|
+
errors: number;
|
|
107
|
+
totalTokens: number;
|
|
108
|
+
totalDuration: number;
|
|
109
|
+
}>;
|
|
110
|
+
}
|
|
111
|
+
export interface Stores {
|
|
112
|
+
state: IStateStore;
|
|
113
|
+
events: IEventStore;
|
|
114
|
+
claims: IClaimStore;
|
|
115
|
+
discoveries: IDiscoveryStore;
|
|
116
|
+
messages: IMessageStore;
|
|
117
|
+
help: IHelpStore;
|
|
118
|
+
progress: IProgressStore;
|
|
119
|
+
conflicts: IConflictStore;
|
|
120
|
+
roles: IRoleStore;
|
|
121
|
+
proposals: IProposalStore;
|
|
122
|
+
reinforcements: IReinforcementStore;
|
|
123
|
+
control: ControlStore;
|
|
124
|
+
runs: IRunStore;
|
|
125
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/stores/interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Message } from '../types.js';
|
|
2
|
+
import type { IMessageStore } from './interfaces.js';
|
|
3
|
+
export declare class MessageStore implements IMessageStore {
|
|
4
|
+
private messages;
|
|
5
|
+
send(from: string, to: string, content: string, replyTo?: string): Promise<Message>;
|
|
6
|
+
getFor(agentId: string, since?: string): Promise<Message[]>;
|
|
7
|
+
getAll(): Promise<Message[]>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
export class MessageStore {
|
|
3
|
+
messages = [];
|
|
4
|
+
async send(from, to, content, replyTo) {
|
|
5
|
+
const msg = {
|
|
6
|
+
id: randomBytes(8).toString('hex'),
|
|
7
|
+
from,
|
|
8
|
+
to,
|
|
9
|
+
content,
|
|
10
|
+
replyTo,
|
|
11
|
+
sentAt: new Date().toISOString(),
|
|
12
|
+
};
|
|
13
|
+
this.messages.push(msg);
|
|
14
|
+
return msg;
|
|
15
|
+
}
|
|
16
|
+
async getFor(agentId, since) {
|
|
17
|
+
return this.messages.filter(m => {
|
|
18
|
+
if (m.to !== agentId)
|
|
19
|
+
return false;
|
|
20
|
+
if (since && m.sentAt <= since)
|
|
21
|
+
return false;
|
|
22
|
+
return true;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
async getAll() {
|
|
26
|
+
return [...this.messages];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/stores/messages.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,OAAO,YAAY;IACf,QAAQ,GAAc,EAAE,CAAC;IAEjC,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,EAAU,EAAE,OAAe,EAAE,OAAgB;QACpE,MAAM,GAAG,GAAY;YACnB,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;YAClC,IAAI;YACJ,EAAE;YACF,OAAO;YACP,OAAO;YACP,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACjC,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,KAAc;QAC1C,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YAC9B,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO;gBAAE,OAAO,KAAK,CAAC;YACnC,IAAI,KAAK,IAAI,CAAC,CAAC,MAAM,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;YAC7C,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM;QACV,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProgressReport } from '../types.js';
|
|
2
|
+
import type { IProgressStore } from './interfaces.js';
|
|
3
|
+
export declare class ProgressStore implements IProgressStore {
|
|
4
|
+
private reports;
|
|
5
|
+
report(claim: string, agentId: string, progress: number, note?: string): Promise<ProgressReport>;
|
|
6
|
+
get(claim: string): Promise<ProgressReport | null>;
|
|
7
|
+
list(): Promise<ProgressReport[]>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export class ProgressStore {
|
|
2
|
+
reports = new Map();
|
|
3
|
+
async report(claim, agentId, progress, note) {
|
|
4
|
+
const report = {
|
|
5
|
+
claim,
|
|
6
|
+
agent: agentId,
|
|
7
|
+
progress: Math.max(0, Math.min(1, progress)),
|
|
8
|
+
note,
|
|
9
|
+
updatedAt: new Date().toISOString(),
|
|
10
|
+
};
|
|
11
|
+
this.reports.set(claim, report);
|
|
12
|
+
return report;
|
|
13
|
+
}
|
|
14
|
+
async get(claim) {
|
|
15
|
+
return this.reports.get(claim) ?? null;
|
|
16
|
+
}
|
|
17
|
+
async list() {
|
|
18
|
+
return [...this.reports.values()];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/stores/progress.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,aAAa;IAChB,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEpD,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,OAAe,EAAE,QAAgB,EAAE,IAAa;QAC1E,MAAM,MAAM,GAAmB;YAC7B,KAAK;YACL,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;YAC5C,IAAI;YACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAChC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAa;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Proposal } from '../types.js';
|
|
2
|
+
import type { IProposalStore, IEventStore } from './interfaces.js';
|
|
3
|
+
export declare class ProposalStore implements IProposalStore {
|
|
4
|
+
private proposals;
|
|
5
|
+
private eventStore;
|
|
6
|
+
constructor(eventStore: IEventStore);
|
|
7
|
+
propose(agentId: string, action: string, detail?: string, quorum?: number): Promise<Proposal>;
|
|
8
|
+
endorse(proposalId: string, agentId: string): Promise<Proposal | null>;
|
|
9
|
+
list(status?: string): Promise<Proposal[]>;
|
|
10
|
+
get(proposalId: string): Promise<Proposal | null>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
export class ProposalStore {
|
|
3
|
+
proposals = new Map();
|
|
4
|
+
eventStore;
|
|
5
|
+
constructor(eventStore) {
|
|
6
|
+
this.eventStore = eventStore;
|
|
7
|
+
}
|
|
8
|
+
async propose(agentId, action, detail, quorum) {
|
|
9
|
+
const proposal = {
|
|
10
|
+
id: randomBytes(8).toString('hex'),
|
|
11
|
+
proposedBy: agentId,
|
|
12
|
+
action,
|
|
13
|
+
detail,
|
|
14
|
+
requires_quorum: quorum ?? 2,
|
|
15
|
+
endorsements: [agentId],
|
|
16
|
+
status: 'open',
|
|
17
|
+
createdAt: new Date().toISOString(),
|
|
18
|
+
};
|
|
19
|
+
this.proposals.set(proposal.id, proposal);
|
|
20
|
+
await this.eventStore.publish('governance.proposal.created', { proposal_id: proposal.id, action, proposedBy: agentId, requires_quorum: proposal.requires_quorum }, agentId);
|
|
21
|
+
return proposal;
|
|
22
|
+
}
|
|
23
|
+
async endorse(proposalId, agentId) {
|
|
24
|
+
const proposal = this.proposals.get(proposalId);
|
|
25
|
+
if (!proposal || proposal.status !== 'open')
|
|
26
|
+
return null;
|
|
27
|
+
if (!proposal.endorsements.includes(agentId)) {
|
|
28
|
+
proposal.endorsements.push(agentId);
|
|
29
|
+
}
|
|
30
|
+
if (proposal.endorsements.length >= proposal.requires_quorum) {
|
|
31
|
+
proposal.status = 'approved';
|
|
32
|
+
await this.eventStore.publish('governance.proposal.approved', { proposal_id: proposalId, action: proposal.action, endorsements: proposal.endorsements }, agentId);
|
|
33
|
+
}
|
|
34
|
+
return proposal;
|
|
35
|
+
}
|
|
36
|
+
async list(status) {
|
|
37
|
+
const all = [...this.proposals.values()];
|
|
38
|
+
if (!status)
|
|
39
|
+
return all;
|
|
40
|
+
return all.filter(p => p.status === status);
|
|
41
|
+
}
|
|
42
|
+
async get(proposalId) {
|
|
43
|
+
return this.proposals.get(proposalId) ?? null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=proposals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposals.js","sourceRoot":"","sources":["../../src/stores/proposals.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,OAAO,aAAa;IAChB,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IACxC,UAAU,CAAc;IAEhC,YAAY,UAAuB;QACjC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,MAAc,EAAE,MAAe,EAAE,MAAe;QAC7E,MAAM,QAAQ,GAAa;YACzB,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;YAClC,UAAU,EAAE,OAAO;YACnB,MAAM;YACN,MAAM;YACN,eAAe,EAAE,MAAM,IAAI,CAAC;YAC5B,YAAY,EAAE,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC1C,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,6BAA6B,EAAE,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,CAAC,eAAe,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5K,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,UAAkB,EAAE,OAAe;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QACzD,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,QAAQ,CAAC,YAAY,CAAC,MAAM,IAAI,QAAQ,CAAC,eAAe,EAAE,CAAC;YAC7D,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC;YAC7B,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,8BAA8B,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE,EAAE,OAAO,CAAC,CAAC;QACpK,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAe;QACxB,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC;QACxB,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,UAAkB;QAC1B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;IAChD,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Claim, ClaimResult } from '../../types.js';
|
|
2
|
+
import type { IClaimStore, IEventStore } from '../interfaces.js';
|
|
3
|
+
import type { Redis } from './db.js';
|
|
4
|
+
export declare class RedisClaimStore implements IClaimStore {
|
|
5
|
+
private client;
|
|
6
|
+
private hashKey;
|
|
7
|
+
private eventStore;
|
|
8
|
+
constructor(client: Redis, namespace: string, eventStore: IEventStore);
|
|
9
|
+
private static CLAIM_SCRIPT;
|
|
10
|
+
claim(resource: string, value: string, agentId: string, ttlMs?: number): Promise<ClaimResult>;
|
|
11
|
+
release(resource: string, agentId: string): Promise<Claim | null>;
|
|
12
|
+
check(resource: string): Promise<Claim | null>;
|
|
13
|
+
list(pattern?: string): Promise<Claim[]>;
|
|
14
|
+
getAll(): Promise<Claim[]>;
|
|
15
|
+
load(claims: Claim[]): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { matchGlob, isExpired } from '../../utils.js';
|
|
2
|
+
export class RedisClaimStore {
|
|
3
|
+
client;
|
|
4
|
+
hashKey;
|
|
5
|
+
eventStore;
|
|
6
|
+
constructor(client, namespace, eventStore) {
|
|
7
|
+
this.client = client;
|
|
8
|
+
this.hashKey = `incubator:${namespace}:claims`;
|
|
9
|
+
this.eventStore = eventStore;
|
|
10
|
+
}
|
|
11
|
+
// Lua script for atomic claim check-and-set
|
|
12
|
+
// KEYS[1] = hash key, ARGV[1] = resource, ARGV[2] = new claim JSON,
|
|
13
|
+
// ARGV[3] = agentId, ARGV[4] = now (epoch ms)
|
|
14
|
+
static CLAIM_SCRIPT = `
|
|
15
|
+
local raw = redis.call('HGET', KEYS[1], ARGV[1])
|
|
16
|
+
if raw then
|
|
17
|
+
local existing = cjson.decode(raw)
|
|
18
|
+
if existing.status == 'active' then
|
|
19
|
+
-- Check if existing claim has expired
|
|
20
|
+
local ttl = tonumber(existing.ttlMs or 0)
|
|
21
|
+
if ttl and ttl > 0 and existing.claimedAt then
|
|
22
|
+
-- Parse ISO date to epoch ms (compare with ARGV[4])
|
|
23
|
+
-- claimedAtMs is stored alongside for Lua comparison
|
|
24
|
+
local createdMs = tonumber(existing.claimedAtMs or 0)
|
|
25
|
+
if createdMs > 0 and (tonumber(ARGV[4]) > createdMs + ttl) then
|
|
26
|
+
-- expired, allow claim through
|
|
27
|
+
elseif existing.owner ~= ARGV[3] then
|
|
28
|
+
return raw
|
|
29
|
+
end
|
|
30
|
+
elseif existing.owner ~= ARGV[3] then
|
|
31
|
+
return raw
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
redis.call('HSET', KEYS[1], ARGV[1], ARGV[2])
|
|
36
|
+
return nil
|
|
37
|
+
`;
|
|
38
|
+
async claim(resource, value, agentId, ttlMs) {
|
|
39
|
+
const now = new Date();
|
|
40
|
+
const claim = {
|
|
41
|
+
resource,
|
|
42
|
+
value,
|
|
43
|
+
owner: agentId,
|
|
44
|
+
status: 'active',
|
|
45
|
+
claimedAt: now.toISOString(),
|
|
46
|
+
ttlMs,
|
|
47
|
+
};
|
|
48
|
+
// Store epoch ms for Lua script TTL comparison
|
|
49
|
+
claim.claimedAtMs = now.getTime();
|
|
50
|
+
const claimJson = JSON.stringify(claim);
|
|
51
|
+
// Atomic check-and-set via Lua script
|
|
52
|
+
const result = await this.client.eval(RedisClaimStore.CLAIM_SCRIPT, 1, this.hashKey, resource, claimJson, agentId, String(now.getTime()));
|
|
53
|
+
if (result) {
|
|
54
|
+
// Script returned existing claim data — rejected
|
|
55
|
+
const existing = JSON.parse(result);
|
|
56
|
+
if (existing.owner === agentId) {
|
|
57
|
+
// Same owner re-claiming: update
|
|
58
|
+
existing.value = value;
|
|
59
|
+
existing.ttlMs = ttlMs;
|
|
60
|
+
await this.client.hset(this.hashKey, resource, JSON.stringify(existing));
|
|
61
|
+
return { status: 'approved', claim: existing };
|
|
62
|
+
}
|
|
63
|
+
return { status: 'rejected', claim: existing };
|
|
64
|
+
}
|
|
65
|
+
await this.eventStore.publish('claim.acquired', { resource, value, owner: agentId }, agentId);
|
|
66
|
+
return { status: 'approved', claim };
|
|
67
|
+
}
|
|
68
|
+
async release(resource, agentId) {
|
|
69
|
+
const raw = await this.client.hget(this.hashKey, resource);
|
|
70
|
+
if (!raw)
|
|
71
|
+
return null;
|
|
72
|
+
const claim = JSON.parse(raw);
|
|
73
|
+
if (claim.status !== 'active')
|
|
74
|
+
return null;
|
|
75
|
+
if (claim.owner !== agentId)
|
|
76
|
+
return null;
|
|
77
|
+
claim.status = 'released';
|
|
78
|
+
await this.client.hset(this.hashKey, resource, JSON.stringify(claim));
|
|
79
|
+
await this.eventStore.publish('claim.released', { resource, owner: agentId }, agentId);
|
|
80
|
+
return claim;
|
|
81
|
+
}
|
|
82
|
+
async check(resource) {
|
|
83
|
+
const raw = await this.client.hget(this.hashKey, resource);
|
|
84
|
+
if (!raw)
|
|
85
|
+
return null;
|
|
86
|
+
const claim = JSON.parse(raw);
|
|
87
|
+
if (claim.status === 'active' && isExpired(claim.claimedAt, claim.ttlMs)) {
|
|
88
|
+
claim.status = 'expired';
|
|
89
|
+
await this.client.hset(this.hashKey, resource, JSON.stringify(claim));
|
|
90
|
+
}
|
|
91
|
+
return claim;
|
|
92
|
+
}
|
|
93
|
+
async list(pattern) {
|
|
94
|
+
const all = await this.client.hgetall(this.hashKey);
|
|
95
|
+
const results = [];
|
|
96
|
+
for (const [, raw] of Object.entries(all)) {
|
|
97
|
+
const claim = JSON.parse(raw);
|
|
98
|
+
if (claim.status === 'active' && isExpired(claim.claimedAt, claim.ttlMs)) {
|
|
99
|
+
claim.status = 'expired';
|
|
100
|
+
await this.client.hset(this.hashKey, claim.resource, JSON.stringify(claim));
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (claim.status !== 'active')
|
|
104
|
+
continue;
|
|
105
|
+
if (pattern && !matchGlob(pattern, claim.resource))
|
|
106
|
+
continue;
|
|
107
|
+
results.push(claim);
|
|
108
|
+
}
|
|
109
|
+
return results;
|
|
110
|
+
}
|
|
111
|
+
async getAll() {
|
|
112
|
+
const all = await this.client.hgetall(this.hashKey);
|
|
113
|
+
return Object.values(all).map(raw => JSON.parse(raw));
|
|
114
|
+
}
|
|
115
|
+
async load(claims) {
|
|
116
|
+
await this.client.del(this.hashKey);
|
|
117
|
+
if (claims.length === 0)
|
|
118
|
+
return;
|
|
119
|
+
const data = {};
|
|
120
|
+
for (const claim of claims) {
|
|
121
|
+
data[claim.resource] = JSON.stringify(claim);
|
|
122
|
+
}
|
|
123
|
+
await this.client.hset(this.hashKey, data);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=claims.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claims.js","sourceRoot":"","sources":["../../../src/stores/redis/claims.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface Redis {
|
|
2
|
+
get(key: string): Promise<string | null>;
|
|
3
|
+
set(key: string, value: string): Promise<'OK'>;
|
|
4
|
+
del(...keys: string[]): Promise<number>;
|
|
5
|
+
hget(key: string, field: string): Promise<string | null>;
|
|
6
|
+
hset(key: string, field: string, value: string): Promise<number>;
|
|
7
|
+
hset(key: string, data: Record<string, string>): Promise<number>;
|
|
8
|
+
hdel(key: string, ...fields: string[]): Promise<number>;
|
|
9
|
+
hgetall(key: string): Promise<Record<string, string>>;
|
|
10
|
+
incr(key: string): Promise<number>;
|
|
11
|
+
zadd(key: string, ...args: (string | number)[]): Promise<number>;
|
|
12
|
+
zrangebyscore(key: string, min: string | number, max: string | number): Promise<string[]>;
|
|
13
|
+
zrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
14
|
+
rpush(key: string, ...values: string[]): Promise<number>;
|
|
15
|
+
lrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
16
|
+
multi(): RedisPipeline;
|
|
17
|
+
publish(channel: string, message: string): Promise<number>;
|
|
18
|
+
quit(): Promise<'OK'>;
|
|
19
|
+
status: string;
|
|
20
|
+
duplicate(): Redis;
|
|
21
|
+
}
|
|
22
|
+
export interface RedisPipeline {
|
|
23
|
+
incr(key: string): RedisPipeline;
|
|
24
|
+
set(key: string, value: string): RedisPipeline;
|
|
25
|
+
zadd(key: string, ...args: (string | number)[]): RedisPipeline;
|
|
26
|
+
del(...keys: string[]): RedisPipeline;
|
|
27
|
+
rpush(key: string, ...values: string[]): RedisPipeline;
|
|
28
|
+
hset(key: string, data: Record<string, string>): RedisPipeline;
|
|
29
|
+
exec(): Promise<Array<[Error | null, unknown]> | null>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get or create a Redis client for the given URL.
|
|
33
|
+
* Cached by URL — same URL returns the same client.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getRedisClient(url: string): Redis;
|
|
36
|
+
/**
|
|
37
|
+
* Wait for a Redis client to be ready.
|
|
38
|
+
*/
|
|
39
|
+
export declare function waitForReady(client: Redis): Promise<void>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
const clientCache = new Map();
|
|
3
|
+
/**
|
|
4
|
+
* Get or create a Redis client for the given URL.
|
|
5
|
+
* Cached by URL — same URL returns the same client.
|
|
6
|
+
*/
|
|
7
|
+
export function getRedisClient(url) {
|
|
8
|
+
const cached = clientCache.get(url);
|
|
9
|
+
if (cached)
|
|
10
|
+
return cached;
|
|
11
|
+
const require = createRequire(import.meta.url);
|
|
12
|
+
const IORedis = require('ioredis');
|
|
13
|
+
const client = new IORedis(url);
|
|
14
|
+
clientCache.set(url, client);
|
|
15
|
+
return client;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Wait for a Redis client to be ready.
|
|
19
|
+
*/
|
|
20
|
+
export async function waitForReady(client) {
|
|
21
|
+
if (client.status === 'ready')
|
|
22
|
+
return;
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
const onReady = () => { cleanup(); resolve(); };
|
|
25
|
+
const onError = (err) => { cleanup(); reject(err); };
|
|
26
|
+
const cleanup = () => {
|
|
27
|
+
client.removeListener('ready', onReady);
|
|
28
|
+
client.removeListener('error', onError);
|
|
29
|
+
};
|
|
30
|
+
client.once('ready', onReady);
|
|
31
|
+
client.once('error', onError);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/stores/redis/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAmC5C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAiB,CAAC;AAE7C;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAA+B,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IAEhC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAa;IAC9C,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO;QAAE,OAAO;IACtC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,OAAO,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,CAAC,GAAU,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,GAAG,EAAE;YAClB,MAAsE,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxG,MAAsE,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3G,CAAC,CAAC;QACD,MAA4D,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACpF,MAA4D,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Discovery } from '../../types.js';
|
|
2
|
+
import type { IDiscoveryStore, IEventStore } from '../interfaces.js';
|
|
3
|
+
import type { Redis } from './db.js';
|
|
4
|
+
export declare class RedisDiscoveryStore implements IDiscoveryStore {
|
|
5
|
+
private client;
|
|
6
|
+
private listKey;
|
|
7
|
+
private eventStore;
|
|
8
|
+
constructor(client: Redis, namespace: string, eventStore: IEventStore);
|
|
9
|
+
publish(topic: string, content: string, agentId: string, category?: string): Promise<Discovery>;
|
|
10
|
+
search(query?: string, category?: string): Promise<Discovery[]>;
|
|
11
|
+
getAll(): Promise<Discovery[]>;
|
|
12
|
+
load(discoveries: Discovery[]): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { generateId } from '../../utils.js';
|
|
2
|
+
export class RedisDiscoveryStore {
|
|
3
|
+
client;
|
|
4
|
+
listKey;
|
|
5
|
+
eventStore;
|
|
6
|
+
constructor(client, namespace, eventStore) {
|
|
7
|
+
this.client = client;
|
|
8
|
+
this.listKey = `incubator:${namespace}:discoveries`;
|
|
9
|
+
this.eventStore = eventStore;
|
|
10
|
+
}
|
|
11
|
+
async publish(topic, content, agentId, category) {
|
|
12
|
+
const discovery = {
|
|
13
|
+
id: generateId(),
|
|
14
|
+
topic,
|
|
15
|
+
content,
|
|
16
|
+
category,
|
|
17
|
+
publishedBy: agentId,
|
|
18
|
+
publishedAt: new Date().toISOString(),
|
|
19
|
+
};
|
|
20
|
+
await this.client.rpush(this.listKey, JSON.stringify(discovery));
|
|
21
|
+
await this.eventStore.publish('discovery.published', {
|
|
22
|
+
id: discovery.id,
|
|
23
|
+
topic,
|
|
24
|
+
category,
|
|
25
|
+
}, agentId);
|
|
26
|
+
return discovery;
|
|
27
|
+
}
|
|
28
|
+
async search(query, category) {
|
|
29
|
+
const raws = await this.client.lrange(this.listKey, 0, -1);
|
|
30
|
+
let results = raws.map(raw => JSON.parse(raw));
|
|
31
|
+
if (category) {
|
|
32
|
+
results = results.filter(d => d.category === category);
|
|
33
|
+
}
|
|
34
|
+
if (query) {
|
|
35
|
+
const lower = query.toLowerCase();
|
|
36
|
+
results = results.filter(d => d.topic.toLowerCase().includes(lower) ||
|
|
37
|
+
d.content.toLowerCase().includes(lower));
|
|
38
|
+
}
|
|
39
|
+
return results;
|
|
40
|
+
}
|
|
41
|
+
async getAll() {
|
|
42
|
+
const raws = await this.client.lrange(this.listKey, 0, -1);
|
|
43
|
+
return raws.map(raw => JSON.parse(raw));
|
|
44
|
+
}
|
|
45
|
+
async load(discoveries) {
|
|
46
|
+
const pipeline = this.client.multi();
|
|
47
|
+
pipeline.del(this.listKey);
|
|
48
|
+
for (const d of discoveries) {
|
|
49
|
+
pipeline.rpush(this.listKey, JSON.stringify(d));
|
|
50
|
+
}
|
|
51
|
+
await pipeline.exec();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=discoveries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discoveries.js","sourceRoot":"","sources":["../../../src/stores/redis/discoveries.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,OAAO,mBAAmB;IACtB,MAAM,CAAQ;IACd,OAAO,CAAS;IAChB,UAAU,CAAc;IAEhC,YAAY,MAAa,EAAE,SAAiB,EAAE,UAAuB;QACnE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,aAAa,SAAS,cAAc,CAAC;QACpD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,KAAa,EAAE,OAAe,EAAE,OAAe,EAAE,QAAiB;QAC9E,MAAM,SAAS,GAAc;YAC3B,EAAE,EAAE,UAAU,EAAE;YAChB,KAAK;YACL,OAAO;YACP,QAAQ;YACR,WAAW,EAAE,OAAO;YACpB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACtC,CAAC;QAEF,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;QACjE,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,qBAAqB,EAAE;YACnD,EAAE,EAAE,SAAS,CAAC,EAAE;YAChB,KAAK;YACL,QAAQ;SACT,EAAE,OAAO,CAAC,CAAC;QAEZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAc,EAAE,QAAiB;QAC5C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3D,IAAI,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC,CAAC;QAE5D,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YAClC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC3B,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACrC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CACxC,CAAC;QACJ,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,WAAwB;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACrC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE3B,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IncubatorEvent } from '../../types.js';
|
|
2
|
+
import type { IEventStore } from '../interfaces.js';
|
|
3
|
+
import type { Redis } from './db.js';
|
|
4
|
+
export declare class RedisEventStore implements IEventStore {
|
|
5
|
+
private client;
|
|
6
|
+
private eventsKey;
|
|
7
|
+
private cursorKey;
|
|
8
|
+
constructor(client: Redis, namespace: string);
|
|
9
|
+
publish(type: string, data: unknown, agentId: string): Promise<IncubatorEvent>;
|
|
10
|
+
getEvents(since?: number, type?: string): Promise<{
|
|
11
|
+
events: IncubatorEvent[];
|
|
12
|
+
cursor: number;
|
|
13
|
+
}>;
|
|
14
|
+
getCursor(): Promise<number>;
|
|
15
|
+
getAll(): Promise<IncubatorEvent[]>;
|
|
16
|
+
load(events: IncubatorEvent[], cursor: number): Promise<void>;
|
|
17
|
+
}
|