@openapi-flow/core 0.3.5 → 0.3.6

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.
@@ -249,6 +249,10 @@ export { createResponseValueSchema } from './openapi/response/create-response-va
249
249
  export { listApiResponsePointers } from './openapi/response/list-api-response-pointers.js';
250
250
  export type * from './types/api-response-pointers.js';
251
251
  export type * from './types/workflow-review-suggestions.js';
252
+ export type * from './types/workflow-review-feedback.js';
253
+ export { workflowReviewFeedbackSchema, createWorkflowReviewFeedbackSchema, } from './schemas/workflow-review-feedback-schema.js';
254
+ export { createWorkflowReviewFeedback } from './review/feedback/create-workflow-review-feedback.js';
255
+ export { isWorkflowReviewFeedback } from './review/feedback/is-workflow-review-feedback.js';
252
256
  export { describeWorkflowReviewSuggestions } from './review/suggestions/describe-workflow-review-suggestions.js';
253
257
  export { createWorkflowReviewSuggestions } from './review/suggestions/create-workflow-review-suggestions.js';
254
258
  export { createWorkflowReviewChoiceSuggestion } from './review/suggestions/create-workflow-review-choice-suggestion.js';
@@ -187,6 +187,9 @@ export { createResponseArrayItemSchema } from './openapi/response/create-respons
187
187
  export { createNativeArrayItemSchema } from './bindings/create-native-array-item-schema.js';
188
188
  export { createResponseValueSchema } from './openapi/response/create-response-value-schema.js';
189
189
  export { listApiResponsePointers } from './openapi/response/list-api-response-pointers.js';
190
+ export { workflowReviewFeedbackSchema, createWorkflowReviewFeedbackSchema, } from './schemas/workflow-review-feedback-schema.js';
191
+ export { createWorkflowReviewFeedback } from './review/feedback/create-workflow-review-feedback.js';
192
+ export { isWorkflowReviewFeedback } from './review/feedback/is-workflow-review-feedback.js';
190
193
  export { describeWorkflowReviewSuggestions } from './review/suggestions/describe-workflow-review-suggestions.js';
191
194
  export { createWorkflowReviewSuggestions } from './review/suggestions/create-workflow-review-suggestions.js';
192
195
  export { createWorkflowReviewChoiceSuggestion } from './review/suggestions/create-workflow-review-choice-suggestion.js';
@@ -20,7 +20,8 @@ export function buildWorkflowClarificationResolution(input) {
20
20
  continue;
21
21
  if (reply.kind === 'defer')
22
22
  continue;
23
- if (reply.kind !== question.answer.kind)
23
+ // Offered controls constrain choice IDs, not an explicitly authored human text answer.
24
+ if (reply.kind !== 'text' && reply.kind !== question.answer.kind)
24
25
  throw new Error(`Clarification reply ${reply.questionId} must use ${question.answer.kind}`);
25
26
  let answerText;
26
27
  if (reply.kind === 'text')
@@ -0,0 +1,3 @@
1
+ import type { CreateWorkflowReviewFeedbackInput, WorkflowReviewFeedbackReceipt } from '../../types/workflow-review-feedback.js';
2
+ /** Validate explicit human intent and retain its source, without choosing or approving anything. */
3
+ export declare function createWorkflowReviewFeedback(input: CreateWorkflowReviewFeedbackInput): WorkflowReviewFeedbackReceipt;
@@ -0,0 +1,21 @@
1
+ import { createWorkflowReviewFeedbackSchema } from '../../schemas/workflow-review-feedback-schema.js';
2
+ import { planningEvidenceTextSchema } from '../../schemas/planning-evidence-schema.js';
3
+ /** Validate explicit human intent and retain its source, without choosing or approving anything. */
4
+ export function createWorkflowReviewFeedback(input) {
5
+ const feedback = createWorkflowReviewFeedbackSchema(input.boundary).parse(input.feedback);
6
+ const messageId = planningEvidenceTextSchema.parse(input.messageId);
7
+ const question = feedback.scope.kind === 'question'
8
+ ? input.boundary.questions.find((entry) => feedback.scope.kind === 'question' &&
9
+ entry.id === feedback.scope.questionId)
10
+ : undefined;
11
+ if (feedback.scope.kind === 'question' && question === undefined)
12
+ throw new Error(`Review feedback is missing original question ${feedback.scope.questionId}`);
13
+ return {
14
+ boundaryKey: feedback.boundaryKey,
15
+ boundaryKind: input.boundary.kind,
16
+ expectedRevision: feedback.expectedRevision,
17
+ scope: structuredClone(feedback.scope),
18
+ ...(question === undefined ? {} : { question: structuredClone(question) }),
19
+ message: { id: messageId, text: feedback.text },
20
+ };
21
+ }
@@ -0,0 +1,3 @@
1
+ import type { WorkflowReviewFeedback } from '../../types/workflow-review-feedback.js';
2
+ /** Structural dispatch only. Acceptance still requires the exact current boundary schema. */
3
+ export declare function isWorkflowReviewFeedback(value: unknown): value is WorkflowReviewFeedback;
@@ -0,0 +1,5 @@
1
+ import { workflowReviewFeedbackSchema } from '../../schemas/workflow-review-feedback-schema.js';
2
+ /** Structural dispatch only. Acceptance still requires the exact current boundary schema. */
3
+ export function isWorkflowReviewFeedback(value) {
4
+ return workflowReviewFeedbackSchema.safeParse(value).success;
5
+ }
@@ -0,0 +1,31 @@
1
+ import { z } from 'zod';
2
+ import type { WorkflowReviewBoundary } from '../types/workflow-review-suggestions.js';
3
+ export declare const workflowReviewFeedbackSchema: z.ZodObject<{
4
+ kind: z.ZodLiteral<"review-feedback">;
5
+ boundaryKey: z.ZodString;
6
+ expectedRevision: z.ZodNumber;
7
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
8
+ kind: z.ZodLiteral<"review">;
9
+ }, z.core.$strict>, z.ZodObject<{
10
+ kind: z.ZodLiteral<"question">;
11
+ questionId: z.ZodString;
12
+ }, z.core.$strict>], "kind">;
13
+ text: z.ZodString;
14
+ }, z.core.$strict>;
15
+ /** Derive exact review/question identities from the caller's current source-owned boundary. */
16
+ export declare function createWorkflowReviewFeedbackSchema(input: WorkflowReviewBoundary): z.ZodObject<{
17
+ kind: z.ZodLiteral<"review-feedback">;
18
+ text: z.ZodString;
19
+ boundaryKey: z.ZodLiteral<string>;
20
+ expectedRevision: z.ZodLiteral<number>;
21
+ scope: z.ZodObject<{
22
+ kind: z.ZodLiteral<"review">;
23
+ }, z.core.$strict> | z.ZodDiscriminatedUnion<[z.ZodObject<{
24
+ kind: z.ZodLiteral<"review">;
25
+ }, z.core.$strict>, z.ZodObject<{
26
+ kind: z.ZodLiteral<"question">;
27
+ questionId: z.ZodEnum<{
28
+ [x: string]: string;
29
+ }>;
30
+ }, z.core.$strict>], "kind">;
31
+ }, z.core.$strict>;
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ import { planningEvidenceTextSchema } from './planning-evidence-schema.js';
3
+ import { workflowReviewBoundarySchema } from './workflow-review-suggestion-settings-schema.js';
4
+ export const workflowReviewFeedbackSchema = z.strictObject({
5
+ kind: z.literal('review-feedback'),
6
+ boundaryKey: planningEvidenceTextSchema,
7
+ expectedRevision: z.number().int().nonnegative(),
8
+ scope: z.discriminatedUnion('kind', [
9
+ z.strictObject({ kind: z.literal('review') }),
10
+ z.strictObject({
11
+ kind: z.literal('question'),
12
+ questionId: planningEvidenceTextSchema,
13
+ }),
14
+ ]),
15
+ text: planningEvidenceTextSchema,
16
+ });
17
+ /** Derive exact review/question identities from the caller's current source-owned boundary. */
18
+ export function createWorkflowReviewFeedbackSchema(input) {
19
+ const boundary = workflowReviewBoundarySchema.parse(input);
20
+ const reviewScope = z.strictObject({ kind: z.literal('review') });
21
+ const scope = boundary.questions.length === 0
22
+ ? reviewScope
23
+ : z.discriminatedUnion('kind', [
24
+ reviewScope,
25
+ z.strictObject({
26
+ kind: z.literal('question'),
27
+ questionId: z.enum(boundary.questions.map((question) => question.id)),
28
+ }),
29
+ ]);
30
+ return workflowReviewFeedbackSchema.extend({
31
+ boundaryKey: z.literal(boundary.key),
32
+ expectedRevision: z.literal(boundary.revision),
33
+ scope,
34
+ });
35
+ }
@@ -103,7 +103,9 @@ export type WorkflowClarificationReply = {
103
103
  kind: 'multiple-choice';
104
104
  questionId: string;
105
105
  choiceIds: string[];
106
- } | {
106
+ }
107
+ /** Explicit human text may answer any question; it is never converted to a choice ID. */
108
+ | {
107
109
  kind: 'text';
108
110
  questionId: string;
109
111
  text: string;
@@ -0,0 +1,30 @@
1
+ import type { WorkflowReviewBoundary, WorkflowReviewQuestion } from './workflow-review-suggestions.js';
2
+ import type { WorkflowSourceMessage } from './workflow-draft.js';
3
+ export type WorkflowReviewFeedbackScope = {
4
+ kind: 'review';
5
+ } | {
6
+ kind: 'question';
7
+ questionId: WorkflowReviewQuestion['id'];
8
+ };
9
+ /** Human-authored feedback is never a choice, a literal API value, or an approval. */
10
+ export interface WorkflowReviewFeedback {
11
+ kind: 'review-feedback';
12
+ boundaryKey: WorkflowReviewBoundary['key'];
13
+ expectedRevision: WorkflowReviewBoundary['revision'];
14
+ scope: WorkflowReviewFeedbackScope;
15
+ text: string;
16
+ }
17
+ export interface CreateWorkflowReviewFeedbackInput {
18
+ boundary: WorkflowReviewBoundary;
19
+ feedback: WorkflowReviewFeedback;
20
+ messageId: WorkflowSourceMessage['id'];
21
+ }
22
+ /** The host decides which planning stage to revisit. This receipt applies no graph edit. */
23
+ export interface WorkflowReviewFeedbackReceipt {
24
+ boundaryKey: WorkflowReviewBoundary['key'];
25
+ boundaryKind: WorkflowReviewBoundary['kind'];
26
+ expectedRevision: WorkflowReviewBoundary['revision'];
27
+ scope: WorkflowReviewFeedbackScope;
28
+ question?: WorkflowReviewQuestion;
29
+ message: WorkflowSourceMessage;
30
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openapi-flow/core",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "license": "MIT",
5
5
  "description": "Engine-independent OpenAPI catalogs, operation contracts and typed request schemas",
6
6
  "keywords": [