@falai/agent 0.4.0 ā 0.5.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 +21 -74
- package/dist/cjs/core/Agent.d.ts +22 -29
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +465 -275
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/Events.d.ts +10 -1
- package/dist/cjs/core/Events.d.ts.map +1 -1
- package/dist/cjs/core/Events.js +3 -2
- package/dist/cjs/core/Events.js.map +1 -1
- package/dist/cjs/core/PersistenceManager.d.ts +19 -0
- package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
- package/dist/cjs/core/PersistenceManager.js +57 -0
- package/dist/cjs/core/PersistenceManager.js.map +1 -1
- package/dist/cjs/core/PromptComposer.d.ts +24 -0
- package/dist/cjs/core/PromptComposer.d.ts.map +1 -0
- package/dist/cjs/core/PromptComposer.js +127 -0
- package/dist/cjs/core/PromptComposer.js.map +1 -0
- package/dist/cjs/core/ResponseEngine.d.ts +19 -0
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -0
- package/dist/cjs/core/ResponseEngine.js +51 -0
- package/dist/cjs/core/ResponseEngine.js.map +1 -0
- package/dist/cjs/core/Route.d.ts +18 -12
- package/dist/cjs/core/Route.d.ts.map +1 -1
- package/dist/cjs/core/Route.js +15 -9
- package/dist/cjs/core/Route.js.map +1 -1
- package/dist/cjs/core/RoutingEngine.d.ts +38 -0
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -0
- package/dist/cjs/core/RoutingEngine.js +110 -0
- package/dist/cjs/core/RoutingEngine.js.map +1 -0
- package/dist/cjs/core/State.d.ts +15 -4
- package/dist/cjs/core/State.d.ts.map +1 -1
- package/dist/cjs/core/State.js +21 -2
- package/dist/cjs/core/State.js.map +1 -1
- package/dist/cjs/core/ToolExecutor.d.ts +29 -0
- package/dist/cjs/core/ToolExecutor.d.ts.map +1 -0
- package/dist/cjs/core/ToolExecutor.js +73 -0
- package/dist/cjs/core/ToolExecutor.js.map +1 -0
- package/dist/cjs/core/Transition.d.ts +5 -5
- package/dist/cjs/core/Transition.d.ts.map +1 -1
- package/dist/cjs/core/Transition.js.map +1 -1
- package/dist/cjs/index.d.ts +6 -8
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +8 -10
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.js +10 -13
- package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +12 -8
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.js +10 -53
- package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.js +10 -53
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +13 -9
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/ai.d.ts +8 -2
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/history.d.ts +8 -0
- package/dist/cjs/types/history.d.ts.map +1 -1
- package/dist/cjs/types/index.d.ts +0 -3
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +1 -3
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/route.d.ts +39 -4
- package/dist/cjs/types/route.d.ts.map +1 -1
- package/dist/cjs/types/routing.d.ts +16 -0
- package/dist/cjs/types/routing.d.ts.map +1 -0
- package/dist/cjs/types/routing.js +3 -0
- package/dist/cjs/types/routing.js.map +1 -0
- package/dist/cjs/types/schema.d.ts +22 -0
- package/dist/cjs/types/schema.d.ts.map +1 -0
- package/dist/cjs/types/schema.js +3 -0
- package/dist/cjs/types/schema.js.map +1 -0
- package/dist/cjs/types/session.d.ts +72 -0
- package/dist/cjs/types/session.d.ts.map +1 -0
- package/dist/cjs/types/session.js +140 -0
- package/dist/cjs/types/session.js.map +1 -0
- package/dist/cjs/types/tool.d.ts +11 -5
- package/dist/cjs/types/tool.d.ts.map +1 -1
- package/dist/cjs/utils/id.d.ts +0 -5
- package/dist/cjs/utils/id.d.ts.map +1 -1
- package/dist/cjs/utils/id.js +0 -10
- package/dist/cjs/utils/id.js.map +1 -1
- package/dist/cjs/utils/schema.d.ts +17 -0
- package/dist/cjs/utils/schema.d.ts.map +1 -0
- package/dist/cjs/utils/schema.js +32 -0
- package/dist/cjs/utils/schema.js.map +1 -0
- package/dist/core/Agent.d.ts +22 -29
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +465 -275
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/Events.d.ts +10 -1
- package/dist/core/Events.d.ts.map +1 -1
- package/dist/core/Events.js +3 -2
- package/dist/core/Events.js.map +1 -1
- package/dist/core/PersistenceManager.d.ts +19 -0
- package/dist/core/PersistenceManager.d.ts.map +1 -1
- package/dist/core/PersistenceManager.js +57 -0
- package/dist/core/PersistenceManager.js.map +1 -1
- package/dist/core/PromptComposer.d.ts +24 -0
- package/dist/core/PromptComposer.d.ts.map +1 -0
- package/dist/core/PromptComposer.js +123 -0
- package/dist/core/PromptComposer.js.map +1 -0
- package/dist/core/ResponseEngine.d.ts +19 -0
- package/dist/core/ResponseEngine.d.ts.map +1 -0
- package/dist/core/ResponseEngine.js +47 -0
- package/dist/core/ResponseEngine.js.map +1 -0
- package/dist/core/Route.d.ts +18 -12
- package/dist/core/Route.d.ts.map +1 -1
- package/dist/core/Route.js +15 -9
- package/dist/core/Route.js.map +1 -1
- package/dist/core/RoutingEngine.d.ts +38 -0
- package/dist/core/RoutingEngine.d.ts.map +1 -0
- package/dist/core/RoutingEngine.js +106 -0
- package/dist/core/RoutingEngine.js.map +1 -0
- package/dist/core/State.d.ts +15 -4
- package/dist/core/State.d.ts.map +1 -1
- package/dist/core/State.js +21 -2
- package/dist/core/State.js.map +1 -1
- package/dist/core/ToolExecutor.d.ts +29 -0
- package/dist/core/ToolExecutor.d.ts.map +1 -0
- package/dist/core/ToolExecutor.js +69 -0
- package/dist/core/ToolExecutor.js.map +1 -0
- package/dist/core/Transition.d.ts +5 -5
- package/dist/core/Transition.d.ts.map +1 -1
- package/dist/core/Transition.js.map +1 -1
- package/dist/index.d.ts +6 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/dist/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/AnthropicProvider.js +10 -13
- package/dist/providers/AnthropicProvider.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +12 -8
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/OpenAIProvider.js +10 -53
- package/dist/providers/OpenAIProvider.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/OpenRouterProvider.js +10 -53
- package/dist/providers/OpenRouterProvider.js.map +1 -1
- package/dist/types/agent.d.ts +13 -9
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/ai.d.ts +8 -2
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/history.d.ts +8 -0
- package/dist/types/history.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/route.d.ts +39 -4
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/routing.d.ts +16 -0
- package/dist/types/routing.d.ts.map +1 -0
- package/dist/types/routing.js +2 -0
- package/dist/types/routing.js.map +1 -0
- package/dist/types/schema.d.ts +22 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +2 -0
- package/dist/types/schema.js.map +1 -0
- package/dist/types/session.d.ts +72 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +132 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/tool.d.ts +11 -5
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/utils/id.d.ts +0 -5
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +0 -9
- package/dist/utils/id.js.map +1 -1
- package/dist/utils/schema.d.ts +17 -0
- package/dist/utils/schema.d.ts.map +1 -0
- package/dist/utils/schema.js +27 -0
- package/dist/utils/schema.js.map +1 -0
- package/docs/ADAPTERS.md +83 -3
- package/docs/API_REFERENCE.md +95 -104
- package/docs/ARCHITECTURE.md +284 -286
- package/docs/CONSTRUCTOR_OPTIONS.md +192 -135
- package/docs/CONTEXT_MANAGEMENT.md +311 -28
- package/docs/CONTRIBUTING.md +1 -1
- package/docs/DOMAINS.md +61 -0
- package/docs/GETTING_STARTED.md +177 -88
- package/docs/PERSISTENCE.md +170 -23
- package/docs/README.md +7 -10
- package/examples/business-onboarding.ts +21 -9
- package/examples/company-qna-agent.ts +508 -0
- package/examples/declarative-agent.ts +143 -26
- package/examples/domain-scoping.ts +31 -10
- package/examples/extracted-data-modification.ts +415 -0
- package/examples/healthcare-agent.ts +194 -90
- package/examples/openai-agent.ts +67 -25
- package/examples/opensearch-persistence.ts +455 -151
- package/examples/persistent-onboarding.ts +162 -96
- package/examples/prisma-persistence.ts +371 -125
- package/examples/redis-persistence.ts +393 -23
- package/examples/rules-prohibitions.ts +32 -11
- package/examples/streaming-agent.ts +61 -13
- package/examples/travel-agent.ts +266 -133
- package/package.json +1 -1
- package/src/core/Agent.ts +679 -332
- package/src/core/Events.ts +12 -2
- package/src/core/PersistenceManager.ts +83 -0
- package/src/core/PromptComposer.ts +143 -0
- package/src/core/ResponseEngine.ts +82 -0
- package/src/core/Route.ts +32 -17
- package/src/core/RoutingEngine.ts +165 -0
- package/src/core/State.ts +55 -15
- package/src/core/ToolExecutor.ts +117 -0
- package/src/core/Transition.ts +5 -5
- package/src/index.ts +12 -21
- package/src/providers/AnthropicProvider.ts +10 -13
- package/src/providers/GeminiProvider.ts +12 -8
- package/src/providers/OpenAIProvider.ts +10 -56
- package/src/providers/OpenRouterProvider.ts +10 -56
- package/src/types/agent.ts +16 -10
- package/src/types/ai.ts +6 -2
- package/src/types/history.ts +8 -0
- package/src/types/index.ts +0 -11
- package/src/types/route.ts +41 -5
- package/src/types/routing.ts +18 -0
- package/src/types/schema.ts +23 -0
- package/src/types/session.ts +207 -0
- package/src/types/tool.ts +29 -7
- package/src/utils/id.ts +0 -10
- package/src/utils/schema.ts +32 -0
- package/dist/cjs/core/ConditionEvaluator.d.ts +0 -72
- package/dist/cjs/core/ConditionEvaluator.d.ts.map +0 -1
- package/dist/cjs/core/ConditionEvaluator.js +0 -272
- package/dist/cjs/core/ConditionEvaluator.js.map +0 -1
- package/dist/cjs/core/Observation.d.ts +0 -24
- package/dist/cjs/core/Observation.d.ts.map +0 -1
- package/dist/cjs/core/Observation.js +0 -39
- package/dist/cjs/core/Observation.js.map +0 -1
- package/dist/cjs/core/PreparationEngine.d.ts +0 -105
- package/dist/cjs/core/PreparationEngine.d.ts.map +0 -1
- package/dist/cjs/core/PreparationEngine.js +0 -320
- package/dist/cjs/core/PreparationEngine.js.map +0 -1
- package/dist/cjs/core/PromptBuilder.d.ts +0 -136
- package/dist/cjs/core/PromptBuilder.d.ts.map +0 -1
- package/dist/cjs/core/PromptBuilder.js +0 -421
- package/dist/cjs/core/PromptBuilder.js.map +0 -1
- package/dist/cjs/types/observation.d.ts +0 -27
- package/dist/cjs/types/observation.d.ts.map +0 -1
- package/dist/cjs/types/observation.js +0 -6
- package/dist/cjs/types/observation.js.map +0 -1
- package/dist/cjs/types/prompt.d.ts +0 -46
- package/dist/cjs/types/prompt.d.ts.map +0 -1
- package/dist/cjs/types/prompt.js +0 -19
- package/dist/cjs/types/prompt.js.map +0 -1
- package/dist/core/ConditionEvaluator.d.ts +0 -72
- package/dist/core/ConditionEvaluator.d.ts.map +0 -1
- package/dist/core/ConditionEvaluator.js +0 -268
- package/dist/core/ConditionEvaluator.js.map +0 -1
- package/dist/core/Observation.d.ts +0 -24
- package/dist/core/Observation.d.ts.map +0 -1
- package/dist/core/Observation.js +0 -35
- package/dist/core/Observation.js.map +0 -1
- package/dist/core/PreparationEngine.d.ts +0 -105
- package/dist/core/PreparationEngine.d.ts.map +0 -1
- package/dist/core/PreparationEngine.js +0 -316
- package/dist/core/PreparationEngine.js.map +0 -1
- package/dist/core/PromptBuilder.d.ts +0 -136
- package/dist/core/PromptBuilder.d.ts.map +0 -1
- package/dist/core/PromptBuilder.js +0 -417
- package/dist/core/PromptBuilder.js.map +0 -1
- package/dist/types/observation.d.ts +0 -27
- package/dist/types/observation.d.ts.map +0 -1
- package/dist/types/observation.js +0 -5
- package/dist/types/observation.js.map +0 -1
- package/dist/types/prompt.d.ts +0 -46
- package/dist/types/prompt.d.ts.map +0 -1
- package/dist/types/prompt.js +0 -16
- package/dist/types/prompt.js.map +0 -1
- package/docs/STRUCTURE.md +0 -58
- package/src/core/ConditionEvaluator.ts +0 -381
- package/src/core/Observation.ts +0 -47
- package/src/core/PreparationEngine.ts +0 -500
- package/src/core/PromptBuilder.ts +0 -617
- package/src/types/observation.ts +0 -29
- package/src/types/prompt.ts +0 -49
|
@@ -1,175 +1,479 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OpenSearch Persistence
|
|
2
|
+
* Example: Using OpenSearch for Persistence with Session State
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* 2. Run OpenSearch locally:
|
|
10
|
-
* docker run -d -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" opensearchproject/opensearch:latest
|
|
11
|
-
* 3. Run this example: bun run examples/opensearch-persistence.ts
|
|
4
|
+
* OpenSearch provides powerful persistence with:
|
|
5
|
+
* - Full-text search across conversations
|
|
6
|
+
* - Analytics and aggregations on extracted data
|
|
7
|
+
* - Time-series analysis of sessions
|
|
8
|
+
* - Compatible with Elasticsearch 7.x
|
|
12
9
|
*/
|
|
13
10
|
|
|
14
|
-
// @ts-ignore - OpenSearch is a peer dependency
|
|
15
|
-
import { Client } from "@opensearch-project/opensearch";
|
|
16
11
|
import {
|
|
17
12
|
Agent,
|
|
18
13
|
GeminiProvider,
|
|
19
14
|
OpenSearchAdapter,
|
|
20
|
-
defineTool,
|
|
21
15
|
createMessageEvent,
|
|
22
16
|
EventSource,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
autoCreateIndices: true, // Automatically create indices with mappings
|
|
44
|
-
refresh: "wait_for", // Wait for documents to be searchable (slower but consistent)
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Define context type
|
|
48
|
-
interface TravelContext {
|
|
17
|
+
MessageEventData,
|
|
18
|
+
Event,
|
|
19
|
+
} from "../src/index";
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
import { Client } from "@opensearch-project/opensearch";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Setup Steps:
|
|
25
|
+
*
|
|
26
|
+
* 1. Install OpenSearch and client:
|
|
27
|
+
* brew install opensearch (macOS) or docker run opensearch
|
|
28
|
+
* npm install @opensearch-project/opensearch
|
|
29
|
+
*
|
|
30
|
+
* 2. Start OpenSearch:
|
|
31
|
+
* opensearch or docker start opensearch
|
|
32
|
+
*
|
|
33
|
+
* 3. Run this example
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
interface ConversationContext {
|
|
49
37
|
userId: string;
|
|
50
38
|
userName: string;
|
|
39
|
+
department: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface ComplaintData {
|
|
43
|
+
category: string;
|
|
44
|
+
severity: "low" | "medium" | "high" | "critical";
|
|
45
|
+
description: string;
|
|
46
|
+
affectedService?: string;
|
|
47
|
+
requestedResolution?: string;
|
|
51
48
|
}
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
50
|
+
async function example() {
|
|
51
|
+
// Initialize OpenSearch client
|
|
52
|
+
const client = new Client({
|
|
53
|
+
node: process.env.OPENSEARCH_URL || "https://localhost:9200",
|
|
54
|
+
ssl: {
|
|
55
|
+
rejectUnauthorized: false, // For development only
|
|
56
|
+
},
|
|
57
|
+
auth: {
|
|
58
|
+
username: "admin",
|
|
59
|
+
password: "admin",
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const userId = "user_123";
|
|
64
|
+
|
|
65
|
+
// Create adapter
|
|
66
|
+
const adapter = new OpenSearchAdapter(client, {
|
|
67
|
+
indices: {
|
|
68
|
+
sessions: "agent_sessions",
|
|
69
|
+
messages: "agent_messages",
|
|
70
|
+
},
|
|
71
|
+
autoCreateIndices: true,
|
|
72
|
+
refresh: "wait_for", // Ensure searchability immediately
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Initialize indices
|
|
76
|
+
await adapter.initialize();
|
|
77
|
+
|
|
78
|
+
// Create agent with OpenSearch persistence
|
|
79
|
+
const agent = new Agent<ConversationContext>({
|
|
80
|
+
name: "Customer Service Agent",
|
|
81
|
+
description: "Handle customer complaints with full-text search",
|
|
82
|
+
goal: "Resolve customer issues efficiently",
|
|
83
|
+
ai: new GeminiProvider({
|
|
84
|
+
apiKey: process.env.GEMINI_API_KEY!,
|
|
85
|
+
model: "models/gemini-2.0-flash-exp",
|
|
86
|
+
}),
|
|
87
|
+
context: {
|
|
88
|
+
userId,
|
|
89
|
+
userName: "Alice",
|
|
90
|
+
department: "customer_service",
|
|
91
|
+
},
|
|
92
|
+
persistence: {
|
|
93
|
+
adapter,
|
|
94
|
+
autoSave: true, // Auto-save session state with extracted data
|
|
95
|
+
userId,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Create complaint handling route
|
|
100
|
+
const complaintRoute = agent.createRoute<ComplaintData>({
|
|
101
|
+
title: "Handle Customer Complaint",
|
|
102
|
+
description: "Process and resolve customer complaints",
|
|
103
|
+
conditions: [
|
|
104
|
+
"User has a complaint",
|
|
105
|
+
"User reports an issue or problem",
|
|
106
|
+
"User is dissatisfied",
|
|
107
|
+
],
|
|
108
|
+
gatherSchema: {
|
|
109
|
+
type: "object",
|
|
110
|
+
properties: {
|
|
111
|
+
category: {
|
|
112
|
+
type: "string",
|
|
113
|
+
description: "Complaint category",
|
|
114
|
+
},
|
|
115
|
+
severity: {
|
|
116
|
+
type: "string",
|
|
117
|
+
enum: ["low", "medium", "high", "critical"],
|
|
118
|
+
default: "medium",
|
|
119
|
+
description: "Severity level",
|
|
120
|
+
},
|
|
121
|
+
description: {
|
|
122
|
+
type: "string",
|
|
123
|
+
description: "Detailed complaint description",
|
|
124
|
+
},
|
|
125
|
+
affectedService: {
|
|
126
|
+
type: "string",
|
|
127
|
+
description: "Which service is affected",
|
|
128
|
+
},
|
|
129
|
+
requestedResolution: {
|
|
130
|
+
type: "string",
|
|
131
|
+
description: "What resolution the customer wants",
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
required: ["category", "severity", "description"],
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// State flow
|
|
139
|
+
complaintRoute.initialState
|
|
140
|
+
.transitionTo({
|
|
141
|
+
chatState: "Understand the complaint",
|
|
142
|
+
gather: ["category", "severity", "description"],
|
|
143
|
+
skipIf: (data) => !!data.description,
|
|
144
|
+
})
|
|
145
|
+
.transitionTo({
|
|
146
|
+
chatState: "Identify affected service",
|
|
147
|
+
gather: ["affectedService"],
|
|
148
|
+
skipIf: (data) => !!data.affectedService,
|
|
149
|
+
requiredData: ["description"],
|
|
150
|
+
})
|
|
151
|
+
.transitionTo({
|
|
152
|
+
chatState: "Ask for desired resolution",
|
|
153
|
+
gather: ["requestedResolution"],
|
|
154
|
+
skipIf: (data) => !!data.requestedResolution,
|
|
155
|
+
requiredData: ["category", "description"],
|
|
156
|
+
})
|
|
157
|
+
.transitionTo({
|
|
158
|
+
chatState: "Propose solution and close complaint",
|
|
159
|
+
requiredData: ["category", "description"],
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const persistence = agent.getPersistenceManager();
|
|
163
|
+
if (!persistence) return;
|
|
164
|
+
|
|
165
|
+
// Create session with state
|
|
166
|
+
const { sessionData, sessionState } =
|
|
167
|
+
await persistence.createSessionWithState<ComplaintData>({
|
|
168
|
+
userId,
|
|
169
|
+
agentName: "Customer Service Agent",
|
|
170
|
+
initialData: {
|
|
171
|
+
severity: "medium",
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
console.log("⨠Session created in OpenSearch:", sessionData.id);
|
|
176
|
+
|
|
177
|
+
// Conversation flow
|
|
178
|
+
const history: Event<MessageEventData>[] = [];
|
|
179
|
+
let session = sessionState;
|
|
180
|
+
|
|
181
|
+
// Turn 1
|
|
182
|
+
console.log("\n--- Turn 1 ---");
|
|
183
|
+
const message1 = createMessageEvent(
|
|
184
|
+
EventSource.CUSTOMER,
|
|
185
|
+
"Alice",
|
|
186
|
+
"I'm very upset! Your app keeps crashing when I try to make a payment. This is critical!"
|
|
187
|
+
);
|
|
188
|
+
history.push(message1);
|
|
189
|
+
|
|
190
|
+
const response1 = await agent.respond({ history, session });
|
|
191
|
+
|
|
192
|
+
console.log("š¤ Agent:", response1.message);
|
|
193
|
+
console.log("š Extracted:", response1.session?.extracted);
|
|
194
|
+
|
|
195
|
+
await persistence.saveMessage({
|
|
196
|
+
sessionId: sessionData.id,
|
|
197
|
+
role: "user",
|
|
198
|
+
content: message1.data.message,
|
|
199
|
+
event: message1,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
await persistence.saveMessage({
|
|
203
|
+
sessionId: sessionData.id,
|
|
204
|
+
role: "agent",
|
|
205
|
+
content: response1.message,
|
|
206
|
+
route: response1.session?.currentRoute?.id,
|
|
207
|
+
state: response1.session?.currentState?.id,
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
session = response1.session!;
|
|
211
|
+
|
|
212
|
+
// Turn 2
|
|
213
|
+
console.log("\n--- Turn 2 ---");
|
|
214
|
+
history.push(
|
|
215
|
+
createMessageEvent(EventSource.AI_AGENT, "Agent", response1.message)
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
const message2 = createMessageEvent(
|
|
219
|
+
EventSource.CUSTOMER,
|
|
220
|
+
"Alice",
|
|
221
|
+
"It's the payment service. I want a full refund and compensation!"
|
|
222
|
+
);
|
|
223
|
+
history.push(message2);
|
|
224
|
+
|
|
225
|
+
const response2 = await agent.respond({ history, session });
|
|
226
|
+
|
|
227
|
+
console.log("š¤ Agent:", response2.message);
|
|
228
|
+
console.log("š Extracted:", response2.session?.extracted);
|
|
229
|
+
|
|
230
|
+
await persistence.saveMessage({
|
|
231
|
+
sessionId: sessionData.id,
|
|
232
|
+
role: "user",
|
|
233
|
+
content: message2.data.message,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
await persistence.saveMessage({
|
|
237
|
+
sessionId: sessionData.id,
|
|
238
|
+
role: "agent",
|
|
239
|
+
content: response2.message,
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// Load session from OpenSearch
|
|
243
|
+
console.log("\n--- Loading Session from OpenSearch ---");
|
|
244
|
+
const loadedSession = await persistence.loadSessionState<ComplaintData>(
|
|
245
|
+
sessionData.id
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
console.log("š„ Loaded session:", {
|
|
249
|
+
currentRoute: loadedSession?.currentRoute?.title,
|
|
250
|
+
extracted: loadedSession?.extracted,
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// Demonstrate full-text search
|
|
254
|
+
console.log("\n--- Full-Text Search Example ---");
|
|
255
|
+
const searchResults = await client.search({
|
|
256
|
+
index: "agent_messages",
|
|
257
|
+
body: {
|
|
258
|
+
query: {
|
|
259
|
+
match: {
|
|
260
|
+
content: "payment crash",
|
|
261
|
+
},
|
|
66
262
|
},
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
console.log(
|
|
267
|
+
`š Found ${searchResults.body.hits.total.value} messages matching "payment crash"`
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
// Demonstrate aggregations
|
|
271
|
+
console.log("\n--- Analytics Example ---");
|
|
272
|
+
const aggResults = await client.search({
|
|
273
|
+
index: "agent_sessions",
|
|
274
|
+
body: {
|
|
275
|
+
size: 0,
|
|
276
|
+
aggs: {
|
|
277
|
+
by_status: {
|
|
278
|
+
terms: { field: "status.keyword" },
|
|
279
|
+
},
|
|
280
|
+
by_agent: {
|
|
281
|
+
terms: { field: "agentName.keyword" },
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
console.log("š Session statistics:", aggResults.body.aggregations);
|
|
288
|
+
|
|
289
|
+
// Complete session
|
|
290
|
+
await persistence.completeSession(sessionData.id);
|
|
291
|
+
console.log("\nā
Session completed and indexed!");
|
|
292
|
+
|
|
293
|
+
// Cleanup
|
|
294
|
+
if (adapter.disconnect) {
|
|
295
|
+
await adapter.disconnect();
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Advanced Example: Search and Analytics on Extracted Data
|
|
301
|
+
*/
|
|
302
|
+
async function analyticsExample() {
|
|
303
|
+
const client = new Client({
|
|
304
|
+
node: process.env.OPENSEARCH_URL || "https://localhost:9200",
|
|
305
|
+
ssl: { rejectUnauthorized: false },
|
|
306
|
+
auth: { username: "admin", password: "admin" },
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const adapter = new OpenSearchAdapter(client, {
|
|
310
|
+
indices: {
|
|
311
|
+
sessions: "support_sessions",
|
|
312
|
+
messages: "support_messages",
|
|
313
|
+
},
|
|
314
|
+
autoCreateIndices: true,
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
await adapter.initialize();
|
|
318
|
+
|
|
319
|
+
interface TicketData {
|
|
320
|
+
ticketType: string;
|
|
321
|
+
priority: string;
|
|
322
|
+
tags: string[];
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const agent = new Agent({
|
|
326
|
+
name: "Support Analyzer",
|
|
327
|
+
ai: new GeminiProvider({
|
|
328
|
+
apiKey: process.env.GEMINI_API_KEY!,
|
|
329
|
+
model: "models/gemini-2.0-flash-exp",
|
|
330
|
+
}),
|
|
331
|
+
persistence: {
|
|
332
|
+
adapter,
|
|
333
|
+
autoSave: true,
|
|
334
|
+
userId: "analyst_001",
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
const ticketRoute = agent.createRoute<TicketData>({
|
|
339
|
+
title: "Analyze Support Ticket",
|
|
340
|
+
gatherSchema: {
|
|
72
341
|
type: "object",
|
|
73
342
|
properties: {
|
|
74
|
-
|
|
75
|
-
|
|
343
|
+
ticketType: { type: "string" },
|
|
344
|
+
priority: { type: "string" },
|
|
345
|
+
tags: {
|
|
346
|
+
type: "array",
|
|
347
|
+
items: { type: "string" },
|
|
348
|
+
},
|
|
76
349
|
},
|
|
77
|
-
required: ["
|
|
350
|
+
required: ["ticketType", "priority"],
|
|
78
351
|
},
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
ticketRoute.initialState.transitionTo({
|
|
355
|
+
chatState: "Analyze and categorize ticket",
|
|
356
|
+
gather: ["ticketType", "priority", "tags"],
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
const persistence = agent.getPersistenceManager()!;
|
|
360
|
+
|
|
361
|
+
// Create multiple sessions
|
|
362
|
+
for (let i = 0; i < 3; i++) {
|
|
363
|
+
const { sessionData, sessionState } =
|
|
364
|
+
await persistence.createSessionWithState<TicketData>({
|
|
365
|
+
userId: "analyst_001",
|
|
366
|
+
agentName: "Support Analyzer",
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
const response = await agent.respond({
|
|
370
|
+
history: [
|
|
371
|
+
createMessageEvent(
|
|
372
|
+
EventSource.CUSTOMER,
|
|
373
|
+
"User",
|
|
374
|
+
`Support ticket ${i + 1}: ${
|
|
375
|
+
["Billing issue", "Technical problem", "Feature request"][i]
|
|
376
|
+
}`
|
|
377
|
+
),
|
|
378
|
+
],
|
|
379
|
+
session: sessionState,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
await persistence.saveMessage({
|
|
383
|
+
sessionId: sessionData.id,
|
|
384
|
+
role: "agent",
|
|
385
|
+
content: response.message,
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
await persistence.completeSession(sessionData.id);
|
|
79
389
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
apiKey: process.env.GEMINI_API_KEY || "",
|
|
88
|
-
model: "gemini-2.0-flash-exp",
|
|
89
|
-
}),
|
|
90
|
-
context: {
|
|
91
|
-
userId: "user_123",
|
|
92
|
-
userName: "Alex",
|
|
93
|
-
},
|
|
94
|
-
persistence: {
|
|
95
|
-
adapter,
|
|
96
|
-
autoSave: true,
|
|
97
|
-
userId: "user_123",
|
|
98
|
-
},
|
|
99
|
-
capabilities: [
|
|
100
|
-
{
|
|
101
|
-
title: "Flight Booking",
|
|
102
|
-
description: "Book flights for travel",
|
|
103
|
-
tools: [bookFlight],
|
|
390
|
+
|
|
391
|
+
// Search across all sessions
|
|
392
|
+
console.log("\n--- Search All Sessions ---");
|
|
393
|
+
const allSessions = await client.search({
|
|
394
|
+
index: "support_sessions",
|
|
395
|
+
body: {
|
|
396
|
+
query: { match_all: {} },
|
|
104
397
|
},
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const history2 = [
|
|
128
|
-
...history1,
|
|
129
|
-
createMessageEvent(
|
|
130
|
-
EventSource.AI_AGENT,
|
|
131
|
-
"Travel Assistant",
|
|
132
|
-
response.message
|
|
133
|
-
),
|
|
134
|
-
createMessageEvent(
|
|
135
|
-
EventSource.CUSTOMER,
|
|
136
|
-
"Alex",
|
|
137
|
-
"Make it for next Monday"
|
|
138
|
-
),
|
|
139
|
-
];
|
|
140
|
-
response = await agent.respond({ history: history2 });
|
|
141
|
-
console.log("š¤ Agent:", response.message);
|
|
142
|
-
console.log();
|
|
143
|
-
|
|
144
|
-
// Get persistence manager
|
|
145
|
-
const pm = agent.getPersistenceManager();
|
|
146
|
-
if (pm) {
|
|
147
|
-
// Query sessions
|
|
148
|
-
const sessions = await pm.getUserSessions("user_123");
|
|
149
|
-
console.log(`š Found ${sessions.length} session(s) for user_123`);
|
|
150
|
-
|
|
151
|
-
if (sessions.length > 0) {
|
|
152
|
-
const session = sessions[0];
|
|
153
|
-
console.log(` Session ID: ${session.id}`);
|
|
154
|
-
console.log(` Status: ${session.status}`);
|
|
155
|
-
console.log(` Messages: ${session.messageCount || 0}`);
|
|
156
|
-
console.log();
|
|
157
|
-
|
|
158
|
-
// Query messages
|
|
159
|
-
const messages = await pm.getSessionMessages(session.id);
|
|
160
|
-
console.log(`š Session has ${messages.length} message(s):`);
|
|
161
|
-
messages.forEach((msg, idx) => {
|
|
162
|
-
console.log(
|
|
163
|
-
` ${idx + 1}. [${msg.role}] ${msg.content.substring(0, 50)}...`
|
|
164
|
-
);
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
console.log("\nā
OpenSearch persistence example completed!");
|
|
170
|
-
} catch (error) {
|
|
171
|
-
console.error("ā Error:", error);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
console.log(
|
|
401
|
+
`š Total sessions indexed: ${allSessions.body.hits.total.value}`
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
// Analyze extracted data patterns
|
|
405
|
+
console.log("\n--- Analyze Extracted Data ---");
|
|
406
|
+
const sessions = allSessions.body.hits.hits;
|
|
407
|
+
|
|
408
|
+
sessions.forEach((hit: any) => {
|
|
409
|
+
const collectedData = hit._source.collectedData;
|
|
410
|
+
console.log(`Session ${hit._id}:`, {
|
|
411
|
+
extracted: collectedData?.extracted,
|
|
412
|
+
route: hit._source.currentRoute,
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
console.log("ā
Analytics complete!");
|
|
417
|
+
|
|
418
|
+
if (adapter.disconnect) {
|
|
419
|
+
await adapter.disconnect();
|
|
172
420
|
}
|
|
173
421
|
}
|
|
174
422
|
|
|
175
|
-
|
|
423
|
+
/**
|
|
424
|
+
* Time-Series Analysis Example
|
|
425
|
+
*/
|
|
426
|
+
async function timeSeriesExample() {
|
|
427
|
+
const client = new Client({
|
|
428
|
+
node: process.env.OPENSEARCH_URL || "https://localhost:9200",
|
|
429
|
+
ssl: { rejectUnauthorized: false },
|
|
430
|
+
auth: { username: "admin", password: "admin" },
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
const adapter = new OpenSearchAdapter(client);
|
|
434
|
+
await adapter.initialize();
|
|
435
|
+
|
|
436
|
+
const agent = new Agent({
|
|
437
|
+
name: "Metrics Agent",
|
|
438
|
+
ai: new GeminiProvider({
|
|
439
|
+
apiKey: process.env.GEMINI_API_KEY!,
|
|
440
|
+
model: "models/gemini-2.0-flash-exp",
|
|
441
|
+
}),
|
|
442
|
+
persistence: { adapter, userId: "metrics_user" },
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
const persistence = agent.getPersistenceManager()!;
|
|
446
|
+
|
|
447
|
+
// Query sessions over time
|
|
448
|
+
const timeQuery = await client.search({
|
|
449
|
+
index: "agent_sessions",
|
|
450
|
+
body: {
|
|
451
|
+
size: 0,
|
|
452
|
+
aggs: {
|
|
453
|
+
sessions_over_time: {
|
|
454
|
+
date_histogram: {
|
|
455
|
+
field: "createdAt",
|
|
456
|
+
calendar_interval: "day",
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
avg_message_count: {
|
|
460
|
+
avg: { field: "messageCount" },
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
console.log("š Time-series metrics:", timeQuery.body.aggregations);
|
|
467
|
+
console.log("ā
Time-series analysis complete!");
|
|
468
|
+
|
|
469
|
+
if (adapter.disconnect) {
|
|
470
|
+
await adapter.disconnect();
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// Run the example
|
|
475
|
+
if (require.main === module) {
|
|
476
|
+
example().catch(console.error);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
export { example, analyticsExample, timeSeriesExample };
|