jsfe 1.37.0 → 1.37.1
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 +1 -1
- package/dist/docs/flow-docs.d.ts.map +1 -1
- package/dist/docs/flow-docs.js +4 -3
- package/dist/forms/contracts.d.ts.map +1 -1
- package/dist/forms/contracts.js +2 -3
- package/dist/forms/flows.d.ts +3 -0
- package/dist/forms/flows.d.ts.map +1 -1
- package/dist/forms/flows.js +5 -0
- package/dist/forms/index.d.ts +1 -1
- package/dist/forms/index.js +1 -1
- package/dist/runtime-identity.js +1 -1
- package/docs/copilot-reference.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -387,7 +387,7 @@ means a reply that picks none of them. A picked choice sets `responseVariable` t
|
|
|
387
387
|
`answers` sets `{ key: '' }` unless `responseParameters` are declared too. The request carries the options it offers
|
|
388
388
|
(`request.options`); a host validates a reply against those, never a fixed list. The form readers use it: an unread
|
|
389
389
|
answer with any words goes to the ranker with the question's choices (`exact` ones too, since `exact` is how words match
|
|
390
|
-
a choice; never the YES of a firm confirmation
|
|
390
|
+
a choice; never the YES of a firm confirmation, which a form's confirmation is when an action it authorizes is `confirm.exact`; a NO always) and the escape every question supports, `__agent` (a person);
|
|
391
391
|
text is never offered. **Arguments in an unread answer** (jsfe 1.36): the asked input's `rank_parameters` (`[{ name, description, type?, reads? }]`) are extracted when the ranker says the reply answers the question, and a choice's own `parameters` when it is picked (`responseParameters` may name the array variable that holds them). Each value is read by the form's reader as if said alone: `reads` names the input it answers, else it answers the asked question, so that question's rules decide a number's field. Two readings of one input that differ take nothing, and nothing read asks again, as before. A form's `confirm.rank_parameters` do the same at its confirmation (no `reads`: read as a correction there); a value read changes the form, which is confirmed again. A charge or a cancellation is guarded by the action's `confirm: {exact: true}`, not by the choice's
|
|
392
392
|
`exact`. A confirmation's exhausted attempts go to the `give-up` worker.
|
|
393
393
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-docs.d.ts","sourceRoot":"","sources":["../../src/docs/flow-docs.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"flow-docs.d.ts","sourceRoot":"","sources":["../../src/docs/flow-docs.js"],"names":[],"mappings":"AAmBA;;;;;;;;;;;EA+RC"}
|
package/dist/docs/flow-docs.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import fs from 'fs';
|
|
16
16
|
import path from 'path';
|
|
17
17
|
import { resolveSetDataReferences } from '../forms/declarations.js';
|
|
18
|
+
import { confirmationFirmness } from '../forms/flows.js';
|
|
18
19
|
export function generateFlowDocs({ sets, root, check = false, hostRun = {}, log = console.log }) {
|
|
19
20
|
// A catalog or value written as {"$data": path} is documented as compilation resolves it.
|
|
20
21
|
const SETS = sets.map((s) => ({ ...s, flows: resolveSetDataReferences(s.flows) }));
|
|
@@ -354,7 +355,7 @@ export function generateFlowDocs({ sets, root, check = false, hostRun = {}, log
|
|
|
354
355
|
else { /* no menu */ }
|
|
355
356
|
return c.done();
|
|
356
357
|
}
|
|
357
|
-
function formChart(fm) {
|
|
358
|
+
function formChart(fm, performs) {
|
|
358
359
|
const c = builder();
|
|
359
360
|
if (fm.before && fm.before.length) {
|
|
360
361
|
c.steps(fm.before);
|
|
@@ -365,7 +366,7 @@ export function generateFlowDocs({ sets, root, check = false, hostRun = {}, log
|
|
|
365
366
|
c.then({ label: `${i.name}${i.label ? ' (' + i.label + ')' : ''}${extra ? ': ' + extra : ''}`, kind: 'input' });
|
|
366
367
|
}
|
|
367
368
|
if (fm.confirm) {
|
|
368
|
-
c.then({ label:
|
|
369
|
+
c.then({ label: `confirm (${confirmationFirmness(performs)})`, kind: 'decision' });
|
|
369
370
|
}
|
|
370
371
|
else { /* no confirmation */ }
|
|
371
372
|
if (fm.after && fm.after.length) {
|
|
@@ -414,7 +415,7 @@ export function generateFlowDocs({ sets, root, check = false, hostRun = {}, log
|
|
|
414
415
|
}
|
|
415
416
|
else { /* not a provider */ }
|
|
416
417
|
if (flow.form) {
|
|
417
|
-
out.push('', '### Form', '', formChart(flow.form));
|
|
418
|
+
out.push('', '### Form', '', formChart(flow.form, flow.performs));
|
|
418
419
|
}
|
|
419
420
|
else { /* not a form */ }
|
|
420
421
|
// A form the jsfe SDK compiled (the system set) carries its inputs as a variable; its steps are the engine's run-form loop.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/forms/contracts.js"],"names":[],"mappings":"AAgBA;;;IAGC;AACD;;;;;EAGC;AACD,qGAAqG;AACrG;;QAwCC;AAqBD;;;QAEC;AAgBD;;;;;;;;;QASC;AACD;;;;QAGC;AACD;;;;;;;;
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/forms/contracts.js"],"names":[],"mappings":"AAgBA;;;IAGC;AACD;;;;;EAGC;AACD,qGAAqG;AACrG;;QAwCC;AAqBD;;;QAEC;AAgBD;;;;;;;;;QASC;AACD;;;;QAGC;AACD;;;;;;;;QA8BC;AAED,mHAAmH;AACnH,kDAgBC;AAED,+GAA+G;AAC/G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4EC"}
|
package/dist/forms/contracts.js
CHANGED
|
@@ -5,7 +5,7 @@ import { INPUT_PROPOSALS_REQUIREMENT, hasInputProposals, proposalRuntimeSteps }
|
|
|
5
5
|
import { ACTION_TOOLS } from './action-tools.js';
|
|
6
6
|
import { normalizeHostRequirements } from '../host/capabilities.js';
|
|
7
7
|
import { validateActionProjection, actionProjectionExpression } from './action-projection.js';
|
|
8
|
-
import { formFlow, FIELD_PRESETS } from './flows.js';
|
|
8
|
+
import { formFlow, FIELD_PRESETS, confirmationFirmness } from './flows.js';
|
|
9
9
|
import { resolveFormInputs } from '../helpers/form-state.js';
|
|
10
10
|
const ROLES = new Set(['provider', 'performer', 'collector', 'gate', 'router', 'worker']);
|
|
11
11
|
const EFFECTS = new Set(['read', 'send', 'write', 'charge', 'cancel', 'handoff']);
|
|
@@ -158,8 +158,7 @@ export function definePerformer({ performs, contract, prepare, present, project
|
|
|
158
158
|
when('bad_request', "!(pf_action === null || pf_action && typeof pf_action === 'object' && pf_action.action) || pf_action !== null && (!pf_request || typeof pf_request !== 'object')", { id: `${spec.id}_prepare_failed`, type: 'FLOW', value: 'give-up', callType: 'reboot', recovery: { version: 1, mode: 'none', reason: 'performer_request_invalid' }, parameters: { context: '{{exit_context}}', context_es: '{{exit_context_es}}' } }),
|
|
159
159
|
set('proposal', 'pf_record', "pf_action ? prepareFormAction(cargo, form_instance, pf_action, pf_request) : null"),
|
|
160
160
|
];
|
|
161
|
-
|
|
162
|
-
const flow = formFlow({ ...spec, confirm, confirm_soft: !performs.some(action => action.confirm?.exact), confirmation_condition: "pf_action !== null && pf_action && typeof pf_action === 'object'",
|
|
161
|
+
const flow = formFlow({ ...spec, confirm, confirm_soft: confirmationFirmness(performs) === 'soft', confirmation_condition: "pf_action !== null && pf_action && typeof pf_action === 'object'",
|
|
163
162
|
extraVars: { ...spec.extraVars, ...(provides ? { provides, questions: providerQuestions(provides) } : {}), performs, projection: project, pf_action: null, pf_request: null, pf_record: null, pf_result: null, pf_receipt: null },
|
|
164
163
|
before_confirm: confirm ? [...prepareSteps, ...(spec.before_confirm || [])] : spec.before_confirm || [],
|
|
165
164
|
after: [...(confirm ? [] : prepareSteps),
|
package/dist/forms/flows.d.ts
CHANGED
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
*/
|
|
14
14
|
/** rank_parameters and a choice's parameters: [{ name, description, type?, reads? }] (reads: the input the value answers). */
|
|
15
15
|
export function validateRankParameters(id: any, name: any, what: any, list: any): void;
|
|
16
|
+
/** How firm a form's confirmation is: firm when an action it authorizes declares confirm.exact (charge, cancel, irreversible)
|
|
17
|
+
* or it authorizes none (a plain form); soft when it authorizes actions and none is exact (owner 2026-11-08). */
|
|
18
|
+
export function confirmationFirmness(performs: any): "firm" | "soft";
|
|
16
19
|
export function formFlow({ id, name, version, description, inputs, after, extraVars, parameters, confirm, confirm_soft, before_confirm, declined, stop, close_on_stop, on_no, resume_on_parent_change, before, done, primary, scope, validator, confirmation_condition, prompt, prompt_es, incomplete_outcome, on_exhausted, must_complete, first_task, first_task_es, acknowledge }: {
|
|
17
20
|
id: any;
|
|
18
21
|
name: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../src/forms/flows.js"],"names":[],"mappings":"AA6GA;;;;;;;GAOG;AACH;;;;GAIG;AACH,8HAA8H;AAC9H,uFAIC;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+DC;AACD;;;GAGG;AACH;;;;;;EAGC;AAolBD,wHAAwH;AACxH,wEAaC;AACD,4FAA4F;AAC5F;;;EAYC;AACD,sGAAsG;AACtG;;;EAOC;
|
|
1
|
+
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../src/forms/flows.js"],"names":[],"mappings":"AA6GA;;;;;;;GAOG;AACH;;;;GAIG;AACH,8HAA8H;AAC9H,uFAIC;AAiBD;iHACiH;AACjH,qEAEC;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+DC;AACD;;;GAGG;AACH;;;;;;EAGC;AAolBD,wHAAwH;AACxH,wEAaC;AACD,4FAA4F;AAC5F;;;EAYC;AACD,sGAAsG;AACtG;;;EAOC;AA3yBM,6CAAuG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAogC9G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAOG"}
|
package/dist/forms/flows.js
CHANGED
|
@@ -145,6 +145,11 @@ function validateAcceptanceDeclarations(id, inputs) {
|
|
|
145
145
|
else { /* no invites, or a list of names */ }
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
+
/** How firm a form's confirmation is: firm when an action it authorizes declares confirm.exact (charge, cancel, irreversible)
|
|
149
|
+
* or it authorizes none (a plain form); soft when it authorizes actions and none is exact (owner 2026-11-08). */
|
|
150
|
+
export function confirmationFirmness(performs) {
|
|
151
|
+
return Array.isArray(performs) && performs.length && !performs.some((action) => action?.confirm?.exact) ? 'soft' : 'firm';
|
|
152
|
+
}
|
|
148
153
|
export function formFlow({ id, name, version, description, inputs, after = [], extraVars = {}, parameters = [], confirm = null, confirm_soft = false, before_confirm = [], declined = [], stop = '', close_on_stop = false, on_no = '', resume_on_parent_change = false, before = [], done = true, primary = false, scope = 'isolated', validator = '', confirmation_condition = 'true', prompt = undefined, prompt_es = undefined, incomplete_outcome = null, on_exhausted = null, must_complete = false, first_task = '', first_task_es = '', acknowledge = 'all' }) {
|
|
149
154
|
validateFormExhaustion(on_exhausted);
|
|
150
155
|
if (acknowledge !== 'all' && acknowledge !== 'data')
|
package/dist/forms/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { explainSession } from "./inspection.js";
|
|
|
5
5
|
export { continuationBreaks } from "./continuation-compat.js";
|
|
6
6
|
export { inheritFlowDeclaration } from "./declaration-capture.js";
|
|
7
7
|
export { withSafetyRevision, CONTINUATION_SAFETY_REQUIREMENT } from "./continuation-safety.js";
|
|
8
|
-
export { FIELD_PRESETS, formFlow, declinedFlow, textValue } from "./flows.js";
|
|
8
|
+
export { FIELD_PRESETS, formFlow, declinedFlow, textValue, confirmationFirmness } from "./flows.js";
|
|
9
9
|
export { linkFormSchemas, defineWorker, defineProvider, defineForm, definePerformer, validateFlowContracts, operationWorkers, providerQuestions, providerParameter } from "./contracts.js";
|
|
10
10
|
export { addressDraft, zipLocation, streetLocation, resolvedAddress } from "../helpers/address.js";
|
|
11
11
|
export { Form, Provider, Performer, Worker, compileExpression } from "./authoring.js";
|
package/dist/forms/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { FLOWS as FORM_FLOWS } from './flows.js';
|
|
|
5
5
|
import { FLOWS as CHOICE_FLOWS } from './choice-flow.js';
|
|
6
6
|
import { FLOWS as IDENTITY } from './identity-flows.js';
|
|
7
7
|
export const FLOWS = [...FORM_FLOWS, ...ADDRESS_FLOWS, ...CHOICE_FLOWS, ...IDENTITY].map(flow => withSafetyRevision(flow, 'dispatch-intake-2026-10-22'));
|
|
8
|
-
export { FIELD_PRESETS, formFlow, declinedFlow, textValue } from './flows.js';
|
|
8
|
+
export { FIELD_PRESETS, formFlow, declinedFlow, textValue, confirmationFirmness } from './flows.js';
|
|
9
9
|
export { FLOWS as IDENTITY_FLOWS } from './identity-flows.js';
|
|
10
10
|
export { linkFormSchemas, defineWorker, defineProvider, defineForm, definePerformer, validateFlowContracts, operationWorkers, providerQuestions, providerParameter } from './contracts.js';
|
|
11
11
|
export { compileFormPrompts } from './prompt-compiler.js';
|
package/dist/runtime-identity.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const JSFE_RUNTIME_FINGERPRINT = "sha256:
|
|
1
|
+
export const JSFE_RUNTIME_FINGERPRINT = "sha256:452fe6731c7d9d4b43d0961d3eb33a429f0d3c2d7392acb968f4cbda7f514c95";
|
|
@@ -347,7 +347,7 @@ A Performer requires `form`, nonempty `performs`, `prepare` worker and `present`
|
|
|
347
347
|
| `subject` | Ownership path such as `form.data.account` or `form.data.subject`; bind account/service identity, not an unrelated session flag. |
|
|
348
348
|
| `gate:{flow?,verified:[paths]}` | Execution-time verification; rerun the declared flow before each fresh effect. |
|
|
349
349
|
| `flow`, `tool` | Installed executor worker and/or registered tool identity. |
|
|
350
|
-
| `confirm:{exact:true}` | Required for charge, cancel or `reversible:false`. This requires a real form confirmation question. |
|
|
350
|
+
| `confirm:{exact:true}` | Required for charge, cancel or `reversible:false`. This requires a real form confirmation question, and makes it firm (YES only by `CONFIRM_WORDS` or its own exact phrases, never offered to the reply ranker). A performer none of whose actions is exact (filing a request) confirms softly: the wider YES vocabulary, and YES is offered to the ranker. There is no separate attribute for this. |
|
|
351
351
|
| `outcomes` | Map declared executor statuses to business outcomes, including unknown results. |
|
|
352
352
|
| `retry` | Explicit policies: `after:[knownStatuses]`; unknown retry only for SEND with `unknown:"explicit"` and a new accepted recovery choice. |
|
|
353
353
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsfe",
|
|
3
|
-
"version": "1.37.
|
|
3
|
+
"version": "1.37.1",
|
|
4
4
|
"description": "TypeScript workflow engine for conversational/automation apps: multi-flow orchestration, interrupt/resume, stack-based control, robust errors, and flexible tool/REST integration.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ron Pinkas",
|