@avee1234/agent-kit 0.2.0 → 0.3.1
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 +4 -0
- package/dist/cli.cjs +100 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +77 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +294 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -2
- package/dist/index.d.ts +52 -2
- package/dist/index.js +291 -7
- package/dist/index.js.map +1 -1
- package/package.json +16 -2
package/dist/index.js
CHANGED
|
@@ -64,7 +64,15 @@ var OpenAICompatibleAdapter = class {
|
|
|
64
64
|
function: {
|
|
65
65
|
name: t.name,
|
|
66
66
|
description: t.description,
|
|
67
|
-
parameters: {
|
|
67
|
+
parameters: {
|
|
68
|
+
type: "object",
|
|
69
|
+
properties: Object.fromEntries(
|
|
70
|
+
Object.entries(t.parameters).map(([key, val]) => {
|
|
71
|
+
const { required: _req, ...rest } = val;
|
|
72
|
+
return [key, rest];
|
|
73
|
+
})
|
|
74
|
+
)
|
|
75
|
+
}
|
|
68
76
|
}
|
|
69
77
|
}));
|
|
70
78
|
}
|
|
@@ -110,7 +118,15 @@ var OpenAICompatibleAdapter = class {
|
|
|
110
118
|
function: {
|
|
111
119
|
name: t.name,
|
|
112
120
|
description: t.description,
|
|
113
|
-
parameters: {
|
|
121
|
+
parameters: {
|
|
122
|
+
type: "object",
|
|
123
|
+
properties: Object.fromEntries(
|
|
124
|
+
Object.entries(t.parameters).map(([key, val]) => {
|
|
125
|
+
const { required: _req, ...rest } = val;
|
|
126
|
+
return [key, rest];
|
|
127
|
+
})
|
|
128
|
+
)
|
|
129
|
+
}
|
|
114
130
|
}
|
|
115
131
|
}));
|
|
116
132
|
}
|
|
@@ -572,13 +588,11 @@ var HierarchicalStrategy = class {
|
|
|
572
588
|
parameters: {
|
|
573
589
|
agentName: {
|
|
574
590
|
type: "string",
|
|
575
|
-
description:
|
|
576
|
-
required: true
|
|
591
|
+
description: `The name of the agent to delegate to. Available: ${[...agents.map((a) => a.name)].join(", ")}`
|
|
577
592
|
},
|
|
578
593
|
task: {
|
|
579
594
|
type: "string",
|
|
580
|
-
description: "The task to assign to the agent"
|
|
581
|
-
required: true
|
|
595
|
+
description: "The task to assign to the agent"
|
|
582
596
|
}
|
|
583
597
|
},
|
|
584
598
|
execute: async (params) => {
|
|
@@ -687,10 +701,27 @@ var Team = class {
|
|
|
687
701
|
}
|
|
688
702
|
};
|
|
689
703
|
|
|
704
|
+
// src/store/cosine.ts
|
|
705
|
+
function cosineSimilarity(a, b) {
|
|
706
|
+
let dot = 0;
|
|
707
|
+
let normA = 0;
|
|
708
|
+
let normB = 0;
|
|
709
|
+
for (let i = 0; i < a.length; i++) {
|
|
710
|
+
dot += a[i] * b[i];
|
|
711
|
+
normA += a[i] * a[i];
|
|
712
|
+
normB += b[i] * b[i];
|
|
713
|
+
}
|
|
714
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
715
|
+
if (denom === 0) return 0;
|
|
716
|
+
return dot / denom;
|
|
717
|
+
}
|
|
718
|
+
|
|
690
719
|
// src/store/in-memory.ts
|
|
691
720
|
var InMemoryStore = class {
|
|
692
721
|
messages = /* @__PURE__ */ new Map();
|
|
693
722
|
summaries = /* @__PURE__ */ new Map();
|
|
723
|
+
// agentId -> (summaryId -> embedding vector)
|
|
724
|
+
embeddings = /* @__PURE__ */ new Map();
|
|
694
725
|
async saveMessages(agentId, messages) {
|
|
695
726
|
const existing = this.messages.get(agentId) ?? [];
|
|
696
727
|
existing.push(...messages);
|
|
@@ -711,6 +742,28 @@ var InMemoryStore = class {
|
|
|
711
742
|
const matches = all.filter((s) => s.content.toLowerCase().includes(queryLower)).sort((a, b) => b.timestamp - a.timestamp).slice(0, limit);
|
|
712
743
|
return matches;
|
|
713
744
|
}
|
|
745
|
+
async saveEmbedding(agentId, summaryId, embedding) {
|
|
746
|
+
let agentMap = this.embeddings.get(agentId);
|
|
747
|
+
if (!agentMap) {
|
|
748
|
+
agentMap = /* @__PURE__ */ new Map();
|
|
749
|
+
this.embeddings.set(agentId, agentMap);
|
|
750
|
+
}
|
|
751
|
+
agentMap.set(summaryId, embedding);
|
|
752
|
+
}
|
|
753
|
+
async searchByEmbedding(agentId, embedding, limit) {
|
|
754
|
+
const agentMap = this.embeddings.get(agentId);
|
|
755
|
+
if (!agentMap || agentMap.size === 0) return [];
|
|
756
|
+
const summaries = this.summaries.get(agentId) ?? [];
|
|
757
|
+
const summaryById = new Map(summaries.map((s) => [s.id, s]));
|
|
758
|
+
const scored = [];
|
|
759
|
+
for (const [summaryId, storedEmbedding] of agentMap) {
|
|
760
|
+
const summary = summaryById.get(summaryId);
|
|
761
|
+
if (!summary) continue;
|
|
762
|
+
const score = cosineSimilarity(embedding, storedEmbedding);
|
|
763
|
+
scored.push({ summary, score });
|
|
764
|
+
}
|
|
765
|
+
return scored.sort((a, b) => b.score - a.score).slice(0, limit).map((entry) => entry.summary);
|
|
766
|
+
}
|
|
714
767
|
};
|
|
715
768
|
|
|
716
769
|
// src/store/sqlite.ts
|
|
@@ -743,8 +796,14 @@ var SQLiteStore = class {
|
|
|
743
796
|
message_range_from INTEGER NOT NULL,
|
|
744
797
|
message_range_to INTEGER NOT NULL
|
|
745
798
|
);
|
|
799
|
+
CREATE TABLE IF NOT EXISTS embeddings (
|
|
800
|
+
summary_id TEXT PRIMARY KEY,
|
|
801
|
+
agent_id TEXT NOT NULL,
|
|
802
|
+
embedding BLOB NOT NULL
|
|
803
|
+
);
|
|
746
804
|
CREATE INDEX IF NOT EXISTS idx_messages_agent ON messages(agent_id);
|
|
747
805
|
CREATE INDEX IF NOT EXISTS idx_summaries_agent ON summaries(agent_id);
|
|
806
|
+
CREATE INDEX IF NOT EXISTS idx_embeddings_agent ON embeddings(agent_id);
|
|
748
807
|
`);
|
|
749
808
|
}
|
|
750
809
|
async saveMessages(agentId, messages) {
|
|
@@ -804,25 +863,208 @@ var SQLiteStore = class {
|
|
|
804
863
|
messageRange: { from: row.message_range_from, to: row.message_range_to }
|
|
805
864
|
}));
|
|
806
865
|
}
|
|
866
|
+
async saveEmbedding(agentId, summaryId, embedding) {
|
|
867
|
+
this.db.prepare(
|
|
868
|
+
"INSERT OR REPLACE INTO embeddings (summary_id, agent_id, embedding) VALUES (?, ?, ?)"
|
|
869
|
+
).run(summaryId, agentId, JSON.stringify(embedding));
|
|
870
|
+
}
|
|
871
|
+
async searchByEmbedding(agentId, embedding, limit) {
|
|
872
|
+
const rows = this.db.prepare(
|
|
873
|
+
`SELECT e.summary_id, s.content, s.timestamp, s.message_range_from, s.message_range_to, e.embedding
|
|
874
|
+
FROM embeddings e
|
|
875
|
+
JOIN summaries s ON e.summary_id = s.id
|
|
876
|
+
WHERE e.agent_id = ?`
|
|
877
|
+
).all(agentId);
|
|
878
|
+
if (rows.length === 0) return [];
|
|
879
|
+
const scored = rows.map((row) => {
|
|
880
|
+
const storedEmbedding = JSON.parse(row.embedding);
|
|
881
|
+
const score = cosineSimilarity(embedding, storedEmbedding);
|
|
882
|
+
return {
|
|
883
|
+
summary: {
|
|
884
|
+
id: row.summary_id,
|
|
885
|
+
content: row.content,
|
|
886
|
+
timestamp: row.timestamp,
|
|
887
|
+
messageRange: { from: row.message_range_from, to: row.message_range_to }
|
|
888
|
+
},
|
|
889
|
+
score
|
|
890
|
+
};
|
|
891
|
+
});
|
|
892
|
+
return scored.sort((a, b) => b.score - a.score).slice(0, limit).map((entry) => entry.summary);
|
|
893
|
+
}
|
|
807
894
|
close() {
|
|
808
895
|
this.db.close();
|
|
809
896
|
}
|
|
810
897
|
};
|
|
811
898
|
|
|
899
|
+
// src/store/postgres.ts
|
|
900
|
+
import { createRequire as createRequire2 } from "module";
|
|
901
|
+
var require3 = createRequire2(import.meta.url);
|
|
902
|
+
var SCHEMA_SQL = `
|
|
903
|
+
CREATE EXTENSION IF NOT EXISTS vector;
|
|
904
|
+
|
|
905
|
+
CREATE TABLE IF NOT EXISTS agent_messages (
|
|
906
|
+
id SERIAL PRIMARY KEY,
|
|
907
|
+
agent_id TEXT NOT NULL,
|
|
908
|
+
role TEXT NOT NULL,
|
|
909
|
+
content TEXT NOT NULL,
|
|
910
|
+
timestamp BIGINT NOT NULL,
|
|
911
|
+
tool_calls JSONB,
|
|
912
|
+
tool_call_id TEXT
|
|
913
|
+
);
|
|
914
|
+
|
|
915
|
+
CREATE TABLE IF NOT EXISTS agent_summaries (
|
|
916
|
+
id TEXT PRIMARY KEY,
|
|
917
|
+
agent_id TEXT NOT NULL,
|
|
918
|
+
content TEXT NOT NULL,
|
|
919
|
+
timestamp BIGINT NOT NULL,
|
|
920
|
+
message_range_from BIGINT NOT NULL,
|
|
921
|
+
message_range_to BIGINT NOT NULL,
|
|
922
|
+
embedding vector(768)
|
|
923
|
+
);
|
|
924
|
+
|
|
925
|
+
CREATE INDEX IF NOT EXISTS idx_agent_messages_agent ON agent_messages(agent_id);
|
|
926
|
+
CREATE INDEX IF NOT EXISTS idx_agent_summaries_agent ON agent_summaries(agent_id);
|
|
927
|
+
`;
|
|
928
|
+
var PostgresStore = class _PostgresStore {
|
|
929
|
+
pool;
|
|
930
|
+
constructor(config) {
|
|
931
|
+
const { Pool } = require3("pg");
|
|
932
|
+
this.pool = new Pool({ connectionString: config.connectionString });
|
|
933
|
+
void this.init();
|
|
934
|
+
}
|
|
935
|
+
async init() {
|
|
936
|
+
await this.pool.query(SCHEMA_SQL);
|
|
937
|
+
}
|
|
938
|
+
/** Factory that ensures schema is ready before returning the store. */
|
|
939
|
+
static async create(config) {
|
|
940
|
+
const store = new _PostgresStore(config);
|
|
941
|
+
await store.init();
|
|
942
|
+
return store;
|
|
943
|
+
}
|
|
944
|
+
async saveMessages(agentId, messages) {
|
|
945
|
+
for (const msg of messages) {
|
|
946
|
+
await this.pool.query(
|
|
947
|
+
`INSERT INTO agent_messages (agent_id, role, content, timestamp, tool_calls, tool_call_id)
|
|
948
|
+
VALUES ($1, $2, $3, $4, $5, $6)`,
|
|
949
|
+
[
|
|
950
|
+
agentId,
|
|
951
|
+
msg.role,
|
|
952
|
+
msg.content,
|
|
953
|
+
msg.timestamp,
|
|
954
|
+
msg.toolCalls ? JSON.stringify(msg.toolCalls) : null,
|
|
955
|
+
msg.toolCallId ?? null
|
|
956
|
+
]
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
async getRecentMessages(agentId, limit) {
|
|
961
|
+
const result = await this.pool.query(
|
|
962
|
+
`SELECT role, content, timestamp, tool_calls, tool_call_id
|
|
963
|
+
FROM agent_messages
|
|
964
|
+
WHERE agent_id = $1
|
|
965
|
+
ORDER BY id DESC
|
|
966
|
+
LIMIT $2`,
|
|
967
|
+
[agentId, limit]
|
|
968
|
+
);
|
|
969
|
+
return result.rows.reverse().map((row) => ({
|
|
970
|
+
role: row.role,
|
|
971
|
+
content: row.content,
|
|
972
|
+
timestamp: Number(row.timestamp),
|
|
973
|
+
...row.tool_calls ? {
|
|
974
|
+
toolCalls: typeof row.tool_calls === "string" ? JSON.parse(row.tool_calls) : row.tool_calls
|
|
975
|
+
} : {},
|
|
976
|
+
...row.tool_call_id ? { toolCallId: row.tool_call_id } : {}
|
|
977
|
+
}));
|
|
978
|
+
}
|
|
979
|
+
async saveSummary(agentId, summary) {
|
|
980
|
+
await this.pool.query(
|
|
981
|
+
`INSERT INTO agent_summaries (id, agent_id, content, timestamp, message_range_from, message_range_to)
|
|
982
|
+
VALUES ($1, $2, $3, $4, $5, $6)`,
|
|
983
|
+
[
|
|
984
|
+
summary.id,
|
|
985
|
+
agentId,
|
|
986
|
+
summary.content,
|
|
987
|
+
summary.timestamp,
|
|
988
|
+
summary.messageRange.from,
|
|
989
|
+
summary.messageRange.to
|
|
990
|
+
]
|
|
991
|
+
);
|
|
992
|
+
}
|
|
993
|
+
async searchSummaries(agentId, query, limit) {
|
|
994
|
+
const result = await this.pool.query(
|
|
995
|
+
`SELECT id, content, timestamp, message_range_from, message_range_to
|
|
996
|
+
FROM agent_summaries
|
|
997
|
+
WHERE agent_id = $1 AND content ILIKE $2
|
|
998
|
+
ORDER BY timestamp DESC
|
|
999
|
+
LIMIT $3`,
|
|
1000
|
+
[agentId, `%${query}%`, limit]
|
|
1001
|
+
);
|
|
1002
|
+
return result.rows.map((row) => ({
|
|
1003
|
+
id: row.id,
|
|
1004
|
+
content: row.content,
|
|
1005
|
+
timestamp: Number(row.timestamp),
|
|
1006
|
+
messageRange: {
|
|
1007
|
+
from: Number(row.message_range_from),
|
|
1008
|
+
to: Number(row.message_range_to)
|
|
1009
|
+
}
|
|
1010
|
+
}));
|
|
1011
|
+
}
|
|
1012
|
+
async saveEmbedding(agentId, summaryId, embedding) {
|
|
1013
|
+
const vectorLiteral = `[${embedding.join(",")}]`;
|
|
1014
|
+
await this.pool.query(
|
|
1015
|
+
`UPDATE agent_summaries SET embedding = $1 WHERE id = $2 AND agent_id = $3`,
|
|
1016
|
+
[vectorLiteral, summaryId, agentId]
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
1019
|
+
async searchByEmbedding(agentId, embedding, limit) {
|
|
1020
|
+
const vectorLiteral = `[${embedding.join(",")}]`;
|
|
1021
|
+
const result = await this.pool.query(
|
|
1022
|
+
`SELECT id, content, timestamp, message_range_from, message_range_to
|
|
1023
|
+
FROM agent_summaries
|
|
1024
|
+
WHERE agent_id = $1 AND embedding IS NOT NULL
|
|
1025
|
+
ORDER BY embedding <=> $2
|
|
1026
|
+
LIMIT $3`,
|
|
1027
|
+
[agentId, vectorLiteral, limit]
|
|
1028
|
+
);
|
|
1029
|
+
return result.rows.map((row) => ({
|
|
1030
|
+
id: row.id,
|
|
1031
|
+
content: row.content,
|
|
1032
|
+
timestamp: Number(row.timestamp),
|
|
1033
|
+
messageRange: {
|
|
1034
|
+
from: Number(row.message_range_from),
|
|
1035
|
+
to: Number(row.message_range_to)
|
|
1036
|
+
}
|
|
1037
|
+
}));
|
|
1038
|
+
}
|
|
1039
|
+
async close() {
|
|
1040
|
+
await this.pool.end();
|
|
1041
|
+
}
|
|
1042
|
+
};
|
|
1043
|
+
|
|
812
1044
|
// src/memory.ts
|
|
813
1045
|
var Memory = class {
|
|
814
1046
|
store;
|
|
815
1047
|
windowSize;
|
|
816
1048
|
summarizeAfter;
|
|
817
1049
|
model;
|
|
1050
|
+
embeddingAdapter;
|
|
818
1051
|
messageCount = /* @__PURE__ */ new Map();
|
|
819
1052
|
constructor(config = {}) {
|
|
820
1053
|
this.windowSize = config.windowSize ?? 20;
|
|
821
1054
|
this.summarizeAfter = config.summarizeAfter ?? 20;
|
|
1055
|
+
this.embeddingAdapter = config.embedding;
|
|
822
1056
|
if (!config.store || config.store === "memory") {
|
|
823
1057
|
this.store = new InMemoryStore();
|
|
824
1058
|
} else if (config.store === "sqlite") {
|
|
825
1059
|
this.store = new SQLiteStore(config.path ?? "./agent-memory.db");
|
|
1060
|
+
} else if (config.store === "postgres") {
|
|
1061
|
+
const connectionString = config.url ?? config.path;
|
|
1062
|
+
if (!connectionString) {
|
|
1063
|
+
throw new Error(
|
|
1064
|
+
"Memory store 'postgres' requires a connection string via the 'url' config option."
|
|
1065
|
+
);
|
|
1066
|
+
}
|
|
1067
|
+
this.store = new PostgresStore({ connectionString });
|
|
826
1068
|
} else {
|
|
827
1069
|
this.store = config.store;
|
|
828
1070
|
}
|
|
@@ -844,7 +1086,13 @@ var Memory = class {
|
|
|
844
1086
|
}
|
|
845
1087
|
async getContext(agentId, query) {
|
|
846
1088
|
const recentMessages = await this.store.getRecentMessages(agentId, this.windowSize);
|
|
847
|
-
|
|
1089
|
+
let relevantSummaries;
|
|
1090
|
+
if (this.embeddingAdapter && this.store.searchByEmbedding) {
|
|
1091
|
+
const queryEmbedding = await this.embeddingAdapter.embed(query);
|
|
1092
|
+
relevantSummaries = await this.store.searchByEmbedding(agentId, queryEmbedding, 3);
|
|
1093
|
+
} else {
|
|
1094
|
+
relevantSummaries = await this.store.searchSummaries(agentId, query, 3);
|
|
1095
|
+
}
|
|
848
1096
|
return { recentMessages, relevantSummaries };
|
|
849
1097
|
}
|
|
850
1098
|
async summarize(agentId) {
|
|
@@ -867,6 +1115,10 @@ var Memory = class {
|
|
|
867
1115
|
}
|
|
868
1116
|
});
|
|
869
1117
|
await this.store.saveSummary(agentId, summary);
|
|
1118
|
+
if (this.embeddingAdapter && this.store.saveEmbedding) {
|
|
1119
|
+
const embedding = await this.embeddingAdapter.embed(summary.content);
|
|
1120
|
+
await this.store.saveEmbedding(agentId, summary.id, embedding);
|
|
1121
|
+
}
|
|
870
1122
|
}
|
|
871
1123
|
close() {
|
|
872
1124
|
if ("close" in this.store && typeof this.store.close === "function") {
|
|
@@ -874,13 +1126,45 @@ var Memory = class {
|
|
|
874
1126
|
}
|
|
875
1127
|
}
|
|
876
1128
|
};
|
|
1129
|
+
|
|
1130
|
+
// src/model/ollama-embedding.ts
|
|
1131
|
+
var OllamaEmbeddingAdapter = class {
|
|
1132
|
+
baseURL;
|
|
1133
|
+
model;
|
|
1134
|
+
constructor(config = {}) {
|
|
1135
|
+
this.baseURL = config.baseURL ?? "http://localhost:11434";
|
|
1136
|
+
this.model = config.model ?? "nomic-embed-text";
|
|
1137
|
+
}
|
|
1138
|
+
async embed(text) {
|
|
1139
|
+
const [vector] = await this.request(text);
|
|
1140
|
+
return vector;
|
|
1141
|
+
}
|
|
1142
|
+
async embedBatch(texts) {
|
|
1143
|
+
if (texts.length === 0) return [];
|
|
1144
|
+
return this.request(texts);
|
|
1145
|
+
}
|
|
1146
|
+
async request(input) {
|
|
1147
|
+
const response = await fetch(`${this.baseURL}/api/embed`, {
|
|
1148
|
+
method: "POST",
|
|
1149
|
+
headers: { "Content-Type": "application/json" },
|
|
1150
|
+
body: JSON.stringify({ model: this.model, input })
|
|
1151
|
+
});
|
|
1152
|
+
if (!response.ok) {
|
|
1153
|
+
throw new Error(`Ollama embedding request failed: ${response.status} ${response.statusText}`);
|
|
1154
|
+
}
|
|
1155
|
+
const data = await response.json();
|
|
1156
|
+
return data.embeddings;
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
877
1159
|
export {
|
|
878
1160
|
Agent,
|
|
879
1161
|
AgentEventEmitter,
|
|
880
1162
|
InMemoryStore,
|
|
881
1163
|
Memory,
|
|
882
1164
|
MockAdapter,
|
|
1165
|
+
OllamaEmbeddingAdapter,
|
|
883
1166
|
OpenAICompatibleAdapter,
|
|
1167
|
+
PostgresStore,
|
|
884
1168
|
SQLiteStore,
|
|
885
1169
|
Team,
|
|
886
1170
|
Tool,
|