@smyslenny/agent-memory 4.2.0 → 4.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 +1 -1
- package/dist/bin/agent-memory.js +66 -9
- package/dist/bin/agent-memory.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +65 -9
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +66 -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/README.md
CHANGED
|
@@ -22,7 +22,7 @@ AgentMemory is a SQLite-first memory layer for AI agents. It lets an agent:
|
|
|
22
22
|
- **maintain** them over time with `reflect`, `reindex`, and feedback signals
|
|
23
23
|
- **integrate** through **CLI**, **MCP stdio**, or **HTTP/SSE**
|
|
24
24
|
|
|
25
|
-
Current release: **`4.
|
|
25
|
+
Current release: **`4.3.0`**.
|
|
26
26
|
|
|
27
27
|
Without an embedding provider, AgentMemory still works in **BM25-only mode**.
|
|
28
28
|
With one configured, it adds **hybrid recall** and **semantic dedup**.
|
package/dist/bin/agent-memory.js
CHANGED
|
@@ -691,12 +691,54 @@ function createLocalHttpEmbeddingProvider(opts) {
|
|
|
691
691
|
}
|
|
692
692
|
};
|
|
693
693
|
}
|
|
694
|
+
function createGeminiEmbeddingProvider(opts) {
|
|
695
|
+
const baseUrl = trimTrailingSlashes(opts.baseUrl || GEMINI_DEFAULT_BASE_URL);
|
|
696
|
+
const descriptorInput = `${baseUrl}|${opts.model}|${opts.dimension}`;
|
|
697
|
+
const id = stableProviderId(`gemini:${opts.model}`, descriptorInput);
|
|
698
|
+
return {
|
|
699
|
+
id,
|
|
700
|
+
model: opts.model,
|
|
701
|
+
dimension: opts.dimension,
|
|
702
|
+
async embed(texts) {
|
|
703
|
+
if (texts.length === 0) return [];
|
|
704
|
+
const fetchFn = getFetch(opts.fetchImpl);
|
|
705
|
+
const url = `${baseUrl}/v1beta/models/${opts.model}:batchEmbedContents?key=${opts.apiKey}`;
|
|
706
|
+
const requests = texts.map((text) => ({
|
|
707
|
+
model: `models/${opts.model}`,
|
|
708
|
+
content: { parts: [{ text }] },
|
|
709
|
+
outputDimensionality: opts.dimension
|
|
710
|
+
}));
|
|
711
|
+
const response = await fetchFn(url, {
|
|
712
|
+
method: "POST",
|
|
713
|
+
headers: { "content-type": "application/json" },
|
|
714
|
+
body: JSON.stringify({ requests })
|
|
715
|
+
});
|
|
716
|
+
if (!response.ok) {
|
|
717
|
+
const detail = await response.text().catch(() => "");
|
|
718
|
+
throw new Error(`Gemini embedding request failed: ${response.status} ${response.statusText}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
719
|
+
}
|
|
720
|
+
const json2 = await response.json();
|
|
721
|
+
const embeddings = json2?.embeddings;
|
|
722
|
+
if (!Array.isArray(embeddings)) {
|
|
723
|
+
throw new Error("Gemini embedding response missing embeddings array");
|
|
724
|
+
}
|
|
725
|
+
return embeddings.map(
|
|
726
|
+
(entry, index) => assertEmbeddingVector(entry?.values, opts.dimension, `Gemini embedding item ${index}`)
|
|
727
|
+
);
|
|
728
|
+
},
|
|
729
|
+
async healthcheck() {
|
|
730
|
+
await this.embed(["healthcheck"]);
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
}
|
|
694
734
|
function normalizeEmbeddingBaseUrl(baseUrl) {
|
|
695
735
|
return trimTrailingSlashes(baseUrl);
|
|
696
736
|
}
|
|
737
|
+
var GEMINI_DEFAULT_BASE_URL;
|
|
697
738
|
var init_embedding = __esm({
|
|
698
739
|
"src/search/embedding.ts"() {
|
|
699
740
|
"use strict";
|
|
741
|
+
GEMINI_DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com";
|
|
700
742
|
}
|
|
701
743
|
});
|
|
702
744
|
|
|
@@ -708,7 +750,7 @@ function parseDimension(raw) {
|
|
|
708
750
|
}
|
|
709
751
|
function parseProvider(raw) {
|
|
710
752
|
if (!raw) return null;
|
|
711
|
-
if (raw === "openai-compatible" || raw === "local-http") {
|
|
753
|
+
if (raw === "openai-compatible" || raw === "local-http" || raw === "gemini") {
|
|
712
754
|
return raw;
|
|
713
755
|
}
|
|
714
756
|
throw new Error(`Unsupported embedding provider: ${raw}`);
|
|
@@ -719,8 +761,8 @@ function getEmbeddingProviderConfigFromEnv(env = process.env) {
|
|
|
719
761
|
const baseUrl = env.AGENT_MEMORY_EMBEDDING_BASE_URL;
|
|
720
762
|
const model = env.AGENT_MEMORY_EMBEDDING_MODEL;
|
|
721
763
|
const dimension = parseDimension(env.AGENT_MEMORY_EMBEDDING_DIMENSION);
|
|
722
|
-
if (!baseUrl) {
|
|
723
|
-
throw new Error("AGENT_MEMORY_EMBEDDING_BASE_URL is required when embeddings are enabled");
|
|
764
|
+
if (!baseUrl && provider !== "gemini") {
|
|
765
|
+
throw new Error("AGENT_MEMORY_EMBEDDING_BASE_URL is required when embeddings are enabled (not needed for gemini provider)");
|
|
724
766
|
}
|
|
725
767
|
if (!model) {
|
|
726
768
|
throw new Error("AGENT_MEMORY_EMBEDDING_MODEL is required when embeddings are enabled");
|
|
@@ -731,9 +773,12 @@ function getEmbeddingProviderConfigFromEnv(env = process.env) {
|
|
|
731
773
|
if (provider === "openai-compatible" && !env.AGENT_MEMORY_EMBEDDING_API_KEY) {
|
|
732
774
|
throw new Error("AGENT_MEMORY_EMBEDDING_API_KEY is required for openai-compatible providers");
|
|
733
775
|
}
|
|
776
|
+
if (provider === "gemini" && !env.AGENT_MEMORY_EMBEDDING_API_KEY) {
|
|
777
|
+
throw new Error("AGENT_MEMORY_EMBEDDING_API_KEY is required for gemini provider (Google AI API key)");
|
|
778
|
+
}
|
|
734
779
|
return {
|
|
735
780
|
provider,
|
|
736
|
-
baseUrl,
|
|
781
|
+
baseUrl: baseUrl ?? "",
|
|
737
782
|
model,
|
|
738
783
|
dimension,
|
|
739
784
|
apiKey: env.AGENT_MEMORY_EMBEDDING_API_KEY
|
|
@@ -742,8 +787,17 @@ function getEmbeddingProviderConfigFromEnv(env = process.env) {
|
|
|
742
787
|
function createEmbeddingProvider(input, opts) {
|
|
743
788
|
const normalized = {
|
|
744
789
|
...input,
|
|
745
|
-
baseUrl: normalizeEmbeddingBaseUrl(input.baseUrl)
|
|
790
|
+
baseUrl: input.baseUrl ? normalizeEmbeddingBaseUrl(input.baseUrl) : ""
|
|
746
791
|
};
|
|
792
|
+
if (normalized.provider === "gemini") {
|
|
793
|
+
return createGeminiEmbeddingProvider({
|
|
794
|
+
model: normalized.model,
|
|
795
|
+
dimension: normalized.dimension,
|
|
796
|
+
apiKey: normalized.apiKey,
|
|
797
|
+
baseUrl: normalized.baseUrl || void 0,
|
|
798
|
+
fetchImpl: opts?.fetchImpl
|
|
799
|
+
});
|
|
800
|
+
}
|
|
747
801
|
if (normalized.provider === "openai-compatible") {
|
|
748
802
|
return createOpenAICompatibleEmbeddingProvider({
|
|
749
803
|
baseUrl: normalized.baseUrl,
|
|
@@ -770,13 +824,16 @@ function resolveEmbeddingProviderConfig(opts) {
|
|
|
770
824
|
const model = opts?.config?.model ?? envConfig?.model;
|
|
771
825
|
const dimension = opts?.config?.dimension ?? envConfig?.dimension;
|
|
772
826
|
const apiKey = opts?.config?.apiKey ?? envConfig?.apiKey;
|
|
773
|
-
if (!provider || !
|
|
827
|
+
if (!provider || !model || !dimension) {
|
|
774
828
|
throw new Error("Incomplete embedding provider configuration");
|
|
775
829
|
}
|
|
776
|
-
if (provider
|
|
777
|
-
throw new Error("
|
|
830
|
+
if (provider !== "gemini" && !baseUrl) {
|
|
831
|
+
throw new Error("baseUrl is required for non-gemini embedding providers");
|
|
832
|
+
}
|
|
833
|
+
if ((provider === "openai-compatible" || provider === "gemini") && !apiKey) {
|
|
834
|
+
throw new Error(`${provider} embedding provider requires an API key`);
|
|
778
835
|
}
|
|
779
|
-
return { provider, baseUrl, model, dimension, apiKey };
|
|
836
|
+
return { provider, baseUrl: baseUrl ?? "", model, dimension, apiKey };
|
|
780
837
|
}
|
|
781
838
|
function getEmbeddingProvider(opts) {
|
|
782
839
|
const config = resolveEmbeddingProviderConfig({ config: opts?.config, env: opts?.env });
|