Crux
API Reference@use-crux/core

Connected Knowledge Relations

relate(), relateReferences(), relateEntities(), relation stages, emit API, and KnowledgeLocator.

import {
  knowledgeModel,
  relate,
  relateEntities,
  relateReferences,
} from "@use-crux/core/knowledge";
import type {
  KnowledgeLocator,
  RelateConfig,
  RelateEmitApi,
  RelateEmitOptions,
  RelateRun,
  RelateRunInput,
  RelationStage,
  RelationTypeSpec,
} from "@use-crux/core/knowledge";

Overview

Relation stages define a typed graph vocabulary and a production mode for emitting edge claims during indexing. Use relate() for custom vocabularies, relateReferences() for explicit document references, and relateEntities() for generic entity mentions and entity relationships.

Prompt Bounds

Model-mode relation derivation uses these internal bounds:

ConstantValueApplies To
MAX_DERIVE_BATCH_CHARS12000Estimated source content assigned to one generated extraction batch.
MAX_DERIVE_PROMPT_CHARS12000Final derive or repair prompt sent for one batch.

Chunks are sorted by ordinal and assigned whole, in order, to deterministic batches. The stage vocabulary, instructions, source id, and document title repeat per batch. The document body appears as a bounded excerpt in the first batch only. Calls scale with source size, and claims from all successful batches are unioned before cache replacement.

Routine per-chunk truncation is not used. Truncation warnings are returned on result.knowledge from knowledgeBase().index() and knowledgeBase().reindex() only when a single chunk is too large for one batch. The same bounded summary is recorded on the mutation effect receipt evidence.

relate(config)

Creates a frozen relation stage for an indexing pipeline.

function relate<const TTypes extends Record<string, RelationTypeSpec>>(
  config: RelateConfig<TTypes>,
): RelationStage<TTypes>;

Parameters

type RelateConfig<TTypes extends Record<string, RelationTypeSpec>> = {
  readonly id: string;
  readonly version: number;
  readonly types: TTypes;
} & (
  | {
      readonly model: KnowledgeModel;
      readonly instructions?: string;
      readonly run?: never;
    }
  | {
      readonly run: RelateRun<TTypes>;
      readonly model?: never;
      readonly instructions?: never;
    }
);
OptionTypeDefaultConstraints
idstringRequiredMust be a non-empty string.
versionnumberRequiredMust be an integer greater than or equal to 1.
typesRecord<string, RelationTypeSpec>RequiredMust include at least one type. Type names must be non-empty and cannot contain : or %.
modelKnowledgeModelRequired in model modeMutually exclusive with run. Must have non-empty name and fingerprint, plus generateText and generateObject.
instructionsstringundefinedOnly valid with model.
runRelateRun<TTypes>Required in run modeMutually exclusive with model. Must be a function.

RelationTypeSpec

interface RelationTypeSpec {
  readonly from: readonly KnowledgeRefKind[];
  readonly to: readonly KnowledgeRefKind[];
  readonly direction: "directed" | "symmetric";
  readonly description: string;
}

from and to must be non-empty arrays of valid KnowledgeRefKind values. The stage normalizes kind order to chunk, document, entity, parent.

Returns

type RelationStage<TTypes extends Record<string, RelationTypeSpec>> =
  RelationDeriveStage & {
    readonly types: TTypes;
  } & (
    | {
        readonly mode: "model";
        readonly model: KnowledgeModel;
        readonly instructions?: string;
        readonly run?: never;
      }
    | {
        readonly mode: "run";
        readonly run: RelateRun<TTypes>;
        readonly model?: never;
        readonly instructions?: never;
      }
  );

The returned object includes _tag: "RelationStage", kind: "relation", id, version, normalized types, mode, and fingerprint().

Emit API

interface RelateRunInput {
  readonly document: CruxDocument;
  readonly chunks: readonly CruxChunk[];
}

type KnowledgeLocator =
  | { readonly url: string }
  | { readonly title: string }
  | { readonly anchor: string };

interface RelateEmitOptions {
  readonly description?: string;
  readonly evidence: KnowledgeRef | readonly KnowledgeRef[];
  readonly provenance?: "exact" | "derived";
}

interface RelateEmitApi<TTypes extends Record<string, RelationTypeSpec>> {
  emit<TType extends keyof TTypes & string>(
    type: TType,
    from: KnowledgeRefOfKinds<TTypes[TType]["from"][number]> | KnowledgeLocator,
    to: KnowledgeRefOfKinds<TTypes[TType]["to"][number]> | KnowledgeLocator,
    opts?: RelateEmitOptions,
  ): void;
}

KnowledgeLocator is resolved against indexed records during graph compilation. description is persisted only when it is a string of 2,000 characters or fewer.

Failures

relate() throws plain Errors for invalid identity, mode, model, type names, type specs, invalid kind arrays, and invalid instructions.

Example

import { relate } from "@use-crux/core/knowledge";

const citations = relate({
  id: "citations",
  version: 1,
  types: {
    cites: {
      from: ["chunk"],
      to: ["document"],
      direction: "directed",
      description: "A chunk cites another document",
    },
  },
  run: (_input, api) => {
    const evidence = {
      kind: "chunk",
      sourceId: "guide",
      chunkId: "intro",
    } as const;

    api.emit(
      "cites",
      evidence,
      { title: "Protocol Reference" },
      { evidence, provenance: "exact" },
    );
  },
});

relateReferences(config?)

Creates the built-in explicit-reference relation stage.

interface RelateReferencesConfig {
  readonly id?: string;
}

function relateReferences(
  config?: RelateReferencesConfig,
): RelationStage<{
  readonly references: {
    readonly from: readonly ["chunk"];
    readonly to: readonly ["document"];
    readonly direction: "directed";
    readonly description: "A chunk explicitly references another document";
  };
}>;
OptionTypeDefaultConstraints
idstring"references"Must satisfy relate() id validation.

The stage scans chunk text for Markdown links, bare http or https URLs, and cited titles in quoted or bracketed citation forms. It emits references claims from chunk refs to { url } or { title } locators with provenance: "exact".

Example

import { indexingPipeline } from "@use-crux/core/indexing";
import { relateReferences } from "@use-crux/core/knowledge";

const pipeline = indexingPipeline({
  derive: [relateReferences()],
});

relateEntities(config)

Creates the built-in entity relation stage.

interface RelateEntitiesConfig {
  readonly model: KnowledgeModel;
  readonly id?: string;
  readonly instructions?: string;
}

function relateEntities(config: RelateEntitiesConfig): RelationStage<{
  readonly mentions: {
    readonly from: readonly ["chunk"];
    readonly to: readonly ["entity"];
    readonly direction: "directed";
    readonly description: "A chunk mentions an entity";
  };
  readonly related: {
    readonly from: readonly ["entity"];
    readonly to: readonly ["entity"];
    readonly direction: "symmetric";
    readonly description: "Two entities are related in the source text";
  };
}>;
OptionTypeDefaultConstraints
modelKnowledgeModelRequiredMust pass entity model validation.
idstring"entities"Used as the underlying relation stage id.
instructionsstringundefinedAppended to the built-in extraction prompt.

The stage emits mentions from chunks to entity refs and related symmetric edges between entity refs. Entity ids are stable ids over trimmed, lowercased, whitespace-collapsed names. Related descriptions are accepted up to 500 characters.

Failures

ConditionError
Invalid model shapeError("Entity relations require a knowledge model.") or the model field-specific message
Returned object fails the entity schema after parsingError("Relation <id> returned invalid entity relations.")

Example

import { indexingPipeline } from "@use-crux/core/indexing";
import { knowledgeModel, relateEntities } from "@use-crux/core/knowledge";

const extractor = knowledgeModel({
  name: "entity-extractor",
  version: "1",
  generateText,
  generateObject,
});

const pipeline = indexingPipeline({
  derive: [
    relateEntities({
      model: extractor,
      instructions: "Prefer product and organization names.",
    }),
  ],
});

On this page