Archived
rename crates/ to engrams/, bindings/ to receptors/
- crates/ → engrams/ (Rust engrams live here) - bindings/ → receptors/ (cross-language access points into the graph) - Cargo.toml workspace paths updated
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
/// Projection API routes.
|
||||
///
|
||||
/// POST /projections — register a projection schema
|
||||
/// GET /projections — list all registered schemas
|
||||
/// POST /projections/{name}/query — run activation then project results
|
||||
/// GET /projections/{name}/schema — get a schema definition
|
||||
use axum::{
|
||||
extract::{Path, State},
|
||||
http::StatusCode,
|
||||
Json,
|
||||
};
|
||||
use engram_projection::{
|
||||
engine::ProjectionEngine,
|
||||
schema::{ProjectionResult, ProjectionSchema},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
// ── POST /projections ─────────────────────────────────────────────────────────
|
||||
|
||||
pub async fn register_projection(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Json(schema): Json<ProjectionSchema>,
|
||||
) -> Result<StatusCode, StatusCode> {
|
||||
let mut reg = state
|
||||
.projection_registry
|
||||
.lock()
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
reg.upsert(schema)
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
Ok(StatusCode::CREATED)
|
||||
}
|
||||
|
||||
// ── GET /projections ──────────────────────────────────────────────────────────
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ListProjectionsResponse {
|
||||
pub schemas: Vec<ProjectionSchema>,
|
||||
}
|
||||
|
||||
pub async fn list_projections(
|
||||
State(state): State<Arc<AppState>>,
|
||||
) -> Result<Json<ListProjectionsResponse>, StatusCode> {
|
||||
let reg = state
|
||||
.projection_registry
|
||||
.lock()
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
let schemas = reg.list().into_iter().cloned().collect();
|
||||
Ok(Json(ListProjectionsResponse { schemas }))
|
||||
}
|
||||
|
||||
// ── GET /projections/{name}/schema ────────────────────────────────────────────
|
||||
|
||||
pub async fn get_projection_schema(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(name): Path<String>,
|
||||
) -> Result<Json<ProjectionSchema>, StatusCode> {
|
||||
let reg = state
|
||||
.projection_registry
|
||||
.lock()
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
match reg.get(&name) {
|
||||
Ok(schema) => Ok(Json(schema.clone())),
|
||||
Err(_) => Err(StatusCode::NOT_FOUND),
|
||||
}
|
||||
}
|
||||
|
||||
// ── POST /projections/{name}/query ────────────────────────────────────────────
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ProjectionQueryRequest {
|
||||
/// Seed node IDs for spreading activation.
|
||||
pub seeds: Vec<Uuid>,
|
||||
/// Query embedding for spreading activation.
|
||||
pub query_embedding: Vec<f32>,
|
||||
#[serde(default = "default_depth")]
|
||||
pub max_depth: u8,
|
||||
#[serde(default = "default_limit")]
|
||||
pub limit: usize,
|
||||
}
|
||||
|
||||
fn default_depth() -> u8 {
|
||||
3
|
||||
}
|
||||
fn default_limit() -> usize {
|
||||
20
|
||||
}
|
||||
|
||||
pub async fn query_projection(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(name): Path<String>,
|
||||
Json(req): Json<ProjectionQueryRequest>,
|
||||
) -> Result<Json<ProjectionResult>, StatusCode> {
|
||||
// Load schema
|
||||
let schema = {
|
||||
let reg = state
|
||||
.projection_registry
|
||||
.lock()
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
match reg.get(&name) {
|
||||
Ok(s) => s.clone(),
|
||||
Err(_) => return Err(StatusCode::NOT_FOUND),
|
||||
}
|
||||
};
|
||||
|
||||
// Run spreading activation
|
||||
let activated = {
|
||||
let db = state.db.lock().map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
db.activate(&req.seeds, &req.query_embedding, req.max_depth, req.limit)
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
|
||||
};
|
||||
|
||||
// Apply projection
|
||||
let result = ProjectionEngine::project(&schema, &activated)
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
Ok(Json(result))
|
||||
}
|
||||
Reference in New Issue
Block a user