TypeScript Conversation History
This guide continues from TypeScript Getting Started and adds history channel recording.
Prerequisites
Starting checkpoint: typescript/examples/vecelai/doc-checkpoints/02-with-memory
Make sure you’ve completed the TypeScript Getting Started guide first.
Add History Recording
Checkpoint 03 adds only the history recording delta:
const result = await withMemoryService(
{
...memoryServiceConfig,
conversationId,
authorization,
userText: userMessage,
memoryContentType: "vercelai",
},
async (contextMemory) => {
contextMemory.append({ role: "user", content: userMessage });
const generated = await generateText({
model,
messages: [
{
role: "system",
content: "You are a TypeScript memory-service demo agent.",
},
...contextMemory.get(),
],
});
contextMemory.append({ role: "assistant", content: generated.text });
return generated;
},
);
const assistantText = result.text;
res.type("text/plain").send(assistantText); What changed: The app uses withMemoryService(...) and passes userText.
Note: When userText is provided, withMemoryService(...) records both the USER history turn and the resulting AI history response automatically.
Why needed: memory keeps model context while history stores user-facing conversation turns for timeline, replay, and search features.
Make sure you define a shell function that can get the bearer token for the bob user:
function get-token() {
curl -sSfX POST http://localhost:8081/realms/memory-service/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=memory-service-client" \
-d "client_secret=change-me" \
-d "grant_type=password" \
-d "username=bob" \
-d "password=bob" \
| jq -r '.access_token'
}Send a chat turn:
curl -NsSfX POST http://localhost:9090/chat/52b0f67a-6d8a-4d35-a2e5-8abf0e7f1c22 \
-H "Content-Type: text/plain" \
-H "Authorization: Bearer $(get-token)" \
-d "Give me a random number between 1 and 100." Example output:
42 Filtering conversations by metadata
listConversations accepts a metadata array of filter expressions. The service combines them with AND and supports at most five predicates.
import { createMemoryServiceProxy } from "@chirino/memory-service-vercelai";
const proxy = createMemoryServiceProxy(config);
const res1 = await proxy.listConversations({ metadata: ["status=waiting"] });
const res2 = await proxy.listConversations({
metadata: ["status=waiting", "agent-id!=worker-2"],
});
const { data: conversations } = await res2.json();
Operators are = (equal) and != (not equal). Matching is exact and case-sensitive against scalar string values. Missing keys, null, numbers, booleans, arrays, and objects do not match either operator. Filter keys may contain only ASCII letters, digits, underscores, and hyphens.
Completed Checkpoint
Completed code: typescript/examples/vecelai/doc-checkpoints/03-with-history
Next Steps
Continue to:
- Conversation Forking - Branch a conversation from a specific prior entry
- Response Recording and Resumption - Stream responses and support resume/cancel
- Sharing - Add conversation membership and ownership transfer APIs
- Indexing and Search - Add
indexedContentand search endpoint support