markform 0.1.5 → 0.1.6
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 +76 -53
- package/dist/ai-sdk.mjs +1 -1
- package/dist/{apply-BCCiJzQr.mjs → apply-DMQl-VVd.mjs} +3 -23
- package/dist/bin.mjs +4 -4
- package/dist/{cli-D469amuk.mjs → cli-CXjkdym_.mjs} +80 -12
- package/dist/cli.mjs +4 -4
- package/dist/index.d.mts +60 -6
- package/dist/index.mjs +2 -2
- package/dist/{shared-BqPnYXrn.mjs → shared-DRlgu2ZJ.mjs} +1 -1
- package/dist/{shared-CZsyShck.mjs → shared-u22MtBRo.mjs} +1 -1
- package/dist/{src-Df0XX7UB.mjs → src-o_5TSoHQ.mjs} +87 -18
- package/docs/markform-apis.md +52 -1
- package/docs/markform-spec.md +9 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,23 +1,57 @@
|
|
|
1
1
|
# Markform
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Markform** turns Markdown documents into executable specifications for structured data
|
|
4
|
+
collection.
|
|
5
|
+
Define fields, validation rules, and instructions in a single `.form.md` file
|
|
6
|
+
that is readable by humans, parseable by machines, and fillable by LLM agents.
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
The core idea: **a form combines structure, unstructured context, and memory in a simple
|
|
9
|
+
text document**. Users can give inputs via UIs or CLI. Agents can fill fields
|
|
10
|
+
incrementally via tools or APIs.
|
|
11
|
+
Validation catches errors early and humans can review or intervene at any point.
|
|
12
|
+
The entire workflow is visible in a token-friendly text file you can read, diff, and
|
|
13
|
+
version control.
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
validation rules.
|
|
12
|
-
Fields, validation rules, and instructions are encoded as Markdoc tags.
|
|
15
|
+
Syntax is [Markdoc](https://github.com/markdoc/markdoc), which is Markdown extended with
|
|
16
|
+
`{% tag %}` annotations, so LLMs are already quite good at writing Markform docs.
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
agent
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
## Why?
|
|
19
|
+
|
|
20
|
+
Many agent workflow frameworks emphasize *prompts* and the *flow* of information (the
|
|
21
|
+
*how*) over the desired *structure* of the results (the *what*). Markform lets you build
|
|
22
|
+
agent workflows by structuring and validating *what* you want (the structure of
|
|
23
|
+
information, validations, and reviews encoded in a form) instead of *how* to run a
|
|
24
|
+
workflow as code (via explicit workflows or just an unstructured swarm of agents).
|
|
25
|
+
|
|
26
|
+
For centuries, humans have used paper forms to systematize and manage processes.
|
|
27
|
+
A well-designed form with instructions, field definitions, and validations is a concise
|
|
28
|
+
way to share context: background knowledge, goals, process rules, and memories.
|
|
29
|
+
I don’t think AI changes this essential aspect of knowledge work.
|
|
30
|
+
It’s time to bring bureaucracy to the agents.
|
|
31
|
+
|
|
32
|
+
There’s one more key benefit to this approach: LLMs are good at writing forms!
|
|
33
|
+
Because the syntax is just Markdown with Jinja-style tags, agents can convert an
|
|
34
|
+
informal Markdown doc describing a process to a precise Markform process easily.
|
|
35
|
+
|
|
36
|
+
(For more, see [the FAQ](#faq).)
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Try filling in one of a few example forms without installing.
|
|
42
|
+
# First set OPENAI_API_KEY or ANTHROPIC_API_KEY in environment or .env file
|
|
43
|
+
# to try the research examples.
|
|
44
|
+
npx markform examples
|
|
45
|
+
|
|
46
|
+
# Read the docs
|
|
47
|
+
npx markform # CLI help
|
|
48
|
+
npx markform readme # This file
|
|
49
|
+
npx markform docs # Quick start for humans or agents to write Markforms
|
|
50
|
+
npx markform spec # Read the full spec
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This lets you walk through a form interactively from the CLI, with the option to have an
|
|
54
|
+
agent fill in parts of the form.
|
|
21
55
|
|
|
22
56
|
## Installation
|
|
23
57
|
|
|
@@ -31,17 +65,6 @@ npm install -g markform
|
|
|
31
65
|
npm install markform
|
|
32
66
|
```
|
|
33
67
|
|
|
34
|
-
## Quick Start
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
# Try it without installing
|
|
38
|
-
npx markform examples
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
This walks you through an example form interactively, with optional AI agent filling.
|
|
42
|
-
You’ll need at least one [API key](#supported-providers) form a provider with a model
|
|
43
|
-
that supports web search to have LLMs fill in forms.
|
|
44
|
-
|
|
45
68
|
## Example: Research a Movie
|
|
46
69
|
|
|
47
70
|
### Form Definition
|
|
@@ -156,38 +179,24 @@ Convicted banker Andy Dufresne is sent to Shawshank State Penitentiary, where he
|
|
|
156
179
|
|
|
157
180
|
### More Example Forms
|
|
158
181
|
|
|
159
|
-
The package includes example forms
|
|
160
|
-
[`examples/`](https://github.com/jlevy/markform/tree/main/packages/markform/examples).
|
|
182
|
+
The package includes example forms.
|
|
161
183
|
View them with `markform examples --list` or try these interactively:
|
|
162
184
|
|
|
163
|
-
- [`
|
|
185
|
+
- [`simple.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/simple/simple.form.md)
|
|
186
|
+
\- Basic form demonstrating all field kinds.
|
|
187
|
+
|
|
188
|
+
- [`movie-research-minimal.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research-minimal.form.md)
|
|
164
189
|
\- The quick example above.
|
|
165
190
|
|
|
166
|
-
- [`movie-research
|
|
191
|
+
- [`movie-research-basic.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research-basic.form.md)
|
|
167
192
|
\- Standard movie research with IMDB, Rotten Tomatoes, Metacritic.
|
|
168
193
|
|
|
169
|
-
- [`movie-research
|
|
194
|
+
- [`movie-research-deep.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research-deep.form.md)
|
|
170
195
|
\- Comprehensive movie analysis with streaming, box office, analysis.
|
|
171
196
|
|
|
172
|
-
- [`
|
|
173
|
-
\- Basic form demonstrating all field kinds.
|
|
174
|
-
|
|
175
|
-
- [`earnings-analysis/earnings-analysis.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/earnings-analysis/earnings-analysis.form.md)
|
|
197
|
+
- [`earnings-analysis.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/earnings-analysis/earnings-analysis.form.md)
|
|
176
198
|
\- Financial analysis form.
|
|
177
199
|
|
|
178
|
-
## Why?
|
|
179
|
-
|
|
180
|
-
Many agent workflow frameworks emphasize the *flow* of information (the *how*) over its
|
|
181
|
-
*structure* (the *what*). But the *how* is constantly changing.
|
|
182
|
-
|
|
183
|
-
What we often really want is to express *desired structure and validation rules* for
|
|
184
|
-
content directly in a way that provides clear context to agents and humans at all times.
|
|
185
|
-
|
|
186
|
-
Humans have for centuries used paper forms to systematize and manage processes.
|
|
187
|
-
The key insight of Markform is that the most natural way to express the state and
|
|
188
|
-
context for a workflow is often *forms*. Just as Markdown is a transparent format for
|
|
189
|
-
documents, Markform is a transparent text format for structured information.
|
|
190
|
-
|
|
191
200
|
## CLI Commands
|
|
192
201
|
|
|
193
202
|
### Explore Examples
|
|
@@ -415,6 +424,19 @@ const result = await generateText({
|
|
|
415
424
|
|
|
416
425
|
## FAQ
|
|
417
426
|
|
|
427
|
+
### Can you say more why this is a good idea?
|
|
428
|
+
|
|
429
|
+
Yes! I’ve come to believe forms are a missing piece of the workflow problem with agents.
|
|
430
|
+
For deep research or complex multi-step workflows, key pieces need to be *precisely
|
|
431
|
+
controlled*, *domain-specific*, and *always improving*. You need precise documentation
|
|
432
|
+
on the key intermediate states and final output from an AI pipeline.
|
|
433
|
+
|
|
434
|
+
But you don’t want structure in a GUI (not token friendly) or code (hard to update) or
|
|
435
|
+
dependent on the whims of a thinking model (changes all the time).
|
|
436
|
+
Forms define these pieces and are easy to edit.
|
|
437
|
+
All other choices can be left to the agents themselves, with the structure and
|
|
438
|
+
validations enforced by the form-filling tools the agents use.
|
|
439
|
+
|
|
418
440
|
### Is this mature?
|
|
419
441
|
|
|
420
442
|
No! I just wrote it.
|
|
@@ -467,7 +489,8 @@ This enables powerful AI workflows that assemble information in a defined struct
|
|
|
467
489
|
|
|
468
490
|
### Does anything like this already exist?
|
|
469
491
|
|
|
470
|
-
Not
|
|
492
|
+
Not that I have seen.
|
|
493
|
+
The closest alternatives are:
|
|
471
494
|
|
|
472
495
|
- Plain Markdown docs can be used as templates and filled in by agents.
|
|
473
496
|
These are more expressive, but it is hard to edit them programmatically or use LLMs to
|
|
@@ -481,13 +504,13 @@ Not really. The closest alternatives are:
|
|
|
481
504
|
human-friendly UI. But these do not have a human-friendly text format for use by
|
|
482
505
|
agents as well as humans.
|
|
483
506
|
|
|
484
|
-
| Approach | Has GUI | Human-readable
|
|
507
|
+
| Approach | Has GUI | Human-readable source format | Agent-editable | APIs and validation rules |
|
|
485
508
|
| --- | :---: | :---: | :---: | :---: |
|
|
486
509
|
| Plain Markdown | ☑️ existing tools | ✅ | ⚠️ fragile | ❌ |
|
|
487
|
-
| JSON with schema |
|
|
510
|
+
| JSON with schema | ⚠️ in some apps | ⚠️ um it’s JSON | ✅ | ✅ |
|
|
488
511
|
| SaaS tools (Typeform, Docusign, PDF forms) | ✅ | ⚠️ rarely | ⚠️ if they add it | ⚠️ if they add it |
|
|
489
|
-
| Excel/Google Sheets | ✅ | ❌ .xlsx | ⚠️ with tools | ✅ |
|
|
490
|
-
| **Markform** | ☑️ existing tools | ✅ | ✅ | ✅ |
|
|
512
|
+
| Excel/Google Sheets | ✅ | ❌ .csv (poor) or .xlsx (worse) | ⚠️ with tools | ✅ with some coding |
|
|
513
|
+
| **Markform** | ☑️ existing tools | ✅ | ✅ with this package | ✅ with this package |
|
|
491
514
|
|
|
492
515
|
### What are example use cases?
|
|
493
516
|
|
package/dist/ai-sdk.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { L as PatchSchema } from "./coreTypes-pyctKRgc.mjs";
|
|
2
|
-
import { r as inspect, t as applyPatches, u as serialize } from "./apply-
|
|
2
|
+
import { r as inspect, t as applyPatches, u as serialize } from "./apply-DMQl-VVd.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
//#region src/integrations/vercelAiSdkTools.ts
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { resolve } from "node:path";
|
|
2
|
-
|
|
3
1
|
//#region src/llms.ts
|
|
4
2
|
/**
|
|
5
3
|
* Parse a model ID string into provider and model components for display.
|
|
@@ -113,13 +111,6 @@ function getWebSearchConfig(provider) {
|
|
|
113
111
|
//#endregion
|
|
114
112
|
//#region src/settings.ts
|
|
115
113
|
/**
|
|
116
|
-
* Global settings and constants for Markform.
|
|
117
|
-
*
|
|
118
|
-
* This file consolidates non-changing default values that were previously
|
|
119
|
-
* scattered across the codebase. These are NOT runtime configurable - they
|
|
120
|
-
* are compile-time constants.
|
|
121
|
-
*/
|
|
122
|
-
/**
|
|
123
114
|
* The current Markform spec version in full notation (e.g., "MF/0.1").
|
|
124
115
|
* This is distinct from npm package version and tracks the format that
|
|
125
116
|
* .form.md files conform to.
|
|
@@ -165,25 +156,14 @@ function parseRolesFlag(raw) {
|
|
|
165
156
|
*/
|
|
166
157
|
const DEFAULT_PRIORITY = "medium";
|
|
167
158
|
/**
|
|
168
|
-
* The default port for the serve command.
|
|
169
|
-
*/
|
|
170
|
-
const DEFAULT_PORT = 3344;
|
|
171
|
-
/**
|
|
172
159
|
* Default forms directory for CLI output (relative to cwd).
|
|
173
160
|
* Commands write form outputs here to avoid cluttering the workspace.
|
|
174
161
|
*/
|
|
175
162
|
const DEFAULT_FORMS_DIR = "./forms";
|
|
176
163
|
/**
|
|
177
|
-
*
|
|
178
|
-
* Uses the provided override or falls back to DEFAULT_FORMS_DIR.
|
|
179
|
-
*
|
|
180
|
-
* @param override Optional override path from CLI --forms-dir option
|
|
181
|
-
* @param cwd Base directory for resolving relative paths (defaults to process.cwd())
|
|
182
|
-
* @returns Absolute path to the forms directory
|
|
164
|
+
* The default port for the serve command.
|
|
183
165
|
*/
|
|
184
|
-
|
|
185
|
-
return resolve(cwd, override ?? DEFAULT_FORMS_DIR);
|
|
186
|
-
}
|
|
166
|
+
const DEFAULT_PORT = 3344;
|
|
187
167
|
/**
|
|
188
168
|
* Default maximum turns for the fill harness.
|
|
189
169
|
* Prevents runaway loops during agent execution.
|
|
@@ -2824,4 +2804,4 @@ function applyPatches(form, patches) {
|
|
|
2824
2804
|
}
|
|
2825
2805
|
|
|
2826
2806
|
//#endregion
|
|
2827
|
-
export {
|
|
2807
|
+
export { SUGGESTED_LLMS as A, DEFAULT_ROLE_INSTRUCTIONS as C, deriveReportPath as D, deriveExportPath as E, parseModelIdForDisplay as F, formatSuggestedLlms as M, getWebSearchConfig as N, detectFileType as O, hasWebSearchSupport as P, DEFAULT_ROLES as S, USER_ROLE as T, DEFAULT_MAX_TURNS as _, computeAllSummaries as a, DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN as b, computeStructureSummary as c, serializeRawMarkdown as d, serializeReportMarkdown as f, DEFAULT_MAX_PATCHES_PER_TURN as g, DEFAULT_MAX_ISSUES_PER_TURN as h, validate as i, WEB_SEARCH_CONFIG as j, parseRolesFlag as k, isFormComplete as l, DEFAULT_FORMS_DIR as m, getFieldsForRoles as n, computeFormState as o, AGENT_ROLE as p, inspect as r, computeProgressSummary as s, applyPatches as t, serialize as u, DEFAULT_PORT as v, REPORT_EXTENSION as w, DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN as x, DEFAULT_PRIORITY as y };
|
package/dist/bin.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "./coreTypes-pyctKRgc.mjs";
|
|
3
|
-
import "./apply-
|
|
4
|
-
import "./src-
|
|
3
|
+
import "./apply-DMQl-VVd.mjs";
|
|
4
|
+
import "./src-o_5TSoHQ.mjs";
|
|
5
5
|
import "./session-uF0e6m6k.mjs";
|
|
6
|
-
import "./
|
|
7
|
-
import
|
|
6
|
+
import { t as runCli } from "./cli-CXjkdym_.mjs";
|
|
7
|
+
import "./shared-DRlgu2ZJ.mjs";
|
|
8
8
|
import { resolve } from "node:path";
|
|
9
9
|
import { existsSync } from "node:fs";
|
|
10
10
|
import { config } from "dotenv";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { L as PatchSchema } from "./coreTypes-pyctKRgc.mjs";
|
|
2
|
-
import { A as
|
|
3
|
-
import { a as resolveHarnessConfig, c as getProviderNames, f as createMockAgent, i as runResearch, l as resolveModel, m as createHarness, s as getProviderInfo, t as VERSION, u as createLiveAgent, w as parseForm } from "./src-
|
|
2
|
+
import { A as SUGGESTED_LLMS, D as deriveReportPath, E as deriveExportPath, F as parseModelIdForDisplay, M as formatSuggestedLlms, O as detectFileType, P as hasWebSearchSupport, T as USER_ROLE, _ as DEFAULT_MAX_TURNS, b as DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN, d as serializeRawMarkdown, f as serializeReportMarkdown, g as DEFAULT_MAX_PATCHES_PER_TURN, h as DEFAULT_MAX_ISSUES_PER_TURN, j as WEB_SEARCH_CONFIG, k as parseRolesFlag, m as DEFAULT_FORMS_DIR, p as AGENT_ROLE, r as inspect, t as applyPatches, u as serialize, v as DEFAULT_PORT, w as REPORT_EXTENSION, x as DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN } from "./apply-DMQl-VVd.mjs";
|
|
3
|
+
import { a as resolveHarnessConfig, c as getProviderNames, f as createMockAgent, i as runResearch, l as resolveModel, m as createHarness, s as getProviderInfo, t as VERSION, u as createLiveAgent, w as parseForm } from "./src-o_5TSoHQ.mjs";
|
|
4
4
|
import { n as serializeSession } from "./session-uF0e6m6k.mjs";
|
|
5
|
-
import { a as formatPath, c as logError, d as logTiming, f as logVerbose, g as writeFile, i as formatOutput, l as logInfo, m as readFile$1, n as createSpinner, o as getCommandContext, p as logWarn, r as ensureFormsDir, s as logDryRun, t as OUTPUT_FORMATS, u as logSuccess } from "./shared-
|
|
5
|
+
import { a as formatPath, c as logError, d as logTiming, f as logVerbose, g as writeFile, i as formatOutput, l as logInfo, m as readFile$1, n as createSpinner, o as getCommandContext, p as logWarn, r as ensureFormsDir, s as logDryRun, t as OUTPUT_FORMATS, u as logSuccess } from "./shared-DRlgu2ZJ.mjs";
|
|
6
6
|
import YAML from "yaml";
|
|
7
|
-
import { basename, dirname, join, resolve } from "node:path";
|
|
8
7
|
import { Command } from "commander";
|
|
9
8
|
import pc from "picocolors";
|
|
9
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
10
10
|
import { existsSync, readFileSync } from "node:fs";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
12
|
import { readFile } from "node:fs/promises";
|
|
@@ -14,6 +14,27 @@ import * as p from "@clack/prompts";
|
|
|
14
14
|
import { exec, spawn } from "node:child_process";
|
|
15
15
|
import { createServer } from "node:http";
|
|
16
16
|
|
|
17
|
+
//#region src/cli/lib/paths.ts
|
|
18
|
+
/**
|
|
19
|
+
* Path utilities for CLI commands.
|
|
20
|
+
*
|
|
21
|
+
* This module contains Node.js-dependent path utilities that are only used
|
|
22
|
+
* by CLI code. Keeping these separate from settings.ts allows the core
|
|
23
|
+
* library to remain Node.js-free.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the forms directory path to an absolute path.
|
|
27
|
+
* Uses the provided override or falls back to DEFAULT_FORMS_DIR.
|
|
28
|
+
*
|
|
29
|
+
* @param override Optional override path from CLI --forms-dir option
|
|
30
|
+
* @param cwd Base directory for resolving relative paths (defaults to process.cwd())
|
|
31
|
+
* @returns Absolute path to the forms directory
|
|
32
|
+
*/
|
|
33
|
+
function getFormsDir(override, cwd = process.cwd()) {
|
|
34
|
+
return resolve(cwd, override ?? DEFAULT_FORMS_DIR);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
17
38
|
//#region src/cli/commands/apis.ts
|
|
18
39
|
/**
|
|
19
40
|
* Get the path to the markform-apis.md file.
|
|
@@ -2101,6 +2122,39 @@ function registerExportCommand(program) {
|
|
|
2101
2122
|
});
|
|
2102
2123
|
}
|
|
2103
2124
|
|
|
2125
|
+
//#endregion
|
|
2126
|
+
//#region src/cli/lib/fillCallbacks.ts
|
|
2127
|
+
/**
|
|
2128
|
+
* Create FillCallbacks for CLI commands.
|
|
2129
|
+
*
|
|
2130
|
+
* Provides spinner feedback during tool execution (especially web search).
|
|
2131
|
+
* Only implements tool callbacks - turn/LLM callbacks are handled by CLI's
|
|
2132
|
+
* own logging which has richer context.
|
|
2133
|
+
*
|
|
2134
|
+
* @param spinner - Active spinner handle to update
|
|
2135
|
+
* @param ctx - Command context for verbose logging
|
|
2136
|
+
* @returns FillCallbacks with onToolStart and onToolEnd
|
|
2137
|
+
*
|
|
2138
|
+
* @example
|
|
2139
|
+
* ```typescript
|
|
2140
|
+
* const spinner = createSpinner({ type: 'api', provider, model });
|
|
2141
|
+
* const callbacks = createCliToolCallbacks(spinner, ctx);
|
|
2142
|
+
* const agent = createLiveAgent({ model, callbacks, ... });
|
|
2143
|
+
* ```
|
|
2144
|
+
*/
|
|
2145
|
+
function createCliToolCallbacks(spinner, ctx) {
|
|
2146
|
+
return {
|
|
2147
|
+
onToolStart: ({ name }) => {
|
|
2148
|
+
if (name.includes("search")) spinner.message(`🔍 Web search...`);
|
|
2149
|
+
logVerbose(ctx, ` Tool started: ${name}`);
|
|
2150
|
+
},
|
|
2151
|
+
onToolEnd: ({ name, durationMs, error }) => {
|
|
2152
|
+
if (error) logVerbose(ctx, ` Tool ${name} failed: ${error} (${durationMs}ms)`);
|
|
2153
|
+
else logVerbose(ctx, ` Tool ${name} completed (${durationMs}ms)`);
|
|
2154
|
+
}
|
|
2155
|
+
};
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2104
2158
|
//#endregion
|
|
2105
2159
|
//#region src/cli/commands/fill.ts
|
|
2106
2160
|
/**
|
|
@@ -2243,6 +2297,7 @@ function registerFillCommand(program) {
|
|
|
2243
2297
|
let mockPath;
|
|
2244
2298
|
let agentProvider;
|
|
2245
2299
|
let agentModelName;
|
|
2300
|
+
let currentSpinner = null;
|
|
2246
2301
|
if (options.mock) {
|
|
2247
2302
|
mockPath = resolve(options.mockSource);
|
|
2248
2303
|
logVerbose(ctx, `Reading mock source: ${mockPath}`);
|
|
@@ -2262,13 +2317,21 @@ function registerFillCommand(program) {
|
|
|
2262
2317
|
logVerbose(ctx, `Reading system prompt from: ${promptPath}`);
|
|
2263
2318
|
systemPrompt = await readFile$1(promptPath);
|
|
2264
2319
|
}
|
|
2320
|
+
const callbacks = createCliToolCallbacks({
|
|
2321
|
+
message: (msg) => currentSpinner?.message(msg),
|
|
2322
|
+
update: (context) => currentSpinner?.update(context),
|
|
2323
|
+
stop: (msg) => currentSpinner?.stop(msg),
|
|
2324
|
+
error: (msg) => currentSpinner?.error(msg),
|
|
2325
|
+
getElapsedMs: () => currentSpinner?.getElapsedMs() ?? 0
|
|
2326
|
+
}, ctx);
|
|
2265
2327
|
const primaryRole = targetRoles[0] === "*" ? AGENT_ROLE : targetRoles[0];
|
|
2266
2328
|
const liveAgent = createLiveAgent({
|
|
2267
2329
|
model,
|
|
2268
2330
|
provider,
|
|
2269
2331
|
systemPromptAddition: systemPrompt,
|
|
2270
2332
|
targetRole: primaryRole,
|
|
2271
|
-
enableWebSearch: true
|
|
2333
|
+
enableWebSearch: true,
|
|
2334
|
+
callbacks
|
|
2272
2335
|
});
|
|
2273
2336
|
agent = liveAgent;
|
|
2274
2337
|
logInfo(ctx, `Available tools: ${liveAgent.getAvailableToolNames().join(", ")}`);
|
|
@@ -2285,18 +2348,23 @@ function registerFillCommand(program) {
|
|
|
2285
2348
|
logInfo(ctx, `${pc.bold(`Turn ${stepResult.turnNumber}:`)} ${formatTurnIssues(stepResult.issues)}`);
|
|
2286
2349
|
while (!stepResult.isComplete && !harness.hasReachedMaxTurns()) {
|
|
2287
2350
|
let spinner = null;
|
|
2288
|
-
if (!options.mock && agentProvider && agentModelName && process.stdout.isTTY && !ctx.quiet)
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2351
|
+
if (!options.mock && agentProvider && agentModelName && process.stdout.isTTY && !ctx.quiet) {
|
|
2352
|
+
spinner = createSpinner({
|
|
2353
|
+
type: "api",
|
|
2354
|
+
provider: agentProvider,
|
|
2355
|
+
model: agentModelName,
|
|
2356
|
+
turnNumber: stepResult.turnNumber
|
|
2357
|
+
});
|
|
2358
|
+
currentSpinner = spinner;
|
|
2359
|
+
}
|
|
2294
2360
|
let response;
|
|
2295
2361
|
try {
|
|
2296
2362
|
response = await agent.generatePatches(stepResult.issues, harness.getForm(), harnessConfig.maxPatchesPerTurn);
|
|
2297
2363
|
spinner?.stop();
|
|
2364
|
+
currentSpinner = null;
|
|
2298
2365
|
} catch (error) {
|
|
2299
2366
|
spinner?.error("LLM call failed");
|
|
2367
|
+
currentSpinner = null;
|
|
2300
2368
|
throw error;
|
|
2301
2369
|
}
|
|
2302
2370
|
const { patches, stats } = response;
|
|
@@ -4037,7 +4105,7 @@ function registerResearchCommand(program) {
|
|
|
4037
4105
|
if (options.transcript && result.transcript) {
|
|
4038
4106
|
const { serializeSession: serializeSession$1 } = await import("./session-B_stoXQn.mjs");
|
|
4039
4107
|
const transcriptPath = outputPath.replace(/\.form\.md$/, ".session.yaml");
|
|
4040
|
-
const { writeFile: writeFile$1 } = await import("./shared-
|
|
4108
|
+
const { writeFile: writeFile$1 } = await import("./shared-u22MtBRo.mjs");
|
|
4041
4109
|
await writeFile$1(transcriptPath, serializeSession$1(result.transcript));
|
|
4042
4110
|
logInfo(ctx, `Transcript: ${transcriptPath}`);
|
|
4043
4111
|
}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "./coreTypes-pyctKRgc.mjs";
|
|
2
|
-
import "./apply-
|
|
3
|
-
import "./src-
|
|
2
|
+
import "./apply-DMQl-VVd.mjs";
|
|
3
|
+
import "./src-o_5TSoHQ.mjs";
|
|
4
4
|
import "./session-uF0e6m6k.mjs";
|
|
5
|
-
import "./
|
|
6
|
-
import
|
|
5
|
+
import { t as runCli } from "./cli-CXjkdym_.mjs";
|
|
6
|
+
import "./shared-DRlgu2ZJ.mjs";
|
|
7
7
|
|
|
8
8
|
export { runCli };
|
package/dist/index.d.mts
CHANGED
|
@@ -519,6 +519,57 @@ interface Agent {
|
|
|
519
519
|
*/
|
|
520
520
|
generatePatches(issues: InspectIssue[], form: ParsedForm, maxPatches: number): Promise<AgentResponse>;
|
|
521
521
|
}
|
|
522
|
+
/**
|
|
523
|
+
* Callbacks for observing form-filling execution in real-time.
|
|
524
|
+
*
|
|
525
|
+
* All callbacks are optional - implement only what you need.
|
|
526
|
+
* Callback errors are caught and ignored (won't abort fill).
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```typescript
|
|
530
|
+
* await fillForm({
|
|
531
|
+
* form: formMarkdown,
|
|
532
|
+
* model: 'anthropic/claude-sonnet-4-5',
|
|
533
|
+
* enableWebSearch: true,
|
|
534
|
+
* callbacks: {
|
|
535
|
+
* onTurnStart: ({ turnNumber }) => console.log(`Starting turn ${turnNumber}`),
|
|
536
|
+
* onToolStart: ({ name }) => spinner.message(`🔧 ${name}...`),
|
|
537
|
+
* onTurnComplete: (progress) => console.log(`Turn ${progress.turnNumber} done`),
|
|
538
|
+
* },
|
|
539
|
+
* });
|
|
540
|
+
* ```
|
|
541
|
+
*/
|
|
542
|
+
interface FillCallbacks {
|
|
543
|
+
/** Called when a turn begins */
|
|
544
|
+
onTurnStart?(turn: {
|
|
545
|
+
turnNumber: number;
|
|
546
|
+
issuesCount: number;
|
|
547
|
+
}): void;
|
|
548
|
+
/** Called when a turn completes */
|
|
549
|
+
onTurnComplete?(progress: TurnProgress): void;
|
|
550
|
+
/** Called before a tool executes */
|
|
551
|
+
onToolStart?(call: {
|
|
552
|
+
name: string;
|
|
553
|
+
input: unknown;
|
|
554
|
+
}): void;
|
|
555
|
+
/** Called after a tool completes */
|
|
556
|
+
onToolEnd?(call: {
|
|
557
|
+
name: string;
|
|
558
|
+
output: unknown;
|
|
559
|
+
durationMs: number;
|
|
560
|
+
error?: string;
|
|
561
|
+
}): void;
|
|
562
|
+
/** Called before an LLM request */
|
|
563
|
+
onLlmCallStart?(call: {
|
|
564
|
+
model: string;
|
|
565
|
+
}): void;
|
|
566
|
+
/** Called after an LLM response */
|
|
567
|
+
onLlmCallEnd?(call: {
|
|
568
|
+
model: string;
|
|
569
|
+
inputTokens: number;
|
|
570
|
+
outputTokens: number;
|
|
571
|
+
}): void;
|
|
572
|
+
}
|
|
522
573
|
/**
|
|
523
574
|
* Options for the fillForm function.
|
|
524
575
|
*/
|
|
@@ -544,8 +595,8 @@ interface FillOptions {
|
|
|
544
595
|
targetRoles?: string[];
|
|
545
596
|
/** Fill mode: 'continue' (skip filled) or 'overwrite' (re-fill) */
|
|
546
597
|
fillMode?: FillMode;
|
|
547
|
-
/**
|
|
548
|
-
|
|
598
|
+
/** Callbacks for observing form-filling execution */
|
|
599
|
+
callbacks?: FillCallbacks;
|
|
549
600
|
/** AbortSignal for cancellation */
|
|
550
601
|
signal?: AbortSignal;
|
|
551
602
|
/**
|
|
@@ -673,6 +724,7 @@ declare function createMockAgent(completedForm: ParsedForm): MockAgent;
|
|
|
673
724
|
* const result = await fillForm({
|
|
674
725
|
* form: formMarkdown,
|
|
675
726
|
* model: 'anthropic/claude-sonnet-4-5',
|
|
727
|
+
* enableWebSearch: true,
|
|
676
728
|
* inputContext: {
|
|
677
729
|
* company_name: 'Apple Inc.',
|
|
678
730
|
* },
|
|
@@ -680,8 +732,10 @@ declare function createMockAgent(completedForm: ParsedForm): MockAgent;
|
|
|
680
732
|
* ## Additional Context
|
|
681
733
|
* ${backgroundInfo}
|
|
682
734
|
* `,
|
|
683
|
-
*
|
|
684
|
-
*
|
|
735
|
+
* callbacks: {
|
|
736
|
+
* onTurnComplete: (progress) => {
|
|
737
|
+
* console.log(`Turn ${progress.turnNumber}: ${progress.requiredIssuesRemaining} remaining`);
|
|
738
|
+
* },
|
|
685
739
|
* },
|
|
686
740
|
* });
|
|
687
741
|
*
|
|
@@ -791,7 +845,7 @@ declare function validateResearchForm(form: ParsedForm): {
|
|
|
791
845
|
* This is the main library entry point that exports the core engine,
|
|
792
846
|
* types, and utilities for working with .form.md files.
|
|
793
847
|
*/
|
|
794
|
-
/** Markform version (
|
|
848
|
+
/** Markform version (injected at build time). */
|
|
795
849
|
declare const VERSION: string;
|
|
796
850
|
//#endregion
|
|
797
|
-
export { type AgentResponse, type AnswerState, AnswerStateSchema, type ApplyResult, ApplyResultSchema, type CellResponse, CellResponseSchema, type CellScopeRef, type CheckboxMode, CheckboxModeSchema, type CheckboxProgressCounts, CheckboxProgressCountsSchema, type CheckboxValue, CheckboxValueSchema, type CheckboxesField, CheckboxesFieldSchema, type CheckboxesValue, CheckboxesValueSchema, type ClearFieldPatch, ClearFieldPatchSchema, type CoerceInputContextResult, type CoercionResult, type ColumnTypeName, ColumnTypeNameSchema, type ComputedSummaries, type DateField, DateFieldSchema, type DateValue, DateValueSchema, type DocumentationBlock, DocumentationBlockSchema, type DocumentationTag, DocumentationTagSchema, type ExplicitCheckboxValue, ExplicitCheckboxValueSchema, type Field, type FieldBase, type FieldGroup, FieldGroupSchema, type FieldKind, FieldKindSchema, type FieldProgress, FieldProgressSchema, type FieldResponse, FieldResponseSchema, FieldSchema, type FieldScopeRef, type FieldValue, FieldValueSchema, type FillOptions, type FillResult, type FillStatus, FormHarness, type FormSchema, FormSchemaSchema, type FrontmatterHarnessConfig, type HarnessConfig, HarnessConfigSchema, type Id, type IdIndexEntry, IdSchema, type InputContext, type InspectIssue, InspectIssueSchema, type InspectOptions, type InspectResult, InspectResultSchema, type IssueReason, IssueReasonSchema, type IssueScope, IssueScopeSchema, type MarkformFrontmatter, MarkformFrontmatterSchema, MockAgent, type MultiCheckboxState, MultiCheckboxStateSchema, type MultiSelectField, MultiSelectFieldSchema, type MultiSelectValue, MultiSelectValueSchema, type NodeType, type NumberField, NumberFieldSchema, type NumberValue, NumberValueSchema, type Option, type OptionId, OptionIdSchema, OptionSchema, ParseError, type ParseScopeRefResult, type ParseTableResult, type ParsedForm, type ParsedRawTable, type ParsedScopeRef, type Patch, PatchSchema, type ProgressCounts, ProgressCountsSchema, type ProgressState, ProgressStateSchema, type ProgressSummary, ProgressSummarySchema, type QualifiedColumnRef, type QualifiedOptionRef, type QualifiedScopeRef, type RawFieldValue, type ResearchOptions, type ResearchResult, type ResearchStatus, type SerializeOptions, type SessionFinal, SessionFinalSchema, type SessionTranscript, SessionTranscriptSchema, type SessionTurn, SessionTurnSchema, type SessionTurnStats, type SetCheckboxesPatch, SetCheckboxesPatchSchema, type SetDatePatch, SetDatePatchSchema, type SetMultiSelectPatch, SetMultiSelectPatchSchema, type SetNumberPatch, SetNumberPatchSchema, type SetSingleSelectPatch, SetSingleSelectPatchSchema, type SetStringListPatch, SetStringListPatchSchema, type SetStringPatch, SetStringPatchSchema, type SetTablePatch, SetTablePatchSchema, type SetUrlListPatch, SetUrlListPatchSchema, type SetUrlPatch, SetUrlPatchSchema, type SetYearPatch, SetYearPatchSchema, type Severity, SeveritySchema, type SimpleCheckboxState, SimpleCheckboxStateSchema, type SingleSelectField, SingleSelectFieldSchema, type SingleSelectValue, SingleSelectValueSchema, type SourcePosition, SourcePositionSchema, type SourceRange, SourceRangeSchema, type StepResult, StepResultSchema, type StringField, StringFieldSchema, type StringListField, StringListFieldSchema, type StringListValue, StringListValueSchema, type StringValue, StringValueSchema, type StructureSummary, StructureSummarySchema, type TableColumn, TableColumnSchema, type TableField, TableFieldSchema, type TableRowPatch, TableRowPatchSchema, type TableRowResponse, TableRowResponseSchema, type TableValue, TableValueSchema, type TurnProgress, type TurnStats, type UrlField, UrlFieldSchema, type UrlListField, UrlListFieldSchema, type UrlListValue, UrlListValueSchema, type UrlValue, UrlValueSchema, VERSION, type ValidateOptions, type ValidateResult, type ValidationIssue, ValidationIssueSchema, type ValidatorContext, type ValidatorFn, type ValidatorRef, ValidatorRefSchema, type ValidatorRegistry, type YearField, YearFieldSchema, type YearValue, YearValueSchema, applyPatches, coerceInputContext, coerceToFieldPatch, computeAllSummaries, computeFormState, computeProgressSummary, computeStructureSummary, createHarness, createMockAgent, fillForm, findFieldById, getFieldId, inspect, isCellRef, isFieldRef, isFormComplete, isQualifiedRef, isResearchForm, parseCellValue, parseForm, parseMarkdownTable, parseRawTable, parseScopeRef, parseSession, resolveHarnessConfig, runResearch, serialize, serializeScopeRef, serializeSession, validate, validateResearchForm };
|
|
851
|
+
export { type AgentResponse, type AnswerState, AnswerStateSchema, type ApplyResult, ApplyResultSchema, type CellResponse, CellResponseSchema, type CellScopeRef, type CheckboxMode, CheckboxModeSchema, type CheckboxProgressCounts, CheckboxProgressCountsSchema, type CheckboxValue, CheckboxValueSchema, type CheckboxesField, CheckboxesFieldSchema, type CheckboxesValue, CheckboxesValueSchema, type ClearFieldPatch, ClearFieldPatchSchema, type CoerceInputContextResult, type CoercionResult, type ColumnTypeName, ColumnTypeNameSchema, type ComputedSummaries, type DateField, DateFieldSchema, type DateValue, DateValueSchema, type DocumentationBlock, DocumentationBlockSchema, type DocumentationTag, DocumentationTagSchema, type ExplicitCheckboxValue, ExplicitCheckboxValueSchema, type Field, type FieldBase, type FieldGroup, FieldGroupSchema, type FieldKind, FieldKindSchema, type FieldProgress, FieldProgressSchema, type FieldResponse, FieldResponseSchema, FieldSchema, type FieldScopeRef, type FieldValue, FieldValueSchema, type FillCallbacks, type FillOptions, type FillResult, type FillStatus, FormHarness, type FormSchema, FormSchemaSchema, type FrontmatterHarnessConfig, type HarnessConfig, HarnessConfigSchema, type Id, type IdIndexEntry, IdSchema, type InputContext, type InspectIssue, InspectIssueSchema, type InspectOptions, type InspectResult, InspectResultSchema, type IssueReason, IssueReasonSchema, type IssueScope, IssueScopeSchema, type MarkformFrontmatter, MarkformFrontmatterSchema, MockAgent, type MultiCheckboxState, MultiCheckboxStateSchema, type MultiSelectField, MultiSelectFieldSchema, type MultiSelectValue, MultiSelectValueSchema, type NodeType, type NumberField, NumberFieldSchema, type NumberValue, NumberValueSchema, type Option, type OptionId, OptionIdSchema, OptionSchema, ParseError, type ParseScopeRefResult, type ParseTableResult, type ParsedForm, type ParsedRawTable, type ParsedScopeRef, type Patch, PatchSchema, type ProgressCounts, ProgressCountsSchema, type ProgressState, ProgressStateSchema, type ProgressSummary, ProgressSummarySchema, type QualifiedColumnRef, type QualifiedOptionRef, type QualifiedScopeRef, type RawFieldValue, type ResearchOptions, type ResearchResult, type ResearchStatus, type SerializeOptions, type SessionFinal, SessionFinalSchema, type SessionTranscript, SessionTranscriptSchema, type SessionTurn, SessionTurnSchema, type SessionTurnStats, type SetCheckboxesPatch, SetCheckboxesPatchSchema, type SetDatePatch, SetDatePatchSchema, type SetMultiSelectPatch, SetMultiSelectPatchSchema, type SetNumberPatch, SetNumberPatchSchema, type SetSingleSelectPatch, SetSingleSelectPatchSchema, type SetStringListPatch, SetStringListPatchSchema, type SetStringPatch, SetStringPatchSchema, type SetTablePatch, SetTablePatchSchema, type SetUrlListPatch, SetUrlListPatchSchema, type SetUrlPatch, SetUrlPatchSchema, type SetYearPatch, SetYearPatchSchema, type Severity, SeveritySchema, type SimpleCheckboxState, SimpleCheckboxStateSchema, type SingleSelectField, SingleSelectFieldSchema, type SingleSelectValue, SingleSelectValueSchema, type SourcePosition, SourcePositionSchema, type SourceRange, SourceRangeSchema, type StepResult, StepResultSchema, type StringField, StringFieldSchema, type StringListField, StringListFieldSchema, type StringListValue, StringListValueSchema, type StringValue, StringValueSchema, type StructureSummary, StructureSummarySchema, type TableColumn, TableColumnSchema, type TableField, TableFieldSchema, type TableRowPatch, TableRowPatchSchema, type TableRowResponse, TableRowResponseSchema, type TableValue, TableValueSchema, type TurnProgress, type TurnStats, type UrlField, UrlFieldSchema, type UrlListField, UrlListFieldSchema, type UrlListValue, UrlListValueSchema, type UrlValue, UrlValueSchema, VERSION, type ValidateOptions, type ValidateResult, type ValidationIssue, ValidationIssueSchema, type ValidatorContext, type ValidatorFn, type ValidatorRef, ValidatorRefSchema, type ValidatorRegistry, type YearField, YearFieldSchema, type YearValue, YearValueSchema, applyPatches, coerceInputContext, coerceToFieldPatch, computeAllSummaries, computeFormState, computeProgressSummary, computeStructureSummary, createHarness, createMockAgent, fillForm, findFieldById, getFieldId, inspect, isCellRef, isFieldRef, isFormComplete, isQualifiedRef, isResearchForm, parseCellValue, parseForm, parseMarkdownTable, parseRawTable, parseScopeRef, parseSession, resolveHarnessConfig, runResearch, serialize, serializeScopeRef, serializeSession, validate, validateResearchForm };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { $ as SetUrlPatchSchema, A as MultiCheckboxStateSchema, B as ProgressSummarySchema, C as HarnessConfigSchema, Ct as ValidatorRefSchema, D as IssueReasonSchema, E as InspectResultSchema, F as OptionIdSchema, G as SetDatePatchSchema, H as SessionTranscriptSchema, I as OptionSchema, J as SetSingleSelectPatchSchema, K as SetMultiSelectPatchSchema, L as PatchSchema, M as MultiSelectValueSchema, N as NumberFieldSchema, O as IssueScopeSchema, P as NumberValueSchema, Q as SetUrlListPatchSchema, R as ProgressCountsSchema, S as FormSchemaSchema, St as ValidationIssueSchema, T as InspectIssueSchema, Tt as YearValueSchema, U as SessionTurnSchema, V as SessionFinalSchema, W as SetCheckboxesPatchSchema, X as SetStringPatchSchema, Y as SetStringListPatchSchema, Z as SetTablePatchSchema, _ as FieldKindSchema, _t as TableValueSchema, a as CheckboxProgressCountsSchema, at as SourcePositionSchema, b as FieldSchema, bt as UrlListValueSchema, c as CheckboxesValueSchema, ct as StringFieldSchema, d as DateFieldSchema, dt as StringValueSchema, et as SetYearPatchSchema, f as DateValueSchema, ft as StructureSummarySchema, g as FieldGroupSchema, gt as TableRowResponseSchema, h as ExplicitCheckboxValueSchema, ht as TableRowPatchSchema, i as CheckboxModeSchema, it as SingleSelectValueSchema, j as MultiSelectFieldSchema, k as MarkformFrontmatterSchema, l as ClearFieldPatchSchema, lt as StringListFieldSchema, m as DocumentationTagSchema, mt as TableFieldSchema, n as ApplyResultSchema, nt as SimpleCheckboxStateSchema, o as CheckboxValueSchema, ot as SourceRangeSchema, p as DocumentationBlockSchema, pt as TableColumnSchema, q as SetNumberPatchSchema, r as CellResponseSchema, rt as SingleSelectFieldSchema, s as CheckboxesFieldSchema, st as StepResultSchema, t as AnswerStateSchema, tt as SeveritySchema, u as ColumnTypeNameSchema, ut as StringListValueSchema, v as FieldProgressSchema, vt as UrlFieldSchema, w as IdSchema, wt as YearFieldSchema, x as FieldValueSchema, xt as UrlValueSchema, y as FieldResponseSchema, yt as UrlListFieldSchema, z as ProgressStateSchema } from "./coreTypes-pyctKRgc.mjs";
|
|
2
|
-
import { a as computeAllSummaries, c as computeStructureSummary, i as validate, l as isFormComplete, o as computeFormState, r as inspect, s as computeProgressSummary, t as applyPatches, u as serialize } from "./apply-
|
|
3
|
-
import { C as serializeScopeRef, D as parseRawTable, E as parseMarkdownTable, O as ParseError, S as parseScopeRef, T as parseCellValue, _ as findFieldById, a as resolveHarnessConfig, b as isFieldRef, d as MockAgent, f as createMockAgent, g as coerceToFieldPatch, h as coerceInputContext, i as runResearch, m as createHarness, n as isResearchForm, o as fillForm, p as FormHarness, r as validateResearchForm, t as VERSION, v as getFieldId, w as parseForm, x as isQualifiedRef, y as isCellRef } from "./src-
|
|
2
|
+
import { a as computeAllSummaries, c as computeStructureSummary, i as validate, l as isFormComplete, o as computeFormState, r as inspect, s as computeProgressSummary, t as applyPatches, u as serialize } from "./apply-DMQl-VVd.mjs";
|
|
3
|
+
import { C as serializeScopeRef, D as parseRawTable, E as parseMarkdownTable, O as ParseError, S as parseScopeRef, T as parseCellValue, _ as findFieldById, a as resolveHarnessConfig, b as isFieldRef, d as MockAgent, f as createMockAgent, g as coerceToFieldPatch, h as coerceInputContext, i as runResearch, m as createHarness, n as isResearchForm, o as fillForm, p as FormHarness, r as validateResearchForm, t as VERSION, v as getFieldId, w as parseForm, x as isQualifiedRef, y as isCellRef } from "./src-o_5TSoHQ.mjs";
|
|
4
4
|
import { n as serializeSession, t as parseSession } from "./session-uF0e6m6k.mjs";
|
|
5
5
|
|
|
6
6
|
export { AnswerStateSchema, ApplyResultSchema, CellResponseSchema, CheckboxModeSchema, CheckboxProgressCountsSchema, CheckboxValueSchema, CheckboxesFieldSchema, CheckboxesValueSchema, ClearFieldPatchSchema, ColumnTypeNameSchema, DateFieldSchema, DateValueSchema, DocumentationBlockSchema, DocumentationTagSchema, ExplicitCheckboxValueSchema, FieldGroupSchema, FieldKindSchema, FieldProgressSchema, FieldResponseSchema, FieldSchema, FieldValueSchema, FormHarness, FormSchemaSchema, HarnessConfigSchema, IdSchema, InspectIssueSchema, InspectResultSchema, IssueReasonSchema, IssueScopeSchema, MarkformFrontmatterSchema, MockAgent, MultiCheckboxStateSchema, MultiSelectFieldSchema, MultiSelectValueSchema, NumberFieldSchema, NumberValueSchema, OptionIdSchema, OptionSchema, ParseError, PatchSchema, ProgressCountsSchema, ProgressStateSchema, ProgressSummarySchema, SessionFinalSchema, SessionTranscriptSchema, SessionTurnSchema, SetCheckboxesPatchSchema, SetDatePatchSchema, SetMultiSelectPatchSchema, SetNumberPatchSchema, SetSingleSelectPatchSchema, SetStringListPatchSchema, SetStringPatchSchema, SetTablePatchSchema, SetUrlListPatchSchema, SetUrlPatchSchema, SetYearPatchSchema, SeveritySchema, SimpleCheckboxStateSchema, SingleSelectFieldSchema, SingleSelectValueSchema, SourcePositionSchema, SourceRangeSchema, StepResultSchema, StringFieldSchema, StringListFieldSchema, StringListValueSchema, StringValueSchema, StructureSummarySchema, TableColumnSchema, TableFieldSchema, TableRowPatchSchema, TableRowResponseSchema, TableValueSchema, UrlFieldSchema, UrlListFieldSchema, UrlListValueSchema, UrlValueSchema, VERSION, ValidationIssueSchema, ValidatorRefSchema, YearFieldSchema, YearValueSchema, applyPatches, coerceInputContext, coerceToFieldPatch, computeAllSummaries, computeFormState, computeProgressSummary, computeStructureSummary, createHarness, createMockAgent, fillForm, findFieldById, getFieldId, inspect, isCellRef, isFieldRef, isFormComplete, isQualifiedRef, isResearchForm, parseCellValue, parseForm, parseMarkdownTable, parseRawTable, parseScopeRef, parseSession, resolveHarnessConfig, runResearch, serialize, serializeScopeRef, serializeSession, validate, validateResearchForm };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as formatPath, c as logError, d as logTiming, f as logVerbose, g as writeFile, h as shouldUseColors, i as formatOutput, l as logInfo, m as readFile, n as createSpinner, o as getCommandContext, p as logWarn, r as ensureFormsDir, s as logDryRun, t as OUTPUT_FORMATS, u as logSuccess } from "./shared-
|
|
1
|
+
import { a as formatPath, c as logError, d as logTiming, f as logVerbose, g as writeFile, h as shouldUseColors, i as formatOutput, l as logInfo, m as readFile, n as createSpinner, o as getCommandContext, p as logWarn, r as ensureFormsDir, s as logDryRun, t as OUTPUT_FORMATS, u as logSuccess } from "./shared-DRlgu2ZJ.mjs";
|
|
2
2
|
|
|
3
3
|
export { writeFile };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { L as PatchSchema } from "./coreTypes-pyctKRgc.mjs";
|
|
2
|
-
import { C as DEFAULT_ROLE_INSTRUCTIONS,
|
|
3
|
-
import { createRequire } from "node:module";
|
|
2
|
+
import { C as DEFAULT_ROLE_INSTRUCTIONS, N as getWebSearchConfig, S as DEFAULT_ROLES, _ as DEFAULT_MAX_TURNS, b as DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN, g as DEFAULT_MAX_PATCHES_PER_TURN, h as DEFAULT_MAX_ISSUES_PER_TURN, n as getFieldsForRoles, p as AGENT_ROLE, r as inspect, t as applyPatches, u as serialize, x as DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN, y as DEFAULT_PRIORITY } from "./apply-DMQl-VVd.mjs";
|
|
4
3
|
import { z } from "zod";
|
|
5
4
|
import Markdoc from "@markdoc/markdoc";
|
|
6
5
|
import YAML from "yaml";
|
|
@@ -7613,6 +7612,7 @@ var LiveAgent = class {
|
|
|
7613
7612
|
enableWebSearch;
|
|
7614
7613
|
webSearchTools = null;
|
|
7615
7614
|
additionalTools;
|
|
7615
|
+
callbacks;
|
|
7616
7616
|
constructor(config) {
|
|
7617
7617
|
this.model = config.model;
|
|
7618
7618
|
this.maxStepsPerTurn = config.maxStepsPerTurn ?? 3;
|
|
@@ -7621,6 +7621,7 @@ var LiveAgent = class {
|
|
|
7621
7621
|
this.provider = config.provider;
|
|
7622
7622
|
this.enableWebSearch = config.enableWebSearch;
|
|
7623
7623
|
this.additionalTools = config.additionalTools ?? {};
|
|
7624
|
+
this.callbacks = config.callbacks;
|
|
7624
7625
|
if (this.enableWebSearch && this.provider) this.webSearchTools = loadWebSearchTools(this.provider);
|
|
7625
7626
|
}
|
|
7626
7627
|
/**
|
|
@@ -7646,14 +7647,18 @@ var LiveAgent = class {
|
|
|
7646
7647
|
if (this.systemPromptAddition) systemPrompt += "\n\n# Additional Context\n" + this.systemPromptAddition;
|
|
7647
7648
|
if (this.enableWebSearch && this.provider && !this.webSearchTools) this.webSearchTools = loadWebSearchTools(this.provider);
|
|
7648
7649
|
if (this.webSearchTools && Object.keys(this.webSearchTools).length > 0) systemPrompt += "\n\n" + WEB_SEARCH_INSTRUCTIONS;
|
|
7649
|
-
const tools = {
|
|
7650
|
+
const tools = wrapToolsWithCallbacks({
|
|
7650
7651
|
generatePatches: {
|
|
7651
7652
|
description: GENERATE_PATCHES_TOOL_DESCRIPTION,
|
|
7652
7653
|
inputSchema: zodSchema(z.object({ patches: z.array(PatchSchema).max(maxPatches).describe("Array of patches. Each patch sets a value for one field.") }))
|
|
7653
7654
|
},
|
|
7654
7655
|
...this.webSearchTools,
|
|
7655
7656
|
...this.additionalTools
|
|
7656
|
-
};
|
|
7657
|
+
}, this.callbacks);
|
|
7658
|
+
const modelId = this.model.modelId ?? "unknown";
|
|
7659
|
+
if (this.callbacks?.onLlmCallStart) try {
|
|
7660
|
+
this.callbacks.onLlmCallStart({ model: modelId });
|
|
7661
|
+
} catch {}
|
|
7657
7662
|
const result = await generateText({
|
|
7658
7663
|
model: this.model,
|
|
7659
7664
|
system: systemPrompt,
|
|
@@ -7661,6 +7666,13 @@ var LiveAgent = class {
|
|
|
7661
7666
|
tools,
|
|
7662
7667
|
stopWhen: stepCountIs(this.maxStepsPerTurn)
|
|
7663
7668
|
});
|
|
7669
|
+
if (this.callbacks?.onLlmCallEnd) try {
|
|
7670
|
+
this.callbacks.onLlmCallEnd({
|
|
7671
|
+
model: modelId,
|
|
7672
|
+
inputTokens: result.usage?.inputTokens ?? 0,
|
|
7673
|
+
outputTokens: result.usage?.outputTokens ?? 0
|
|
7674
|
+
});
|
|
7675
|
+
} catch {}
|
|
7664
7676
|
const patches = [];
|
|
7665
7677
|
const toolCallCounts = /* @__PURE__ */ new Map();
|
|
7666
7678
|
for (const step of result.steps) for (const toolCall of step.toolCalls) {
|
|
@@ -7797,6 +7809,60 @@ function findField(form, fieldId) {
|
|
|
7797
7809
|
return null;
|
|
7798
7810
|
}
|
|
7799
7811
|
/**
|
|
7812
|
+
* Wrap tools with callbacks for observability.
|
|
7813
|
+
*
|
|
7814
|
+
* Only wraps tools that have an execute function.
|
|
7815
|
+
* Declarative tools (schema only) are passed through unchanged.
|
|
7816
|
+
*/
|
|
7817
|
+
function wrapToolsWithCallbacks(tools, callbacks) {
|
|
7818
|
+
if (!callbacks?.onToolStart && !callbacks?.onToolEnd) return tools;
|
|
7819
|
+
const wrapped = {};
|
|
7820
|
+
for (const [name$2, tool$1] of Object.entries(tools)) {
|
|
7821
|
+
const execute = tool$1.execute;
|
|
7822
|
+
if (typeof execute === "function") wrapped[name$2] = wrapTool(name$2, tool$1, execute, callbacks);
|
|
7823
|
+
else wrapped[name$2] = tool$1;
|
|
7824
|
+
}
|
|
7825
|
+
return wrapped;
|
|
7826
|
+
}
|
|
7827
|
+
/**
|
|
7828
|
+
* Wrap a single tool with callbacks.
|
|
7829
|
+
*/
|
|
7830
|
+
function wrapTool(name$2, tool$1, originalExecute, callbacks) {
|
|
7831
|
+
return {
|
|
7832
|
+
...tool$1,
|
|
7833
|
+
execute: async (input) => {
|
|
7834
|
+
const startTime = Date.now();
|
|
7835
|
+
if (callbacks.onToolStart) try {
|
|
7836
|
+
callbacks.onToolStart({
|
|
7837
|
+
name: name$2,
|
|
7838
|
+
input
|
|
7839
|
+
});
|
|
7840
|
+
} catch {}
|
|
7841
|
+
try {
|
|
7842
|
+
const output = await originalExecute(input);
|
|
7843
|
+
if (callbacks.onToolEnd) try {
|
|
7844
|
+
callbacks.onToolEnd({
|
|
7845
|
+
name: name$2,
|
|
7846
|
+
output,
|
|
7847
|
+
durationMs: Date.now() - startTime
|
|
7848
|
+
});
|
|
7849
|
+
} catch {}
|
|
7850
|
+
return output;
|
|
7851
|
+
} catch (error) {
|
|
7852
|
+
if (callbacks.onToolEnd) try {
|
|
7853
|
+
callbacks.onToolEnd({
|
|
7854
|
+
name: name$2,
|
|
7855
|
+
output: null,
|
|
7856
|
+
durationMs: Date.now() - startTime,
|
|
7857
|
+
error: error instanceof Error ? error.message : String(error)
|
|
7858
|
+
});
|
|
7859
|
+
} catch {}
|
|
7860
|
+
throw error;
|
|
7861
|
+
}
|
|
7862
|
+
}
|
|
7863
|
+
};
|
|
7864
|
+
}
|
|
7865
|
+
/**
|
|
7800
7866
|
* Load web search tools for a provider.
|
|
7801
7867
|
* Uses centralized config from llms.ts.
|
|
7802
7868
|
*/
|
|
@@ -7994,6 +8060,7 @@ function buildResult(form, turns, totalPatches, status, inputContextWarnings, re
|
|
|
7994
8060
|
* const result = await fillForm({
|
|
7995
8061
|
* form: formMarkdown,
|
|
7996
8062
|
* model: 'anthropic/claude-sonnet-4-5',
|
|
8063
|
+
* enableWebSearch: true,
|
|
7997
8064
|
* inputContext: {
|
|
7998
8065
|
* company_name: 'Apple Inc.',
|
|
7999
8066
|
* },
|
|
@@ -8001,8 +8068,10 @@ function buildResult(form, turns, totalPatches, status, inputContextWarnings, re
|
|
|
8001
8068
|
* ## Additional Context
|
|
8002
8069
|
* ${backgroundInfo}
|
|
8003
8070
|
* `,
|
|
8004
|
-
*
|
|
8005
|
-
*
|
|
8071
|
+
* callbacks: {
|
|
8072
|
+
* onTurnComplete: (progress) => {
|
|
8073
|
+
* console.log(`Turn ${progress.turnNumber}: ${progress.requiredIssuesRemaining} remaining`);
|
|
8074
|
+
* },
|
|
8006
8075
|
* },
|
|
8007
8076
|
* });
|
|
8008
8077
|
*
|
|
@@ -8079,7 +8148,8 @@ async function fillForm(options) {
|
|
|
8079
8148
|
targetRole: targetRoles[0] ?? AGENT_ROLE,
|
|
8080
8149
|
provider,
|
|
8081
8150
|
enableWebSearch: options.enableWebSearch,
|
|
8082
|
-
additionalTools: options.additionalTools
|
|
8151
|
+
additionalTools: options.additionalTools,
|
|
8152
|
+
callbacks: options.callbacks
|
|
8083
8153
|
});
|
|
8084
8154
|
let turnCount = 0;
|
|
8085
8155
|
let stepResult = harness.step();
|
|
@@ -8088,6 +8158,12 @@ async function fillForm(options) {
|
|
|
8088
8158
|
ok: false,
|
|
8089
8159
|
reason: "cancelled"
|
|
8090
8160
|
}, inputContextWarnings, stepResult.issues);
|
|
8161
|
+
if (options.callbacks?.onTurnStart) try {
|
|
8162
|
+
options.callbacks.onTurnStart({
|
|
8163
|
+
turnNumber: turnCount + 1,
|
|
8164
|
+
issuesCount: stepResult.issues.length
|
|
8165
|
+
});
|
|
8166
|
+
} catch {}
|
|
8091
8167
|
const { patches, stats } = await agent.generatePatches(stepResult.issues, form, maxPatchesPerTurn);
|
|
8092
8168
|
if (options.signal?.aborted) return buildResult(form, turnCount, totalPatches, {
|
|
8093
8169
|
ok: false,
|
|
@@ -8102,9 +8178,9 @@ async function fillForm(options) {
|
|
|
8102
8178
|
stepResult = harness.apply(patches, stepResult.issues, llmStats);
|
|
8103
8179
|
totalPatches += patches.length;
|
|
8104
8180
|
turnCount++;
|
|
8105
|
-
if (options.onTurnComplete) try {
|
|
8181
|
+
if (options.callbacks?.onTurnComplete) try {
|
|
8106
8182
|
const requiredIssues = stepResult.issues.filter((i) => i.severity === "required");
|
|
8107
|
-
options.onTurnComplete({
|
|
8183
|
+
options.callbacks.onTurnComplete({
|
|
8108
8184
|
turnNumber: turnCount,
|
|
8109
8185
|
issuesShown: stepResult.issues.length,
|
|
8110
8186
|
patchesApplied: patches.length,
|
|
@@ -8266,15 +8342,8 @@ function validateResearchForm(form) {
|
|
|
8266
8342
|
|
|
8267
8343
|
//#endregion
|
|
8268
8344
|
//#region src/index.ts
|
|
8269
|
-
/**
|
|
8270
|
-
|
|
8271
|
-
*
|
|
8272
|
-
* This is the main library entry point that exports the core engine,
|
|
8273
|
-
* types, and utilities for working with .form.md files.
|
|
8274
|
-
*/
|
|
8275
|
-
const pkg = createRequire(import.meta.url)("../package.json");
|
|
8276
|
-
/** Markform version (read from package.json). */
|
|
8277
|
-
const VERSION = pkg.version;
|
|
8345
|
+
/** Markform version (injected at build time). */
|
|
8346
|
+
const VERSION = "0.1.6";
|
|
8278
8347
|
|
|
8279
8348
|
//#endregion
|
|
8280
8349
|
export { serializeScopeRef as C, parseRawTable as D, parseMarkdownTable as E, ParseError as O, parseScopeRef as S, parseCellValue as T, findFieldById as _, resolveHarnessConfig as a, isFieldRef as b, getProviderNames as c, MockAgent as d, createMockAgent as f, coerceToFieldPatch as g, coerceInputContext as h, runResearch as i, resolveModel as l, createHarness as m, isResearchForm as n, fillForm as o, FormHarness as p, validateResearchForm as r, getProviderInfo as s, VERSION as t, createLiveAgent as u, getFieldId as v, parseForm as w, isQualifiedRef as x, isCellRef as y };
|
package/docs/markform-apis.md
CHANGED
|
@@ -152,10 +152,57 @@ High-level API for filling a form with an AI model.
|
|
|
152
152
|
const result = await fillForm({
|
|
153
153
|
form: parsedForm,
|
|
154
154
|
model: 'anthropic/claude-sonnet-4-5',
|
|
155
|
-
|
|
155
|
+
enableWebSearch: true,
|
|
156
|
+
targetRoles: ['agent'],
|
|
156
157
|
});
|
|
157
158
|
```
|
|
158
159
|
|
|
160
|
+
### FillCallbacks
|
|
161
|
+
|
|
162
|
+
Optional callbacks for observing form-filling execution in real-time.
|
|
163
|
+
All callbacks are optional and errors in callbacks don't abort filling.
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import type { FillCallbacks } from 'markform';
|
|
167
|
+
|
|
168
|
+
const callbacks: FillCallbacks = {
|
|
169
|
+
onTurnStart: ({ turnNumber, issuesCount }) => {
|
|
170
|
+
console.log(`Turn ${turnNumber}: ${issuesCount} issues`);
|
|
171
|
+
},
|
|
172
|
+
onTurnComplete: (progress) => {
|
|
173
|
+
console.log(`Completed: ${progress.patchesApplied} patches applied`);
|
|
174
|
+
},
|
|
175
|
+
onToolStart: ({ name }) => {
|
|
176
|
+
spinner.message(`🔧 ${name}...`);
|
|
177
|
+
},
|
|
178
|
+
onToolEnd: ({ name, durationMs }) => {
|
|
179
|
+
console.log(`${name} completed in ${durationMs}ms`);
|
|
180
|
+
},
|
|
181
|
+
onLlmCallStart: ({ model }) => {
|
|
182
|
+
console.log(`Calling ${model}...`);
|
|
183
|
+
},
|
|
184
|
+
onLlmCallEnd: ({ inputTokens, outputTokens }) => {
|
|
185
|
+
console.log(`Tokens: ${inputTokens} in, ${outputTokens} out`);
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
await fillForm({
|
|
190
|
+
form: parsedForm,
|
|
191
|
+
model: 'anthropic/claude-sonnet-4-5',
|
|
192
|
+
enableWebSearch: true,
|
|
193
|
+
callbacks,
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
| Callback | Parameters | Description |
|
|
198
|
+
| --- | --- | --- |
|
|
199
|
+
| `onTurnStart` | `{ turnNumber, issuesCount }` | Called when a turn begins |
|
|
200
|
+
| `onTurnComplete` | `TurnProgress` | Called when a turn completes |
|
|
201
|
+
| `onToolStart` | `{ name, input }` | Called before a tool executes |
|
|
202
|
+
| `onToolEnd` | `{ name, output, durationMs, error? }` | Called after a tool completes |
|
|
203
|
+
| `onLlmCallStart` | `{ model }` | Called before an LLM request |
|
|
204
|
+
| `onLlmCallEnd` | `{ model, inputTokens, outputTokens }` | Called after an LLM response |
|
|
205
|
+
|
|
159
206
|
### createHarness(form, config?): FormHarness
|
|
160
207
|
|
|
161
208
|
Create a harness for manual control over the fill loop.
|
|
@@ -187,6 +234,10 @@ import type {
|
|
|
187
234
|
FieldValue,
|
|
188
235
|
Patch,
|
|
189
236
|
InspectResult,
|
|
237
|
+
FillCallbacks,
|
|
238
|
+
FillOptions,
|
|
239
|
+
FillResult,
|
|
240
|
+
TurnProgress,
|
|
190
241
|
// ... many more
|
|
191
242
|
} from 'markform';
|
|
192
243
|
```
|
package/docs/markform-spec.md
CHANGED
|
@@ -118,12 +118,20 @@ Built on [Markdoc’s tag syntax specification][markdoc-spec] and
|
|
|
118
118
|
---
|
|
119
119
|
markform:
|
|
120
120
|
spec: MF/0.1
|
|
121
|
+
run_mode: research # optional: interactive | fill | research
|
|
121
122
|
form_summary: { ... } # derived: structure summary
|
|
122
123
|
form_progress: { ... } # derived: progress summary
|
|
123
124
|
form_state: complete|incomplete|invalid|empty # derived: overall progress state
|
|
124
125
|
---
|
|
125
126
|
```
|
|
126
127
|
|
|
128
|
+
**Optional metadata fields:**
|
|
129
|
+
|
|
130
|
+
- `run_mode` (*recommended*): Suggests how CLI tools should execute this form. Values:
|
|
131
|
+
`interactive` (user fills via prompts), `fill` (agent fills), or `research` (agent
|
|
132
|
+
fills with web search). When omitted, tools may infer from field roles or require
|
|
133
|
+
explicit selection. This is a hint for tooling, not enforced by the engine.
|
|
134
|
+
|
|
127
135
|
**Behavioral rules (*required*):**
|
|
128
136
|
|
|
129
137
|
- *required:* `form_summary`, `form_progress`, and `form_state` are derived,
|
|
@@ -1343,6 +1351,7 @@ interface FormMetadata {
|
|
|
1343
1351
|
markformVersion: string;
|
|
1344
1352
|
roles: string[]; // available roles for field assignment
|
|
1345
1353
|
roleInstructions: Record<string, string>; // instructions per role
|
|
1354
|
+
runMode?: 'interactive' | 'fill' | 'research'; // optional: hint for CLI tools
|
|
1346
1355
|
}
|
|
1347
1356
|
|
|
1348
1357
|
// ParsedForm: canonical internal representation returned by parseForm()
|