@anvia/core 1.0.2 → 1.0.4
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/README.md +63 -0
- package/dist/agent/index.d.ts +3 -3
- package/dist/agent/index.js +6 -4
- package/dist/{agent-DYfzP-n5.d.ts → agent-fvQIBLBk.d.ts} +1 -1
- package/dist/{chunk-AR2K73CJ.js → chunk-34EDX4ZL.js} +4 -83
- package/dist/chunk-34EDX4ZL.js.map +1 -0
- package/dist/chunk-4EWTDOLR.js +412 -0
- package/dist/chunk-4EWTDOLR.js.map +1 -0
- package/dist/chunk-KSKST3KP.js +86 -0
- package/dist/chunk-KSKST3KP.js.map +1 -0
- package/dist/{chunk-YFJ4NHV6.js → chunk-LZD36ZAP.js} +86 -1
- package/dist/chunk-LZD36ZAP.js.map +1 -0
- package/dist/{chunk-PH6OTIPZ.js → chunk-NMVCGWQY.js} +4 -4
- package/dist/{chunk-EO2GECYH.js → chunk-OIB3URVG.js} +2 -2
- package/dist/{chunk-IWJK7JB5.js → chunk-VSTJNHOZ.js} +2 -2
- package/dist/documents/index.d.ts +2 -0
- package/dist/documents/index.js +6 -335
- package/dist/documents/index.js.map +1 -1
- package/dist/evals/index.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -5
- package/dist/internal/agent.d.ts +2 -2
- package/dist/internal/agent.js +6 -4
- package/dist/internal/agent.js.map +1 -1
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.js +2 -1
- package/dist/pipeline/index.d.ts +76 -3
- package/dist/pipeline/index.js +268 -27
- package/dist/pipeline/index.js.map +1 -1
- package/dist/skills/index.js +4 -3
- package/dist/text-document-B-X7Vxq1.d.ts +32 -0
- package/dist/tool/index.js +3 -2
- package/dist/{types-BUEZMBhO.d.ts → types-ChH_bdtR.d.ts} +1 -0
- package/dist/vector-store/index.d.ts +25 -5
- package/dist/vector-store/index.js +6 -1
- package/package.json +1 -1
- package/dist/chunk-AR2K73CJ.js.map +0 -1
- package/dist/chunk-YFJ4NHV6.js.map +0 -1
- /package/dist/{chunk-PH6OTIPZ.js.map → chunk-NMVCGWQY.js.map} +0 -0
- /package/dist/{chunk-EO2GECYH.js.map → chunk-OIB3URVG.js.map} +0 -0
- /package/dist/{chunk-IWJK7JB5.js.map → chunk-VSTJNHOZ.js.map} +0 -0
package/README.md
CHANGED
|
@@ -500,6 +500,43 @@ const { runId, output } = await pipeline.run({
|
|
|
500
500
|
});
|
|
501
501
|
```
|
|
502
502
|
|
|
503
|
+
Pipelines use the same named observability configuration as Agents. Pipeline observers receive the
|
|
504
|
+
root run and every composed, parallel, Agent, extraction, and custom stage. A primary stage trace is
|
|
505
|
+
propagated into an Agent stage so its generations and tools become children of that stage. This
|
|
506
|
+
requires the Pipeline and Agent `primaryTrace` names to match. When they differ, Anvia leaves the
|
|
507
|
+
Agent trace unchanged without raising an error:
|
|
508
|
+
|
|
509
|
+
```ts
|
|
510
|
+
const pipeline = new Pipeline({
|
|
511
|
+
id: "support-flow",
|
|
512
|
+
inputSchema: z.string(),
|
|
513
|
+
observability: {
|
|
514
|
+
observers: { telemetry: pipelineObserver },
|
|
515
|
+
primaryTrace: "telemetry",
|
|
516
|
+
},
|
|
517
|
+
}).agent({
|
|
518
|
+
id: "draft",
|
|
519
|
+
agent,
|
|
520
|
+
suspension: "reject",
|
|
521
|
+
request: ({ input }) => ({ prompt: input }),
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
const result = await pipeline.run({
|
|
525
|
+
input: "Customer cannot complete checkout.",
|
|
526
|
+
trace: { sessionId: "support-session" },
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
console.log(result.trace);
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
The `observer` passed to `pipeline.run()` remains a separate stage-event sink intended for Studio,
|
|
533
|
+
logging, and other operational consumers. Its errors are isolated unless `failOnObserverError` is
|
|
534
|
+
enabled.
|
|
535
|
+
|
|
536
|
+
`observability.errorPolicy` controls named observer failures instead. It accepts `"ignore"` or
|
|
537
|
+
`"throw"` and defaults to `"ignore"`. With `"throw"`, the run rejects with a
|
|
538
|
+
`PipelineObserverDispatchError` containing the failed phase and per-observer failures.
|
|
539
|
+
|
|
503
540
|
## Documents
|
|
504
541
|
|
|
505
542
|
Applications own file discovery, file reads, source metadata, and per-file error policy. Core only
|
|
@@ -538,6 +575,32 @@ slice. PDF pages are one-based, and the parser task is disposed before extractio
|
|
|
538
575
|
If parsing or abort handling fails together with parser cleanup, extraction rejects with an
|
|
539
576
|
`AggregateError` containing the operation failure first and the cleanup failure second.
|
|
540
577
|
|
|
578
|
+
For the common vector ingestion path, embed and upsert raw text with one call:
|
|
579
|
+
|
|
580
|
+
```ts
|
|
581
|
+
import { ingestVectorText } from "@anvia/core/vector-store";
|
|
582
|
+
|
|
583
|
+
await ingestVectorText({
|
|
584
|
+
store,
|
|
585
|
+
document: {
|
|
586
|
+
id: "incident-42",
|
|
587
|
+
text,
|
|
588
|
+
metadata: { tenant: "acme" },
|
|
589
|
+
},
|
|
590
|
+
embeddingModel,
|
|
591
|
+
chunking: {
|
|
592
|
+
strategy: "recursive",
|
|
593
|
+
maxSize: 1_000,
|
|
594
|
+
overlap: 100,
|
|
595
|
+
separators: ["\n\n", "\n", " "],
|
|
596
|
+
},
|
|
597
|
+
});
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
`ingestVectorDocuments()` accepts the same document shape for batches. Without `chunking`, each
|
|
601
|
+
source document is embedded as one chunk. Chunk embeddings remain grouped under the source document
|
|
602
|
+
ID so re-ingestion replaces its complete vector representation instead of leaving stale chunks.
|
|
603
|
+
|
|
541
604
|
## Media
|
|
542
605
|
|
|
543
606
|
Media helpers follow the same one-object API and share `providerOptions`, `retries`, and
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { M as ModelCallOptions } from '../model-call-options-CZkSw_xN.js';
|
|
2
2
|
export { R as RetryContext, a as RetryOptions, b as RetrySetting } from '../retry-CjvSlKGW.js';
|
|
3
|
-
export { A as Agent, a as AgentContextInput, b as AgentMemory, c as AgentMemoryOptions, d as AgentOptions, e as AgentToolInput, f as AgentToolOptions, C as CreateHybridVectorContextOptions, g as CreateVectorContextOptions, V as VectorContext, h as VectorContextBaseOptions, i as createVectorContext, j as isVectorContext } from '../agent-
|
|
3
|
+
export { A as Agent, a as AgentContextInput, b as AgentMemory, c as AgentMemoryOptions, d as AgentOptions, e as AgentToolInput, f as AgentToolOptions, C as CreateHybridVectorContextOptions, g as CreateVectorContextOptions, V as VectorContext, h as VectorContextBaseOptions, i as createVectorContext, j as isVectorContext } from '../agent-fvQIBLBk.js';
|
|
4
4
|
import { M as Message, U as Usage, C as CompletionFinishReason } from '../types-DgvozfPc.js';
|
|
5
|
-
import { A as AgentBlockedOutcome, g as AgentInteractionOutcome } from '../types-
|
|
6
|
-
export { a as AgentChildStreamEvent, b as AgentDeltaEvent, c as AgentErrorEvent, d as AgentErrorStreamEvent, e as AgentFinishEvent, f as AgentInput, h as AgentLifecycle, i as AgentMemoryCompactionEvent, j as AgentMemoryCompactionOptions, k as AgentOutcome, l as AgentPrompt, m as AgentResponse, n as AgentRunOptions, o as AgentRunSettings, p as AgentStartEvent, q as AgentSteerInput, r as AgentSteerReceipt, s as AgentStepFinishEvent, t as AgentStream, u as AgentStreamEvent, v as AgentToolCallDeltaEvent, w as AgentToolFinishEvent, x as AgentToolStartEvent } from '../types-
|
|
5
|
+
import { A as AgentBlockedOutcome, g as AgentInteractionOutcome } from '../types-ChH_bdtR.js';
|
|
6
|
+
export { a as AgentChildStreamEvent, b as AgentDeltaEvent, c as AgentErrorEvent, d as AgentErrorStreamEvent, e as AgentFinishEvent, f as AgentInput, h as AgentLifecycle, i as AgentMemoryCompactionEvent, j as AgentMemoryCompactionOptions, k as AgentOutcome, l as AgentPrompt, m as AgentResponse, n as AgentRunOptions, o as AgentRunSettings, p as AgentStartEvent, q as AgentSteerInput, r as AgentSteerReceipt, s as AgentStepFinishEvent, t as AgentStream, u as AgentStreamEvent, v as AgentToolCallDeltaEvent, w as AgentToolFinishEvent, x as AgentToolStartEvent } from '../types-ChH_bdtR.js';
|
|
7
7
|
import '../zod-schema-C7F4clpm.js';
|
|
8
8
|
import 'zod';
|
|
9
9
|
import '../types-DhkodEft.js';
|
package/dist/agent/index.js
CHANGED
|
@@ -2,14 +2,16 @@ import {
|
|
|
2
2
|
Agent,
|
|
3
3
|
createVectorContext,
|
|
4
4
|
isVectorContext
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-NMVCGWQY.js";
|
|
6
6
|
import "../chunk-OJBFDBLG.js";
|
|
7
7
|
import "../chunk-J6LVLV6P.js";
|
|
8
8
|
import "../chunk-XMVOBX43.js";
|
|
9
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-34EDX4ZL.js";
|
|
10
|
+
import "../chunk-KSKST3KP.js";
|
|
10
11
|
import "../chunk-YK4WAAS4.js";
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-OIB3URVG.js";
|
|
13
|
+
import "../chunk-LZD36ZAP.js";
|
|
14
|
+
import "../chunk-4EWTDOLR.js";
|
|
13
15
|
import {
|
|
14
16
|
AgentRunBlockedError,
|
|
15
17
|
AgentRunCancelledError,
|
|
@@ -4,7 +4,7 @@ import { Z as ZodSchema } from './zod-schema-C7F4clpm.js';
|
|
|
4
4
|
import { d as GuardrailPolicyInput, c as GuardrailPolicy } from './types-DhkodEft.js';
|
|
5
5
|
import { a as McpServer } from './types-DjqRHeAi.js';
|
|
6
6
|
import { E as MemoryStore, z as MemorySavePolicy, F as MemoryTokenCounter, n as MemoryCompactor, d as MemoryCompactionConflictRetryOptions, y as MemoryOptions, k as MemoryCompactionResult } from './types-CSYt7-It.js';
|
|
7
|
-
import { h as AgentLifecycle, F as AgentObservabilityOptions, n as AgentRunOptions, k as AgentOutcome, o as AgentRunSettings, t as AgentStream, j as AgentMemoryCompactionOptions } from './types-
|
|
7
|
+
import { h as AgentLifecycle, F as AgentObservabilityOptions, n as AgentRunOptions, k as AgentOutcome, o as AgentRunSettings, t as AgentStream, j as AgentMemoryCompactionOptions } from './types-ChH_bdtR.js';
|
|
8
8
|
import { A as AgentMiddleware } from './middleware-kcF8AusP.js';
|
|
9
9
|
import { A as AnyTool, T as Tool, c as ToolCallContext, N as NormalizedToolOutput } from './tool-BpqpoRSE.js';
|
|
10
10
|
import { AgentContinuation, AgentInteractionResponse } from './agent/interactions/index.js';
|
|
@@ -1,89 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
observerSnapshot
|
|
3
|
+
} from "./chunk-KSKST3KP.js";
|
|
1
4
|
import {
|
|
2
5
|
Usage
|
|
3
6
|
} from "./chunk-TB5EKZM7.js";
|
|
4
7
|
|
|
5
|
-
// src/observability/snapshot.ts
|
|
6
|
-
function observerSnapshot(value) {
|
|
7
|
-
if (containsError(value, /* @__PURE__ */ new WeakSet())) {
|
|
8
|
-
return cloneObserverFallback(value, /* @__PURE__ */ new WeakMap());
|
|
9
|
-
}
|
|
10
|
-
try {
|
|
11
|
-
return globalThis.structuredClone(value);
|
|
12
|
-
} catch {
|
|
13
|
-
return cloneObserverFallback(value, /* @__PURE__ */ new WeakMap());
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function cloneObserverFallback(value, seen) {
|
|
17
|
-
if (typeof value !== "object" || value === null) {
|
|
18
|
-
return value;
|
|
19
|
-
}
|
|
20
|
-
const existing = seen.get(value);
|
|
21
|
-
if (existing !== void 0) {
|
|
22
|
-
return existing;
|
|
23
|
-
}
|
|
24
|
-
if (Array.isArray(value)) {
|
|
25
|
-
const clone2 = [];
|
|
26
|
-
seen.set(value, clone2);
|
|
27
|
-
clone2.push(...value.map((item) => cloneObserverFallback(item, seen)));
|
|
28
|
-
return clone2;
|
|
29
|
-
}
|
|
30
|
-
if (value instanceof Date) {
|
|
31
|
-
return new Date(value.getTime());
|
|
32
|
-
}
|
|
33
|
-
if (value instanceof Error) {
|
|
34
|
-
const clone2 = Object.create(Object.getPrototypeOf(value));
|
|
35
|
-
seen.set(value, clone2);
|
|
36
|
-
Object.defineProperties(clone2, {
|
|
37
|
-
name: { configurable: true, writable: true, value: value.name },
|
|
38
|
-
message: { configurable: true, writable: true, value: value.message }
|
|
39
|
-
});
|
|
40
|
-
if (value.stack !== void 0) {
|
|
41
|
-
Object.defineProperty(clone2, "stack", {
|
|
42
|
-
configurable: true,
|
|
43
|
-
writable: true,
|
|
44
|
-
value: value.stack
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
if (value.cause !== void 0) {
|
|
48
|
-
Object.defineProperty(clone2, "cause", {
|
|
49
|
-
configurable: true,
|
|
50
|
-
writable: true,
|
|
51
|
-
value: cloneObserverFallback(value.cause, seen)
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
for (const key of Object.getOwnPropertyNames(value)) {
|
|
55
|
-
if (key === "name" || key === "message" || key === "stack" || key === "cause") continue;
|
|
56
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
57
|
-
if (descriptor === void 0) continue;
|
|
58
|
-
if ("value" in descriptor) {
|
|
59
|
-
descriptor.value = cloneObserverFallback(descriptor.value, seen);
|
|
60
|
-
}
|
|
61
|
-
Object.defineProperty(clone2, key, descriptor);
|
|
62
|
-
}
|
|
63
|
-
return clone2;
|
|
64
|
-
}
|
|
65
|
-
if (Object.getPrototypeOf(value) !== Object.prototype) {
|
|
66
|
-
return value;
|
|
67
|
-
}
|
|
68
|
-
const clone = {};
|
|
69
|
-
seen.set(value, clone);
|
|
70
|
-
for (const [key, item] of Object.entries(value)) {
|
|
71
|
-
clone[key] = cloneObserverFallback(item, seen);
|
|
72
|
-
}
|
|
73
|
-
return clone;
|
|
74
|
-
}
|
|
75
|
-
function containsError(value, seen) {
|
|
76
|
-
if (typeof value !== "object" || value === null) return false;
|
|
77
|
-
if (value instanceof Error) return true;
|
|
78
|
-
if (seen.has(value)) return false;
|
|
79
|
-
seen.add(value);
|
|
80
|
-
if (Array.isArray(value)) {
|
|
81
|
-
return value.some((item) => containsError(item, seen));
|
|
82
|
-
}
|
|
83
|
-
if (Object.getPrototypeOf(value) !== Object.prototype) return false;
|
|
84
|
-
return Object.values(value).some((item) => containsError(item, seen));
|
|
85
|
-
}
|
|
86
|
-
|
|
87
8
|
// src/observability/group.ts
|
|
88
9
|
var AgentObserverDispatchError = class extends AggregateError {
|
|
89
10
|
phase;
|
|
@@ -321,4 +242,4 @@ export {
|
|
|
321
242
|
AgentObserverDispatchError,
|
|
322
243
|
startAgentRunObservers
|
|
323
244
|
};
|
|
324
|
-
//# sourceMappingURL=chunk-
|
|
245
|
+
//# sourceMappingURL=chunk-34EDX4ZL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/observability/group.ts"],"sourcesContent":["import { Usage } from \"../completion\";\nimport { observerSnapshot } from \"./snapshot\";\nimport type {\n AgentGenerationEndArgs,\n AgentGenerationErrorArgs,\n AgentGenerationObserver,\n AgentGenerationStartArgs,\n AgentGenerationUpdateArgs,\n AgentObserverErrorPolicy,\n AgentObserverMap,\n AgentRunEndArgs,\n AgentRunErrorArgs,\n AgentRunEventArgs,\n AgentRunObserver,\n AgentRunStartArgs,\n AgentToolEndArgs,\n AgentToolErrorArgs,\n AgentToolObserver,\n AgentToolStartArgs,\n AgentToolStreamEventArgs,\n AgentToolSuspendedArgs,\n AgentTraceInfo,\n} from \"./types\";\n\nexport type AgentObserverFailure = {\n readonly observer: string;\n readonly error: unknown;\n};\n\nexport class AgentObserverDispatchError extends AggregateError {\n readonly phase: string;\n readonly failures: readonly AgentObserverFailure[];\n\n constructor(phase: string, failures: readonly AgentObserverFailure[]) {\n super(\n failures.map((failure) => failure.error),\n `Agent observer ${phase} failed for ${failures.map((failure) => failure.observer).join(\", \")}.`,\n );\n this.name = \"AgentObserverDispatchError\";\n this.phase = phase;\n this.failures = Object.freeze([...failures]);\n }\n}\n\ntype NamedObserver<T> = {\n readonly name: string;\n readonly observer: T;\n};\n\ntype ActiveNamedObserver<T> = NamedObserver<T> & {\n terminal: boolean;\n};\n\nexport async function startAgentRunObservers(\n observers: AgentObserverMap,\n args: AgentRunStartArgs,\n options: {\n readonly primaryTrace?: string | undefined;\n readonly errorPolicy: AgentObserverErrorPolicy;\n },\n): Promise<ActiveAgentRunObservers> {\n const runObservers: ActiveNamedObserver<AgentRunObserver>[] = [];\n const failures: AgentObserverFailure[] = [];\n for (const [name, observer] of Object.entries(observers)) {\n try {\n const runObserver = await observer.startRun(observerSnapshot(args));\n if (runObserver !== undefined) {\n runObservers.push({ name, observer: runObserver, terminal: false });\n }\n } catch (error) {\n failures.push({ observer: name, error });\n }\n }\n if (options.errorPolicy === \"throw\" && failures.length > 0) {\n const startupError = new AgentObserverDispatchError(\"startRun\", failures);\n const cleanupFailures = await terminateObservers(runObservers, (observer) =>\n observer.error?.(\n observerSnapshot({\n status: \"failed\",\n error: startupError,\n usage: Usage.empty(),\n messages: [...args.history, args.prompt],\n }),\n ),\n );\n throw new AgentObserverDispatchError(\"startRun\", [...failures, ...cleanupFailures]);\n }\n return new ActiveAgentRunObservers(runObservers, options);\n}\n\nexport class ActiveAgentRunObservers {\n readonly trace: AgentTraceInfo | undefined;\n\n constructor(\n private readonly runObservers: readonly ActiveNamedObserver<AgentRunObserver>[],\n private readonly options: {\n readonly primaryTrace?: string | undefined;\n readonly errorPolicy: AgentObserverErrorPolicy;\n },\n ) {\n const primary =\n options.primaryTrace === undefined\n ? undefined\n : runObservers.find((entry) => entry.name === options.primaryTrace);\n this.trace =\n primary?.observer.trace === undefined\n ? undefined\n : Object.freeze({ observer: primary.name, ...primary.observer.trace });\n }\n\n async startGeneration(args: AgentGenerationStartArgs): Promise<ActiveGenerationObservers> {\n const generationObservers: ActiveNamedObserver<AgentGenerationObserver>[] = [];\n const failures: AgentObserverFailure[] = [];\n for (const entry of this.runObservers) {\n if (entry.observer.startGeneration === undefined) continue;\n try {\n const observer = await entry.observer.startGeneration(observerSnapshot(args));\n if (observer !== undefined) {\n generationObservers.push({ name: entry.name, observer, terminal: false });\n }\n } catch (error) {\n failures.push({ observer: entry.name, error });\n }\n }\n if (this.options.errorPolicy === \"throw\" && failures.length > 0) {\n const startupError = new AgentObserverDispatchError(\"startGeneration\", failures);\n const cleanupFailures = await terminateObservers(generationObservers, (observer) =>\n observer.error?.(observerSnapshot({ turn: args.turn, error: startupError })),\n );\n throw new AgentObserverDispatchError(\"startGeneration\", [...failures, ...cleanupFailures]);\n }\n return new ActiveGenerationObservers(generationObservers, this.options.errorPolicy);\n }\n\n async startTool(args: AgentToolStartArgs): Promise<ActiveToolObservers> {\n const toolObservers: ActiveNamedObserver<AgentToolObserver>[] = [];\n const failures: AgentObserverFailure[] = [];\n for (const entry of this.runObservers) {\n if (entry.observer.startTool === undefined) continue;\n try {\n const observer = await entry.observer.startTool(observerSnapshot(args));\n if (observer !== undefined) {\n toolObservers.push({ name: entry.name, observer, terminal: false });\n }\n } catch (error) {\n failures.push({ observer: entry.name, error });\n }\n }\n if (this.options.errorPolicy === \"throw\" && failures.length > 0) {\n const startupError = new AgentObserverDispatchError(\"startTool\", failures);\n const cleanupFailures = await terminateObservers(toolObservers, (observer) =>\n observer.error?.(observerSnapshot({ ...args, error: startupError })),\n );\n throw new AgentObserverDispatchError(\"startTool\", [...failures, ...cleanupFailures]);\n }\n return new ActiveToolObservers(toolObservers, this.options.errorPolicy);\n }\n\n async end(args: AgentRunEndArgs): Promise<void> {\n await dispatchTerminalObservers(\n this.runObservers,\n \"end\",\n (observer) => observer.end(observerSnapshot(args)),\n this.options.errorPolicy,\n );\n }\n\n async error(args: AgentRunErrorArgs): Promise<void> {\n await dispatchTerminalObservers(\n this.runObservers,\n \"error\",\n (observer) => observer.error?.(observerSnapshot(args)),\n \"ignore\",\n );\n }\n\n async event(args: AgentRunEventArgs): Promise<void> {\n await dispatchObservers(\n this.runObservers,\n \"event\",\n (observer) => observer.event?.(observerSnapshot(args)),\n this.options.errorPolicy,\n );\n }\n}\n\nexport class ActiveGenerationObservers {\n constructor(\n private readonly observers: readonly ActiveNamedObserver<AgentGenerationObserver>[],\n private readonly errorPolicy: AgentObserverErrorPolicy,\n ) {}\n\n async end(args: AgentGenerationEndArgs): Promise<void> {\n await dispatchTerminalObservers(\n this.observers,\n \"generation.end\",\n (observer) => observer.end(observerSnapshot(args)),\n this.errorPolicy,\n );\n }\n\n async error(args: AgentGenerationErrorArgs): Promise<void> {\n await dispatchTerminalObservers(\n this.observers,\n \"generation.error\",\n (observer) => observer.error?.(observerSnapshot(args)),\n \"ignore\",\n );\n }\n\n async update(args: AgentGenerationUpdateArgs): Promise<void> {\n await dispatchObservers(\n this.observers,\n \"generation.update\",\n (observer) => observer.update?.(observerSnapshot(args)),\n this.errorPolicy,\n );\n }\n}\n\nexport class ActiveToolObservers {\n constructor(\n private readonly observers: readonly ActiveNamedObserver<AgentToolObserver>[],\n private readonly errorPolicy: AgentObserverErrorPolicy,\n ) {}\n\n async streamEvent(args: AgentToolStreamEventArgs): Promise<void> {\n await dispatchObservers(\n this.observers,\n \"tool.streamEvent\",\n (observer) => observer.streamEvent?.(observerSnapshot(args)),\n this.errorPolicy,\n );\n }\n\n async end(args: AgentToolEndArgs): Promise<void> {\n await dispatchTerminalObservers(\n this.observers,\n \"tool.end\",\n (observer) => observer.end(observerSnapshot(args)),\n this.errorPolicy,\n );\n }\n\n async suspend(args: AgentToolSuspendedArgs): Promise<void> {\n await dispatchTerminalObservers(\n this.observers,\n \"tool.suspend\",\n (observer) => observer.suspend?.(observerSnapshot(args)),\n this.errorPolicy,\n );\n }\n\n async error(args: AgentToolErrorArgs): Promise<void> {\n await dispatchTerminalObservers(\n this.observers,\n \"tool.error\",\n (observer) => observer.error?.(observerSnapshot(args)),\n \"ignore\",\n );\n }\n}\n\nasync function dispatchObservers<T>(\n observers: readonly NamedObserver<T>[],\n phase: string,\n dispatch: (observer: T) => void | Promise<void> | undefined,\n errorPolicy: AgentObserverErrorPolicy,\n): Promise<void> {\n const failures: AgentObserverFailure[] = [];\n for (const entry of observers) {\n try {\n await dispatch(entry.observer);\n } catch (error) {\n failures.push({ observer: entry.name, error });\n }\n }\n throwObserverFailures(phase, failures, errorPolicy);\n}\n\nasync function dispatchTerminalObservers<T>(\n observers: readonly ActiveNamedObserver<T>[],\n phase: string,\n dispatch: (observer: T) => void | Promise<void> | undefined,\n errorPolicy: AgentObserverErrorPolicy,\n): Promise<void> {\n const failures = await terminateObservers(observers, dispatch);\n throwObserverFailures(phase, failures, errorPolicy);\n}\n\nasync function terminateObservers<T>(\n observers: readonly ActiveNamedObserver<T>[],\n dispatch: (observer: T) => void | Promise<void> | undefined,\n): Promise<AgentObserverFailure[]> {\n const failures: AgentObserverFailure[] = [];\n for (const entry of observers) {\n if (entry.terminal) continue;\n entry.terminal = true;\n try {\n await dispatch(entry.observer);\n } catch (error) {\n failures.push({ observer: entry.name, error });\n }\n }\n return failures;\n}\n\nfunction throwObserverFailures(\n phase: string,\n failures: readonly AgentObserverFailure[],\n errorPolicy: AgentObserverErrorPolicy,\n): void {\n if (errorPolicy === \"throw\" && failures.length > 0) {\n throw new AgentObserverDispatchError(phase, failures);\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
// src/documents/chunk-text.ts
|
|
2
|
+
function chunkText(options) {
|
|
3
|
+
const validated = validateOptions(options);
|
|
4
|
+
if (validated.text.length === 0) {
|
|
5
|
+
return [];
|
|
6
|
+
}
|
|
7
|
+
if (validated.strategy === "fixed") {
|
|
8
|
+
return chunkFixed(validated.text, validated.maxSize, validated.overlap);
|
|
9
|
+
}
|
|
10
|
+
const ranges = resolveRecursiveRanges(
|
|
11
|
+
validated.text,
|
|
12
|
+
{ start: 0, end: validated.text.length },
|
|
13
|
+
validated.maxSize,
|
|
14
|
+
validated.separators
|
|
15
|
+
);
|
|
16
|
+
return applyRecursiveOverlap(validated.text, ranges, validated.maxSize, validated.overlap);
|
|
17
|
+
}
|
|
18
|
+
function validateOptions(options) {
|
|
19
|
+
if (typeof options !== "object" || options === null) {
|
|
20
|
+
throw new TypeError("chunkText options must be an object");
|
|
21
|
+
}
|
|
22
|
+
const value = options;
|
|
23
|
+
if (typeof value.text !== "string") {
|
|
24
|
+
throw new TypeError("chunkText text must be a string");
|
|
25
|
+
}
|
|
26
|
+
if (!Number.isSafeInteger(value.maxSize) || value.maxSize <= 0) {
|
|
27
|
+
throw new RangeError("chunkText maxSize must be a positive safe integer");
|
|
28
|
+
}
|
|
29
|
+
const maxSize = value.maxSize;
|
|
30
|
+
const overlap = value.overlap === void 0 ? 0 : value.overlap;
|
|
31
|
+
if (!Number.isSafeInteger(overlap) || overlap < 0 || overlap >= maxSize) {
|
|
32
|
+
throw new RangeError(
|
|
33
|
+
"chunkText overlap must be a non-negative safe integer smaller than maxSize"
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
if (value.strategy === "fixed") {
|
|
37
|
+
if ("separators" in value) {
|
|
38
|
+
throw new TypeError("chunkText fixed strategy does not accept separators");
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
text: value.text,
|
|
42
|
+
strategy: "fixed",
|
|
43
|
+
maxSize,
|
|
44
|
+
overlap
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (value.strategy !== "recursive") {
|
|
48
|
+
throw new TypeError('chunkText strategy must be either "fixed" or "recursive"');
|
|
49
|
+
}
|
|
50
|
+
if (!Array.isArray(value.separators) || value.separators.length === 0) {
|
|
51
|
+
throw new TypeError("chunkText recursive separators must be a non-empty array");
|
|
52
|
+
}
|
|
53
|
+
const separators = value.separators;
|
|
54
|
+
const seen = /* @__PURE__ */ new Set();
|
|
55
|
+
for (const separator of separators) {
|
|
56
|
+
if (typeof separator !== "string" || separator.length === 0) {
|
|
57
|
+
throw new TypeError("chunkText recursive separators must contain non-empty strings");
|
|
58
|
+
}
|
|
59
|
+
if (seen.has(separator)) {
|
|
60
|
+
throw new TypeError("chunkText recursive separators must not contain duplicates");
|
|
61
|
+
}
|
|
62
|
+
seen.add(separator);
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
text: value.text,
|
|
66
|
+
strategy: "recursive",
|
|
67
|
+
maxSize,
|
|
68
|
+
overlap,
|
|
69
|
+
separators
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function chunkFixed(text, maxSize, overlap) {
|
|
73
|
+
const chunks = [];
|
|
74
|
+
let start = 0;
|
|
75
|
+
while (start < text.length) {
|
|
76
|
+
const end = Math.min(start + maxSize, text.length);
|
|
77
|
+
chunks.push(createChunk(text, chunks.length, start, end));
|
|
78
|
+
if (end === text.length) {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
start = end - overlap;
|
|
82
|
+
}
|
|
83
|
+
return chunks;
|
|
84
|
+
}
|
|
85
|
+
function resolveRecursiveRanges(text, initialRange, maxSize, separators) {
|
|
86
|
+
const resolved = [];
|
|
87
|
+
const pending = [
|
|
88
|
+
{ range: initialRange, separatorIndex: 0 }
|
|
89
|
+
];
|
|
90
|
+
while (pending.length > 0) {
|
|
91
|
+
const current = pending.pop();
|
|
92
|
+
if (current === void 0) {
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
if (current.range.end - current.range.start <= maxSize) {
|
|
96
|
+
resolved.push(current.range);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
let pieces;
|
|
100
|
+
let nextSeparatorIndex = separators.length;
|
|
101
|
+
for (let index = current.separatorIndex; index < separators.length; index += 1) {
|
|
102
|
+
const candidate = splitAfterSeparator(text, current.range, separators[index]);
|
|
103
|
+
if (candidate.length > 1) {
|
|
104
|
+
pieces = candidate;
|
|
105
|
+
nextSeparatorIndex = index + 1;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (pieces === void 0) {
|
|
110
|
+
resolved.push(...hardSplit(current.range, maxSize));
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
for (let index = pieces.length - 1; index >= 0; index -= 1) {
|
|
114
|
+
pending.push({ range: pieces[index], separatorIndex: nextSeparatorIndex });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return resolved;
|
|
118
|
+
}
|
|
119
|
+
function splitAfterSeparator(text, range, separator) {
|
|
120
|
+
const ranges = [];
|
|
121
|
+
let start = range.start;
|
|
122
|
+
let searchFrom = range.start;
|
|
123
|
+
while (searchFrom < range.end) {
|
|
124
|
+
const separatorStart = text.indexOf(separator, searchFrom);
|
|
125
|
+
if (separatorStart < 0 || separatorStart + separator.length > range.end) {
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
const end = separatorStart + separator.length;
|
|
129
|
+
if (end > start) {
|
|
130
|
+
ranges.push({ start, end });
|
|
131
|
+
}
|
|
132
|
+
start = end;
|
|
133
|
+
searchFrom = end;
|
|
134
|
+
}
|
|
135
|
+
if (start < range.end) {
|
|
136
|
+
ranges.push({ start, end: range.end });
|
|
137
|
+
}
|
|
138
|
+
return ranges;
|
|
139
|
+
}
|
|
140
|
+
function hardSplit(range, maxSize) {
|
|
141
|
+
const ranges = [];
|
|
142
|
+
for (let start = range.start; start < range.end; start += maxSize) {
|
|
143
|
+
ranges.push({ start, end: Math.min(start + maxSize, range.end) });
|
|
144
|
+
}
|
|
145
|
+
return ranges;
|
|
146
|
+
}
|
|
147
|
+
function applyRecursiveOverlap(text, ranges, maxSize, overlap) {
|
|
148
|
+
const boundaries = ranges.map((range) => range.end);
|
|
149
|
+
const chunks = [];
|
|
150
|
+
let start = 0;
|
|
151
|
+
let previousEnd = 0;
|
|
152
|
+
while (start < text.length) {
|
|
153
|
+
const limit = Math.min(start + maxSize, text.length);
|
|
154
|
+
const boundary = findLastBoundaryAtMost(boundaries, limit);
|
|
155
|
+
const end = boundary !== void 0 && boundary > previousEnd ? boundary : limit;
|
|
156
|
+
chunks.push(createChunk(text, chunks.length, start, end));
|
|
157
|
+
if (end === text.length) {
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
previousEnd = end;
|
|
161
|
+
start = Math.max(0, end - overlap);
|
|
162
|
+
}
|
|
163
|
+
return chunks;
|
|
164
|
+
}
|
|
165
|
+
function findLastBoundaryAtMost(boundaries, limit) {
|
|
166
|
+
let low = 0;
|
|
167
|
+
let high = boundaries.length;
|
|
168
|
+
while (low < high) {
|
|
169
|
+
const middle = low + Math.floor((high - low) / 2);
|
|
170
|
+
if (boundaries[middle] <= limit) {
|
|
171
|
+
low = middle + 1;
|
|
172
|
+
} else {
|
|
173
|
+
high = middle;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return boundaries[low - 1];
|
|
177
|
+
}
|
|
178
|
+
function createChunk(text, index, start, end) {
|
|
179
|
+
return { index, text: text.slice(start, end), start, end };
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/documents/pdf.ts
|
|
183
|
+
async function extractPdfText(options) {
|
|
184
|
+
if (typeof options !== "object" || options === null) {
|
|
185
|
+
throw new TypeError("extractPdfText options must be an object");
|
|
186
|
+
}
|
|
187
|
+
if (!(options.data instanceof Uint8Array)) {
|
|
188
|
+
throw new TypeError("extractPdfText data must be a Uint8Array");
|
|
189
|
+
}
|
|
190
|
+
if (options.abortSignal !== void 0 && !isAbortSignal(options.abortSignal)) {
|
|
191
|
+
throw new TypeError("extractPdfText abortSignal must be an AbortSignal");
|
|
192
|
+
}
|
|
193
|
+
const { abortSignal } = options;
|
|
194
|
+
abortSignal?.throwIfAborted();
|
|
195
|
+
const data = new Uint8Array(options.data);
|
|
196
|
+
const pdfjs = await loadPdfjs();
|
|
197
|
+
abortSignal?.throwIfAborted();
|
|
198
|
+
const loadingTask = pdfjs.getDocument({ data });
|
|
199
|
+
let destroyPromise;
|
|
200
|
+
const destroy = () => {
|
|
201
|
+
destroyPromise ??= loadingTask.destroy();
|
|
202
|
+
return destroyPromise;
|
|
203
|
+
};
|
|
204
|
+
const abort = createAbortPromise(abortSignal, destroy);
|
|
205
|
+
return runWithCleanup(
|
|
206
|
+
async () => {
|
|
207
|
+
const document = await abort.wait(loadingTask.promise);
|
|
208
|
+
const pages = [];
|
|
209
|
+
for (let pageNumber = 1; pageNumber <= document.numPages; pageNumber += 1) {
|
|
210
|
+
abortSignal?.throwIfAborted();
|
|
211
|
+
const page = await abort.wait(document.getPage(pageNumber));
|
|
212
|
+
const content = await abort.wait(page.getTextContent());
|
|
213
|
+
pages.push({ pageNumber, text: extractPageText(content.items) });
|
|
214
|
+
}
|
|
215
|
+
return { pages };
|
|
216
|
+
},
|
|
217
|
+
async () => {
|
|
218
|
+
abort.dispose();
|
|
219
|
+
await destroy();
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
async function loadPdfjs() {
|
|
224
|
+
try {
|
|
225
|
+
return await import("pdfjs-dist/legacy/build/pdf.mjs");
|
|
226
|
+
} catch (cause) {
|
|
227
|
+
if (!isMissingPdfjsDependency(cause)) {
|
|
228
|
+
throw cause;
|
|
229
|
+
}
|
|
230
|
+
throw new Error(
|
|
231
|
+
'PDF extraction requires the optional "pdfjs-dist" package. Install it in your application to use extractPdfText().',
|
|
232
|
+
{ cause }
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function isMissingPdfjsDependency(error) {
|
|
237
|
+
const seen = /* @__PURE__ */ new Set();
|
|
238
|
+
let current = error;
|
|
239
|
+
while (current instanceof Error && !seen.has(current)) {
|
|
240
|
+
seen.add(current);
|
|
241
|
+
if (current.message.includes("pdfjs-dist") && "code" in current && current.code === "ERR_MODULE_NOT_FOUND") {
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
current = "cause" in current ? current.cause : void 0;
|
|
245
|
+
}
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
async function runWithCleanup(operation, cleanup) {
|
|
249
|
+
let outcome;
|
|
250
|
+
try {
|
|
251
|
+
outcome = { ok: true, value: await operation() };
|
|
252
|
+
} catch (error) {
|
|
253
|
+
outcome = { ok: false, error };
|
|
254
|
+
}
|
|
255
|
+
let cleanupError;
|
|
256
|
+
let cleanupFailed = false;
|
|
257
|
+
try {
|
|
258
|
+
await cleanup();
|
|
259
|
+
} catch (error) {
|
|
260
|
+
cleanupFailed = true;
|
|
261
|
+
cleanupError = error;
|
|
262
|
+
}
|
|
263
|
+
if (!outcome.ok) {
|
|
264
|
+
if (cleanupFailed) {
|
|
265
|
+
throw new AggregateError(
|
|
266
|
+
[outcome.error, cleanupError],
|
|
267
|
+
"PDF extraction and cleanup both failed",
|
|
268
|
+
{ cause: outcome.error }
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
throw outcome.error;
|
|
272
|
+
}
|
|
273
|
+
if (cleanupFailed) {
|
|
274
|
+
throw cleanupError;
|
|
275
|
+
}
|
|
276
|
+
return outcome.value;
|
|
277
|
+
}
|
|
278
|
+
function isAbortSignal(value) {
|
|
279
|
+
if (typeof value !== "object" || value === null) {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
const candidate = value;
|
|
283
|
+
return typeof candidate.aborted === "boolean" && typeof candidate.addEventListener === "function" && typeof candidate.removeEventListener === "function" && typeof candidate.throwIfAborted === "function";
|
|
284
|
+
}
|
|
285
|
+
function extractPageText(items) {
|
|
286
|
+
let text = "";
|
|
287
|
+
for (const item of items) {
|
|
288
|
+
if (typeof item !== "object" || item === null) {
|
|
289
|
+
throw new TypeError("PDF text content contains a malformed item");
|
|
290
|
+
}
|
|
291
|
+
if (!("str" in item)) {
|
|
292
|
+
if ("type" in item && (item.type === "beginMarkedContent" || item.type === "beginMarkedContentProps" || item.type === "endMarkedContent")) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
throw new TypeError("PDF text content contains an unknown non-text item");
|
|
296
|
+
}
|
|
297
|
+
if (typeof item.str !== "string") {
|
|
298
|
+
throw new TypeError("PDF text content item str must be a string");
|
|
299
|
+
}
|
|
300
|
+
if (!("hasEOL" in item) || typeof item.hasEOL !== "boolean") {
|
|
301
|
+
throw new TypeError("PDF text content item hasEOL must be a boolean");
|
|
302
|
+
}
|
|
303
|
+
text += item.str;
|
|
304
|
+
if (item.hasEOL) {
|
|
305
|
+
text += "\n";
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return text;
|
|
309
|
+
}
|
|
310
|
+
function createAbortPromise(abortSignal, destroy) {
|
|
311
|
+
if (abortSignal === void 0) {
|
|
312
|
+
return {
|
|
313
|
+
wait: (promise) => promise,
|
|
314
|
+
dispose: () => void 0
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
let rejectAbort;
|
|
318
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
319
|
+
rejectAbort = reject;
|
|
320
|
+
});
|
|
321
|
+
const onAbort = () => {
|
|
322
|
+
void destroy();
|
|
323
|
+
rejectAbort?.(
|
|
324
|
+
abortSignal.reason ?? new DOMException("The operation was aborted", "AbortError")
|
|
325
|
+
);
|
|
326
|
+
};
|
|
327
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
328
|
+
if (abortSignal.aborted) {
|
|
329
|
+
onAbort();
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
wait: (promise) => Promise.race([promise, aborted]),
|
|
333
|
+
dispose: () => abortSignal.removeEventListener("abort", onAbort)
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// src/documents/text-document.ts
|
|
338
|
+
function chunkTextDocuments(options) {
|
|
339
|
+
if (typeof options !== "object" || options === null) {
|
|
340
|
+
throw new TypeError("chunkTextDocuments options must contain a documents array");
|
|
341
|
+
}
|
|
342
|
+
const documents = options.documents;
|
|
343
|
+
if (!Array.isArray(documents)) {
|
|
344
|
+
throw new TypeError("chunkTextDocuments options must contain a documents array");
|
|
345
|
+
}
|
|
346
|
+
const ids = /* @__PURE__ */ new Set();
|
|
347
|
+
const chunks = [];
|
|
348
|
+
for (const document of documents) {
|
|
349
|
+
validateDocument(document, ids);
|
|
350
|
+
chunks.push(...chunkDocument(document, options.chunking));
|
|
351
|
+
}
|
|
352
|
+
return chunks;
|
|
353
|
+
}
|
|
354
|
+
function validateDocument(document, ids) {
|
|
355
|
+
if (typeof document !== "object" || document === null) {
|
|
356
|
+
throw new TypeError("Text documents must be objects");
|
|
357
|
+
}
|
|
358
|
+
if (typeof document.id !== "string" || document.id.length === 0) {
|
|
359
|
+
throw new TypeError("Text document ids must be non-empty strings");
|
|
360
|
+
}
|
|
361
|
+
if (ids.has(document.id)) {
|
|
362
|
+
throw new TypeError(`Duplicate text document id: ${document.id}`);
|
|
363
|
+
}
|
|
364
|
+
if (typeof document.text !== "string" || document.text.length === 0) {
|
|
365
|
+
throw new TypeError(`Text document ${document.id} must contain non-empty text`);
|
|
366
|
+
}
|
|
367
|
+
ids.add(document.id);
|
|
368
|
+
}
|
|
369
|
+
function chunkDocument(document, chunking) {
|
|
370
|
+
if (chunking === void 0 || chunking.strategy === "none") {
|
|
371
|
+
return [createDocumentChunk(document, 0, document.text)];
|
|
372
|
+
}
|
|
373
|
+
const textChunks = chunkDocumentText(document.text, chunking);
|
|
374
|
+
return textChunks.map((chunk) => createDocumentChunk(document, chunk.index, chunk.text));
|
|
375
|
+
}
|
|
376
|
+
function chunkDocumentText(text, chunking) {
|
|
377
|
+
const overlap = chunking.overlap ?? 0;
|
|
378
|
+
if (chunking.strategy === "fixed") {
|
|
379
|
+
return chunkText({
|
|
380
|
+
text,
|
|
381
|
+
strategy: "fixed",
|
|
382
|
+
maxSize: chunking.maxSize,
|
|
383
|
+
overlap
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
return chunkText({
|
|
387
|
+
text,
|
|
388
|
+
strategy: "recursive",
|
|
389
|
+
maxSize: chunking.maxSize,
|
|
390
|
+
overlap,
|
|
391
|
+
separators: chunking.separators
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
function createDocumentChunk(document, index, text) {
|
|
395
|
+
const chunk = {
|
|
396
|
+
id: `${document.id}:chunk:${index}`,
|
|
397
|
+
documentId: document.id,
|
|
398
|
+
index,
|
|
399
|
+
text
|
|
400
|
+
};
|
|
401
|
+
if (document.metadata === void 0) {
|
|
402
|
+
return chunk;
|
|
403
|
+
}
|
|
404
|
+
return { ...chunk, metadata: document.metadata };
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
export {
|
|
408
|
+
chunkText,
|
|
409
|
+
extractPdfText,
|
|
410
|
+
chunkTextDocuments
|
|
411
|
+
};
|
|
412
|
+
//# sourceMappingURL=chunk-4EWTDOLR.js.map
|