@falai/agent 0.3.12 → 0.3.21
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 +74 -0
- package/dist/adapters/MemoryAdapter.d.ts +47 -0
- package/dist/adapters/MemoryAdapter.d.ts.map +1 -0
- package/dist/adapters/MemoryAdapter.js +178 -0
- package/dist/adapters/MemoryAdapter.js.map +1 -0
- package/dist/adapters/MongoAdapter.d.ts +97 -0
- package/dist/adapters/MongoAdapter.d.ts.map +1 -0
- package/dist/adapters/MongoAdapter.js +163 -0
- package/dist/adapters/MongoAdapter.js.map +1 -0
- package/dist/adapters/PostgreSQLAdapter.d.ts +71 -0
- package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -0
- package/dist/adapters/PostgreSQLAdapter.js +256 -0
- package/dist/adapters/PostgreSQLAdapter.js.map +1 -0
- package/dist/adapters/RedisAdapter.d.ts +71 -0
- package/dist/adapters/RedisAdapter.d.ts.map +1 -0
- package/dist/adapters/RedisAdapter.js +226 -0
- package/dist/adapters/RedisAdapter.js.map +1 -0
- package/dist/adapters/SQLiteAdapter.d.ts +69 -0
- package/dist/adapters/SQLiteAdapter.d.ts.map +1 -0
- package/dist/adapters/SQLiteAdapter.js +307 -0
- package/dist/adapters/SQLiteAdapter.js.map +1 -0
- package/dist/adapters/index.d.ts +9 -0
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +5 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/cjs/adapters/MemoryAdapter.d.ts +47 -0
- package/dist/cjs/adapters/MemoryAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/MemoryAdapter.js +182 -0
- package/dist/cjs/adapters/MemoryAdapter.js.map +1 -0
- package/dist/cjs/adapters/MongoAdapter.d.ts +97 -0
- package/dist/cjs/adapters/MongoAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/MongoAdapter.js +167 -0
- package/dist/cjs/adapters/MongoAdapter.js.map +1 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +71 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.js +260 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -0
- package/dist/cjs/adapters/RedisAdapter.d.ts +71 -0
- package/dist/cjs/adapters/RedisAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/RedisAdapter.js +230 -0
- package/dist/cjs/adapters/RedisAdapter.js.map +1 -0
- package/dist/cjs/adapters/SQLiteAdapter.d.ts +69 -0
- package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/SQLiteAdapter.js +311 -0
- package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -0
- package/dist/cjs/adapters/index.d.ts +9 -0
- package/dist/cjs/adapters/index.d.ts.map +1 -1
- package/dist/cjs/adapters/index.js +11 -1
- package/dist/cjs/adapters/index.js.map +1 -1
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +11 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/docs/ADAPTERS.md +151 -0
- package/docs/API_REFERENCE.md +448 -0
- package/docs/PERSISTENCE.md +176 -6
- package/examples/redis-persistence.ts +89 -0
- package/package.json +26 -2
- package/src/adapters/MemoryAdapter.ts +245 -0
- package/src/adapters/MongoAdapter.ts +295 -0
- package/src/adapters/PostgreSQLAdapter.ts +417 -0
- package/src/adapters/RedisAdapter.ts +365 -0
- package/src/adapters/SQLiteAdapter.ts +449 -0
- package/src/adapters/index.ts +27 -0
- package/src/index.ts +22 -0
package/docs/API_REFERENCE.md
CHANGED
|
@@ -672,6 +672,454 @@ const provider = new OpenRouterProvider({
|
|
|
672
672
|
|
|
673
673
|
---
|
|
674
674
|
|
|
675
|
+
## Persistence Adapters
|
|
676
|
+
|
|
677
|
+
Optional persistence for auto-saving sessions and messages. All adapters implement the `PersistenceAdapter` interface.
|
|
678
|
+
|
|
679
|
+
### `PersistenceManager`
|
|
680
|
+
|
|
681
|
+
Manages persistence operations for sessions and messages.
|
|
682
|
+
|
|
683
|
+
#### Constructor
|
|
684
|
+
|
|
685
|
+
```typescript
|
|
686
|
+
new PersistenceManager(config: PersistenceConfig)
|
|
687
|
+
|
|
688
|
+
interface PersistenceConfig {
|
|
689
|
+
adapter: PersistenceAdapter;
|
|
690
|
+
autoSave?: boolean; // Default: true
|
|
691
|
+
userId?: string; // Optional: associate with user
|
|
692
|
+
}
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
#### Methods
|
|
696
|
+
|
|
697
|
+
##### `createSession(data: Partial<SessionData>): Promise<SessionData>`
|
|
698
|
+
|
|
699
|
+
Creates a new conversation session.
|
|
700
|
+
|
|
701
|
+
```typescript
|
|
702
|
+
const session = await persistence.createSession({
|
|
703
|
+
userId: "user_123",
|
|
704
|
+
agentName: "Support Bot",
|
|
705
|
+
initialData: { channel: "web" },
|
|
706
|
+
});
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
##### `getSession(sessionId: string): Promise<SessionData | null>`
|
|
710
|
+
|
|
711
|
+
Retrieves a session by ID.
|
|
712
|
+
|
|
713
|
+
##### `findActiveSession(userId: string): Promise<SessionData | null>`
|
|
714
|
+
|
|
715
|
+
Finds the active session for a user.
|
|
716
|
+
|
|
717
|
+
##### `getUserSessions(userId: string, limit?: number): Promise<SessionData[]>`
|
|
718
|
+
|
|
719
|
+
Gets all sessions for a user.
|
|
720
|
+
|
|
721
|
+
##### `updateSessionStatus(sessionId: string, status: SessionStatus): Promise<SessionData | null>`
|
|
722
|
+
|
|
723
|
+
Updates session status ("active" | "completed" | "abandoned").
|
|
724
|
+
|
|
725
|
+
##### `saveMessage(data: Partial<MessageData>): Promise<MessageData>`
|
|
726
|
+
|
|
727
|
+
Saves a message to the database.
|
|
728
|
+
|
|
729
|
+
```typescript
|
|
730
|
+
await persistence.saveMessage({
|
|
731
|
+
sessionId: session.id,
|
|
732
|
+
role: "user",
|
|
733
|
+
content: "Hello!",
|
|
734
|
+
});
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
##### `getSessionMessages(sessionId: string, limit?: number): Promise<MessageData[]>`
|
|
738
|
+
|
|
739
|
+
Gets all messages for a session.
|
|
740
|
+
|
|
741
|
+
##### `loadSessionHistory(sessionId: string, limit?: number): Promise<Event[]>`
|
|
742
|
+
|
|
743
|
+
Loads session history in Event format for agent.respond().
|
|
744
|
+
|
|
745
|
+
```typescript
|
|
746
|
+
const history = await persistence.loadSessionHistory(sessionId);
|
|
747
|
+
const response = await agent.respond({ history });
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
##### `completeSession(sessionId: string): Promise<SessionData | null>`
|
|
751
|
+
|
|
752
|
+
Marks a session as completed.
|
|
753
|
+
|
|
754
|
+
##### `abandonSession(sessionId: string): Promise<SessionData | null>`
|
|
755
|
+
|
|
756
|
+
Marks a session as abandoned.
|
|
757
|
+
|
|
758
|
+
---
|
|
759
|
+
|
|
760
|
+
### `PrismaAdapter`
|
|
761
|
+
|
|
762
|
+
Type-safe ORM adapter with migrations support.
|
|
763
|
+
|
|
764
|
+
#### Constructor
|
|
765
|
+
|
|
766
|
+
```typescript
|
|
767
|
+
new PrismaAdapter(options: PrismaAdapterOptions)
|
|
768
|
+
|
|
769
|
+
interface PrismaAdapterOptions {
|
|
770
|
+
prisma: PrismaClient;
|
|
771
|
+
autoMigrate?: boolean; // Default: false
|
|
772
|
+
tables?: {
|
|
773
|
+
sessions?: string; // Default: "AgentSession"
|
|
774
|
+
messages?: string; // Default: "AgentMessage"
|
|
775
|
+
};
|
|
776
|
+
fieldMappings?: FieldMappings; // Custom field names
|
|
777
|
+
}
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
#### Example
|
|
781
|
+
|
|
782
|
+
```typescript
|
|
783
|
+
import { PrismaAdapter } from "@falai/agent";
|
|
784
|
+
import { PrismaClient } from "@prisma/client";
|
|
785
|
+
|
|
786
|
+
const prisma = new PrismaClient();
|
|
787
|
+
|
|
788
|
+
const agent = new Agent({
|
|
789
|
+
persistence: {
|
|
790
|
+
adapter: new PrismaAdapter({
|
|
791
|
+
prisma,
|
|
792
|
+
autoMigrate: true, // Auto-run migrations
|
|
793
|
+
tables: {
|
|
794
|
+
sessions: "CustomSessions",
|
|
795
|
+
messages: "CustomMessages",
|
|
796
|
+
},
|
|
797
|
+
}),
|
|
798
|
+
userId: "user_123",
|
|
799
|
+
},
|
|
800
|
+
});
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
**Schema Example:** See [examples/prisma-schema.example.prisma](../examples/prisma-schema.example.prisma)
|
|
804
|
+
|
|
805
|
+
**Full Example:** See [examples/prisma-persistence.ts](../examples/prisma-persistence.ts)
|
|
806
|
+
|
|
807
|
+
---
|
|
808
|
+
|
|
809
|
+
### `RedisAdapter`
|
|
810
|
+
|
|
811
|
+
Fast, in-memory persistence for high-throughput applications.
|
|
812
|
+
|
|
813
|
+
#### Constructor
|
|
814
|
+
|
|
815
|
+
```typescript
|
|
816
|
+
new RedisAdapter(options: RedisAdapterOptions)
|
|
817
|
+
|
|
818
|
+
interface RedisAdapterOptions {
|
|
819
|
+
redis: RedisClient; // ioredis or redis client
|
|
820
|
+
keyPrefix?: string; // Default: "agent:"
|
|
821
|
+
sessionTTL?: number; // Default: 7 days (in seconds)
|
|
822
|
+
messageTTL?: number; // Default: 30 days (in seconds)
|
|
823
|
+
}
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
#### Example
|
|
827
|
+
|
|
828
|
+
```typescript
|
|
829
|
+
import { RedisAdapter } from "@falai/agent";
|
|
830
|
+
import Redis from "ioredis";
|
|
831
|
+
|
|
832
|
+
const redis = new Redis();
|
|
833
|
+
|
|
834
|
+
const agent = new Agent({
|
|
835
|
+
persistence: {
|
|
836
|
+
adapter: new RedisAdapter({
|
|
837
|
+
redis,
|
|
838
|
+
keyPrefix: "chat:",
|
|
839
|
+
sessionTTL: 24 * 60 * 60, // 24 hours
|
|
840
|
+
messageTTL: 7 * 24 * 60 * 60, // 7 days
|
|
841
|
+
}),
|
|
842
|
+
},
|
|
843
|
+
});
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
**Install:** `npm install ioredis` or `npm install redis`
|
|
847
|
+
|
|
848
|
+
**Full Example:** See [examples/redis-persistence.ts](../examples/redis-persistence.ts)
|
|
849
|
+
|
|
850
|
+
---
|
|
851
|
+
|
|
852
|
+
### `MongoAdapter`
|
|
853
|
+
|
|
854
|
+
Document-based storage with flexible schema.
|
|
855
|
+
|
|
856
|
+
#### Constructor
|
|
857
|
+
|
|
858
|
+
```typescript
|
|
859
|
+
new MongoAdapter(options: MongoAdapterOptions)
|
|
860
|
+
|
|
861
|
+
interface MongoAdapterOptions {
|
|
862
|
+
client: MongoClient;
|
|
863
|
+
databaseName: string;
|
|
864
|
+
collections?: {
|
|
865
|
+
sessions?: string; // Default: "agent_sessions"
|
|
866
|
+
messages?: string; // Default: "agent_messages"
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
#### Example
|
|
872
|
+
|
|
873
|
+
```typescript
|
|
874
|
+
import { MongoAdapter } from "@falai/agent";
|
|
875
|
+
import { MongoClient } from "mongodb";
|
|
876
|
+
|
|
877
|
+
const client = new MongoClient("mongodb://localhost:27017");
|
|
878
|
+
await client.connect();
|
|
879
|
+
|
|
880
|
+
const agent = new Agent({
|
|
881
|
+
persistence: {
|
|
882
|
+
adapter: new MongoAdapter({
|
|
883
|
+
client,
|
|
884
|
+
databaseName: "myapp",
|
|
885
|
+
collections: {
|
|
886
|
+
sessions: "chat_sessions",
|
|
887
|
+
messages: "chat_messages",
|
|
888
|
+
},
|
|
889
|
+
}),
|
|
890
|
+
},
|
|
891
|
+
});
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
**Install:** `npm install mongodb`
|
|
895
|
+
|
|
896
|
+
---
|
|
897
|
+
|
|
898
|
+
### `PostgreSQLAdapter`
|
|
899
|
+
|
|
900
|
+
Raw SQL adapter with auto table/index creation.
|
|
901
|
+
|
|
902
|
+
#### Constructor
|
|
903
|
+
|
|
904
|
+
```typescript
|
|
905
|
+
new PostgreSQLAdapter(options: PostgreSQLAdapterOptions)
|
|
906
|
+
|
|
907
|
+
interface PostgreSQLAdapterOptions {
|
|
908
|
+
client: PgClient; // pg client
|
|
909
|
+
tables?: {
|
|
910
|
+
sessions?: string; // Default: "agent_sessions"
|
|
911
|
+
messages?: string; // Default: "agent_messages"
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
#### Methods
|
|
917
|
+
|
|
918
|
+
##### `initialize(): Promise<void>`
|
|
919
|
+
|
|
920
|
+
Creates tables and indexes if they don't exist.
|
|
921
|
+
|
|
922
|
+
#### Example
|
|
923
|
+
|
|
924
|
+
```typescript
|
|
925
|
+
import { PostgreSQLAdapter } from "@falai/agent";
|
|
926
|
+
import { Client } from "pg";
|
|
927
|
+
|
|
928
|
+
const client = new Client({
|
|
929
|
+
host: "localhost",
|
|
930
|
+
database: "myapp",
|
|
931
|
+
user: "postgres",
|
|
932
|
+
password: "password",
|
|
933
|
+
});
|
|
934
|
+
await client.connect();
|
|
935
|
+
|
|
936
|
+
const adapter = new PostgreSQLAdapter({ client });
|
|
937
|
+
|
|
938
|
+
// Auto-create tables
|
|
939
|
+
await adapter.initialize();
|
|
940
|
+
|
|
941
|
+
const agent = new Agent({
|
|
942
|
+
persistence: { adapter },
|
|
943
|
+
});
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
**Install:** `npm install pg`
|
|
947
|
+
|
|
948
|
+
---
|
|
949
|
+
|
|
950
|
+
### `SQLiteAdapter`
|
|
951
|
+
|
|
952
|
+
Lightweight, file-based database for local development.
|
|
953
|
+
|
|
954
|
+
#### Constructor
|
|
955
|
+
|
|
956
|
+
```typescript
|
|
957
|
+
new SQLiteAdapter(options: SQLiteAdapterOptions)
|
|
958
|
+
|
|
959
|
+
interface SQLiteAdapterOptions {
|
|
960
|
+
db: SqliteDatabase; // better-sqlite3 database
|
|
961
|
+
tables?: {
|
|
962
|
+
sessions?: string; // Default: "agent_sessions"
|
|
963
|
+
messages?: string; // Default: "agent_messages"
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
#### Methods
|
|
969
|
+
|
|
970
|
+
##### `initialize(): Promise<void>`
|
|
971
|
+
|
|
972
|
+
Creates tables and indexes if they don't exist.
|
|
973
|
+
|
|
974
|
+
#### Example
|
|
975
|
+
|
|
976
|
+
```typescript
|
|
977
|
+
import { SQLiteAdapter } from "@falai/agent";
|
|
978
|
+
import Database from "better-sqlite3";
|
|
979
|
+
|
|
980
|
+
const db = new Database("agent.db");
|
|
981
|
+
const adapter = new SQLiteAdapter({ db });
|
|
982
|
+
|
|
983
|
+
// Auto-create tables
|
|
984
|
+
await adapter.initialize();
|
|
985
|
+
|
|
986
|
+
const agent = new Agent({
|
|
987
|
+
persistence: { adapter },
|
|
988
|
+
});
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
**Install:** `npm install better-sqlite3`
|
|
992
|
+
|
|
993
|
+
**Perfect for:** Local development, testing, desktop apps, single-user applications
|
|
994
|
+
|
|
995
|
+
---
|
|
996
|
+
|
|
997
|
+
### `MemoryAdapter`
|
|
998
|
+
|
|
999
|
+
Zero-dependency in-memory storage for testing and development.
|
|
1000
|
+
|
|
1001
|
+
#### Constructor
|
|
1002
|
+
|
|
1003
|
+
```typescript
|
|
1004
|
+
new MemoryAdapter();
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
No options needed - it's ready to go! ✨
|
|
1008
|
+
|
|
1009
|
+
#### Methods
|
|
1010
|
+
|
|
1011
|
+
##### `clear(): void`
|
|
1012
|
+
|
|
1013
|
+
Clears all stored data (useful for testing).
|
|
1014
|
+
|
|
1015
|
+
##### `getSnapshot(): { sessions: SessionData[]; messages: MessageData[] }`
|
|
1016
|
+
|
|
1017
|
+
Returns a snapshot of all data (useful for debugging/testing).
|
|
1018
|
+
|
|
1019
|
+
#### Example
|
|
1020
|
+
|
|
1021
|
+
```typescript
|
|
1022
|
+
import { MemoryAdapter } from "@falai/agent";
|
|
1023
|
+
|
|
1024
|
+
const adapter = new MemoryAdapter();
|
|
1025
|
+
|
|
1026
|
+
const agent = new Agent({
|
|
1027
|
+
persistence: { adapter },
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
// Perfect for unit tests!
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
**Testing Example:**
|
|
1034
|
+
|
|
1035
|
+
```typescript
|
|
1036
|
+
describe("Agent", () => {
|
|
1037
|
+
const adapter = new MemoryAdapter();
|
|
1038
|
+
|
|
1039
|
+
afterEach(() => {
|
|
1040
|
+
adapter.clear(); // Reset between tests
|
|
1041
|
+
});
|
|
1042
|
+
|
|
1043
|
+
it("should persist messages", async () => {
|
|
1044
|
+
const agent = new Agent({
|
|
1045
|
+
persistence: { adapter },
|
|
1046
|
+
});
|
|
1047
|
+
|
|
1048
|
+
// ... test logic ...
|
|
1049
|
+
|
|
1050
|
+
const { sessions, messages } = adapter.getSnapshot();
|
|
1051
|
+
expect(sessions).toHaveLength(1);
|
|
1052
|
+
expect(messages).toHaveLength(2);
|
|
1053
|
+
});
|
|
1054
|
+
});
|
|
1055
|
+
```
|
|
1056
|
+
|
|
1057
|
+
**No installation required** - built into the framework!
|
|
1058
|
+
|
|
1059
|
+
---
|
|
1060
|
+
|
|
1061
|
+
### Persistence Types
|
|
1062
|
+
|
|
1063
|
+
#### `SessionData`
|
|
1064
|
+
|
|
1065
|
+
```typescript
|
|
1066
|
+
interface SessionData {
|
|
1067
|
+
id: string;
|
|
1068
|
+
userId?: string;
|
|
1069
|
+
agentName?: string;
|
|
1070
|
+
status: SessionStatus; // "active" | "completed" | "abandoned"
|
|
1071
|
+
currentRoute?: string;
|
|
1072
|
+
currentState?: string;
|
|
1073
|
+
collectedData?: Record<string, unknown>;
|
|
1074
|
+
messageCount: number;
|
|
1075
|
+
lastMessageAt?: Date;
|
|
1076
|
+
completedAt?: Date;
|
|
1077
|
+
createdAt: Date;
|
|
1078
|
+
updatedAt: Date;
|
|
1079
|
+
}
|
|
1080
|
+
```
|
|
1081
|
+
|
|
1082
|
+
#### `MessageData`
|
|
1083
|
+
|
|
1084
|
+
```typescript
|
|
1085
|
+
interface MessageData {
|
|
1086
|
+
id: string;
|
|
1087
|
+
sessionId: string;
|
|
1088
|
+
userId?: string;
|
|
1089
|
+
role: MessageRole; // "user" | "agent" | "system"
|
|
1090
|
+
content: string;
|
|
1091
|
+
route?: string;
|
|
1092
|
+
state?: string;
|
|
1093
|
+
toolCalls?: Array<{
|
|
1094
|
+
toolName: string;
|
|
1095
|
+
arguments: Record<string, unknown>;
|
|
1096
|
+
result?: unknown;
|
|
1097
|
+
}>;
|
|
1098
|
+
event?: Event;
|
|
1099
|
+
createdAt: Date;
|
|
1100
|
+
}
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
#### `PersistenceAdapter`
|
|
1104
|
+
|
|
1105
|
+
Interface for creating custom adapters:
|
|
1106
|
+
|
|
1107
|
+
```typescript
|
|
1108
|
+
interface PersistenceAdapter {
|
|
1109
|
+
sessionRepository: SessionRepository;
|
|
1110
|
+
messageRepository: MessageRepository;
|
|
1111
|
+
initialize?(): Promise<void>; // Optional: setup tables/indexes
|
|
1112
|
+
disconnect?(): Promise<void>; // Optional: cleanup
|
|
1113
|
+
}
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
**See Also:**
|
|
1117
|
+
|
|
1118
|
+
- [docs/PERSISTENCE.md](./PERSISTENCE.md) - Complete persistence guide
|
|
1119
|
+
- [docs/ADAPTERS.md](./ADAPTERS.md) - Adapter comparison and details
|
|
1120
|
+
|
|
1121
|
+
---
|
|
1122
|
+
|
|
675
1123
|
### `PromptBuilder`
|
|
676
1124
|
|
|
677
1125
|
Constructs prompts for AI generation.
|
package/docs/PERSISTENCE.md
CHANGED
|
@@ -408,12 +408,182 @@ Check your field mappings match your actual database schema.
|
|
|
408
408
|
|
|
409
409
|
## Other Databases
|
|
410
410
|
|
|
411
|
-
The adapter pattern works with any database.
|
|
411
|
+
The adapter pattern works with any database. Built-in adapters:
|
|
412
412
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
-
|
|
416
|
-
|
|
417
|
-
|
|
413
|
+
### Redis
|
|
414
|
+
|
|
415
|
+
Perfect for high-throughput, real-time applications:
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
import { RedisAdapter } from "@falai/agent";
|
|
419
|
+
import Redis from "ioredis";
|
|
420
|
+
|
|
421
|
+
const redis = new Redis();
|
|
422
|
+
|
|
423
|
+
const agent = new Agent({
|
|
424
|
+
persistence: {
|
|
425
|
+
adapter: new RedisAdapter({
|
|
426
|
+
redis,
|
|
427
|
+
keyPrefix: "agent:", // Optional: custom prefix
|
|
428
|
+
sessionTTL: 24 * 60 * 60, // Optional: 24 hours
|
|
429
|
+
messageTTL: 7 * 24 * 60 * 60, // Optional: 7 days
|
|
430
|
+
}),
|
|
431
|
+
},
|
|
432
|
+
});
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
**Install:** `npm install ioredis` or `npm install redis`
|
|
436
|
+
|
|
437
|
+
### Coming Soon
|
|
438
|
+
|
|
439
|
+
Create your own adapter for:
|
|
440
|
+
|
|
441
|
+
- **MongoDB**: Document-based storage ✅ **Available!**
|
|
442
|
+
- **PostgreSQL**: Raw SQL for custom schemas ✅ **Available!**
|
|
443
|
+
- **MySQL**: Traditional relational database (coming soon)
|
|
444
|
+
- **Elasticsearch**: Full-text search integration (coming soon)
|
|
418
445
|
|
|
419
446
|
Just implement the `PersistenceAdapter` interface!
|
|
447
|
+
|
|
448
|
+
### MongoDB
|
|
449
|
+
|
|
450
|
+
Document-based storage with flexible schema:
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
import { MongoAdapter } from "@falai/agent";
|
|
454
|
+
import { MongoClient } from "mongodb";
|
|
455
|
+
|
|
456
|
+
const client = new MongoClient("mongodb://localhost:27017");
|
|
457
|
+
await client.connect();
|
|
458
|
+
|
|
459
|
+
const agent = new Agent({
|
|
460
|
+
persistence: {
|
|
461
|
+
adapter: new MongoAdapter({
|
|
462
|
+
client,
|
|
463
|
+
databaseName: "myapp",
|
|
464
|
+
collections: {
|
|
465
|
+
// Optional: custom names
|
|
466
|
+
sessions: "agent_sessions",
|
|
467
|
+
messages: "agent_messages",
|
|
468
|
+
},
|
|
469
|
+
}),
|
|
470
|
+
},
|
|
471
|
+
});
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
**Install:** `npm install mongodb`
|
|
475
|
+
|
|
476
|
+
### PostgreSQL
|
|
477
|
+
|
|
478
|
+
Raw SQL adapter with auto-table creation:
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
import { PostgreSQLAdapter } from "@falai/agent";
|
|
482
|
+
import { Client } from "pg";
|
|
483
|
+
|
|
484
|
+
const client = new Client({
|
|
485
|
+
host: "localhost",
|
|
486
|
+
database: "myapp",
|
|
487
|
+
user: "postgres",
|
|
488
|
+
password: "password",
|
|
489
|
+
});
|
|
490
|
+
await client.connect();
|
|
491
|
+
|
|
492
|
+
const adapter = new PostgreSQLAdapter({
|
|
493
|
+
client,
|
|
494
|
+
tables: {
|
|
495
|
+
// Optional: custom names
|
|
496
|
+
sessions: "agent_sessions",
|
|
497
|
+
messages: "agent_messages",
|
|
498
|
+
},
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
// Auto-create tables with indexes
|
|
502
|
+
await adapter.initialize();
|
|
503
|
+
|
|
504
|
+
const agent = new Agent({
|
|
505
|
+
persistence: {
|
|
506
|
+
adapter,
|
|
507
|
+
},
|
|
508
|
+
});
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**Install:** `npm install pg`
|
|
512
|
+
|
|
513
|
+
**Note:** PostgreSQL adapter includes `initialize()` method to auto-create tables with proper indexes and foreign keys.
|
|
514
|
+
|
|
515
|
+
### SQLite
|
|
516
|
+
|
|
517
|
+
Lightweight, file-based database for local development:
|
|
518
|
+
|
|
519
|
+
```typescript
|
|
520
|
+
import { SQLiteAdapter } from "@falai/agent";
|
|
521
|
+
import Database from "better-sqlite3";
|
|
522
|
+
|
|
523
|
+
const db = new Database("agent.db");
|
|
524
|
+
|
|
525
|
+
const adapter = new SQLiteAdapter({ db });
|
|
526
|
+
|
|
527
|
+
// Auto-create tables
|
|
528
|
+
await adapter.initialize();
|
|
529
|
+
|
|
530
|
+
const agent = new Agent({
|
|
531
|
+
persistence: { adapter },
|
|
532
|
+
});
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
**Install:** `npm install better-sqlite3`
|
|
536
|
+
|
|
537
|
+
**Perfect for:**
|
|
538
|
+
|
|
539
|
+
- Local development
|
|
540
|
+
- Testing
|
|
541
|
+
- Desktop applications
|
|
542
|
+
- Single-user apps
|
|
543
|
+
|
|
544
|
+
### Memory (Built-in)
|
|
545
|
+
|
|
546
|
+
Zero-dependency in-memory storage for testing:
|
|
547
|
+
|
|
548
|
+
```typescript
|
|
549
|
+
import { MemoryAdapter } from "@falai/agent";
|
|
550
|
+
|
|
551
|
+
const agent = new Agent({
|
|
552
|
+
persistence: {
|
|
553
|
+
adapter: new MemoryAdapter(),
|
|
554
|
+
userId: "test_user",
|
|
555
|
+
},
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
// Perfect for unit tests - no database setup required!
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
**Features:**
|
|
562
|
+
|
|
563
|
+
- No installation required ✨
|
|
564
|
+
- Perfect for testing
|
|
565
|
+
- Data snapshot for debugging
|
|
566
|
+
- Clear method for test cleanup
|
|
567
|
+
|
|
568
|
+
**Example test:**
|
|
569
|
+
|
|
570
|
+
```typescript
|
|
571
|
+
describe("Agent persistence", () => {
|
|
572
|
+
const adapter = new MemoryAdapter();
|
|
573
|
+
|
|
574
|
+
afterEach(() => {
|
|
575
|
+
adapter.clear(); // Clean state between tests
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
it("should save session", async () => {
|
|
579
|
+
const agent = new Agent({
|
|
580
|
+
persistence: { adapter },
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
// Test your logic...
|
|
584
|
+
|
|
585
|
+
const snapshot = adapter.getSnapshot();
|
|
586
|
+
expect(snapshot.sessions).toHaveLength(1);
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
```
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Using Redis for Persistence
|
|
3
|
+
*
|
|
4
|
+
* Fast, in-memory persistence perfect for:
|
|
5
|
+
* - High-throughput applications
|
|
6
|
+
* - Session caching
|
|
7
|
+
* - Real-time chat applications
|
|
8
|
+
* - Temporary conversation storage
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Agent, GeminiProvider, RedisAdapter } from "../src/index";
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
import Redis from "ioredis";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Setup Steps:
|
|
17
|
+
*
|
|
18
|
+
* 1. Install Redis and client:
|
|
19
|
+
* brew install redis (macOS) or apt-get install redis (Linux)
|
|
20
|
+
* npm install ioredis
|
|
21
|
+
*
|
|
22
|
+
* 2. Start Redis:
|
|
23
|
+
* redis-server
|
|
24
|
+
*
|
|
25
|
+
* 3. Run this example
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
async function example() {
|
|
29
|
+
// Initialize Redis client
|
|
30
|
+
const redis = new Redis();
|
|
31
|
+
|
|
32
|
+
// Create agent with Redis persistence
|
|
33
|
+
const agent = new Agent({
|
|
34
|
+
name: "Chat Assistant",
|
|
35
|
+
description: "Fast, real-time chat assistant",
|
|
36
|
+
ai: new GeminiProvider({
|
|
37
|
+
apiKey: process.env.GEMINI_API_KEY!,
|
|
38
|
+
model: "models/gemini-2.0-flash-exp",
|
|
39
|
+
}),
|
|
40
|
+
// ✨ Redis adapter with custom options
|
|
41
|
+
persistence: {
|
|
42
|
+
adapter: new RedisAdapter({
|
|
43
|
+
redis,
|
|
44
|
+
keyPrefix: "chat:", // Custom prefix
|
|
45
|
+
sessionTTL: 24 * 60 * 60, // 24 hours
|
|
46
|
+
messageTTL: 7 * 24 * 60 * 60, // 7 days
|
|
47
|
+
}),
|
|
48
|
+
autoSave: true,
|
|
49
|
+
userId: "user_123",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const persistence = agent.getPersistenceManager();
|
|
54
|
+
if (!persistence) return;
|
|
55
|
+
|
|
56
|
+
// Create session
|
|
57
|
+
const session = await persistence.createSession({
|
|
58
|
+
userId: "user_123",
|
|
59
|
+
agentName: "Chat Assistant",
|
|
60
|
+
initialData: { chatType: "support" },
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
console.log("✨ Session created in Redis:", session.id);
|
|
64
|
+
|
|
65
|
+
// Save a message
|
|
66
|
+
await persistence.saveMessage({
|
|
67
|
+
sessionId: session.id,
|
|
68
|
+
role: "user",
|
|
69
|
+
content: "Hello! I need help",
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Load messages
|
|
73
|
+
const messages = await persistence.getSessionMessages(session.id);
|
|
74
|
+
console.log(`💬 ${messages.length} messages in session`);
|
|
75
|
+
|
|
76
|
+
// Complete session
|
|
77
|
+
await persistence.completeSession(session.id);
|
|
78
|
+
console.log("✅ Session completed");
|
|
79
|
+
|
|
80
|
+
// Cleanup
|
|
81
|
+
await redis.quit();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Run the example
|
|
85
|
+
if (require.main === module) {
|
|
86
|
+
example().catch(console.error);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { example };
|