@exulu/backend 1.66.0 → 1.67.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.cts CHANGED
@@ -184,7 +184,47 @@ interface Item {
184
184
  [key: string]: any;
185
185
  }
186
186
 
187
- declare const PUBLIC_TOOL_TYPES: readonly ["function", "web_search", "skill"];
187
+ /**
188
+ * OAuth 2.0 configuration for an {@link ExuluTool}. When a tool is constructed
189
+ * with an `oauth` property, Exulu wraps its `execute` so it only runs when a
190
+ * valid access token exists for the calling (toolId, userId) pair. When no
191
+ * valid token exists the tool short-circuits and returns an authorization URL
192
+ * the agent can show the user; the generic /oauth/callback route completes the
193
+ * flow and persists the tokens.
194
+ *
195
+ * Only the standard authorization-code grant is supported. All values are
196
+ * declared in code (source them from env vars or however you like) — none of
197
+ * them are exposed as admin-configurable tool config.
198
+ */
199
+ type ExuluOauthConfig = {
200
+ /** The provider's authorization endpoint, e.g. https://app.hubspot.com/oauth/authorize */
201
+ authorizationUrl: string;
202
+ /** The provider's token endpoint, e.g. https://api.hubapi.com/oauth/v1/token */
203
+ tokenUrl: string;
204
+ clientId: string;
205
+ /** Never leaves the server: used only in the server-side token exchange. */
206
+ clientSecret: string;
207
+ /** Scopes to request; joined with spaces in the authorization URL. */
208
+ scopes: string[];
209
+ /** PKCE (S256). Defaults to true; set false for providers that reject PKCE. */
210
+ pkce?: boolean;
211
+ /**
212
+ * Extra query params appended to the authorization URL, e.g.
213
+ * `{ access_type: "offline", prompt: "consent" }` to make Google return a
214
+ * refresh token.
215
+ */
216
+ extraAuthParams?: Record<string, string>;
217
+ };
218
+ /** The oauth context injected into an oauth-enabled tool's execute inputs. */
219
+ type ExuluOauthToolContext = {
220
+ accessToken: string;
221
+ /** null when the provider did not report an expiry. */
222
+ expiresAt: Date | null;
223
+ /** Space-joined scopes the token was granted, when reported by the provider. */
224
+ scopes: string | null;
225
+ };
226
+
227
+ declare const PUBLIC_TOOL_TYPES: readonly ["function", "web_search", "skill", "context"];
188
228
  type PublicToolType = (typeof PUBLIC_TOOL_TYPES)[number];
189
229
  type ToolType = PublicToolType | "agent" | "context";
190
230
  declare class ExuluTool {
@@ -196,13 +236,14 @@ declare class ExuluTool {
196
236
  type: ToolType;
197
237
  tool: Tool;
198
238
  needsApproval: boolean;
239
+ oauth?: ExuluOauthConfig;
199
240
  config: {
200
241
  name: string;
201
242
  description: string;
202
243
  type: "boolean" | "string" | "number" | "variable";
203
244
  default?: string | boolean | number;
204
245
  }[];
205
- constructor({ id, name, description, category, inputSchema, type, execute, config, needsApproval, }: {
246
+ constructor({ id, name, description, category, inputSchema, type, execute, config, needsApproval, oauth, }: {
206
247
  id: string;
207
248
  name: string;
208
249
  description: string;
@@ -216,6 +257,7 @@ declare class ExuluTool {
216
257
  default?: string | boolean | number;
217
258
  }[];
218
259
  needsApproval?: boolean;
260
+ oauth?: ExuluOauthConfig;
219
261
  execute: (inputs: any, options?: any) => Promise<{
220
262
  result?: string;
221
263
  job?: string;
@@ -475,6 +517,70 @@ declare const VectorMethodEnum: {
475
517
  };
476
518
  type VectorMethod = (typeof VectorMethodEnum)[keyof typeof VectorMethodEnum];
477
519
 
520
+ /**
521
+ * A single entity type a context extracts (e.g. { name: "Person", description: "..." }).
522
+ * Declared in code on the ExuluContext `entities.types`, and/or in the DB via the
523
+ * `entity_type_settings` admin table. The effective set is the union of both.
524
+ */
525
+ type EntityTypeDefinition = {
526
+ name: string;
527
+ description: string;
528
+ };
529
+ /**
530
+ * The opt-in entity-layer configuration on an ExuluContext. When this block is
531
+ * absent (and no admin types exist for the context) the entity layer is OFF and
532
+ * retrieval/ingestion behave exactly as before.
533
+ */
534
+ type ExuluEntitiesConfig = {
535
+ /** Entity types declared in code. Merged (union) with admin-declared types. */
536
+ types?: EntityTypeDefinition[];
537
+ /** models.id used for extraction. Resolved via resolveModel(). Falls back to a platform default. */
538
+ model?: string;
539
+ /** Where to extract from. "chunks" (default) locates each mention to a chunk. */
540
+ extractFrom?: "chunks" | "document";
541
+ /** Weight of the shared-entity boost term in retrieval ranking. Default 0.3. */
542
+ boostWeight?: number;
543
+ /** Drop mentions below this extractor confidence (0..1). Default 0.5. */
544
+ confidenceThreshold?: number;
545
+ /** Target language for canonical entity names. Default "english". */
546
+ canonicalLanguage?: string;
547
+ };
548
+ /** A related entity surfaced via derived co-occurrence. */
549
+ type RelatedEntity = {
550
+ id: string;
551
+ name: string;
552
+ type: string;
553
+ /** Relatedness weight (normalized Jaccard over shared documents). */
554
+ weight: number;
555
+ };
556
+ /** Entity intelligence for one query entity, returned to the calling agent. */
557
+ type QueryEntityInsight = {
558
+ id: string;
559
+ type: string;
560
+ name: string;
561
+ /** How many of the returned chunks mention this entity. */
562
+ matchedInResults: number;
563
+ /** Distinct documents in the context mentioning this entity (maintained counter). */
564
+ relatedDocCount: number;
565
+ /** Top-K co-occurring entities, weighted. */
566
+ relatedEntities: RelatedEntity[];
567
+ };
568
+ type EntityInsights = {
569
+ queryEntities: QueryEntityInsight[];
570
+ };
571
+ /** Caller-supplied entity filter for agent-driven exploration. */
572
+ type EntityFilter = {
573
+ /** Resolve directly by entity id. */
574
+ entityIds?: string[];
575
+ /** Or resolve by (type, name) — name is normalized to a canonical key. */
576
+ entities?: {
577
+ type: string;
578
+ name: string;
579
+ }[];
580
+ /** "any" (default): chunk mentions at least one. "all": chunk mentions all. */
581
+ mode?: "any" | "all";
582
+ };
583
+
478
584
  type VectorSearchChunkResult = {
479
585
  chunk_content: string;
480
586
  chunk_index: number;
@@ -491,6 +597,12 @@ type VectorSearchChunkResult = {
491
597
  chunk_cosine_distance?: number;
492
598
  chunk_fts_rank?: number;
493
599
  chunk_hybrid_score?: number;
600
+ /** Entities mentioned in this chunk (present only when the entity layer is on). */
601
+ chunk_entities?: {
602
+ id: string;
603
+ name: string;
604
+ type: string;
605
+ }[];
494
606
  context?: {
495
607
  name: string;
496
608
  id: string;
@@ -579,8 +691,14 @@ declare class ExuluContext {
579
691
  };
580
692
  languages?: ("german" | "english")[];
581
693
  };
694
+ /**
695
+ * Optional entity-layer configuration. When present (or when an admin has
696
+ * configured entity types for this context) the graph/entity retrieval
697
+ * features are switched on. Absent → identical behavior to before.
698
+ */
699
+ entities?: ExuluEntitiesConfig;
582
700
  sources: ExuluContextSource[];
583
- constructor({ id, name, description, embedder, processor, active, fields, queryRewriter, resultReranker, configuration, sources, }: {
701
+ constructor({ id, name, description, embedder, processor, active, fields, queryRewriter, resultReranker, configuration, entities, sources, }: {
584
702
  id: string;
585
703
  name: string;
586
704
  fields: ExuluContextFieldDefinition[];
@@ -607,6 +725,7 @@ declare class ExuluContext {
607
725
  hybrid?: number;
608
726
  };
609
727
  };
728
+ entities?: ExuluEntitiesConfig;
610
729
  });
611
730
  processField: (trigger: STATISTICS_LABELS, item: Item, exuluConfig: ExuluConfig, user?: number, role?: string) => Promise<{
612
731
  result: Item | undefined;
@@ -633,6 +752,7 @@ declare class ExuluContext {
633
752
  before?: number;
634
753
  after?: number;
635
754
  };
755
+ entityFilter?: EntityFilter;
636
756
  }) => Promise<{
637
757
  itemFilters: SearchFilters;
638
758
  chunkFilters: SearchFilters;
@@ -645,6 +765,7 @@ declare class ExuluContext {
645
765
  embedder: string;
646
766
  };
647
767
  chunks: VectorSearchChunkResult[];
768
+ entityInsights?: EntityInsights;
648
769
  }>;
649
770
  deleteAll: () => Promise<{
650
771
  count: number;
@@ -697,6 +818,30 @@ declare class ExuluContext {
697
818
  }>;
698
819
  };
699
820
  };
821
+ /**
822
+ * Entity-layer administration: backfill extraction over existing items,
823
+ * count stale items (for the admin "run backfill?" prompt), and purge a type.
824
+ */
825
+ entityLayer: {
826
+ /** Count items whose entities were extracted with an out-of-date type set. */
827
+ countStale: () => Promise<number>;
828
+ /**
829
+ * Full re-extraction over items. `onlyStale` (default true) limits to items
830
+ * whose type-set signature is out of date. Runs inline in batches with a
831
+ * safeguard cap; entity extraction (not re-embedding) is what runs here.
832
+ */
833
+ backfill: ({ onlyStale, limit, }?: {
834
+ onlyStale?: boolean;
835
+ limit?: number;
836
+ }) => Promise<{
837
+ processed: number;
838
+ skipped: number;
839
+ }>;
840
+ /** Remove all entities (and their mentions via cascade) of a given type. */
841
+ purgeType: (typeName: string) => Promise<{
842
+ removed: number;
843
+ }>;
844
+ };
700
845
  createItemsTable: () => Promise<void>;
701
846
  createChunksTable: () => Promise<void>;
702
847
  }
@@ -2221,4 +2366,4 @@ declare const ExuluPython: {
2221
2366
  instructions: typeof getPythonSetupInstructions;
2222
2367
  };
2223
2368
 
2224
- export { type JOB_STATUS as EXULU_JOB_STATUS, JOB_STATUS_ENUM as EXULU_JOB_STATUS_ENUM, type STATISTICS_TYPE as EXULU_STATISTICS_TYPE, STATISTICS_TYPE_ENUM as EXULU_STATISTICS_TYPE_ENUM, type ExuluAgent, ExuluApp, ExuluAuthentication, ExuluChunkers, ExuluContext, ExuluDatabase, ExuluDefaultProviders, ExuluDefaultTools, ExuluDocumentProcessor, ExuluEmbedder, ExuluEval, type Item as ExuluItem, ExuluJobs, ExuluOtel, ExuluProvider, ExuluPython, queues as ExuluQueues, ExuluReranker, ExuluTool, trajectoryRegistry as ExuluTrajectoryRegistry, ExuluVariables };
2369
+ export { type JOB_STATUS as EXULU_JOB_STATUS, JOB_STATUS_ENUM as EXULU_JOB_STATUS_ENUM, type STATISTICS_TYPE as EXULU_STATISTICS_TYPE, STATISTICS_TYPE_ENUM as EXULU_STATISTICS_TYPE_ENUM, type ExuluAgent, ExuluApp, ExuluAuthentication, ExuluChunkers, ExuluContext, ExuluDatabase, ExuluDefaultProviders, ExuluDefaultTools, ExuluDocumentProcessor, ExuluEmbedder, ExuluEval, type Item as ExuluItem, ExuluJobs, type ExuluOauthConfig, type ExuluOauthToolContext, ExuluOtel, ExuluProvider, ExuluPython, queues as ExuluQueues, ExuluReranker, ExuluTool, trajectoryRegistry as ExuluTrajectoryRegistry, ExuluVariables };
package/dist/index.d.ts CHANGED
@@ -184,7 +184,47 @@ interface Item {
184
184
  [key: string]: any;
185
185
  }
186
186
 
187
- declare const PUBLIC_TOOL_TYPES: readonly ["function", "web_search", "skill"];
187
+ /**
188
+ * OAuth 2.0 configuration for an {@link ExuluTool}. When a tool is constructed
189
+ * with an `oauth` property, Exulu wraps its `execute` so it only runs when a
190
+ * valid access token exists for the calling (toolId, userId) pair. When no
191
+ * valid token exists the tool short-circuits and returns an authorization URL
192
+ * the agent can show the user; the generic /oauth/callback route completes the
193
+ * flow and persists the tokens.
194
+ *
195
+ * Only the standard authorization-code grant is supported. All values are
196
+ * declared in code (source them from env vars or however you like) — none of
197
+ * them are exposed as admin-configurable tool config.
198
+ */
199
+ type ExuluOauthConfig = {
200
+ /** The provider's authorization endpoint, e.g. https://app.hubspot.com/oauth/authorize */
201
+ authorizationUrl: string;
202
+ /** The provider's token endpoint, e.g. https://api.hubapi.com/oauth/v1/token */
203
+ tokenUrl: string;
204
+ clientId: string;
205
+ /** Never leaves the server: used only in the server-side token exchange. */
206
+ clientSecret: string;
207
+ /** Scopes to request; joined with spaces in the authorization URL. */
208
+ scopes: string[];
209
+ /** PKCE (S256). Defaults to true; set false for providers that reject PKCE. */
210
+ pkce?: boolean;
211
+ /**
212
+ * Extra query params appended to the authorization URL, e.g.
213
+ * `{ access_type: "offline", prompt: "consent" }` to make Google return a
214
+ * refresh token.
215
+ */
216
+ extraAuthParams?: Record<string, string>;
217
+ };
218
+ /** The oauth context injected into an oauth-enabled tool's execute inputs. */
219
+ type ExuluOauthToolContext = {
220
+ accessToken: string;
221
+ /** null when the provider did not report an expiry. */
222
+ expiresAt: Date | null;
223
+ /** Space-joined scopes the token was granted, when reported by the provider. */
224
+ scopes: string | null;
225
+ };
226
+
227
+ declare const PUBLIC_TOOL_TYPES: readonly ["function", "web_search", "skill", "context"];
188
228
  type PublicToolType = (typeof PUBLIC_TOOL_TYPES)[number];
189
229
  type ToolType = PublicToolType | "agent" | "context";
190
230
  declare class ExuluTool {
@@ -196,13 +236,14 @@ declare class ExuluTool {
196
236
  type: ToolType;
197
237
  tool: Tool;
198
238
  needsApproval: boolean;
239
+ oauth?: ExuluOauthConfig;
199
240
  config: {
200
241
  name: string;
201
242
  description: string;
202
243
  type: "boolean" | "string" | "number" | "variable";
203
244
  default?: string | boolean | number;
204
245
  }[];
205
- constructor({ id, name, description, category, inputSchema, type, execute, config, needsApproval, }: {
246
+ constructor({ id, name, description, category, inputSchema, type, execute, config, needsApproval, oauth, }: {
206
247
  id: string;
207
248
  name: string;
208
249
  description: string;
@@ -216,6 +257,7 @@ declare class ExuluTool {
216
257
  default?: string | boolean | number;
217
258
  }[];
218
259
  needsApproval?: boolean;
260
+ oauth?: ExuluOauthConfig;
219
261
  execute: (inputs: any, options?: any) => Promise<{
220
262
  result?: string;
221
263
  job?: string;
@@ -475,6 +517,70 @@ declare const VectorMethodEnum: {
475
517
  };
476
518
  type VectorMethod = (typeof VectorMethodEnum)[keyof typeof VectorMethodEnum];
477
519
 
520
+ /**
521
+ * A single entity type a context extracts (e.g. { name: "Person", description: "..." }).
522
+ * Declared in code on the ExuluContext `entities.types`, and/or in the DB via the
523
+ * `entity_type_settings` admin table. The effective set is the union of both.
524
+ */
525
+ type EntityTypeDefinition = {
526
+ name: string;
527
+ description: string;
528
+ };
529
+ /**
530
+ * The opt-in entity-layer configuration on an ExuluContext. When this block is
531
+ * absent (and no admin types exist for the context) the entity layer is OFF and
532
+ * retrieval/ingestion behave exactly as before.
533
+ */
534
+ type ExuluEntitiesConfig = {
535
+ /** Entity types declared in code. Merged (union) with admin-declared types. */
536
+ types?: EntityTypeDefinition[];
537
+ /** models.id used for extraction. Resolved via resolveModel(). Falls back to a platform default. */
538
+ model?: string;
539
+ /** Where to extract from. "chunks" (default) locates each mention to a chunk. */
540
+ extractFrom?: "chunks" | "document";
541
+ /** Weight of the shared-entity boost term in retrieval ranking. Default 0.3. */
542
+ boostWeight?: number;
543
+ /** Drop mentions below this extractor confidence (0..1). Default 0.5. */
544
+ confidenceThreshold?: number;
545
+ /** Target language for canonical entity names. Default "english". */
546
+ canonicalLanguage?: string;
547
+ };
548
+ /** A related entity surfaced via derived co-occurrence. */
549
+ type RelatedEntity = {
550
+ id: string;
551
+ name: string;
552
+ type: string;
553
+ /** Relatedness weight (normalized Jaccard over shared documents). */
554
+ weight: number;
555
+ };
556
+ /** Entity intelligence for one query entity, returned to the calling agent. */
557
+ type QueryEntityInsight = {
558
+ id: string;
559
+ type: string;
560
+ name: string;
561
+ /** How many of the returned chunks mention this entity. */
562
+ matchedInResults: number;
563
+ /** Distinct documents in the context mentioning this entity (maintained counter). */
564
+ relatedDocCount: number;
565
+ /** Top-K co-occurring entities, weighted. */
566
+ relatedEntities: RelatedEntity[];
567
+ };
568
+ type EntityInsights = {
569
+ queryEntities: QueryEntityInsight[];
570
+ };
571
+ /** Caller-supplied entity filter for agent-driven exploration. */
572
+ type EntityFilter = {
573
+ /** Resolve directly by entity id. */
574
+ entityIds?: string[];
575
+ /** Or resolve by (type, name) — name is normalized to a canonical key. */
576
+ entities?: {
577
+ type: string;
578
+ name: string;
579
+ }[];
580
+ /** "any" (default): chunk mentions at least one. "all": chunk mentions all. */
581
+ mode?: "any" | "all";
582
+ };
583
+
478
584
  type VectorSearchChunkResult = {
479
585
  chunk_content: string;
480
586
  chunk_index: number;
@@ -491,6 +597,12 @@ type VectorSearchChunkResult = {
491
597
  chunk_cosine_distance?: number;
492
598
  chunk_fts_rank?: number;
493
599
  chunk_hybrid_score?: number;
600
+ /** Entities mentioned in this chunk (present only when the entity layer is on). */
601
+ chunk_entities?: {
602
+ id: string;
603
+ name: string;
604
+ type: string;
605
+ }[];
494
606
  context?: {
495
607
  name: string;
496
608
  id: string;
@@ -579,8 +691,14 @@ declare class ExuluContext {
579
691
  };
580
692
  languages?: ("german" | "english")[];
581
693
  };
694
+ /**
695
+ * Optional entity-layer configuration. When present (or when an admin has
696
+ * configured entity types for this context) the graph/entity retrieval
697
+ * features are switched on. Absent → identical behavior to before.
698
+ */
699
+ entities?: ExuluEntitiesConfig;
582
700
  sources: ExuluContextSource[];
583
- constructor({ id, name, description, embedder, processor, active, fields, queryRewriter, resultReranker, configuration, sources, }: {
701
+ constructor({ id, name, description, embedder, processor, active, fields, queryRewriter, resultReranker, configuration, entities, sources, }: {
584
702
  id: string;
585
703
  name: string;
586
704
  fields: ExuluContextFieldDefinition[];
@@ -607,6 +725,7 @@ declare class ExuluContext {
607
725
  hybrid?: number;
608
726
  };
609
727
  };
728
+ entities?: ExuluEntitiesConfig;
610
729
  });
611
730
  processField: (trigger: STATISTICS_LABELS, item: Item, exuluConfig: ExuluConfig, user?: number, role?: string) => Promise<{
612
731
  result: Item | undefined;
@@ -633,6 +752,7 @@ declare class ExuluContext {
633
752
  before?: number;
634
753
  after?: number;
635
754
  };
755
+ entityFilter?: EntityFilter;
636
756
  }) => Promise<{
637
757
  itemFilters: SearchFilters;
638
758
  chunkFilters: SearchFilters;
@@ -645,6 +765,7 @@ declare class ExuluContext {
645
765
  embedder: string;
646
766
  };
647
767
  chunks: VectorSearchChunkResult[];
768
+ entityInsights?: EntityInsights;
648
769
  }>;
649
770
  deleteAll: () => Promise<{
650
771
  count: number;
@@ -697,6 +818,30 @@ declare class ExuluContext {
697
818
  }>;
698
819
  };
699
820
  };
821
+ /**
822
+ * Entity-layer administration: backfill extraction over existing items,
823
+ * count stale items (for the admin "run backfill?" prompt), and purge a type.
824
+ */
825
+ entityLayer: {
826
+ /** Count items whose entities were extracted with an out-of-date type set. */
827
+ countStale: () => Promise<number>;
828
+ /**
829
+ * Full re-extraction over items. `onlyStale` (default true) limits to items
830
+ * whose type-set signature is out of date. Runs inline in batches with a
831
+ * safeguard cap; entity extraction (not re-embedding) is what runs here.
832
+ */
833
+ backfill: ({ onlyStale, limit, }?: {
834
+ onlyStale?: boolean;
835
+ limit?: number;
836
+ }) => Promise<{
837
+ processed: number;
838
+ skipped: number;
839
+ }>;
840
+ /** Remove all entities (and their mentions via cascade) of a given type. */
841
+ purgeType: (typeName: string) => Promise<{
842
+ removed: number;
843
+ }>;
844
+ };
700
845
  createItemsTable: () => Promise<void>;
701
846
  createChunksTable: () => Promise<void>;
702
847
  }
@@ -2221,4 +2366,4 @@ declare const ExuluPython: {
2221
2366
  instructions: typeof getPythonSetupInstructions;
2222
2367
  };
2223
2368
 
2224
- export { type JOB_STATUS as EXULU_JOB_STATUS, JOB_STATUS_ENUM as EXULU_JOB_STATUS_ENUM, type STATISTICS_TYPE as EXULU_STATISTICS_TYPE, STATISTICS_TYPE_ENUM as EXULU_STATISTICS_TYPE_ENUM, type ExuluAgent, ExuluApp, ExuluAuthentication, ExuluChunkers, ExuluContext, ExuluDatabase, ExuluDefaultProviders, ExuluDefaultTools, ExuluDocumentProcessor, ExuluEmbedder, ExuluEval, type Item as ExuluItem, ExuluJobs, ExuluOtel, ExuluProvider, ExuluPython, queues as ExuluQueues, ExuluReranker, ExuluTool, trajectoryRegistry as ExuluTrajectoryRegistry, ExuluVariables };
2369
+ export { type JOB_STATUS as EXULU_JOB_STATUS, JOB_STATUS_ENUM as EXULU_JOB_STATUS_ENUM, type STATISTICS_TYPE as EXULU_STATISTICS_TYPE, STATISTICS_TYPE_ENUM as EXULU_STATISTICS_TYPE_ENUM, type ExuluAgent, ExuluApp, ExuluAuthentication, ExuluChunkers, ExuluContext, ExuluDatabase, ExuluDefaultProviders, ExuluDefaultTools, ExuluDocumentProcessor, ExuluEmbedder, ExuluEval, type Item as ExuluItem, ExuluJobs, type ExuluOauthConfig, type ExuluOauthToolContext, ExuluOtel, ExuluProvider, ExuluPython, queues as ExuluQueues, ExuluReranker, ExuluTool, trajectoryRegistry as ExuluTrajectoryRegistry, ExuluVariables };