markform 0.1.11 → 0.1.13

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/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
- import { $ as SetUrlListPatchSchema, A as MultiCheckboxStateSchema, At as WireToolResultSchema, B as ProgressSummarySchema, C as HarnessConfigSchema, Ct as ValidationIssueSchema, D as IssueReasonSchema, Dt as WireResponseFormatSchema, E as InspectResultSchema, Et as WireRequestFormatSchema, F as OptionIdSchema, G as SetCheckboxesPatchSchema, H as SessionFinalSchema, I as OptionSchema, J as SetNumberPatchSchema, K as SetDatePatchSchema, L as PatchSchema, M as MultiSelectValueSchema, Mt as YearValueSchema, N as NumberFieldSchema, O as IssueScopeSchema, Ot as WireResponseStepSchema, P as NumberValueSchema, Q as SetTablePatchSchema, R as ProgressCountsSchema, S as FormSchemaSchema, St as UrlValueSchema, T as InspectIssueSchema, Tt as WireFormatSchema, U as SessionTranscriptSchema, V as RunModeSchema, W as SessionTurnSchema, X as SetStringListPatchSchema, Y as SetSingleSelectPatchSchema, Z as SetStringPatchSchema, _ as FieldKindSchema, _t as TableRowResponseSchema, a as CheckboxProgressCountsSchema, at as SingleSelectValueSchema, b as FieldSchema, bt as UrlListFieldSchema, c as CheckboxesValueSchema, ct as StepResultSchema, d as DateFieldSchema, dt as StringListValueSchema, et as SetUrlPatchSchema, f as DateValueSchema, ft as StringValueSchema, g as FieldGroupSchema, gt as TableRowPatchSchema, h as ExplicitCheckboxValueSchema, ht as TableFieldSchema, i as CheckboxModeSchema, it as SingleSelectFieldSchema, j as MultiSelectFieldSchema, jt as YearFieldSchema, k as MarkformFrontmatterSchema, kt as WireToolCallSchema, l as ClearFieldPatchSchema, lt as StringFieldSchema, m as DocumentationTagSchema, mt as TableColumnSchema, n as ApplyResultSchema, nt as SeveritySchema, o as CheckboxValueSchema, ot as SourcePositionSchema, p as DocumentationBlockSchema, pt as StructureSummarySchema, q as SetMultiSelectPatchSchema, r as CellResponseSchema, rt as SimpleCheckboxStateSchema, s as CheckboxesFieldSchema, st as SourceRangeSchema, t as AnswerStateSchema, tt as SetYearPatchSchema, u as ColumnTypeNameSchema, ut as StringListFieldSchema, v as FieldProgressSchema, vt as TableValueSchema, w as IdSchema, wt as ValidatorRefSchema, x as FieldValueSchema, xt as UrlListValueSchema, y as FieldResponseSchema, yt as UrlFieldSchema, z as ProgressStateSchema } from "./coreTypes-Z8SvQyoL.mjs";
3
- import { $ as isPatchError, B as MarkformAbortError, G as MarkformPatchError, H as MarkformError, J as isAbortError, K as MarkformValidationError, Q as isParseError, U as MarkformLlmError, V as MarkformConfigError, W as MarkformParseError, X as isLlmError, Y as isConfigError, Z as isMarkformError, a as validate, c as computeProgressSummary, d as serializeForm, et as isRetryableError, i as inspect, l as computeStructureSummary, o as computeAllSummaries, p as serializeReport, q as ParseError, s as computeFormState, t as applyPatches, tt as isValidationError, u as isFormComplete } from "./apply-yfRtNIHc.mjs";
4
- import { A as parseRawTable, C as parseScopeRef, D as parseForm, E as formToJsonSchema, O as parseCellValue, S as isQualifiedRef, T as fieldToJsonSchema, _ as coerceToFieldPatch, a as resolveHarnessConfig, b as isCellRef, f as MockAgent, g as coerceInputContext, h as createHarness, i as runResearch, k as parseMarkdownTable, m as FormHarness, n as isResearchForm, o as fillForm, p as createMockAgent, r as validateResearchForm, t as VERSION, v as findFieldById, w as serializeScopeRef, x as isFieldRef, y as getFieldId } from "./src-ozWOSQTW.mjs";
5
- import { n as serializeSession, t as parseSession } from "./session-DX-DvjRP.mjs";
2
+ import { $ as SetUrlListPatchSchema, A as MultiCheckboxStateSchema, At as WireToolResultSchema, B as ProgressSummarySchema, C as HarnessConfigSchema, Ct as ValidationIssueSchema, D as IssueReasonSchema, Dt as WireResponseFormatSchema, E as InspectResultSchema, Et as WireRequestFormatSchema, F as OptionIdSchema, G as SetCheckboxesPatchSchema, H as SessionFinalSchema, I as OptionSchema, J as SetNumberPatchSchema, K as SetDatePatchSchema, L as PatchSchema, M as MultiSelectValueSchema, Mt as YearValueSchema, N as NumberFieldSchema, O as IssueScopeSchema, Ot as WireResponseStepSchema, P as NumberValueSchema, Q as SetTablePatchSchema, R as ProgressCountsSchema, S as FormSchemaSchema, St as UrlValueSchema, T as InspectIssueSchema, Tt as WireFormatSchema, U as SessionTranscriptSchema, V as RunModeSchema, W as SessionTurnSchema, X as SetStringListPatchSchema, Y as SetSingleSelectPatchSchema, Z as SetStringPatchSchema, _ as FieldKindSchema, _t as TableRowResponseSchema, a as CheckboxProgressCountsSchema, at as SingleSelectValueSchema, b as FieldSchema, bt as UrlListFieldSchema, c as CheckboxesValueSchema, ct as StepResultSchema, d as DateFieldSchema, dt as StringListValueSchema, et as SetUrlPatchSchema, f as DateValueSchema, ft as StringValueSchema, g as FieldGroupSchema, gt as TableRowPatchSchema, h as ExplicitCheckboxValueSchema, ht as TableFieldSchema, i as CheckboxModeSchema, it as SingleSelectFieldSchema, j as MultiSelectFieldSchema, jt as YearFieldSchema, k as MarkformFrontmatterSchema, kt as WireToolCallSchema, l as ClearFieldPatchSchema, lt as StringFieldSchema, m as DocumentationTagSchema, mt as TableColumnSchema, n as ApplyResultSchema, nt as SeveritySchema, o as CheckboxValueSchema, ot as SourcePositionSchema, p as DocumentationBlockSchema, pt as StructureSummarySchema, q as SetMultiSelectPatchSchema, r as CellResponseSchema, rt as SimpleCheckboxStateSchema, s as CheckboxesFieldSchema, st as SourceRangeSchema, t as AnswerStateSchema, tt as SetYearPatchSchema, u as ColumnTypeNameSchema, ut as StringListFieldSchema, v as FieldProgressSchema, vt as TableValueSchema, w as IdSchema, wt as ValidatorRefSchema, x as FieldValueSchema, xt as UrlListValueSchema, y as FieldResponseSchema, yt as UrlFieldSchema, z as ProgressStateSchema } from "./coreTypes-Big8sgih.mjs";
3
+ import { $ as isParseError, G as MarkformParseError, H as MarkformConfigError, J as ParseError, K as MarkformPatchError, Q as isMarkformError, U as MarkformError, V as MarkformAbortError, W as MarkformLlmError, X as isConfigError, Y as isAbortError, Z as isLlmError, a as validate, c as computeProgressSummary, d as serializeForm, et as isPatchError, i as inspect, l as computeStructureSummary, nt as isValidationError, o as computeAllSummaries, p as serializeReport, q as MarkformValidationError, s as computeFormState, t as applyPatches, tt as isRetryableError, u as isFormComplete } from "./apply-D5FLd9Yp.mjs";
4
+ import { A as parseRawTable, C as parseScopeRef, D as parseForm, E as formToJsonSchema, O as parseCellValue, S as isQualifiedRef, T as fieldToJsonSchema, _ as coerceToFieldPatch, a as resolveHarnessConfig, b as isCellRef, f as MockAgent, g as coerceInputContext, h as createHarness, i as runResearch, k as parseMarkdownTable, m as FormHarness, n as isResearchForm, o as fillForm, p as createMockAgent, r as validateResearchForm, t as VERSION, v as findFieldById, w as serializeScopeRef, x as isFieldRef, y as getFieldId } from "./src-DuA3kv-E.mjs";
5
+ import { n as serializeSession, t as parseSession } from "./session-CrhOG4eH.mjs";
6
6
 
7
7
  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, MarkformAbortError, MarkformConfigError, MarkformError, MarkformFrontmatterSchema, MarkformLlmError, MarkformParseError, MarkformPatchError, MarkformValidationError, MockAgent, MultiCheckboxStateSchema, MultiSelectFieldSchema, MultiSelectValueSchema, NumberFieldSchema, NumberValueSchema, OptionIdSchema, OptionSchema, ParseError, PatchSchema, ProgressCountsSchema, ProgressStateSchema, ProgressSummarySchema, RunModeSchema, 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, WireFormatSchema, WireRequestFormatSchema, WireResponseFormatSchema, WireResponseStepSchema, WireToolCallSchema, WireToolResultSchema, YearFieldSchema, YearValueSchema, applyPatches, coerceInputContext, coerceToFieldPatch, computeAllSummaries, computeFormState, computeProgressSummary, computeStructureSummary, createHarness, createMockAgent, fieldToJsonSchema, fillForm, findFieldById, formToJsonSchema, getFieldId, inspect, isAbortError, isCellRef, isConfigError, isFieldRef, isFormComplete, isLlmError, isMarkformError, isParseError, isPatchError, isQualifiedRef, isResearchForm, isRetryableError, isValidationError, parseCellValue, parseForm, parseMarkdownTable, parseRawTable, parseScopeRef, parseSession, resolveHarnessConfig, runResearch, serializeForm, serializeReport, serializeScopeRef, serializeSession, validate, validateResearchForm };
@@ -1,4 +1,4 @@
1
1
 
2
- import { n as serializeSession, t as parseSession } from "./session-DX-DvjRP.mjs";
2
+ import { n as serializeSession, t as parseSession } from "./session-CrhOG4eH.mjs";
3
3
 
4
4
  export { serializeSession };
@@ -1,5 +1,5 @@
1
1
 
2
- import { U as SessionTranscriptSchema } from "./coreTypes-Z8SvQyoL.mjs";
2
+ import { U as SessionTranscriptSchema } from "./coreTypes-Big8sgih.mjs";
3
3
  import YAML from "yaml";
4
4
 
5
5
  //#region src/engine/session.ts
@@ -1,6 +1,6 @@
1
1
 
2
- import { L as PatchSchema, V as RunModeSchema } from "./coreTypes-Z8SvQyoL.mjs";
3
- import { C as DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN, L as getWebSearchConfig, S as DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN, T as DEFAULT_ROLE_INSTRUCTIONS, V as MarkformConfigError, W as MarkformParseError, _ as DEFAULT_MAX_ISSUES_PER_TURN, d as serializeForm, i as inspect, m as AGENT_ROLE, r as getFieldsForRoles, t as applyPatches, v as DEFAULT_MAX_PATCHES_PER_TURN, w as DEFAULT_ROLES, x as DEFAULT_PRIORITY, y as DEFAULT_MAX_TURNS } from "./apply-yfRtNIHc.mjs";
2
+ import { L as PatchSchema, V as RunModeSchema } from "./coreTypes-Big8sgih.mjs";
3
+ import { C as DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN, E as DEFAULT_ROLE_INSTRUCTIONS, G as MarkformParseError, H as MarkformConfigError, R as getWebSearchConfig, S as DEFAULT_PRIORITY, T as DEFAULT_ROLES, _ as DEFAULT_MAX_ISSUES_PER_TURN, b as DEFAULT_MAX_TURNS, d as serializeForm, i as inspect, m as AGENT_ROLE, r as getFieldsForRoles, t as applyPatches, v as DEFAULT_MAX_PATCHES_PER_TURN, w as DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN, y as DEFAULT_MAX_STEPS_PER_TURN } from "./apply-D5FLd9Yp.mjs";
4
4
  import { z } from "zod";
5
5
  import Markdoc from "@markdoc/markdoc";
6
6
  import YAML from "yaml";
@@ -2538,12 +2538,12 @@ var FormHarness = class {
2538
2538
  if (this.state !== "wait") throw new Error(`Cannot apply in state: ${this.state}`);
2539
2539
  if (patches.length > this.config.maxPatchesPerTurn) throw new Error(`Too many patches: ${patches.length} > ${this.config.maxPatchesPerTurn}`);
2540
2540
  const applyResult = applyPatches(this.form, patches);
2541
- const patchesActuallyApplied = applyResult.applyStatus === "applied" ? patches.length : 0;
2541
+ const patchesActuallyApplied = applyResult.appliedPatches.length;
2542
2542
  const result = inspect(this.form, { targetRoles: this.config.targetRoles });
2543
2543
  const stepResult = this.computeStepResult(result);
2544
2544
  stepResult.patchesApplied = patchesActuallyApplied;
2545
2545
  stepResult.rejectedPatches = applyResult.rejectedPatches;
2546
- this.recordTurn(issues, patches, result, llmStats, context, applyResult.rejectedPatches, wire);
2546
+ this.recordTurn(issues, patches, result, llmStats, context, applyResult.rejectedPatches, applyResult.warnings, wire);
2547
2547
  if (stepResult.issues.length === 0 || this.turnNumber >= this.config.maxTurns) this.state = "complete";
2548
2548
  else this.state = "wait";
2549
2549
  return stepResult;
@@ -2567,7 +2567,7 @@ var FormHarness = class {
2567
2567
  /**
2568
2568
  * Record a turn in the session transcript.
2569
2569
  */
2570
- recordTurn(issues, patches, result, llmStats, context, rejectedPatches, wire) {
2570
+ recordTurn(issues, patches, result, llmStats, context, rejectedPatches, warnings, wire) {
2571
2571
  const hash = sha256(serializeForm(this.form));
2572
2572
  const requiredIssueCount = result.issues.filter((i) => i.severity === "required").length;
2573
2573
  const turn = {
@@ -2575,7 +2575,8 @@ var FormHarness = class {
2575
2575
  inspect: { issues },
2576
2576
  apply: {
2577
2577
  patches,
2578
- ...rejectedPatches && rejectedPatches.length > 0 && { rejectedPatches }
2578
+ ...rejectedPatches && rejectedPatches.length > 0 && { rejectedPatches },
2579
+ ...warnings && warnings.length > 0 && { warnings }
2579
2580
  },
2580
2581
  after: {
2581
2582
  requiredIssueCount,
@@ -7916,15 +7917,15 @@ function getIssuesIntro(issueCount) {
7916
7917
  const PATCH_FORMATS = {
7917
7918
  string: "{ op: \"set_string\", fieldId: \"...\", value: \"...\" }",
7918
7919
  number: "{ op: \"set_number\", fieldId: \"...\", value: 123 }",
7919
- string_list: "{ op: \"set_string_list\", fieldId: \"...\", items: [\"...\", \"...\"] }",
7920
- single_select: "{ op: \"set_single_select\", fieldId: \"...\", selected: \"option_id\" }",
7921
- multi_select: "{ op: \"set_multi_select\", fieldId: \"...\", selected: [\"opt1\", \"opt2\"] }",
7922
- checkboxes: "{ op: \"set_checkboxes\", fieldId: \"...\", values: { \"opt1\": \"done\", \"opt2\": \"todo\" } }",
7920
+ string_list: "{ op: \"set_string_list\", fieldId: \"...\", value: [\"...\", \"...\"] }",
7921
+ single_select: "{ op: \"set_single_select\", fieldId: \"...\", value: \"option_id\" }",
7922
+ multi_select: "{ op: \"set_multi_select\", fieldId: \"...\", value: [\"opt1\", \"opt2\"] }",
7923
+ checkboxes: "{ op: \"set_checkboxes\", fieldId: \"...\", value: { \"opt1\": \"done\", \"opt2\": \"todo\" } }",
7923
7924
  url: "{ op: \"set_url\", fieldId: \"...\", value: \"https://...\" }",
7924
- url_list: "{ op: \"set_url_list\", fieldId: \"...\", items: [\"https://...\", \"https://...\"] }",
7925
+ url_list: "{ op: \"set_url_list\", fieldId: \"...\", value: [\"https://...\", \"https://...\"] }",
7925
7926
  date: "{ op: \"set_date\", fieldId: \"...\", value: \"2024-01-15\" }",
7926
7927
  year: "{ op: \"set_year\", fieldId: \"...\", value: 2024 }",
7927
- table: "{ op: \"set_table\", fieldId: \"...\", rows: [{ col1: \"value1\", col2: \"value2\" }, ...] }"
7928
+ table: "{ op: \"set_table\", fieldId: \"...\", value: [{ col1: \"value1\", col2: \"value2\" }, ...] }"
7928
7929
  };
7929
7930
  /**
7930
7931
  * Get the correct patch format for a field kind.
@@ -8011,7 +8012,7 @@ var LiveAgent = class {
8011
8012
  callbacks;
8012
8013
  constructor(config) {
8013
8014
  this.model = config.model;
8014
- this.maxStepsPerTurn = config.maxStepsPerTurn ?? 3;
8015
+ this.maxStepsPerTurn = config.maxStepsPerTurn ?? DEFAULT_MAX_STEPS_PER_TURN;
8015
8016
  this.systemPromptAddition = config.systemPromptAddition;
8016
8017
  this.targetRole = config.targetRole ?? AGENT_ROLE;
8017
8018
  this.provider = config.provider;
@@ -8708,12 +8709,14 @@ async function fillForm(options) {
8708
8709
  }
8709
8710
  inputContextWarnings = coercionResult.warnings;
8710
8711
  }
8711
- const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;
8712
+ const maxTurnsTotal = options.maxTurnsTotal ?? DEFAULT_MAX_TURNS;
8713
+ const startingTurnNumber = options.startingTurnNumber ?? 0;
8712
8714
  const maxPatchesPerTurn = options.maxPatchesPerTurn ?? DEFAULT_MAX_PATCHES_PER_TURN;
8713
8715
  const maxIssuesPerTurn = options.maxIssuesPerTurn ?? DEFAULT_MAX_ISSUES_PER_TURN;
8714
8716
  const targetRoles = options.targetRoles ?? [AGENT_ROLE];
8717
+ const remainingTurns = Math.max(0, maxTurnsTotal - startingTurnNumber);
8715
8718
  const harness = createHarness(form, {
8716
- maxTurns,
8719
+ maxTurns: remainingTurns,
8717
8720
  maxPatchesPerTurn,
8718
8721
  maxIssuesPerTurn,
8719
8722
  targetRoles,
@@ -8726,12 +8729,19 @@ async function fillForm(options) {
8726
8729
  provider,
8727
8730
  enableWebSearch: options.enableWebSearch,
8728
8731
  additionalTools: options.additionalTools,
8729
- callbacks: options.callbacks
8732
+ callbacks: options.callbacks,
8733
+ maxStepsPerTurn: options.maxStepsPerTurn
8730
8734
  });
8731
- let turnCount = 0;
8735
+ let turnCount = startingTurnNumber;
8736
+ let turnsThisCall = 0;
8732
8737
  let stepResult = harness.step();
8733
8738
  let previousRejections;
8734
8739
  while (!stepResult.isComplete && !harness.hasReachedMaxTurns()) {
8740
+ if (options.maxTurnsThisCall !== void 0 && turnsThisCall >= options.maxTurnsThisCall) return buildResult(form, turnCount, totalPatches, {
8741
+ ok: false,
8742
+ reason: "batch_limit",
8743
+ message: `Reached per-call limit (${options.maxTurnsThisCall} turns)`
8744
+ }, inputContextWarnings, stepResult.issues);
8735
8745
  if (options.signal?.aborted) return buildResult(form, turnCount, totalPatches, {
8736
8746
  ok: false,
8737
8747
  reason: "cancelled"
@@ -8779,6 +8789,7 @@ async function fillForm(options) {
8779
8789
  const actualPatchesApplied = stepResult.patchesApplied ?? patches.length;
8780
8790
  totalPatches += actualPatchesApplied;
8781
8791
  turnCount++;
8792
+ turnsThisCall++;
8782
8793
  previousRejections = stepResult.rejectedPatches;
8783
8794
  if (options.callbacks?.onTurnComplete) try {
8784
8795
  const requiredIssues = stepResult.issues.filter((i) => i.severity === "required");
@@ -8800,7 +8811,7 @@ async function fillForm(options) {
8800
8811
  return buildResult(form, turnCount, totalPatches, {
8801
8812
  ok: false,
8802
8813
  reason: "max_turns",
8803
- message: `Reached maximum turns (${maxTurns})`
8814
+ message: `Reached maximum total turns (${maxTurnsTotal})`
8804
8815
  }, inputContextWarnings, stepResult.issues);
8805
8816
  }
8806
8817
 
@@ -8821,7 +8832,7 @@ async function fillForm(options) {
8821
8832
  function resolveHarnessConfig(form, options) {
8822
8833
  const frontmatterConfig = form.metadata?.harnessConfig;
8823
8834
  return {
8824
- maxTurns: options?.maxTurns ?? frontmatterConfig?.maxTurns ?? DEFAULT_MAX_TURNS,
8835
+ maxTurns: options?.maxTurnsTotal ?? frontmatterConfig?.maxTurns ?? DEFAULT_MAX_TURNS,
8825
8836
  maxPatchesPerTurn: options?.maxPatchesPerTurn ?? frontmatterConfig?.maxPatchesPerTurn ?? DEFAULT_MAX_PATCHES_PER_TURN,
8826
8837
  maxIssuesPerTurn: options?.maxIssuesPerTurn ?? frontmatterConfig?.maxIssuesPerTurn ?? DEFAULT_MAX_ISSUES_PER_TURN,
8827
8838
  targetRoles: options?.targetRoles,
@@ -8849,7 +8860,7 @@ async function runResearch(form, options) {
8849
8860
  const { model, provider } = await resolveModel(modelSpec);
8850
8861
  const config = {
8851
8862
  ...resolveHarnessConfig(form, options),
8852
- maxTurns: options.maxTurns ?? form.metadata?.harnessConfig?.maxTurns ?? DEFAULT_MAX_TURNS,
8863
+ maxTurns: options.maxTurnsTotal ?? form.metadata?.harnessConfig?.maxTurns ?? DEFAULT_MAX_TURNS,
8853
8864
  maxIssuesPerTurn: options.maxIssuesPerTurn ?? form.metadata?.harnessConfig?.maxIssuesPerTurn ?? DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN,
8854
8865
  maxPatchesPerTurn: options.maxPatchesPerTurn ?? form.metadata?.harnessConfig?.maxPatchesPerTurn ?? DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN,
8855
8866
  targetRoles: options.targetRoles ?? [AGENT_ROLE],
@@ -8948,7 +8959,7 @@ function validateResearchForm(form) {
8948
8959
  //#endregion
8949
8960
  //#region src/index.ts
8950
8961
  /** Markform version (injected at build time). */
8951
- const VERSION = "0.1.11";
8962
+ const VERSION = "0.1.13";
8952
8963
 
8953
8964
  //#endregion
8954
8965
  export { parseRawTable as A, parseScopeRef as C, parseForm as D, formToJsonSchema as E, parseCellValue as O, isQualifiedRef as S, fieldToJsonSchema as T, coerceToFieldPatch as _, resolveHarnessConfig as a, isCellRef as b, getProviderNames as c, createLiveAgent as d, MockAgent as f, coerceInputContext as g, createHarness as h, runResearch as i, parseMarkdownTable as k, resolveModel as l, FormHarness as m, isResearchForm as n, fillForm as o, createMockAgent as p, validateResearchForm as r, getProviderInfo as s, VERSION as t, buildMockWireFormat as u, findFieldById as v, serializeScopeRef as w, isFieldRef as x, getFieldId as y };
@@ -53,11 +53,13 @@ Generate a filtered markdown report suitable for sharing.
53
53
  Produces clean, readable markdown with:
54
54
 
55
55
  - Fields and groups with `report=false` excluded
56
+
56
57
  - Documentation blocks with `report=false` excluded
58
+
57
59
  - Instructions blocks excluded by default (unless `report=true`)
58
60
 
59
- This is useful for generating shareable reports from completed forms without
60
- internal instructions or agent-only content.
61
+ This is useful for generating shareable reports from completed forms without internal
62
+ instructions or agent-only content.
61
63
 
62
64
  ### validate(form: ParsedForm, options?: ValidateOptions): ValidateResult
63
65
 
@@ -127,14 +129,15 @@ Each patch has an `op` and `fieldId`.
127
129
  | --- | --- | --- |
128
130
  | `set_string` | string | `{ "op": "set_string", "fieldId": "name", "value": "Alice" }` |
129
131
  | `set_number` | number | `{ "op": "set_number", "fieldId": "age", "value": 25 }` |
130
- | `set_string_list` | string_list | `{ "op": "set_string_list", "fieldId": "tags", "items": ["a", "b"] }` |
131
- | `set_single_select` | single_select | `{ "op": "set_single_select", "fieldId": "rating", "selected": "high" }` |
132
- | `set_multi_select` | multi_select | `{ "op": "set_multi_select", "fieldId": "cats", "selected": ["a", "b"] }` |
133
- | `set_checkboxes` | checkboxes | `{ "op": "set_checkboxes", "fieldId": "tasks", "values": {"item1": "done"} }` |
132
+ | `set_string_list` | string_list | `{ "op": "set_string_list", "fieldId": "tags", "value": ["a", "b"] }` |
133
+ | `set_single_select` | single_select | `{ "op": "set_single_select", "fieldId": "rating", "value": "high" }` |
134
+ | `set_multi_select` | multi_select | `{ "op": "set_multi_select", "fieldId": "cats", "value": ["a", "b"] }` |
135
+ | `set_checkboxes` | checkboxes | `{ "op": "set_checkboxes", "fieldId": "tasks", "value": {"item1": "done"} }` |
134
136
  | `set_url` | url | `{ "op": "set_url", "fieldId": "website", "value": "https://..." }` |
135
- | `set_url_list` | url_list | `{ "op": "set_url_list", "fieldId": "sources", "items": ["https://..."] }` |
137
+ | `set_url_list` | url_list | `{ "op": "set_url_list", "fieldId": "sources", "value": ["https://..."] }` |
136
138
  | `set_date` | date | `{ "op": "set_date", "fieldId": "deadline", "value": "2024-06-15" }` |
137
139
  | `set_year` | year | `{ "op": "set_year", "fieldId": "founded", "value": 2015 }` |
140
+ | `set_table` | table | `{ "op": "set_table", "fieldId": "data", "value": [{"col1": "v1"}] }` |
138
141
  | `clear_field` | any | `{ "op": "clear_field", "fieldId": "name" }` |
139
142
  | `skip_field` | optional | `{ "op": "skip_field", "fieldId": "notes", "reason": "Not applicable" }` |
140
143
  | `abort_field` | any | `{ "op": "abort_field", "fieldId": "data", "reason": "Unable to find" }` |
@@ -176,14 +179,91 @@ const result = await fillForm({
176
179
  form: parsedForm,
177
180
  model: 'anthropic/claude-sonnet-4-5',
178
181
  enableWebSearch: true,
182
+ captureWireFormat: false,
179
183
  targetRoles: ['agent'],
180
184
  });
181
185
  ```
182
186
 
187
+ **FillOptions fields:**
188
+
189
+ | Field | Type | Default | Description |
190
+ | --- | --- | --- | --- |
191
+ | `form` | `string \| ParsedForm` | (required) | Form markdown or parsed form |
192
+ | `model` | `string \| LanguageModel` | (required) | Model identifier or instance |
193
+ | `enableWebSearch` | `boolean` | (required) | Enable provider web search tools |
194
+ | `captureWireFormat` | `boolean` | (required) | Capture full LLM request/response |
195
+ | `inputContext` | `InputContext` | `undefined` | Pre-fill fields by ID |
196
+ | `systemPromptAddition` | `string` | `undefined` | Additional system prompt context |
197
+ | `maxTurnsTotal` | `number` | `100` | Maximum TOTAL turns across all calls (safety limit) |
198
+ | `maxTurnsThisCall` | `number` | `undefined` | Per-call turn limit for resumable fills |
199
+ | `startingTurnNumber` | `number` | `0` | Starting turn for progress tracking |
200
+ | `maxPatchesPerTurn` | `number` | `20` | Maximum patches per turn |
201
+ | `maxIssuesPerTurn` | `number` | `10` | Maximum issues shown per turn |
202
+ | `maxStepsPerTurn` | `number` | `20` | Maximum AI SDK steps (tool call rounds) per turn |
203
+ | `targetRoles` | `string[]` | `['agent']` | Roles to fill |
204
+ | `fillMode` | `FillMode` | `'continue'` | `'continue'` or `'overwrite'` |
205
+ | `callbacks` | `FillCallbacks` | `undefined` | Progress callbacks |
206
+ | `signal` | `AbortSignal` | `undefined` | Cancellation signal |
207
+ | `additionalTools` | `Record<string, Tool>` | `undefined` | Custom tools for agent |
208
+
209
+ ### FillStatus
210
+
211
+ The `status` field in `FillResult` indicates success or failure:
212
+
213
+ | Status | Description |
214
+ | --- | --- |
215
+ | `{ ok: true }` | Form completed successfully |
216
+ | `{ ok: false, reason: 'max_turns' }` | Hit overall `maxTurnsTotal` safety limit |
217
+ | `{ ok: false, reason: 'batch_limit' }` | Hit `maxTurnsThisCall` per-call limit |
218
+ | `{ ok: false, reason: 'cancelled' }` | Aborted via signal |
219
+ | `{ ok: false, reason: 'error' }` | Unexpected error |
220
+
221
+ ### Resumable Form Fills
222
+
223
+ For orchestrated environments with timeout constraints (e.g., Convex, AWS Step
224
+ Functions), use `maxTurnsThisCall` to limit turns per call and resume from checkpoints.
225
+
226
+ ```typescript
227
+ import { fillForm } from 'markform';
228
+
229
+ // First call - limit to 2 turns
230
+ const r1 = await fillForm({
231
+ form: formMarkdown,
232
+ model: 'anthropic/claude-sonnet-4-5',
233
+ enableWebSearch: false,
234
+ captureWireFormat: false,
235
+ maxTurnsThisCall: 2, // Stop after 2 turns
236
+ });
237
+
238
+ if (!r1.status.ok && r1.status.reason === 'batch_limit') {
239
+ // Resume from checkpoint using r1.markdown
240
+ const r2 = await fillForm({
241
+ form: r1.markdown, // Use checkpoint as input
242
+ model: 'anthropic/claude-sonnet-4-5',
243
+ enableWebSearch: false,
244
+ captureWireFormat: false,
245
+ startingTurnNumber: r1.turns, // Continue turn count
246
+ });
247
+
248
+ console.log('Total turns:', r2.turns);
249
+ console.log('Status:', r2.status);
250
+ }
251
+ ```
252
+
253
+ **Key points:**
254
+
255
+ - `maxTurnsThisCall` limits turns in a single call, returns `batch_limit` when reached
256
+
257
+ - `result.markdown` contains the form checkpoint (serialized state)
258
+
259
+ - `startingTurnNumber` ensures accurate progress tracking across calls
260
+
261
+ - The form itself is the state—no session storage needed
262
+
183
263
  ### FillCallbacks
184
264
 
185
265
  Optional callbacks for observing form-filling execution in real-time.
186
- All callbacks are optional and errors in callbacks don't abort filling.
266
+ All callbacks are optional and errors in callbacks dont abort filling.
187
267
 
188
268
  ```typescript
189
269
  import type { FillCallbacks } from 'markform';
@@ -127,10 +127,11 @@ markform:
127
127
 
128
128
  **Optional metadata fields:**
129
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.
130
+ - `run_mode` (*recommended*): Suggests how CLI tools should execute this form.
131
+ Values: `interactive` (user fills via prompts), `fill` (agent fills), or `research`
132
+ (agent fills with web search).
133
+ When omitted, tools may infer from field roles or require explicit selection.
134
+ This is a hint for tooling, not enforced by the engine.
134
135
 
135
136
  **Behavioral rules (*required*):**
136
137
 
@@ -211,8 +212,8 @@ Markform defines its own scoping rules where option IDs are field-scoped.
211
212
  Custom tags are defined following [Markdoc tag conventions][markdoc-tags]. See
212
213
  [Markdoc Config][markdoc-config] for how to register custom tags.
213
214
 
214
- All fields use the unified `{% field kind="..." %}` syntax. The `kind` attribute
215
- identifies what type of field a `Field` or `FieldValue` represents.
215
+ All fields use the unified `{% field kind="..." %}` syntax.
216
+ The `kind` attribute identifies what type of field a `Field` or `FieldValue` represents.
216
217
  (In TypeScript, the type is `FieldKind`.)
217
218
 
218
219
  | Kind | Description |
@@ -254,8 +255,9 @@ to different actors.
254
255
  | `placeholder` | string | Hint text shown in empty fields (displayed in UI) |
255
256
  | `examples` | string[] | Example values for the field (helps LLMs, shown in prompts) |
256
257
 
257
- These attributes are only valid on text-entry field kinds. Using them on chooser fields
258
- (single-select, multi-select, checkboxes) will result in a parse error.
258
+ These attributes are only valid on text-entry field kinds.
259
+ Using them on chooser fields (single-select, multi-select, checkboxes) will result in a
260
+ parse error.
259
261
 
260
262
  **Example with placeholder and examples:**
261
263
  ```md
@@ -299,7 +301,8 @@ compatibility:
299
301
  | `multi_select` | `[x]` | Selected | `- [x] Option {% #opt_id %}` |
300
302
 
301
303
  **Note:** `single_select` enforces that exactly one option has `[x]`. The distinction
302
- between `single_select` and `multi_select` is in the `kind` attribute, not the marker syntax.
304
+ between `single_select` and `multi_select` is in the `kind` attribute, not the marker
305
+ syntax.
303
306
 
304
307
  The `{% #id %}` annotation **is** native Markdoc syntax (see
305
308
  [Attributes][markdoc-attributes]).
@@ -464,8 +467,8 @@ columnTypes=[{type: "string", required: true}, "number", "url"]
464
467
  {% /field %}
465
468
  ```
466
469
 
467
- **Sentinel values in table cells:**
468
- Cells can use `%SKIP%` and `%ABORT%` sentinels with optional reasons:
470
+ **Sentinel values in table cells:** Cells can use `%SKIP%` and `%ABORT%` sentinels with
471
+ optional reasons:
469
472
  ```md
470
473
  | 2017 | I, Tonya | 90 | %SKIP% (Box office not tracked) |
471
474
  ```
@@ -906,8 +909,8 @@ ACME
906
909
  {% /field %} {% field kind="string" id="fiscal_period" label="Fiscal period"
907
910
  required=true %}{% /field %} {% /group %}
908
911
 
909
- {% group id="source_docs" title="Source Documents" %} {% checkboxes
910
- id="docs_reviewed" label="Documents reviewed" required=true %}
912
+ {% group id="source_docs" title="Source Documents" %} {% checkboxes id="docs_reviewed"
913
+ label="Documents reviewed" required=true %}
911
914
 
912
915
  - [x] 10-K {% #ten_k %}
913
916
 
@@ -915,8 +918,7 @@ id="docs_reviewed" label="Documents reviewed" required=true %}
915
918
 
916
919
  - [/] Earnings release {% #earnings_release %}
917
920
 
918
- - [ ] Earnings call transcript {% #call_transcript %} {% /field %} {% /group
919
- %}
921
+ - [ ] Earnings call transcript {% #call_transcript %} {% /field %} {% /group %}
920
922
  ````
921
923
 
922
924
  Notes:
@@ -1859,7 +1861,7 @@ YAML keys use snake_case for readability and consistency with common YAML conven
1859
1861
  | TypeScript kind | `'string_list'` |
1860
1862
  | Attributes | `id`, `label`, `required`, `minItems`, `maxItems`, `itemMinLength`, `itemMaxLength`, `uniqueItems` |
1861
1863
  | FieldValue | `{ kind: 'string_list'; items: string[] }` |
1862
- | Patch operation | `{ op: 'set_string_list'; fieldId: Id; items: string[] }` |
1864
+ | Patch operation | `{ op: 'set_string_list'; fieldId: Id; value: string[] }` |
1863
1865
  | Zod | `z.array(z.string().min(itemMin).max(itemMax)).min(n).max(m)` |
1864
1866
  | JSON Schema | `{ type: "array", items: { type: "string" }, minItems, maxItems, uniqueItems }` |
1865
1867
 
@@ -1872,7 +1874,7 @@ YAML keys use snake_case for readability and consistency with common YAML conven
1872
1874
  | TypeScript kind | `'single_select'` |
1873
1875
  | Attributes | `id`, `label`, `required` + inline `options` via list syntax |
1874
1876
  | FieldValue | `{ kind: 'single_select'; selected: OptionId \| null }` |
1875
- | Patch operation | `{ op: 'set_single_select'; fieldId: Id; selected: OptionId \| null }` |
1877
+ | Patch operation | `{ op: 'set_single_select'; fieldId: Id; value: OptionId \| null }` |
1876
1878
  | Zod | `z.enum([...optionIds])` |
1877
1879
  | JSON Schema | `{ type: "string", enum: [...optionIds] }` |
1878
1880
 
@@ -1885,7 +1887,7 @@ YAML keys use snake_case for readability and consistency with common YAML conven
1885
1887
  | TypeScript kind | `'multi_select'` |
1886
1888
  | Attributes | `id`, `label`, `required`, `minSelections`, `maxSelections` + inline `options` |
1887
1889
  | FieldValue | `{ kind: 'multi_select'; selected: OptionId[] }` |
1888
- | Patch operation | `{ op: 'set_multi_select'; fieldId: Id; selected: OptionId[] }` |
1890
+ | Patch operation | `{ op: 'set_multi_select'; fieldId: Id; value: OptionId[] }` |
1889
1891
  | Zod | `z.array(z.enum([...optionIds])).min(n).max(m)` |
1890
1892
  | JSON Schema | `{ type: "array", items: { enum: [...optionIds] }, minItems, maxItems }` |
1891
1893
 
@@ -1898,7 +1900,7 @@ YAML keys use snake_case for readability and consistency with common YAML conven
1898
1900
  | TypeScript kind | `'checkboxes'` |
1899
1901
  | Attributes | `id`, `label`, `required`, `checkboxMode` (`multi`/`simple`/`explicit`), `minDone` (simple only) + inline `options` |
1900
1902
  | FieldValue | `{ kind: 'checkboxes'; values: Record<OptionId, CheckboxValue> }` |
1901
- | Patch operation | `{ op: 'set_checkboxes'; fieldId: Id; values: Record<OptionId, CheckboxValue> }` |
1903
+ | Patch operation | `{ op: 'set_checkboxes'; fieldId: Id; value: Record<OptionId, CheckboxValue> }` |
1902
1904
  | Zod | `z.record(z.enum([...states]))` |
1903
1905
  | JSON Schema | `{ type: "object", additionalProperties: { enum: [...states] } }` |
1904
1906
 
@@ -1924,7 +1926,7 @@ YAML keys use snake_case for readability and consistency with common YAML conven
1924
1926
  | TypeScript kind | `'url_list'` |
1925
1927
  | Attributes | `id`, `label`, `required`, `minItems`, `maxItems`, `uniqueItems` |
1926
1928
  | FieldValue | `{ kind: 'url_list'; items: string[] }` |
1927
- | Patch operation | `{ op: 'set_url_list'; fieldId: Id; items: string[] }` |
1929
+ | Patch operation | `{ op: 'set_url_list'; fieldId: Id; value: string[] }` |
1928
1930
  | Zod | `z.array(z.url()).min(n).max(m)` |
1929
1931
  | JSON Schema | `{ type: "array", items: { type: "string", format: "uri" }, minItems, maxItems, uniqueItems }` |
1930
1932
 
@@ -1963,7 +1965,7 @@ YAML keys use snake_case for readability and consistency with common YAML conven
1963
1965
  | TypeScript kind | `'table'` |
1964
1966
  | Attributes | `id`, `label`, `required`, `columnIds`, `columnLabels`, `columnTypes`, `minRows`, `maxRows` |
1965
1967
  | FieldValue | `{ kind: 'table'; rows: TableRowResponse[] }` |
1966
- | Patch operation | `{ op: 'set_table'; fieldId: Id; rows: PatchTableRow[] }` |
1968
+ | Patch operation | `{ op: 'set_table'; fieldId: Id; value: PatchTableRow[] }` |
1967
1969
  | Zod | `z.object({ kind: z.literal('table'), rows: z.array(TableRowResponseSchema) })` |
1968
1970
  | JSON Schema | `{ type: "object", properties: { kind: { const: "table" }, rows: { type: "array" } } }` |
1969
1971
 
@@ -2541,12 +2543,15 @@ This formula ensures:
2541
2543
  type Patch =
2542
2544
  | { op: 'set_string'; fieldId: Id; value: string | null }
2543
2545
  | { op: 'set_number'; fieldId: Id; value: number | null }
2544
- | { op: 'set_string_list'; fieldId: Id; items: string[] }
2545
- | { op: 'set_checkboxes'; fieldId: Id; values: Record<OptionId, CheckboxValue> }
2546
- | { op: 'set_single_select'; fieldId: Id; selected: OptionId | null }
2547
- | { op: 'set_multi_select'; fieldId: Id; selected: OptionId[] }
2546
+ | { op: 'set_string_list'; fieldId: Id; value: string[] }
2547
+ | { op: 'set_checkboxes'; fieldId: Id; value: Record<OptionId, CheckboxValue> }
2548
+ | { op: 'set_single_select'; fieldId: Id; value: OptionId | null }
2549
+ | { op: 'set_multi_select'; fieldId: Id; value: OptionId[] }
2548
2550
  | { op: 'set_url'; fieldId: Id; value: string | null }
2549
- | { op: 'set_url_list'; fieldId: Id; items: string[] }
2551
+ | { op: 'set_url_list'; fieldId: Id; value: string[] }
2552
+ | { op: 'set_table'; fieldId: Id; value: PatchTableRow[] }
2553
+ | { op: 'set_date'; fieldId: Id; value: string | null }
2554
+ | { op: 'set_year'; fieldId: Id; value: number | null }
2550
2555
  | { op: 'clear_field'; fieldId: Id }
2551
2556
  | { op: 'skip_field'; fieldId: Id; role: string; reason?: string }
2552
2557
  | { op: 'abort_field'; fieldId: Id; role: string; reason?: string }
@@ -2564,10 +2569,10 @@ Option IDs in patches are **local to the field** specified by `fieldId`. You do
2564
2569
  the qualified `{fieldId}.{optionId}` form in patches—the `fieldId` already provides the
2565
2570
  scope. For example:
2566
2571
 
2567
- - `{ op: 'set_checkboxes', fieldId: 'docs_reviewed', values: { ten_k: 'done', ten_q:
2572
+ - `{ op: 'set_checkboxes', fieldId: 'docs_reviewed', value: { ten_k: 'done', ten_q:
2568
2573
  'done' } }`
2569
2574
 
2570
- - `{ op: 'set_single_select', fieldId: 'rating', selected: 'bullish' }`
2575
+ - `{ op: 'set_single_select', fieldId: 'rating', value: 'bullish' }`
2571
2576
 
2572
2577
  **Patch semantics:**
2573
2578