@atmalviya/xray
v0.1.0
Published
X-Ray SDK and API for debugging multi-step, non-deterministic algorithmic systems
Maintainers
Readme
X-Ray SDK & API
A general-purpose SDK and API for debugging multi-step, non-deterministic algorithmic systems. X-Ray answers "why did the system make this decision?" rather than just "what happened?"
Overview
X-Ray provides transparency into decision-making processes across multi-step pipelines. It captures:
- Inputs and outputs at each step
- Candidates considered and filters applied
- Reasoning behind decisions (especially for LLM-based steps)
- Metrics and timing for performance analysis
Unlike traditional tracing (Jaeger, Zipkin), X-Ray focuses on business logic decisions rather than function calls.
Project Structure
.
├── sdk/ # TypeScript SDK
│ ├── src/
│ └── package.json
├── api/ # Backend API server
│ ├── src/
│ ├── prisma/
│ └── package.json
├── examples/ # Example usage
├── ARCHITECTURE.md # System design and rationale
└── README.md # This fileInstallation
npm install @atmalviya/xrayThis installs both the SDK and CLI tools.
Quick Start
📖 For detailed testing instructions, see TESTING.md
1. Initialize X-Ray
# Initialize X-Ray in your project
npx xray init
# This will:
# - Create .env file with DATABASE_URL and XRAY_PORT
# - Set up configuration2. Set Up Database
# Run database migrations
npx xray migrate3. Start the API Server
# Start the X-Ray API server
npx xray start
# Or specify a port
npx xray start --port 3000The API will run on http://localhost:3000 (or your specified port)
4. Use the SDK in Your Code
3. Use the SDK in Your Code
import { XRayClient } from '@atmalviya/xray';
const xray = new XRayClient({
baseUrl: 'http://localhost:3000',
defaultMetadata: {
service: 'my-service',
env: 'production'
}
});
// Wrap your pipeline
async function myPipeline(input) {
const run = xray.startRun({
pipelineName: 'my_pipeline',
metadata: { inputId: input.id }
});
return run.execute(async () => {
const step1Result = await run.step('step1', 'llm', async (ctx) => {
const result = await callLLM(ctx.input);
ctx.record({
output: result,
reasoning: result.explanation
});
return result;
}, { input: { prompt: input.prompt } });
const step2Result = await run.step('step2', 'filter', async (ctx) => {
const filtered = filterResults(ctx.input.candidates);
ctx.record({
metrics: {
candidateCountBefore: ctx.input.candidates.length,
candidateCountAfter: filtered.length,
dropRate: 1 - filtered.length / ctx.input.candidates.length
}
});
return filtered;
}, { input: { candidates: step1Result } });
return step2Result;
});
}Examples
Simple Examples
examples/test.ts- Basic test scriptexamples/minimal-example.ts- Minimal instrumentation (<5 minutes)
Complex Examples
examples/competitor-selection.ts- Competitor selection pipeline with 5 stepsexamples/complex-pipeline.ts- E-commerce recommendation system with:- 10,000+ product catalog
- 6 different step types (LLM, retrieval, filter, ranking, selection)
- Complex multi-stage filtering
- LLM-based relevance ranking
- Diversity-aware selection
- Detailed metrics and reasoning at each step
Run the complex example:
cd examples
npm run complex
# or
ts-node --transpile-only complex-pipeline.tsAPI Endpoints
Ingest
- POST /xray/events - Accepts batched events from SDK
- Headers:
Authorization: Bearer <api-key> - Body:
{ events: XRayEvent[] }
- Headers:
Query
GET /xray/runs - List runs
- Query params:
pipelineName,status,startDate,endDate,limit,offset
- Query params:
GET /xray/runs/:runId - Get a specific run with all steps
GET /xray/runs/:runId/steps/:stepId - Get full details for a step
POST /xray/query/steps - Advanced cross-pipeline queries
{ "filters": [ { "field": "stepType", "op": "eq", "value": "filter" }, { "field": "metrics.dropRate", "op": "gt", "value": 0.9 } ], "include": ["run", "step"], "limit": 100 }
Approach
Design Principles
- Pipeline-agnostic: Works with any multi-step process, not tied to specific domains
- Fail-safe: SDK never breaks your pipeline, even if backend is unavailable
- Queryable: Cross-pipeline queries enabled by conventions (stepType, metrics)
- Performance-conscious: Sampling and summarization to handle large candidate sets
Key Features
- Event batching: SDK batches events and sends them asynchronously
- Sampling: Configurable per-step sampling for large datasets
- Fail-open: Pipeline continues normally if X-Ray backend is down
- JSONB storage: Flexible metadata and metrics storage in PostgreSQL
Known Limitations
- JSONB query limitations: Complex nested queries on metrics require careful indexing
- No UI: API-only, no visual dashboard (see "What Next" in ARCHITECTURE.md)
- Single language: SDK is TypeScript/JavaScript only (Python/Java/Go planned)
- No streaming: Events are batched, not streamed in real-time
- No authentication: Authentication disabled for local development (should be added for production)
Future Improvements
See ARCHITECTURE.md "What Next?" section for planned enhancements:
- Multi-language SDKs
- Visual dashboard
- Advanced querying and anomaly detection
- OpenTelemetry integration
- Performance optimizations (read replicas, materialized views)
Development
SDK Development
cd sdk
npm run build # Compile TypeScript
npm run dev # Watch modeAPI Development
cd api
npm run dev # Start with hot reload
npm run db:studio # Open Prisma Studio for database inspectionLicense
MIT
