Memory API
- Plan type:
plan - Parent plan:
N/A - Depends on:
shared-lambda-interface.md - Status:
documentation
Status semantics: - draft: Plan is being created or updated and is not final. - approved: Plan is approved but not yet applied in code. - documentation: Code currently exists and matches the plan contract.
Update rule: - When an existing plan is edited, set status to draft until re-approved.
System Intent
- What is being built: Unified memory API contract for session lifecycle, query execution, and session feed retrieval.
- Primary consumer(s): API callers (app, CLI, and backend-integrated clients).
- Boundary (black-box scope only): dummy endpoint behavior for
startSession, queryMemories, and fetchSessions, where each endpoint returns random but contract-shaped output.
Stage Gate Tracker
- [x] Stage 1 Mermaid approved
- [x] Stage 2 I/O contracts approved
- [x] Stage 3 pseudocode/technical details approved or skipped
1. Mermaid Diagram
Reference: .agent/skills/create-mermaid-diagram/SKILL.md
flowchart TD
A[API Caller] -->|POST /sessions/session body.session_id?| B[session Lambda - main/server/api/sessions/session/app.py]
B -->|StartSessionResponse| A
A -->|POST /sessions/query| C[queryMemories Lambda - main/server/api/sessions/query/app.py]
A -->|POST /sessions/feed| D[fetchSessions Lambda - main/server/api/sessions/feed/app.py]
C -->|QueryMemoriesResponse| A
D -->|FetchSessionsResponse| A
classDef unchanged fill:#d3d3d3,stroke:#666,stroke-width:1px;
classDef updated fill:#ffe58a,stroke:#666,stroke-width:1px;
classDef deleted fill:#f4a6a6,stroke:#666,stroke-width:1px;
classDef created fill:#a8e6a3,stroke:#666,stroke-width:1px;
class A,B,C,D unchanged;
Temporary Execution Mode (Dummy API First)
- Current execution target is a dummy API implementation that does not require persistence.
startSession: return random SessionMetadata; if session_id is provided, echo it in the response metadata. queryMemories: return a random placeholder answer and optionally echo conversation. fetchSessions: return random/synthetic SessionMetadata and random paginated queries. - Auth middleware remains required for all endpoints in this phase.
- Error handling and ownership enforcement beyond auth are intentionally out of scope for this dummy phase.
Legacy API Replacement Notes (Executed)
| new API (target) | replaces existing API | existing implementation path | current behavior in code | updated |
POST /sessions/session | N/A (new capability) | main/server/api/sessions/session/app.py | active dummy endpoint | Y |
POST /sessions/query | POST /memories/search | main/server/api/memories/search/app.py (deleted) | replaced by active dummy endpoint main/server/api/sessions/query/app.py | Y |
POST /sessions/feed | POST /conversations/feed | main/server/api/conversations/feed/app.py (deleted) | replaced by active dummy endpoint main/server/api/sessions/feed/app.py | Y |
Endpoint Contract
| operation | method | path | request type | success response type | error envelope | updated |
startSession | POST | /sessions/session | StartSessionRequest | StartSessionResponse | N/A (dummy phase) | |
queryMemories | POST | /sessions/query | QueryMemoriesRequest | QueryMemoriesResponse | N/A (dummy phase) | |
fetchSessions | POST | /sessions/feed | FetchSessionsRequest | FetchSessionsResponse | N/A (dummy phase) | |
Global Types
SessionMetadata {
session_id: string
title?: string
created_at: string (ISO-8601 timestamp)
updated_at: string (ISO-8601 timestamp)
message_count: number
}
SessionMessage {
message_id: string
session_id?: string
role: "user" | "assistant"
content: string
created_at: string (ISO-8601 timestamp)
}
StartSessionRequest {
session_id?: string
}
StartSessionResponse {
session: SessionMetadata
}
SearchMemoriesPayload {
conversation?: string (session id)
query: string
}
QueryMemoriesRequest = SearchMemoriesPayload
QueryMemoriesResponse {
answer: string
conversation?: string (session id when query is session-bound)
}
FetchSessionsRequest {
session_id?: string
cursor?: string | null
limit?: number (int, 1..50, default=20)
}
FetchSessionsResponse {
session: SessionMetadata
queries: SessionMessage[] (ordered most-recent-first)
next_cursor?: string | null
}
Flow: main/server/api/sessions/session/app.py.implementation
- Test files:
main/server/tests/unit/test_sessions_session_app.py - Core files:
main/server/api/sessions/session/app.py - Replaces:
N/A (new API capability)
Type Definitions
StartSessionLambdaInput = StartSessionRequest
StartSessionLambdaOutput = StartSessionResponse
Paths
| path-name | input | output/expected state change | path-type | notes | updated |
start-session.success-random | StartSessionLambdaInput (session_id optional) | StartSessionLambdaOutput with random SessionMetadata (echoes provided session_id when present) | happy path | returns contract-shaped random metadata for dummy API behavior | |
Flow: main/server/api/sessions/query/app.py.implementation
- Test files:
main/server/tests/unit/test_sessions_query_app.py - Core files:
main/server/api/sessions/query/app.py - Replaces:
POST /memories/search (main/server/api/memories/search/app.py, deleted after migration)
Type Definitions
SessionsQueryLambdaInput = QueryMemoriesRequest
SessionsQueryLambdaOutput = QueryMemoriesResponse
Paths
| path-name | input | output/expected state change | path-type | notes | updated |
sessions-query.success-random | SessionsQueryLambdaInput query provided (conversation optional) | SessionsQueryLambdaOutput with random placeholder answer (echoes conversation when provided) | happy path | always returns random answer in dummy mode | |
Flow: main/server/api/sessions/feed/app.py.implementation
- Test files:
main/server/tests/unit/test_sessions_feed_app.py - Core files:
main/server/api/sessions/feed/app.py - Replaces:
POST /conversations/feed (main/server/api/conversations/feed/app.py, deleted after migration)
Type Definitions
SessionsFeedLambdaInput = FetchSessionsRequest
SessionsFeedLambdaOutput = FetchSessionsResponse
Paths
| path-name | input | output/expected state change | path-type | notes | updated |
sessions-feed.success-random | SessionsFeedLambdaInput with session_id and optional cursor/limit | SessionsFeedLambdaOutput with random session metadata + random query page (may be empty) + optional next_cursor | happy path | returns contract-shaped synthetic page data | |
3. Pseudocode / Technical Details for Critical Flows (Optional)
Dummy Output Rules
- Pseudocode intent for this phase: just return correct-looking response shapes; nothing serious (no persistence, no retrieval, no ownership/data-layer enforcement).
startSession returns random SessionMetadata with contract-valid timestamps. queryMemories returns a random placeholder answer string. fetchSessions returns random session metadata and random message rows in the expected response shape.
startSession(payload):
return {
session: randomContractSessionMetadata(
session_id = payload.session_id if provided else random_id()
)
}
queryMemories(payload):
return {
answer: random_placeholder_string(),
conversation: payload.conversation if provided else omitted
}
fetchSessions(payload):
return {
session: randomContractSessionMetadata(session_id = payload.session_id),
queries: randomContractMessages(limit = payload.limit or 20),
next_cursor: random_or_null_cursor()
}
After all stages are approved, apply .agent/skills/reconcile-plans/SKILL.md to propagate contract updates across linked plans.