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:
| Constant | Value | Applies To |
|---|---|---|
MAX_DERIVE_BATCH_CHARS | 12000 | Estimated source content assigned to one generated extraction batch. |
MAX_DERIVE_PROMPT_CHARS | 12000 | Final 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;
}
);| Option | Type | Default | Constraints |
|---|---|---|---|
id | string | Required | Must be a non-empty string. |
version | number | Required | Must be an integer greater than or equal to 1. |
types | Record<string, RelationTypeSpec> | Required | Must include at least one type. Type names must be non-empty and cannot contain : or %. |
model | KnowledgeModel | Required in model mode | Mutually exclusive with run. Must have non-empty name and fingerprint, plus generateText and generateObject. |
instructions | string | undefined | Only valid with model. |
run | RelateRun<TTypes> | Required in run mode | Mutually 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";
};
}>;| Option | Type | Default | Constraints |
|---|---|---|---|
id | string | "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";
};
}>;| Option | Type | Default | Constraints |
|---|---|---|---|
model | KnowledgeModel | Required | Must pass entity model validation. |
id | string | "entities" | Used as the underlying relation stage id. |
instructions | string | undefined | Appended 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
| Condition | Error |
|---|---|
| Invalid model shape | Error("Entity relations require a knowledge model.") or the model field-specific message |
| Returned object fails the entity schema after parsing | Error("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.",
}),
],
});Related
- Reference: Connected Knowledge
- Reference: Connected Knowledge model and refs
- Reference: Connected Knowledge recipe steps