markform 0.1.12 → 0.1.14

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.
@@ -1,5 +1,5 @@
1
1
 
2
- import { U as SessionTranscriptSchema } from "./coreTypes-Z8SvQyoL.mjs";
2
+ import { U as SessionTranscriptSchema } from "./coreTypes-DiCddBKu.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-WeeBXwXg.mjs";
2
+ import { L as PatchSchema, V as RunModeSchema } from "./coreTypes-DiCddBKu.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-CUH_16RD.mjs";
4
4
  import { z } from "zod";
5
5
  import Markdoc from "@markdoc/markdoc";
6
6
  import YAML from "yaml";
@@ -2139,12 +2139,41 @@ function coerceToCheckboxes(field, rawValue) {
2139
2139
  value: {}
2140
2140
  }
2141
2141
  };
2142
+ const validOptions = new Set(field.options.map((o) => o.id));
2143
+ const checkboxMode = field.checkboxMode;
2144
+ if (Array.isArray(rawValue)) {
2145
+ const defaultState = checkboxMode === "explicit" ? "yes" : "done";
2146
+ const values$1 = {};
2147
+ for (const item of rawValue) {
2148
+ if (typeof item !== "string") return {
2149
+ ok: false,
2150
+ error: `Array items for checkboxes field '${field.id}' must be strings (option IDs), got ${typeof item}`
2151
+ };
2152
+ if (!validOptions.has(item)) return {
2153
+ ok: false,
2154
+ error: `Invalid option '${item}' for checkboxes field '${field.id}'. Valid options: ${Array.from(validOptions).join(", ")}`
2155
+ };
2156
+ values$1[item] = defaultState;
2157
+ }
2158
+ const patch$1 = {
2159
+ op: "set_checkboxes",
2160
+ fieldId: field.id,
2161
+ value: values$1
2162
+ };
2163
+ if (rawValue.length === 0) return {
2164
+ ok: true,
2165
+ patch: patch$1
2166
+ };
2167
+ return {
2168
+ ok: true,
2169
+ patch: patch$1,
2170
+ warning: `Coerced array to checkboxes object with '${defaultState}' state for field '${field.id}'`
2171
+ };
2172
+ }
2142
2173
  if (!isPlainObject(rawValue)) return {
2143
2174
  ok: false,
2144
- error: `checkboxes field '${field.id}' requires a Record<string, CheckboxValue>, got ${typeof rawValue}`
2175
+ error: `checkboxes field '${field.id}' requires a Record<string, CheckboxValue> or array of option IDs, got ${typeof rawValue}`
2145
2176
  };
2146
- const validOptions = new Set(field.options.map((o) => o.id));
2147
- const checkboxMode = field.checkboxMode;
2148
2177
  const values = {};
2149
2178
  let hadBooleanCoercion = false;
2150
2179
  const validValues = new Set(checkboxMode === "explicit" ? [
@@ -2538,12 +2567,12 @@ var FormHarness = class {
2538
2567
  if (this.state !== "wait") throw new Error(`Cannot apply in state: ${this.state}`);
2539
2568
  if (patches.length > this.config.maxPatchesPerTurn) throw new Error(`Too many patches: ${patches.length} > ${this.config.maxPatchesPerTurn}`);
2540
2569
  const applyResult = applyPatches(this.form, patches);
2541
- const patchesActuallyApplied = applyResult.applyStatus === "applied" ? patches.length : 0;
2570
+ const patchesActuallyApplied = applyResult.appliedPatches.length;
2542
2571
  const result = inspect(this.form, { targetRoles: this.config.targetRoles });
2543
2572
  const stepResult = this.computeStepResult(result);
2544
2573
  stepResult.patchesApplied = patchesActuallyApplied;
2545
2574
  stepResult.rejectedPatches = applyResult.rejectedPatches;
2546
- this.recordTurn(issues, patches, result, llmStats, context, applyResult.rejectedPatches, wire);
2575
+ this.recordTurn(issues, patches, result, llmStats, context, applyResult.rejectedPatches, applyResult.warnings, wire);
2547
2576
  if (stepResult.issues.length === 0 || this.turnNumber >= this.config.maxTurns) this.state = "complete";
2548
2577
  else this.state = "wait";
2549
2578
  return stepResult;
@@ -2567,7 +2596,7 @@ var FormHarness = class {
2567
2596
  /**
2568
2597
  * Record a turn in the session transcript.
2569
2598
  */
2570
- recordTurn(issues, patches, result, llmStats, context, rejectedPatches, wire) {
2599
+ recordTurn(issues, patches, result, llmStats, context, rejectedPatches, warnings, wire) {
2571
2600
  const hash = sha256(serializeForm(this.form));
2572
2601
  const requiredIssueCount = result.issues.filter((i) => i.severity === "required").length;
2573
2602
  const turn = {
@@ -2575,7 +2604,8 @@ var FormHarness = class {
2575
2604
  inspect: { issues },
2576
2605
  apply: {
2577
2606
  patches,
2578
- ...rejectedPatches && rejectedPatches.length > 0 && { rejectedPatches }
2607
+ ...rejectedPatches && rejectedPatches.length > 0 && { rejectedPatches },
2608
+ ...warnings && warnings.length > 0 && { warnings }
2579
2609
  },
2580
2610
  after: {
2581
2611
  requiredIssueCount,
@@ -7860,25 +7890,51 @@ var anthropic = createAnthropic();
7860
7890
  * fabrication of data.
7861
7891
  */
7862
7892
  const DEFAULT_SYSTEM_PROMPT = `# Form Instructions
7863
- Carefully research answers to all questions in the form, using all available tools you have.
7864
7893
 
7865
- Guidelines:
7866
- 1. Focus on required fields first (severity: "required"), then address optional fields (severity: "recommended")
7867
- 2. You MUST address ALL issues shown to you - both required AND recommended (optional)
7868
- 3. NEVER fabricate or guess information - only use data you can verify
7869
- 4. If you cannot find verifiable information for a field, use skip_field to mark it as skipped with a reason
7870
- 5. For string fields: use appropriate text from verified sources
7871
- 6. For number fields: use appropriate numeric values from verified sources
7872
- 7. For single_select: choose one valid option ID
7873
- 8. For multi_select: choose one or more valid option IDs
7874
- 9. For checkboxes: use the appropriate state for the checkbox mode:
7875
- - Mode "simple": done (checked) or todo (unchecked)
7876
- - Mode "multi": done, todo, or na (not applicable)
7877
- - Mode "explicit": yes or no (must explicitly answer)
7894
+ Research and fill the form fields using all available tools. Focus on accuracy over completeness.
7895
+
7896
+ ## Guidelines
7897
+ 1. Address required fields first (severity: "required"), then optional fields (severity: "recommended")
7898
+ 2. NEVER fabricate or guess information - only use data you can verify
7899
+ 3. If you cannot find verifiable information, use skip_field with a reason
7900
+
7901
+ ## Patch Format Examples
7902
+
7903
+ Use the fill_form tool with patches in these formats:
7904
+
7905
+ | Type | Example |
7906
+ |------|---------|
7907
+ | string | \`{ op: "set_string", fieldId: "name", value: "Acme Corp" }\` |
7908
+ | number | \`{ op: "set_number", fieldId: "age", value: 32 }\` |
7909
+ | string_list | \`{ op: "set_string_list", fieldId: "tags", value: ["ai", "ml"] }\` |
7910
+ | url | \`{ op: "set_url", fieldId: "website", value: "https://example.com" }\` |
7911
+ | url_list | \`{ op: "set_url_list", fieldId: "sources", value: ["https://a.com", "https://b.com"] }\` |
7912
+ | date | \`{ op: "set_date", fieldId: "event_date", value: "2024-06-15" }\` |
7913
+ | year | \`{ op: "set_year", fieldId: "founded", value: 2024 }\` |
7914
+ | single_select | \`{ op: "set_single_select", fieldId: "priority", value: "high" }\` |
7915
+ | multi_select | \`{ op: "set_multi_select", fieldId: "categories", value: ["frontend", "backend"] }\` |
7916
+ | checkboxes | \`{ op: "set_checkboxes", fieldId: "tasks", value: { "task1": "done", "task2": "todo" } }\` |
7917
+ | table | \`{ op: "set_table", fieldId: "team", value: [{ "name": "Alice", "role": "Engineer" }] }\` |
7878
7918
 
7879
- CRITICAL: Accuracy is more important than completeness. Use skip_field when information cannot be verified.
7919
+ ## Important: checkboxes vs multi_select
7880
7920
 
7881
- Always use the fill_form tool to submit your field values.
7921
+ These two types look similar but have DIFFERENT value formats:
7922
+
7923
+ - **multi_select** → array of option IDs: \`["opt1", "opt2"]\`
7924
+ - **checkboxes** → object mapping IDs to states: \`{ "opt1": "done", "opt2": "todo" }\`
7925
+
7926
+ **Checkbox states by mode:**
7927
+ - Mode "simple": \`"done"\` or \`"todo"\`
7928
+ - Mode "multi": \`"done"\`, \`"todo"\`, \`"incomplete"\`, \`"active"\`, or \`"na"\`
7929
+ - Mode "explicit": \`"yes"\` or \`"no"\` (if unknown, use abort_field)
7930
+
7931
+ **WRONG:** \`{ op: "set_checkboxes", value: ["task1", "task2"] }\`
7932
+ **RIGHT:** \`{ op: "set_checkboxes", value: { "task1": "done", "task2": "done" } }\`
7933
+
7934
+ ## Skipping Fields
7935
+
7936
+ If you cannot find verifiable information:
7937
+ \`{ op: "skip_field", fieldId: "...", reason: "Could not find verified data" }\`
7882
7938
  `;
7883
7939
  /**
7884
7940
  * Web search instructions appended when web search tools are available.
@@ -7914,33 +7970,49 @@ function getIssuesIntro(issueCount) {
7914
7970
  * Used in PATCH_FORMAT_INSTRUCTIONS and rejection feedback hints.
7915
7971
  */
7916
7972
  const PATCH_FORMATS = {
7917
- string: "{ op: \"set_string\", fieldId: \"...\", value: \"...\" }",
7918
- number: "{ op: \"set_number\", fieldId: \"...\", value: 123 }",
7919
- string_list: "{ op: \"set_string_list\", fieldId: \"...\", value: [\"...\", \"...\"] }",
7973
+ string: "{ op: \"set_string\", fieldId: \"...\", value: \"text here\" }",
7974
+ number: "{ op: \"set_number\", fieldId: \"...\", value: 42 }",
7975
+ string_list: "{ op: \"set_string_list\", fieldId: \"...\", value: [\"item1\", \"item2\"] }",
7920
7976
  single_select: "{ op: \"set_single_select\", fieldId: \"...\", value: \"option_id\" }",
7921
7977
  multi_select: "{ op: \"set_multi_select\", fieldId: \"...\", value: [\"opt1\", \"opt2\"] }",
7922
7978
  checkboxes: "{ op: \"set_checkboxes\", fieldId: \"...\", value: { \"opt1\": \"done\", \"opt2\": \"todo\" } }",
7923
- url: "{ op: \"set_url\", fieldId: \"...\", value: \"https://...\" }",
7924
- url_list: "{ op: \"set_url_list\", fieldId: \"...\", value: [\"https://...\", \"https://...\"] }",
7925
- date: "{ op: \"set_date\", fieldId: \"...\", value: \"2024-01-15\" }",
7979
+ url: "{ op: \"set_url\", fieldId: \"...\", value: \"https://example.com\" }",
7980
+ url_list: "{ op: \"set_url_list\", fieldId: \"...\", value: [\"https://a.com\", \"https://b.com\"] }",
7981
+ date: "{ op: \"set_date\", fieldId: \"...\", value: \"2024-06-15\" }",
7926
7982
  year: "{ op: \"set_year\", fieldId: \"...\", value: 2024 }",
7927
- table: "{ op: \"set_table\", fieldId: \"...\", value: [{ col1: \"value1\", col2: \"value2\" }, ...] }"
7983
+ table: "{ op: \"set_table\", fieldId: \"...\", value: [{ col1: \"val1\", col2: \"val2\" }] }"
7928
7984
  };
7929
7985
  /**
7930
7986
  * Get the correct patch format for a field kind.
7931
7987
  *
7932
7988
  * @param fieldKind - The field kind (e.g., "table", "string")
7933
- * @param fieldId - Optional field ID to substitute in the example
7934
- * @param columnIds - Optional column IDs for table fields
7989
+ * @param options - Optional configuration for the hint
7935
7990
  * @returns The patch format example string
7936
7991
  */
7937
- function getPatchFormatHint(fieldKind, fieldId, columnIds) {
7992
+ function getPatchFormatHint(fieldKind, fieldIdOrOptions, columnIds) {
7993
+ let options = {};
7994
+ if (typeof fieldIdOrOptions === "string") options = {
7995
+ fieldId: fieldIdOrOptions,
7996
+ columnIds
7997
+ };
7998
+ else if (fieldIdOrOptions) options = fieldIdOrOptions;
7938
7999
  let format = PATCH_FORMATS[fieldKind];
7939
8000
  if (!format) return `Use the correct set_${fieldKind} operation for this field type.`;
7940
- if (fieldId) format = format.replace("fieldId: \"...\"", `fieldId: "${fieldId}"`);
7941
- if (fieldKind === "table" && columnIds && columnIds.length > 0) {
7942
- const colExample = columnIds.map((id) => `"${id}": "..."`).join(", ");
7943
- format = format.replace("{ col1: \"value1\", col2: \"value2\" }", `{ ${colExample} }`);
8001
+ if (options.fieldId) format = format.replace("fieldId: \"...\"", `fieldId: "${options.fieldId}"`);
8002
+ if (fieldKind === "checkboxes") {
8003
+ const mode = options.checkboxMode ?? "multi";
8004
+ const optIds = options.optionIds ?? ["opt1", "opt2"];
8005
+ const [state1, state2] = {
8006
+ simple: ["done", "todo"],
8007
+ multi: ["done", "todo"],
8008
+ explicit: ["yes", "no"]
8009
+ }[mode] ?? ["done", "todo"];
8010
+ const valueExample = optIds.length >= 2 ? `{ "${optIds[0]}": "${state1}", "${optIds[1]}": "${state2}" }` : optIds.length === 1 ? `{ "${optIds[0]}": "${state1}" }` : `{ "opt1": "${state1}", "opt2": "${state2}" }`;
8011
+ format = format.replace("{ \"opt1\": \"done\", \"opt2\": \"todo\" }", valueExample);
8012
+ }
8013
+ if (fieldKind === "table" && options.columnIds && options.columnIds.length > 0) {
8014
+ const colExample = options.columnIds.map((id) => `"${id}": "..."`).join(", ");
8015
+ format = format.replace("{ col1: \"val1\", col2: \"val2\" }", `{ ${colExample} }`);
7944
8016
  }
7945
8017
  return format;
7946
8018
  }
@@ -8011,7 +8083,7 @@ var LiveAgent = class {
8011
8083
  callbacks;
8012
8084
  constructor(config) {
8013
8085
  this.model = config.model;
8014
- this.maxStepsPerTurn = config.maxStepsPerTurn ?? 3;
8086
+ this.maxStepsPerTurn = config.maxStepsPerTurn ?? DEFAULT_MAX_STEPS_PER_TURN;
8015
8087
  this.systemPromptAddition = config.systemPromptAddition;
8016
8088
  this.targetRole = config.targetRole ?? AGENT_ROLE;
8017
8089
  this.provider = config.provider;
@@ -8274,11 +8346,16 @@ function buildContextPrompt(issues, form, maxPatches, previousRejections) {
8274
8346
  const field = findField(form, issue.ref);
8275
8347
  if (field) {
8276
8348
  lines.push(` Type: ${field.kind}`);
8349
+ let optionIds;
8277
8350
  if ("options" in field && field.options) {
8278
- const optionIds = field.options.map((o) => o.id).join(", ");
8279
- lines.push(` Options: ${optionIds}`);
8351
+ optionIds = field.options.map((o) => o.id);
8352
+ lines.push(` Options: ${optionIds.join(", ")}`);
8353
+ }
8354
+ let checkboxMode;
8355
+ if (field.kind === "checkboxes" && "checkboxMode" in field) {
8356
+ checkboxMode = field.checkboxMode ?? "multi";
8357
+ lines.push(` Mode: ${checkboxMode}`);
8280
8358
  }
8281
- if (field.kind === "checkboxes" && "checkboxMode" in field) lines.push(` Mode: ${field.checkboxMode ?? "multi"}`);
8282
8359
  let columnIds;
8283
8360
  if (field.kind === "table" && "columns" in field && field.columns) {
8284
8361
  columnIds = field.columns.map((c) => c.id);
@@ -8291,7 +8368,12 @@ function buildContextPrompt(issues, form, maxPatches, previousRejections) {
8291
8368
  lines.push(` Rows: ${constraints.join(", ")}`);
8292
8369
  }
8293
8370
  }
8294
- const patchHint = getPatchFormatHint(field.kind, field.id, columnIds);
8371
+ const patchHint = getPatchFormatHint(field.kind, {
8372
+ fieldId: field.id,
8373
+ columnIds,
8374
+ checkboxMode,
8375
+ optionIds
8376
+ });
8295
8377
  lines.push(` Set: ${patchHint}`);
8296
8378
  if (issue.severity === "required") lines.push(` This field is required.`);
8297
8379
  else lines.push(` Skip: { op: "skip_field", fieldId: "${field.id}", reason: "..." }`);
@@ -8728,7 +8810,8 @@ async function fillForm(options) {
8728
8810
  provider,
8729
8811
  enableWebSearch: options.enableWebSearch,
8730
8812
  additionalTools: options.additionalTools,
8731
- callbacks: options.callbacks
8813
+ callbacks: options.callbacks,
8814
+ maxStepsPerTurn: options.maxStepsPerTurn
8732
8815
  });
8733
8816
  let turnCount = startingTurnNumber;
8734
8817
  let turnsThisCall = 0;
@@ -8957,7 +9040,7 @@ function validateResearchForm(form) {
8957
9040
  //#endregion
8958
9041
  //#region src/index.ts
8959
9042
  /** Markform version (injected at build time). */
8960
- const VERSION = "0.1.12";
9043
+ const VERSION = "0.1.14";
8961
9044
 
8962
9045
  //#endregion
8963
9046
  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 };
@@ -199,6 +199,7 @@ const result = await fillForm({
199
199
  | `startingTurnNumber` | `number` | `0` | Starting turn for progress tracking |
200
200
  | `maxPatchesPerTurn` | `number` | `20` | Maximum patches per turn |
201
201
  | `maxIssuesPerTurn` | `number` | `10` | Maximum issues shown per turn |
202
+ | `maxStepsPerTurn` | `number` | `20` | Maximum AI SDK steps (tool call rounds) per turn |
202
203
  | `targetRoles` | `string[]` | `['agent']` | Roles to fill |
203
204
  | `fillMode` | `FillMode` | `'continue'` | `'continue'` or `'overwrite'` |
204
205
  | `callbacks` | `FillCallbacks` | `undefined` | Progress callbacks |