npm package: @kortexya/reasoninglayer
Description: TypeScript client SDK for the Reasoning Layer API
Latest version: 0.14.0

# @kortexya/reasoninglayer

TypeScript SDK for the [Reasoning Layer](https://kortexya.com) API — a knowledge representation and reasoning engine.

## Features

- **Zero runtime dependencies** — only `fetch` and `AbortController` (ES2022)
- **Dual ESM/CJS** — works in Node 18+, modern browsers, Deno, and Bun
- **Full type safety** — strict TypeScript with discriminated unions, no `any` types
- **29 resource clients** covering sorts, terms, inference, query, fuzzy logic, cognitive agents, causal reasoning, optimization, and more
- **8 builder namespaces** — `Value`, `FeatureInput`, `TermInput`, `guard`, `SortBuilder`, `psi`, `allen`, `LP`
- **Automatic retry** — exponential backoff with jitter on 429 and 503 responses
- **WebSocket** — real-time cognitive agent event subscriptions with auto-reconnect
- **Error hierarchy** — typed errors for constraint violations, rate limits, timeouts, and network failures

## Installation

```bash
npm install @kortexya/reasoninglayer
# or
pnpm add @kortexya/reasoninglayer
# or
yarn add @kortexya/reasoninglayer
```

## Quick Start

```typescript
import { ReasoningLayerClient, Value, TermInput, FeatureInput } from '@kortexya/reasoninglayer';

const client = new ReasoningLayerClient({
  baseUrl: 'http://localhost:8083',
  tenantId: 'your-tenant-uuid',
});

// Create a sort hierarchy
const personSort = await client.sorts.createSort({ name: 'person' });
const employeeSort = await client.sorts.createSort({
  name: 'employee',
  parents: [personSort.id],
  features: { salary: { value_type: 'Real' } },
});

// Create a psi-term
const term = await client.terms.createTerm({
  sort_id: employeeSort.id,
  features: {
    name: Value.string('Alice'),
    salary: Value.real(95000),
  },
});

// Add inference rules (homoiconic format)
await client.inference.addRule({
  head: TermInput.byName('well_paid', {
    person: FeatureInput.variable('X'),
  }),
  body: [
    {
      term: TermInput.byName('employee', {
        name: FeatureInput.variable('X'),
        salary: FeatureInput.constrainedVar('S', { op: 'gt', value: 80000 }),
      }),
    },
  ],
});

// Query with backward chaining
const result = await client.inference.backwardChain({
  goal: TermInput.byName('well_paid', {
    person: FeatureInput.variable('Who'),
  }),
  max_solutions: 10,
});

console.log(result.solutions); // Solutions with bindings
```

## Resource Clients

| Client | Domain | Key Operations |
|--------|--------|---------------|
| `sorts` | Sort hierarchy | create, GLB/LUB, compare, similarity |
| `terms` | Psi-terms | CRUD, bulk create, validation |
| `inference` | Inference engine | rules, facts, backward/forward chaining, fuzzy, Bayesian, NAF |
| `query` | Query | unifiable, by-sort, structured search, NL query |
| `cognitive` | Cognitive agents | BDI cycle, beliefs, goals, messaging, WebSocket events |
| `fuzzy` | Fuzzy logic | unify, merge, subsumption, top-K search |
| `constraints` | Constraints | arithmetic solving, graph visualization |
| `namespaces` | Namespaces | hierarchy, imports, metadata |
| `collections` | Collections | CRUD, tagging |
| `execution` | Execution | sessions, backtracking, goal stack |
| `causal` | Causal reasoning | Pearl's hierarchy, interventions, counterfactuals |
| `ingestion` | Data ingestion | documents, markdown, RDF, sessions |
| `reviews` | Reviews | approve, reject, merge, re-extract |
| `visualization` | Visualization | lattice, hypergraph, residuation state |
| `ilp` | ILP | pattern learning, GFlowNet, synthesis |
| `reasoning` | Reasoning | entailment, residuation, resource coordination |
| `statistical` | Statistics | correlation, independence, causal discovery |
| `control` | Proof control | cut, findall, forall, NAF, conditionals |
| `spaces` | Spaces | computation spaces, clone, commit, search |
| `row` | Row polymorphism | schema-flexible search, unification |
| `sources` | Data sources | register, schema discovery, ingest |
| `communities` | Communities | detection, memberships, search |
| `utilities` | Utilities | strings, arithmetic, term copy |
| `scenarios` | Scenarios | CRUD, verification |
| `actionReviews` | Action reviews | approve, reject, modify autonomous actions |
| `discovery` | Discovery | causal effect discovery, prediction |
| `extract` | Extraction | entity extraction from text |
| `optimize` | Optimization | LP solve, KB-driven optimization |

## Configuration

```typescript
const client = new ReasoningLayerClient({
  baseUrl: 'http://localhost:8083',  // Required
  tenantId: 'your-tenant-uuid',     // Required, sent as X-Tenant-Id
  bearerToken: 'eyJhbGciOi...',     // Optional, sent as Authorization: Bearer
  userId: 'user-uuid',              // Optional, sent as X-User-Id
  namespaceId: 'ns-uuid',           // Optional, sent as X-Namespace-Id
  maxRetries: 3,                    // Default: 3
  timeoutMs: 30000,                 // Default: 30000ms
  retryOn503: true,                 // Default: true
  fetch: customFetch,               // Optional: custom fetch implementation
  interceptors: [loggingMiddleware], // Optional: request/response middleware
});
```

## Response Metadata

```typescript
// Default: returns data directly
const sort = await client.sorts.createSort({ name: 'person' });

// With metadata: returns { data, status, headers, rateLimit }
const result = await client.sorts.withMetadata().createSort({ name: 'person' });
console.log(result.status);    // 201
console.log(result.rateLimit); // { limit, remaining, retryAfter }
```

## Error Handling

```typescript
import {
  ApiError,
  ConstraintViolationError,
  RateLimitError,
  TimeoutError,
  NetworkError,
} from '@kortexya/reasoninglayer';

try {
  await client.terms.createTerm({ ... });
} catch (error) {
  if (error instanceof ConstraintViolationError) {
    console.log(error.termId, error.feature, error.constraint);
  } else if (error instanceof RateLimitError) {
    console.log(`Retry after ${error.retryAfter}s`);
  } else if (error instanceof TimeoutError) {
    console.log(`Timed out after ${error.timeoutMs}ms`);
  } else if (error instanceof NetworkError) {
    console.log('Connection failed:', error.message);
  }
}
```

## Builders

The SDK provides builder functions for constructing API request values with full type safety:

```typescript
import { Value, FeatureInput, TermInput, guard, allen, SortBuilder, psi, LP } from '@kortexya/reasoninglayer';

// Tagged values (term CRUD)
Value.string('hello')           // { type: 'String', value: 'hello' }
Value.integer(42)               // { type: 'Integer', value: 42 }
Value.fuzzyNumber('triangular', { a: 20, b: 22, c: 24 })

// Untagged values (inference)
FeatureInput.string('hello')    // 'hello'
FeatureInput.variable('X')      // { name: 'X' }
FeatureInput.constrainedVar('S', { op: 'gt', value: 80000 })

// Guard constraints
guard('gt', 100)                // { guard: { op: 'gt', value: 100 } }

// Allen temporal relations
allen('before')                 // { allen: 'before' }

// LP optimization
LP.maximize({ x: 3, y: 5 })    // objective function
LP.constraint({ x: 1, y: 3 }, '<=', 12)  // linear constraint
LP.nonNegative('x', 'y')       // variable bounds

// Fluent sort builder
new SortBuilder('employee')
  .parents(['person'])
  .feature('salary', 'Real')
  .boundConstraint('salary', 'gt', 50000)
  .build()
```

## Development

```bash
pnpm install                    # Install dependencies
pnpm run build                  # Build (dual ESM/CJS + .d.ts)
pnpm run typecheck              # Type check (tsc --noEmit)
pnpm test                       # Run tests
pnpm run test:watch             # Watch mode
pnpm run generate-manifest      # Generate endpoint manifest from OpenAPI spec
pnpm run check-completeness     # Report SDK coverage vs. OpenAPI spec
pnpm run sync-check             # Compare generated vs hand-written types
pnpm run docs:build             # Build documentation site
```

## Compatibility

| SDK Version | Min Backend Version | Node | Browser |
|-------------|-------------------|------|---------|
| 0.1.0       | Latest            | 18+  | ES2022+ |

## License

MIT