@archmax-ai/harness 1.0.0 → 1.1.0
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 +11 -6
- package/dist/assembly/compose.js +3 -1
- package/dist/assembly/compose.js.map +1 -1
- package/dist/authoring-skill/archmax-harness/SKILL.md +5 -2
- package/dist/authoring-skill/archmax-harness/references/backend-integration.md +25 -13
- package/dist/authoring-skill/archmax-harness/references/workflow-schema.md +36 -6
- package/dist/authoring-skill/archmax-harness/references/workflow-yaml.md +3 -0
- package/dist/core/attachments.d.ts +2 -0
- package/dist/core/attachments.js +2 -1
- package/dist/core/attachments.js.map +1 -1
- package/dist/core/file-operations.d.ts +6 -0
- package/dist/core/file-operations.js +29 -0
- package/dist/core/file-operations.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/machine/signature-pattern.d.ts +24 -0
- package/dist/machine/signature-pattern.js +67 -0
- package/dist/machine/signature-pattern.js.map +1 -0
- package/dist/machine/signature.d.ts +137 -35
- package/dist/machine/signature.js +476 -25
- package/dist/machine/signature.js.map +1 -1
- package/dist/machine/spec-schema.d.ts +202 -1
- package/dist/machine/spec-schema.js +143 -4
- package/dist/machine/spec-schema.js.map +1 -1
- package/dist/public/spec.d.ts +5 -1
- package/dist/public/spec.js +4 -0
- package/dist/public/spec.js.map +1 -1
- package/dist/workflow/control-tools.js +3 -1
- package/dist/workflow/control-tools.js.map +1 -1
- package/dist/workflow/file-values.d.ts +4 -1
- package/dist/workflow/file-values.js +2 -0
- package/dist/workflow/file-values.js.map +1 -1
- package/dist/workflow/middleware.d.ts +2 -0
- package/dist/workflow/middleware.js +1 -0
- package/dist/workflow/middleware.js.map +1 -1
- package/dist/workflow/render-prompt.js +7 -2
- package/dist/workflow/render-prompt.js.map +1 -1
- package/dist/workflow/signature-checks.d.ts +8 -3
- package/dist/workflow/signature-checks.js +17 -4
- package/dist/workflow/signature-checks.js.map +1 -1
- package/dist/workflow/sub-workflow.js +4 -1
- package/dist/workflow/sub-workflow.js.map +1 -1
- package/package.json +3 -2
- package/skills/archmax-harness/SKILL.md +5 -2
- package/skills/archmax-harness/references/backend-integration.md +25 -13
- package/skills/archmax-harness/references/workflow-schema.md +36 -6
- package/skills/archmax-harness/references/workflow-yaml.md +3 -0
|
@@ -82,7 +82,7 @@ From `@archmax-ai/harness` (`src/index.ts`):
|
|
|
82
82
|
| `workflowStateSchema`, `workflowPaths`, `sessionPaths`, `runArtifactPaths` | schema/fn | State schema + path helpers |
|
|
83
83
|
| `runTests`, `RunTestsOptions`, `CaseResult` | fn/type | Run a workflow's cases — [against your own agent](#cases-against-your-agent) |
|
|
84
84
|
| `toolsFromMap`, `AgentToolDescriptor`, `ToolContext`, `ToolPaths`, `PathAccess`, `ToolPathsError` | fn/type/class | Host tools: a `name → descriptor` map, each descriptor's declared `paths` and a handler handed the turn's workspace — [host tools](#host-tools) |
|
|
85
|
-
| `SIGNATURE_TYPES`, `normalizeSignature`, `signatureForTrigger`, `signatureJsonSchema`, `signatureValueIssues` | const/fn | A trigger's typed signature as JSON Schema and its conformance rule — [exposing a workflow](#exposing-a-workflow-to-outside-callers); also on `@archmax-ai/harness/spec` |
|
|
85
|
+
| `SIGNATURE_TYPES`, `SIGNATURE_FORMATS`, `SIGNATURE_CONTENTS`, `normalizeSignature`, `signatureForTrigger`, `signatureJsonSchema`, `signatureValueIssues` | const/fn | A trigger's typed signature, rules included, as JSON Schema and its conformance rule — [exposing a workflow](#exposing-a-workflow-to-outside-callers); also on `@archmax-ai/harness/spec` |
|
|
86
86
|
|
|
87
87
|
## createAgent options
|
|
88
88
|
|
|
@@ -399,12 +399,22 @@ const outcome = await agent.workflow!.send(sessionId, { message: "Refund the ord
|
|
|
399
399
|
- `signatureJsonSchema(entries)` → `{ type: "object", properties, required }`:
|
|
400
400
|
one property per entry in declaration order, every name required,
|
|
401
401
|
`date`/`date-time`/`file` as `{ type: "string", format }`, an untyped entry as `{}`,
|
|
402
|
-
an entry's `description` carried over.
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
`
|
|
402
|
+
an entry's `description` carried over. Rules map to their JSON Schema keywords:
|
|
403
|
+
`format: email` → `format: "email"`, `format: url` → `format: "uri"` plus
|
|
404
|
+
`pattern: "^https?://"`, `format: phone` → the E.164 `pattern`; `pattern`,
|
|
405
|
+
`minLength`/`maxLength`, `enum`, numeric `minimum`/`maximum` and
|
|
406
|
+
`minItems`/`maxItems` as themselves; `content` → `contentMediaType`. Date
|
|
407
|
+
bounds, `accept` and `maxSize` are not mapped (the runtime still enforces
|
|
408
|
+
them). It adds no `additionalProperties`; set it for your own ingress.
|
|
409
|
+
- `signatureValueIssues(entries, values, options?)` → one issue per missing name
|
|
410
|
+
and per non-conforming value; `[]` means the turn boundary will not refuse the
|
|
411
|
+
map for its signature. A value breaking a rule is an `invalid` issue carrying
|
|
412
|
+
`rule` (one per entry, the first rule broken), so code that filters
|
|
413
|
+
`kind === "invalid"` enforces rules unchanged. `options.now` pins the clock
|
|
414
|
+
for `today`/`now` (tests, a host's own clock). It is synchronous, pure and
|
|
415
|
+
browser-safe, and a `pattern` runs in RE2, so it is safe in a request path on
|
|
416
|
+
input from anyone. It **never coerces or trims**: a form that collects text
|
|
417
|
+
converts `"4"` to `4` before it validates or seeds.
|
|
408
418
|
- A trigger's `description` is written for the caller. Use it as the MCP tool
|
|
409
419
|
or operation description. The session's own model never sees it.
|
|
410
420
|
- **A `file` entry** (`format: "file"` in the schema) takes a workspace path. To
|
|
@@ -417,13 +427,15 @@ const outcome = await agent.workflow!.send(sessionId, { message: "Refund the ord
|
|
|
417
427
|
`InvalidTurnFileError`, before anything is written, for a bad variable or file
|
|
418
428
|
name, a variable also given in `variables`, a session parked at a human state, or
|
|
419
429
|
bytes the store cannot hold exactly (a non-text file needs a store with
|
|
420
|
-
`uploadFiles`). `signatureValueIssues` checks only a `file` value's shape
|
|
421
|
-
start form validates the path the upload will
|
|
422
|
-
lets `files` supply it
|
|
430
|
+
`uploadFiles`). `signatureValueIssues` checks only a `file` value's shape and its
|
|
431
|
+
`accept` extensions, so a start form validates the path the upload will
|
|
432
|
+
produce, or skips the entry and lets `files` supply it; `maxSize` is checked by
|
|
433
|
+
the runtime at the turn boundary, against the placed file.
|
|
423
434
|
- A host that reads specs itself must read `requires`/`returns` through
|
|
424
|
-
`normalizeSignature` (both spellings → `{ name, type?, description
|
|
425
|
-
never as `string[]`: an entry
|
|
426
|
-
|
|
435
|
+
`normalizeSignature` (both spellings → `{ name, type?, description?, …rules }[]`,
|
|
436
|
+
`maxSize` in bytes, `today`/`now` kept symbolic), never as `string[]`: an entry
|
|
437
|
+
may be an object. Hosts must be on the release that introduced typed entries
|
|
438
|
+
(and, for rules, 1.1.0) before any workspace they read uses them.
|
|
427
439
|
|
|
428
440
|
## Lifecycle events
|
|
429
441
|
|
|
@@ -606,7 +606,8 @@ states:
|
|
|
606
606
|
description: Enrich one order and say whether it is late. # for callers only
|
|
607
607
|
requires: # a firing must supply these to start
|
|
608
608
|
- order_id # bare name = untyped
|
|
609
|
-
- { name: due, type: date, description: The day the order is due. }
|
|
609
|
+
- { name: due, type: date, minimum: today, description: The day the order is due. }
|
|
610
|
+
- { name: priority, type: string, enum: [low, normal, high] } # a rule
|
|
610
611
|
returns: # the run guarantees these when it completes
|
|
611
612
|
- enrichment_file
|
|
612
613
|
- { name: delayed, type: boolean }
|
|
@@ -635,10 +636,11 @@ states:
|
|
|
635
636
|
state through a code state that checks the returns and sends the work back
|
|
636
637
|
with what is missing. Each entry is a bare
|
|
637
638
|
run-variable name (**untyped**: any value, `null` included) or a strict object
|
|
638
|
-
`{ name, type?, description
|
|
639
|
+
`{ name, type?, description?, …rules }` naming one; the spellings mix in one list and
|
|
639
640
|
names are distinct across both. What the agent must *do* to produce a
|
|
640
641
|
variable still belongs in the `instructions` that set it. The names — with
|
|
641
|
-
type and description when declared, as
|
|
642
|
+
type, rules and description when declared, as
|
|
643
|
+
`name (type; rule; rule) — description` — are
|
|
642
644
|
rendered into the prompt under the trigger's entry state, so the agent is told
|
|
643
645
|
what to produce before it can be failed for omitting it. A trigger's
|
|
644
646
|
`requires:` also **guarantees** the variable for `${{…}}` guards, so `validate`
|
|
@@ -654,9 +656,37 @@ states:
|
|
|
654
656
|
refused before any model call), **at the write** (`archmax_set_variables` of a
|
|
655
657
|
mistyped typed return of the current trigger is a correctable refusal,
|
|
656
658
|
nothing written) and **at completion** (a mistyped typed return rejects the
|
|
657
|
-
run — in practice a code state's write). There are no
|
|
658
|
-
|
|
659
|
-
|
|
659
|
+
run — in practice a code state's write). There are no item or property
|
|
660
|
+
schemas and no optional inputs. An unknown `type`, an unknown entry key
|
|
661
|
+
(`default:`) or an empty `description` fails load.
|
|
662
|
+
- **Rules** say what a typed value must look like beyond its type, spelled as
|
|
663
|
+
JSON Schema keywords, and are held wherever the type is (start, write,
|
|
664
|
+
completion, a delegation call and its settle):
|
|
665
|
+
|
|
666
|
+
| Rule | On | Value |
|
|
667
|
+
| --- | --- | --- |
|
|
668
|
+
| `format` | `string` | `email` (WHATWG grammar, a domain with a TLD), `url` (absolute `http(s)://`, no credentials), `phone` (E.164, `+4930123456`) |
|
|
669
|
+
| `pattern` | `string` | a regex found anywhere in the value (anchor with `^…$`), ≤ 1,000 characters |
|
|
670
|
+
| `minLength`, `maxLength` | `string` | non-negative integers, counted in code points |
|
|
671
|
+
| `enum` | `string` | a non-empty list of distinct strings, matched exactly |
|
|
672
|
+
| `content` | `string` | `text`, `markdown` or `html`: a **declaration** for the host, never checked or sanitised |
|
|
673
|
+
| `minimum`, `maximum` | `integer`, `number` | numbers, inclusive |
|
|
674
|
+
| `minimum`, `maximum` | `date` | `YYYY-MM-DD` or `today` (UTC), inclusive |
|
|
675
|
+
| `minimum`, `maximum` | `date-time` | an RFC 3339 instant or `now`, inclusive |
|
|
676
|
+
| `minItems`, `maxItems` | `array` | non-negative integers |
|
|
677
|
+
| `accept` | `file` | extensions like `.pdf`, matched on the last extension, case-insensitively |
|
|
678
|
+
| `maxSize` | `file` | bytes, or `<n>KB` / `<n>MB` (1,000-based); checked where the file crosses a boundary |
|
|
679
|
+
|
|
680
|
+
Nothing is coerced or trimmed; a mistyped value reports its type, not a rule;
|
|
681
|
+
each entry reports only the first rule it breaks (`'quantity' must be at most
|
|
682
|
+
100`). Load fails, naming the entry and key, for a rule on a type that does not
|
|
683
|
+
take it or on an untyped entry, `format` with `pattern`, a pattern that does not
|
|
684
|
+
compile or uses a lookaround or backreference, and inconsistent bounds (`min…`
|
|
685
|
+
above `max…`, an empty or repeated `enum`). A `pattern` runs in RE2 (linear
|
|
686
|
+
time, so no input can make it slow) and must also compile as an ECMA-262 `u`
|
|
687
|
+
regex, so RE2-only syntax like `(?i)` or `\pL` is refused. Add rules where a
|
|
688
|
+
caller outside the session supplies the value (a form, an MCP client), or where
|
|
689
|
+
the agent must produce a value of a set shape; the agent sees them in its prompt.
|
|
660
690
|
- **A `file` value must name a readable file.** The pure rule checks only the
|
|
661
691
|
path's shape (a host runs it in a browser). At the start, at the write, at
|
|
662
692
|
completion and at a delegation call the runtime also requires a **file** (not a
|
|
@@ -59,9 +59,12 @@ states:
|
|
|
59
59
|
requires: # variables a firing must supply (a caller's required params):
|
|
60
60
|
- order_id # a bare name is untyped (any value, null included)
|
|
61
61
|
- { name: due, type: date, description: The day it is due. } # typed: held at the boundary
|
|
62
|
+
- { name: contact, type: string, format: email } # a rule beside the type: held wherever the type is
|
|
62
63
|
returns: [result_file] # variables the run guarantees on completion (a caller's result);
|
|
63
64
|
# short of them: a child returns what it set + a `note`; a top-level run is rejected
|
|
64
65
|
# entry types: string integer number boolean date date-time object array file
|
|
66
|
+
# rules: format pattern minLength maxLength enum content (string); minimum maximum
|
|
67
|
+
# (integer number date date-time); minItems maxItems (array); accept maxSize (file)
|
|
65
68
|
instructions: >-
|
|
66
69
|
Record the decision in scratchpad/refund.json, then archmax_advance to
|
|
67
70
|
check-policy; never close the case yourself. If a note sends the case
|