mirror of
https://github.com/TencentCloud/TencentDB-Agent-Memory
synced 2026-07-10 12:34:27 +00:00
feat: release v1.0.0
This commit is contained in:
@@ -63,6 +63,23 @@ print(core["content"])
|
||||
# L3: write core memory
|
||||
client.write_core("# User Profile\n...")
|
||||
|
||||
# Offload v2: send tool pairs for server-side L1 async processing (fire-and-forget)
|
||||
client.offload_ingest(
|
||||
session_id="agent_sess_123",
|
||||
tool_pairs=[
|
||||
{"tool_name": "search", "tool_call_id": "call_1", "params": {"q": "..."}, "result": "...", "timestamp": "..."},
|
||||
],
|
||||
)
|
||||
|
||||
# Offload v2: server-side context compaction (sync wait for result)
|
||||
compacted = client.offload_compact(
|
||||
session_id="agent_sess_123",
|
||||
messages=[...],
|
||||
ratio=0.7,
|
||||
context_window=128000,
|
||||
)
|
||||
print(compacted["messages"], compacted["report"])
|
||||
|
||||
# Read memory pipeline artifacts (e.g. persona.md, scene_blocks/*.md)
|
||||
raw = client.read_file("scene_blocks/工作.md")
|
||||
```
|
||||
@@ -103,6 +120,9 @@ asyncio.run(main())
|
||||
| L2 | `rm_scenario()` | `POST /v2/scenario/rm` |
|
||||
| L3 | `read_core()` | `POST /v2/core/read` |
|
||||
| L3 | `write_core()` | `POST /v2/core/write` |
|
||||
| Offload | `offload_ingest()` | `POST /v2/offload/ingest` |
|
||||
| Offload | `offload_compact()` | `POST /v2/offload/compact` |
|
||||
| Offload | `offload_query_mmd()` | `POST /v2/offload/query-mmd` |
|
||||
|
||||
## Error Handling
|
||||
|
||||
|
||||
@@ -63,6 +63,23 @@ print(core["content"])
|
||||
# L3: 写入核心记忆
|
||||
client.write_core("# User Profile\n...")
|
||||
|
||||
# Offload v2: 上报工具调用对,触发服务端 L1 异步处理(可 fire-and-forget)
|
||||
client.offload_ingest(
|
||||
session_id="agent_sess_123",
|
||||
tool_pairs=[
|
||||
{"tool_name": "search", "tool_call_id": "call_1", "params": {"q": "..."}, "result": "...", "timestamp": "..."},
|
||||
],
|
||||
)
|
||||
|
||||
# Offload v2: 服务端上下文压缩(同步等待结果)
|
||||
compacted = client.offload_compact(
|
||||
session_id="agent_sess_123",
|
||||
messages=[...],
|
||||
ratio=0.7,
|
||||
context_window=128000,
|
||||
)
|
||||
print(compacted["messages"], compacted["report"])
|
||||
|
||||
# 读取记忆 pipeline 产物(如 persona.md、scene_blocks/*.md)
|
||||
raw = client.read_file("scene_blocks/工作.md")
|
||||
```
|
||||
@@ -103,6 +120,9 @@ asyncio.run(main())
|
||||
| L2 | `rm_scenario()` | `POST /v2/scenario/rm` |
|
||||
| L3 | `read_core()` | `POST /v2/core/read` |
|
||||
| L3 | `write_core()` | `POST /v2/core/write` |
|
||||
| Offload | `offload_ingest()` | `POST /v2/offload/ingest` |
|
||||
| Offload | `offload_compact()` | `POST /v2/offload/compact` |
|
||||
| Offload | `offload_query_mmd()` | `POST /v2/offload/query-mmd` |
|
||||
|
||||
## 错误处理
|
||||
|
||||
|
||||
@@ -255,6 +255,116 @@ class MemoryClient:
|
||||
"""``POST /core/write``"""
|
||||
return self._stub.post(f"{_V2}/core/write", {"content": content})
|
||||
|
||||
# -- Offload (Ingest + Compact + Query-MMD) ----------------------------
|
||||
|
||||
def offload_ingest(
|
||||
self,
|
||||
session_id: str,
|
||||
tool_pairs: List[Dict[str, Any]],
|
||||
*,
|
||||
prompt: Optional[str] = None,
|
||||
recent_messages: Optional[List[Dict[str, Any]]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""``POST /v2/offload/ingest`` — 上报工具调用对,触发 L1 异步处理。
|
||||
|
||||
可 fire-and-forget 使用(忽略返回值)。
|
||||
|
||||
Parameters
|
||||
----------
|
||||
session_id : str
|
||||
会话 ID。
|
||||
tool_pairs : list[dict]
|
||||
工具调用对列表,每个元素包含 ``tool_name``、``tool_call_id``、
|
||||
``params``、``result``、``timestamp``,可选 ``duration_ms``。
|
||||
prompt : str, optional
|
||||
最新 user message,用于 L1.5 任务判断。
|
||||
recent_messages : list[dict], optional
|
||||
近期历史消息列表(``role`` + ``content``),辅助 L1 提取上下文。
|
||||
"""
|
||||
return self._stub.post(
|
||||
f"{_V2}/offload/ingest",
|
||||
_strip_none({
|
||||
"session_id": session_id,
|
||||
"tool_pairs": tool_pairs,
|
||||
"prompt": prompt,
|
||||
"recent_messages": recent_messages,
|
||||
}),
|
||||
)
|
||||
|
||||
def offload_compact(
|
||||
self,
|
||||
session_id: str,
|
||||
messages: List[Dict[str, Any]],
|
||||
ratio: float,
|
||||
total_tokens: int,
|
||||
*,
|
||||
context_window: Optional[int] = None,
|
||||
message_tokens: Optional[List[int]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""``POST /v2/offload/compact`` — 对 messages 执行服务端上下文压缩。
|
||||
|
||||
Parameters
|
||||
----------
|
||||
session_id : str
|
||||
会话 ID。
|
||||
messages : list[dict]
|
||||
当前完整对话消息列表。
|
||||
ratio : float
|
||||
当前 token 使用比例(已用 / context_window),触发压缩策略判断。
|
||||
total_tokens : int
|
||||
当前完整上下文的总 token 数(包含 system prompt、tool schemas 等不在
|
||||
messages 中的隐性开销)。服务端用于计算 fixed overhead 和校准 token 估算。
|
||||
context_window : int, optional
|
||||
模型 context window 大小(token 数)。
|
||||
message_tokens : list[int], optional
|
||||
每条消息对应的 token 数,提供时可跳过服务端估算,提升性能。
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
``messages``(压缩后消息列表)+ ``report``(压缩报告)。
|
||||
"""
|
||||
return self._stub.post(
|
||||
f"{_V2}/offload/compact",
|
||||
_strip_none({
|
||||
"session_id": session_id,
|
||||
"messages": messages,
|
||||
"ratio": ratio,
|
||||
"total_tokens": total_tokens,
|
||||
"context_window": context_window,
|
||||
"message_tokens": message_tokens,
|
||||
}),
|
||||
)
|
||||
|
||||
def offload_query_mmd(
|
||||
self,
|
||||
session_id: str,
|
||||
*,
|
||||
limit: Optional[int] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""``POST /v2/offload/query-mmd`` — 查询 session 的任务流程图(MMD 文件)。
|
||||
|
||||
Parameters
|
||||
----------
|
||||
session_id : str
|
||||
会话 ID。
|
||||
limit : int, optional
|
||||
最多返回几个 MMD 文件。``limit=1`` 时走快速路径只返回当前活跃 MMD。
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
``mmds``(列表,每项含 ``filename``、``content``、``version``)+
|
||||
``current_mmd``(当前活跃 MMD 文件名,无则为 ``None``)。
|
||||
"""
|
||||
return self._stub.post(
|
||||
f"{_V2}/offload/query-mmd",
|
||||
_strip_none({
|
||||
"session_id": session_id,
|
||||
"limit": limit,
|
||||
}),
|
||||
)
|
||||
|
||||
# -- File read (memory pipeline artifacts) -----------------------------
|
||||
|
||||
def read_file(self, path: str) -> str:
|
||||
@@ -432,6 +542,65 @@ class AsyncMemoryClient:
|
||||
async def write_core(self, content: str) -> Dict[str, Any]:
|
||||
return await self._stub.post(f"{_V2}/core/write", {"content": content})
|
||||
|
||||
# -- Offload (Ingest + Compact + Query-MMD) ----------------------------
|
||||
|
||||
async def offload_ingest(
|
||||
self,
|
||||
session_id: str,
|
||||
tool_pairs: List[Dict[str, Any]],
|
||||
*,
|
||||
prompt: Optional[str] = None,
|
||||
recent_messages: Optional[List[Dict[str, Any]]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""``POST /v2/offload/ingest``(异步)"""
|
||||
return await self._stub.post(
|
||||
f"{_V2}/offload/ingest",
|
||||
_strip_none({
|
||||
"session_id": session_id,
|
||||
"tool_pairs": tool_pairs,
|
||||
"prompt": prompt,
|
||||
"recent_messages": recent_messages,
|
||||
}),
|
||||
)
|
||||
|
||||
async def offload_compact(
|
||||
self,
|
||||
session_id: str,
|
||||
messages: List[Dict[str, Any]],
|
||||
ratio: float,
|
||||
total_tokens: int,
|
||||
*,
|
||||
context_window: Optional[int] = None,
|
||||
message_tokens: Optional[List[int]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""``POST /v2/offload/compact``(异步)"""
|
||||
return await self._stub.post(
|
||||
f"{_V2}/offload/compact",
|
||||
_strip_none({
|
||||
"session_id": session_id,
|
||||
"messages": messages,
|
||||
"ratio": ratio,
|
||||
"total_tokens": total_tokens,
|
||||
"context_window": context_window,
|
||||
"message_tokens": message_tokens,
|
||||
}),
|
||||
)
|
||||
|
||||
async def offload_query_mmd(
|
||||
self,
|
||||
session_id: str,
|
||||
*,
|
||||
limit: Optional[int] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""``POST /v2/offload/query-mmd``(异步)"""
|
||||
return await self._stub.post(
|
||||
f"{_V2}/offload/query-mmd",
|
||||
_strip_none({
|
||||
"session_id": session_id,
|
||||
"limit": limit,
|
||||
}),
|
||||
)
|
||||
|
||||
# -- lifecycle ---------------------------------------------------------
|
||||
|
||||
# -- File read (memory pipeline artifacts) -----------------------------
|
||||
|
||||
@@ -58,6 +58,28 @@ console.log(core.content);
|
||||
// L3: write core memory
|
||||
await client.writeCore({ content: "# User Profile\n..." });
|
||||
|
||||
// Offload v2: send tool pairs for server-side L1 async processing (fire-and-forget)
|
||||
await client.offloadIngest({
|
||||
session_id: "agent_sess_123",
|
||||
tool_pairs: [
|
||||
{ tool_name: "search", tool_call_id: "call_1", params: { q: "..." }, result: "...", timestamp: "..." },
|
||||
],
|
||||
});
|
||||
|
||||
// Offload v2: server-side context compaction (sync wait for result)
|
||||
const compacted = await client.offloadCompact({
|
||||
session_id: "agent_sess_123",
|
||||
messages: [...],
|
||||
ratio: 0.7,
|
||||
context_window: 128000,
|
||||
total_tokens: 160000,
|
||||
});
|
||||
console.log(compacted.messages, compacted.report);
|
||||
|
||||
// Offload v2: query MMD task graphs
|
||||
const mmd = await client.offloadQueryMmd({ session_id: "agent_sess_123", limit: 1 });
|
||||
console.log(mmd.current_mmd, mmd.mmds);
|
||||
|
||||
// Read memory pipeline artifacts (e.g. persona.md, scene_blocks/*.md)
|
||||
const raw = await client.readFile("scene_blocks/工作.md");
|
||||
```
|
||||
@@ -80,6 +102,9 @@ const raw = await client.readFile("scene_blocks/工作.md");
|
||||
| L2 | `rmScenario()` | `POST /v2/scenario/rm` |
|
||||
| L3 | `readCore()` | `POST /v2/core/read` |
|
||||
| L3 | `writeCore()` | `POST /v2/core/write` |
|
||||
| Offload | `offloadIngest()` | `POST /v2/offload/ingest` |
|
||||
| Offload | `offloadCompact()` | `POST /v2/offload/compact` |
|
||||
| Offload | `offloadQueryMmd()` | `POST /v2/offload/query-mmd` |
|
||||
|
||||
## Error Handling
|
||||
|
||||
|
||||
@@ -58,6 +58,28 @@ console.log(core.content);
|
||||
// L3: 写入核心记忆
|
||||
await client.writeCore({ content: "# User Profile\n..." });
|
||||
|
||||
// Offload v2: 上报工具调用对,触发服务端 L1 异步处理(fire-and-forget)
|
||||
await client.offloadIngest({
|
||||
session_id: "agent_sess_123",
|
||||
tool_pairs: [
|
||||
{ tool_name: "search", tool_call_id: "call_1", params: { q: "..." }, result: "...", timestamp: "..." },
|
||||
],
|
||||
});
|
||||
|
||||
// Offload v2: 服务端上下文压缩(同步等待结果)
|
||||
const compacted = await client.offloadCompact({
|
||||
session_id: "agent_sess_123",
|
||||
messages: [...],
|
||||
ratio: 0.7,
|
||||
context_window: 128000,
|
||||
total_tokens: 160000,
|
||||
});
|
||||
console.log(compacted.messages, compacted.report);
|
||||
|
||||
// Offload v2: 查询任务流程图(MMD)
|
||||
const mmd = await client.offloadQueryMmd({ session_id: "agent_sess_123", limit: 1 });
|
||||
console.log(mmd.current_mmd, mmd.mmds);
|
||||
|
||||
// 读取记忆 pipeline 产物(如 persona.md、scene_blocks/*.md)
|
||||
const raw = await client.readFile("scene_blocks/工作.md");
|
||||
```
|
||||
@@ -80,6 +102,9 @@ const raw = await client.readFile("scene_blocks/工作.md");
|
||||
| L2 | `rmScenario()` | `POST /v2/scenario/rm` |
|
||||
| L3 | `readCore()` | `POST /v2/core/read` |
|
||||
| L3 | `writeCore()` | `POST /v2/core/write` |
|
||||
| Offload | `offloadIngest()` | `POST /v2/offload/ingest` |
|
||||
| Offload | `offloadCompact()` | `POST /v2/offload/compact` |
|
||||
| Offload | `offloadQueryMmd()` | `POST /v2/offload/query-mmd` |
|
||||
|
||||
## 错误处理
|
||||
|
||||
|
||||
@@ -25,6 +25,12 @@ import type {
|
||||
CoreFile,
|
||||
CoreWriteData,
|
||||
CoreWriteRequest,
|
||||
OffloadCompactData,
|
||||
OffloadCompactRequest,
|
||||
OffloadIngestData,
|
||||
OffloadIngestRequest,
|
||||
OffloadQueryMmdData,
|
||||
OffloadQueryMmdRequest,
|
||||
ScenarioFile,
|
||||
ScenarioListData,
|
||||
ScenarioListRequest,
|
||||
@@ -148,6 +154,32 @@ export class MemoryClient {
|
||||
return this.http.post(`${V2}/core/write`, params as unknown as Record<string, unknown>);
|
||||
}
|
||||
|
||||
// -- Offload (Compaction + Ingest) ------------------------------------
|
||||
|
||||
/**
|
||||
* Send tool pairs (+ optional context) to offload server for L1 processing.
|
||||
* Fire-and-forget usage: caller can `.catch()` without blocking.
|
||||
*/
|
||||
offloadIngest(params: OffloadIngestRequest): Promise<OffloadIngestData> {
|
||||
return this.http.post(`${V2}/offload/ingest`, stripUndefined(params as unknown as Record<string, unknown>));
|
||||
}
|
||||
|
||||
/**
|
||||
* Request server-side context compaction.
|
||||
* Returns compacted messages + report, or throws on failure.
|
||||
*/
|
||||
offloadCompact(params: OffloadCompactRequest): Promise<OffloadCompactData> {
|
||||
return this.http.post(`${V2}/offload/compact`, stripUndefined(params as unknown as Record<string, unknown>));
|
||||
}
|
||||
|
||||
/**
|
||||
* Query MMD task graphs for a session.
|
||||
* limit=1 returns only the current active MMD (fast path).
|
||||
*/
|
||||
offloadQueryMmd(params: OffloadQueryMmdRequest): Promise<OffloadQueryMmdData> {
|
||||
return this.http.post(`${V2}/offload/query-mmd`, stripUndefined(params as unknown as Record<string, unknown>));
|
||||
}
|
||||
|
||||
// -- File read (memory pipeline artifacts) ----------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,4 +6,28 @@ export { MemoryClient, type MemoryClientConfig, type Transport } from "./client.
|
||||
export { TDAMError } from "./errors.js";
|
||||
export { HttpTransport, type HttpTransportOptions } from "./http.js";
|
||||
export { MemoryFileReader, StsCredentialManager, StsCredential, createMemoryFileReader, cosV5Sign, type MemoryFileReaderConfig } from "./cos.js";
|
||||
export type * from "./types.js";
|
||||
export type {
|
||||
// L0
|
||||
ConversationItem, ConversationAddRequest, ConversationAddData,
|
||||
ConversationQueryRequest, ConversationQueryData,
|
||||
ConversationSearchRequest, ConversationSearchData,
|
||||
ConversationDeleteRequest, ConversationDeleteData,
|
||||
// L1
|
||||
AtomicDetail, AtomicUpdateRequest, AtomicUpdateData,
|
||||
AtomicQueryRequest, AtomicQueryData,
|
||||
AtomicSearchRequest, AtomicSearchData,
|
||||
AtomicDeleteRequest, AtomicDeleteData,
|
||||
// L2
|
||||
ScenarioEntry, ScenarioListRequest, ScenarioListData,
|
||||
ScenarioReadRequest, ScenarioFile,
|
||||
ScenarioWriteRequest, ScenarioWriteData,
|
||||
ScenarioRmRequest,
|
||||
// L3
|
||||
CoreFile, CoreWriteRequest, CoreWriteData,
|
||||
// Offload
|
||||
OffloadToolPair, OffloadRecentMessage,
|
||||
OffloadIngestRequest, OffloadIngestData,
|
||||
OffloadCompactRequest, OffloadCompactData, OffloadCompactReport,
|
||||
// Common
|
||||
ApiResponseEnvelope,
|
||||
} from "./types.js";
|
||||
|
||||
@@ -188,3 +188,75 @@ export interface CoreWriteRequest {
|
||||
export interface CoreWriteData {
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Offload (Compaction + Ingest)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export interface OffloadToolPair {
|
||||
tool_name: string;
|
||||
tool_call_id: string;
|
||||
params: unknown;
|
||||
result: unknown;
|
||||
error?: string;
|
||||
timestamp: string;
|
||||
duration_ms?: number;
|
||||
}
|
||||
|
||||
export interface OffloadRecentMessage {
|
||||
role: "user" | "assistant";
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface OffloadIngestRequest {
|
||||
session_id: string;
|
||||
tool_pairs: OffloadToolPair[];
|
||||
prompt?: string;
|
||||
recent_messages?: OffloadRecentMessage[];
|
||||
}
|
||||
|
||||
export interface OffloadIngestData {
|
||||
accepted: boolean;
|
||||
}
|
||||
|
||||
export interface OffloadCompactRequest {
|
||||
session_id: string;
|
||||
messages: unknown[];
|
||||
ratio: number;
|
||||
context_window: number;
|
||||
total_tokens: number;
|
||||
message_tokens?: number[];
|
||||
}
|
||||
|
||||
export interface OffloadCompactReport {
|
||||
resolvedLevel: string;
|
||||
originalCount: number;
|
||||
compactedCount: number;
|
||||
fastPathReplaced: number;
|
||||
fastPathDeleted: number;
|
||||
mildReplacements: number;
|
||||
aggressiveDeleted: number;
|
||||
emergencyDeleted: number;
|
||||
mmdInjected: number;
|
||||
}
|
||||
|
||||
export interface OffloadCompactData {
|
||||
messages: unknown[];
|
||||
report: OffloadCompactReport;
|
||||
}
|
||||
|
||||
export interface OffloadQueryMmdRequest {
|
||||
session_id: string;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface OffloadMmdFile {
|
||||
filename: string;
|
||||
content: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface OffloadQueryMmdData {
|
||||
mmds: OffloadMmdFile[];
|
||||
current_mmd: string | null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user