Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ cdk.out/
.DS_Store
*.log
.env

# Python
__pycache__/
*.pyc
.venv/
.pytest_cache/
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,19 @@ GitHub Actions workflows are defined in:

Deployment uses OIDC role assumption (no long-lived AWS keys).

## Demo Agents

The `demo/agents/` directory contains working AI tutors (LangGraph-based) that demonstrate TLCS integration for learner memory. These agents run locally and connect to deployed TLCS infrastructure.

```bash
cd demo/agents
uv sync
export OPENAI_API_KEY=your-key
uv run python scripts/demo_alice_conversation.py --mock # Full demo with AI conversation
```

See [demo/agents/README.md](demo/agents/README.md) for full documentation.

## Account Bootstrap

See [`docs/bootstrap-and-operations.md`](docs/bootstrap-and-operations.md) for bootstrap, deploy, environment teardown, observability, and idempotency guidance.
23 changes: 23 additions & 0 deletions demo/agents/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Model Provider: "openai" or "bedrock"
MODEL_PROVIDER=openai

# OpenAI (if MODEL_PROVIDER=openai)
OPENAI_API_KEY=sk-...

# AWS Bedrock (if MODEL_PROVIDER=bedrock)
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...

# TLCS Integration
TLCS_ENDPOINT=https://your-tlcs-api.amazonaws.com
TLCS_CLIENT_ID=your-cognito-client-id
TLCS_CLIENT_SECRET=your-cognito-client-secret
TLCS_TOKEN_URL=https://your-cognito-domain/oauth2/token

# Storage Backend: "memory" or "dynamodb"
STORAGE_BACKEND=memory

# DynamoDB (if STORAGE_BACKEND=dynamodb)
DYNAMODB_ENDPOINT=http://localhost:8000
MEMORIES_TABLE=demo-agents-memories
163 changes: 163 additions & 0 deletions demo/agents/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Demo Agents Architecture

## Component Overview

### Memory Service (`memory/service.py`)

Central service implementing Pre-read 2.3 five-component architecture:

1. **Memory Store**: In-memory or DynamoDB-backed storage for MemoryItems
2. **Policy & AuthZ**: Scope-based access control via Grants
3. **Context Router**: Scoped retrieval with minimization
4. **Audit Subsystem**: Append-only operation log
5. **Interoperability**: Caliper export, TLCS sync

### TLCS Client (`memory/tlcs/`)

HTTP client for TLCS integration:

- OAuth2 client credentials flow (Cognito)
- Token caching with auto-refresh
- `push_caliper()`: POST to /ingest/caliper
- `pull_context()`: GET from /learners/{id}/context

### Scope System (`memory/scopes.py`)

Multi-dimensional access control:

- **Subject areas**: math, writing, general
- **Categories**: mastery, goal, preference, constraint
- **Source types**: user_declared, model_inferred
- **Purposes**: tutoring, assessment, college_apps

### LangGraph Agents (`graph/agents/`)

AI tutors built with LangGraph:

- Memory extraction from conversations
- Personalized responses using learner context
- Automatic memory updates based on interactions

## Data Flow

```
1. User → Agent
Natural language conversation

2. Agent → Memory Service
Extract and store memories

3. Memory Service → TLCS
Push Caliper events

4. TLCS → Memory Service
Pull learner context

5. Memory Service → Agent
Provide scoped context

6. Agent → User
Personalized response
```

## Schema Mapping

### MemoryItem → Caliper Event

| MemoryItem Field | Caliper Field | Notes |
|------------------|---------------|-------|
| `id` | `generated.@id` | As URN |
| `category=MASTERY` | `@type: "AssessmentEvent"` | Event type |
| `category=GOAL` | `@type: "AssignableEvent"` | With action "Activated" |
| `confidence` | `extensions.scoreGiven` | Numeric 0-1 |
| `subject_area` | `object.name` | Subject context |
| `source_type` | `extensions.sourceType` | "user_declared" / "model_inferred" |
| `content` | `extensions.description` | Human-readable |
| `learner_id` | `actor.@id` | As URN |

### TLCS Context → MemoryItem

| TLCS Field | MemoryItem Field | Notes |
|------------|------------------|-------|
| `session.credentialId` | `original_id` | Round-trip fidelity |
| `session.issuerId` | `metadata["issuer_id"]` | Store in metadata |
| `trust.issuerKnown` | `metadata["issuer_known"]` | Trust indicator |
| `context.course` | `subject_area` | Direct mapping |
| `claim.category` | `category` | See mapping below |

**Claim Category Mapping:**

| TLCS Category | MemoryCategory |
|---------------|----------------|
| `achievement` | `MASTERY` |
| `competency` | `MASTERY` |
| `activity` | `FACT` |
| `participation` | `FACT` |

## Security Model

### Scope-Based Access

Every memory operation validates:

1. **Grant validity**: Is the grant active and not expired?
2. **Subject scope**: Does the memory's subject match allowed subjects?
3. **Category scope**: Is this category accessible to the agent?
4. **Purpose scope**: Is the requested purpose allowed?
5. **Source type**: Should model-inferred memories be included?

### Trust Indicators

Memories from TLCS include trust metadata:

- `issuer_known`: Is the issuer in TLCS's trusted list?
- `source_type`: Was this user-declared or model-inferred?
- `provenance`: Full chain of custody

## Deployment Options

### Local Development

```
┌─────────────────────────────────────────────┐
│ Local Machine │
│ │
│ ┌─────────────┐ ┌─────────────────────┐ │
│ │ LangGraph │ │ Memory Service │ │
│ │ Studio │───>│ (in-memory) │ │
│ └─────────────┘ └─────────────────────┘ │
│ │ │
│ v │
│ ┌─────────────────────┐ │
│ │ Mock TLCS Client │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────┘
```

### AWS Deployment

```
┌────────────────────────────────────────────────────────────┐
│ AWS Account │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Demo Agents (ECS) │ │
│ │ ┌─────────────┐ ┌─────────────────────┐ │ │
│ │ │ LangGraph │ │ Memory Service │ │ │
│ │ │ Container │───>│ (DynamoDB) │ │ │
│ │ └─────────────┘ └─────────────────────┘ │ │
│ └────────────────────────────│─────────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ TLCS (Lambda) │ │
│ │ POST /ingest/caliper GET /learners/{id}/context │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Cognito (OAuth2) │ │
│ │ Token endpoint for client credentials flow │ │
│ └──────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────┘
```
29 changes: 29 additions & 0 deletions demo/agents/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM python:3.12-slim

WORKDIR /app

# Install uv for fast dependency management
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

# Copy project files
COPY pyproject.toml .
COPY graph/ ./graph/
COPY memory/ ./memory/
COPY langgraph.json .

# Install dependencies with AWS extras
RUN uv pip install --system -e ".[aws,api]"

# Environment defaults
ENV MODEL_PROVIDER=bedrock
ENV STORAGE_BACKEND=memory
ENV PORT=8000

EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import httpx; httpx.get('http://localhost:8000/health')" || exit 1

# Run LangGraph API server
CMD ["langgraph", "up", "--host", "0.0.0.0", "--port", "8000"]
Loading
Loading