@openapi-flow/core 0.3.1 → 0.3.3

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.
Files changed (26) hide show
  1. package/README.md +3 -1
  2. package/dist/draft/edits/inputs/create-workflow-draft-api-input-edit-contract.js +3 -1
  3. package/dist/draft/edits/inputs/describe-workflow-draft-api-input-edit.js +17 -9
  4. package/dist/draft/edits/inputs/resolve-workflow-draft-api-input-edits.js +24 -7
  5. package/dist/public-api.d.ts +2 -0
  6. package/dist/public-api.js +2 -0
  7. package/dist/schemas/create-workflow-draft-api-input-edit-answers-schema.d.ts +3 -0
  8. package/dist/schemas/create-workflow-draft-api-input-edit-answers-schema.js +39 -0
  9. package/dist/schemas/create-workflow-draft-api-input-edit-target-value-schema.d.ts +5 -0
  10. package/dist/schemas/create-workflow-draft-api-input-edit-target-value-schema.js +24 -0
  11. package/dist/schemas/create-workflow-draft-api-input-edit-values-schema.js +2 -24
  12. package/dist/schemas/create-workflow-draft-edit-proposal-schema.js +1 -1
  13. package/dist/schemas/native-node-planning-record-schema.d.ts +4 -0
  14. package/dist/schemas/native-node-planning-record-schema.js +2 -1
  15. package/dist/schemas/workflow-connection-planning-schema.d.ts +4 -0
  16. package/dist/schemas/workflow-connection-planning-schema.js +2 -1
  17. package/dist/schemas/workflow-draft-api-input-edit-answers-schema.d.ts +13 -0
  18. package/dist/schemas/workflow-draft-api-input-edit-answers-schema.js +10 -0
  19. package/dist/schemas/workflow-draft-edit-message-fields.js +1 -1
  20. package/dist/schemas/workflow-draft-edit-plan-schema.d.ts +1 -1
  21. package/dist/types/native-node-planning.d.ts +3 -2
  22. package/dist/types/workflow-connection-planning.d.ts +4 -3
  23. package/dist/types/workflow-draft-api-input-edit.d.ts +20 -3
  24. package/dist/workflow/connections/describe-workflow-connection-planning.js +5 -3
  25. package/dist/workflow/planning/describe-native-node-planning.js +4 -0
  26. package/package.json +1 -1
package/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  Zod `^4.6.5` is a required peer, shared with the host rather than installed as a separately pinned runtime copy. Development tests use 4.6.5; the strict installed-consumer check also uses the host's 4.6.7. This preserves the public schema type boundary without casts or dependency overrides.
4
4
 
5
- Version **0.3.1**. Canonical draft, clarification and runtime-input APIs described below are included in this release. Ajv 8.20.0 does not correctly validate a declared `properties.__proto__`; generated validation may reject valid data or omit that property's constraints. This previously accepted limitation remains unchanged, without renaming data or skipping its failing regression. See the [release record](https://github.com/carefreelife98/openapi-flow/blob/main/docs/releases/0.3.1.md).
5
+ Version **0.3.3**. Canonical draft, clarification and runtime-input APIs described below are included in this release. Ajv 8.20.0 does not correctly validate a declared `properties.__proto__`; generated validation may reject valid data or omit that property's constraints. This previously accepted limitation remains unchanged, without renaming data or skipping its failing regression. See the [release record](https://github.com/carefreelife98/openapi-flow/blob/main/docs/releases/0.3.3.md).
6
+
7
+ Native and fixed-material connection planning accept the optional, existing `WorkflowEntryPointContract` as `entrypoint`. Core validates and snapshots this owner-provided start alongside the other inputs; it does not infer one when absent, add a selectable trigger or let model output modify it.
6
8
 
7
9
  Connection planning accepts explicit current `deferredApiInputIds` derived with `collectDeferredApiInputSlots`. Missing inputs remain absent and require canonical template preflight before execution; supplied values and the full DAG are still validated. See [input deferral](https://github.com/carefreelife98/openapi-flow/blob/main/docs/deferred-connection-planning.md).
8
10
 
@@ -62,7 +62,9 @@ export function createWorkflowDraftApiInputEditContract(input) {
62
62
  };
63
63
  return {
64
64
  id: 'api-input-edit:' +
65
- createHash('sha256').update(JSON.stringify(fields)).digest('hex'),
65
+ createHash('sha256')
66
+ .update(JSON.stringify([described.stageFingerprint, fields]))
67
+ .digest('hex'),
66
68
  ...fields,
67
69
  };
68
70
  }
@@ -1,31 +1,39 @@
1
- import { validateWorkflowDraftEditPlan } from '../validate-workflow-draft-edit-plan.js';
1
+ import { stageWorkflowDraftEdit } from '../stage-workflow-draft-edit.js';
2
2
  import { createApiRequestSchema } from '../../../schemas/create-api-request-schema.js';
3
3
  import { resolveWorkflowDraftApiMaterials } from '../../resolve-workflow-draft-api-materials.js';
4
4
  import { resolveWorkflowPlanningMessages } from '../../../planning/evidence/resolve-workflow-planning-messages.js';
5
5
  export function describeWorkflowDraftApiInputEdit(input) {
6
- validateWorkflowDraftEditPlan(input);
6
+ const stage = stageWorkflowDraftEdit({
7
+ ...input,
8
+ resolutions: input.resolutions === undefined ? [] : input.resolutions,
9
+ });
7
10
  const step = input.plan.steps.find((step) => step.id === input.stepId);
8
11
  if (!step || step.decision.kind !== 'revise-api-inputs')
9
12
  throw new Error('API input edit stepId must identify a revise-api-inputs decision');
10
13
  const nodeId = step.decision.nodeId;
11
- if (input.plan.steps.some((other) => other.decision.kind === 'replace-api-operation' &&
12
- other.decision.nodeId === nodeId))
13
- throw new Error('API input edit must use a draft after its operation replacement is resolved');
14
- const original = input.draft.apiCalls.find((call) => call.id === nodeId);
14
+ if (!stage.pendingResolutionStepIds.includes(step.id))
15
+ throw new Error('API input edit step already has a supplied result; remove that result explicitly before replanning');
16
+ if (stage.blockedSourceNodeIds.includes(nodeId))
17
+ throw new Error(`API input edit target ${nodeId} is blocked by an unresolved contract or requirement`);
18
+ const stagedCall = stage.content.apiCalls.find((call) => call.id === nodeId);
19
+ if (stagedCall === undefined)
20
+ throw new Error(`API input edit target ${nodeId} has no staged API instance`);
15
21
  const material = resolveWorkflowDraftApiMaterials({
16
- content: input.draft,
22
+ content: stage.content,
17
23
  context: input.context,
18
- }).find((item) => item.callId === original.id);
24
+ }).find((item) => item.callId === stagedCall.id);
19
25
  const call = structuredClone({
20
- ...original,
26
+ ...stagedCall,
21
27
  ...(input.requestMediaType === undefined
22
28
  ? {}
23
29
  : { requestMediaType: input.requestMediaType }),
24
30
  });
25
31
  return {
32
+ stageFingerprint: stage.fingerprint,
26
33
  stepId: step.id,
27
34
  instruction: step.decision.instruction,
28
35
  call,
36
+ operation: structuredClone(material.operation),
29
37
  requestSchema: createApiRequestSchema({
30
38
  operation: material.operation,
31
39
  requestMediaType: call.requestMediaType,
@@ -1,8 +1,8 @@
1
1
  import { createWorkflowDraftApiInputEditValuesSchema } from '../../../schemas/create-workflow-draft-api-input-edit-values-schema.js';
2
+ import { createWorkflowDraftApiInputEditAnswersSchema } from '../../../schemas/create-workflow-draft-api-input-edit-answers-schema.js';
2
3
  import { describeWorkflowDraftApiInputEdit } from './describe-workflow-draft-api-input-edit.js';
3
4
  import { validateWorkflowPlanningEvidence } from '../../../planning/evidence/validate-workflow-planning-evidence.js';
4
5
  import { applyWorkflowDraftApiInputEdits } from '../values/apply-workflow-draft-api-input-edits.js';
5
- import { resolveWorkflowDraftApiMaterials } from '../../resolve-workflow-draft-api-materials.js';
6
6
  import { validateApiArguments } from '../../../arguments/validate-api-arguments.js';
7
7
  import { orderWorkflowDraftValueEdits } from '../values/order-workflow-draft-value-edits.js';
8
8
  import { verifyApiInputLiteralSource } from '../../../arguments/sources/verify-api-input-literal-source.js';
@@ -10,6 +10,12 @@ import { verifyApiInputLiteralSource } from '../../../arguments/sources/verify-a
10
10
  export function resolveWorkflowDraftApiInputEdits(input) {
11
11
  const output = createWorkflowDraftApiInputEditValuesSchema(input).parse(input.output);
12
12
  const described = describeWorkflowDraftApiInputEdit(input);
13
+ const confirmedAnswers = input.confirmedAnswers === undefined
14
+ ? undefined
15
+ : structuredClone(createWorkflowDraftApiInputEditAnswersSchema(input).parse(input.confirmedAnswers));
16
+ const human = confirmedAnswers === undefined
17
+ ? {}
18
+ : { confirmedAnswers: structuredClone(confirmedAnswers) };
13
19
  const sets = [];
14
20
  const removals = [];
15
21
  const pendingTargets = [];
@@ -25,7 +31,15 @@ export function resolveWorkflowDraftApiInputEdits(input) {
25
31
  evidence: answer.explanation.evidence,
26
32
  });
27
33
  if (answer.status === 'needs-input') {
28
- pendingTargets.push(structuredClone(target));
34
+ const confirmed = confirmedAnswers?.answers.find((item) => item.targetId === target.id);
35
+ if (confirmed === undefined)
36
+ pendingTargets.push(structuredClone(target));
37
+ else
38
+ sets.push({
39
+ kind: 'set',
40
+ pointer: target.pointer,
41
+ value: structuredClone(confirmed.value),
42
+ });
29
43
  continue;
30
44
  }
31
45
  const message = described.messages.find((message) => message.id === answer.source.messageId);
@@ -45,16 +59,18 @@ export function resolveWorkflowDraftApiInputEdits(input) {
45
59
  contractId: input.contract.id,
46
60
  values: output,
47
61
  pendingTargets,
62
+ ...human,
48
63
  };
49
64
  // Targets address the original value. Set before deletion; remove higher array
50
65
  // indices first so one deletion does not retarget another original index.
51
66
  const edits = orderWorkflowDraftValueEdits([...sets, ...removals]);
52
- const material = resolveWorkflowDraftApiMaterials({
53
- content: input.draft,
54
- context: input.context,
55
- }).find((item) => item.callId === described.call.id);
56
67
  const selected = {
57
- ...material,
68
+ callId: described.call.id,
69
+ operation: described.operation,
70
+ bindings: described.call.bindings,
71
+ ...(described.call.requestedInputs === undefined
72
+ ? {}
73
+ : { requestedInputs: described.call.requestedInputs }),
58
74
  requestMediaType: described.call.requestMediaType,
59
75
  };
60
76
  const values = applyWorkflowDraftApiInputEdits(described.call.values, edits, selected);
@@ -63,6 +79,7 @@ export function resolveWorkflowDraftApiInputEdits(input) {
63
79
  status: 'ready',
64
80
  contractId: input.contract.id,
65
81
  values: output,
82
+ ...human,
66
83
  resolution: {
67
84
  stepId: input.stepId,
68
85
  kind: 'api-inputs',
@@ -101,6 +101,8 @@ export { createWorkflowDraftApiInputEditContract } from './draft/edits/inputs/cr
101
101
  export { validateWorkflowDraftApiInputEditContract } from './draft/edits/inputs/validate-workflow-draft-api-input-edit-contract.js';
102
102
  export { createWorkflowDraftApiInputEditProposalSchema } from './schemas/workflow-draft-api-input-edit-proposal-schema.js';
103
103
  export { createWorkflowDraftApiInputEditValuesSchema } from './schemas/create-workflow-draft-api-input-edit-values-schema.js';
104
+ export { createWorkflowDraftApiInputEditAnswersSchema } from './schemas/create-workflow-draft-api-input-edit-answers-schema.js';
105
+ export { workflowDraftApiInputEditAnswersSchema } from './schemas/workflow-draft-api-input-edit-answers-schema.js';
104
106
  export { resolveWorkflowDraftApiInputEdits } from './draft/edits/inputs/resolve-workflow-draft-api-input-edits.js';
105
107
  export { prepareWorkflowDraftEdit } from './draft/edits/prepare-workflow-draft-edit.js';
106
108
  export { assembleWorkflowDraftEdit } from './draft/edits/assemble-workflow-draft-edit.js';
@@ -72,6 +72,8 @@ export { createWorkflowDraftApiInputEditContract } from './draft/edits/inputs/cr
72
72
  export { validateWorkflowDraftApiInputEditContract } from './draft/edits/inputs/validate-workflow-draft-api-input-edit-contract.js';
73
73
  export { createWorkflowDraftApiInputEditProposalSchema } from './schemas/workflow-draft-api-input-edit-proposal-schema.js';
74
74
  export { createWorkflowDraftApiInputEditValuesSchema } from './schemas/create-workflow-draft-api-input-edit-values-schema.js';
75
+ export { createWorkflowDraftApiInputEditAnswersSchema } from './schemas/create-workflow-draft-api-input-edit-answers-schema.js';
76
+ export { workflowDraftApiInputEditAnswersSchema } from './schemas/workflow-draft-api-input-edit-answers-schema.js';
75
77
  export { resolveWorkflowDraftApiInputEdits } from './draft/edits/inputs/resolve-workflow-draft-api-input-edits.js';
76
78
  export { prepareWorkflowDraftEdit } from './draft/edits/prepare-workflow-draft-edit.js';
77
79
  export { assembleWorkflowDraftEdit } from './draft/edits/assemble-workflow-draft-edit.js';
@@ -0,0 +1,3 @@
1
+ import type { WorkflowDraftApiInputEditAnswerSchemaInput, WorkflowDraftApiInputEditAnswersSchema } from '../types/workflow-draft-api-input-edit.js';
2
+ /** Human replies own values only for targets the original proposal left pending. */
3
+ export declare function createWorkflowDraftApiInputEditAnswersSchema(input: WorkflowDraftApiInputEditAnswerSchemaInput): WorkflowDraftApiInputEditAnswersSchema;
@@ -0,0 +1,39 @@
1
+ import { z } from 'zod';
2
+ import { createWorkflowDraftApiInputEditValuesSchema } from './create-workflow-draft-api-input-edit-values-schema.js';
3
+ import { createWorkflowDraftApiInputEditTargetValueSchema } from './create-workflow-draft-api-input-edit-target-value-schema.js';
4
+ import { createSchemaResourceContext } from '../bindings/resources/create-schema-resource-context.js';
5
+ import { workflowDraftApiInputEditAnswerSchema, workflowDraftApiInputEditAnswersSchema, } from './workflow-draft-api-input-edit-answers-schema.js';
6
+ /** Human replies own values only for targets the original proposal left pending. */
7
+ export function createWorkflowDraftApiInputEditAnswersSchema(input) {
8
+ const output = createWorkflowDraftApiInputEditValuesSchema(input).parse(input.output);
9
+ const targets = input.contract.targets
10
+ .filter((target) => target.kind === 'set')
11
+ .filter((target) => output.values[target.id].status === 'needs-input');
12
+ const resources = createSchemaResourceContext(input.contract.schemaResource);
13
+ const wire = resources.bundleStaticProjections(Object.fromEntries(targets.map((target) => [target.id, target.schema])));
14
+ const alternatives = targets.map((target) => workflowDraftApiInputEditAnswerSchema.extend({
15
+ targetId: z
16
+ .literal(target.id)
17
+ .describe(`The pending input target ${target.pointer} in this contract.`),
18
+ value: createWorkflowDraftApiInputEditTargetValueSchema(target, resources, input.contract.nodeId, wire.projections[target.id]),
19
+ }));
20
+ const answers = alternatives.length === 0
21
+ ? z.array(z.never()).max(0)
22
+ : z
23
+ .array(alternatives.length === 1 ? alternatives[0] : z.union(alternatives))
24
+ .superRefine((items, context) => {
25
+ if (new Set(items.map((item) => item.targetId)).size !== items.length)
26
+ context.addIssue({
27
+ code: 'custom',
28
+ message: 'Typed API edit answers require distinct pending target IDs',
29
+ });
30
+ });
31
+ return workflowDraftApiInputEditAnswersSchema
32
+ .extend({
33
+ contractId: z.literal(input.contract.id),
34
+ answers,
35
+ })
36
+ .meta({
37
+ $defs: wire.definitions,
38
+ });
39
+ }
@@ -0,0 +1,5 @@
1
+ import type { WorkflowDraftApiInputEditTarget } from '../types/workflow-draft-api-input-edit.js';
2
+ import type { SchemaResourceContext } from '../types/schema-resource.js';
3
+ import type { BindingSchema } from '../types/api-bindings.js';
4
+ /** The same original OAS value assertions for model proposals and explicit typed replies. */
5
+ export declare function createWorkflowDraftApiInputEditTargetValueSchema(target: WorkflowDraftApiInputEditTarget, resources: SchemaResourceContext, nodeId: string, projection: BindingSchema): import("zod").ZodType<import("../public-api.js").JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<import("../public-api.js").JsonValue, unknown>>;
@@ -0,0 +1,24 @@
1
+ import { createOasValueValidator } from '../openapi/common/create-oas-value-validator.js';
2
+ import { createOasValueValidationSchema } from './create-oas-value-validation-schema.js';
3
+ /** The same original OAS value assertions for model proposals and explicit typed replies. */
4
+ export function createWorkflowDraftApiInputEditTargetValueSchema(target, resources, nodeId, projection) {
5
+ if (target.kind !== 'set')
6
+ throw new Error(`API input edit set target ${target.pointer} has no OAS schema`);
7
+ const assertions = typeof target.schema === 'boolean'
8
+ ? target.schema
9
+ ? {}
10
+ : { not: {} }
11
+ : target.schema;
12
+ const source = `API input edit ${nodeId}${target.pointer}`;
13
+ const wireAssertions = typeof projection === 'boolean'
14
+ ? projection
15
+ ? {}
16
+ : { not: {} }
17
+ : projection;
18
+ return createOasValueValidationSchema(createOasValueValidator({ ...assertions, $defs: { resource: resources.root } }, 'draft-2020-12', source), source).meta(typeof wireAssertions.$ref === 'string'
19
+ ? wireAssertions
20
+ : {
21
+ ...wireAssertions,
22
+ description: 'The complete actual value explicitly supplied by the current user request. Preserve its type. No examples, defaults, old field values or invented placeholders.',
23
+ });
24
+ }
@@ -1,31 +1,9 @@
1
1
  import { z } from 'zod';
2
2
  import { validateWorkflowDraftApiInputEditContract } from '../draft/edits/inputs/validate-workflow-draft-api-input-edit-contract.js';
3
3
  import { createWorkflowDraftEditMessageFields } from './workflow-draft-edit-message-fields.js';
4
- import { createOasValueValidator } from '../openapi/common/create-oas-value-validator.js';
5
- import { createOasValueValidationSchema } from './create-oas-value-validation-schema.js';
4
+ import { createWorkflowDraftApiInputEditTargetValueSchema } from './create-workflow-draft-api-input-edit-target-value-schema.js';
6
5
  import { createSchemaResourceContext } from '../bindings/resources/create-schema-resource-context.js';
7
6
  import { apiInputLiteralSourceSchema } from './api-input-literal-source-schema.js';
8
- function targetValueSchema(target, resources, nodeId, projection) {
9
- if (target.kind !== 'set')
10
- throw new Error(`API input edit set target ${target.pointer} has no OAS schema`);
11
- const assertions = typeof target.schema === 'boolean'
12
- ? target.schema
13
- ? {}
14
- : { not: {} }
15
- : target.schema;
16
- const source = `API input edit ${nodeId}${target.pointer}`;
17
- const wireAssertions = typeof projection === 'boolean'
18
- ? projection
19
- ? {}
20
- : { not: {} }
21
- : projection;
22
- return createOasValueValidationSchema(createOasValueValidator({ ...assertions, $defs: { resource: resources.root } }, 'draft-2020-12', source), source).meta(typeof wireAssertions.$ref === 'string'
23
- ? wireAssertions
24
- : {
25
- ...wireAssertions,
26
- description: 'The complete actual value explicitly supplied by the current user request. Preserve its type. No examples, defaults, old field values or invented placeholders.',
27
- });
28
- }
29
7
  /** Only selected set-values are model-owned; per-field OAS assertions stay intact. */
30
8
  export function createWorkflowDraftApiInputEditValuesSchema(input, messageSchema) {
31
9
  validateWorkflowDraftApiInputEditContract(input);
@@ -43,7 +21,7 @@ export function createWorkflowDraftApiInputEditValuesSchema(input, messageSchema
43
21
  z.union([
44
22
  z.strictObject({
45
23
  status: z.literal('provided'),
46
- value: targetValueSchema(target, resources, input.contract.nodeId, wire.projections[target.id]),
24
+ value: createWorkflowDraftApiInputEditTargetValueSchema(target, resources, input.contract.nodeId, wire.projections[target.id]),
47
25
  source: apiInputLiteralSourceSchema.extend({
48
26
  messageId: z.enum(input.requestMessageIds),
49
27
  }),
@@ -7,7 +7,7 @@ export function createWorkflowDraftEditProposalSchema(options, sources) {
7
7
  reason: z
8
8
  .string()
9
9
  .min(1)
10
- .describe('A short user-facing reason, not chain-of-thought.'),
10
+ .describe("A short user-facing reason in the current user's language, not chain-of-thought. Do not translate identifiers, literal values or source quotations."),
11
11
  evidence: z.array(sources.evidenceSchema).min(1),
12
12
  });
13
13
  const fields = {
@@ -4,6 +4,10 @@ export declare const nativeNodePlanningOptionsSchema: z.ZodObject<{
4
4
  planId: z.ZodString;
5
5
  scenario: z.ZodString;
6
6
  allowRuntimeParameters: z.ZodOptional<z.ZodBoolean>;
7
+ entrypoint: z.ZodOptional<z.ZodObject<{
8
+ kind: z.ZodString;
9
+ description: z.ZodString;
10
+ }, z.core.$strict>>;
7
11
  }, z.core.$strict>;
8
12
  export declare const nativePlanningProposalSchema: z.ZodObject<{
9
13
  nativeNodes: z.ZodArray<z.ZodObject<{
@@ -1,10 +1,11 @@
1
1
  import { z } from 'zod';
2
- import { planningEvidenceTextSchema } from './planning-evidence-schema.js';
2
+ import { planningEvidenceTextSchema, workflowEntryPointContractSchema, } from './planning-evidence-schema.js';
3
3
  import { workflowDraftNativeNodeSchema } from './workflow-draft-schema.js';
4
4
  export const nativeNodePlanningOptionsSchema = z.strictObject({
5
5
  planId: planningEvidenceTextSchema,
6
6
  scenario: planningEvidenceTextSchema,
7
7
  allowRuntimeParameters: z.boolean().optional(),
8
+ entrypoint: workflowEntryPointContractSchema.optional(),
8
9
  });
9
10
  export const nativePlanningProposalSchema = z.strictObject({
10
11
  nativeNodes: z.array(workflowDraftNativeNodeSchema),
@@ -4,6 +4,10 @@ import type { WorkflowPlanningSourceEvidence } from '../types/workflow-planning-
4
4
  import type { WorkflowPlanNodeContract } from '../types/workflow-plan.js';
5
5
  export declare const workflowConnectionIdentitySchema: z.ZodObject<{
6
6
  scenario: z.ZodString;
7
+ entrypoint: z.ZodOptional<z.ZodObject<{
8
+ kind: z.ZodString;
9
+ description: z.ZodString;
10
+ }, z.core.$strict>>;
7
11
  }, z.core.$strict>;
8
12
  export declare const workflowConnectionProposalSchema: z.ZodObject<{
9
13
  edges: z.ZodArray<z.ZodObject<{
@@ -1,9 +1,10 @@
1
1
  import { z } from 'zod';
2
- import { planningEvidenceTextSchema } from './planning-evidence-schema.js';
2
+ import { planningEvidenceTextSchema, workflowEntryPointContractSchema, } from './planning-evidence-schema.js';
3
3
  import { workflowDraftNativeNodeSchema, workflowDraftEdgeSchema, } from './workflow-draft-schema.js';
4
4
  import { workflowReviewGapSchema, workflowBlockedCallSchema, } from './workflow-planning-material-schema.js';
5
5
  export const workflowConnectionIdentitySchema = z.strictObject({
6
6
  scenario: planningEvidenceTextSchema,
7
+ entrypoint: workflowEntryPointContractSchema.optional(),
7
8
  });
8
9
  export const workflowConnectionProposalSchema = z.strictObject({
9
10
  edges: z.array(workflowDraftEdgeSchema),
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ /** Transport shape only. The contextual factory owns current-target and OAS checks. */
3
+ export declare const workflowDraftApiInputEditAnswerSchema: z.ZodObject<{
4
+ targetId: z.ZodString;
5
+ value: z.ZodJSONSchema;
6
+ }, z.core.$strict>;
7
+ export declare const workflowDraftApiInputEditAnswersSchema: z.ZodObject<{
8
+ contractId: z.ZodString;
9
+ answers: z.ZodArray<z.ZodObject<{
10
+ targetId: z.ZodString;
11
+ value: z.ZodJSONSchema;
12
+ }, z.core.$strict>>;
13
+ }, z.core.$strict>;
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ /** Transport shape only. The contextual factory owns current-target and OAS checks. */
3
+ export const workflowDraftApiInputEditAnswerSchema = z.strictObject({
4
+ targetId: z.string().min(1),
5
+ value: z.json(),
6
+ });
7
+ export const workflowDraftApiInputEditAnswersSchema = z.strictObject({
8
+ contractId: z.string().min(1),
9
+ answers: z.array(workflowDraftApiInputEditAnswerSchema),
10
+ });
@@ -25,7 +25,7 @@ export function createWorkflowDraftEditMessageFields(messageIds, includeExplanat
25
25
  reason: z
26
26
  .string()
27
27
  .min(1)
28
- .describe('Short user-facing reason, not chain-of-thought.'),
28
+ .describe("Short user-facing reason in the current user's language, not chain-of-thought. Do not translate identifiers, literal values or source quotations."),
29
29
  evidence: z.array(message).min(1),
30
30
  }),
31
31
  }
@@ -21,13 +21,13 @@ export declare const workflowDraftEditPlanSchema: z.ZodObject<{
21
21
  decision: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
22
22
  newNodeId: z.ZodOptional<z.ZodString>;
23
23
  stages: z.ZodArray<z.ZodEnum<{
24
+ clarification: "clarification";
24
25
  "api-bindings": "api-bindings";
25
26
  "api-arguments": "api-arguments";
26
27
  "native-parameters": "native-parameters";
27
28
  requirements: "requirements";
28
29
  connections: "connections";
29
30
  "resolve-contracts": "resolve-contracts";
30
- clarification: "clarification";
31
31
  }>>;
32
32
  }, z.core.$strict>>;
33
33
  }, z.core.$strict>;
@@ -1,4 +1,5 @@
1
1
  import type { ApiBindingMaterial } from './api-bindings.js';
2
+ import type { WorkflowPlanningContext } from './planning-evidence.js';
2
3
  import type { z } from 'zod';
3
4
  import type { JsonValueObject } from './api-arguments.js';
4
5
  import type { JsonObject } from './openapi.js';
@@ -8,7 +9,7 @@ import type { NativeInstanceDependencyPlan, NativeNodeConfigurationDependencies
8
9
  import type { WorkflowNativeMaterialSources, MissingWorkflowNativeMaterialRequirement, ResolveNativeMaterialSnapshotInput } from './native-material-snapshot.js';
9
10
  import type { WorkflowReviewGap } from './reviewable-workflow.js';
10
11
  import type { PlannedNativeNode, WorkflowCapability, WorkflowPlanGap, WorkflowPlanNodeContract, NativeRuntimeParameterSelection } from './workflow-plan.js';
11
- export interface NativeNodePlanningInput {
12
+ export interface NativeNodePlanningInput extends Pick<WorkflowPlanningContext, 'entrypoint'> {
12
13
  planId: string;
13
14
  scenario: string;
14
15
  capabilities?: WorkflowCapability[];
@@ -38,7 +39,7 @@ export interface NativePlanningApiMaterial {
38
39
  operation: ApiBindingMaterial['operation']['operation'];
39
40
  effective: ApiBindingMaterial['operation']['effective'];
40
41
  }
41
- export interface NativeNodePlanningContext {
42
+ export interface NativeNodePlanningContext extends Pick<WorkflowPlanningContext, 'entrypoint'> {
42
43
  scenario: string;
43
44
  apiMaterials: NativePlanningApiMaterial[];
44
45
  preparedNativeNodes: PreparedNativeNodeMaterial[];
@@ -4,6 +4,7 @@ import type { PreparedNativeNodeMaterial } from './native-node-planning.js';
4
4
  import type { WorkflowPlanningSourceEvidence } from './workflow-planning-materials.js';
5
5
  import type { WorkflowApiInputDeferral } from './workflow-api-input-readiness.js';
6
6
  import type { DeferredApiInputSlot } from './deferred-api-inputs.js';
7
+ import type { WorkflowPlanningContext } from './planning-evidence.js';
7
8
  export interface WorkflowConnectionMaterialInput extends WorkflowApiInputDeferral {
8
9
  materials?: ReviewableWorkflowApiMaterial[];
9
10
  capabilities?: WorkflowCapability[];
@@ -11,7 +12,7 @@ export interface WorkflowConnectionMaterialInput extends WorkflowApiInputDeferra
11
12
  gaps?: WorkflowReviewGap[];
12
13
  edges?: WorkflowPlanEdge[];
13
14
  }
14
- export interface WorkflowConnectionPlanningInput extends WorkflowConnectionMaterialInput {
15
+ export interface WorkflowConnectionPlanningInput extends WorkflowConnectionMaterialInput, Pick<WorkflowPlanningContext, 'entrypoint'> {
15
16
  scenario: string;
16
17
  }
17
18
  export interface WorkflowConnectionMaterials extends WorkflowApiInputDeferral {
@@ -33,7 +34,7 @@ export interface WorkflowNativeParameterReadiness {
33
34
  /** Explicit runtime ownership, not missing plan-time values or unresolved graph gaps. */
34
35
  executionInputPointers: string[];
35
36
  }
36
- export interface WorkflowConnectionPlanningContext {
37
+ export interface WorkflowConnectionPlanningContext extends Pick<WorkflowPlanningContext, 'entrypoint'> {
37
38
  scenario: string;
38
39
  nodes: WorkflowPlanNodeContract[];
39
40
  nativeNodes?: PreparedNativeNodeMaterial[];
@@ -45,7 +46,7 @@ export interface WorkflowConnectionPlanningContext {
45
46
  /** Code-derived missing values, never missing API capabilities or generated literals. */
46
47
  deferredApiInputs?: DeferredApiInputSlot[];
47
48
  }
48
- export interface WorkflowConnectionPlanningSnapshot extends WorkflowConnectionMaterials {
49
+ export interface WorkflowConnectionPlanningSnapshot extends WorkflowConnectionMaterials, Pick<WorkflowPlanningContext, 'entrypoint'> {
49
50
  scenario: string;
50
51
  }
51
52
  export interface WorkflowConnectionPlanningDescription {
@@ -4,15 +4,20 @@ import type { BindingSchema, ApiBindingMaterial } from './api-bindings.js';
4
4
  import type { WorkflowMessageEvidence } from './planning-evidence.js';
5
5
  import type { WorkflowDecisionExplanation } from './workflow-clarification.js';
6
6
  import type { ValidateWorkflowDraftEditPlanInput } from './workflow-draft-edit.js';
7
- import type { WorkflowDraftEditResolution } from './workflow-draft-edit-assembly.js';
7
+ import type { WorkflowDraftEditResolution, WorkflowDraftEditRepair } from './workflow-draft-edit-assembly.js';
8
+ import type { ApiOperationContract } from './api-operation.js';
8
9
  import type { WorkflowDraftApiCall, WorkflowSourceMessage } from './workflow-draft.js';
9
10
  import type { JsonObject } from './openapi.js';
10
11
  import type { ApiInputLiteralSource } from './api-input-literal-source.js';
12
+ import type { workflowDraftApiInputEditAnswerSchema, workflowDraftApiInputEditAnswersSchema } from '../schemas/workflow-draft-api-input-edit-answers-schema.js';
11
13
  export interface WorkflowDraftApiInputEditMaterial extends ApiBindingMaterial {
12
14
  requestedInputs?: string[];
13
15
  }
14
16
  export interface WorkflowDraftApiInputEditInput extends ValidateWorkflowDraftEditPlanInput {
15
17
  stepId: string;
18
+ /** Explicit completed materials in this same plan. Omission means none. */
19
+ resolutions?: WorkflowDraftEditResolution[];
20
+ repairs?: WorkflowDraftEditRepair[];
16
21
  /** Omission preserves the call's explicit existing media selection. */
17
22
  requestMediaType?: string;
18
23
  }
@@ -34,9 +39,11 @@ export type WorkflowDraftApiInputEditTarget = Omit<ProposedWorkflowDraftApiInput
34
39
  kind: 'remove';
35
40
  });
36
41
  export interface WorkflowDraftApiInputEditDescription {
42
+ stageFingerprint: string;
37
43
  stepId: string;
38
44
  instruction: string;
39
45
  call: WorkflowDraftApiCall;
46
+ operation: ApiOperationContract;
40
47
  requestSchema: JsonObject;
41
48
  messages: WorkflowSourceMessage[];
42
49
  includeExplanations: boolean;
@@ -72,10 +79,16 @@ export type WorkflowDraftApiInputEditValue = ({
72
79
  export interface WorkflowDraftApiInputEditValues {
73
80
  values: Record<string, WorkflowDraftApiInputEditValue>;
74
81
  }
75
- export interface ResolveWorkflowDraftApiInputEditsInput extends WorkflowDraftApiInputEditContractInput {
82
+ export type WorkflowDraftApiInputEditAnswer = z.infer<typeof workflowDraftApiInputEditAnswerSchema>;
83
+ export type WorkflowDraftApiInputEditAnswers = z.infer<typeof workflowDraftApiInputEditAnswersSchema>;
84
+ export interface WorkflowDraftApiInputEditAnswerSchemaInput extends WorkflowDraftApiInputEditContractInput {
76
85
  output: WorkflowDraftApiInputEditValues;
77
86
  }
78
- export type WorkflowDraftApiInputEditResult = {
87
+ export interface ResolveWorkflowDraftApiInputEditsInput extends WorkflowDraftApiInputEditAnswerSchemaInput {
88
+ /** Explicit user answers to pending targets, separate from the unchanged model output. */
89
+ confirmedAnswers?: WorkflowDraftApiInputEditAnswers;
90
+ }
91
+ export type WorkflowDraftApiInputEditResult = ({
79
92
  status: 'ready';
80
93
  contractId: string;
81
94
  values: WorkflowDraftApiInputEditValues;
@@ -87,5 +100,9 @@ export type WorkflowDraftApiInputEditResult = {
87
100
  contractId: string;
88
101
  values: WorkflowDraftApiInputEditValues;
89
102
  pendingTargets: WorkflowDraftApiInputEditTarget[];
103
+ }) & {
104
+ /** Present only when the caller supplied an explicit typed reply. */
105
+ confirmedAnswers?: WorkflowDraftApiInputEditAnswers;
90
106
  };
91
107
  export type WorkflowDraftApiInputEditValuesSchema = z.ZodType<WorkflowDraftApiInputEditValues>;
108
+ export type WorkflowDraftApiInputEditAnswersSchema = z.ZodType<WorkflowDraftApiInputEditAnswers>;
@@ -8,9 +8,11 @@ import { createNativePlanningCapabilityMaterial } from '../planning/create-nativ
8
8
  import { prepareWorkflowConnectionMaterials } from './prepare-workflow-connection-materials.js';
9
9
  /** Capture declared data before awaiting the model; never clone opaque callbacks or forward audit metadata. */
10
10
  export function describeWorkflowConnectionPlanning(input) {
11
- const { scenario } = workflowConnectionIdentitySchema.parse({
11
+ const identity = workflowConnectionIdentitySchema.parse({
12
12
  scenario: input.scenario,
13
+ ...(input.entrypoint === undefined ? {} : { entrypoint: input.entrypoint }),
13
14
  });
15
+ const { scenario } = identity;
14
16
  for (const field of [
15
17
  'materials',
16
18
  'capabilities',
@@ -37,7 +39,7 @@ export function describeWorkflowConnectionPlanning(input) {
37
39
  edges: structuredClone((input.edges === undefined ? [] : input.edges).map((edge) => workflowDraftEdgeSchema.parse(edge))),
38
40
  });
39
41
  const context = {
40
- scenario,
42
+ ...structuredClone(identity),
41
43
  nodes: structuredClone(prepared.contracts),
42
44
  ...(prepared.nativeNodes.length
43
45
  ? {
@@ -71,7 +73,7 @@ export function describeWorkflowConnectionPlanning(input) {
71
73
  : { deferredApiInputs: structuredClone(prepared.deferredApiInputs) }),
72
74
  };
73
75
  return {
74
- input: { ...prepared, scenario },
76
+ input: { ...prepared, ...identity },
75
77
  context,
76
78
  sources: structuredClone({
77
79
  materials,
@@ -10,6 +10,7 @@ export function describeNativeNodePlanning(input) {
10
10
  planId: input.planId,
11
11
  scenario: input.scenario,
12
12
  allowRuntimeParameters: input.allowRuntimeParameters,
13
+ ...(input.entrypoint === undefined ? {} : { entrypoint: input.entrypoint }),
13
14
  });
14
15
  const { capabilities, apiMaterials, preparedNativeNodes: prepared, } = captureWorkflowPlanningMaterials(input);
15
16
  const apiIds = apiMaterials.map((material) => material.callId);
@@ -28,6 +29,9 @@ export function describeNativeNodePlanning(input) {
28
29
  planningCapabilities,
29
30
  context: {
30
31
  scenario: options.scenario,
32
+ ...(options.entrypoint === undefined
33
+ ? {}
34
+ : { entrypoint: structuredClone(options.entrypoint) }),
31
35
  apiMaterials: apiMaterials.map(({ callId, operation, purpose }) => ({
32
36
  callId,
33
37
  ...(purpose === undefined ? {} : { purpose }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openapi-flow/core",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "license": "MIT",
5
5
  "description": "Engine-independent OpenAPI catalogs, operation contracts and typed request schemas",
6
6
  "keywords": [