X-Ray SDK and API for debugging multi-step, non-deterministic algorithmic systems
npm install @atmalviya/xrayA 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?"
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.
```
.
├── 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 file
`bash`
npm install @atmalviya/xray
This installs both the SDK and CLI tools.
> 📖 For detailed testing instructions, see TESTING.md
`bashInitialize X-Ray in your project
npx xray init
$3
`bash
Run database migrations
npx xray migrate
`$3
`bash
Start the X-Ray API server
npx xray startOr specify a port
npx xray start --port 3000
`The API will run on
http://localhost:3000 (or your specified port)$3
$3
`typescript
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
$3
-
examples/test.ts - Basic test script
- examples/minimal-example.ts - Minimal instrumentation (<5 minutes)$3
-
examples/competitor-selection.ts - Competitor selection pipeline with 5 steps
- examples/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 stepRun the complex example:
`bash
cd examples
npm run complex
or
ts-node --transpile-only complex-pipeline.ts
`API Endpoints
$3
- POST /xray/events - Accepts batched events from SDK
- Headers:
Authorization: Bearer
- Body: { events: XRayEvent[] }$3
- GET /xray/runs - List runs
- Query params:
pipelineName, status, startDate, endDate, limit, offset
- 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
`json
{
"filters": [
{ "field": "stepType", "op": "eq", "value": "filter" },
{ "field": "metrics.dropRate", "op": "gt", "value": 0.9 }
],
"include": ["run", "step"],
"limit": 100
}
`Approach
$3
1. Pipeline-agnostic: Works with any multi-step process, not tied to specific domains
2. Fail-safe: SDK never breaks your pipeline, even if backend is unavailable
3. Queryable: Cross-pipeline queries enabled by conventions (stepType, metrics)
4. Performance-conscious: Sampling and summarization to handle large candidate sets
$3
- 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
1. JSONB query limitations: Complex nested queries on metrics require careful indexing
2. No UI: API-only, no visual dashboard (see "What Next" in ARCHITECTURE.md)
3. Single language: SDK is TypeScript/JavaScript only (Python/Java/Go planned)
4. No streaming: Events are batched, not streamed in real-time
5. 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
$3
`bash
cd sdk
npm run build # Compile TypeScript
npm run dev # Watch mode
`$3
`bash
cd api
npm run dev # Start with hot reload
npm run db:studio # Open Prisma Studio for database inspection
``MIT