@kortexya/reasoninglayer 0.23.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,8 +29,9 @@ yarn add @kortexya/reasoninglayer
29
29
  import { ReasoningLayerClient, Value, TermInput, FeatureInput } from '@kortexya/reasoninglayer';
30
30
 
31
31
  const client = new ReasoningLayerClient({
32
- baseUrl: 'http://localhost:8083',
32
+ baseUrl: 'https://platform.ovh.reasoninglayer.ai',
33
33
  tenantId: 'your-tenant-uuid',
34
+ auth: { mode: 'bearer', token: process.env.RL_API_TOKEN! },
34
35
  });
35
36
 
36
37
  // Create a sort hierarchy
@@ -113,19 +114,55 @@ console.log(result.solutions); // Solutions with bindings
113
114
 
114
115
  ```typescript
115
116
  const client = new ReasoningLayerClient({
116
- baseUrl: 'http://localhost:8083', // Required
117
- tenantId: 'your-tenant-uuid', // Required, sent as X-Tenant-Id
118
- bearerToken: 'eyJhbGciOi...', // Optional, sent as Authorization: Bearer
119
- userId: 'user-uuid', // Optional, sent as X-User-Id
120
- namespaceId: 'ns-uuid', // Optional, sent as X-Namespace-Id
121
- maxRetries: 3, // Default: 3
122
- timeoutMs: 30000, // Default: 30000ms
123
- retryOn503: true, // Default: true
124
- fetch: customFetch, // Optional: custom fetch implementation
125
- interceptors: [loggingMiddleware], // Optional: request/response middleware
117
+ baseUrl: 'https://platform.ovh.reasoninglayer.ai', // Required
118
+ tenantId: 'your-tenant-uuid', // Required, sent as X-Tenant-Id
119
+ auth: { mode: 'bearer', token: 'eyJ…' }, // Required see Authentication below
120
+ userId: 'user-uuid', // Optional, sent as X-User-Id
121
+ namespaceId: 'ns-uuid', // Optional, sent as X-Namespace-Id
122
+ maxRetries: 3, // Default: 3
123
+ timeoutMs: 30000, // Default: 30000ms
124
+ retryOn503: true, // Default: false
125
+ fetch: customFetch, // Optional: custom fetch implementation
126
+ interceptors: [loggingMiddleware], // Optional: request/response middleware
126
127
  });
127
128
  ```
128
129
 
130
+ ### Authentication
131
+
132
+ The `auth` field is **required** and must be one of two modes. There is no
133
+ unauthenticated mode — the SDK will not silently ship requests that the
134
+ gateway would reject.
135
+
136
+ **`bearer` — server-side / programmatic usage.** Send a long-lived API token
137
+ (typically a service-account token issued by the auth gateway) on every
138
+ request as `Authorization: Bearer <token>`.
139
+
140
+ ```typescript
141
+ const client = new ReasoningLayerClient({
142
+ baseUrl: 'https://platform.ovh.reasoninglayer.ai',
143
+ tenantId: '550e8400-e29b-41d4-a716-446655440000',
144
+ auth: { mode: 'bearer', token: process.env.RL_API_TOKEN! },
145
+ });
146
+ ```
147
+
148
+ **`cookie` — in-browser SPA usage.** Rely on the session cookie set by the
149
+ auth gateway after an interactive login. The SDK issues HTTP requests with
150
+ `credentials: 'include'` so the cookie is attached even on cross-origin
151
+ requests; WebSocket connections rely on the browser attaching the cookie
152
+ automatically (same-origin).
153
+
154
+ ```typescript
155
+ const client = new ReasoningLayerClient({
156
+ baseUrl: 'https://platform.ovh.reasoninglayer.ai',
157
+ tenantId: '550e8400-e29b-41d4-a716-446655440000',
158
+ auth: { mode: 'cookie' },
159
+ });
160
+ ```
161
+
162
+ The choice between modes belongs to the **deployment context** of the
163
+ caller, not the SDK — pick `bearer` from servers and CI, `cookie` from
164
+ browser code that has already gone through the platform's login flow.
165
+
129
166
  ## Response Metadata
130
167
 
131
168
  ```typescript
package/dist/index.cjs CHANGED
@@ -7,7 +7,7 @@ var __export = (target, all) => {
7
7
  };
8
8
 
9
9
  // src/config.ts
10
- var SDK_VERSION = "0.23.1";
10
+ var SDK_VERSION = "1.0.1";
11
11
  function resolveConfig(config) {
12
12
  if (!config.baseUrl) {
13
13
  throw new Error("ClientConfig.baseUrl is required");
@@ -15,13 +15,21 @@ function resolveConfig(config) {
15
15
  if (!config.tenantId) {
16
16
  throw new Error("ClientConfig.tenantId is required");
17
17
  }
18
+ if (!config.auth) {
19
+ throw new Error(
20
+ "ClientConfig.auth is required \u2014 pass { mode: 'bearer', token } or { mode: 'cookie' }"
21
+ );
22
+ }
23
+ if (config.auth.mode === "bearer" && !config.auth.token) {
24
+ throw new Error("ClientConfig.auth.token is required when mode is 'bearer'");
25
+ }
18
26
  return {
19
27
  baseUrl: config.baseUrl.replace(/\/+$/, ""),
20
28
  tenantId: config.tenantId,
21
29
  userId: config.userId,
22
30
  namespaceId: config.namespaceId,
23
31
  authenticatedUser: config.authenticatedUser,
24
- bearerToken: config.bearerToken,
32
+ auth: config.auth,
25
33
  timeoutMs: config.timeoutMs ?? 3e4,
26
34
  maxRetries: config.maxRetries ?? 3,
27
35
  retryOn503: config.retryOn503 ?? false,
@@ -377,8 +385,8 @@ var WebSocketClient = class {
377
385
  buildUrl(path, params) {
378
386
  const baseUrl = this.config.baseUrl.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
379
387
  const queryParams = new URLSearchParams({ tenant_id: this.config.tenantId });
380
- if (this.config.bearerToken) {
381
- queryParams.set("token", this.config.bearerToken);
388
+ if (this.config.auth.mode === "bearer") {
389
+ queryParams.set("token", this.config.auth.token);
382
390
  }
383
391
  if (params) {
384
392
  for (const [key, value] of Object.entries(params)) {
@@ -617,7 +625,7 @@ function buildAuthHeaders(config) {
617
625
  if (config.userId) headers["X-User-Id"] = config.userId;
618
626
  if (config.namespaceId) headers["X-Namespace-Id"] = config.namespaceId;
619
627
  if (config.authenticatedUser) headers["X-Authenticated-User"] = config.authenticatedUser;
620
- if (config.bearerToken) headers["Authorization"] = `Bearer ${config.bearerToken}`;
628
+ if (config.auth.mode === "bearer") headers["Authorization"] = `Bearer ${config.auth.token}`;
621
629
  return headers;
622
630
  }
623
631
  function transformRequestInit(init) {
@@ -644,10 +652,14 @@ function createCustomFetch(config) {
644
652
  const response = await executeFetch(input, transformedInit, timeoutMs, config);
645
653
  if (response.ok) return response;
646
654
  let body;
655
+ const rawText = await response.clone().text().catch(() => "");
647
656
  try {
648
- body = await response.clone().json();
657
+ body = rawText ? JSON.parse(rawText) : { error: "unknown", message: `HTTP ${response.status}` };
649
658
  } catch {
650
- body = { error: "unknown", message: `HTTP ${response.status}` };
659
+ body = {
660
+ error: "unknown",
661
+ message: rawText.trim() || `HTTP ${response.status}`
662
+ };
651
663
  }
652
664
  const apiError = createApiError(response.status, body, response.headers);
653
665
  if (response.status === 429 && attempt < maxRetries) {
@@ -685,7 +697,11 @@ async function executeFetch(input, init, timeoutMs, config) {
685
697
  const existingSignal = init?.signal;
686
698
  const combinedSignal = existingSignal ? AbortSignal.any([timeoutController.signal, existingSignal]) : timeoutController.signal;
687
699
  const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
688
- const request = new Request(url, { ...init, signal: combinedSignal });
700
+ const request = new Request(url, {
701
+ ...init,
702
+ signal: combinedSignal,
703
+ credentials: config.auth.mode === "cookie" ? "include" : "same-origin"
704
+ });
689
705
  try {
690
706
  const fetchFn = config.fetch;
691
707
  const baseFetch = (req) => fetchFn(req);
@@ -19393,10 +19409,14 @@ function ComponentHealthDtoFromApiToFront(dto) {
19393
19409
  };
19394
19410
  }
19395
19411
  function EnrichedHealthResponseFromApiToFront(dto) {
19412
+ if (dto == null) {
19413
+ return { buildInfo: void 0, components: [], status: "unknown" };
19414
+ }
19415
+ const rawBuildInfo = dto.build_info;
19396
19416
  return {
19397
- buildInfo: BuildInfoDtoFromApiToFront(dto.build_info),
19398
- components: dto.components.map(ComponentHealthDtoFromApiToFront),
19399
- status: dto.status
19417
+ buildInfo: rawBuildInfo == null ? void 0 : BuildInfoDtoFromApiToFront(rawBuildInfo),
19418
+ components: (dto.components ?? []).map(ComponentHealthDtoFromApiToFront),
19419
+ status: dto.status ?? "unknown"
19400
19420
  };
19401
19421
  }
19402
19422