Projection
KIT · constant · 运行时值
导入
import { Projection } from '@jangts/agent-core/kits/projection';import { Projection } from '@jangts/agent-core/kits/projection';其他公开入口:@jangts/agent-core/types、@jangts/agent-core/kits/projection、@jangts/agent-core/kits。
定义
成员目录
| 成员 | 用途 |
|---|---|
defineContentProjection | 完整输入输出见下方重载。 |
projectContinuousExcerpt | 完整输入输出见下方重载。 |
defineTreeProjection | 完整输入输出见下方重载。 |
成员详情
defineContentProjection
Projection.defineContentProjection(options: ContentProjectionOptions): Readonly<{ project: ({ value, maxChars: limit, }: { value: unknown; maxChars: number; }) => ContentProjection; }>Compile a JSON-preserving projector.
Keep valid JSON while reducing prose before dropping records; budgets are caller policy. The candidate list is tried in order (outer counts, inner lengths), so callers control whether trimming text or dropping items is preferred, and the configured fallback is used only when no candidate fits.
| 参数 | 类型 | 传递 | 说明 |
|---|---|---|---|
options | ContentProjectionOptions | 必需 | — |
options 的字段
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
counts | readonly number[] | 必需 | 只读。Maximum array items to keep, tried in order before moving to the next length. |
lengths | readonly number[] | 必需 | 只读。Maximum characters per string, tried in order inside each count candidate. |
render | (excerpt: unknown) => string | 必需 | 只读。Renders a shortened value; must be synchronous. |
fallback | (limit: number) => string | 必需 | 只读。Builds fallback text for a limit, used when no candidate fits; must be synchronous. |
返回: Readonly<{ project: ({ value, maxChars: limit, }: { value: unknown; maxChars: number; }) => ContentProjection; }>。
返回值结构
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
project | ({ value, maxChars: limit, }: { value: unknown; maxChars: number; }) => ContentProjection | 必需 | 见类型定义及调用场景。 |
projectContinuousExcerpt
Projection.projectContinuousExcerpt(body: string, limit: number, render: (length: number) => string): ContentProjection | undefinedProject a continuous excerpt of a body by binary-searching the longest prefix that fits.
Binary-search a continuous prefix and keep an existing surrogate pair intact. render receives the prefix length, not the text, so the caller decides how the excerpt is framed.
| 参数 | 类型 | 传递 | 说明 |
|---|---|---|---|
body | string | 必需 | — |
limit | number | 必需 | — |
render | (length: number) => string | 必需 | — |
返回: ContentProjection \| undefined。
返回值的可选结构: 选择其中一种结构,各分支的字段要求分别列出。
分支 1
undefined
分支 2
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
text | string | 必需 | 只读。Rendered text that fits the requested budget. |
truncated | boolean | 必需 | 只读。True when anything was shortened or replaced by the fallback. |
defineTreeProjection
Projection.defineTreeProjection<Context>(options: TreeProjectionOptions<Context>): Readonly<{ visit: (value: unknown, context: Context) => unknown; }>Compile a depth-limited tree transform.
Traverse synchronously in property/array order; only undefined omits a result. Because a visitor returns a new value instead of mutating, an omitted branch disappears from arrays and objects the same way, and maxDepth bounds both cycles and cost.
| 类型参数 | 约束 | 默认类型 |
|---|---|---|
Context | — | — |
| 参数 | 类型 | 传递 | 说明 |
|---|---|---|---|
options | TreeProjectionOptions<Context> | 必需 | — |
options 的字段
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
maxDepth | number | 必需 | 只读。Maximum included depth; deeper values are omitted. Must be a non-negative integer. |
omit | ((value: unknown, depth: number, context: Context) => boolean) | undefined | 可省略 | 只读。Drops a value when it returns true; must be synchronous boolean. |
visitRecord | ((value: Record<string, unknown>, depth: number, context: Context) => void) | undefined | 可省略 | 只读。Observes every retained record, for example to record which fields were kept. |
返回: Readonly<{ visit: (value: unknown, context: Context) => unknown; }>。
返回值结构
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
visit | (value: unknown, context: Context) => unknown | 必需 | 见类型定义及调用场景。 |
使用示例
- Projection:按预算投影内容:先缩短文本,再减少条目;源数据、投影结果和预算由 App 显式区分。
为同一份查询结果准备紧凑 JSON
入门 · Node.js
import { Projection } from '@jangts/agent-core/kits/projection';
const projection = Projection.defineContentProjection({
counts: [10, 3, 1], lengths: [200, 80, 20],
render: value => JSON.stringify(value), fallback: () => '{}',
});
const result = projection.project({ value: { items: [{ title: '配置说明', body: '正文'.repeat(100) }] }, maxChars: 120 });
console.log(result.text, result.truncated);import { Projection } from '@jangts/agent-core/kits/projection';
const projection = Projection.defineContentProjection({
counts: [10, 3, 1], lengths: [200, 80, 20],
render: value => JSON.stringify(value), fallback: () => '{}',
});
const result = projection.project({ value: { items: [{ title: '配置说明', body: '正文'.repeat(100) }] }, maxChars: 120 });
console.log(result.text, result.truncated);相同数据先移除私有字段,再按预算投影
配置 · Node.js
import { Projection } from '@jangts/agent-core/kits/projection';
const tree = Projection.defineTreeProjection({
maxDepth: 4,
visitRecord(record) { delete record.privateNote; },
});
const source = { items: [{ title: '配置说明', body: '正文'.repeat(100), privateNote: '不向模型提供' }] };
// 调用者明确选择副本所有权;visitor 不会碰原记录。
const publicData = tree.visit(structuredClone(source), undefined);
const compact = Projection.defineContentProjection({ counts: [10, 3, 1], lengths: [200, 80, 20], render: JSON.stringify, fallback: () => '{}' });
console.log(compact.project({ value: publicData, maxChars: 120 }));import { Projection } from '@jangts/agent-core/kits/projection';
const tree = Projection.defineTreeProjection({
maxDepth: 4,
visitRecord(record) { delete record.privateNote; },
});
const source = { items: [{ title: '配置说明', body: '正文'.repeat(100), privateNote: '不向模型提供' }] };
// 调用者明确选择副本所有权;visitor 不会碰原记录。
const publicData = tree.visit(structuredClone(source), undefined);
const compact = Projection.defineContentProjection({ counts: [10, 3, 1], lengths: [200, 80, 20], render: JSON.stringify, fallback: () => '{}' });
console.log(compact.project({ value: publicData, maxChars: 120 }));保留连续正文而非拆散段落
扩展 · Node.js
render 的输出长度须随前缀长度单调增长,二分搜索才有意义。
import { Projection } from '@jangts/agent-core/kits/projection';
const body = '一段连续的资料正文。'.repeat(100);
const excerpt = Projection.projectContinuousExcerpt(body, 120, length => JSON.stringify({ excerpt: body.slice(0, length) }));
if (excerpt) console.log(JSON.parse(excerpt.text));import { Projection } from '@jangts/agent-core/kits/projection';
const body = '一段连续的资料正文。'.repeat(100);
const excerpt = Projection.projectContinuousExcerpt(body, 120, length => JSON.stringify({ excerpt: body.slice(0, length) }));
if (excerpt)
console.log(JSON.parse(excerpt.text));