markform 0.1.7 → 0.1.9
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 +451 -240
- package/dist/ai-sdk.d.mts +1 -1
- package/dist/ai-sdk.mjs +2 -2
- package/dist/{apply-g23rRn7p.mjs → apply-B2kt6C2z.mjs} +136 -32
- package/dist/bin.mjs +1 -1
- package/dist/{cli-Bqlm-WWw.mjs → cli-Dt_PlYi_.mjs} +519 -60
- package/dist/cli.mjs +1 -1
- package/dist/{coreTypes-__Cwxz5q.mjs → coreTypes-B1oI7qvV.mjs} +52 -4
- package/dist/{coreTypes-DCvD7feM.d.mts → coreTypes-JCPm418M.d.mts} +265 -9
- package/dist/index.d.mts +22 -10
- package/dist/index.mjs +5 -5
- package/dist/{session-DruaYPZ1.mjs → session-CzCh6JeY.mjs} +1 -1
- package/dist/{session-CgCNni0e.mjs → session-Dxqwt0RC.mjs} +3 -3
- package/dist/{shared-C9yW5FLZ.mjs → shared-CNqwaxUt.mjs} +1 -1
- package/dist/{shared-DQ6y3Ggc.mjs → shared-D3dNi-Gn.mjs} +1 -1
- package/dist/{src-BiuxbzF3.mjs → src-DFsC5wwy.mjs} +308 -59
- package/docs/markform-apis.md +30 -1
- package/docs/markform-reference.md +65 -6
- package/docs/markform-spec.md +3 -3
- package/examples/movie-research/{movie-research-deep.form.md → movie-deep-research.form.md} +17 -58
- package/examples/movie-research/movie-research-demo.form.md +25 -34
- package/examples/rejection-test/rejection-test-mock-filled.form.md +41 -0
- package/examples/rejection-test/rejection-test-mock-filled.report.md +15 -0
- package/examples/rejection-test/rejection-test-mock-filled.schema.json +59 -0
- package/examples/rejection-test/rejection-test-mock-filled.yml +13 -0
- package/examples/rejection-test/rejection-test.form.md +35 -0
- package/examples/rejection-test/rejection-test.session.yaml +534 -0
- package/examples/simple/simple-mock-filled.report.md +96 -0
- package/examples/simple/simple-mock-filled.schema.json +374 -0
- package/examples/simple/simple-mock-filled.yml +87 -0
- package/examples/simple/simple-skipped-filled.report.md +90 -0
- package/examples/simple/simple-skipped-filled.schema.json +374 -0
- package/examples/simple/simple-skipped-filled.yml +77 -0
- package/examples/simple/simple-with-skips.session.yaml +1969 -21
- package/examples/simple/simple.session.yaml +1982 -21
- package/package.json +1 -1
- package/examples/earnings-analysis/earnings-analysis.form.md +0 -159
- package/examples/earnings-analysis/earnings-analysis.raw.md +0 -801
- package/examples/earnings-analysis/earnings-analysis.valid.ts +0 -198
- package/examples/movie-research/movie-research-basic.form.md +0 -169
package/README.md
CHANGED
|
@@ -1,49 +1,69 @@
|
|
|
1
1
|
# Markform
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
incrementally via
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
[](https://github.com/jlevy/markform/actions/workflows/ci.yml)
|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
**Markform** is a text format for defining structured forms that humans can read,
|
|
7
|
+
machines can parse, and agents can fill via tool calls.
|
|
8
|
+
|
|
9
|
+
Define instructions, fields, and validation rules in a single `.form.md` file.
|
|
10
|
+
Agents fill forms incrementally via patches.
|
|
11
|
+
Fields are validated, so errors are caught early and can be corrected.
|
|
12
|
+
Humans can review or intervene at any point.
|
|
13
|
+
|
|
14
|
+
**Why forms?** For deep research or complex AI tasks, you need more than just prompts or
|
|
15
|
+
flow: you need *structure*, which is precise control over agent output at every stage of
|
|
16
|
+
a workflow. A well-designed form combines instructions, structured data, and validations
|
|
17
|
+
in one place.
|
|
18
|
+
|
|
19
|
+
**How it works:**
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
- A Markform document exposes a programmatic interface: users fill fields via CLI or web
|
|
22
|
+
UI, agents fill via tool calls ([Vercel AI SDK](https://github.com/vercel/ai)
|
|
23
|
+
integration included).
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
- Changes are explicit patch operations (`{ "op": "set_string", "fieldId": "name",
|
|
26
|
+
"value": "Alice" }`) validated against a schema specified in the form.
|
|
27
|
+
The agent sees validation errors and can self-correct.
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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).
|
|
29
|
+
- The format extends Markdown with a
|
|
30
|
+
[precise specification](https://github.com/jlevy/markform/blob/main/docs/markform-spec.md).
|
|
31
|
+
Export Markform syntax to JSON, YAML, JSON Schema, or plain Markdown reports.
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
Markform syntax is a good source format: token-efficient text you can read, diff, and
|
|
34
|
+
version control.
|
|
35
|
+
It is built with [Markdoc](https://github.com/markdoc/markdoc), which is
|
|
36
|
+
a Markdown extension from Stripe with Jinja-style `{% tag %}` annotations.
|
|
37
|
+
|
|
38
|
+
## Why Do Agents Need Forms?
|
|
39
|
+
|
|
40
|
+
For centuries, humans have used paper forms and
|
|
41
|
+
[checklists](https://en.wikipedia.org/wiki/The_Checklist_Manifesto) to systematize
|
|
42
|
+
complex processes. A form with instructions, field definitions, and validations is a
|
|
43
|
+
concise way to share context: goals, background knowledge, process rules, and state
|
|
44
|
+
(memory). I don’t think AI changes this essential aspect of knowledge work.
|
|
31
45
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
46
|
+
Most agent frameworks focus on *prompts* and *flow* (the how) over the *structure* of
|
|
47
|
+
results (the what).
|
|
48
|
+
But for deep research or other multi-step workflows, you need precise
|
|
49
|
+
control over intermediate states and final output.
|
|
50
|
+
You don’t want that structure in a GUI (not token-friendly), in code (hard to update),
|
|
51
|
+
or dependent on model whims (changes unpredictably with model updates).
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
Forms solve this. Forms codify operational excellence.
|
|
54
|
+
They’re easy to read, easy to edit, and enforce standards.
|
|
55
|
+
Because LLMs handle Markdown and Jinja-style tags well, agents can also help create and
|
|
56
|
+
improve the forms themselves—closing the meta-loop.
|
|
57
|
+
|
|
58
|
+
It’s time to bring bureaucracy to the agents!
|
|
59
|
+
See [the FAQ](#faq) for more on the design.
|
|
37
60
|
|
|
38
61
|
## Quick Start
|
|
39
62
|
|
|
40
63
|
```bash
|
|
41
|
-
# Copy example forms to ./forms/ and run one interactively
|
|
64
|
+
# Copy example forms to ./forms/ and run one interactively.
|
|
42
65
|
# Set OPENAI_API_KEY or ANTHROPIC_API_KEY (or put in .env) for research examples
|
|
43
|
-
npx markform examples
|
|
44
|
-
|
|
45
|
-
# Or run forms directly
|
|
46
|
-
npx markform run # Browse and run forms interactively
|
|
66
|
+
npx markform@latest examples
|
|
47
67
|
|
|
48
68
|
# Read the docs (tell your agents to run these; they are agent-friendly!)
|
|
49
69
|
npx markform # CLI help
|
|
@@ -52,7 +72,8 @@ npx markform docs # Quick reference for writing Markforms
|
|
|
52
72
|
npx markform spec # Read the full spec
|
|
53
73
|
```
|
|
54
74
|
|
|
55
|
-
The `markform examples` command copies sample forms
|
|
75
|
+
The `markform examples` command copies some sample forms to `./forms` and prompts you to
|
|
76
|
+
fill in a form interactively and then optionally have an agent complete it.
|
|
56
77
|
Pick `movie-research-demo.form.md` for a quick example.
|
|
57
78
|
|
|
58
79
|
## Installation
|
|
@@ -72,56 +93,94 @@ npm install markform
|
|
|
72
93
|
### Form Definition
|
|
73
94
|
|
|
74
95
|
A `.form.md` file is simply a Markdoc file.
|
|
75
|
-
It combines YAML frontmatter with Markdoc-tagged content
|
|
96
|
+
It combines YAML frontmatter with Markdoc-tagged content.
|
|
76
97
|
|
|
77
|
-
|
|
98
|
+
The text can be any Markdown.
|
|
99
|
+
The tags define things like fields:
|
|
100
|
+
|
|
101
|
+
```jinja
|
|
102
|
+
{% field kind="string" id="movie" label="Movie" role="user"
|
|
103
|
+
required=true minLength=1 maxLength=300 %}{% /field %}
|
|
104
|
+
|
|
105
|
+
{% field kind="single_select" id="mpaa_rating" role="agent" label="MPAA Rating" %}
|
|
106
|
+
- [ ] G {% #g %}
|
|
107
|
+
- [ ] PG {% #pg %}
|
|
108
|
+
- [ ] PG-13 {% #pg_13 %}
|
|
109
|
+
- [ ] R {% #r %}
|
|
110
|
+
- [ ] NC-17 {% #nc_17 %}
|
|
111
|
+
- [ ] NR/Unrated {% #nr %}
|
|
112
|
+
{% /field %}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Fields have types defined by the attributes.
|
|
116
|
+
Values are filled in incrementally, just like any form.
|
|
117
|
+
Once filled in, values appear directly inside the tags, in Markdown format:
|
|
118
|
+
|
|
119
|
+
````jinja
|
|
120
|
+
{% field kind="string" id="movie" label="Movie" role="user"
|
|
121
|
+
required=true minLength=1 maxLength=300 %}
|
|
122
|
+
```value
|
|
123
|
+
The Shawshank Redemption
|
|
124
|
+
```
|
|
125
|
+
{% /field %}
|
|
126
|
+
|
|
127
|
+
{% field kind="single_select" id="mpaa_rating" role="agent" label="MPAA Rating" %}
|
|
128
|
+
- [ ] G {% #g %}
|
|
129
|
+
- [ ] PG {% #pg %}
|
|
130
|
+
- [ ] PG-13 {% #pg_13 %}
|
|
131
|
+
- [x] R {% #r %}
|
|
132
|
+
- [ ] NC-17 {% #nc_17 %}
|
|
133
|
+
- [ ] NR/Unrated {% #nr %}
|
|
134
|
+
{% /field %}
|
|
135
|
+
````
|
|
136
|
+
|
|
137
|
+
Note fields can have a `role="user"` to indicate they are filled interactively by the
|
|
138
|
+
user, or a `role="agent"` to indicate an agent should fill them in.
|
|
139
|
+
|
|
140
|
+
There are also tags for user or agent instructions per field or at form level and
|
|
141
|
+
grouping of forms.
|
|
142
|
+
|
|
143
|
+
Checkboxes and tables as values are supported!
|
|
144
|
+
Checkboxes can be single-select or multi-select.
|
|
145
|
+
|
|
146
|
+
Here’s a full example:
|
|
147
|
+
|
|
148
|
+
<details>
|
|
149
|
+
|
|
150
|
+
<summary>Markform for Movie Research Demo (click to expand)</summary>
|
|
151
|
+
|
|
152
|
+
```jinja
|
|
78
153
|
---
|
|
79
154
|
markform:
|
|
80
155
|
spec: MF/0.1
|
|
81
|
-
title: Movie Research
|
|
82
|
-
description:
|
|
156
|
+
title: Movie Research Demo
|
|
157
|
+
description: Movie lookup with ratings from IMDB and Rotten Tomatoes.
|
|
158
|
+
run_mode: research
|
|
83
159
|
roles:
|
|
84
160
|
- user
|
|
85
161
|
- agent
|
|
86
162
|
role_instructions:
|
|
87
163
|
user: "Enter the movie title."
|
|
88
164
|
agent: |
|
|
89
|
-
|
|
90
|
-
This is a demo lookup - just get the core facts.
|
|
165
|
+
Identify the movie with web searches and use imdb.com and rottentomatoes.com to fill in the ratings.
|
|
91
166
|
---
|
|
92
|
-
{% form id="movie_research_demo"
|
|
93
|
-
|
|
94
|
-
## Movie Research Example
|
|
167
|
+
{% form id="movie_research_demo" %}
|
|
168
|
+
{% group id="movie_input" %}
|
|
95
169
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
What movie do you want to research? \[*This field is filled in by the user (`role="user"`).*\]
|
|
170
|
+
## What movie do you want to research?
|
|
99
171
|
|
|
100
172
|
{% field kind="string" id="movie" label="Movie" role="user" required=true minLength=1 maxLength=300 %}{% /field %}
|
|
101
173
|
{% instructions ref="movie" %}Enter the movie title (add year or details for disambiguation).{% /instructions %}
|
|
102
174
|
|
|
103
175
|
{% /group %}
|
|
104
176
|
|
|
105
|
-
## About the Movie
|
|
106
|
-
|
|
107
177
|
{% group id="about_the_movie" title="About the Movie" %}
|
|
108
178
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
{% field kind="string" id="full_title" label="Full Title" role="agent" required=true %}{% /field %}
|
|
112
|
-
{% instructions ref="full_title" %}Official title, including subtitle if any.{% /instructions %}
|
|
113
|
-
|
|
114
|
-
**Release year:**
|
|
115
|
-
|
|
116
|
-
{% field kind="number" id="year" label="Release Year" role="agent" required=true min=1888 max=2030 %}{% /field %}
|
|
117
|
-
|
|
118
|
-
**IMDB:**
|
|
179
|
+
## Movie Ratings
|
|
119
180
|
|
|
120
|
-
|
|
181
|
+
Here are the ratings for the movie:
|
|
121
182
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
{% field kind="single_select" id="mpaa_rating" label="MPAA Rating" role="agent" %}
|
|
183
|
+
{% field kind="single_select" id="mpaa_rating" role="agent" label="MPAA Rating" %}
|
|
125
184
|
- [ ] G {% #g %}
|
|
126
185
|
- [ ] PG {% #pg %}
|
|
127
186
|
- [ ] PG-13 {% #pg_13 %}
|
|
@@ -130,56 +189,184 @@ What movie do you want to research? \[*This field is filled in by the user (`rol
|
|
|
130
189
|
- [ ] NR/Unrated {% #nr %}
|
|
131
190
|
{% /field %}
|
|
132
191
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
192
|
+
{% field kind="table" id="ratings_table" role="agent"
|
|
193
|
+
label="Ratings" required=true
|
|
194
|
+
columnIds=["source", "score", "votes"] columnTypes=["string", "number", "number"]
|
|
195
|
+
minRows=0 maxRows=3 %}
|
|
196
|
+
| Source | Score | Votes |
|
|
197
|
+
|--------|-------|-------|
|
|
198
|
+
{% /field %}
|
|
139
199
|
|
|
140
|
-
{%
|
|
141
|
-
|
|
200
|
+
{% instructions ref="ratings_table" %}
|
|
201
|
+
Fill in scores and vote counts from each source:
|
|
202
|
+
- IMDB: Rating (1.0-10.0 scale), vote count
|
|
203
|
+
- RT Critics: Tomatometer (0-100%), review count
|
|
204
|
+
- RT Audience: Audience Score (0-100%), rating count
|
|
205
|
+
{% /instructions %}
|
|
142
206
|
|
|
143
207
|
{% /group %}
|
|
144
|
-
|
|
145
208
|
{% /form %}
|
|
146
209
|
```
|
|
147
210
|
|
|
211
|
+
</details>
|
|
212
|
+
|
|
148
213
|
### Form Report Output
|
|
149
214
|
|
|
150
215
|
Run `npx markform examples` to copy examples, then `npx markform run` and select `Movie
|
|
151
|
-
Research
|
|
152
|
-
The report output looks like:
|
|
216
|
+
Research Demo` to fill it.
|
|
153
217
|
|
|
154
|
-
|
|
155
|
-
|
|
218
|
+
A form can be exported
|
|
219
|
+
|
|
220
|
+
- as the filled form (Markform format, just like the input)
|
|
221
|
+
|
|
222
|
+
- as a report (plain Markdown)
|
|
156
223
|
|
|
157
|
-
|
|
224
|
+
- as values (YAML or JSON)
|
|
158
225
|
|
|
226
|
+
- as a JSON schema (just the structure)
|
|
227
|
+
|
|
228
|
+
The report output (using `gpt-5-mini` to fill it in) looks like:
|
|
229
|
+
|
|
230
|
+
```markdown
|
|
159
231
|
Movie:
|
|
160
|
-
|
|
232
|
+
The Shawshank Redemption
|
|
161
233
|
|
|
162
234
|
## About the Movie
|
|
163
235
|
|
|
164
|
-
|
|
236
|
+
MPAA Rating:
|
|
237
|
+
R
|
|
238
|
+
|
|
239
|
+
Ratings:
|
|
240
|
+
| Source | Score | Votes |
|
|
241
|
+
| --- | --- | --- |
|
|
242
|
+
| IMDB | 9.3 | 3100000 |
|
|
243
|
+
| RT Critics | 89 | 146 |
|
|
244
|
+
| RT Audience | 98 | 250000 |
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Here is the schema and YAML values for the form above.
|
|
248
|
+
|
|
249
|
+
<details> <summary>Filled Markform (click to expand)</summary>
|
|
250
|
+
|
|
251
|
+
````jinja
|
|
252
|
+
{% form id="movie_research_demo" %}
|
|
253
|
+
|
|
254
|
+
{% group id="movie_input" %}
|
|
255
|
+
|
|
256
|
+
{% field kind="string" id="movie" role="user" label="Movie" maxLength=300 minLength=1 required=true %}
|
|
257
|
+
```value
|
|
165
258
|
The Shawshank Redemption
|
|
259
|
+
```
|
|
260
|
+
{% /field %}
|
|
166
261
|
|
|
167
|
-
|
|
168
|
-
|
|
262
|
+
{% instructions ref="movie" %}
|
|
263
|
+
Enter the movie title (add year or details for disambiguation).
|
|
264
|
+
{% /instructions %}
|
|
169
265
|
|
|
170
|
-
|
|
171
|
-
https://www.imdb.com/title/tt0111161/
|
|
266
|
+
{% /group %}
|
|
172
267
|
|
|
173
|
-
|
|
174
|
-
R
|
|
268
|
+
{% group id="about_the_movie" title="About the Movie" %}
|
|
175
269
|
|
|
176
|
-
|
|
177
|
-
|
|
270
|
+
{% field kind="single_select" id="mpaa_rating" label="MPAA Rating" %}
|
|
271
|
+
- [ ] G {% #g %}
|
|
272
|
+
- [ ] PG {% #pg %}
|
|
273
|
+
- [ ] PG-13 {% #pg_13 %}
|
|
274
|
+
- [x] R {% #r %}
|
|
275
|
+
- [ ] NC-17 {% #nc_17 %}
|
|
276
|
+
- [ ] NR/Unrated {% #nr %}
|
|
277
|
+
{% /field %}
|
|
178
278
|
|
|
179
|
-
|
|
180
|
-
|
|
279
|
+
{% field kind="table" id="ratings_table"
|
|
280
|
+
columnIds=["source", "score", "votes"] columnLabels=["Source", "Score", "Votes"]
|
|
281
|
+
columnTypes=["string", "number", "number"]
|
|
282
|
+
label="Ratings" maxRows=3 minRows=0 required=true %}
|
|
283
|
+
| Source | Score | Votes |
|
|
284
|
+
| --- | --- | --- |
|
|
285
|
+
| IMDB | 9.3 | 3100000 |
|
|
286
|
+
| RT Critics | 89 | 146 |
|
|
287
|
+
| RT Audience | 98 | 250000 |
|
|
288
|
+
{% /field %}
|
|
289
|
+
|
|
290
|
+
{% instructions ref="ratings_table" %}
|
|
291
|
+
Fill in scores and vote counts from each source:
|
|
292
|
+
- IMDB: Rating (1.0-10.0 scale), vote count
|
|
293
|
+
- RT Critics: Tomatometer (0-100%), review count
|
|
294
|
+
- RT Audience: Audience Score (0-100%), rating count
|
|
295
|
+
{% /instructions %}
|
|
296
|
+
|
|
297
|
+
{% /group %}
|
|
298
|
+
|
|
299
|
+
{% /form %}
|
|
300
|
+
````
|
|
301
|
+
|
|
302
|
+
</details>
|
|
303
|
+
|
|
304
|
+
<details> <summary>YAML Export (click to expand)</summary>
|
|
305
|
+
|
|
306
|
+
```yaml
|
|
307
|
+
values:
|
|
308
|
+
movie:
|
|
309
|
+
state: answered
|
|
310
|
+
value: The Shawshank Redemption
|
|
311
|
+
mpaa_rating:
|
|
312
|
+
state: answered
|
|
313
|
+
value: r
|
|
314
|
+
ratings_table:
|
|
315
|
+
state: answered
|
|
316
|
+
value:
|
|
317
|
+
- source: IMDB
|
|
318
|
+
score: 9.3
|
|
319
|
+
votes: 3100000
|
|
320
|
+
- source: RT Critics
|
|
321
|
+
score: 89
|
|
322
|
+
votes: 146
|
|
323
|
+
- source: RT Audience
|
|
324
|
+
score: 98
|
|
325
|
+
votes: 250000
|
|
181
326
|
```
|
|
182
327
|
|
|
328
|
+
</details>
|
|
329
|
+
|
|
330
|
+
<details> <summary>JSON Schema (click to expand)</summary>
|
|
331
|
+
|
|
332
|
+
```json
|
|
333
|
+
{
|
|
334
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
335
|
+
"$id": "movie_research_demo",
|
|
336
|
+
"type": "object",
|
|
337
|
+
"properties": {
|
|
338
|
+
"movie": {
|
|
339
|
+
"type": "string",
|
|
340
|
+
"title": "Movie",
|
|
341
|
+
"minLength": 1,
|
|
342
|
+
"maxLength": 300
|
|
343
|
+
},
|
|
344
|
+
"mpaa_rating": {
|
|
345
|
+
"type": "string",
|
|
346
|
+
"enum": ["g", "pg", "pg_13", "r", "nc_17", "nr"],
|
|
347
|
+
"title": "MPAA Rating"
|
|
348
|
+
},
|
|
349
|
+
"ratings_table": {
|
|
350
|
+
"type": "array",
|
|
351
|
+
"items": {
|
|
352
|
+
"type": "object",
|
|
353
|
+
"properties": {
|
|
354
|
+
"source": { "title": "Source", "type": "string" },
|
|
355
|
+
"score": { "title": "Score", "type": "number" },
|
|
356
|
+
"votes": { "title": "Votes", "type": "number" }
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
"title": "Ratings",
|
|
360
|
+
"minItems": 0,
|
|
361
|
+
"maxItems": 3
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
"required": ["movie", "ratings_table"]
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
</details>
|
|
369
|
+
|
|
183
370
|
### More Example Forms
|
|
184
371
|
|
|
185
372
|
The package includes example forms.
|
|
@@ -192,14 +379,103 @@ View them with `markform examples --list`, copy with `markform examples`, and ru
|
|
|
192
379
|
- [`movie-research-demo.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research-demo.form.md)
|
|
193
380
|
\- The quick example above.
|
|
194
381
|
|
|
195
|
-
- [`movie-research
|
|
196
|
-
\-
|
|
382
|
+
- [`movie-deep-research.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-deep-research.form.md)
|
|
383
|
+
\- Comprehensive movie analysis with streaming, box office, technical specs.
|
|
384
|
+
|
|
385
|
+
### Why a New Format?
|
|
386
|
+
|
|
387
|
+
The closest alternatives I’ve seen are:
|
|
388
|
+
|
|
389
|
+
- Plain Markdown docs can be used as templates and filled in by agents.
|
|
390
|
+
These are more expressive, but it is hard to edit them programmatically or use LLMs to
|
|
391
|
+
update them reliably.
|
|
392
|
+
|
|
393
|
+
- JSON + JSON Schema which are good for struture but terrible for additional
|
|
394
|
+
unstructured context like instructions Markdown.
|
|
395
|
+
|
|
396
|
+
- Agent to-do lists are part of many chat or coding interfaces and are programmatically
|
|
397
|
+
edited by agents. But these are limited to simple checklists, not forms with other
|
|
398
|
+
fields.
|
|
399
|
+
|
|
400
|
+
- Numerous tools like Typeform, Google Forms, PDF forms, and Docusign offer
|
|
401
|
+
human-friendly UI. But these do not have a human-friendly text format for use by
|
|
402
|
+
agents as well as humans.
|
|
403
|
+
|
|
404
|
+
| Approach | Usable GUI editor | Human-readable source format | Agent-editable | APIs and validation rules |
|
|
405
|
+
| --- | :---: | :---: | :---: | :---: |
|
|
406
|
+
| Plain Markdown | ✅<br>IDEs/editors | ✅ | ⚠️<br>fragile | ❌ |
|
|
407
|
+
| JSON + JSON Schema | ✅<br>IDEs/editors | ⚠️<br>no free text | ✅ | ✅ |
|
|
408
|
+
| SaaS tools (Typeform, Docusign, PDF forms) | ✅ | ⚠️<br>rarely | ⚠️<br>sometimes | ⚠️<br>sometimes |
|
|
409
|
+
| HTML/web Forms | ✅<br>IDEs/editors | ⚠️<br>HTML+code | ⚠️<br>coding agent | ✅ |
|
|
410
|
+
| Excel/Google Sheets | ✅<br>app | ❌<br>.csv/.xlsx | ⚠️<br>with tools | ✅<br>with some coding |
|
|
411
|
+
| **Markform** | ✅<br>IDEs/editors | ✅ | ✅<br>with this package | ✅<br>with this package |
|
|
412
|
+
|
|
413
|
+
## Architecture
|
|
414
|
+
|
|
415
|
+
This repo has a specification and an implementation.
|
|
416
|
+
The implementation is a TypeScript API with Vercel AI SDK integration, and a CLI
|
|
417
|
+
interface.
|
|
197
418
|
|
|
198
|
-
|
|
199
|
-
|
|
419
|
+
```mermaid
|
|
420
|
+
flowchart LR
|
|
421
|
+
subgraph SPEC["<b>MARKFORM SPEC</b>"]
|
|
422
|
+
direction TB
|
|
200
423
|
|
|
201
|
-
|
|
202
|
-
|
|
424
|
+
subgraph L1["<b>LAYER 1: SYNTAX</b><br/>Markdoc tag syntax and frontmatter (form, group, string-field, checkboxes, etc.)"]
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
subgraph L2["<b>LAYER 2: FORM DATA MODEL</b><br/>Schema definitions for forms, fields, values (in Zod but mappable to JSON Schema or Pydantic)"]
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
subgraph L3["<b>LAYER 3: VALIDATION & FORM FILLING</b><br/>Rules for filling forms via patches, field ids, required field semantics, validation hooks"]
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
subgraph L4["<b>LAYER 4: TOOL API & INTERFACES</b><br/>Abstract API for agents and humans (TypeScript and AI SDK integration)"]
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
L4 --> L3 --> L2 --> L1
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
subgraph IMPL["<b>THIS IMPLEMENTATION</b>"]
|
|
440
|
+
direction TB
|
|
441
|
+
|
|
442
|
+
subgraph CLI["<b>`markform` CLI</b><br/>Command-line interface to all features"]
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
subgraph AGENT["<b>AGENT TOOL INTERFACE</b><br/>Tool API library using AI SDK tools"]
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
subgraph HARNESS["<b>EXECUTION HARNESS</b><br/>Step-by-step form-filling agentic loop"]
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
subgraph ENGINE["<b>CORE TYPESCRIPT APIS</b><br/>Markdoc parser, serializer, patch application, validation (uses jiti for TypeScript rules)"]
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
subgraph TEST["<b>TESTING FRAMEWORK</b><br/>Golden session testing with .session.yaml transcripts"]
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
CLI --> ENGINE
|
|
458
|
+
CLI --> HARNESS
|
|
459
|
+
AGENT --> HARNESS
|
|
460
|
+
AGENT --> ENGINE
|
|
461
|
+
HARNESS --> ENGINE
|
|
462
|
+
ENGINE --> TEST
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
SPEC ~~~ IMPL
|
|
466
|
+
|
|
467
|
+
style SPEC fill:#e8f4f8,stroke:#0077b6
|
|
468
|
+
style L1 fill:#caf0f8,stroke:#0077b6
|
|
469
|
+
style L2 fill:#caf0f8,stroke:#0077b6
|
|
470
|
+
style L3 fill:#caf0f8,stroke:#0077b6
|
|
471
|
+
style L4 fill:#caf0f8,stroke:#0077b6
|
|
472
|
+
style IMPL fill:#fff3e6,stroke:#fb8500
|
|
473
|
+
style ENGINE fill:#ffe8cc,stroke:#fb8500
|
|
474
|
+
style CLI fill:#ffe8cc,stroke:#fb8500
|
|
475
|
+
style AGENT fill:#ffe8cc,stroke:#fb8500
|
|
476
|
+
style HARNESS fill:#ffe8cc,stroke:#fb8500
|
|
477
|
+
style TEST fill:#ffe8cc,stroke:#fb8500
|
|
478
|
+
```
|
|
203
479
|
|
|
204
480
|
## CLI Commands
|
|
205
481
|
|
|
@@ -208,10 +484,8 @@ View them with `markform examples --list`, copy with `markform examples`, and ru
|
|
|
208
484
|
```bash
|
|
209
485
|
# Copy all bundled examples to ./forms/
|
|
210
486
|
markform examples
|
|
211
|
-
|
|
212
487
|
# List available examples
|
|
213
488
|
markform examples --list
|
|
214
|
-
|
|
215
489
|
# Copy a specific example
|
|
216
490
|
markform examples --name movie-research-demo
|
|
217
491
|
```
|
|
@@ -221,7 +495,6 @@ markform examples --name movie-research-demo
|
|
|
221
495
|
```bash
|
|
222
496
|
# Browse forms in ./forms/ and run one interactively
|
|
223
497
|
markform run
|
|
224
|
-
|
|
225
498
|
# Run a specific form directly
|
|
226
499
|
markform run forms/movie-research-demo.form.md
|
|
227
500
|
```
|
|
@@ -238,7 +511,6 @@ markform status my-form.form.md
|
|
|
238
511
|
```bash
|
|
239
512
|
# View form structure, progress, and validation issues
|
|
240
513
|
markform inspect my-form.form.md
|
|
241
|
-
|
|
242
514
|
# Output as JSON
|
|
243
515
|
markform inspect my-form.form.md --format=json
|
|
244
516
|
```
|
|
@@ -248,10 +520,8 @@ markform inspect my-form.form.md --format=json
|
|
|
248
520
|
```bash
|
|
249
521
|
# Interactive mode: fill user-role fields via prompts
|
|
250
522
|
markform fill my-form.form.md --interactive
|
|
251
|
-
|
|
252
523
|
# Agent mode: use an LLM to fill agent-role fields
|
|
253
524
|
markform fill my-form.form.md --model=anthropic/claude-sonnet-4-5
|
|
254
|
-
|
|
255
525
|
# Mock agent for testing (uses pre-filled form as source)
|
|
256
526
|
markform fill my-form.form.md --mock --mock-source filled.form.md
|
|
257
527
|
```
|
|
@@ -261,22 +531,30 @@ markform fill my-form.form.md --mock --mock-source filled.form.md
|
|
|
261
531
|
```bash
|
|
262
532
|
# Export as readable markdown (strips Markdoc tags)
|
|
263
533
|
markform export my-form.form.md --format=markdown
|
|
264
|
-
|
|
265
534
|
# Export values as JSON
|
|
266
535
|
markform export my-form.form.md --format=json
|
|
267
|
-
|
|
268
536
|
# Export values as YAML
|
|
269
537
|
markform export my-form.form.md --format=yaml
|
|
270
|
-
|
|
271
538
|
# Dump just the current values
|
|
272
539
|
markform dump my-form.form.md
|
|
273
540
|
```
|
|
274
541
|
|
|
542
|
+
### Export JSON Schema
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
# Export form structure as JSON Schema (for validation, code generation, etc.)
|
|
546
|
+
markform schema my-form.form.md
|
|
547
|
+
# Pure JSON Schema without Markform extensions
|
|
548
|
+
markform schema my-form.form.md --pure
|
|
549
|
+
# Specify JSON Schema draft version
|
|
550
|
+
markform schema my-form.form.md --draft draft-07
|
|
551
|
+
```
|
|
552
|
+
|
|
275
553
|
### Apply Patches
|
|
276
554
|
|
|
277
555
|
```bash
|
|
278
556
|
# Apply a JSON patch to update field values
|
|
279
|
-
markform apply my-form.form.md --patch '[{"op":"
|
|
557
|
+
markform apply my-form.form.md --patch '[{"op":"set_string","fieldId":"name","value":"Alice"}]'
|
|
280
558
|
```
|
|
281
559
|
|
|
282
560
|
### Web Interface
|
|
@@ -291,105 +569,37 @@ markform serve my-form.form.md
|
|
|
291
569
|
```bash
|
|
292
570
|
# Quick reference for writing forms (agent-friendly)
|
|
293
571
|
markform docs
|
|
294
|
-
|
|
295
572
|
# Full specification
|
|
296
573
|
markform spec
|
|
297
|
-
|
|
298
574
|
# TypeScript and AI SDK API documentation
|
|
299
575
|
markform apis
|
|
300
|
-
|
|
301
576
|
# This README
|
|
302
577
|
markform readme
|
|
303
|
-
|
|
304
578
|
# See supported AI providers and example models
|
|
305
579
|
markform models
|
|
306
|
-
|
|
307
580
|
# See all commands
|
|
308
581
|
markform --help
|
|
309
582
|
```
|
|
310
583
|
|
|
311
|
-
##
|
|
312
|
-
|
|
313
|
-
Standard LLMs can be used to fill in forms or create research reports from form
|
|
314
|
-
templates. The package currently has support for these models built in, and enables web
|
|
315
|
-
search tools for them if possible.
|
|
316
|
-
|
|
317
|
-
| Provider | Env Variable | Example Models |
|
|
318
|
-
| --- | --- | --- |
|
|
319
|
-
| openai | `OPENAI_API_KEY` | gpt-5-mini, gpt-5.1, gpt-5.2 |
|
|
320
|
-
| anthropic | `ANTHROPIC_API_KEY` | claude-sonnet-4-5, claude-opus-4-5 |
|
|
321
|
-
| google | `GOOGLE_API_KEY` | gemini-2.5-pro, gemini-2.5-flash |
|
|
322
|
-
| xai | `XAI_API_KEY` | grok-4, grok-4-fast |
|
|
323
|
-
| deepseek | `DEEPSEEK_API_KEY` | deepseek-chat, deepseek-reasoner |
|
|
584
|
+
## API Key Setup
|
|
324
585
|
|
|
325
586
|
Set the appropriate environment variable for your provider before running `markform
|
|
326
|
-
fill
|
|
327
|
-
[`src/settings.ts`](https://github.com/jlevy/markform/blob/main/packages/markform/src/settings.ts)
|
|
328
|
-
for the full list of models.
|
|
329
|
-
|
|
330
|
-
## Architecture
|
|
331
|
-
|
|
332
|
-
```mermaid
|
|
333
|
-
flowchart LR
|
|
334
|
-
subgraph SPEC["<b>MARKFORM SPEC</b>"]
|
|
335
|
-
direction TB
|
|
336
|
-
|
|
337
|
-
subgraph L1["<b>LAYER 1: SYNTAX</b><br/>Markdoc tag syntax and frontmatter (form, group, string-field, checkboxes, etc.)"]
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
subgraph L2["<b>LAYER 2: FORM DATA MODEL</b><br/>Schema definitions for forms, fields, values (in Zod but mappable to JSON Schema or Pydantic)"]
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
subgraph L3["<b>LAYER 3: VALIDATION & FORM FILLING</b><br/>Rules for filling forms via patches, field ids, required field semantics, validation hooks"]
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
subgraph L4["<b>LAYER 4: TOOL API & INTERFACES</b><br/>Abstract API for agents and humans (TypeScript and AI SDK integration)"]
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
L4 -->
|
|
350
|
-
|
|
351
|
-
L3 --> L2 --> L1
|
|
352
|
-
end
|
|
353
|
-
|
|
354
|
-
subgraph IMPL["<b>THIS IMPLEMENTATION</b>"]
|
|
355
|
-
direction TB
|
|
356
|
-
|
|
357
|
-
subgraph ENGINE["<b>ENGINE IMPLEMENTATION</b><br/>Markdoc parser, serializer, patch application, validation (uses jiti for TypeScript rules)"]
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
subgraph UI["<b>USER INTERFACES</b><br/>CLI commands, web UI (serve), render to HTML"]
|
|
361
|
-
end
|
|
362
|
-
|
|
363
|
-
subgraph AGENT["<b>AGENT INTERFACES</b><br/>Tool API library, MCP server, AI SDK tools"]
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
subgraph HARNESS["<b>EXECUTION HARNESS</b><br/>Step-by-step form-filling agentic loop"]
|
|
367
|
-
end
|
|
587
|
+
fill`:
|
|
368
588
|
|
|
369
|
-
|
|
370
|
-
|
|
589
|
+
| Provider | Env Variable | Native Web Search |
|
|
590
|
+
| --- | --- | :---: |
|
|
591
|
+
| openai | `OPENAI_API_KEY` | ✓ |
|
|
592
|
+
| anthropic | `ANTHROPIC_API_KEY` | ✓ |
|
|
593
|
+
| google | `GOOGLE_API_KEY` | ✓ |
|
|
594
|
+
| xai | `XAI_API_KEY` | ✓ |
|
|
595
|
+
| deepseek | `DEEPSEEK_API_KEY` | ✗ |
|
|
371
596
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
ENGINE --> TEST
|
|
377
|
-
end
|
|
597
|
+
Run `markform models` to see available models.
|
|
598
|
+
See
|
|
599
|
+
[`src/settings.ts`](https://github.com/jlevy/markform/blob/main/packages/markform/src/settings.ts)
|
|
600
|
+
for defaults.
|
|
378
601
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
style SPEC fill:#e8f4f8,stroke:#0077b6
|
|
382
|
-
style L1 fill:#caf0f8,stroke:#0077b6
|
|
383
|
-
style L2 fill:#caf0f8,stroke:#0077b6
|
|
384
|
-
style L3 fill:#caf0f8,stroke:#0077b6
|
|
385
|
-
style L4 fill:#caf0f8,stroke:#0077b6
|
|
386
|
-
style IMPL fill:#fff3e6,stroke:#fb8500
|
|
387
|
-
style ENGINE fill:#ffe8cc,stroke:#fb8500
|
|
388
|
-
style UI fill:#ffe8cc,stroke:#fb8500
|
|
389
|
-
style AGENT fill:#ffe8cc,stroke:#fb8500
|
|
390
|
-
style HARNESS fill:#ffe8cc,stroke:#fb8500
|
|
391
|
-
style TEST fill:#ffe8cc,stroke:#fb8500
|
|
392
|
-
```
|
|
602
|
+
If unsure, try `gpt-5-mini` first as it’s fast and supports web search.
|
|
393
603
|
|
|
394
604
|
## Programmatic Usage
|
|
395
605
|
|
|
@@ -399,17 +609,17 @@ applications.
|
|
|
399
609
|
### Basic Parsing
|
|
400
610
|
|
|
401
611
|
```typescript
|
|
402
|
-
import { parseForm,
|
|
612
|
+
import { parseForm, serialize } from "markform";
|
|
403
613
|
|
|
404
614
|
// Parse a .form.md file
|
|
405
615
|
const form = parseForm(markdownContent);
|
|
406
616
|
|
|
407
617
|
// Access schema and values
|
|
408
618
|
console.log(form.schema.title);
|
|
409
|
-
console.log(form.
|
|
619
|
+
console.log(form.responsesByFieldId);
|
|
410
620
|
|
|
411
621
|
// Serialize back to markdown
|
|
412
|
-
const output =
|
|
622
|
+
const output = serialize(form);
|
|
413
623
|
```
|
|
414
624
|
|
|
415
625
|
### AI SDK Integration
|
|
@@ -422,10 +632,14 @@ import { createMarkformTools, MarkformSessionStore } from "markform/ai-sdk";
|
|
|
422
632
|
import { generateText } from "ai";
|
|
423
633
|
import { anthropic } from "@ai-sdk/anthropic";
|
|
424
634
|
|
|
635
|
+
// Parse form and create session store (tracks state across tool calls)
|
|
425
636
|
const form = parseForm(markdownContent);
|
|
426
637
|
const store = new MarkformSessionStore(form);
|
|
638
|
+
|
|
639
|
+
// Create tools the agent can call: inspect, apply patches, export
|
|
427
640
|
const tools = createMarkformTools({ sessionStore: store });
|
|
428
641
|
|
|
642
|
+
// Agent fills the form via tool calls until complete or maxSteps reached
|
|
429
643
|
const result = await generateText({
|
|
430
644
|
model: anthropic("claude-sonnet-4-5-20250929"),
|
|
431
645
|
prompt: "Fill out this form with appropriate values...",
|
|
@@ -443,11 +657,32 @@ const result = await generateText({
|
|
|
443
657
|
| `markform_export` | Export schema and values as JSON |
|
|
444
658
|
| `markform_get_markdown` | Get canonical Markdown representation |
|
|
445
659
|
|
|
660
|
+
## Other Documentation
|
|
661
|
+
|
|
662
|
+
- **[Quick
|
|
663
|
+
Reference](https://github.com/jlevy/markform/blob/main/docs/markform-reference.md)**
|
|
664
|
+
(or run `markform docs`) — Concise syntax reference (agent-friendly)
|
|
665
|
+
|
|
666
|
+
- **[Markform Spec](https://github.com/jlevy/markform/blob/main/docs/markform-spec.md)**
|
|
667
|
+
(or run `markform spec`) — Complete syntax and semantics
|
|
668
|
+
|
|
669
|
+
- **[API
|
|
670
|
+
Documentation](https://github.com/jlevy/markform/blob/main/docs/markform-apis.md)**
|
|
671
|
+
(or run `markform apis`) — TypeScript and AI SDK APIs
|
|
672
|
+
|
|
673
|
+
- **[Design
|
|
674
|
+
Doc](https://github.com/jlevy/markform/blob/main/docs/project/architecture/current/arch-markform-design.md)**
|
|
675
|
+
— Technical design and roadmap
|
|
676
|
+
|
|
677
|
+
- **[Development](https://github.com/jlevy/markform/blob/main/docs/development.md)** —
|
|
678
|
+
Build, test, and contribute
|
|
679
|
+
|
|
446
680
|
## FAQ
|
|
447
681
|
|
|
448
|
-
### Can you
|
|
682
|
+
### Can you talk more about why forms are cool?
|
|
449
683
|
|
|
450
|
-
|
|
684
|
+
As a matter of fact, I can!
|
|
685
|
+
I’ve come to believe forms are a missing piece of the workflow problem with agents.
|
|
451
686
|
For deep research or complex multi-step workflows, key pieces need to be *precisely
|
|
452
687
|
controlled*, *domain-specific*, and *always improving*. You need precise documentation
|
|
453
688
|
on the key intermediate states and final output from an AI pipeline.
|
|
@@ -458,6 +693,27 @@ Forms define these pieces and are easy to edit.
|
|
|
458
693
|
All other choices can be left to the agents themselves, with the structure and
|
|
459
694
|
validations enforced by the form-filling tools the agents use.
|
|
460
695
|
|
|
696
|
+
Another cool thing about forms: they get rid of the inefficiencies of conversation chat
|
|
697
|
+
history.
|
|
698
|
+
Often when an agentic loop is built, it just saves the chat history for context.
|
|
699
|
+
But a form is inherently more efficient: the harness itself can be stateless.
|
|
700
|
+
It just shares the partly-filled form with the agent, and it has full context in one
|
|
701
|
+
message. That’s what the agentic loop in this implementation does.
|
|
702
|
+
|
|
703
|
+
Finally, the meta-loop of *creating and improving* forms is easier to automate:
|
|
704
|
+
|
|
705
|
+
- To get started, you can ask a good coding model to convert any unstructured doc
|
|
706
|
+
describing a process to a form.
|
|
707
|
+
The model can also use the CLI or tools to validate and test it.
|
|
708
|
+
|
|
709
|
+
- Any time you have a workflow problem, you can ask an LLM to diagnose it and if
|
|
710
|
+
possible, go back and fix up the form with additional instructions or fields or checks
|
|
711
|
+
that would prevent the problem from happening again.
|
|
712
|
+
|
|
713
|
+
I suspect dynamic form structures like this could make complex deep research more
|
|
714
|
+
powerful. Just as you plan a spec before implementing with a coding agent, you could use
|
|
715
|
+
Markform to encode a research plan before dispatching agents to fill it.
|
|
716
|
+
|
|
461
717
|
### Is this mature?
|
|
462
718
|
|
|
463
719
|
No! I just wrote it.
|
|
@@ -478,11 +734,11 @@ See
|
|
|
478
734
|
for more thoughts on how this works.
|
|
479
735
|
And see [the complete history of
|
|
480
736
|
specs](https://github.com/jlevy/markform/tree/main/docs/project/specs/done) for examples
|
|
481
|
-
of how everything is done with specs
|
|
737
|
+
of how everything is done with specs.
|
|
482
738
|
|
|
483
|
-
Although I didn’t
|
|
484
|
-
|
|
485
|
-
And this
|
|
739
|
+
Although I didn’t write much code, there was a *lot* of management, review, and
|
|
740
|
+
iteration on design decisions.
|
|
741
|
+
And yes, this README is written by me.
|
|
486
742
|
:)
|
|
487
743
|
|
|
488
744
|
### What are the goals of Markform?
|
|
@@ -522,31 +778,6 @@ This enables powerful AI workflows that assemble information in a defined struct
|
|
|
522
778
|
- An **agent execution harness** for step-by-step form filling, enabling deep research
|
|
523
779
|
agents that assemble validated output in a structured format.
|
|
524
780
|
|
|
525
|
-
### Does anything like this already exist?
|
|
526
|
-
|
|
527
|
-
Not that I have seen.
|
|
528
|
-
The closest alternatives are:
|
|
529
|
-
|
|
530
|
-
- Plain Markdown docs can be used as templates and filled in by agents.
|
|
531
|
-
These are more expressive, but it is hard to edit them programmatically or use LLMs to
|
|
532
|
-
update them reliably.
|
|
533
|
-
|
|
534
|
-
- Agent to-do lists are part of many chat or coding interfaces and are programmatically
|
|
535
|
-
edited by agents. But these are limited to simple checklists, not forms with other
|
|
536
|
-
fields.
|
|
537
|
-
|
|
538
|
-
- Numerous tools like Typeform, Google Forms, PDF forms, and Docusign offer
|
|
539
|
-
human-friendly UI. But these do not have a human-friendly text format for use by
|
|
540
|
-
agents as well as humans.
|
|
541
|
-
|
|
542
|
-
| Approach | Has GUI | Human-readable source format | Agent-editable | APIs and validation rules |
|
|
543
|
-
| --- | :---: | :---: | :---: | :---: |
|
|
544
|
-
| Plain Markdown | ☑️ existing tools | ✅ | ⚠️ fragile | ❌ |
|
|
545
|
-
| JSON with schema | ⚠️ in some apps | ⚠️ um it’s JSON | ✅ | ✅ |
|
|
546
|
-
| SaaS tools (Typeform, Docusign, PDF forms) | ✅ | ⚠️ rarely | ⚠️ if they add it | ⚠️ if they add it |
|
|
547
|
-
| Excel/Google Sheets | ✅ | ❌ .csv (poor) or .xlsx (worse) | ⚠️ with tools | ✅ with some coding |
|
|
548
|
-
| **Markform** | ☑️ existing tools | ✅ | ✅ with this package | ✅ with this package |
|
|
549
|
-
|
|
550
781
|
### What are example use cases?
|
|
551
782
|
|
|
552
783
|
- Deep research tools where agents need to follow codified processes to assemble
|
|
@@ -587,26 +818,6 @@ settings:
|
|
|
587
818
|
|
|
588
819
|
Or see [markdoc/language-server](https://github.com/markdoc/language-server).
|
|
589
820
|
|
|
590
|
-
## Documentation
|
|
591
|
-
|
|
592
|
-
- **[Quick
|
|
593
|
-
Reference](https://github.com/jlevy/markform/blob/main/docs/markform-reference.md)**
|
|
594
|
-
(or run `markform docs`) - Concise syntax reference (agent-friendly)
|
|
595
|
-
|
|
596
|
-
- **[Markform Spec](https://github.com/jlevy/markform/blob/main/docs/markform-spec.md)**
|
|
597
|
-
(or run `markform spec`) - Complete syntax and semantics
|
|
598
|
-
|
|
599
|
-
- **[API
|
|
600
|
-
Documentation](https://github.com/jlevy/markform/blob/main/docs/markform-apis.md)**
|
|
601
|
-
(or run `markform apis`) - TypeScript and AI SDK APIs
|
|
602
|
-
|
|
603
|
-
- **[Design
|
|
604
|
-
Doc](https://github.com/jlevy/markform/blob/main/docs/project/architecture/current/arch-markform-design.md)**
|
|
605
|
-
\- Technical design and roadmap
|
|
606
|
-
|
|
607
|
-
- **[Development](https://github.com/jlevy/markform/blob/main/docs/development.md)** -
|
|
608
|
-
Build, test, and contribute
|
|
609
|
-
|
|
610
821
|
## License
|
|
611
822
|
|
|
612
823
|
AGPL-3.0-or-later. [Contact me](https://github.com/jlevy) for additional licensing
|