Skip to content
12 min read · 2,387 words

Class: SpooledMarkdownArtifact ​

Defined in: src/lib/classes/spooled_markdown_artifact.ts:139

A @nhtio/adk!SpooledArtifact specialisation that adds markdown-aware structural queries.

Remarks ​

Designed for large markdown documents where loading the full content into memory is impractical. The structural index (heading positions, code block positions) is built by a single line-by-line scan of the @nhtio/adk!SpoolReader without retaining any content. Only the tiny metadata index and the parsed frontmatter object are cached.

Content retrieval is always bounded — use cat(start, end) or the startLine/endLine parameters on inline methods to fetch only the lines you need.

Inline methods (md_links, md_images, md_text, md_ast) accept optional line-range arguments. Without a range they read the full document — documented trade-off, caller responsibility to bound the range for large documents.

The processor always applies remark-gfm (tables, task lists, strikethrough, autolinks) in addition to standard CommonMark and YAML frontmatter.

Extends ​

Constructors ​

Constructor ​

ts
new SpooledMarkdownArtifact(reader: SpoolReader): SpooledMarkdownArtifact;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:146

Parameters ​

ParameterTypeDescription
readerSpoolReaderThe backing store to read from.

Returns ​

SpooledMarkdownArtifact

Overrides ​

SpooledArtifact.constructor

Properties ​

PropertyModifierTypeDescriptionOverridesDefined in
toolMethodsstaticreadonly ToolMethodDescriptor[]The markdown-specific artifact-query descriptors this class adds on top of the base set. Remarks Lists artifact_md_frontmatter, artifact_md_headings, artifact_md_code_blocks, artifact_md_sections, artifact_md_links, artifact_md_images, artifact_md_text, artifact_md_ast. The base seven descriptors (artifact_head, etc.) are NOT included here — they are forged separately by SpooledMarkdownArtifact.forgeTools, which calls SpooledArtifact.forgeTools(ctx) to produce the base-narrowed tools and then registers its own markdown tools on the result. Downstream consumers building custom subclasses should follow the same pattern: own only your own descriptors; override forgeTools to compose with the base output.SpooledArtifact.toolMethodssrc/lib/classes/spooled_markdown_artifact.ts:176

Methods ​

[ENCODE_METHOD]() ​

ts
ENCODE_METHOD: unknown;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:665

Serialise this SpooledMarkdownArtifact into an @nhtio/encoder snapshot — the reader handle.

Returns ​

unknown

A snapshot consumed by SpooledMarkdownArtifact.[DECODE_METHOD].

Remarks ​

The structural index and frontmatter caches are derived and not encoded. Round-trips via SpooledMarkdownArtifact.[DECODE_METHOD].

Overrides ​

SpooledArtifact.[ENCODE_METHOD]


asString() ​

ts
asString(): Promise<string>;

Defined in: src/lib/classes/spooled_artifact.ts:677

Returns the full artifact body as a single byte-faithful string.

Returns ​

Promise<string>

The full content as a single string.

Remarks ​

Round-trip faithful to whatever bytes the @nhtio/adk!SpoolReader was constructed over — preserves trailing newlines and non-\n line terminators that SpooledArtifact.cat discards via its line-based view. This is the canonical primitive for "inline the artifact content directly into a message" use cases.

asString() and the static forgeTools(ctx) factory on each subclass are independent alternatives — a consumer chooses per turn whether to inline the body in a message (await tc.results.asString()) or hand the model query tools (SpooledArtifact.forgeTools(ctx)). Neither calls the other; either works with neither.

Inherited from ​

SpooledArtifact.asString


byteLength() ​

ts
byteLength(): Promise<number>;

Defined in: src/lib/classes/spooled_artifact.ts:548

Returns the total byte length of the underlying data.

Returns ​

Promise<number>

The byte length as reported by the @nhtio/adk!SpoolReader.

Inherited from ​

SpooledArtifact.byteLength


cat() ​

ts
cat(start?: number, end?: number): Promise<string[]>;

Defined in: src/lib/classes/spooled_artifact.ts:529

Returns lines from the artifact, optionally bounded to a range.

Parameters ​

ParameterTypeDescription
start?number0-based start line index (inclusive). Defaults to 0.
end?number0-based end line index (exclusive). Defaults to lineCount().

Returns ​

Promise<string[]>

Array of line strings in the requested range.

Remarks ​

Without arguments, returns all lines — equivalent to POSIX cat. With start and/or end, behaves like Array.prototype.slice: start defaults to 0, end defaults to the total line count, and only lines in [start, end) are fetched from the backing store. For large artifacts, prefer a bounded range or SpooledArtifact.head / SpooledArtifact.tail.

Inherited from ​

SpooledArtifact.cat


estimateHandleTokens() ​

ts
estimateHandleTokens(
   callId: string,
   encoding:
  | "gpt2"
  | "r50k_base"
  | "p50k_base"
  | "p50k_edit"
  | "cl100k_base"
  | "o200k_base"
  | "gemini"
  | "gemma"
  | "llama2"
  | "claude",
   renderer?: (input: {
  artifact: unknown;
  byteLength: number;
  callId: string;
  encoding?: string;
  estimatedTokens?: number;
  lineCount: number;
}) => string): number;

Defined in: src/lib/classes/spooled_artifact.ts:594

Estimates tokens for the exact handle-body metadata rendered for this artifact.

The fallback renderer is an interim core-safe implementation. Its output is deliberately specified here for fan-in parity: the lines are the fixed prose and metadata strings below, with one \n separator, and method entries formatted as - name — description (or - name). The canonical renderer in chat_common should eventually delegate to this builder rather than maintain a second copy.

Parameters ​

ParameterTypeDescription
callIdstringThe turn-local artifact identifier.
encoding| "gpt2" | "r50k_base" | "p50k_base" | "p50k_edit" | "cl100k_base" | "o200k_base" | "gemini" | "gemma" | "llama2" | "claude"The token encoding used for estimation.
renderer?(input: { artifact: unknown; byteLength: number; callId: string; encoding?: string; estimatedTokens?: number; lineCount: number; }) => stringOptional renderer overriding the interim default.

Returns ​

number

A synchronous token estimate.

Inherited from ​

SpooledArtifact.estimateHandleTokens


estimateTokens() ​

ts
estimateTokens(encoding:
  | "gpt2"
  | "r50k_base"
  | "p50k_base"
  | "p50k_edit"
  | "cl100k_base"
  | "o200k_base"
  | "gemini"
  | "gemma"
  | "llama2"
| "claude"): Promise<number>;

Defined in: src/lib/classes/spooled_artifact.ts:656

Estimates the total token count of the artifact under encoding.

Parameters ​

ParameterTypeDescription
encoding| "gpt2" | "r50k_base" | "p50k_base" | "p50k_edit" | "cl100k_base" | "o200k_base" | "gemini" | "gemma" | "llama2" | "claude"The encoding identifier to use for counting.

Returns ​

Promise<number>

The estimated number of tokens.

Remarks ​

Reads the full byte-faithful content via SpooledArtifact.asString (which delegates to @nhtio/adk!SpoolReader.readAll) and delegates to @nhtio/adk!Tokenizable.estimateTokens. The estimate therefore reflects the actual source bytes — including trailing newlines and non-\n line terminators that the line-based SpooledArtifact.cat view would otherwise discard or misrepresent.

Inherited from ​

SpooledArtifact.estimateTokens


grep() ​

ts
grep(pattern: RegExp): Promise<string[]>;

Defined in: src/lib/classes/spooled_artifact.ts:501

Returns all lines that match pattern.

Parameters ​

ParameterTypeDescription
patternRegExpThe regular expression to test each line against.

Returns ​

Promise<string[]>

Array of matching line strings, in order.

Remarks ​

Behaves like POSIX grep: each line is tested against the pattern and included in the result when it matches. The pattern is applied as a JavaScript RegExp; flags (e.g. case- insensitivity) should be encoded in the expression itself.

Stateful flags (g, y) on the supplied RegExp would normally cause pattern.test() to advance lastIndex across calls, producing skipped matches and order-dependent results. To keep the per-line semantics stateless, grep resets pattern.lastIndex to 0 before each line test. The forged artifact_grep tool also rejects g and y flags up-front at schema validation time.

Inherited from ​

SpooledArtifact.grep


hasSizeHints() ​

ts
hasSizeHints(): boolean;

Defined in: src/lib/classes/spooled_artifact.ts:567

Returns whether producer-computed size metadata is available.

Returns ​

boolean

true when SpooledArtifact._setSizeHints has populated the cache.

Inherited from ​

SpooledArtifact.hasSizeHints


ts
head(n?: number): Promise<string[]>;

Defined in: src/lib/classes/spooled_artifact.ts:448

Returns the first n lines of the artifact.

Parameters ​

ParameterTypeDefault valueDescription
nnumber10Number of lines to return. Defaults to 10.

Returns ​

Promise<string[]>

Array of line strings, without trailing newlines.

Remarks ​

If the artifact contains fewer than n lines, all available lines are returned. Matches the behaviour of POSIX head -n.

Inherited from ​

SpooledArtifact.head


lineCount() ​

ts
lineCount(): Promise<number>;

Defined in: src/lib/classes/spooled_artifact.ts:576

Returns the total number of lines in the artifact.

Returns ​

Promise<number>

The line count as reported by the @nhtio/adk!SpoolReader.

Inherited from ​

SpooledArtifact.lineCount


md_ast() ​

ts
md_ast(startLine?: number, endLine?: number): Promise<Root>;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:589

Returns the full MDAST Root for the specified line range.

Parameters ​

ParameterTypeDescription
startLine?number0-based start line (inclusive). Defaults to 0.
endLine?number0-based end line (exclusive). Defaults to lineCount().

Returns ​

Promise<Root>

Remarks ​

Without a range, reads the full document — for large documents, use SpooledMarkdownArtifact.md_sections to locate sections and pass bounded line ranges here.


md_code_blocks() ​

ts
md_code_blocks(lang?: string): Promise<MarkdownCodeEntry[]>;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:544

Returns all fenced code block entries, optionally filtered by language identifier.

Parameters ​

ParameterTypeDescription
lang?stringWhen provided, only blocks with this exact lang identifier are returned. Pass an empty string to match blocks with no lang identifier.

Returns ​

Promise<MarkdownCodeEntry[]>

Remarks ​

Returns line-range metadata only — no content is fetched. Use cat(entry.startLine + 1, entry.endLine) to retrieve the code body (excluding fence lines).


md_frontmatter() ​

ts
md_frontmatter(): Promise<
  | Record<string, unknown>
| undefined>;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:488

Returns the parsed YAML frontmatter, or undefined when no frontmatter block is present.

Returns ​

Promise< | Record<string, unknown> | undefined>

Remarks ​

Short-circuits after reading the frontmatter block — never reads the document body. Caches the result so subsequent calls are free. The result is undefined (not an empty object) when no frontmatter is found, distinguishing "no frontmatter" from "empty frontmatter".


md_headings() ​

ts
md_headings(depth?: 1 | 2 | 3 | 4 | 5 | 6): Promise<MarkdownHeadingEntry[]>;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:528

Returns all headings in document order, optionally filtered by depth.

Parameters ​

ParameterTypeDescription
depth?1 | 2 | 3 | 4 | 5 | 6When provided, only headings at this ATX depth (1–6) are returned.

Returns ​

Promise<MarkdownHeadingEntry[]>

Remarks ​

Uses the cached structural index — no content is fetched from the @nhtio/adk!SpoolReader.


md_images() ​

ts
md_images(startLine?: number, endLine?: number): Promise<{
  alt: string;
  title?: string;
  url: string;
}[]>;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:623

Returns all images in the specified line range.

Parameters ​

ParameterTypeDescription
startLine?number0-based start line (inclusive). Defaults to 0.
endLine?number0-based end line (exclusive). Defaults to lineCount().

Returns ​

Promise<{ alt: string; title?: string; url: string; }[]>


ts
md_links(startLine?: number, endLine?: number): Promise<{
  text: string;
  title?: string;
  url: string;
}[]>;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:600

Returns all inline and reference links in the specified line range.

Parameters ​

ParameterTypeDescription
startLine?number0-based start line (inclusive). Defaults to 0.
endLine?number0-based end line (exclusive). Defaults to lineCount().

Returns ​

Promise<{ text: string; title?: string; url: string; }[]>


md_sections() ​

ts
md_sections(depth?: 1 | 2 | 3 | 4 | 5 | 6): Promise<MarkdownSection[]>;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:563

Returns document sections derived from the structural index.

Parameters ​

ParameterTypeDescription
depth?1 | 2 | 3 | 4 | 5 | 6When provided, only sections at this ATX depth (1–6) are returned.

Returns ​

Promise<MarkdownSection[]>

Remarks ​

Returns only line-range metadata — body content is never fetched. To retrieve the body of a section, call cat(section.bodyStartLine, section.bodyEndLine + 1).

When depth is provided, only sections introduced by a heading at that depth are returned; deeper headings become part of the body.


md_text() ​

ts
md_text(startLine?: number, endLine?: number): Promise<string>;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:650

Returns all document text with markup stripped, for the specified line range.

Parameters ​

ParameterTypeDescription
startLine?number0-based start line (inclusive). Defaults to 0.
endLine?number0-based end line (exclusive). Defaults to lineCount().

Returns ​

Promise<string>

Remarks ​

Uses mdast-util-to-string to extract plain text from the AST — code, link text, and alt text are included; markdown syntax is removed.


tail() ​

ts
tail(n?: number): Promise<string[]>;

Defined in: src/lib/classes/spooled_artifact.ts:471

Returns the last n lines of the artifact.

Parameters ​

ParameterTypeDefault valueDescription
nnumber10Number of lines to return. Defaults to 10.

Returns ​

Promise<string[]>

Array of line strings, without trailing newlines.

Remarks ​

If the artifact contains fewer than n lines, all available lines are returned. Matches the behaviour of POSIX tail -n.

Inherited from ​

SpooledArtifact.tail


[DECODE_METHOD]() ​

ts
static DECODE_METHOD: SpooledMarkdownArtifact;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:676

Reconstruct a SpooledMarkdownArtifact from a SpooledMarkdownArtifact.[ENCODE_METHOD] snapshot.

Parameters ​

ParameterTypeDescription
dataunknownThe snapshot produced by SpooledMarkdownArtifact.[ENCODE_METHOD].

Returns ​

SpooledMarkdownArtifact

A fresh SpooledMarkdownArtifact backed by a freshly-resolved reader.

Overrides ​

SpooledArtifact.[DECODE_METHOD]


forgeTools() ​

ts
static forgeTools(ctx: DispatchContext): ToolRegistry;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:320

Forges base-class tools plus markdown-specific tools narrowed to SpooledMarkdownArtifact.

Parameters ​

ParameterType
ctxDispatchContext

Returns ​

ToolRegistry

Remarks ​

Standard subclass extension pattern: call SpooledArtifact.forgeTools(ctx) to produce the base seven artifact_* tools narrowed to any SpooledArtifact in the turn, then register one ArtifactTool per markdown-specific descriptor narrowed to markdown artifacts. Downstream consumers building their own subclasses should follow the same shape.

Overrides ​

SpooledArtifact.forgeTools


isSpooledArtifact() ​

ts
static isSpooledArtifact(value: unknown): value is SpooledArtifact;

Defined in: src/lib/classes/spooled_artifact.ts:408

Returns true if value is a SpooledArtifact instance (including any subclass).

Parameters ​

ParameterTypeDescription
valueunknownThe value to test.

Returns ​

value is SpooledArtifact

true when value is a SpooledArtifact instance.

Remarks ​

Uses the cross-realm-safe @nhtio/adk!isInstanceOf guard: instanceof first, then Symbol.hasInstance, then a constructor.name fallback. Subclass instances (e.g. @nhtio/adk!SpooledJsonArtifact) satisfy this guard because instanceof walks the prototype chain. The fallbacks handle the dual-module-copy case where two distinct SpooledArtifact classes coexist in the same realm (e.g. one bundled into a downstream library, one in the consumer's node_modules).

Inherited from ​

SpooledArtifact.isSpooledArtifact


isSpooledArtifactConstructor() ​

ts
static isSpooledArtifactConstructor(value: unknown): value is SpooledArtifactConstructor<SpooledArtifact>;

Defined in: src/lib/classes/spooled_artifact.ts:425

Returns true if value is a constructor function whose prototype chain includes SpooledArtifact (including SpooledArtifact itself).

Parameters ​

ParameterTypeDescription
valueunknownThe value to test.

Returns ​

value is SpooledArtifactConstructor<SpooledArtifact>

true when value is a constructor for SpooledArtifact or a subclass.

Remarks ​

Used by @nhtio/adk!Tool to validate the optional artifactConstructor field. Performs an instanceof-based check on the prototype chain; falls back to a duck-type test that looks for the canonical SpooledArtifact instance methods on value.prototype for cross-realm safety (constructors passed from a different module copy or VM context).

Inherited from ​

SpooledArtifact.isSpooledArtifactConstructor


isSpooledMarkdownArtifact() ​

ts
static isSpooledMarkdownArtifact(value: unknown): value is SpooledMarkdownArtifact;

Defined in: src/lib/classes/spooled_markdown_artifact.ts:159

Returns true if value is a SpooledMarkdownArtifact instance.

Parameters ​

ParameterType
valueunknown

Returns ​

value is SpooledMarkdownArtifact

Remarks ​

Uses the cross-realm-safe @nhtio/adk!isInstanceOf guard: instanceof first, then Symbol.hasInstance, then a constructor.name fallback. Matches the pattern used by every other class guard in the ADK; safe against the dual-module-copy case where two distinct SpooledMarkdownArtifact classes coexist in the same realm.