@smyslenny/agent-memory 4.2.0 → 4.3.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 +1 -1
- package/dist/bin/agent-memory.js +61 -9
- package/dist/bin/agent-memory.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +61 -9
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +61 -9
- package/dist/mcp/server.js.map +1 -1
- package/package.json +2 -2
- package/docs/design/.next-id +0 -1
- package/docs/design/0004-agent-memory-integration.md +0 -316
- package/docs/design/0005-reranker-api-integration.md +0 -276
- package/docs/design/0006-multi-provider-embedding.md +0 -196
- package/docs/design/0014-memory-core-dedup.md +0 -722
- package/docs/design/0015-v4-overhaul.md +0 -631
- package/docs/design/0016-v41-warm-boot-surface-emotion.md +0 -228
- package/docs/design/TEMPLATE.md +0 -67
- package/docs/roadmap/integration-plan-v1.md +0 -139
- package/docs/roadmap/memory-architecture.md +0 -168
- package/docs/roadmap/warm-boot.md +0 -135
package/dist/index.d.ts
CHANGED
|
@@ -550,7 +550,7 @@ declare function exportMemories(db: Database.Database, dirPath: string, opts?: {
|
|
|
550
550
|
agent_id?: string;
|
|
551
551
|
}): ExportResult;
|
|
552
552
|
|
|
553
|
-
type EmbeddingProviderKind = "openai-compatible" | "local-http";
|
|
553
|
+
type EmbeddingProviderKind = "openai-compatible" | "local-http" | "gemini";
|
|
554
554
|
interface EmbeddingProviderConfig {
|
|
555
555
|
provider: EmbeddingProviderKind;
|
|
556
556
|
baseUrl: string;
|
package/dist/index.js
CHANGED
|
@@ -676,6 +676,44 @@ function createLocalHttpEmbeddingProvider(opts) {
|
|
|
676
676
|
}
|
|
677
677
|
};
|
|
678
678
|
}
|
|
679
|
+
function createGeminiEmbeddingProvider(opts) {
|
|
680
|
+
const id = stableProviderId(`gemini:${opts.model}`, `${opts.model}|${opts.dimension}`);
|
|
681
|
+
return {
|
|
682
|
+
id,
|
|
683
|
+
model: opts.model,
|
|
684
|
+
dimension: opts.dimension,
|
|
685
|
+
async embed(texts) {
|
|
686
|
+
if (texts.length === 0) return [];
|
|
687
|
+
const fetchFn = getFetch(opts.fetchImpl);
|
|
688
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/${opts.model}:batchEmbedContents?key=${opts.apiKey}`;
|
|
689
|
+
const requests = texts.map((text) => ({
|
|
690
|
+
model: `models/${opts.model}`,
|
|
691
|
+
content: { parts: [{ text }] },
|
|
692
|
+
outputDimensionality: opts.dimension
|
|
693
|
+
}));
|
|
694
|
+
const response = await fetchFn(url, {
|
|
695
|
+
method: "POST",
|
|
696
|
+
headers: { "content-type": "application/json" },
|
|
697
|
+
body: JSON.stringify({ requests })
|
|
698
|
+
});
|
|
699
|
+
if (!response.ok) {
|
|
700
|
+
const detail = await response.text().catch(() => "");
|
|
701
|
+
throw new Error(`Gemini embedding request failed: ${response.status} ${response.statusText}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
702
|
+
}
|
|
703
|
+
const json2 = await response.json();
|
|
704
|
+
const embeddings = json2?.embeddings;
|
|
705
|
+
if (!Array.isArray(embeddings)) {
|
|
706
|
+
throw new Error("Gemini embedding response missing embeddings array");
|
|
707
|
+
}
|
|
708
|
+
return embeddings.map(
|
|
709
|
+
(entry, index) => assertEmbeddingVector(entry?.values, opts.dimension, `Gemini embedding item ${index}`)
|
|
710
|
+
);
|
|
711
|
+
},
|
|
712
|
+
async healthcheck() {
|
|
713
|
+
await this.embed(["healthcheck"]);
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
}
|
|
679
717
|
function normalizeEmbeddingBaseUrl(baseUrl) {
|
|
680
718
|
return trimTrailingSlashes(baseUrl);
|
|
681
719
|
}
|
|
@@ -688,7 +726,7 @@ function parseDimension(raw) {
|
|
|
688
726
|
}
|
|
689
727
|
function parseProvider(raw) {
|
|
690
728
|
if (!raw) return null;
|
|
691
|
-
if (raw === "openai-compatible" || raw === "local-http") {
|
|
729
|
+
if (raw === "openai-compatible" || raw === "local-http" || raw === "gemini") {
|
|
692
730
|
return raw;
|
|
693
731
|
}
|
|
694
732
|
throw new Error(`Unsupported embedding provider: ${raw}`);
|
|
@@ -699,8 +737,8 @@ function getEmbeddingProviderConfigFromEnv(env = process.env) {
|
|
|
699
737
|
const baseUrl = env.AGENT_MEMORY_EMBEDDING_BASE_URL;
|
|
700
738
|
const model = env.AGENT_MEMORY_EMBEDDING_MODEL;
|
|
701
739
|
const dimension = parseDimension(env.AGENT_MEMORY_EMBEDDING_DIMENSION);
|
|
702
|
-
if (!baseUrl) {
|
|
703
|
-
throw new Error("AGENT_MEMORY_EMBEDDING_BASE_URL is required when embeddings are enabled");
|
|
740
|
+
if (!baseUrl && provider !== "gemini") {
|
|
741
|
+
throw new Error("AGENT_MEMORY_EMBEDDING_BASE_URL is required when embeddings are enabled (not needed for gemini provider)");
|
|
704
742
|
}
|
|
705
743
|
if (!model) {
|
|
706
744
|
throw new Error("AGENT_MEMORY_EMBEDDING_MODEL is required when embeddings are enabled");
|
|
@@ -711,9 +749,12 @@ function getEmbeddingProviderConfigFromEnv(env = process.env) {
|
|
|
711
749
|
if (provider === "openai-compatible" && !env.AGENT_MEMORY_EMBEDDING_API_KEY) {
|
|
712
750
|
throw new Error("AGENT_MEMORY_EMBEDDING_API_KEY is required for openai-compatible providers");
|
|
713
751
|
}
|
|
752
|
+
if (provider === "gemini" && !env.AGENT_MEMORY_EMBEDDING_API_KEY) {
|
|
753
|
+
throw new Error("AGENT_MEMORY_EMBEDDING_API_KEY is required for gemini provider (Google AI API key)");
|
|
754
|
+
}
|
|
714
755
|
return {
|
|
715
756
|
provider,
|
|
716
|
-
baseUrl,
|
|
757
|
+
baseUrl: baseUrl ?? "",
|
|
717
758
|
model,
|
|
718
759
|
dimension,
|
|
719
760
|
apiKey: env.AGENT_MEMORY_EMBEDDING_API_KEY
|
|
@@ -722,8 +763,16 @@ function getEmbeddingProviderConfigFromEnv(env = process.env) {
|
|
|
722
763
|
function createEmbeddingProvider(input, opts) {
|
|
723
764
|
const normalized = {
|
|
724
765
|
...input,
|
|
725
|
-
baseUrl: normalizeEmbeddingBaseUrl(input.baseUrl)
|
|
766
|
+
baseUrl: input.baseUrl ? normalizeEmbeddingBaseUrl(input.baseUrl) : ""
|
|
726
767
|
};
|
|
768
|
+
if (normalized.provider === "gemini") {
|
|
769
|
+
return createGeminiEmbeddingProvider({
|
|
770
|
+
model: normalized.model,
|
|
771
|
+
dimension: normalized.dimension,
|
|
772
|
+
apiKey: normalized.apiKey,
|
|
773
|
+
fetchImpl: opts?.fetchImpl
|
|
774
|
+
});
|
|
775
|
+
}
|
|
727
776
|
if (normalized.provider === "openai-compatible") {
|
|
728
777
|
return createOpenAICompatibleEmbeddingProvider({
|
|
729
778
|
baseUrl: normalized.baseUrl,
|
|
@@ -750,13 +799,16 @@ function resolveEmbeddingProviderConfig(opts) {
|
|
|
750
799
|
const model = opts?.config?.model ?? envConfig?.model;
|
|
751
800
|
const dimension = opts?.config?.dimension ?? envConfig?.dimension;
|
|
752
801
|
const apiKey = opts?.config?.apiKey ?? envConfig?.apiKey;
|
|
753
|
-
if (!provider || !
|
|
802
|
+
if (!provider || !model || !dimension) {
|
|
754
803
|
throw new Error("Incomplete embedding provider configuration");
|
|
755
804
|
}
|
|
756
|
-
if (provider
|
|
757
|
-
throw new Error("
|
|
805
|
+
if (provider !== "gemini" && !baseUrl) {
|
|
806
|
+
throw new Error("baseUrl is required for non-gemini embedding providers");
|
|
807
|
+
}
|
|
808
|
+
if ((provider === "openai-compatible" || provider === "gemini") && !apiKey) {
|
|
809
|
+
throw new Error(`${provider} embedding provider requires an API key`);
|
|
758
810
|
}
|
|
759
|
-
return { provider, baseUrl, model, dimension, apiKey };
|
|
811
|
+
return { provider, baseUrl: baseUrl ?? "", model, dimension, apiKey };
|
|
760
812
|
}
|
|
761
813
|
function getEmbeddingProvider(opts) {
|
|
762
814
|
const config = resolveEmbeddingProviderConfig({ config: opts?.config, env: opts?.env });
|