@falai/agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +516 -0
- package/dist/constants/index.d.ts +5 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +5 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/core/Agent.d.ts +98 -0
- package/dist/core/Agent.d.ts.map +1 -0
- package/dist/core/Agent.js +248 -0
- package/dist/core/Agent.js.map +1 -0
- package/dist/core/DomainRegistry.d.ts +26 -0
- package/dist/core/DomainRegistry.d.ts.map +1 -0
- package/dist/core/DomainRegistry.js +41 -0
- package/dist/core/DomainRegistry.js.map +1 -0
- package/dist/core/Events.d.ts +19 -0
- package/dist/core/Events.d.ts.map +1 -0
- package/dist/core/Events.js +79 -0
- package/dist/core/Events.js.map +1 -0
- package/dist/core/Observation.d.ts +24 -0
- package/dist/core/Observation.d.ts.map +1 -0
- package/dist/core/Observation.js +35 -0
- package/dist/core/Observation.js.map +1 -0
- package/dist/core/PromptBuilder.d.ts +121 -0
- package/dist/core/PromptBuilder.d.ts.map +1 -0
- package/dist/core/PromptBuilder.js +339 -0
- package/dist/core/PromptBuilder.js.map +1 -0
- package/dist/core/Route.d.ts +46 -0
- package/dist/core/Route.d.ts.map +1 -0
- package/dist/core/Route.js +113 -0
- package/dist/core/Route.js.map +1 -0
- package/dist/core/State.d.ts +50 -0
- package/dist/core/State.d.ts.map +1 -0
- package/dist/core/State.js +110 -0
- package/dist/core/State.js.map +1 -0
- package/dist/core/Tool.d.ts +31 -0
- package/dist/core/Tool.d.ts.map +1 -0
- package/dist/core/Tool.js +33 -0
- package/dist/core/Tool.js.map +1 -0
- package/dist/core/Transition.d.ts +32 -0
- package/dist/core/Transition.d.ts.map +1 -0
- package/dist/core/Transition.js +59 -0
- package/dist/core/Transition.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/GeminiProvider.d.ts +40 -0
- package/dist/providers/GeminiProvider.d.ts.map +1 -0
- package/dist/providers/GeminiProvider.js +126 -0
- package/dist/providers/GeminiProvider.js.map +1 -0
- package/dist/providers/OpenAIProvider.d.ts +42 -0
- package/dist/providers/OpenAIProvider.d.ts.map +1 -0
- package/dist/providers/OpenAIProvider.js +164 -0
- package/dist/providers/OpenAIProvider.js.map +1 -0
- package/dist/providers/OpenRouterProvider.d.ts +46 -0
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -0
- package/dist/providers/OpenRouterProvider.js +171 -0
- package/dist/providers/OpenRouterProvider.js.map +1 -0
- package/dist/types/agent.d.ts +105 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +18 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/ai.d.ts +78 -0
- package/dist/types/ai.d.ts.map +1 -0
- package/dist/types/ai.js +5 -0
- package/dist/types/ai.js.map +1 -0
- package/dist/types/history.d.ts +112 -0
- package/dist/types/history.d.ts.map +1 -0
- package/dist/types/history.js +34 -0
- package/dist/types/history.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/observation.d.ts +25 -0
- package/dist/types/observation.d.ts.map +1 -0
- package/dist/types/observation.js +5 -0
- package/dist/types/observation.js.map +1 -0
- package/dist/types/prompt.d.ts +46 -0
- package/dist/types/prompt.d.ts.map +1 -0
- package/dist/types/prompt.js +16 -0
- package/dist/types/prompt.js.map +1 -0
- package/dist/types/route.d.ts +59 -0
- package/dist/types/route.d.ts.map +1 -0
- package/dist/types/route.js +5 -0
- package/dist/types/route.js.map +1 -0
- package/dist/types/tool.d.ts +46 -0
- package/dist/types/tool.d.ts.map +1 -0
- package/dist/types/tool.js +5 -0
- package/dist/types/tool.js.map +1 -0
- package/dist/utils/retry.d.ts +13 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +70 -0
- package/dist/utils/retry.js.map +1 -0
- package/docs/API_REFERENCE.md +517 -0
- package/docs/CONSTRUCTOR_OPTIONS.md +256 -0
- package/docs/CONTRIBUTING.md +481 -0
- package/docs/GETTING_STARTED.md +328 -0
- package/docs/PROVIDERS.md +472 -0
- package/docs/PUBLISHING.md +174 -0
- package/docs/README.md +68 -0
- package/docs/STRUCTURE.md +32 -0
- package/examples/declarative-agent.ts +217 -0
- package/examples/healthcare-agent.ts +283 -0
- package/examples/openai-agent.ts +167 -0
- package/examples/travel-agent.ts +342 -0
- package/package.json +73 -0
- package/src/constants/index.ts +5 -0
- package/src/core/Agent.ts +307 -0
- package/src/core/DomainRegistry.ts +50 -0
- package/src/core/Events.ts +101 -0
- package/src/core/Observation.ts +46 -0
- package/src/core/PromptBuilder.ts +511 -0
- package/src/core/Route.ts +136 -0
- package/src/core/State.ts +153 -0
- package/src/core/Tool.ts +54 -0
- package/src/core/Transition.ts +66 -0
- package/src/index.ts +83 -0
- package/src/providers/GeminiProvider.ts +220 -0
- package/src/providers/OpenAIProvider.ts +272 -0
- package/src/providers/OpenRouterProvider.ts +282 -0
- package/src/types/agent.ts +112 -0
- package/src/types/ai.ts +85 -0
- package/src/types/history.ts +125 -0
- package/src/types/index.ts +56 -0
- package/src/types/observation.ts +27 -0
- package/src/types/prompt.ts +49 -0
- package/src/types/route.ts +68 -0
- package/src/types/tool.ts +53 -0
- package/src/utils/retry.ts +96 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Agent implementation
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
AgentOptions,
|
|
7
|
+
Term,
|
|
8
|
+
Guideline,
|
|
9
|
+
GuidelineMatch,
|
|
10
|
+
Capability,
|
|
11
|
+
} from "@/types/agent";
|
|
12
|
+
import type { Event, StateRef } from "@/types/index";
|
|
13
|
+
import type { RouteOptions } from "@/types/route";
|
|
14
|
+
|
|
15
|
+
import { Route } from "@/core/Route";
|
|
16
|
+
import { DomainRegistry } from "@/core/DomainRegistry";
|
|
17
|
+
import { PromptBuilder } from "@/core/PromptBuilder";
|
|
18
|
+
import { Observation } from "@/core/Observation";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Main Agent class with generic context support
|
|
22
|
+
*/
|
|
23
|
+
export class Agent<TContext = unknown> {
|
|
24
|
+
private terms: Term[] = [];
|
|
25
|
+
private guidelines: Guideline[] = [];
|
|
26
|
+
private capabilities: Capability[] = [];
|
|
27
|
+
private routes: Route[] = [];
|
|
28
|
+
private observations: Observation[] = [];
|
|
29
|
+
private domainRegistry = new DomainRegistry();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Dynamic domain property - populated via addDomain
|
|
33
|
+
*/
|
|
34
|
+
public readonly domain: Record<string, Record<string, unknown>> = {};
|
|
35
|
+
|
|
36
|
+
constructor(private readonly options: AgentOptions<TContext>) {
|
|
37
|
+
// Initialize with default values
|
|
38
|
+
if (!this.options.maxEngineIterations) {
|
|
39
|
+
this.options.maxEngineIterations = 1;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Initialize from options
|
|
43
|
+
if (options.terms) {
|
|
44
|
+
this.terms = [...options.terms];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (options.guidelines) {
|
|
48
|
+
options.guidelines.forEach((guideline) => {
|
|
49
|
+
this.createGuideline(guideline);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (options.capabilities) {
|
|
54
|
+
options.capabilities.forEach((capability) => {
|
|
55
|
+
this.createCapability(capability);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (options.routes) {
|
|
60
|
+
options.routes.forEach((routeOptions) => {
|
|
61
|
+
this.createRoute(routeOptions);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (options.observations) {
|
|
66
|
+
options.observations.forEach((obsOptions) => {
|
|
67
|
+
const obs = this.createObservation(obsOptions.description);
|
|
68
|
+
|
|
69
|
+
// If route refs were provided, resolve and disambiguate
|
|
70
|
+
if (obsOptions.routeRefs && obsOptions.routeRefs.length > 0) {
|
|
71
|
+
const resolvedRoutes = obsOptions.routeRefs
|
|
72
|
+
.map((ref) => {
|
|
73
|
+
// Try to find route by ID or title
|
|
74
|
+
return this.routes.find((r) => r.id === ref || r.title === ref);
|
|
75
|
+
})
|
|
76
|
+
.filter((r): r is Route => r !== undefined);
|
|
77
|
+
|
|
78
|
+
if (resolvedRoutes.length > 0) {
|
|
79
|
+
obs.disambiguate(resolvedRoutes);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get agent name
|
|
88
|
+
*/
|
|
89
|
+
get name(): string {
|
|
90
|
+
return this.options.name;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get agent description
|
|
95
|
+
*/
|
|
96
|
+
get description(): string | undefined {
|
|
97
|
+
return this.options.description;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Get agent goal
|
|
102
|
+
*/
|
|
103
|
+
get goal(): string | undefined {
|
|
104
|
+
return this.options.goal;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Create a new route (journey)
|
|
109
|
+
*/
|
|
110
|
+
createRoute(options: RouteOptions): Route {
|
|
111
|
+
const route = new Route(options);
|
|
112
|
+
this.routes.push(route);
|
|
113
|
+
return route;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Create a domain term for the glossary
|
|
118
|
+
*/
|
|
119
|
+
createTerm(term: Term): this {
|
|
120
|
+
this.terms.push(term);
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Create a behavioral guideline
|
|
126
|
+
*/
|
|
127
|
+
createGuideline(guideline: Guideline): this {
|
|
128
|
+
const guidelineWithId = {
|
|
129
|
+
...guideline,
|
|
130
|
+
id: guideline.id || `guideline_${this.guidelines.length}`,
|
|
131
|
+
enabled: guideline.enabled !== false, // Default to true
|
|
132
|
+
};
|
|
133
|
+
this.guidelines.push(guidelineWithId);
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Add a capability
|
|
139
|
+
*/
|
|
140
|
+
createCapability(capability: Capability): this {
|
|
141
|
+
const capabilityWithId = {
|
|
142
|
+
...capability,
|
|
143
|
+
id: capability.id || `capability_${this.capabilities.length}`,
|
|
144
|
+
};
|
|
145
|
+
this.capabilities.push(capabilityWithId);
|
|
146
|
+
return this;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Create an observation for disambiguation
|
|
151
|
+
*/
|
|
152
|
+
createObservation(description: string): Observation {
|
|
153
|
+
const observation = new Observation({ description });
|
|
154
|
+
this.observations.push(observation);
|
|
155
|
+
return observation;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Add a domain with its tools/methods
|
|
160
|
+
*/
|
|
161
|
+
addDomain<TName extends string, TDomain extends Record<string, unknown>>(
|
|
162
|
+
name: TName,
|
|
163
|
+
domainObject: TDomain
|
|
164
|
+
): void {
|
|
165
|
+
this.domainRegistry.register(name, domainObject);
|
|
166
|
+
// Attach to the domain property for easy access
|
|
167
|
+
this.domain[name] = domainObject;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Generate a response based on history and context
|
|
172
|
+
*/
|
|
173
|
+
async respond(params: {
|
|
174
|
+
history: Event[];
|
|
175
|
+
state?: StateRef;
|
|
176
|
+
contextOverride?: Partial<TContext>;
|
|
177
|
+
signal?: AbortSignal;
|
|
178
|
+
}): Promise<{ message: string }> {
|
|
179
|
+
const { history, contextOverride, signal } = params;
|
|
180
|
+
|
|
181
|
+
// Merge context
|
|
182
|
+
const effectiveContext = {
|
|
183
|
+
...(this.options.context as Record<string, unknown>),
|
|
184
|
+
...(contextOverride as Record<string, unknown>),
|
|
185
|
+
} as TContext;
|
|
186
|
+
|
|
187
|
+
// Build prompt
|
|
188
|
+
const promptBuilder = new PromptBuilder();
|
|
189
|
+
|
|
190
|
+
// Add agent identity
|
|
191
|
+
if (this.options.description) {
|
|
192
|
+
promptBuilder.addAgentIdentity({
|
|
193
|
+
name: this.options.name,
|
|
194
|
+
description: this.options.description,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Add interaction history
|
|
199
|
+
promptBuilder.addInteractionHistoryForMessageGeneration(history);
|
|
200
|
+
|
|
201
|
+
// Add glossary
|
|
202
|
+
if (this.terms.length > 0) {
|
|
203
|
+
promptBuilder.addGlossary(this.terms);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Add guidelines (convert to GuidelineMatch format, filter enabled only)
|
|
207
|
+
const enabledGuidelines = this.guidelines.filter(
|
|
208
|
+
(g) => g.enabled !== false
|
|
209
|
+
);
|
|
210
|
+
if (enabledGuidelines.length > 0) {
|
|
211
|
+
const guidelineMatches: GuidelineMatch[] = enabledGuidelines.map((g) => ({
|
|
212
|
+
guideline: g,
|
|
213
|
+
}));
|
|
214
|
+
promptBuilder.addGuidelinesForMessageGeneration(guidelineMatches);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Add capabilities
|
|
218
|
+
if (this.capabilities.length > 0) {
|
|
219
|
+
promptBuilder.addCapabilitiesForMessageGeneration(this.capabilities);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Add observations
|
|
223
|
+
if (this.observations.length > 0) {
|
|
224
|
+
const observationsWithRoutes = this.observations
|
|
225
|
+
.map((obs) => ({
|
|
226
|
+
description: obs.description,
|
|
227
|
+
routes: obs.getRoutes().map((routeRef) => {
|
|
228
|
+
const route = this.routes.find((r) => r.id === routeRef.id);
|
|
229
|
+
return { title: route?.title || routeRef.id };
|
|
230
|
+
}),
|
|
231
|
+
}))
|
|
232
|
+
.filter((obs) => obs.routes.length > 0);
|
|
233
|
+
|
|
234
|
+
if (observationsWithRoutes.length > 0) {
|
|
235
|
+
promptBuilder.addObservations(observationsWithRoutes);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Add active routes
|
|
240
|
+
if (this.routes.length > 0) {
|
|
241
|
+
promptBuilder.addActiveRoutes(
|
|
242
|
+
this.routes.map((r) => ({
|
|
243
|
+
title: r.title,
|
|
244
|
+
description: r.description,
|
|
245
|
+
conditions: r.conditions,
|
|
246
|
+
}))
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Build final prompt
|
|
251
|
+
const prompt = promptBuilder.build();
|
|
252
|
+
|
|
253
|
+
// Generate message using AI provider
|
|
254
|
+
const result = await this.options.ai.generateMessage({
|
|
255
|
+
prompt,
|
|
256
|
+
history,
|
|
257
|
+
context: effectiveContext,
|
|
258
|
+
signal,
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
message: result.message,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Get all routes
|
|
268
|
+
*/
|
|
269
|
+
getRoutes(): Route[] {
|
|
270
|
+
return [...this.routes];
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Get all terms
|
|
275
|
+
*/
|
|
276
|
+
getTerms(): Term[] {
|
|
277
|
+
return [...this.terms];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Get all guidelines
|
|
282
|
+
*/
|
|
283
|
+
getGuidelines(): Guideline[] {
|
|
284
|
+
return [...this.guidelines];
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Get all capabilities
|
|
289
|
+
*/
|
|
290
|
+
getCapabilities(): Capability[] {
|
|
291
|
+
return [...this.capabilities];
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Get all observations
|
|
296
|
+
*/
|
|
297
|
+
getObservations(): Observation[] {
|
|
298
|
+
return [...this.observations];
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Get the domain registry
|
|
303
|
+
*/
|
|
304
|
+
getDomainRegistry(): DomainRegistry {
|
|
305
|
+
return this.domainRegistry;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain registry for organizing agent capabilities by domain
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registry that holds domain-specific tools and methods
|
|
7
|
+
*/
|
|
8
|
+
export class DomainRegistry {
|
|
9
|
+
private domains: Map<string, Record<string, unknown>> = new Map();
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Register a new domain with its methods/tools
|
|
13
|
+
*/
|
|
14
|
+
register<TDomain extends Record<string, unknown>>(
|
|
15
|
+
name: string,
|
|
16
|
+
domain: TDomain
|
|
17
|
+
): void {
|
|
18
|
+
if (this.domains.has(name)) {
|
|
19
|
+
throw new Error(`Domain "${name}" is already registered`);
|
|
20
|
+
}
|
|
21
|
+
this.domains.set(name, domain);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get a registered domain
|
|
26
|
+
*/
|
|
27
|
+
get<TDomain extends Record<string, unknown>>(
|
|
28
|
+
name: string
|
|
29
|
+
): TDomain | undefined {
|
|
30
|
+
return this.domains.get(name) as TDomain | undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Check if a domain is registered
|
|
35
|
+
*/
|
|
36
|
+
has(name: string): boolean {
|
|
37
|
+
return this.domains.has(name);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get all registered domains as a single object
|
|
42
|
+
*/
|
|
43
|
+
all(): Record<string, Record<string, unknown>> {
|
|
44
|
+
const result: Record<string, Record<string, unknown>> = {};
|
|
45
|
+
for (const [name, domain] of this.domains) {
|
|
46
|
+
result[name] = domain;
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event utilities and helpers
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
Event,
|
|
7
|
+
EmittedEvent,
|
|
8
|
+
MessageEventData,
|
|
9
|
+
ToolEventData,
|
|
10
|
+
ToolCall,
|
|
11
|
+
} from "@/types/history";
|
|
12
|
+
import { EventKind, EventSource } from "@/types/history";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Adapt an event for inclusion in prompts
|
|
16
|
+
* Transforms event data into a serializable format
|
|
17
|
+
*/
|
|
18
|
+
export function adaptEvent(e: Event | EmittedEvent): string {
|
|
19
|
+
let data: unknown = e.data;
|
|
20
|
+
|
|
21
|
+
if (e.kind === EventKind.MESSAGE) {
|
|
22
|
+
const messageData = e.data as MessageEventData;
|
|
23
|
+
|
|
24
|
+
if (messageData.flagged) {
|
|
25
|
+
data = {
|
|
26
|
+
participant: messageData.participant.display_name,
|
|
27
|
+
message: "<N/A>",
|
|
28
|
+
censored: true,
|
|
29
|
+
reasons: messageData.tags,
|
|
30
|
+
};
|
|
31
|
+
} else {
|
|
32
|
+
data = {
|
|
33
|
+
participant: messageData.participant.display_name,
|
|
34
|
+
message: messageData.message,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (e.kind === EventKind.TOOL) {
|
|
40
|
+
const toolData = e.data as ToolEventData;
|
|
41
|
+
|
|
42
|
+
data = {
|
|
43
|
+
tool_calls: toolData.tool_calls.map((tc) => ({
|
|
44
|
+
tool_id: tc.tool_id,
|
|
45
|
+
arguments: tc.arguments,
|
|
46
|
+
result: tc.result.data,
|
|
47
|
+
})),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const sourceMap: Record<EventSource, string> = {
|
|
52
|
+
[EventSource.CUSTOMER]: "user",
|
|
53
|
+
[EventSource.CUSTOMER_UI]: "frontend_application",
|
|
54
|
+
[EventSource.HUMAN_AGENT]: "human_service_agent",
|
|
55
|
+
[EventSource.HUMAN_AGENT_ON_BEHALF_OF_AI_AGENT]: "ai_agent",
|
|
56
|
+
[EventSource.AI_AGENT]: "ai_agent",
|
|
57
|
+
[EventSource.SYSTEM]: "system-provided",
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return JSON.stringify({
|
|
61
|
+
event_kind: e.kind,
|
|
62
|
+
event_source: sourceMap[e.source],
|
|
63
|
+
data,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Create a message event
|
|
69
|
+
*/
|
|
70
|
+
export function createMessageEvent(
|
|
71
|
+
source: EventSource,
|
|
72
|
+
participantName: string,
|
|
73
|
+
message: string
|
|
74
|
+
): Event<MessageEventData> {
|
|
75
|
+
return {
|
|
76
|
+
kind: EventKind.MESSAGE,
|
|
77
|
+
source,
|
|
78
|
+
data: {
|
|
79
|
+
participant: { display_name: participantName },
|
|
80
|
+
message,
|
|
81
|
+
},
|
|
82
|
+
timestamp: new Date().toISOString(),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Create a tool event
|
|
88
|
+
*/
|
|
89
|
+
export function createToolEvent(
|
|
90
|
+
source: EventSource,
|
|
91
|
+
toolCalls: ToolCall[]
|
|
92
|
+
): Event<ToolEventData> {
|
|
93
|
+
return {
|
|
94
|
+
kind: EventKind.TOOL,
|
|
95
|
+
source,
|
|
96
|
+
data: {
|
|
97
|
+
tool_calls: toolCalls,
|
|
98
|
+
},
|
|
99
|
+
timestamp: new Date().toISOString(),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observation for route disambiguation
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
Observation as IObservation,
|
|
7
|
+
ObservationOptions,
|
|
8
|
+
} from "@/types/observation";
|
|
9
|
+
import type { RouteRef } from "@/types/route";
|
|
10
|
+
import type { Route } from "@/core/Route";
|
|
11
|
+
|
|
12
|
+
let observationIdCounter = 0;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* An observation that can trigger disambiguation between routes
|
|
16
|
+
*/
|
|
17
|
+
export class Observation implements IObservation {
|
|
18
|
+
public readonly id: string;
|
|
19
|
+
public readonly description: string;
|
|
20
|
+
public routes: RouteRef[] = [];
|
|
21
|
+
|
|
22
|
+
constructor(options: ObservationOptions) {
|
|
23
|
+
this.id = `observation_${++observationIdCounter}`;
|
|
24
|
+
this.description = options.description;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Set routes that this observation can disambiguate between
|
|
29
|
+
*/
|
|
30
|
+
disambiguate(routes: (Route | RouteRef)[]): this {
|
|
31
|
+
this.routes = routes.map((r) => {
|
|
32
|
+
if ("getRef" in r) {
|
|
33
|
+
return r.getRef();
|
|
34
|
+
}
|
|
35
|
+
return r;
|
|
36
|
+
});
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get the routes this observation disambiguates
|
|
42
|
+
*/
|
|
43
|
+
getRoutes(): RouteRef[] {
|
|
44
|
+
return [...this.routes];
|
|
45
|
+
}
|
|
46
|
+
}
|