telegram-agent-memory 0.2.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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +186 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +12 -0
- package/dist/intelligence/AnthropicProvider.d.ts +20 -0
- package/dist/intelligence/AnthropicProvider.js +64 -0
- package/dist/intelligence/OpenAIProvider.d.ts +16 -0
- package/dist/intelligence/OpenAIProvider.js +51 -0
- package/dist/intelligence/logger.d.ts +7 -0
- package/dist/intelligence/logger.js +6 -0
- package/dist/intelligence/types.d.ts +18 -0
- package/dist/intelligence/types.js +2 -0
- package/dist/telegram/TelegramMemory.d.ts +174 -0
- package/dist/telegram/TelegramMemory.js +981 -0
- package/dist/telegram/file-memory.d.ts +72 -0
- package/dist/telegram/file-memory.js +325 -0
- package/dist/telegram/local-index.d.ts +53 -0
- package/dist/telegram/local-index.js +130 -0
- package/package.json +68 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.1 - 2026-04-11
|
|
4
|
+
|
|
5
|
+
- moved shared stable profile memory into a canonical `users/<userId>/PROFILE.*` layout
|
|
6
|
+
- kept daily memory and local recall indexes group-scoped under `groups/<groupId>/members/<userId>/`
|
|
7
|
+
- added compatibility coverage for migrating older group-scoped profile data into the shared user-scoped profile file
|
|
8
|
+
- updated the docs so the public file layout matches the actual cross-group memory model
|
|
9
|
+
|
|
10
|
+
## 0.2.0 - 2026-04-10
|
|
11
|
+
|
|
12
|
+
- added built-in support for Anthropic Claude as an LLM provider
|
|
13
|
+
- kept OpenAI-compatible and OpenRouter-style API support through configurable base URLs and headers
|
|
14
|
+
- switched the default semantic index embeddings to a built-in local embedding provider
|
|
15
|
+
- changed the default memory model so stable profile memory is shared across groups while daily memory stays group-specific
|
|
16
|
+
- tightened the engineering quality gate with ESLint, Prettier, `verify`, `release:check`, and GitHub CI
|
|
17
|
+
- improved release hygiene with a changelog, release guide, packaging checks, and clearer product-boundary docs
|
|
18
|
+
|
|
19
|
+
## 0.1.0 - 2026-04-10
|
|
20
|
+
|
|
21
|
+
- initial Telegram-focused public release
|
|
22
|
+
- file-first member memory with `remember()`, `context()`, and `recall()`
|
|
23
|
+
- local semantic index stored in `INDEX.json`
|
|
24
|
+
- fixture-based Telegram memory behavior tests
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 alitayin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Telegram Agent Memory
|
|
2
|
+
|
|
3
|
+
A file-first long-term memory library for Telegram bots.
|
|
4
|
+
|
|
5
|
+
You only need one supported LLM provider API key. No external database is required.
|
|
6
|
+
This package is intentionally scoped to Telegram memory. External vector databases, graph databases, and generic memory-platform APIs are not part of the public product contract.
|
|
7
|
+
|
|
8
|
+
By default, stable member profile memory is shared across groups for the same `userId`, while recent daily memory stays group-specific.
|
|
9
|
+
|
|
10
|
+
The default product flow is simple:
|
|
11
|
+
|
|
12
|
+
- When a member sends a message, the LLM extracts what is worth remembering
|
|
13
|
+
- Long-term member state is written to `PROFILE.md`
|
|
14
|
+
- Recent events are written to `memory/YYYY-MM-DD.md`
|
|
15
|
+
- Before replying, `context()` always includes stable profile memory and automatically adds relevant recent memory
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install telegram-agent-memory
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Minimal Setup
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { createTelegramMemory } from 'telegram-agent-memory';
|
|
27
|
+
|
|
28
|
+
const memory = await createTelegramMemory({
|
|
29
|
+
apiKey: process.env.OPENAI_API_KEY!,
|
|
30
|
+
whatToRemember: `
|
|
31
|
+
Remember:
|
|
32
|
+
- user preferences
|
|
33
|
+
- ongoing plans
|
|
34
|
+
- important status changes
|
|
35
|
+
|
|
36
|
+
Ignore:
|
|
37
|
+
- greetings
|
|
38
|
+
- filler chat
|
|
39
|
+
- one-off small talk
|
|
40
|
+
`,
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Store Memory
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
await memory.remember('I like coffee and usually work in Beijing.', {
|
|
48
|
+
userId: 'tg_user_123',
|
|
49
|
+
groupId: 'tg_group_456',
|
|
50
|
+
username: 'alice',
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
By default, this creates files like:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
.telegram-agent-memory/
|
|
58
|
+
users/
|
|
59
|
+
tg_user_123/
|
|
60
|
+
PROFILE.md
|
|
61
|
+
PROFILE.json
|
|
62
|
+
groups/
|
|
63
|
+
tg_group_456/
|
|
64
|
+
members/
|
|
65
|
+
tg_user_123/
|
|
66
|
+
INDEX.json
|
|
67
|
+
memory/
|
|
68
|
+
2026-04-10.md
|
|
69
|
+
2026-04-10.json
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`users/<userId>/PROFILE.*` is the stable cross-group member profile. `groups/<groupId>/members/<userId>/memory/*` is recent group-specific memory.
|
|
73
|
+
|
|
74
|
+
`INDEX.json` is an internal local embedding index used for automatic recall. It is managed by the library and does not require any external database.
|
|
75
|
+
|
|
76
|
+
## Build Prompt Context
|
|
77
|
+
|
|
78
|
+
This is the main read path.
|
|
79
|
+
|
|
80
|
+
`context()` automatically:
|
|
81
|
+
|
|
82
|
+
- includes stable member profile facts
|
|
83
|
+
- searches recent daily memory with the current message
|
|
84
|
+
- adds only relevant recent memory when it helps
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
const context = await memory.context('What should I know before replying?', {
|
|
88
|
+
userId: 'tg_user_123',
|
|
89
|
+
groupId: 'tg_group_456',
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
console.log(context.text);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The host bot does not need to decide when to use profile memory vs recent memory. The library decides that inside `context()`.
|
|
96
|
+
|
|
97
|
+
## Optional Recall
|
|
98
|
+
|
|
99
|
+
`recall()` still exists as a lower-level compatibility API if you want the ranked memory items directly.
|
|
100
|
+
|
|
101
|
+
## Initialize From Environment
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { createTelegramMemoryFromEnv } from 'telegram-agent-memory';
|
|
105
|
+
|
|
106
|
+
const memory = await createTelegramMemoryFromEnv();
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Common environment variables:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
TELEGRAM_MEMORY_LLM_PROVIDER=openai
|
|
113
|
+
OPENAI_API_KEY=sk-...
|
|
114
|
+
OPENAI_MODEL=gpt-4o-mini
|
|
115
|
+
OPENAI_BASE_URL=
|
|
116
|
+
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
|
|
117
|
+
OPENAI_HEADERS_JSON=
|
|
118
|
+
ANTHROPIC_API_KEY=
|
|
119
|
+
ANTHROPIC_MODEL=claude-3-5-haiku-latest
|
|
120
|
+
ANTHROPIC_BASE_URL=
|
|
121
|
+
ANTHROPIC_HEADERS_JSON=
|
|
122
|
+
TELEGRAM_MEMORY_DIR=./data/telegram-memory
|
|
123
|
+
TELEGRAM_MEMORY_POLICY=Remember user preferences and important status changes. Ignore filler chat.
|
|
124
|
+
TELEGRAM_MEMORY_RECENT_DAYS=3
|
|
125
|
+
TELEGRAM_MEMORY_MAX_PROFILE_FACTS=40
|
|
126
|
+
TELEGRAM_MEMORY_MAX_FACTS_PER_MESSAGE=8
|
|
127
|
+
TELEGRAM_MEMORY_SHARE_PROFILE_ACROSS_GROUPS=true
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
If `TELEGRAM_MEMORY_DIR` is not set, the default path is `.telegram-agent-memory/` under the current working directory.
|
|
131
|
+
|
|
132
|
+
## Public API
|
|
133
|
+
|
|
134
|
+
- `createTelegramMemory(...)`
|
|
135
|
+
- `createTelegramMemoryFromEnv(...)`
|
|
136
|
+
- `TelegramMemory`
|
|
137
|
+
- `remember(...)`
|
|
138
|
+
- `context(...)`
|
|
139
|
+
- `recall(...)` for lower-level access
|
|
140
|
+
|
|
141
|
+
## Provider Compatibility
|
|
142
|
+
|
|
143
|
+
Built-in support today:
|
|
144
|
+
|
|
145
|
+
- OpenAI directly
|
|
146
|
+
- OpenAI-compatible APIs through `OPENAI_BASE_URL`
|
|
147
|
+
- OpenRouter-style setups, including optional headers through `OPENAI_HEADERS_JSON`, `OPENROUTER_HTTP_REFERER`, and `OPENROUTER_APP_NAME`
|
|
148
|
+
- Anthropic Claude through `TELEGRAM_MEMORY_LLM_PROVIDER=anthropic` plus `ANTHROPIC_API_KEY`
|
|
149
|
+
|
|
150
|
+
Embeddings are local by default.
|
|
151
|
+
If you explicitly want OpenAI-compatible remote embeddings, set `OPENAI_EMBEDDING_MODEL`.
|
|
152
|
+
|
|
153
|
+
## Evaluation
|
|
154
|
+
|
|
155
|
+
The repo includes fixture-based product tests for Telegram memory behavior:
|
|
156
|
+
|
|
157
|
+
- extraction into `profile` vs `daily`
|
|
158
|
+
- skip behavior for low-value messages
|
|
159
|
+
- automatic recent-memory recall inside `context()`
|
|
160
|
+
- user/group isolation
|
|
161
|
+
- English, Chinese, and mixed-language message coverage
|
|
162
|
+
|
|
163
|
+
Run them with:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
npm run format:check
|
|
167
|
+
npm run test:telegram-memory
|
|
168
|
+
npm run lint
|
|
169
|
+
npm run release:check
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Design Boundaries
|
|
173
|
+
|
|
174
|
+
- The library is file-first and does not use Qdrant, Neo4j, or another external vector database as part of the product path
|
|
175
|
+
- `INDEX.json` is an internal local semantic index, not a public storage abstraction
|
|
176
|
+
- The only supported public entrypoint is the Telegram-focused package root
|
|
177
|
+
- Historical generic-memory modules now live under `legacy/` and are not part of the npm surface, the default tests, or the supported architecture
|
|
178
|
+
- The package is not designed for high-concurrency centralized shared storage or as a generic cross-channel memory backend
|
|
179
|
+
- Stable profile memory is shared across groups by default; set `TELEGRAM_MEMORY_SHARE_PROFILE_ACROSS_GROUPS=false` only if you explicitly want group-isolated profiles
|
|
180
|
+
|
|
181
|
+
See [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md) for the explicit product boundary.
|
|
182
|
+
For local release hygiene, see [docs/RELEASE.md](./docs/RELEASE.md).
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { TelegramMemory, createTelegramMemory, createTelegramMemoryFromEnv, validateTelegramMemoryConfig, assertValidTelegramMemoryConfig, telegramMemoryConfigFromEnv, TelegramMemoryConfigError, } from './telegram/TelegramMemory';
|
|
2
|
+
export type { TelegramActor, TelegramRecallOptions, TelegramPromptContextOptions, TelegramMemoryStorageConfig, TelegramMemoryBehaviorConfig, TelegramMemoryConfig, TelegramMemoryConfigValidationIssue, TelegramMemoryFromEnvOptions, TelegramMemoryHealthReport, TelegramMemoryPreflightCheck, TelegramMemoryPreflightReport, TelegramRememberResult, TelegramRecallResult, TelegramPromptMemory, TelegramMemoryLogger, TelegramMemoryDependencies, } from './telegram/TelegramMemory';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Product-facing exports for the Telegram intelligent memory package.
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.TelegramMemoryConfigError = exports.telegramMemoryConfigFromEnv = exports.assertValidTelegramMemoryConfig = exports.validateTelegramMemoryConfig = exports.createTelegramMemoryFromEnv = exports.createTelegramMemory = exports.TelegramMemory = void 0;
|
|
5
|
+
var TelegramMemory_1 = require("./telegram/TelegramMemory");
|
|
6
|
+
Object.defineProperty(exports, "TelegramMemory", { enumerable: true, get: function () { return TelegramMemory_1.TelegramMemory; } });
|
|
7
|
+
Object.defineProperty(exports, "createTelegramMemory", { enumerable: true, get: function () { return TelegramMemory_1.createTelegramMemory; } });
|
|
8
|
+
Object.defineProperty(exports, "createTelegramMemoryFromEnv", { enumerable: true, get: function () { return TelegramMemory_1.createTelegramMemoryFromEnv; } });
|
|
9
|
+
Object.defineProperty(exports, "validateTelegramMemoryConfig", { enumerable: true, get: function () { return TelegramMemory_1.validateTelegramMemoryConfig; } });
|
|
10
|
+
Object.defineProperty(exports, "assertValidTelegramMemoryConfig", { enumerable: true, get: function () { return TelegramMemory_1.assertValidTelegramMemoryConfig; } });
|
|
11
|
+
Object.defineProperty(exports, "telegramMemoryConfigFromEnv", { enumerable: true, get: function () { return TelegramMemory_1.telegramMemoryConfigFromEnv; } });
|
|
12
|
+
Object.defineProperty(exports, "TelegramMemoryConfigError", { enumerable: true, get: function () { return TelegramMemory_1.TelegramMemoryConfigError; } });
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { MemoryLogger } from './logger';
|
|
2
|
+
import type { LLMOptions, LLMProvider } from './types';
|
|
3
|
+
export interface AnthropicProviderConfig {
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
model?: string;
|
|
6
|
+
baseURL?: string;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
anthropicVersion?: string;
|
|
9
|
+
logger?: MemoryLogger;
|
|
10
|
+
}
|
|
11
|
+
export declare class AnthropicProvider implements LLMProvider {
|
|
12
|
+
private readonly apiKey?;
|
|
13
|
+
private readonly baseURL;
|
|
14
|
+
private readonly defaultModel;
|
|
15
|
+
private readonly headers?;
|
|
16
|
+
private readonly anthropicVersion;
|
|
17
|
+
private readonly logger?;
|
|
18
|
+
constructor(config?: AnthropicProviderConfig);
|
|
19
|
+
generate(prompt: string, options?: LLMOptions): Promise<string>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AnthropicProvider = void 0;
|
|
4
|
+
const logger_1 = require("./logger");
|
|
5
|
+
const DEFAULT_ANTHROPIC_BASE_URL = 'https://api.anthropic.com';
|
|
6
|
+
const DEFAULT_ANTHROPIC_MODEL = 'claude-3-5-haiku-latest';
|
|
7
|
+
const DEFAULT_ANTHROPIC_VERSION = '2023-06-01';
|
|
8
|
+
class AnthropicProvider {
|
|
9
|
+
constructor(config = {}) {
|
|
10
|
+
this.apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;
|
|
11
|
+
this.baseURL = (config.baseURL || DEFAULT_ANTHROPIC_BASE_URL).replace(/\/+$/, '');
|
|
12
|
+
this.defaultModel = config.model || DEFAULT_ANTHROPIC_MODEL;
|
|
13
|
+
this.headers = config.headers;
|
|
14
|
+
this.anthropicVersion = config.anthropicVersion || DEFAULT_ANTHROPIC_VERSION;
|
|
15
|
+
this.logger = config.logger;
|
|
16
|
+
}
|
|
17
|
+
async generate(prompt, options = {}) {
|
|
18
|
+
const model = options.model || this.defaultModel;
|
|
19
|
+
const temperature = options.temperature ?? 0.3;
|
|
20
|
+
const maxTokens = options.maxTokens || 1000;
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch(`${this.baseURL}/v1/messages`, {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: {
|
|
25
|
+
'content-type': 'application/json',
|
|
26
|
+
'x-api-key': this.apiKey ?? '',
|
|
27
|
+
'anthropic-version': this.anthropicVersion,
|
|
28
|
+
...this.headers,
|
|
29
|
+
},
|
|
30
|
+
body: JSON.stringify({
|
|
31
|
+
model,
|
|
32
|
+
max_tokens: maxTokens,
|
|
33
|
+
temperature,
|
|
34
|
+
system: options.responseFormat === 'json_object'
|
|
35
|
+
? 'You are a fact extraction system. Return strict valid JSON only.'
|
|
36
|
+
: 'You are a fact extraction system.',
|
|
37
|
+
messages: [
|
|
38
|
+
{
|
|
39
|
+
role: 'user',
|
|
40
|
+
content: prompt,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
}),
|
|
44
|
+
});
|
|
45
|
+
const payload = (await response.json());
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new Error(payload.error?.message || `Anthropic request failed with status ${response.status}`);
|
|
48
|
+
}
|
|
49
|
+
return (payload.content
|
|
50
|
+
?.filter((block) => block.type === 'text' && typeof block.text === 'string')
|
|
51
|
+
.map((block) => block.text)
|
|
52
|
+
.join('\n')
|
|
53
|
+
.trim() || '{}');
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.logger?.error?.('Anthropic API request failed.', {
|
|
57
|
+
error: (0, logger_1.formatLoggerError)(error),
|
|
58
|
+
model,
|
|
59
|
+
});
|
|
60
|
+
throw new Error(`Anthropic generation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.AnthropicProvider = AnthropicProvider;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { LLMOptions, LLMProvider } from './types';
|
|
2
|
+
import type { MemoryLogger } from './logger';
|
|
3
|
+
export interface OpenAIProviderConfig {
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
model?: string;
|
|
6
|
+
baseURL?: string;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
logger?: MemoryLogger;
|
|
9
|
+
}
|
|
10
|
+
export declare class OpenAIProvider implements LLMProvider {
|
|
11
|
+
private readonly client;
|
|
12
|
+
private readonly defaultModel;
|
|
13
|
+
private readonly logger?;
|
|
14
|
+
constructor(config?: OpenAIProviderConfig);
|
|
15
|
+
generate(prompt: string, options?: LLMOptions): Promise<string>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OpenAIProvider = void 0;
|
|
7
|
+
const openai_1 = __importDefault(require("openai"));
|
|
8
|
+
const logger_1 = require("./logger");
|
|
9
|
+
class OpenAIProvider {
|
|
10
|
+
constructor(config = {}) {
|
|
11
|
+
this.client = new openai_1.default({
|
|
12
|
+
apiKey: config.apiKey || process.env.OPENAI_API_KEY,
|
|
13
|
+
baseURL: config.baseURL,
|
|
14
|
+
defaultHeaders: config.headers,
|
|
15
|
+
});
|
|
16
|
+
this.defaultModel = config.model || 'gpt-4o-mini';
|
|
17
|
+
this.logger = config.logger;
|
|
18
|
+
}
|
|
19
|
+
async generate(prompt, options = {}) {
|
|
20
|
+
const model = options.model || this.defaultModel;
|
|
21
|
+
const temperature = options.temperature ?? 0.3;
|
|
22
|
+
const maxTokens = options.maxTokens || 1000;
|
|
23
|
+
try {
|
|
24
|
+
const completion = await this.client.chat.completions.create({
|
|
25
|
+
model,
|
|
26
|
+
messages: [
|
|
27
|
+
{
|
|
28
|
+
role: 'system',
|
|
29
|
+
content: 'You are a fact extraction system. Extract structured facts from user messages and return valid JSON.',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
role: 'user',
|
|
33
|
+
content: prompt,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
temperature,
|
|
37
|
+
max_tokens: maxTokens,
|
|
38
|
+
response_format: options.responseFormat === 'json_object' ? { type: 'json_object' } : { type: 'text' },
|
|
39
|
+
});
|
|
40
|
+
return completion.choices[0]?.message?.content || '{}';
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
this.logger?.error?.('OpenAI API request failed.', {
|
|
44
|
+
error: (0, logger_1.formatLoggerError)(error),
|
|
45
|
+
model,
|
|
46
|
+
});
|
|
47
|
+
throw new Error(`OpenAI generation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.OpenAIProvider = OpenAIProvider;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface MemoryLogger {
|
|
2
|
+
debug?(message: string, metadata?: Record<string, unknown>): void;
|
|
3
|
+
info?(message: string, metadata?: Record<string, unknown>): void;
|
|
4
|
+
warn?(message: string, metadata?: Record<string, unknown>): void;
|
|
5
|
+
error?(message: string, metadata?: Record<string, unknown>): void;
|
|
6
|
+
}
|
|
7
|
+
export declare function formatLoggerError(error: unknown): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MemoryLogger } from './logger';
|
|
2
|
+
export interface LLMProvider {
|
|
3
|
+
generate(prompt: string, options?: LLMOptions): Promise<string>;
|
|
4
|
+
}
|
|
5
|
+
export interface LLMOptions {
|
|
6
|
+
temperature?: number;
|
|
7
|
+
maxTokens?: number;
|
|
8
|
+
responseFormat?: 'text' | 'json_object';
|
|
9
|
+
model?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface FactExtractorConfig {
|
|
12
|
+
llm?: LLMProvider;
|
|
13
|
+
mockMode?: boolean;
|
|
14
|
+
language?: string;
|
|
15
|
+
minImportance?: number;
|
|
16
|
+
enableBatch?: boolean;
|
|
17
|
+
logger?: MemoryLogger;
|
|
18
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import type { LLMProvider } from '../intelligence/types';
|
|
2
|
+
import type { MemoryLogger } from '../intelligence/logger';
|
|
3
|
+
import { StoredMemoryFact, TelegramFileMemoryStore } from './file-memory';
|
|
4
|
+
import { TelegramEmbeddingProvider } from './local-index';
|
|
5
|
+
export interface TelegramActor {
|
|
6
|
+
userId: string;
|
|
7
|
+
groupId: string;
|
|
8
|
+
username?: string;
|
|
9
|
+
metadata?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export interface TelegramRecallOptions {
|
|
12
|
+
userId: string;
|
|
13
|
+
groupId: string;
|
|
14
|
+
limit?: number;
|
|
15
|
+
minImportance?: number;
|
|
16
|
+
includeProfile?: boolean;
|
|
17
|
+
recentDays?: number;
|
|
18
|
+
}
|
|
19
|
+
export type TelegramPromptContextOptions = TelegramRecallOptions;
|
|
20
|
+
export interface TelegramMemoryOpenAIConfig {
|
|
21
|
+
apiKey: string;
|
|
22
|
+
model?: string;
|
|
23
|
+
baseURL?: string;
|
|
24
|
+
embeddingModel?: string;
|
|
25
|
+
headers?: Record<string, string>;
|
|
26
|
+
}
|
|
27
|
+
export interface TelegramMemoryAnthropicConfig {
|
|
28
|
+
apiKey: string;
|
|
29
|
+
model?: string;
|
|
30
|
+
baseURL?: string;
|
|
31
|
+
headers?: Record<string, string>;
|
|
32
|
+
}
|
|
33
|
+
export interface TelegramMemoryStorageConfig {
|
|
34
|
+
rootDir?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface TelegramMemoryBehaviorConfig {
|
|
37
|
+
recentDays?: number;
|
|
38
|
+
maxProfileFacts?: number;
|
|
39
|
+
maxFactsPerMessage?: number;
|
|
40
|
+
shareProfileAcrossGroups?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface TelegramMemoryConfig {
|
|
43
|
+
provider?: 'openai' | 'anthropic';
|
|
44
|
+
apiKey?: string;
|
|
45
|
+
model?: string;
|
|
46
|
+
baseURL?: string;
|
|
47
|
+
embeddingModel?: string;
|
|
48
|
+
headers?: Record<string, string>;
|
|
49
|
+
dir?: string;
|
|
50
|
+
whatToRemember?: string;
|
|
51
|
+
openai?: TelegramMemoryOpenAIConfig;
|
|
52
|
+
anthropic?: TelegramMemoryAnthropicConfig;
|
|
53
|
+
storage?: TelegramMemoryStorageConfig;
|
|
54
|
+
behavior?: TelegramMemoryBehaviorConfig;
|
|
55
|
+
}
|
|
56
|
+
export interface TelegramMemoryConfigValidationIssue {
|
|
57
|
+
field: string;
|
|
58
|
+
message: string;
|
|
59
|
+
}
|
|
60
|
+
export interface TelegramMemoryFromEnvOptions {
|
|
61
|
+
env?: NodeJS.ProcessEnv;
|
|
62
|
+
}
|
|
63
|
+
export interface TelegramMemoryDependencies {
|
|
64
|
+
llm?: LLMProvider;
|
|
65
|
+
logger?: TelegramMemoryLogger;
|
|
66
|
+
store?: TelegramFileMemoryStore;
|
|
67
|
+
embedder?: TelegramEmbeddingProvider;
|
|
68
|
+
now?: () => Date;
|
|
69
|
+
}
|
|
70
|
+
export type TelegramMemoryLogger = MemoryLogger;
|
|
71
|
+
export interface TelegramMemoryHealthReport {
|
|
72
|
+
ok: boolean;
|
|
73
|
+
checks: Array<{
|
|
74
|
+
name: 'storage' | 'llm';
|
|
75
|
+
ok: boolean;
|
|
76
|
+
message?: string;
|
|
77
|
+
}>;
|
|
78
|
+
}
|
|
79
|
+
export interface TelegramMemoryPreflightCheck {
|
|
80
|
+
name: 'config' | 'storage' | 'llm';
|
|
81
|
+
ok: boolean;
|
|
82
|
+
fatal: boolean;
|
|
83
|
+
message?: string;
|
|
84
|
+
details?: Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
export interface TelegramMemoryPreflightReport {
|
|
87
|
+
ok: boolean;
|
|
88
|
+
checks: TelegramMemoryPreflightCheck[];
|
|
89
|
+
}
|
|
90
|
+
export interface TelegramRememberResult {
|
|
91
|
+
profileFacts: StoredMemoryFact[];
|
|
92
|
+
dailyFacts: StoredMemoryFact[];
|
|
93
|
+
skipped: boolean;
|
|
94
|
+
summary: {
|
|
95
|
+
added: number;
|
|
96
|
+
profile: number;
|
|
97
|
+
daily: number;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export interface TelegramRecallResult {
|
|
101
|
+
id: string;
|
|
102
|
+
kind: 'profile' | 'daily';
|
|
103
|
+
content: string;
|
|
104
|
+
summary: string;
|
|
105
|
+
category: string;
|
|
106
|
+
importance: number;
|
|
107
|
+
score: number;
|
|
108
|
+
path: string;
|
|
109
|
+
updatedAt: string;
|
|
110
|
+
}
|
|
111
|
+
export type TelegramPromptMemory = TelegramRecallResult;
|
|
112
|
+
export interface BuildContextResult {
|
|
113
|
+
text: string;
|
|
114
|
+
memories: TelegramPromptMemory[];
|
|
115
|
+
}
|
|
116
|
+
export declare class TelegramMemoryConfigError extends Error {
|
|
117
|
+
readonly issues: TelegramMemoryConfigValidationIssue[];
|
|
118
|
+
constructor(message: string, issues: TelegramMemoryConfigValidationIssue[]);
|
|
119
|
+
}
|
|
120
|
+
export declare class TelegramMemory {
|
|
121
|
+
private readonly store;
|
|
122
|
+
private readonly llm;
|
|
123
|
+
private readonly embedder;
|
|
124
|
+
private readonly logger?;
|
|
125
|
+
private readonly now;
|
|
126
|
+
private readonly rootDir;
|
|
127
|
+
private readonly recentDays;
|
|
128
|
+
private readonly maxProfileFacts;
|
|
129
|
+
private readonly maxFactsPerMessage;
|
|
130
|
+
private readonly shareProfileAcrossGroups;
|
|
131
|
+
private readonly provider;
|
|
132
|
+
private readonly rawConfig;
|
|
133
|
+
private readonly whatToRemember?;
|
|
134
|
+
constructor(config: TelegramMemoryConfig, deps?: TelegramMemoryDependencies);
|
|
135
|
+
rememberTelegramMessage(message: string, actor: TelegramActor): Promise<TelegramRememberResult>;
|
|
136
|
+
remember(message: string, actor: TelegramActor): Promise<TelegramRememberResult>;
|
|
137
|
+
recall(query: string, options: TelegramRecallOptions): Promise<TelegramRecallResult[]>;
|
|
138
|
+
buildPromptContext(query: string, options: TelegramPromptContextOptions): Promise<BuildContextResult>;
|
|
139
|
+
context(query: string, options: TelegramPromptContextOptions): Promise<BuildContextResult>;
|
|
140
|
+
getUserMemoryStats(userId: string, groupId: string): Promise<{
|
|
141
|
+
profileFacts: number;
|
|
142
|
+
dailyFacts: number;
|
|
143
|
+
totalFacts: number;
|
|
144
|
+
lastUpdatedAt?: string;
|
|
145
|
+
}>;
|
|
146
|
+
getMemory(memoryId: string): Promise<StoredMemoryFact | null>;
|
|
147
|
+
updateMemory(memoryId: string, updates: Partial<Pick<StoredMemoryFact, 'content' | 'summary' | 'importance' | 'tags'>>): Promise<StoredMemoryFact | null>;
|
|
148
|
+
deleteMemory(memoryId: string): Promise<boolean>;
|
|
149
|
+
getMemoryHistory(memoryId: string): Promise<StoredMemoryFact[]>;
|
|
150
|
+
checkHealth(): Promise<TelegramMemoryHealthReport>;
|
|
151
|
+
preflight(): Promise<TelegramMemoryPreflightReport>;
|
|
152
|
+
private extractFacts;
|
|
153
|
+
private mergeProfileFacts;
|
|
154
|
+
private toStoredFact;
|
|
155
|
+
private searchIndexedFacts;
|
|
156
|
+
private collectFactsForUser;
|
|
157
|
+
private ensureLocalIndex;
|
|
158
|
+
private rebuildLocalIndex;
|
|
159
|
+
private embedQuery;
|
|
160
|
+
private embedTexts;
|
|
161
|
+
private refreshLocalIndexSafely;
|
|
162
|
+
private collectProfileFacts;
|
|
163
|
+
private readWritableProfile;
|
|
164
|
+
private writeWritableProfile;
|
|
165
|
+
private readProfileForFact;
|
|
166
|
+
private writeProfileForFact;
|
|
167
|
+
private isSharedProfilePath;
|
|
168
|
+
private profileMarkdownPathForActor;
|
|
169
|
+
}
|
|
170
|
+
export declare function createTelegramMemory(config: TelegramMemoryConfig, dependencies?: TelegramMemoryDependencies): Promise<TelegramMemory>;
|
|
171
|
+
export declare function validateTelegramMemoryConfig(config: TelegramMemoryConfig): TelegramMemoryConfigValidationIssue[];
|
|
172
|
+
export declare function assertValidTelegramMemoryConfig(config: TelegramMemoryConfig): void;
|
|
173
|
+
export declare function telegramMemoryConfigFromEnv(options?: TelegramMemoryFromEnvOptions): TelegramMemoryConfig;
|
|
174
|
+
export declare function createTelegramMemoryFromEnv(options?: TelegramMemoryFromEnvOptions, dependencies?: TelegramMemoryDependencies): Promise<TelegramMemory>;
|