reorder files
This commit is contained in:
parent
ada9562cc2
commit
646dea89d9
85 changed files with 312 additions and 111 deletions
1
.sesskey
Normal file
1
.sesskey
Normal file
|
|
@ -0,0 +1 @@
|
|||
49ed5f3e-d51f-4fbe-abdb-c909287df6a0
|
||||
|
|
@ -9,9 +9,6 @@ from pathlib import Path
|
|||
from benchmarks.common.benchmark_runner import BenchmarkRunner
|
||||
from memora import TemporalSemanticMemory
|
||||
|
||||
# Add parent directory to path for imports
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
||||
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from typing import List, Dict, Any, Tuple, Optional
|
||||
|
|
@ -20,9 +17,7 @@ import pydantic
|
|||
from openai import AsyncOpenAI
|
||||
import os
|
||||
|
||||
# Import common framework
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
from common.benchmark_runner import BenchmarkDataset, LLMAnswerGenerator, LLMAnswerEvaluator
|
||||
from benchmarks.common.benchmark_runner import BenchmarkDataset, LLMAnswerGenerator, LLMAnswerEvaluator
|
||||
from memora.llm_wrapper import LLMConfig
|
||||
|
||||
class LoComoDataset(BenchmarkDataset):
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@ from pathlib import Path
|
|||
from benchmarks.common.benchmark_runner import BenchmarkRunner
|
||||
from memora import TemporalSemanticMemory
|
||||
|
||||
# Add parent directory to path for imports
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
||||
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from typing import List, Dict, Any, Tuple, Optional
|
||||
|
|
@ -20,9 +17,7 @@ import pydantic
|
|||
from openai import AsyncOpenAI
|
||||
import os
|
||||
|
||||
# Import common framework
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
from common.benchmark_runner import BenchmarkDataset, LLMAnswerGenerator, LLMAnswerEvaluator
|
||||
from benchmarks.common.benchmark_runner import BenchmarkDataset, LLMAnswerGenerator, LLMAnswerEvaluator
|
||||
from memora.llm_wrapper import LLMConfig
|
||||
|
||||
|
||||
|
|
|
|||
23
benchmarks/pyproject.toml
Normal file
23
benchmarks/pyproject.toml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "benchmarks"
|
||||
version = "0.1.0"
|
||||
description = "Benchmarks for Memora memory system"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
"memora",
|
||||
"python-fasthtml>=0.12.33",
|
||||
"streamlit>=1.51.0",
|
||||
"openai>=1.0.0",
|
||||
"rich>=13.0.0",
|
||||
"pydantic>=2.0.0",
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["benchmarks"]
|
||||
|
||||
[tool.uv.sources]
|
||||
memora = { workspace = true }
|
||||
12
control-plane/.dockerignore
Normal file
12
control-plane/.dockerignore
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
.next
|
||||
node_modules
|
||||
npm-debug.log
|
||||
.git
|
||||
.gitignore
|
||||
.env.local
|
||||
.env*.local
|
||||
README.md
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
build-docker.sh
|
||||
docker-compose.yml
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
# Dataplane API Configuration
|
||||
# URL of the Python FastAPI dataplane server
|
||||
NEXT_PUBLIC_DATAPLANE_API_URL=http://localhost:8080
|
||||
# URL of the Python FastAPI dataplane server (server-side only, not exposed to browser)
|
||||
DATAPLANE_API_URL=http://localhost:8080
|
||||
|
|
|
|||
39
control-plane/Dockerfile
Normal file
39
control-plane/Dockerfile
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
FROM node:20-alpine AS base
|
||||
|
||||
# Install dependencies only when needed
|
||||
FROM base AS deps
|
||||
RUN apk add --no-cache libc6-compat
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
# Rebuild the source code only when needed
|
||||
FROM base AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
RUN npm run build
|
||||
|
||||
# Production image, copy all the files and run next
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
|
||||
# Automatically leverage output traces to reduce image size
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENV PORT=3000
|
||||
ENV HOSTNAME="0.0.0.0"
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
|
|
@ -84,7 +84,7 @@ cp .env.local.example .env.local
|
|||
Edit `.env.local`:
|
||||
|
||||
```env
|
||||
NEXT_PUBLIC_DATAPLANE_API_URL=http://localhost:8080
|
||||
DATAPLANE_API_URL=http://localhost:8080
|
||||
```
|
||||
|
||||
### Development
|
||||
|
|
|
|||
74
control-plane/build-docker.sh
Executable file
74
control-plane/build-docker.sh
Executable file
|
|
@ -0,0 +1,74 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Default values
|
||||
IMAGE_NAME="memora-control-plane"
|
||||
IMAGE_TAG="latest"
|
||||
REGISTRY=""
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--name)
|
||||
IMAGE_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
--tag)
|
||||
IMAGE_TAG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--registry)
|
||||
REGISTRY="$2"
|
||||
shift 2
|
||||
;;
|
||||
--help)
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --name NAME Docker image name (default: control-plane)"
|
||||
echo " --tag TAG Docker image tag (default: latest)"
|
||||
echo " --registry REG Docker registry URL (optional)"
|
||||
echo " --help Show this help message"
|
||||
echo ""
|
||||
echo "Example:"
|
||||
echo " $0 --name myapp --tag v1.0.0"
|
||||
echo " $0 --registry docker.io/myuser --name control-plane --tag v1.0.0"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
echo "Use --help for usage information"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Construct full image name
|
||||
if [ -n "$REGISTRY" ]; then
|
||||
FULL_IMAGE_NAME="${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"
|
||||
else
|
||||
FULL_IMAGE_NAME="${IMAGE_NAME}:${IMAGE_TAG}"
|
||||
fi
|
||||
|
||||
echo "Building Docker image: ${FULL_IMAGE_NAME}"
|
||||
echo "========================================"
|
||||
|
||||
# Build the Docker image
|
||||
docker build -t "${FULL_IMAGE_NAME}" .
|
||||
|
||||
echo ""
|
||||
echo "Build completed successfully!"
|
||||
echo "Image: ${FULL_IMAGE_NAME}"
|
||||
echo ""
|
||||
echo "To run the container:"
|
||||
echo " docker run -p 3000:3000 \\"
|
||||
echo " -e DATAPLANE_API_URL=http://your-api-url:8080 \\"
|
||||
echo " ${FULL_IMAGE_NAME}"
|
||||
echo ""
|
||||
echo "Or with an env file:"
|
||||
echo " docker run -p 3000:3000 --env-file .env.local ${FULL_IMAGE_NAME}"
|
||||
echo ""
|
||||
echo "To push to registry (if registry specified):"
|
||||
if [ -n "$REGISTRY" ]; then
|
||||
echo " docker push ${FULL_IMAGE_NAME}"
|
||||
fi
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
/* config options here */
|
||||
output: 'standalone',
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
const DATAPLANE_URL = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
const DATAPLANE_URL = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ export class ServerDataplaneClient {
|
|||
private baseUrl: string;
|
||||
|
||||
constructor() {
|
||||
this.baseUrl = process.env.NEXT_PUBLIC_DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
this.baseUrl = process.env.DATAPLANE_API_URL || 'http://localhost:8080';
|
||||
}
|
||||
|
||||
async fetchDataplane<T>(
|
||||
|
|
|
|||
0
docker/.gitignore → local-db/.gitignore
vendored
0
docker/.gitignore → local-db/.gitignore
vendored
1
memora-dev/memora_dev/__init__.py
Normal file
1
memora-dev/memora_dev/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
"""Utility scripts for Memora development."""
|
||||
|
|
@ -9,9 +9,6 @@ import sys
|
|||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Add parent directory to path to import memory module
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
from memora.api import create_app
|
||||
from memora import TemporalSemanticMemory
|
||||
|
||||
18
memora-dev/pyproject.toml
Normal file
18
memora-dev/pyproject.toml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "memora-dev"
|
||||
version = "0.1.0"
|
||||
description = "Development utilities for Memora"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
"memora",
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["memora_dev"]
|
||||
|
||||
[tool.uv.sources]
|
||||
memora = { workspace = true }
|
||||
|
|
@ -23,14 +23,17 @@ def load_env():
|
|||
if os.getenv("DATABASE_URL"):
|
||||
return
|
||||
|
||||
# Look for .env files in the parent directory (root of the workspace)
|
||||
root_dir = Path(__file__).parent.parent.parent
|
||||
|
||||
# Default to local environment
|
||||
env_file = ".env.local"
|
||||
if Path(env_file).exists():
|
||||
env_file = root_dir / ".env.local"
|
||||
if env_file.exists():
|
||||
load_dotenv(env_file)
|
||||
else:
|
||||
# Fallback to dev
|
||||
env_file = ".env.dev"
|
||||
if Path(env_file).exists():
|
||||
env_file = root_dir / ".env.dev"
|
||||
if env_file.exists():
|
||||
load_dotenv(env_file)
|
||||
|
||||
load_env()
|
||||
43
memora/pyproject.toml
Normal file
43
memora/pyproject.toml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "memora"
|
||||
version = "0.1.0"
|
||||
description = "Temporal + Semantic + Entity Memory System for AI agents using PostgreSQL"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
"asyncpg>=0.29.0",
|
||||
"python-dotenv>=1.0.0",
|
||||
"openai>=1.0.0",
|
||||
"pydantic>=2.0.0",
|
||||
"rich>=13.0.0",
|
||||
"sentence-transformers>=2.2.0",
|
||||
"pytest>=7.0.0",
|
||||
"pytest-asyncio>=0.21.0",
|
||||
"langchain-text-splitters>=0.3.0",
|
||||
"fastapi[standard]>=0.120.3",
|
||||
"uvicorn>=0.38.0",
|
||||
"sqlalchemy>=2.0.44",
|
||||
"alembic>=1.17.1",
|
||||
"pgvector>=0.4.1",
|
||||
"greenlet>=3.2.4",
|
||||
"psycopg2-binary>=2.9.11",
|
||||
"pytest-timeout>=2.4.0",
|
||||
"dateparser>=1.2.0",
|
||||
"tiktoken>=0.12.0",
|
||||
"httpx>=0.27.0",
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["memora"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
log_cli = true
|
||||
log_cli_level = "INFO"
|
||||
log_cli_format = "%(asctime)s %(levelname)s %(message)s"
|
||||
log_cli_date_format = "%Y-%m-%d %H:%M:%S"
|
||||
addopts = "--timeout 60 -p no:warnings"
|
||||
asyncio_default_fixture_loop_scope = "function"
|
||||
|
|
@ -19,7 +19,8 @@ LOCAL_DB_URL = "postgresql://memora:memora_dev@localhost:5432/memora"
|
|||
# Load environment variables from .env.local at the start of test session
|
||||
def pytest_configure(config):
|
||||
"""Load environment variables before running tests."""
|
||||
env_file = Path(__file__).parent.parent / ".env.local"
|
||||
# Look for .env.local in the workspace root (two levels up from tests dir)
|
||||
env_file = Path(__file__).parent.parent.parent / ".env.local"
|
||||
if env_file.exists():
|
||||
load_dotenv(env_file)
|
||||
else:
|
||||
46
openapi.json
46
openapi.json
|
|
@ -472,7 +472,7 @@
|
|||
"Memory Storage"
|
||||
],
|
||||
"summary": "Store multiple memories",
|
||||
"description": "Store multiple memory items in batch with automatic fact extraction.\n\n Features:\n - Efficient batch processing\n - Automatic fact extraction from natural language\n - Entity recognition and linking\n - Document tracking with optional upsert\n - Temporal and semantic linking\n\n The system automatically:\n 1. Extracts semantic facts from the content\n 2. Generates embeddings\n 3. Deduplicates similar facts\n 4. Creates temporal, semantic, and entity links\n 5. Tracks document metadata",
|
||||
"description": "Store multiple memory items in batch with automatic fact extraction.\n\n Features:\n - Efficient batch processing\n - Automatic fact extraction from natural language\n - Entity recognition and linking\n - Document tracking with automatic upsert (when document_id is provided)\n - Temporal and semantic linking\n\n The system automatically:\n 1. Extracts semantic facts from the content\n 2. Generates embeddings\n 3. Deduplicates similar facts\n 4. Creates temporal, semantic, and entity links\n 5. Tracks document metadata\n\n Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior).",
|
||||
"operationId": "api_batch_put_api_memories_batch_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
|
|
@ -514,7 +514,7 @@
|
|||
"Memory Storage"
|
||||
],
|
||||
"summary": "Store multiple memories asynchronously",
|
||||
"description": "Store multiple memory items in batch asynchronously using the task backend.\n\n This endpoint returns immediately after queuing the task, without waiting for completion.\n The actual processing happens in the background.\n\n Features:\n - Immediate response (non-blocking)\n - Background processing via task queue\n - Efficient batch processing\n - Automatic fact extraction from natural language\n - Entity recognition and linking\n - Document tracking with optional upsert\n - Temporal and semantic linking\n\n The system automatically:\n 1. Queues the batch put task\n 2. Returns immediately with success=True, queued=True\n 3. Processes in background: extracts facts, generates embeddings, creates links",
|
||||
"description": "Store multiple memory items in batch asynchronously using the task backend.\n\n This endpoint returns immediately after queuing the task, without waiting for completion.\n The actual processing happens in the background.\n\n Features:\n - Immediate response (non-blocking)\n - Background processing via task queue\n - Efficient batch processing\n - Automatic fact extraction from natural language\n - Entity recognition and linking\n - Document tracking with automatic upsert (when document_id is provided)\n - Temporal and semantic linking\n\n The system automatically:\n 1. Queues the batch put task\n 2. Returns immediately with success=True, queued=True\n 3. Processes in background: extracts facts, generates embeddings, creates links\n\n Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior).",
|
||||
"operationId": "api_batch_put_async_api_memories_batch_async_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
|
|
@ -776,23 +776,6 @@
|
|||
}
|
||||
],
|
||||
"title": "Document Id"
|
||||
},
|
||||
"document_metadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": true,
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Document Metadata"
|
||||
},
|
||||
"upsert": {
|
||||
"type": "boolean",
|
||||
"title": "Upsert",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
|
|
@ -814,8 +797,7 @@
|
|||
"content": "Bob went hiking yesterday",
|
||||
"event_date": "2024-01-15T10:00:00Z"
|
||||
}
|
||||
],
|
||||
"upsert": false
|
||||
]
|
||||
}
|
||||
},
|
||||
"BatchPutResponse": {
|
||||
|
|
@ -1188,7 +1170,10 @@
|
|||
"title": "Query"
|
||||
},
|
||||
"fact_type": {
|
||||
"type": "string",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Fact Type"
|
||||
},
|
||||
"agent_id": {
|
||||
|
|
@ -1215,6 +1200,17 @@
|
|||
"type": "boolean",
|
||||
"title": "Trace",
|
||||
"default": false
|
||||
},
|
||||
"question_date": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Question Date"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
|
|
@ -1226,9 +1222,13 @@
|
|||
"description": "Request model for search endpoint.",
|
||||
"example": {
|
||||
"agent_id": "user123",
|
||||
"fact_type": "world",
|
||||
"fact_type": [
|
||||
"world",
|
||||
"agent"
|
||||
],
|
||||
"max_tokens": 4096,
|
||||
"query": "What did Alice say about machine learning?",
|
||||
"question_date": "2023-05-30T23:40:00",
|
||||
"reranker": "heuristic",
|
||||
"thinking_budget": 100,
|
||||
"trace": true
|
||||
|
|
|
|||
|
|
@ -1,45 +1,5 @@
|
|||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
[tool.uv.workspace]
|
||||
members = ["memora", "benchmarks", "memora-dev"]
|
||||
|
||||
[project]
|
||||
name = "memora"
|
||||
version = "0.1.0"
|
||||
description = "Temporal + Semantic + Entity Memory System for AI agents using PostgreSQL"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
"asyncpg>=0.29.0",
|
||||
"python-dotenv>=1.0.0",
|
||||
"openai>=1.0.0",
|
||||
"pydantic>=2.0.0",
|
||||
"rich>=13.0.0",
|
||||
"sentence-transformers>=2.2.0",
|
||||
"pytest>=7.0.0",
|
||||
"pytest-asyncio>=0.21.0",
|
||||
"langchain-text-splitters>=0.3.0",
|
||||
"fastapi[standard]>=0.120.3",
|
||||
"uvicorn>=0.38.0",
|
||||
"sqlalchemy>=2.0.44",
|
||||
"alembic>=1.17.1",
|
||||
"pgvector>=0.4.1",
|
||||
"greenlet>=3.2.4",
|
||||
"psycopg2-binary>=2.9.11",
|
||||
"pytest-timeout>=2.4.0",
|
||||
"dateparser>=1.2.0",
|
||||
"tiktoken>=0.12.0",
|
||||
"httpx>=0.27.0",
|
||||
"streamlit>=1.51.0",
|
||||
"python-fasthtml>=0.12.33",
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["memora"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
log_cli = true
|
||||
log_cli_level = "INFO"
|
||||
log_cli_format = "%(asctime)s %(levelname)s %(message)s"
|
||||
log_cli_date_format = "%Y-%m-%d %H:%M:%S"
|
||||
addopts = "--timeout 60 -p no:warnings"
|
||||
asyncio_default_fixture_loop_scope = "function"
|
||||
[tool.uv]
|
||||
dev-dependencies = []
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ echo "🛑 Stopping and erasing local PostgreSQL..."
|
|||
echo ""
|
||||
|
||||
# Stop and remove containers, networks, volumes
|
||||
cd docker
|
||||
cd local-db
|
||||
docker-compose down -v
|
||||
|
||||
echo ""
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
cd "$(dirname "$0")/../memora"
|
||||
|
||||
echo "🔄 Database Migration Script"
|
||||
echo "============================"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ echo "🚀 Starting local PostgreSQL..."
|
|||
echo ""
|
||||
|
||||
# Start docker compose
|
||||
cd docker
|
||||
cd local-db
|
||||
docker-compose up -d
|
||||
|
||||
echo ""
|
||||
|
|
@ -25,7 +25,9 @@ cd ..
|
|||
export DATABASE_URL="postgresql://memora:memora_dev@localhost:5432/memora"
|
||||
|
||||
echo "📊 Running database migrations..."
|
||||
cd memora
|
||||
uv run alembic upgrade head
|
||||
cd ..
|
||||
|
||||
echo ""
|
||||
echo "✅ Database initialized successfully!"
|
||||
|
|
|
|||
47
uv.lock
47
uv.lock
|
|
@ -6,6 +6,13 @@ resolution-markers = [
|
|||
"python_full_version < '3.12'",
|
||||
]
|
||||
|
||||
[manifest]
|
||||
members = [
|
||||
"benchmarks",
|
||||
"memora",
|
||||
"memora-dev",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alembic"
|
||||
version = "1.17.1"
|
||||
|
|
@ -208,6 +215,29 @@ wheels = [
|
|||
{ url = "https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515", size = 106392 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "benchmarks"
|
||||
version = "0.1.0"
|
||||
source = { editable = "benchmarks" }
|
||||
dependencies = [
|
||||
{ name = "memora" },
|
||||
{ name = "openai" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "python-fasthtml" },
|
||||
{ name = "rich" },
|
||||
{ name = "streamlit" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "memora", editable = "memora" },
|
||||
{ name = "openai", specifier = ">=1.0.0" },
|
||||
{ name = "pydantic", specifier = ">=2.0.0" },
|
||||
{ name = "python-fasthtml", specifier = ">=0.12.33" },
|
||||
{ name = "rich", specifier = ">=13.0.0" },
|
||||
{ name = "streamlit", specifier = ">=1.51.0" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blinker"
|
||||
version = "1.9.0"
|
||||
|
|
@ -1015,7 +1045,7 @@ wheels = [
|
|||
[[package]]
|
||||
name = "memora"
|
||||
version = "0.1.0"
|
||||
source = { editable = "." }
|
||||
source = { editable = "memora" }
|
||||
dependencies = [
|
||||
{ name = "alembic" },
|
||||
{ name = "asyncpg" },
|
||||
|
|
@ -1032,11 +1062,9 @@ dependencies = [
|
|||
{ name = "pytest-asyncio" },
|
||||
{ name = "pytest-timeout" },
|
||||
{ name = "python-dotenv" },
|
||||
{ name = "python-fasthtml" },
|
||||
{ name = "rich" },
|
||||
{ name = "sentence-transformers" },
|
||||
{ name = "sqlalchemy" },
|
||||
{ name = "streamlit" },
|
||||
{ name = "tiktoken" },
|
||||
{ name = "uvicorn" },
|
||||
]
|
||||
|
|
@ -1058,15 +1086,24 @@ requires-dist = [
|
|||
{ name = "pytest-asyncio", specifier = ">=0.21.0" },
|
||||
{ name = "pytest-timeout", specifier = ">=2.4.0" },
|
||||
{ name = "python-dotenv", specifier = ">=1.0.0" },
|
||||
{ name = "python-fasthtml", specifier = ">=0.12.33" },
|
||||
{ name = "rich", specifier = ">=13.0.0" },
|
||||
{ name = "sentence-transformers", specifier = ">=2.2.0" },
|
||||
{ name = "sqlalchemy", specifier = ">=2.0.44" },
|
||||
{ name = "streamlit", specifier = ">=1.51.0" },
|
||||
{ name = "tiktoken", specifier = ">=0.12.0" },
|
||||
{ name = "uvicorn", specifier = ">=0.38.0" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memora-dev"
|
||||
version = "0.1.0"
|
||||
source = { editable = "memora-dev" }
|
||||
dependencies = [
|
||||
{ name = "memora" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "memora", editable = "memora" }]
|
||||
|
||||
[[package]]
|
||||
name = "mpmath"
|
||||
version = "1.3.0"
|
||||
|
|
|
|||
Loading…
Reference in a new issue