@nexusm/sdk 5.1.0 → 5.2.0

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/dist/index.d.mts CHANGED
@@ -360,25 +360,6 @@ declare class OfflineQueue {
360
360
  * every failure surfaces as a typed {@link NexusError} subclass.
361
361
  */
362
362
 
363
- /**
364
- * HTTP client that communicates with the Nexus API.
365
- *
366
- * All service-level modules (Memory, Conversation, Knowledge, Context)
367
- * delegate their network calls to a shared `HttpClient` instance, which
368
- * guarantees consistent authentication, timeout handling, and error
369
- * mapping across the entire SDK surface.
370
- *
371
- * @example
372
- * ```typescript
373
- * import { resolveConfig } from '../config';
374
- * import { HttpClient } from './client';
375
- *
376
- * const config = resolveConfig({ apiKey: 'nx_test_abc123' });
377
- * const http = new HttpClient(config);
378
- *
379
- * const memories = await http.get<Memory[]>('/memory/search', { query: 'hello' });
380
- * ```
381
- */
382
363
  declare class HttpClient {
383
364
  /** Underlying Axios instance. */
384
365
  private readonly axios;
@@ -2649,6 +2630,25 @@ declare class ValidationError extends ApiError {
2649
2630
  /**
2650
2631
  * HTTP 404 -- the requested resource does not exist.
2651
2632
  */
2633
+ /**
2634
+ * Something between the caller and the Nexus API answered the request.
2635
+ *
2636
+ * Raised for two shapes that are otherwise indistinguishable from success:
2637
+ *
2638
+ * 1. a **3xx redirect** (auth edges such as Cloudflare Access bounce
2639
+ * unauthenticated calls to a login page), and
2640
+ * 2. a **2xx whose body is not JSON** on a call that expects JSON
2641
+ * (a captive portal or proxy returning its own HTML with status 200).
2642
+ *
2643
+ * Both used to resolve successfully with an HTML string as `data`, which a
2644
+ * caller's `result.results ?? []` turns into "zero results" — Kairos logged
2645
+ * "connected" for two months while Nexus recorded zero calls
2646
+ * (Kairos#66 / Aether#372). A wrong credential must fail loudly, not
2647
+ * quietly look like an empty database.
2648
+ */
2649
+ declare class UpstreamInterceptError extends ApiError {
2650
+ constructor(message: string, statusCode: number, response?: unknown);
2651
+ }
2652
2652
  declare class NotFoundError extends ApiError {
2653
2653
  constructor(message: string, response?: unknown);
2654
2654
  }
@@ -2820,4 +2820,4 @@ declare const apiKeyCreateSchema: z.ZodObject<{
2820
2820
  expires_in_days?: number | undefined;
2821
2821
  }>;
2822
2822
 
2823
- export { type Activity, type ActivityProcessingStatus, ActivityService, type ActivityStats, type ActivityStatusResponse, type ActivityStreamRequest, type ActivityStreamResponse, type ActivityType, ApiError, type ApiErrorDetail, type ApiKey, type ApiKeyCreate, type ApiKeyCreated, type ApiResponse, AuthenticationError, type CacheConfig, type CompoundId, ConfigurationError, type ContextDepth, type ContextDepthPreset, type ContextGraphEntity, type ContextLayer, type ContextRequest, type ContextRetrieveResponse, ContextService, type Conversation, type ConversationCreate, type ConversationList, type ConversationListParams, type ConversationMessage, ConversationService, type ConversationStatus, type ConversationSummary, DEFAULT_CONFIG, DEPTH_PRESETS, type EntityListParams, type EntityListResponse, type ErrorReportRequest, type ErrorReportResponse, ErrorService, type ErrorSeverity, type ErrorType, type ExtractionRequest, type ExtractionResult, type FeedbackItemRequest, type FeedbackListItem, type FeedbackListParams, type FeedbackListResponse, type FeedbackResponse, FeedbackService, type FeedbackSubmitRequest, type GraphPath, type GraphPathEntity, type GraphPathRelationship, type GraphQueryRequest, type GraphQueryResponse, type HealthResponse, type HealthStatus, InputValidationError, type JournalEntry, type JournalResponse, type KnowledgeEntity, type KnowledgeRelationship, KnowledgeService, type Memory, type MemoryCreate, type MemoryJournalParams, type MemoryList, type MemoryListParams, type MemorySearch, type MemorySearchResult, MemoryService, type MemoryType, type MemoryUpdate, type Message, type MessageCreate, type MessageList, type MessageListParams, type MessageRole, NetworkError, NexusClient, type NexusConfig, NexusError, NotFoundError, type OfflineConfig, OfflineQueue, type PaginatedResponse, type Pagination, type ProfileMemory, type QueuedRequest, RateLimitError, type RequestOptions, type ResolvedCacheConfig, type ResolvedConfig, type ResolvedRetryConfig, type RetryConfig, type SearchResult, type ServiceStatus, type SortOrder, type Tenant, type TenantQuotas, TenantService, type TenantTier, TimeoutError, type UsageStats, ValidationError, apiKeyCreateSchema, contextRequestSchema, conversationCreateSchema, extractionRequestSchema, graphQueryRequestSchema, memoryCreateSchema, memorySearchSchema, memoryUpdateSchema, messageCreateSchema, resolveConfig };
2823
+ export { type Activity, type ActivityProcessingStatus, ActivityService, type ActivityStats, type ActivityStatusResponse, type ActivityStreamRequest, type ActivityStreamResponse, type ActivityType, ApiError, type ApiErrorDetail, type ApiKey, type ApiKeyCreate, type ApiKeyCreated, type ApiResponse, AuthenticationError, type CacheConfig, type CompoundId, ConfigurationError, type ContextDepth, type ContextDepthPreset, type ContextGraphEntity, type ContextLayer, type ContextRequest, type ContextRetrieveResponse, ContextService, type Conversation, type ConversationCreate, type ConversationList, type ConversationListParams, type ConversationMessage, ConversationService, type ConversationStatus, type ConversationSummary, DEFAULT_CONFIG, DEPTH_PRESETS, type EntityListParams, type EntityListResponse, type ErrorReportRequest, type ErrorReportResponse, ErrorService, type ErrorSeverity, type ErrorType, type ExtractionRequest, type ExtractionResult, type FeedbackItemRequest, type FeedbackListItem, type FeedbackListParams, type FeedbackListResponse, type FeedbackResponse, FeedbackService, type FeedbackSubmitRequest, type GraphPath, type GraphPathEntity, type GraphPathRelationship, type GraphQueryRequest, type GraphQueryResponse, type HealthResponse, type HealthStatus, InputValidationError, type JournalEntry, type JournalResponse, type KnowledgeEntity, type KnowledgeRelationship, KnowledgeService, type Memory, type MemoryCreate, type MemoryJournalParams, type MemoryList, type MemoryListParams, type MemorySearch, type MemorySearchResult, MemoryService, type MemoryType, type MemoryUpdate, type Message, type MessageCreate, type MessageList, type MessageListParams, type MessageRole, NetworkError, NexusClient, type NexusConfig, NexusError, NotFoundError, type OfflineConfig, OfflineQueue, type PaginatedResponse, type Pagination, type ProfileMemory, type QueuedRequest, RateLimitError, type RequestOptions, type ResolvedCacheConfig, type ResolvedConfig, type ResolvedRetryConfig, type RetryConfig, type SearchResult, type ServiceStatus, type SortOrder, type Tenant, type TenantQuotas, TenantService, type TenantTier, TimeoutError, UpstreamInterceptError, type UsageStats, ValidationError, apiKeyCreateSchema, contextRequestSchema, conversationCreateSchema, extractionRequestSchema, graphQueryRequestSchema, memoryCreateSchema, memorySearchSchema, memoryUpdateSchema, messageCreateSchema, resolveConfig };
package/dist/index.d.ts CHANGED
@@ -360,25 +360,6 @@ declare class OfflineQueue {
360
360
  * every failure surfaces as a typed {@link NexusError} subclass.
361
361
  */
362
362
 
363
- /**
364
- * HTTP client that communicates with the Nexus API.
365
- *
366
- * All service-level modules (Memory, Conversation, Knowledge, Context)
367
- * delegate their network calls to a shared `HttpClient` instance, which
368
- * guarantees consistent authentication, timeout handling, and error
369
- * mapping across the entire SDK surface.
370
- *
371
- * @example
372
- * ```typescript
373
- * import { resolveConfig } from '../config';
374
- * import { HttpClient } from './client';
375
- *
376
- * const config = resolveConfig({ apiKey: 'nx_test_abc123' });
377
- * const http = new HttpClient(config);
378
- *
379
- * const memories = await http.get<Memory[]>('/memory/search', { query: 'hello' });
380
- * ```
381
- */
382
363
  declare class HttpClient {
383
364
  /** Underlying Axios instance. */
384
365
  private readonly axios;
@@ -2649,6 +2630,25 @@ declare class ValidationError extends ApiError {
2649
2630
  /**
2650
2631
  * HTTP 404 -- the requested resource does not exist.
2651
2632
  */
2633
+ /**
2634
+ * Something between the caller and the Nexus API answered the request.
2635
+ *
2636
+ * Raised for two shapes that are otherwise indistinguishable from success:
2637
+ *
2638
+ * 1. a **3xx redirect** (auth edges such as Cloudflare Access bounce
2639
+ * unauthenticated calls to a login page), and
2640
+ * 2. a **2xx whose body is not JSON** on a call that expects JSON
2641
+ * (a captive portal or proxy returning its own HTML with status 200).
2642
+ *
2643
+ * Both used to resolve successfully with an HTML string as `data`, which a
2644
+ * caller's `result.results ?? []` turns into "zero results" — Kairos logged
2645
+ * "connected" for two months while Nexus recorded zero calls
2646
+ * (Kairos#66 / Aether#372). A wrong credential must fail loudly, not
2647
+ * quietly look like an empty database.
2648
+ */
2649
+ declare class UpstreamInterceptError extends ApiError {
2650
+ constructor(message: string, statusCode: number, response?: unknown);
2651
+ }
2652
2652
  declare class NotFoundError extends ApiError {
2653
2653
  constructor(message: string, response?: unknown);
2654
2654
  }
@@ -2820,4 +2820,4 @@ declare const apiKeyCreateSchema: z.ZodObject<{
2820
2820
  expires_in_days?: number | undefined;
2821
2821
  }>;
2822
2822
 
2823
- export { type Activity, type ActivityProcessingStatus, ActivityService, type ActivityStats, type ActivityStatusResponse, type ActivityStreamRequest, type ActivityStreamResponse, type ActivityType, ApiError, type ApiErrorDetail, type ApiKey, type ApiKeyCreate, type ApiKeyCreated, type ApiResponse, AuthenticationError, type CacheConfig, type CompoundId, ConfigurationError, type ContextDepth, type ContextDepthPreset, type ContextGraphEntity, type ContextLayer, type ContextRequest, type ContextRetrieveResponse, ContextService, type Conversation, type ConversationCreate, type ConversationList, type ConversationListParams, type ConversationMessage, ConversationService, type ConversationStatus, type ConversationSummary, DEFAULT_CONFIG, DEPTH_PRESETS, type EntityListParams, type EntityListResponse, type ErrorReportRequest, type ErrorReportResponse, ErrorService, type ErrorSeverity, type ErrorType, type ExtractionRequest, type ExtractionResult, type FeedbackItemRequest, type FeedbackListItem, type FeedbackListParams, type FeedbackListResponse, type FeedbackResponse, FeedbackService, type FeedbackSubmitRequest, type GraphPath, type GraphPathEntity, type GraphPathRelationship, type GraphQueryRequest, type GraphQueryResponse, type HealthResponse, type HealthStatus, InputValidationError, type JournalEntry, type JournalResponse, type KnowledgeEntity, type KnowledgeRelationship, KnowledgeService, type Memory, type MemoryCreate, type MemoryJournalParams, type MemoryList, type MemoryListParams, type MemorySearch, type MemorySearchResult, MemoryService, type MemoryType, type MemoryUpdate, type Message, type MessageCreate, type MessageList, type MessageListParams, type MessageRole, NetworkError, NexusClient, type NexusConfig, NexusError, NotFoundError, type OfflineConfig, OfflineQueue, type PaginatedResponse, type Pagination, type ProfileMemory, type QueuedRequest, RateLimitError, type RequestOptions, type ResolvedCacheConfig, type ResolvedConfig, type ResolvedRetryConfig, type RetryConfig, type SearchResult, type ServiceStatus, type SortOrder, type Tenant, type TenantQuotas, TenantService, type TenantTier, TimeoutError, type UsageStats, ValidationError, apiKeyCreateSchema, contextRequestSchema, conversationCreateSchema, extractionRequestSchema, graphQueryRequestSchema, memoryCreateSchema, memorySearchSchema, memoryUpdateSchema, messageCreateSchema, resolveConfig };
2823
+ export { type Activity, type ActivityProcessingStatus, ActivityService, type ActivityStats, type ActivityStatusResponse, type ActivityStreamRequest, type ActivityStreamResponse, type ActivityType, ApiError, type ApiErrorDetail, type ApiKey, type ApiKeyCreate, type ApiKeyCreated, type ApiResponse, AuthenticationError, type CacheConfig, type CompoundId, ConfigurationError, type ContextDepth, type ContextDepthPreset, type ContextGraphEntity, type ContextLayer, type ContextRequest, type ContextRetrieveResponse, ContextService, type Conversation, type ConversationCreate, type ConversationList, type ConversationListParams, type ConversationMessage, ConversationService, type ConversationStatus, type ConversationSummary, DEFAULT_CONFIG, DEPTH_PRESETS, type EntityListParams, type EntityListResponse, type ErrorReportRequest, type ErrorReportResponse, ErrorService, type ErrorSeverity, type ErrorType, type ExtractionRequest, type ExtractionResult, type FeedbackItemRequest, type FeedbackListItem, type FeedbackListParams, type FeedbackListResponse, type FeedbackResponse, FeedbackService, type FeedbackSubmitRequest, type GraphPath, type GraphPathEntity, type GraphPathRelationship, type GraphQueryRequest, type GraphQueryResponse, type HealthResponse, type HealthStatus, InputValidationError, type JournalEntry, type JournalResponse, type KnowledgeEntity, type KnowledgeRelationship, KnowledgeService, type Memory, type MemoryCreate, type MemoryJournalParams, type MemoryList, type MemoryListParams, type MemorySearch, type MemorySearchResult, MemoryService, type MemoryType, type MemoryUpdate, type Message, type MessageCreate, type MessageList, type MessageListParams, type MessageRole, NetworkError, NexusClient, type NexusConfig, NexusError, NotFoundError, type OfflineConfig, OfflineQueue, type PaginatedResponse, type Pagination, type ProfileMemory, type QueuedRequest, RateLimitError, type RequestOptions, type ResolvedCacheConfig, type ResolvedConfig, type ResolvedRetryConfig, type RetryConfig, type SearchResult, type ServiceStatus, type SortOrder, type Tenant, type TenantQuotas, TenantService, type TenantTier, TimeoutError, UpstreamInterceptError, type UsageStats, ValidationError, apiKeyCreateSchema, contextRequestSchema, conversationCreateSchema, extractionRequestSchema, graphQueryRequestSchema, memoryCreateSchema, memorySearchSchema, memoryUpdateSchema, messageCreateSchema, resolveConfig };
package/dist/index.js CHANGED
@@ -51,6 +51,7 @@ __export(index_exports, {
51
51
  RateLimitError: () => RateLimitError,
52
52
  TenantService: () => TenantService,
53
53
  TimeoutError: () => TimeoutError,
54
+ UpstreamInterceptError: () => UpstreamInterceptError,
54
55
  ValidationError: () => ValidationError,
55
56
  apiKeyCreateSchema: () => apiKeyCreateSchema,
56
57
  contextRequestSchema: () => contextRequestSchema,
@@ -230,6 +231,12 @@ var ValidationError = class extends ApiError {
230
231
  this.details = details;
231
232
  }
232
233
  };
234
+ var UpstreamInterceptError = class extends ApiError {
235
+ constructor(message, statusCode, response) {
236
+ super(message, statusCode, response, "NEXUS_UPSTREAM_INTERCEPT");
237
+ this.name = "UpstreamInterceptError";
238
+ }
239
+ };
233
240
  var NotFoundError = class extends ApiError {
234
241
  constructor(message, response) {
235
242
  super(message, 404, response, "NEXUS_NOT_FOUND_ERROR");
@@ -641,6 +648,35 @@ var OfflineQueue = class {
641
648
  };
642
649
 
643
650
  // src/http/client.ts
651
+ function redirectHost(location) {
652
+ if (typeof location !== "string" || location === "") return "an unknown host";
653
+ try {
654
+ return new URL(location).host;
655
+ } catch {
656
+ return "an unparseable location";
657
+ }
658
+ }
659
+ function upstreamRedirectError(response, url) {
660
+ const headers = response.headers ?? {};
661
+ const host = redirectHost(headers.location ?? headers.Location);
662
+ return new UpstreamInterceptError(
663
+ `Request to ${url ?? "the API"} was redirected (HTTP ${response.status}) to ${host} instead of being answered by Nexus. This is typically an expired or missing edge credential (e.g. a Cloudflare Access service token) \u2014 the API itself was never reached.`,
664
+ response.status,
665
+ response.data
666
+ );
667
+ }
668
+ function assertNotIntercepted(response) {
669
+ if (response.config?.responseType === "text") return;
670
+ const headers = response.headers ?? {};
671
+ const raw = headers["content-type"] ?? headers["Content-Type"];
672
+ if (typeof raw !== "string" || raw === "") return;
673
+ if (raw.toLowerCase().includes("json")) return;
674
+ throw new UpstreamInterceptError(
675
+ `Request to ${response.config?.url ?? "the API"} returned HTTP ${response.status} with content-type "${raw}" where JSON was expected. Something between this client and Nexus answered the request (auth edge, proxy, or captive portal); treating it as data would look like an empty result.`,
676
+ response.status,
677
+ response.data
678
+ );
679
+ }
644
680
  var HttpClient = class {
645
681
  /**
646
682
  * Create a new HTTP client.
@@ -658,7 +694,14 @@ var HttpClient = class {
658
694
  }
659
695
  this.axios = import_axios.default.create({
660
696
  baseURL: config.baseUrl,
661
- timeout: config.timeout
697
+ timeout: config.timeout,
698
+ // Never follow redirects (Kairos#66 / Aether#372). An auth edge such as
699
+ // Cloudflare Access answers an unauthenticated call with 302 → its own
700
+ // login page; following it yields a 200 with HTML, which is
701
+ // indistinguishable from an empty result to the caller. With
702
+ // maxRedirects: 0 the 3xx fails axios' status validation and reaches the
703
+ // error interceptor, which turns it into an UpstreamInterceptError.
704
+ maxRedirects: 0
662
705
  });
663
706
  this.setupRequestInterceptor();
664
707
  this.setupResponseInterceptor();
@@ -873,8 +916,11 @@ var HttpClient = class {
873
916
  */
874
917
  setupResponseInterceptor() {
875
918
  this.axios.interceptors.response.use(
876
- // Success handler -- pass through
877
- (response) => response,
919
+ // Success handler -- pass through, except for a 2xx that is not JSON.
920
+ (response) => {
921
+ assertNotIntercepted(response);
922
+ return response;
923
+ },
878
924
  // Error handler -- normalise into NexusError hierarchy
879
925
  (error) => {
880
926
  if (import_axios.default.isCancel(error)) {
@@ -888,6 +934,11 @@ var HttpClient = class {
888
934
  )
889
935
  );
890
936
  }
937
+ if (error.response && error.response.status >= 300 && error.response.status < 400) {
938
+ return Promise.reject(
939
+ upstreamRedirectError(error.response, error.config?.url)
940
+ );
941
+ }
891
942
  if (error.response) {
892
943
  const apiError = ApiError.fromResponse(error.response);
893
944
  const reqUrl = error.config?.url ?? "";
@@ -1544,6 +1595,7 @@ var apiKeyCreateSchema = import_zod5.z.object({
1544
1595
  RateLimitError,
1545
1596
  TenantService,
1546
1597
  TimeoutError,
1598
+ UpstreamInterceptError,
1547
1599
  ValidationError,
1548
1600
  apiKeyCreateSchema,
1549
1601
  contextRequestSchema,