@feltdb/core 0.2.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 +184 -0
- package/dist/agent-decision.d.ts +81 -0
- package/dist/agent-decision.d.ts.map +1 -0
- package/dist/agent-decision.js +18 -0
- package/dist/agent-memory.d.ts +91 -0
- package/dist/agent-memory.d.ts.map +1 -0
- package/dist/agent-memory.js +21 -0
- package/dist/agent-observation.d.ts +61 -0
- package/dist/agent-observation.d.ts.map +1 -0
- package/dist/agent-observation.js +12 -0
- package/dist/agent-registry.d.ts +92 -0
- package/dist/agent-registry.d.ts.map +1 -0
- package/dist/agent-registry.js +134 -0
- package/dist/agent-runtime.d.ts +147 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/agent-runtime.js +240 -0
- package/dist/agent.d.ts +132 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +58 -0
- package/dist/capability.d.ts +21 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +23 -0
- package/dist/collection.d.ts +95 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +289 -0
- package/dist/db.d.ts +504 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +700 -0
- package/dist/execution.d.ts +148 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +18 -0
- package/dist/feltdb.d.ts +82 -0
- package/dist/feltdb.d.ts.map +1 -0
- package/dist/feltdb.js +6 -0
- package/dist/flowspec.d.ts +64 -0
- package/dist/flowspec.d.ts.map +1 -0
- package/dist/flowspec.js +272 -0
- package/dist/http-db.d.ts +50 -0
- package/dist/http-db.d.ts.map +1 -0
- package/dist/http-db.js +205 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/indexeddb-db.d.ts +54 -0
- package/dist/indexeddb-db.d.ts.map +1 -0
- package/dist/indexeddb-db.js +175 -0
- package/dist/memory-db.d.ts +49 -0
- package/dist/memory-db.d.ts.map +1 -0
- package/dist/memory-db.js +97 -0
- package/dist/operation.d.ts +25 -0
- package/dist/operation.d.ts.map +1 -0
- package/dist/operation.js +16 -0
- package/dist/reactive-graph.d.ts +67 -0
- package/dist/reactive-graph.d.ts.map +1 -0
- package/dist/reactive-graph.js +118 -0
- package/dist/recovery.d.ts +68 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +104 -0
- package/dist/storage.d.ts +48 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +6 -0
- package/dist/workflow.d.ts +20 -0
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.js +12 -0
- package/package.json +43 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Registry
|
|
3
|
+
*
|
|
4
|
+
* Similar to PeerRegistry and CapabilityLocationRegistry.
|
|
5
|
+
* Maps AgentRef to Agent definition, available providers, and compatible state.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Registry for agent definitions and discovery
|
|
9
|
+
*/
|
|
10
|
+
export class AgentRegistry {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.agents = new Map();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Register an agent definition
|
|
16
|
+
*/
|
|
17
|
+
register(agentRef, definition) {
|
|
18
|
+
const key = agentRef.toString();
|
|
19
|
+
const entry = {
|
|
20
|
+
agentRef,
|
|
21
|
+
definition,
|
|
22
|
+
providers: [],
|
|
23
|
+
compatibleStateVersions: [],
|
|
24
|
+
registeredAt: Date.now(),
|
|
25
|
+
updatedAt: Date.now(),
|
|
26
|
+
active: true,
|
|
27
|
+
};
|
|
28
|
+
this.agents.set(key, entry);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Unregister an agent
|
|
32
|
+
*/
|
|
33
|
+
unregister(agentRef) {
|
|
34
|
+
const key = agentRef.toString();
|
|
35
|
+
this.agents.delete(key);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get an agent registration entry
|
|
39
|
+
*/
|
|
40
|
+
get(agentRef) {
|
|
41
|
+
const key = agentRef.toString();
|
|
42
|
+
return this.agents.get(key);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get agent by name (returns latest version)
|
|
46
|
+
*/
|
|
47
|
+
getByName(name) {
|
|
48
|
+
let latest;
|
|
49
|
+
for (const entry of this.agents.values()) {
|
|
50
|
+
if (entry.definition.name === name) {
|
|
51
|
+
if (!latest || entry.agentRef.version > latest.agentRef.version) {
|
|
52
|
+
latest = entry;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return latest;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get all registered agents
|
|
60
|
+
*/
|
|
61
|
+
getAll() {
|
|
62
|
+
return Array.from(this.agents.values());
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Add a provider for an agent
|
|
66
|
+
*/
|
|
67
|
+
addProvider(agentRef, provider) {
|
|
68
|
+
const key = agentRef.toString();
|
|
69
|
+
const entry = this.agents.get(key);
|
|
70
|
+
if (!entry) {
|
|
71
|
+
throw new Error(`Agent not registered: ${key}`);
|
|
72
|
+
}
|
|
73
|
+
// Remove existing provider from same peer if any
|
|
74
|
+
entry.providers = entry.providers.filter(p => p.peerId !== provider.peerId);
|
|
75
|
+
// Add new provider
|
|
76
|
+
entry.providers.push(provider);
|
|
77
|
+
entry.updatedAt = Date.now();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Remove a provider
|
|
81
|
+
*/
|
|
82
|
+
removeProvider(agentRef, peerId) {
|
|
83
|
+
const key = agentRef.toString();
|
|
84
|
+
const entry = this.agents.get(key);
|
|
85
|
+
if (!entry) {
|
|
86
|
+
throw new Error(`Agent not registered: ${key}`);
|
|
87
|
+
}
|
|
88
|
+
entry.providers = entry.providers.filter(p => p.peerId !== peerId);
|
|
89
|
+
entry.updatedAt = Date.now();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get available providers for an agent
|
|
93
|
+
*/
|
|
94
|
+
getAvailableProviders(agentRef) {
|
|
95
|
+
const entry = this.get(agentRef);
|
|
96
|
+
if (!entry) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
return entry.providers.filter(p => p.available);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Find agents by capability
|
|
103
|
+
*/
|
|
104
|
+
findByCapability(capability) {
|
|
105
|
+
const result = [];
|
|
106
|
+
for (const entry of this.agents.values()) {
|
|
107
|
+
if (entry.definition.capabilities.includes(capability)) {
|
|
108
|
+
result.push(entry);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Update agent availability
|
|
115
|
+
*/
|
|
116
|
+
updateAvailability(agentRef, peerId, available) {
|
|
117
|
+
const entry = this.get(agentRef);
|
|
118
|
+
if (!entry) {
|
|
119
|
+
throw new Error(`Agent not registered: ${agentRef.toString()}`);
|
|
120
|
+
}
|
|
121
|
+
const provider = entry.providers.find(p => p.peerId === peerId);
|
|
122
|
+
if (provider) {
|
|
123
|
+
provider.available = available;
|
|
124
|
+
provider.lastHeartbeat = Date.now();
|
|
125
|
+
entry.updatedAt = Date.now();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Clear all registrations
|
|
130
|
+
*/
|
|
131
|
+
clear() {
|
|
132
|
+
this.agents.clear();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Runtime
|
|
3
|
+
*
|
|
4
|
+
* Manages agent lifecycle, execution, ownership, and recovery.
|
|
5
|
+
* Agents run on the distributed fabric as durable participants.
|
|
6
|
+
*/
|
|
7
|
+
import type { StateFirstDB } from './db.js';
|
|
8
|
+
import type { AgentRef, AgentDefinition, AgentExecution } from './agent.js';
|
|
9
|
+
import { AgentExecutionStatus } from './agent.js';
|
|
10
|
+
import type { AgentObservation, ObservationTrigger } from './agent-observation.js';
|
|
11
|
+
import type { AgentDecision } from './agent-decision.js';
|
|
12
|
+
import type { AgentRegistry } from './agent-registry.js';
|
|
13
|
+
/**
|
|
14
|
+
* Agent runtime context for execution
|
|
15
|
+
*/
|
|
16
|
+
export interface AgentRuntimeContext {
|
|
17
|
+
/** The database instance */
|
|
18
|
+
db: StateFirstDB;
|
|
19
|
+
/** The executing agent's definition */
|
|
20
|
+
agentDefinition: AgentDefinition;
|
|
21
|
+
/** The current execution */
|
|
22
|
+
execution: AgentExecution;
|
|
23
|
+
/** Observations made so far */
|
|
24
|
+
observations: AgentObservation[];
|
|
25
|
+
/** Decisions made so far */
|
|
26
|
+
decisions: AgentDecision[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Agent runtime handler function
|
|
30
|
+
* Called when agent needs to make decisions
|
|
31
|
+
*/
|
|
32
|
+
export type AgentHandler = (context: AgentRuntimeContext) => Promise<AgentDecision | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Agent runtime configuration
|
|
35
|
+
*/
|
|
36
|
+
export interface AgentRuntimeConfig {
|
|
37
|
+
/** Whether to persist agent state */
|
|
38
|
+
persistent: boolean;
|
|
39
|
+
/** Maximum execution time in milliseconds */
|
|
40
|
+
executionTimeoutMs: number;
|
|
41
|
+
/** Whether to support reactive triggers */
|
|
42
|
+
supportsReactiveTriggers: boolean;
|
|
43
|
+
/** Default retry policy */
|
|
44
|
+
defaultRetryPolicy?: {
|
|
45
|
+
maxAttempts: number;
|
|
46
|
+
backoffMs: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Agent execution result
|
|
51
|
+
*/
|
|
52
|
+
export interface AgentExecutionResult {
|
|
53
|
+
/** The execution that completed */
|
|
54
|
+
execution: AgentExecution;
|
|
55
|
+
/** Final status */
|
|
56
|
+
status: AgentExecutionStatus;
|
|
57
|
+
/** Result reference if successful */
|
|
58
|
+
resultRef?: string;
|
|
59
|
+
/** Error message if failed */
|
|
60
|
+
error?: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Agent ownership manager for distributed execution
|
|
64
|
+
*/
|
|
65
|
+
export declare class AgentOwnershipManager {
|
|
66
|
+
private ownership;
|
|
67
|
+
private locks;
|
|
68
|
+
/**
|
|
69
|
+
* Claim ownership of an execution
|
|
70
|
+
*/
|
|
71
|
+
claim(executionId: string, peerId: string, ttlMs: number): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Release ownership
|
|
74
|
+
*/
|
|
75
|
+
release(executionId: string, peerId: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Get current owner
|
|
78
|
+
*/
|
|
79
|
+
getOwner(executionId: string): string | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Check if ownership is still valid
|
|
82
|
+
*/
|
|
83
|
+
isValid(executionId: string): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Renew ownership lock
|
|
86
|
+
*/
|
|
87
|
+
renew(executionId: string, peerId: string, ttlMs: number): boolean;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Agent Runtime
|
|
91
|
+
*
|
|
92
|
+
* Manages agent lifecycle and execution across the distributed fabric.
|
|
93
|
+
*/
|
|
94
|
+
export declare class AgentRuntime {
|
|
95
|
+
private config;
|
|
96
|
+
private registry;
|
|
97
|
+
private handlers;
|
|
98
|
+
private executions;
|
|
99
|
+
private ownership;
|
|
100
|
+
private triggers;
|
|
101
|
+
constructor(registry: AgentRegistry, config: AgentRuntimeConfig);
|
|
102
|
+
/**
|
|
103
|
+
* Register an agent handler
|
|
104
|
+
*/
|
|
105
|
+
registerHandler(agentName: string, handler: AgentHandler): void;
|
|
106
|
+
/**
|
|
107
|
+
* Create a new agent execution
|
|
108
|
+
*/
|
|
109
|
+
createExecution(db: StateFirstDB, agentRef: AgentRef, goal: string, inputs: string[]): Promise<AgentExecution>;
|
|
110
|
+
/**
|
|
111
|
+
* Start an agent execution
|
|
112
|
+
*/
|
|
113
|
+
start(execution: AgentExecution, peerId: string): Promise<AgentExecutionResult>;
|
|
114
|
+
/**
|
|
115
|
+
* Resume an execution from durable state
|
|
116
|
+
*/
|
|
117
|
+
resume(execution: AgentExecution, peerId: string): Promise<AgentExecutionResult>;
|
|
118
|
+
/**
|
|
119
|
+
* Transition execution to next state
|
|
120
|
+
*/
|
|
121
|
+
transition(execution: AgentExecution, nextStatus: AgentExecutionStatus): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Complete an execution
|
|
124
|
+
*/
|
|
125
|
+
complete(execution: AgentExecution, resultRef: string): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Fail an execution
|
|
128
|
+
*/
|
|
129
|
+
fail(execution: AgentExecution, error: string): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Get execution by ID
|
|
132
|
+
*/
|
|
133
|
+
getExecution(executionId: string): AgentExecution | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* Get current owner of an execution
|
|
136
|
+
*/
|
|
137
|
+
getOwner(executionId: string): string | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Register observation triggers for reactive execution
|
|
140
|
+
*/
|
|
141
|
+
registerTriggers(agentName: string, triggers: ObservationTrigger[]): void;
|
|
142
|
+
/**
|
|
143
|
+
* Get triggers for an agent
|
|
144
|
+
*/
|
|
145
|
+
getTriggers(agentName: string): ObservationTrigger[];
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=agent-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-runtime.d.ts","sourceRoot":"","sources":["../src/agent-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Runtime
|
|
3
|
+
*
|
|
4
|
+
* Manages agent lifecycle, execution, ownership, and recovery.
|
|
5
|
+
* Agents run on the distributed fabric as durable participants.
|
|
6
|
+
*/
|
|
7
|
+
import { AgentExecutionStatus, generateExecutionId } from './agent.js';
|
|
8
|
+
/**
|
|
9
|
+
* Agent ownership manager for distributed execution
|
|
10
|
+
*/
|
|
11
|
+
export class AgentOwnershipManager {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.ownership = new Map(); // executionId -> peerId
|
|
14
|
+
this.locks = new Map();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Claim ownership of an execution
|
|
18
|
+
*/
|
|
19
|
+
claim(executionId, peerId, ttlMs) {
|
|
20
|
+
const existing = this.ownership.get(executionId);
|
|
21
|
+
// Already owned by this peer
|
|
22
|
+
if (existing === peerId) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
// Already owned by another peer
|
|
26
|
+
if (existing) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
// Check if lock is still valid
|
|
30
|
+
const lock = this.locks.get(executionId);
|
|
31
|
+
if (lock && lock.expiresAt > Date.now()) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
// Claim ownership
|
|
35
|
+
this.ownership.set(executionId, peerId);
|
|
36
|
+
this.locks.set(executionId, {
|
|
37
|
+
peerId,
|
|
38
|
+
expiresAt: Date.now() + ttlMs,
|
|
39
|
+
});
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Release ownership
|
|
44
|
+
*/
|
|
45
|
+
release(executionId, peerId) {
|
|
46
|
+
const owner = this.ownership.get(executionId);
|
|
47
|
+
if (owner === peerId) {
|
|
48
|
+
this.ownership.delete(executionId);
|
|
49
|
+
this.locks.delete(executionId);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get current owner
|
|
54
|
+
*/
|
|
55
|
+
getOwner(executionId) {
|
|
56
|
+
return this.ownership.get(executionId);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if ownership is still valid
|
|
60
|
+
*/
|
|
61
|
+
isValid(executionId) {
|
|
62
|
+
const lock = this.locks.get(executionId);
|
|
63
|
+
if (!lock) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return lock.expiresAt > Date.now();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Renew ownership lock
|
|
70
|
+
*/
|
|
71
|
+
renew(executionId, peerId, ttlMs) {
|
|
72
|
+
const owner = this.ownership.get(executionId);
|
|
73
|
+
if (owner !== peerId) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
this.locks.set(executionId, {
|
|
77
|
+
peerId,
|
|
78
|
+
expiresAt: Date.now() + ttlMs,
|
|
79
|
+
});
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Agent Runtime
|
|
85
|
+
*
|
|
86
|
+
* Manages agent lifecycle and execution across the distributed fabric.
|
|
87
|
+
*/
|
|
88
|
+
export class AgentRuntime {
|
|
89
|
+
constructor(registry, config) {
|
|
90
|
+
this.handlers = new Map();
|
|
91
|
+
this.executions = new Map();
|
|
92
|
+
this.triggers = new Map();
|
|
93
|
+
this.registry = registry;
|
|
94
|
+
this.config = config;
|
|
95
|
+
this.ownership = new AgentOwnershipManager();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Register an agent handler
|
|
99
|
+
*/
|
|
100
|
+
registerHandler(agentName, handler) {
|
|
101
|
+
this.handlers.set(agentName, handler);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Create a new agent execution
|
|
105
|
+
*/
|
|
106
|
+
async createExecution(db, agentRef, goal, inputs) {
|
|
107
|
+
const executionId = generateExecutionId(agentRef.name);
|
|
108
|
+
const execution = {
|
|
109
|
+
executionId,
|
|
110
|
+
agentRef,
|
|
111
|
+
status: AgentExecutionStatus.Created,
|
|
112
|
+
goal,
|
|
113
|
+
inputs,
|
|
114
|
+
stateVersion: 0,
|
|
115
|
+
observationIds: [],
|
|
116
|
+
decisionIds: [],
|
|
117
|
+
actionIds: [],
|
|
118
|
+
attempt: 1,
|
|
119
|
+
createdMs: Date.now(),
|
|
120
|
+
};
|
|
121
|
+
this.executions.set(executionId, execution);
|
|
122
|
+
return execution;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Start an agent execution
|
|
126
|
+
*/
|
|
127
|
+
async start(execution, peerId) {
|
|
128
|
+
// Claim ownership
|
|
129
|
+
const claimed = this.ownership.claim(execution.executionId, peerId, 30000);
|
|
130
|
+
if (!claimed) {
|
|
131
|
+
throw new Error(`Failed to claim ownership of execution ${execution.executionId}`);
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
execution.status = AgentExecutionStatus.Planning;
|
|
135
|
+
execution.ownedBy = peerId;
|
|
136
|
+
execution.startedMs = Date.now();
|
|
137
|
+
return {
|
|
138
|
+
execution,
|
|
139
|
+
status: AgentExecutionStatus.Planning,
|
|
140
|
+
resultRef: undefined,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
execution.status = AgentExecutionStatus.Failed;
|
|
145
|
+
execution.error = String(error);
|
|
146
|
+
execution.completedMs = Date.now();
|
|
147
|
+
return {
|
|
148
|
+
execution,
|
|
149
|
+
status: AgentExecutionStatus.Failed,
|
|
150
|
+
error: String(error),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Resume an execution from durable state
|
|
156
|
+
*/
|
|
157
|
+
async resume(execution, peerId) {
|
|
158
|
+
// Try to claim ownership (new peer)
|
|
159
|
+
const claimed = this.ownership.claim(execution.executionId, peerId, 30000);
|
|
160
|
+
if (!claimed && this.ownership.getOwner(execution.executionId) !== peerId) {
|
|
161
|
+
throw new Error(`Cannot resume execution ${execution.executionId}: owned by ${this.ownership.getOwner(execution.executionId)}`);
|
|
162
|
+
}
|
|
163
|
+
execution.ownedBy = peerId;
|
|
164
|
+
execution.status = AgentExecutionStatus.Observing;
|
|
165
|
+
return {
|
|
166
|
+
execution,
|
|
167
|
+
status: AgentExecutionStatus.Observing,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Transition execution to next state
|
|
172
|
+
*/
|
|
173
|
+
async transition(execution, nextStatus) {
|
|
174
|
+
const validTransitions = {
|
|
175
|
+
[AgentExecutionStatus.Created]: [AgentExecutionStatus.Planning],
|
|
176
|
+
[AgentExecutionStatus.Planning]: [AgentExecutionStatus.Observing],
|
|
177
|
+
[AgentExecutionStatus.Observing]: [AgentExecutionStatus.Deciding, AgentExecutionStatus.Waiting],
|
|
178
|
+
[AgentExecutionStatus.Deciding]: [AgentExecutionStatus.Acting],
|
|
179
|
+
[AgentExecutionStatus.Acting]: [AgentExecutionStatus.Observing, AgentExecutionStatus.Waiting, AgentExecutionStatus.Completed],
|
|
180
|
+
[AgentExecutionStatus.Waiting]: [AgentExecutionStatus.Observing, AgentExecutionStatus.Blocked],
|
|
181
|
+
[AgentExecutionStatus.Completed]: [],
|
|
182
|
+
[AgentExecutionStatus.Failed]: [],
|
|
183
|
+
[AgentExecutionStatus.Cancelled]: [],
|
|
184
|
+
[AgentExecutionStatus.Blocked]: [AgentExecutionStatus.Observing],
|
|
185
|
+
};
|
|
186
|
+
const allowed = validTransitions[execution.status] || [];
|
|
187
|
+
if (!allowed.includes(nextStatus)) {
|
|
188
|
+
throw new Error(`Invalid transition from ${execution.status} to ${nextStatus}`);
|
|
189
|
+
}
|
|
190
|
+
execution.status = nextStatus;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Complete an execution
|
|
194
|
+
*/
|
|
195
|
+
async complete(execution, resultRef) {
|
|
196
|
+
execution.status = AgentExecutionStatus.Completed;
|
|
197
|
+
execution.resultRef = resultRef;
|
|
198
|
+
execution.completedMs = Date.now();
|
|
199
|
+
// Release ownership
|
|
200
|
+
if (execution.ownedBy) {
|
|
201
|
+
this.ownership.release(execution.executionId, execution.ownedBy);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Fail an execution
|
|
206
|
+
*/
|
|
207
|
+
async fail(execution, error) {
|
|
208
|
+
execution.status = AgentExecutionStatus.Failed;
|
|
209
|
+
execution.error = error;
|
|
210
|
+
execution.completedMs = Date.now();
|
|
211
|
+
// Release ownership
|
|
212
|
+
if (execution.ownedBy) {
|
|
213
|
+
this.ownership.release(execution.executionId, execution.ownedBy);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Get execution by ID
|
|
218
|
+
*/
|
|
219
|
+
getExecution(executionId) {
|
|
220
|
+
return this.executions.get(executionId);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Get current owner of an execution
|
|
224
|
+
*/
|
|
225
|
+
getOwner(executionId) {
|
|
226
|
+
return this.ownership.getOwner(executionId);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Register observation triggers for reactive execution
|
|
230
|
+
*/
|
|
231
|
+
registerTriggers(agentName, triggers) {
|
|
232
|
+
this.triggers.set(agentName, triggers);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get triggers for an agent
|
|
236
|
+
*/
|
|
237
|
+
getTriggers(agentName) {
|
|
238
|
+
return this.triggers.get(agentName) || [];
|
|
239
|
+
}
|
|
240
|
+
}
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FeltDB Agent Runtime
|
|
3
|
+
*
|
|
4
|
+
* Agents are durable, addressable participants in the FeltDB fabric.
|
|
5
|
+
* An agent's observations, decisions, actions, and results are all part
|
|
6
|
+
* of the same causal graph.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Agent reference - a location-independent address for an agent
|
|
10
|
+
* Format: flow://agent/{name}@{version}
|
|
11
|
+
* Example: flow://agent/researcher@1
|
|
12
|
+
*/
|
|
13
|
+
export interface AgentRef {
|
|
14
|
+
/** Agent name */
|
|
15
|
+
name: string;
|
|
16
|
+
/** Agent version */
|
|
17
|
+
version: number;
|
|
18
|
+
/** Full canonical form */
|
|
19
|
+
toString(): string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Lifecycle states for agent execution
|
|
23
|
+
*/
|
|
24
|
+
export declare enum AgentExecutionStatus {
|
|
25
|
+
Created = "Created",
|
|
26
|
+
Planning = "Planning",
|
|
27
|
+
Observing = "Observing",
|
|
28
|
+
Deciding = "Deciding",
|
|
29
|
+
Acting = "Acting",
|
|
30
|
+
Waiting = "Waiting",
|
|
31
|
+
Completed = "Completed",
|
|
32
|
+
Failed = "Failed",
|
|
33
|
+
Cancelled = "Cancelled",
|
|
34
|
+
Blocked = "Blocked"
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Agent definition: what the agent is capable of doing
|
|
38
|
+
*/
|
|
39
|
+
export interface AgentDefinition {
|
|
40
|
+
/** Unique agent name */
|
|
41
|
+
name: string;
|
|
42
|
+
/** Agent version */
|
|
43
|
+
version: number;
|
|
44
|
+
/** Human-readable description */
|
|
45
|
+
description?: string;
|
|
46
|
+
/** List of capabilities the agent can use */
|
|
47
|
+
capabilities: string[];
|
|
48
|
+
/** Agent goals/objectives */
|
|
49
|
+
goals?: string[];
|
|
50
|
+
/** Execution constraints */
|
|
51
|
+
constraints?: {
|
|
52
|
+
/** Maximum latency in milliseconds */
|
|
53
|
+
maxLatency?: number;
|
|
54
|
+
/** Whether to require fresh state */
|
|
55
|
+
requireFreshState?: boolean;
|
|
56
|
+
/** Maximum number of decision iterations */
|
|
57
|
+
maxIterations?: number;
|
|
58
|
+
/** Maximum concurrent executions */
|
|
59
|
+
maxConcurrent?: number;
|
|
60
|
+
};
|
|
61
|
+
/** Execution tools available to the agent */
|
|
62
|
+
tools?: string[];
|
|
63
|
+
/** Agent policies */
|
|
64
|
+
policies?: {
|
|
65
|
+
/** Require human approval for certain actions */
|
|
66
|
+
requireApproval?: string[];
|
|
67
|
+
/** Actions that are forbidden */
|
|
68
|
+
forbidden?: string[];
|
|
69
|
+
};
|
|
70
|
+
/** Memory scope and retention */
|
|
71
|
+
memory?: {
|
|
72
|
+
/** Maximum memory size in KB */
|
|
73
|
+
maxSize?: number;
|
|
74
|
+
/** Memory retention period in milliseconds */
|
|
75
|
+
retentionMs?: number;
|
|
76
|
+
/** Memory scope (local, distributed, shared) */
|
|
77
|
+
scope?: 'local' | 'distributed' | 'shared';
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Agent execution: a particular invocation of an agent
|
|
82
|
+
*/
|
|
83
|
+
export interface AgentExecution {
|
|
84
|
+
/** Unique execution ID */
|
|
85
|
+
executionId: string;
|
|
86
|
+
/** Reference to the agent being executed */
|
|
87
|
+
agentRef: AgentRef;
|
|
88
|
+
/** Current lifecycle status */
|
|
89
|
+
status: AgentExecutionStatus;
|
|
90
|
+
/** Goal for this execution */
|
|
91
|
+
goal: string;
|
|
92
|
+
/** Input references to the execution */
|
|
93
|
+
inputs: string[];
|
|
94
|
+
/** State version when execution started */
|
|
95
|
+
stateVersion: number;
|
|
96
|
+
/** Peer ID that owns this execution (single-owner semantics) */
|
|
97
|
+
ownedBy?: string;
|
|
98
|
+
/** Observations made during this execution */
|
|
99
|
+
observationIds: string[];
|
|
100
|
+
/** Decisions made during this execution */
|
|
101
|
+
decisionIds: string[];
|
|
102
|
+
/** Actions taken during this execution */
|
|
103
|
+
actionIds: string[];
|
|
104
|
+
/** Result reference after completion */
|
|
105
|
+
resultRef?: string;
|
|
106
|
+
/** Execution attempt number */
|
|
107
|
+
attempt: number;
|
|
108
|
+
/** Timestamp when execution was created */
|
|
109
|
+
createdMs: number;
|
|
110
|
+
/** Timestamp when execution started */
|
|
111
|
+
startedMs?: number;
|
|
112
|
+
/** Timestamp when execution completed */
|
|
113
|
+
completedMs?: number;
|
|
114
|
+
/** Optional error message if execution failed */
|
|
115
|
+
error?: string;
|
|
116
|
+
/** Metadata about the execution */
|
|
117
|
+
metadata?: Record<string, any>;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Parse an agent reference from its canonical form
|
|
121
|
+
* @example parseAgentRef("flow://agent/researcher@1")
|
|
122
|
+
*/
|
|
123
|
+
export declare function parseAgentRef(ref: string): AgentRef;
|
|
124
|
+
/**
|
|
125
|
+
* Create an agent reference
|
|
126
|
+
*/
|
|
127
|
+
export declare function createAgentRef(name: string, version: number): AgentRef;
|
|
128
|
+
/**
|
|
129
|
+
* Generate a unique execution ID
|
|
130
|
+
*/
|
|
131
|
+
export declare function generateExecutionId(agentName: string): string;
|
|
132
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|