@openapi-flow/core 0.3.4 → 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.
- package/README.md +1 -1
- package/dist/public-api.d.ts +7 -0
- package/dist/public-api.js +6 -0
- package/dist/requirements/clarification/build-workflow-clarification-resolution.js +2 -1
- package/dist/review/feedback/create-workflow-review-feedback.d.ts +3 -0
- package/dist/review/feedback/create-workflow-review-feedback.js +21 -0
- package/dist/review/feedback/is-workflow-review-feedback.d.ts +3 -0
- package/dist/review/feedback/is-workflow-review-feedback.js +5 -0
- package/dist/review/suggestions/adopt-workflow-review-suggestion.js +4 -0
- package/dist/review/suggestions/create-workflow-review-choice-suggestion.d.ts +3 -0
- package/dist/review/suggestions/create-workflow-review-choice-suggestion.js +39 -0
- package/dist/review/suggestions/create-workflow-review-suggestions.js +24 -0
- package/dist/schemas/create-workflow-review-suggestions-proposal-schema.js +4 -15
- package/dist/schemas/workflow-review-choice-suggestion-schema.d.ts +13 -0
- package/dist/schemas/workflow-review-choice-suggestion-schema.js +31 -0
- package/dist/schemas/workflow-review-feedback-schema.d.ts +31 -0
- package/dist/schemas/workflow-review-feedback-schema.js +35 -0
- package/dist/schemas/workflow-review-suggestion-fields-schema.d.ts +8 -0
- package/dist/schemas/workflow-review-suggestion-fields-schema.js +17 -0
- package/dist/schemas/workflow-review-suggestion-settings-schema.d.ts +24 -0
- package/dist/schemas/workflow-review-suggestion-settings-schema.js +17 -4
- package/dist/schemas/workflow-review-suggestions-record-schema.d.ts +10 -0
- package/dist/types/workflow-clarification.d.ts +3 -1
- package/dist/types/workflow-review-feedback.d.ts +30 -0
- package/dist/types/workflow-review-feedback.js +1 -0
- package/dist/types/workflow-review-suggestions.d.ts +23 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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.
|
|
5
|
+
Version **0.3.5**. Canonical draft, clarification and runtime-input APIs described below are included in this release source. Original-choice follow-ups now derive their display and typed reply in Core. 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.5.md) for publication and host status.
|
|
6
6
|
|
|
7
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.
|
|
8
8
|
|
package/dist/public-api.d.ts
CHANGED
|
@@ -249,10 +249,17 @@ 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';
|
|
258
|
+
export { createWorkflowReviewChoiceSuggestion } from './review/suggestions/create-workflow-review-choice-suggestion.js';
|
|
254
259
|
export { validateWorkflowReviewSuggestions } from './review/suggestions/validate-workflow-review-suggestions.js';
|
|
255
260
|
export { adoptWorkflowReviewSuggestion } from './review/suggestions/adopt-workflow-review-suggestion.js';
|
|
256
261
|
export { readWorkflowReviewSuggestionLimits } from './review/suggestions/read-workflow-review-suggestion-limits.js';
|
|
257
262
|
export { createWorkflowReviewSuggestionsProposalSchema } from './schemas/create-workflow-review-suggestions-proposal-schema.js';
|
|
263
|
+
export { createWorkflowReviewSuggestionFieldsSchema } from './schemas/workflow-review-suggestion-fields-schema.js';
|
|
264
|
+
export { createWorkflowReviewChoiceSuggestionSchema } from './schemas/workflow-review-choice-suggestion-schema.js';
|
|
258
265
|
export { workflowReviewSuggestionLimitsSchema, workflowReviewSuggestionOptionsSchema, } from './schemas/workflow-review-suggestion-settings-schema.js';
|
package/dist/public-api.js
CHANGED
|
@@ -187,10 +187,16 @@ 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';
|
|
195
|
+
export { createWorkflowReviewChoiceSuggestion } from './review/suggestions/create-workflow-review-choice-suggestion.js';
|
|
192
196
|
export { validateWorkflowReviewSuggestions } from './review/suggestions/validate-workflow-review-suggestions.js';
|
|
193
197
|
export { adoptWorkflowReviewSuggestion } from './review/suggestions/adopt-workflow-review-suggestion.js';
|
|
194
198
|
export { readWorkflowReviewSuggestionLimits } from './review/suggestions/read-workflow-review-suggestion-limits.js';
|
|
195
199
|
export { createWorkflowReviewSuggestionsProposalSchema } from './schemas/create-workflow-review-suggestions-proposal-schema.js';
|
|
200
|
+
export { createWorkflowReviewSuggestionFieldsSchema } from './schemas/workflow-review-suggestion-fields-schema.js';
|
|
201
|
+
export { createWorkflowReviewChoiceSuggestionSchema } from './schemas/workflow-review-choice-suggestion-schema.js';
|
|
196
202
|
export { workflowReviewSuggestionLimitsSchema, workflowReviewSuggestionOptionsSchema, } from './schemas/workflow-review-suggestion-settings-schema.js';
|
|
@@ -20,7 +20,8 @@ export function buildWorkflowClarificationResolution(input) {
|
|
|
20
20
|
continue;
|
|
21
21
|
if (reply.kind === 'defer')
|
|
22
22
|
continue;
|
|
23
|
-
|
|
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
|
+
}
|
|
@@ -28,6 +28,10 @@ export function adoptWorkflowReviewSuggestion(input) {
|
|
|
28
28
|
...(suggestion.kind === 'answer-question'
|
|
29
29
|
? { questionIds: suggestion.questionIds }
|
|
30
30
|
: {}),
|
|
31
|
+
...(suggestion.kind === 'answer-question' &&
|
|
32
|
+
suggestion.choiceReply !== undefined
|
|
33
|
+
? { choiceReply: suggestion.choiceReply }
|
|
34
|
+
: {}),
|
|
31
35
|
adoptedText: suggestion.text,
|
|
32
36
|
}),
|
|
33
37
|
},
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CreateWorkflowReviewChoiceSuggestionInput, ProposedWorkflowReviewSuggestion } from '../../types/workflow-review-suggestions.js';
|
|
2
|
+
/** Derive display and a typed reply from the same original contract. This does not submit or adopt the reply. */
|
|
3
|
+
export declare function createWorkflowReviewChoiceSuggestion(input: CreateWorkflowReviewChoiceSuggestionInput): ProposedWorkflowReviewSuggestion;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describeWorkflowReviewSuggestions } from './describe-workflow-review-suggestions.js';
|
|
2
|
+
import { createWorkflowReviewChoiceSuggestionSchema } from '../../schemas/workflow-review-choice-suggestion-schema.js';
|
|
3
|
+
/** Derive display and a typed reply from the same original contract. This does not submit or adopt the reply. */
|
|
4
|
+
export function createWorkflowReviewChoiceSuggestion(input) {
|
|
5
|
+
const description = describeWorkflowReviewSuggestions(input);
|
|
6
|
+
const question = description.boundary.questions.find((item) => item.id === input.proposal.questionId);
|
|
7
|
+
if (question === undefined || question.answer === undefined)
|
|
8
|
+
throw new Error('Review choice proposal references a missing current choice contract');
|
|
9
|
+
const answer = question.answer;
|
|
10
|
+
const proposal = createWorkflowReviewChoiceSuggestionSchema(question, description.options.includeExplanations).parse(input.proposal);
|
|
11
|
+
const labels = proposal.choiceIds.map((id) => {
|
|
12
|
+
const choice = answer.choices.find((item) => item.id === id);
|
|
13
|
+
if (choice === undefined)
|
|
14
|
+
throw new Error('Review choice proposal references an unknown original choice');
|
|
15
|
+
return choice.label;
|
|
16
|
+
});
|
|
17
|
+
let choiceReply;
|
|
18
|
+
if (answer.kind === 'single-choice') {
|
|
19
|
+
const choiceId = proposal.choiceIds[0];
|
|
20
|
+
if (choiceId === undefined)
|
|
21
|
+
throw new Error('Review single-choice proposal has no choiceId');
|
|
22
|
+
choiceReply = { kind: 'single-choice', questionId: question.id, choiceId };
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
choiceReply = {
|
|
26
|
+
kind: 'multiple-choice',
|
|
27
|
+
questionId: question.id,
|
|
28
|
+
choiceIds: [...proposal.choiceIds],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
kind: 'answer-question',
|
|
33
|
+
questionIds: [question.id],
|
|
34
|
+
text: `${question.message}\n선택: ${labels.join(', ')}`,
|
|
35
|
+
choiceReply,
|
|
36
|
+
sources: [{ kind: 'review-question', questionId: question.id }],
|
|
37
|
+
...(proposal.reason === undefined ? {} : { reason: proposal.reason }),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -4,12 +4,36 @@ import { describeWorkflowReviewSuggestions } from './describe-workflow-review-su
|
|
|
4
4
|
import { createWorkflowReviewSuggestionsProposalSchema } from '../../schemas/create-workflow-review-suggestions-proposal-schema.js';
|
|
5
5
|
import { workflowReviewSuggestionEvidenceSchema } from '../../schemas/workflow-review-suggestion-evidence-schema.js';
|
|
6
6
|
import { validateDescribedWorkflowPlanningEvidence } from '../../planning/evidence/validate-workflow-planning-evidence.js';
|
|
7
|
+
import { createWorkflowReviewChoiceSuggestion } from './create-workflow-review-choice-suggestion.js';
|
|
7
8
|
export function createWorkflowReviewSuggestions(input) {
|
|
8
9
|
const description = describeWorkflowReviewSuggestions(input);
|
|
9
10
|
const proposal = createWorkflowReviewSuggestionsProposalSchema(description, workflowReviewSuggestionEvidenceSchema).parse(input.proposal);
|
|
10
11
|
if (!isDeepStrictEqual(proposal, input.proposal))
|
|
11
12
|
throw new Error('Review suggestions must validate without defaults, coercion or transformation');
|
|
12
13
|
for (const suggestion of proposal.suggestions) {
|
|
14
|
+
if (suggestion.kind === 'answer-question') {
|
|
15
|
+
if (suggestion.choiceReply !== undefined) {
|
|
16
|
+
const reply = suggestion.choiceReply;
|
|
17
|
+
const expected = createWorkflowReviewChoiceSuggestion({
|
|
18
|
+
...input,
|
|
19
|
+
proposal: {
|
|
20
|
+
kind: 'answer-choice',
|
|
21
|
+
questionId: reply.questionId,
|
|
22
|
+
choiceIds: reply.kind === 'single-choice'
|
|
23
|
+
? [reply.choiceId]
|
|
24
|
+
: reply.choiceIds,
|
|
25
|
+
...(suggestion.reason === undefined
|
|
26
|
+
? {}
|
|
27
|
+
: { reason: suggestion.reason }),
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
if (!isDeepStrictEqual(suggestion, expected))
|
|
31
|
+
throw new Error('Typed review choice suggestion must keep its original derived text, reply and question sources');
|
|
32
|
+
}
|
|
33
|
+
else if (suggestion.questionIds.some((id) => description.boundary.questions.find((question) => question.id === id)?.answer !== undefined)) {
|
|
34
|
+
throw new Error('Choice-backed review questions require a typed choiceReply');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
13
37
|
const keys = suggestion.sources.map((source) => JSON.stringify(source));
|
|
14
38
|
if (new Set(keys).size !== keys.length)
|
|
15
39
|
throw new Error('Review suggestion evidence must not repeat identical sources');
|
|
@@ -1,25 +1,13 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { workflowReviewBoundarySchema, workflowReviewSuggestionLimitsSchema, workflowReviewSuggestionOptionsSchema, } from './workflow-review-suggestion-settings-schema.js';
|
|
3
|
+
import { createWorkflowReviewSuggestionFieldsSchema } from './workflow-review-suggestion-fields-schema.js';
|
|
4
|
+
import { workflowReviewChoiceReplySchema } from './workflow-review-choice-suggestion-schema.js';
|
|
3
5
|
/** Only user-facing proposed messages and actual source choices are model-owned. */
|
|
4
6
|
export function createWorkflowReviewSuggestionsProposalSchema(description, evidenceSchema) {
|
|
5
7
|
workflowReviewBoundarySchema.parse(description.boundary);
|
|
6
8
|
workflowReviewSuggestionLimitsSchema.parse(description.limits);
|
|
7
9
|
workflowReviewSuggestionOptionsSchema.parse(description.options);
|
|
8
|
-
const fields =
|
|
9
|
-
text: z
|
|
10
|
-
.string()
|
|
11
|
-
.refine((text) => text.trim().length > 0)
|
|
12
|
-
.describe("A concrete optional message in the user's language. Not a confirmed instruction, a workflow, a value default or a credential. Do not expose internal candidate IDs or bookkeeping references here; use structured sources. Do not present unapproved review assumptions as existing user intent."),
|
|
13
|
-
sources: z.array(evidenceSchema).min(1),
|
|
14
|
-
...(description.options.includeExplanations
|
|
15
|
-
? {
|
|
16
|
-
reason: z
|
|
17
|
-
.string()
|
|
18
|
-
.min(1)
|
|
19
|
-
.describe("Concise relevance in the user's language, not private chain-of-thought. Distinguish actual message evidence from unapproved review material; do not claim the user requested a candidate's assumptions. Keep internal candidate IDs and source bookkeeping in structured sources only."),
|
|
20
|
-
}
|
|
21
|
-
: {}),
|
|
22
|
-
};
|
|
10
|
+
const fields = createWorkflowReviewSuggestionFieldsSchema(description.options, evidenceSchema).shape;
|
|
23
11
|
const choices = [
|
|
24
12
|
z.strictObject({ kind: z.literal('change-request'), ...fields }),
|
|
25
13
|
];
|
|
@@ -32,6 +20,7 @@ export function createWorkflowReviewSuggestionsProposalSchema(description, evide
|
|
|
32
20
|
.array(z.enum(description.boundary.questions.map((question) => question.id)))
|
|
33
21
|
.min(1)
|
|
34
22
|
.refine((ids) => new Set(ids).size === ids.length),
|
|
23
|
+
choiceReply: workflowReviewChoiceReplySchema.optional(),
|
|
35
24
|
...fields,
|
|
36
25
|
}));
|
|
37
26
|
const suggestion = z.union(choices);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { WorkflowReviewQuestion, ProposedWorkflowReviewChoiceSuggestion } from '../types/workflow-review-suggestions.js';
|
|
3
|
+
export declare const workflowReviewChoiceReplySchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
4
|
+
kind: z.ZodLiteral<"single-choice">;
|
|
5
|
+
questionId: z.ZodString;
|
|
6
|
+
choiceId: z.ZodString;
|
|
7
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
8
|
+
kind: z.ZodLiteral<"multiple-choice">;
|
|
9
|
+
questionId: z.ZodString;
|
|
10
|
+
choiceIds: z.ZodArray<z.ZodString>;
|
|
11
|
+
}, z.core.$strict>]>;
|
|
12
|
+
/** One current question, bounded original choices; the model cannot generate its sentence or sources. */
|
|
13
|
+
export declare function createWorkflowReviewChoiceSuggestionSchema(question: WorkflowReviewQuestion, includeExplanations: boolean): z.ZodType<ProposedWorkflowReviewChoiceSuggestion>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { workflowClarificationReplySchema } from './workflow-clarification-reply-schema.js';
|
|
3
|
+
import { workflowReviewQuestionSchema } from './workflow-review-suggestion-settings-schema.js';
|
|
4
|
+
import { workflowReviewSuggestionReasonSchema } from './workflow-review-suggestion-fields-schema.js';
|
|
5
|
+
export const workflowReviewChoiceReplySchema = z.union([
|
|
6
|
+
workflowClarificationReplySchema.options[0],
|
|
7
|
+
workflowClarificationReplySchema.options[1],
|
|
8
|
+
]);
|
|
9
|
+
/** One current question, bounded original choices; the model cannot generate its sentence or sources. */
|
|
10
|
+
export function createWorkflowReviewChoiceSuggestionSchema(question, includeExplanations) {
|
|
11
|
+
const original = workflowReviewQuestionSchema.parse(question);
|
|
12
|
+
z.boolean().parse(includeExplanations);
|
|
13
|
+
if (original.answer === undefined)
|
|
14
|
+
throw new Error('Review choice suggestions require an original choice answer contract');
|
|
15
|
+
const ids = original.answer.choices.map((choice) => choice.id);
|
|
16
|
+
const base = z.strictObject({
|
|
17
|
+
kind: z.literal('answer-choice'),
|
|
18
|
+
questionId: z
|
|
19
|
+
.literal(original.id)
|
|
20
|
+
.describe('The exact supplied current question ID, not a new question.'),
|
|
21
|
+
choiceIds: z
|
|
22
|
+
.array(z.enum(ids))
|
|
23
|
+
.min(1)
|
|
24
|
+
.max(original.answer.kind === 'single-choice' ? 1 : ids.length)
|
|
25
|
+
.refine((choices) => new Set(choices).size === choices.length)
|
|
26
|
+
.describe('Select distinct IDs from this original question. Propose an optional answer; do not submit it, invent a choice, rewrite its label or infer an API binding.'),
|
|
27
|
+
});
|
|
28
|
+
return includeExplanations
|
|
29
|
+
? base.extend({ reason: workflowReviewSuggestionReasonSchema })
|
|
30
|
+
: base;
|
|
31
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ResolvedWorkflowReviewSuggestionOptions } from '../types/workflow-review-suggestions.js';
|
|
3
|
+
export declare const workflowReviewSuggestionReasonSchema: z.ZodString;
|
|
4
|
+
export declare function createWorkflowReviewSuggestionFieldsSchema<Evidence>(options: ResolvedWorkflowReviewSuggestionOptions, evidenceSchema: z.ZodType<Evidence>): z.ZodObject<{
|
|
5
|
+
reason?: z.ZodString | undefined;
|
|
6
|
+
text: z.ZodString;
|
|
7
|
+
sources: z.ZodArray<z.ZodType<Evidence, unknown, z.core.$ZodTypeInternals<Evidence, unknown>>>;
|
|
8
|
+
}, z.core.$strict>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const workflowReviewSuggestionReasonSchema = z
|
|
3
|
+
.string()
|
|
4
|
+
.min(1)
|
|
5
|
+
.describe("Concise relevance in the user's language, not private chain-of-thought. Distinguish actual message evidence from unapproved review material; do not claim the user requested a candidate's assumptions. Keep internal candidate IDs and source bookkeeping in structured sources only.");
|
|
6
|
+
export function createWorkflowReviewSuggestionFieldsSchema(options, evidenceSchema) {
|
|
7
|
+
return z.strictObject({
|
|
8
|
+
text: z
|
|
9
|
+
.string()
|
|
10
|
+
.refine((text) => text.trim().length > 0)
|
|
11
|
+
.describe("A concrete optional message in the user's language. Not a confirmed instruction, a workflow, a value default or a credential. Do not expose internal candidate IDs or bookkeeping references here; use structured sources. Do not present unapproved review assumptions as existing user intent."),
|
|
12
|
+
sources: z.array(evidenceSchema).min(1),
|
|
13
|
+
...(options.includeExplanations
|
|
14
|
+
? { reason: workflowReviewSuggestionReasonSchema }
|
|
15
|
+
: {}),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -6,6 +6,20 @@ export declare const workflowReviewSuggestionOptionsSchema: z.ZodObject<{
|
|
|
6
6
|
includeExplanations: z.ZodDefault<z.ZodBoolean>;
|
|
7
7
|
includeExtensions: z.ZodDefault<z.ZodBoolean>;
|
|
8
8
|
}, z.core.$strict>;
|
|
9
|
+
export declare const workflowReviewQuestionSchema: z.ZodObject<{
|
|
10
|
+
id: z.ZodString;
|
|
11
|
+
message: z.ZodString;
|
|
12
|
+
answer: z.ZodOptional<z.ZodObject<{
|
|
13
|
+
kind: z.ZodEnum<{
|
|
14
|
+
"single-choice": "single-choice";
|
|
15
|
+
"multiple-choice": "multiple-choice";
|
|
16
|
+
}>;
|
|
17
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
18
|
+
id: z.ZodString;
|
|
19
|
+
label: z.ZodString;
|
|
20
|
+
}, z.core.$strict>>;
|
|
21
|
+
}, z.core.$strict>>;
|
|
22
|
+
}, z.core.$strict>;
|
|
9
23
|
export declare const workflowReviewBoundarySchema: z.ZodObject<{
|
|
10
24
|
key: z.ZodString;
|
|
11
25
|
kind: z.ZodEnum<{
|
|
@@ -18,6 +32,16 @@ export declare const workflowReviewBoundarySchema: z.ZodObject<{
|
|
|
18
32
|
questions: z.ZodArray<z.ZodObject<{
|
|
19
33
|
id: z.ZodString;
|
|
20
34
|
message: z.ZodString;
|
|
35
|
+
answer: z.ZodOptional<z.ZodObject<{
|
|
36
|
+
kind: z.ZodEnum<{
|
|
37
|
+
"single-choice": "single-choice";
|
|
38
|
+
"multiple-choice": "multiple-choice";
|
|
39
|
+
}>;
|
|
40
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
41
|
+
id: z.ZodString;
|
|
42
|
+
label: z.ZodString;
|
|
43
|
+
}, z.core.$strict>>;
|
|
44
|
+
}, z.core.$strict>>;
|
|
21
45
|
}, z.core.$strict>>;
|
|
22
46
|
data: z.ZodJSONSchema;
|
|
23
47
|
}, z.core.$strict>;
|
|
@@ -6,6 +6,22 @@ export const workflowReviewSuggestionOptionsSchema = z.strictObject({
|
|
|
6
6
|
includeExplanations: z.boolean().default(true),
|
|
7
7
|
includeExtensions: z.boolean().default(true),
|
|
8
8
|
});
|
|
9
|
+
export const workflowReviewQuestionSchema = z.strictObject({
|
|
10
|
+
id: z.string().min(1),
|
|
11
|
+
message: z.string().refine((value) => value.trim().length > 0),
|
|
12
|
+
answer: z
|
|
13
|
+
.strictObject({
|
|
14
|
+
kind: z.enum(['single-choice', 'multiple-choice']),
|
|
15
|
+
choices: z
|
|
16
|
+
.array(z.strictObject({
|
|
17
|
+
id: z.string().min(1),
|
|
18
|
+
label: z.string().refine((value) => value.trim().length > 0),
|
|
19
|
+
}))
|
|
20
|
+
.min(1)
|
|
21
|
+
.refine((choices) => new Set(choices.map((choice) => choice.id)).size === choices.length),
|
|
22
|
+
})
|
|
23
|
+
.optional(),
|
|
24
|
+
});
|
|
9
25
|
export const workflowReviewBoundarySchema = z.strictObject({
|
|
10
26
|
key: z.string().refine((value) => value.trim().length > 0),
|
|
11
27
|
kind: z.enum([
|
|
@@ -16,10 +32,7 @@ export const workflowReviewBoundarySchema = z.strictObject({
|
|
|
16
32
|
]),
|
|
17
33
|
revision: z.number().int().nonnegative(),
|
|
18
34
|
questions: z
|
|
19
|
-
.array(
|
|
20
|
-
id: z.string().min(1),
|
|
21
|
-
message: z.string().refine((value) => value.trim().length > 0),
|
|
22
|
-
}))
|
|
35
|
+
.array(workflowReviewQuestionSchema)
|
|
23
36
|
.refine((questions) => new Set(questions.map((question) => question.id)).size ===
|
|
24
37
|
questions.length),
|
|
25
38
|
data: z.json(),
|
|
@@ -8,6 +8,16 @@ export declare const workflowReviewSuggestionsRecordSchema: z.ZodObject<{
|
|
|
8
8
|
questions: z.ZodArray<z.ZodObject<{
|
|
9
9
|
id: z.ZodString;
|
|
10
10
|
message: z.ZodString;
|
|
11
|
+
answer: z.ZodOptional<z.ZodObject<{
|
|
12
|
+
kind: z.ZodEnum<{
|
|
13
|
+
"single-choice": "single-choice";
|
|
14
|
+
"multiple-choice": "multiple-choice";
|
|
15
|
+
}>;
|
|
16
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
17
|
+
id: z.ZodString;
|
|
18
|
+
label: z.ZodString;
|
|
19
|
+
}, z.core.$strict>>;
|
|
20
|
+
}, z.core.$strict>>;
|
|
11
21
|
}, z.core.$strict>>;
|
|
12
22
|
kind: z.ZodEnum<{
|
|
13
23
|
"requirements-clarification": "requirements-clarification";
|
|
@@ -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 {};
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import type { JsonValue } from './api-arguments.js';
|
|
2
2
|
import type { WorkflowPlanningContext, WorkflowPlanningContextDescription, WorkflowPlanningEvidence } from './planning-evidence.js';
|
|
3
3
|
import type { WorkflowSourceMessage } from './workflow-draft.js';
|
|
4
|
+
import type { WorkflowClarificationAnswer, WorkflowClarificationChoice, WorkflowClarificationReply } from './workflow-clarification.js';
|
|
5
|
+
export type WorkflowReviewChoice = Pick<WorkflowClarificationChoice, 'id' | 'label'>;
|
|
6
|
+
export interface WorkflowReviewChoiceAnswer {
|
|
7
|
+
kind: Exclude<WorkflowClarificationAnswer['kind'], 'text'>;
|
|
8
|
+
choices: WorkflowReviewChoice[];
|
|
9
|
+
}
|
|
10
|
+
export type WorkflowReviewChoiceReply = Extract<WorkflowClarificationReply, {
|
|
11
|
+
kind: 'single-choice' | 'multiple-choice';
|
|
12
|
+
}>;
|
|
4
13
|
export interface WorkflowReviewQuestion {
|
|
5
14
|
id: string;
|
|
6
15
|
message: string;
|
|
16
|
+
/** Exact original choices supplied by the host. Omission does not infer a choice contract. */
|
|
17
|
+
answer?: WorkflowReviewChoiceAnswer;
|
|
7
18
|
}
|
|
8
19
|
/** The host owns this read-only review projection, not an executable plan or a new OAS contract. */
|
|
9
20
|
export interface WorkflowReviewBoundary {
|
|
@@ -37,6 +48,8 @@ export type ProposedWorkflowReviewSuggestion<Evidence = WorkflowReviewSuggestion
|
|
|
37
48
|
} & ({
|
|
38
49
|
kind: 'answer-question';
|
|
39
50
|
questionIds: string[];
|
|
51
|
+
/** Code-validated original choice, never inferred by parsing the display text. */
|
|
52
|
+
choiceReply?: WorkflowReviewChoiceReply;
|
|
40
53
|
} | {
|
|
41
54
|
kind: 'change-request' | 'extend-workflow';
|
|
42
55
|
});
|
|
@@ -72,6 +85,16 @@ export interface WorkflowReviewSuggestions {
|
|
|
72
85
|
export interface CreateWorkflowReviewSuggestionsInput extends WorkflowReviewSuggestionsInput {
|
|
73
86
|
proposal: WorkflowReviewSuggestionsProposal;
|
|
74
87
|
}
|
|
88
|
+
/** A wire proposal chooses declared identities, not the derived sentence, sources or human receipt. */
|
|
89
|
+
export interface ProposedWorkflowReviewChoiceSuggestion {
|
|
90
|
+
kind: 'answer-choice';
|
|
91
|
+
questionId: string;
|
|
92
|
+
choiceIds: string[];
|
|
93
|
+
reason?: string;
|
|
94
|
+
}
|
|
95
|
+
export interface CreateWorkflowReviewChoiceSuggestionInput extends WorkflowReviewSuggestionsInput {
|
|
96
|
+
proposal: ProposedWorkflowReviewChoiceSuggestion;
|
|
97
|
+
}
|
|
75
98
|
export interface WorkflowReviewSuggestionsValidationInput extends WorkflowReviewSuggestionsInput {
|
|
76
99
|
review: WorkflowReviewSuggestions;
|
|
77
100
|
}
|