@openapi-flow/core 0.3.5 → 0.3.7
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/dist/openapi/selection/resolve-api-operation-choice-answer.d.ts +4 -0
- package/dist/openapi/selection/resolve-api-operation-choice-answer.js +38 -0
- package/dist/openapi/selection/resolve-api-selection-answers.js +2 -8
- package/dist/openapi/selection/validate-api-selection-question.d.ts +2 -0
- package/dist/openapi/selection/validate-api-selection-question.js +13 -0
- package/dist/public-api.d.ts +6 -0
- package/dist/public-api.js +5 -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/schemas/api-operation-answers-schema.d.ts +9 -2
- package/dist/schemas/api-operation-answers-schema.js +10 -4
- package/dist/schemas/api-operation-choice-bounds-schema.d.ts +5 -0
- package/dist/schemas/api-operation-choice-bounds-schema.js +9 -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-suggestions-record-schema.d.ts +6 -6
- package/dist/types/api-clarification.d.ts +16 -2
- 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/package.json +1 -1
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ResolveApiOperationChoiceAnswerInput } from '../../types/api-clarification.js';
|
|
2
|
+
import type { SelectedApiOperation } from '../../types/api-catalog.js';
|
|
3
|
+
/** Resolve only the explicitly declared choice mode; prose never determines cardinality. */
|
|
4
|
+
export declare function resolveApiOperationChoiceAnswer(input: ResolveApiOperationChoiceAnswerInput): SelectedApiOperation[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { apiOperationAnswersSchema } from '../../schemas/api-operation-answers-schema.js';
|
|
2
|
+
import { validateApiSelectionQuestion } from './validate-api-selection-question.js';
|
|
3
|
+
import { apiOperationKeyEquals } from '../catalog/api-operation-key-equals.js';
|
|
4
|
+
/** Resolve only the explicitly declared choice mode; prose never determines cardinality. */
|
|
5
|
+
export function resolveApiOperationChoiceAnswer(input) {
|
|
6
|
+
const { question } = input;
|
|
7
|
+
validateApiSelectionQuestion(question);
|
|
8
|
+
const answer = apiOperationAnswersSchema.element.parse(input.answer);
|
|
9
|
+
if (answer.questionId !== question.id)
|
|
10
|
+
throw new Error(`Operation answer questionId does not match ${question.id}`);
|
|
11
|
+
let keys;
|
|
12
|
+
if (question.kind === 'operation-choice') {
|
|
13
|
+
if (!('operation' in answer))
|
|
14
|
+
throw new Error(`Operation question ${question.id} requires one operation`);
|
|
15
|
+
keys = [answer.operation];
|
|
16
|
+
}
|
|
17
|
+
else if (question.kind === 'operation-multiple-choice') {
|
|
18
|
+
if (!('operations' in answer))
|
|
19
|
+
throw new Error(`Operation question ${question.id} requires an operations array`);
|
|
20
|
+
keys = answer.operations;
|
|
21
|
+
if (keys.length < question.minSelections ||
|
|
22
|
+
keys.length > question.maxSelections)
|
|
23
|
+
throw new Error(`Operation question ${question.id} requires ${question.minSelections}..${question.maxSelections} selections`);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
throw new Error('Operation question has no supported source-owned choice kind');
|
|
27
|
+
}
|
|
28
|
+
const seen = [];
|
|
29
|
+
return keys.map((key) => {
|
|
30
|
+
if (seen.some((previous) => apiOperationKeyEquals(previous, key)))
|
|
31
|
+
throw new Error(`Operation answer ${question.id} contains a duplicate selection`);
|
|
32
|
+
const candidate = question.candidates.find((item) => apiOperationKeyEquals(item.key, key));
|
|
33
|
+
if (!candidate)
|
|
34
|
+
throw new Error(`Operation answer ${question.id} does not match a current offered candidate`);
|
|
35
|
+
seen.push(key);
|
|
36
|
+
return { key: structuredClone(candidate.key), purpose: question.purpose };
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { apiOperationAnswersSchema } from '../../schemas/api-operation-answers-schema.js';
|
|
2
|
-
import {
|
|
2
|
+
import { resolveApiOperationChoiceAnswer } from './resolve-api-operation-choice-answer.js';
|
|
3
3
|
import { resolveApiOperations } from '../resolve-api-operations.js';
|
|
4
4
|
export async function resolveApiSelectionAnswers(input) {
|
|
5
5
|
const answers = apiOperationAnswersSchema.parse(input.answers);
|
|
@@ -13,13 +13,7 @@ export async function resolveApiSelectionAnswers(input) {
|
|
|
13
13
|
const question = input.analysis.questions.find((item) => item.id === answer.questionId);
|
|
14
14
|
if (!question || answered.has(answer.questionId))
|
|
15
15
|
throw new Error(`Unknown or duplicate operation question ${answer.questionId}`);
|
|
16
|
-
|
|
17
|
-
if (!candidate)
|
|
18
|
-
throw new Error(`Operation answer ${answer.questionId} does not match a current offered candidate`);
|
|
19
|
-
operations.push({
|
|
20
|
-
key: structuredClone(candidate.key),
|
|
21
|
-
purpose: question.purpose,
|
|
22
|
-
});
|
|
16
|
+
operations.push(...resolveApiOperationChoiceAnswer({ question, answer }));
|
|
23
17
|
answered.add(question.id);
|
|
24
18
|
}
|
|
25
19
|
return {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { apiOperationChoiceBoundsSchema } from '../../schemas/api-operation-choice-bounds-schema.js';
|
|
2
|
+
export function validateApiSelectionQuestion(question) {
|
|
3
|
+
if (question.kind === 'operation-choice')
|
|
4
|
+
return;
|
|
5
|
+
if (question.kind !== 'operation-multiple-choice')
|
|
6
|
+
throw new Error('Operation question has no supported source-owned choice kind');
|
|
7
|
+
const bounds = apiOperationChoiceBoundsSchema.parse({
|
|
8
|
+
minSelections: question.minSelections,
|
|
9
|
+
maxSelections: question.maxSelections,
|
|
10
|
+
});
|
|
11
|
+
if (bounds.maxSelections > question.candidates.length)
|
|
12
|
+
throw new Error(`Operation question ${question.id} maxSelections exceeds offered candidates`);
|
|
13
|
+
}
|
package/dist/public-api.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ export { inspectApiArgumentRequirements } from './arguments/clarification/inspec
|
|
|
39
39
|
export { validateApiInputAnswers } from './arguments/clarification/validate-api-input-answers.js';
|
|
40
40
|
export { createApiInputAnswersSchema } from './schemas/create-api-input-answers-schema.js';
|
|
41
41
|
export { resolveApiSelectionAnswers } from './openapi/selection/resolve-api-selection-answers.js';
|
|
42
|
+
export { resolveApiOperationChoiceAnswer } from './openapi/selection/resolve-api-operation-choice-answer.js';
|
|
43
|
+
export { validateApiSelectionQuestion } from './openapi/selection/validate-api-selection-question.js';
|
|
42
44
|
export type * from './types/deferred-api-inputs.js';
|
|
43
45
|
export { collectDeferredApiInputSlots } from './inputs/collect-deferred-api-input-slots.js';
|
|
44
46
|
export { createDeferredApiInputsSchema } from './schemas/create-deferred-api-inputs-schema.js';
|
|
@@ -249,6 +251,10 @@ export { createResponseValueSchema } from './openapi/response/create-response-va
|
|
|
249
251
|
export { listApiResponsePointers } from './openapi/response/list-api-response-pointers.js';
|
|
250
252
|
export type * from './types/api-response-pointers.js';
|
|
251
253
|
export type * from './types/workflow-review-suggestions.js';
|
|
254
|
+
export type * from './types/workflow-review-feedback.js';
|
|
255
|
+
export { workflowReviewFeedbackSchema, createWorkflowReviewFeedbackSchema, } from './schemas/workflow-review-feedback-schema.js';
|
|
256
|
+
export { createWorkflowReviewFeedback } from './review/feedback/create-workflow-review-feedback.js';
|
|
257
|
+
export { isWorkflowReviewFeedback } from './review/feedback/is-workflow-review-feedback.js';
|
|
252
258
|
export { describeWorkflowReviewSuggestions } from './review/suggestions/describe-workflow-review-suggestions.js';
|
|
253
259
|
export { createWorkflowReviewSuggestions } from './review/suggestions/create-workflow-review-suggestions.js';
|
|
254
260
|
export { createWorkflowReviewChoiceSuggestion } from './review/suggestions/create-workflow-review-choice-suggestion.js';
|
package/dist/public-api.js
CHANGED
|
@@ -29,6 +29,8 @@ export { inspectApiArgumentRequirements } from './arguments/clarification/inspec
|
|
|
29
29
|
export { validateApiInputAnswers } from './arguments/clarification/validate-api-input-answers.js';
|
|
30
30
|
export { createApiInputAnswersSchema } from './schemas/create-api-input-answers-schema.js';
|
|
31
31
|
export { resolveApiSelectionAnswers } from './openapi/selection/resolve-api-selection-answers.js';
|
|
32
|
+
export { resolveApiOperationChoiceAnswer } from './openapi/selection/resolve-api-operation-choice-answer.js';
|
|
33
|
+
export { validateApiSelectionQuestion } from './openapi/selection/validate-api-selection-question.js';
|
|
32
34
|
export { collectDeferredApiInputSlots } from './inputs/collect-deferred-api-input-slots.js';
|
|
33
35
|
export { createDeferredApiInputsSchema } from './schemas/create-deferred-api-inputs-schema.js';
|
|
34
36
|
export { inspectDeferredApiInputs } from './inputs/inspect-deferred-api-inputs.js';
|
|
@@ -187,6 +189,9 @@ export { createResponseArrayItemSchema } from './openapi/response/create-respons
|
|
|
187
189
|
export { createNativeArrayItemSchema } from './bindings/create-native-array-item-schema.js';
|
|
188
190
|
export { createResponseValueSchema } from './openapi/response/create-response-value-schema.js';
|
|
189
191
|
export { listApiResponsePointers } from './openapi/response/list-api-response-pointers.js';
|
|
192
|
+
export { workflowReviewFeedbackSchema, createWorkflowReviewFeedbackSchema, } from './schemas/workflow-review-feedback-schema.js';
|
|
193
|
+
export { createWorkflowReviewFeedback } from './review/feedback/create-workflow-review-feedback.js';
|
|
194
|
+
export { isWorkflowReviewFeedback } from './review/feedback/is-workflow-review-feedback.js';
|
|
190
195
|
export { describeWorkflowReviewSuggestions } from './review/suggestions/describe-workflow-review-suggestions.js';
|
|
191
196
|
export { createWorkflowReviewSuggestions } from './review/suggestions/create-workflow-review-suggestions.js';
|
|
192
197
|
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
|
-
|
|
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
|
+
}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
export declare const apiOperationAnswersSchema: z.ZodArray<z.ZodObject<{
|
|
2
|
+
export declare const apiOperationAnswersSchema: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
3
3
|
questionId: z.ZodString;
|
|
4
4
|
operation: z.ZodObject<{
|
|
5
5
|
documentId: z.ZodString;
|
|
6
6
|
snapshotId: z.ZodString;
|
|
7
7
|
operationRef: z.ZodString;
|
|
8
8
|
}, z.core.$strict>;
|
|
9
|
-
}, z.core.$strict
|
|
9
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
10
|
+
questionId: z.ZodString;
|
|
11
|
+
operations: z.ZodArray<z.ZodObject<{
|
|
12
|
+
documentId: z.ZodString;
|
|
13
|
+
snapshotId: z.ZodString;
|
|
14
|
+
operationRef: z.ZodString;
|
|
15
|
+
}, z.core.$strict>>;
|
|
16
|
+
}, z.core.$strict>]>>;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { apiOperationKeySchema } from './api-operation-key-schema.js';
|
|
3
3
|
export const apiOperationAnswersSchema = z
|
|
4
|
-
.array(z.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
.array(z.union([
|
|
5
|
+
z.strictObject({
|
|
6
|
+
questionId: z.string().min(1),
|
|
7
|
+
operation: apiOperationKeySchema,
|
|
8
|
+
}),
|
|
9
|
+
z.strictObject({
|
|
10
|
+
questionId: z.string().min(1),
|
|
11
|
+
operations: z.array(apiOperationKeySchema),
|
|
12
|
+
}),
|
|
13
|
+
]))
|
|
8
14
|
.min(1);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const apiOperationChoiceBoundsSchema = z
|
|
3
|
+
.strictObject({
|
|
4
|
+
minSelections: z.number().int().nonnegative().safe(),
|
|
5
|
+
maxSelections: z.number().int().nonnegative().safe(),
|
|
6
|
+
})
|
|
7
|
+
.refine((bounds) => bounds.minSelections <= bounds.maxSelections, {
|
|
8
|
+
message: 'minSelections must not exceed maxSelections',
|
|
9
|
+
});
|
|
@@ -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
|
+
}
|
|
@@ -5,6 +5,12 @@ export declare const workflowReviewSuggestionsRecordSchema: z.ZodObject<{
|
|
|
5
5
|
fingerprint: z.ZodString;
|
|
6
6
|
boundaryKey: z.ZodString;
|
|
7
7
|
target: z.ZodObject<{
|
|
8
|
+
kind: z.ZodEnum<{
|
|
9
|
+
"requirements-clarification": "requirements-clarification";
|
|
10
|
+
"selection-review": "selection-review";
|
|
11
|
+
"planning-questions": "planning-questions";
|
|
12
|
+
"candidate-review": "candidate-review";
|
|
13
|
+
}>;
|
|
8
14
|
questions: z.ZodArray<z.ZodObject<{
|
|
9
15
|
id: z.ZodString;
|
|
10
16
|
message: z.ZodString;
|
|
@@ -19,12 +25,6 @@ export declare const workflowReviewSuggestionsRecordSchema: z.ZodObject<{
|
|
|
19
25
|
}, z.core.$strict>>;
|
|
20
26
|
}, z.core.$strict>>;
|
|
21
27
|
}, z.core.$strict>>;
|
|
22
|
-
kind: z.ZodEnum<{
|
|
23
|
-
"requirements-clarification": "requirements-clarification";
|
|
24
|
-
"selection-review": "selection-review";
|
|
25
|
-
"planning-questions": "planning-questions";
|
|
26
|
-
"candidate-review": "candidate-review";
|
|
27
|
-
}>;
|
|
28
28
|
revision: z.ZodNumber;
|
|
29
29
|
data: z.ZodJSONSchema;
|
|
30
30
|
}, z.core.$strict>;
|
|
@@ -65,16 +65,30 @@ export interface ApiOperationChoice {
|
|
|
65
65
|
candidates: ApiOperationCandidate[];
|
|
66
66
|
explanation?: ApiSelectionExplanation;
|
|
67
67
|
}
|
|
68
|
+
export interface ApiOperationMultipleChoice extends Omit<ApiOperationChoice, 'kind'> {
|
|
69
|
+
kind: 'operation-multiple-choice';
|
|
70
|
+
minSelections: number;
|
|
71
|
+
maxSelections: number;
|
|
72
|
+
}
|
|
73
|
+
export type ApiSelectionQuestion = ApiOperationChoice | ApiOperationMultipleChoice;
|
|
68
74
|
export interface ApiSelectionAnalysis {
|
|
69
75
|
selection: ApiSelection;
|
|
70
|
-
questions:
|
|
76
|
+
questions: ApiSelectionQuestion[];
|
|
71
77
|
}
|
|
72
78
|
export interface ApiOperationAnswer {
|
|
73
79
|
questionId: string;
|
|
74
80
|
operation: ApiOperationKey;
|
|
75
81
|
}
|
|
82
|
+
export interface ApiOperationMultipleAnswer extends Omit<ApiOperationAnswer, 'operation'> {
|
|
83
|
+
operations: ApiOperationKey[];
|
|
84
|
+
}
|
|
85
|
+
export type ApiSelectionAnswer = ApiOperationAnswer | ApiOperationMultipleAnswer;
|
|
86
|
+
export interface ResolveApiOperationChoiceAnswerInput {
|
|
87
|
+
question: ApiSelectionQuestion;
|
|
88
|
+
answer: ApiSelectionAnswer;
|
|
89
|
+
}
|
|
76
90
|
export interface ResolveApiSelectionAnswersInput {
|
|
77
91
|
catalog: ApiCatalog;
|
|
78
92
|
analysis: ApiSelectionAnalysis;
|
|
79
|
-
answers:
|
|
93
|
+
answers: ApiSelectionAnswer[];
|
|
80
94
|
}
|
|
@@ -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 {};
|