npm.io
0.1.3 • Published 2d ago

@subspacecomputing/sdk

Licence
MIT
Version
0.1.3
Deps
0
Size
55 kB
Vulns
0
Weekly
0

ASTRIA — TypeScript SDK

TypeScript SDK for ASTRIA, the Subspace Computing Engine.

Installation

npm install @subspacecomputing/sdk
# or
yarn add @subspacecomputing/sdk
# or
pnpm add @subspacecomputing/sdk

Usage

Initialization
import { ASTRIA } from '@subspacecomputing/sdk';

// Initialize the client (defaults to production URL)
const client = new ASTRIA('your-api-key-here');

// For local testing or custom environments (optional)
// const client = new ASTRIA('your-api-key-here', 'http://localhost:8000');
Teams (X-Team-Id)

Optional third constructor argument sets the team UUID (header X-Team-Id). Use setTeamId to change or clear it. If the API needs a team context, you may get 400 with error.reason === 'team_context_required' — handle ValidationError and read err.errorReason.

const client = new ASTRIA('key', 'https://api.subspacecomputing.com', 'team-uuid');
client.setTeamId(undefined);
Simple Projection (1 scenario)
// Create a simple SP Model
const spec = {
  scenarios: 1, // Must be 1 for project()
  steps: 12,
  variables: [
    {
      name: 'capital',
      init: 1000.0,
      formula: 'capital[t-1] * 1.05', // 5% growth per period
    },
  ],
};

// Run the projection
const result = await client.project(spec);

// Display results
console.log(`Final capital: ${result.final_values.capital}`);
console.log(`Trajectory: ${result.trajectory.capital}`);
Monte Carlo Simulation (Multiple scenarios)
// SP Model with random variables
const spec = {
  scenarios: 1000, // 1000 Monte Carlo scenarios
  steps: 12,
  variables: [
    {
      name: 'taux',
      dist: 'uniform',
      params: { min: 0.03, max: 0.07 },
      per: 'scenario',
    },
    {
      name: 'capital',
      init: 1000.0,
      formula: 'capital[t-1] * (1 + taux)',
    },
  ],
};

// Run the simulation
const result = await client.simulate(spec);

// Analyze results
console.log(`Mean final capital: ${result.last_mean.capital}`);
console.log(`Median: ${result.statistics.capital.median}`);
console.log(`P5: ${result.statistics.capital.percentiles['5']}`);
console.log(`P95: ${result.statistics.capital.percentiles['95']}`);
Per-step statistics (fan charts)

When the API supports it, set include_per_step_statistics: true to receive full MC statistics at each time step (t = 0 through steps). The last entry matches statistics[var].

const spec = {
  scenarios: 1000,
  steps: 12,
  include_per_step_statistics: true,
  variables: [/* ... */],
};

const result = await client.simulate(spec);

if (result.per_step_statistics?.capital) {
  const atHorizon = result.per_step_statistics.capital.at(-1);
  console.log(`P10 at horizon: ${atHorizon?.p10 ?? atHorizon?.percentiles['10']}`);
}
Batch Mode (Multiple Entities)
// SP Model template
const template = {
  scenarios: 1,
  steps: '65 - batch_params.age', // Dynamic steps
  variables: [
    {
      name: 'age_actuel',
      init: 'batch_params.age',
    },
    {
      name: 'salaire',
      init: 'batch_params.salary',
      formula: 'salaire[t-1] * 1.03', // 3% annual increase
    },
    {
      name: 'capital_retraite',
      init: 0.0,
      formula: 'capital_retraite[t-1] * 1.05 + salaire[t] * 0.10',
    },
  ],
};

// Entity data
const batchParams = [
  { entity_id: 'emp_001', age: 45, salary: 60000 },
  { entity_id: 'emp_002', age: 50, salary: 80000 },
  { entity_id: 'emp_003', age: 35, salary: 50000 },
];

// Global aggregations (optional)
const aggregations = [
  {
    name: 'capital_total',
    formula: 'sum(capital_retraite[t_final])',
  },
  {
    name: 'moyenne_capital',
    formula: 'mean(capital_retraite[t_final])',
  },
];

// Run batch
const result = await client.projectBatch(template, batchParams, aggregations);

// Analyze results
for (const entity of result.entities) {
  console.log(`${entity._entity_id}: Capital = ${entity.final_values.capital_retraite}`);
}

console.log(`Total capital: ${result.aggregations?.capital_total}`);
console.log(`Average: ${result.aggregations?.moyenne_capital}`);
Runs: read, artifact, rerun, replay

Four distinct operations on persisted runs:

Method What it does
getRun(runId) Read metadata, stored SP Model snapshot, and result_summary
getRunArtifact(artifactId) Read heavy results already computed (final_values / URL)
rerunRun(runId, specPatch?) Re-execute the run's snapshot in Astria; creates a new run
replayRun(runId, scenarioId) Reproduce one Monte Carlo scenario when seeds were stored
// Cross-language analysis: app computed → TypeScript/Python reads original results
const run = await client.getRun(runId);
console.log(run.result_summary);
if (run.artefact_id) {
  const artifact = await client.getRunArtifact(run.artefact_id);
  console.log(artifact.final_values);
}

// Re-execute the exact snapshot (validation) — new run, same projection
const baseline = await client.rerunRun(runId);
console.log(baseline.run_id, baseline.source_spec_hash, baseline.spec_changed);

// What-if: fork the snapshot with a JSON Merge Patch (source run unchanged)
const whatIf = await client.rerunRun(runId, {
  meta: { seed: 42 },
});
console.log(whatIf.executed_spec_hash);

// Exact one-scenario MC replay (requires meta.store_seeds_for_replay on the source run)
const replay = await client.replayRun(runId, 0);
console.log(replay.final_values);

Notes

  • rerunRun uses the run's stored spec, not the projection's current dsl_template.
  • Requires persist_mode=full.
  • replayRun needs seeds persisted on the source run; it does not accept a body (path params only).
  • Live table_refs may resolve to newer data than at original execution time.
Validation
// Validate an SP Model before execution
const validation = await client.validate(spec);

if (validation.is_valid) {
  console.log('✅ SP Model is valid');
  if (validation.warnings) {
    console.log(`⚠️  Warnings: ${validation.warnings}`);
  }
} else {
  console.log(`❌ Errors: ${validation.errors}`);
}
Utilities
// Get examples
const examples = await client.getExamples();
console.log(`Available examples: ${examples.examples.length}`);

// Check usage
const usage = await client.getUsage();
console.log(
  `Simulations used: ${usage.quota.used}/${usage.quota.limit}`
);

// Get plans
const plans = await client.getPlans();
for (const plan of plans.plans) {
  console.log(`${plan.name}: $${plan.price_monthly}/month`);
}
Error Handling
import {
  ASTRIA,
  SubspaceError,
  QuotaExceededError,
  RateLimitError,
  AuthenticationError,
  ValidationError,
} from '@subspacecomputing/sdk';

try {
  const result = await client.simulate(spec);
} catch (error) {
  if (error instanceof QuotaExceededError) {
    console.error(`Monthly quota exceeded: ${error.message}`);
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limit exceeded: ${error.message}`);
    const retryAfter = error.response?.headers.get('Retry-After');
    if (retryAfter) {
      console.log(`Retry after: ${retryAfter} seconds`);
    }
  } else if (error instanceof AuthenticationError) {
    console.error(`Invalid API key: ${error.message}`);
  } else if (error instanceof ValidationError) {
    console.error(`Validation error: ${error.detail}`);
  } else if (error instanceof SubspaceError) {
    console.error(`API error: ${error.message}`);
  }
}
Rate Limit and Quota Information

After making a request, you can check your rate limit and quota status:

// Make a request
const result = await client.project(spec);

// Check rate limit info
const rateLimit = client.getRateLimitInfo();
if (rateLimit) {
  console.log(
    `Rate limit: ${rateLimit.remaining}/${rateLimit.limit} remaining`
  );
}

// Check quota info
const quota = client.getQuotaInfo();
if (quota) {
  console.log(
    `Quota: ${quota.used}/${quota.limit} used, ${quota.remaining} remaining`
  );
}

Documentation

Full documentation: https://www.subspacecomputing.com/developer

API Reference: https://www.subspacecomputing.com/docs

Support: contact@subspacecomputing.com

License

MIT License. See LICENSE for details.

2026 Subspace Computing Inc. All Rights Reserved

Keywords