@openapi-flow/langchain 0.3.18 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +21 -0
  2. package/dist/arguments/analyze-api-input-answers.js +34 -6
  3. package/dist/arguments/api-argument-planning-error.d.ts +11 -0
  4. package/dist/arguments/api-argument-planning-error.js +32 -0
  5. package/dist/arguments/assert-api-argument-generation-source.d.ts +4 -0
  6. package/dist/arguments/assert-api-argument-generation-source.js +16 -0
  7. package/dist/arguments/attribute-api-literal-generation-sources.d.ts +4 -0
  8. package/dist/arguments/attribute-api-literal-generation-sources.js +16 -0
  9. package/dist/arguments/create-api-argument-rejection.d.ts +3 -0
  10. package/dist/arguments/create-api-argument-rejection.js +38 -0
  11. package/dist/arguments/fingerprint-api-argument-source.d.ts +4 -0
  12. package/dist/arguments/fingerprint-api-argument-source.js +13 -0
  13. package/dist/arguments/generate-api-arguments.js +108 -40
  14. package/dist/arguments/interpret-api-argument-enums.js +1 -0
  15. package/dist/arguments/resolve-api-literal-generation-output.d.ts +3 -0
  16. package/dist/arguments/resolve-api-literal-generation-output.js +14 -0
  17. package/dist/bindings/plan-api-bindings-by-call.js +12 -3
  18. package/dist/bindings/plan-api-call-bindings.js +30 -9
  19. package/dist/bindings/select-api-binding-sources.js +32 -8
  20. package/dist/model/invoke-structured-model.js +32 -6
  21. package/dist/prompts/api-arguments-prompt.d.ts +2 -1
  22. package/dist/prompts/api-arguments-prompt.js +11 -1
  23. package/dist/prompts/api-input-answers-prompt.d.ts +1 -1
  24. package/dist/prompts/api-input-answers-prompt.js +8 -7
  25. package/dist/prompts/api-material-repair-prompt.d.ts +1 -0
  26. package/dist/prompts/api-material-repair-prompt.js +1 -0
  27. package/dist/prompts/incremental-workflow-connections-prompt.d.ts +2 -2
  28. package/dist/prompts/incremental-workflow-connections-prompt.js +5 -4
  29. package/dist/prompts/native-instance-selection-review-prompt.d.ts +1 -0
  30. package/dist/prompts/native-instance-selection-review-prompt.js +9 -0
  31. package/dist/prompts/native-node-planning-prompt.d.ts +1 -1
  32. package/dist/prompts/native-node-planning-prompt.js +2 -0
  33. package/dist/prompts/workflow-connection-goal-recovery-prompt.d.ts +1 -0
  34. package/dist/prompts/workflow-connection-goal-recovery-prompt.js +8 -0
  35. package/dist/prompts/workflow-connection-goal-review-prompt.d.ts +1 -0
  36. package/dist/prompts/workflow-connection-goal-review-prompt.js +7 -0
  37. package/dist/prompts/workflow-connection-native-repair-prompt.d.ts +1 -0
  38. package/dist/prompts/workflow-connection-native-repair-prompt.js +1 -0
  39. package/dist/prompts/workflow-connection-outline-prompt.d.ts +1 -0
  40. package/dist/prompts/workflow-connection-outline-prompt.js +6 -0
  41. package/dist/prompts/workflow-connection-revision-prompt.d.ts +1 -0
  42. package/dist/prompts/workflow-connection-revision-prompt.js +10 -0
  43. package/dist/public-api.d.ts +28 -0
  44. package/dist/public-api.js +21 -0
  45. package/dist/schemas/api-argument-rejection-schema.d.ts +28 -0
  46. package/dist/schemas/api-argument-rejection-schema.js +20 -0
  47. package/dist/schemas/api-input-answer-source-schema.d.ts +5 -5
  48. package/dist/schemas/api-input-answer-source-schema.js +14 -6
  49. package/dist/schemas/api-literal-generation-output-schema.d.ts +35 -4
  50. package/dist/schemas/api-literal-generation-output-schema.js +49 -14
  51. package/dist/schemas/create-connection-material-repair-choice-schema.d.ts +4 -0
  52. package/dist/schemas/create-connection-material-repair-choice-schema.js +23 -0
  53. package/dist/schemas/model-signal-schema.d.ts +3 -0
  54. package/dist/schemas/model-signal-schema.js +3 -0
  55. package/dist/schemas/native-node-parameter-contract.js +2 -0
  56. package/dist/schemas/native-node-planning-contract.js +30 -23
  57. package/dist/schemas/native-planning-rejection-schema.d.ts +11 -0
  58. package/dist/schemas/native-planning-rejection-schema.js +8 -0
  59. package/dist/schemas/workflow-connection-goal-recovery-schema.d.ts +4 -0
  60. package/dist/schemas/workflow-connection-goal-recovery-schema.js +16 -0
  61. package/dist/schemas/workflow-connection-goal-rejection-schema.d.ts +76 -0
  62. package/dist/schemas/workflow-connection-goal-rejection-schema.js +2 -1
  63. package/dist/schemas/workflow-connection-goal-review-schema.d.ts +4 -0
  64. package/dist/schemas/workflow-connection-goal-review-schema.js +26 -0
  65. package/dist/schemas/workflow-connection-goals-schema.d.ts +4 -2
  66. package/dist/schemas/workflow-connection-outline-rejection-schema.d.ts +25 -0
  67. package/dist/schemas/workflow-connection-outline-rejection-schema.js +21 -0
  68. package/dist/schemas/workflow-connection-outline-schema.d.ts +3 -0
  69. package/dist/schemas/workflow-connection-outline-schema.js +25 -0
  70. package/dist/schemas/workflow-connection-revision-rejection-schema.d.ts +113 -0
  71. package/dist/schemas/workflow-connection-revision-rejection-schema.js +23 -0
  72. package/dist/schemas/workflow-connection-revision-schema.d.ts +4 -0
  73. package/dist/schemas/workflow-connection-revision-schema.js +23 -0
  74. package/dist/schemas/workflow-connection-step-schema.d.ts +5 -3
  75. package/dist/schemas/workflow-connection-step-schema.js +62 -31
  76. package/dist/types/api-call-binding-planning.d.ts +2 -1
  77. package/dist/types/api-input-answers.d.ts +3 -6
  78. package/dist/types/argument-generation.d.ts +37 -12
  79. package/dist/types/incremental-connection-planning.d.ts +10 -3
  80. package/dist/types/native-instance-selection-review.d.ts +12 -0
  81. package/dist/types/native-instance-selection-review.js +1 -0
  82. package/dist/types/native-node-planning.d.ts +10 -2
  83. package/dist/types/native-planning-rejection.d.ts +21 -0
  84. package/dist/types/native-planning-rejection.js +1 -0
  85. package/dist/types/workflow-connection-goal-recovery.d.ts +22 -0
  86. package/dist/types/workflow-connection-goal-recovery.js +1 -0
  87. package/dist/types/workflow-connection-goal-review.d.ts +13 -0
  88. package/dist/types/workflow-connection-goal-review.js +1 -0
  89. package/dist/types/workflow-connection-native-repair.d.ts +16 -0
  90. package/dist/types/workflow-connection-native-repair.js +1 -0
  91. package/dist/types/workflow-connection-outline.d.ts +22 -0
  92. package/dist/types/workflow-connection-outline.js +1 -0
  93. package/dist/types/workflow-connection-revision.d.ts +34 -0
  94. package/dist/types/workflow-connection-revision.js +1 -0
  95. package/dist/workflow/connections/create-workflow-connection-goal-rejection.js +8 -2
  96. package/dist/workflow/connections/create-workflow-connection-outline-rejection.d.ts +3 -0
  97. package/dist/workflow/connections/create-workflow-connection-outline-rejection.js +28 -0
  98. package/dist/workflow/connections/create-workflow-connection-revision-rejection.d.ts +3 -0
  99. package/dist/workflow/connections/create-workflow-connection-revision-rejection.js +32 -0
  100. package/dist/workflow/connections/describe-workflow-connection-outline-request.d.ts +3 -0
  101. package/dist/workflow/connections/describe-workflow-connection-outline-request.js +30 -0
  102. package/dist/workflow/connections/generate-workflow-connection-native-parameters.d.ts +4 -0
  103. package/dist/workflow/connections/generate-workflow-connection-native-parameters.js +80 -0
  104. package/dist/workflow/connections/invoke-connection-planning-model.js +3 -0
  105. package/dist/workflow/connections/plan-workflow-connection-goal-recovery.d.ts +3 -0
  106. package/dist/workflow/connections/plan-workflow-connection-goal-recovery.js +111 -0
  107. package/dist/workflow/connections/plan-workflow-connection-goals.js +35 -16
  108. package/dist/workflow/connections/plan-workflow-connection-native-dependencies.d.ts +4 -0
  109. package/dist/workflow/connections/plan-workflow-connection-native-dependencies.js +73 -0
  110. package/dist/workflow/connections/plan-workflow-connection-outline.d.ts +4 -0
  111. package/dist/workflow/connections/plan-workflow-connection-outline.js +93 -0
  112. package/dist/workflow/connections/plan-workflow-connection-revision.d.ts +3 -0
  113. package/dist/workflow/connections/plan-workflow-connection-revision.js +163 -0
  114. package/dist/workflow/connections/plan-workflow-connection-step.js +75 -29
  115. package/dist/workflow/connections/resolve-connection-selections.d.ts +6 -0
  116. package/dist/workflow/connections/resolve-connection-selections.js +28 -0
  117. package/dist/workflow/connections/review-workflow-connection-goals.d.ts +4 -0
  118. package/dist/workflow/connections/review-workflow-connection-goals.js +64 -0
  119. package/dist/workflow/connections/validate-workflow-goal-review-feedback.d.ts +4 -0
  120. package/dist/workflow/connections/validate-workflow-goal-review-feedback.js +22 -0
  121. package/dist/workflow/connections/workflow-connection-native-repair-error.d.ts +6 -0
  122. package/dist/workflow/connections/workflow-connection-native-repair-error.js +18 -0
  123. package/dist/workflow/connections/workflow-connection-planning-error.d.ts +1 -0
  124. package/dist/workflow/connections/workflow-connection-planning-error.js +2 -0
  125. package/dist/workflow/native-selection/create-native-planning-rejection.d.ts +4 -0
  126. package/dist/workflow/native-selection/create-native-planning-rejection.js +45 -0
  127. package/dist/workflow/native-selection/describe-native-planning-request.d.ts +5 -0
  128. package/dist/workflow/native-selection/describe-native-planning-request.js +26 -0
  129. package/dist/workflow/native-selection/native-instance-selection-review-error.d.ts +6 -0
  130. package/dist/workflow/native-selection/native-instance-selection-review-error.js +18 -0
  131. package/dist/workflow/native-selection/review-native-instance-selection.d.ts +4 -0
  132. package/dist/workflow/native-selection/review-native-instance-selection.js +97 -0
  133. package/dist/workflow/native-selection/validate-native-planning-rejections.d.ts +2 -0
  134. package/dist/workflow/native-selection/validate-native-planning-rejections.js +14 -0
  135. package/dist/workflow/resolve-native-node-planning-output.js +3 -1
  136. package/dist/workflow/select-native-node-instances.js +44 -17
  137. package/package.json +2 -2
@@ -0,0 +1,45 @@
1
+ import { isDeepStrictEqual } from 'node:util';
2
+ import { nativePlanningRejectionSchema } from '../../schemas/native-planning-rejection-schema.js';
3
+ import { NativeNodePlanningError } from '../native-node-planning-error.js';
4
+ import { NativeInstanceSelectionReviewError } from './native-instance-selection-review-error.js';
5
+ import { describeNativeSelectionRequest, fingerprintNativeSelectionReviewRequest, } from './describe-native-planning-request.js';
6
+ /** Only unchanged, source-bound output failures are eligible; transport/configuration failures are not proposals. */
7
+ export function createNativeSelectionRejection(input) {
8
+ const error = input.error;
9
+ if (!(error instanceof NativeNodePlanningError) ||
10
+ error.failure.stage !== 'instance-selection' ||
11
+ error.failure.requestFingerprint === undefined)
12
+ return undefined;
13
+ const current = describeNativeSelectionRequest(input);
14
+ if (current.requestFingerprint !== error.failure.requestFingerprint)
15
+ return undefined;
16
+ const parsed = nativePlanningRejectionSchema.safeParse({
17
+ stage: 'instance-selection',
18
+ requestFingerprint: current.requestFingerprint,
19
+ output: error.failure.output,
20
+ reason: error.message,
21
+ });
22
+ if (!parsed.success ||
23
+ !isDeepStrictEqual(parsed.data.output, error.failure.output))
24
+ return undefined;
25
+ return structuredClone(parsed.data);
26
+ }
27
+ export function createNativeSelectionReviewRejection(input) {
28
+ const error = input.error;
29
+ if (!(error instanceof NativeInstanceSelectionReviewError) ||
30
+ error.failure.requestFingerprint === undefined)
31
+ return undefined;
32
+ const requestFingerprint = fingerprintNativeSelectionReviewRequest(input);
33
+ if (requestFingerprint !== error.failure.requestFingerprint)
34
+ return undefined;
35
+ const parsed = nativePlanningRejectionSchema.safeParse({
36
+ stage: 'selection-review',
37
+ requestFingerprint,
38
+ output: error.failure.output,
39
+ reason: error.message,
40
+ });
41
+ if (!parsed.success ||
42
+ !isDeepStrictEqual(parsed.data.output, error.failure.output))
43
+ return undefined;
44
+ return structuredClone(parsed.data);
45
+ }
@@ -0,0 +1,5 @@
1
+ import type { SelectNativeNodeInstancesInput } from '../../types/native-node-planning.js';
2
+ import type { ReviewNativeInstanceSelectionInput } from '../../types/native-instance-selection-review.js';
3
+ import type { NativeSelectionRequestDescription } from '../../types/native-planning-rejection.js';
4
+ export declare function describeNativeSelectionRequest(input: SelectNativeNodeInstancesInput): NativeSelectionRequestDescription;
5
+ export declare function fingerprintNativeSelectionReviewRequest(input: ReviewNativeInstanceSelectionInput): string;
@@ -0,0 +1,26 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { describeNativeInstanceSelection, describeNativeInstanceSelectionFeedback, describeNativeInstanceSelectionReview, } from '@openapi-flow/core';
3
+ export function describeNativeSelectionRequest(input) {
4
+ const { context } = describeNativeInstanceSelection(input);
5
+ const feedback = input.feedback === undefined
6
+ ? undefined
7
+ : describeNativeInstanceSelectionFeedback(input, input.feedback);
8
+ return {
9
+ context,
10
+ ...(feedback === undefined ? {} : { feedback }),
11
+ requestFingerprint: createHash('sha256')
12
+ .update(JSON.stringify([
13
+ input.planId,
14
+ input.allowRuntimeParameters,
15
+ input.includeExplanations,
16
+ context,
17
+ feedback,
18
+ ]))
19
+ .digest('hex'),
20
+ };
21
+ }
22
+ export function fingerprintNativeSelectionReviewRequest(input) {
23
+ return createHash('sha256')
24
+ .update(JSON.stringify(describeNativeInstanceSelectionReview(input)))
25
+ .digest('hex');
26
+ }
@@ -0,0 +1,6 @@
1
+ import { OpenApiFlowError } from '@openapi-flow/core';
2
+ import type { NativeInstanceSelectionReviewFailure } from '../../types/native-instance-selection-review.js';
3
+ export declare class NativeInstanceSelectionReviewError extends OpenApiFlowError {
4
+ readonly failure: NativeInstanceSelectionReviewFailure;
5
+ constructor(failure: NativeInstanceSelectionReviewFailure, cause: Error);
6
+ }
@@ -0,0 +1,18 @@
1
+ import { OpenApiFlowError } from '@openapi-flow/core';
2
+ export class NativeInstanceSelectionReviewError extends OpenApiFlowError {
3
+ failure;
4
+ constructor(failure, cause) {
5
+ super({
6
+ message: `Native selection review failed: ${cause.message}`,
7
+ diagnostic: {
8
+ owner: 'langchain',
9
+ operation: 'reviewNativeInstanceSelection',
10
+ stage: 'model-output',
11
+ code: 'MODEL_OUTPUT_INVALID',
12
+ },
13
+ cause,
14
+ });
15
+ this.name = 'NativeInstanceSelectionReviewError';
16
+ this.failure = failure;
17
+ }
18
+ }
@@ -0,0 +1,4 @@
1
+ import type { NativeInstanceSelectionReview } from '@openapi-flow/core';
2
+ import type { ReviewNativeInstanceSelectionInput } from '../../types/native-instance-selection-review.js';
3
+ /** One review call only. The host owns replanning, user questions, budgets and persistence. */
4
+ export declare function reviewNativeInstanceSelection(input: ReviewNativeInstanceSelectionInput): Promise<NativeInstanceSelectionReview>;
@@ -0,0 +1,97 @@
1
+ import { isDeepStrictEqual } from 'node:util';
2
+ import { HumanMessage, SystemMessage } from '@langchain/core/messages';
3
+ import { describeNativeInstanceSelectionReview, createNativeInstanceSelectionReview, createNativeInstanceSelectionReviewSchema, runOpenApiFlowOperation, } from '@openapi-flow/core';
4
+ import { invokeStructuredModel } from '../../model/invoke-structured-model.js';
5
+ import { serializeStructuredOutputSchema } from '../../schemas/serialize-structured-output-schema.js';
6
+ import { modelSignalSchema } from '../../schemas/model-signal-schema.js';
7
+ import { nativeInstanceSelectionReviewPrompt } from '../../prompts/native-instance-selection-review-prompt.js';
8
+ import { NativeInstanceSelectionReviewError } from './native-instance-selection-review-error.js';
9
+ import { fingerprintNativeSelectionReviewRequest } from './describe-native-planning-request.js';
10
+ import { validateNativePlanningRejections } from './validate-native-planning-rejections.js';
11
+ /** One review call only. The host owns replanning, user questions, budgets and persistence. */
12
+ export async function reviewNativeInstanceSelection(input) {
13
+ const operation = 'reviewNativeInstanceSelection';
14
+ const description = runOpenApiFlowOperation({
15
+ owner: 'langchain',
16
+ operation,
17
+ stage: 'input-validation',
18
+ code: 'PLANNING_INPUT_INVALID',
19
+ }, () => {
20
+ modelSignalSchema.parse(input.signal);
21
+ return describeNativeInstanceSelectionReview(input);
22
+ });
23
+ input.signal?.throwIfAborted();
24
+ const requestFingerprint = fingerprintNativeSelectionReviewRequest(input);
25
+ const rejectedProposals = validateNativePlanningRejections({
26
+ stage: 'selection-review',
27
+ requestFingerprint,
28
+ rejectedProposals: input.rejectedProposals,
29
+ });
30
+ if (!description.gaps.length)
31
+ return createNativeInstanceSelectionReview({
32
+ ...input,
33
+ proposal: { assessments: {} },
34
+ });
35
+ const model = runOpenApiFlowOperation({
36
+ owner: 'langchain',
37
+ operation,
38
+ stage: 'model-configuration',
39
+ code: 'MODEL_CONFIGURATION_FAILED',
40
+ }, () => {
41
+ if (!input.model ||
42
+ typeof input.model.withStructuredOutput !== 'function')
43
+ throw new Error('reviewNativeInstanceSelection.model must support structured output for reported gaps');
44
+ return input.model;
45
+ });
46
+ const checkCurrent = (originalFailure) => {
47
+ runOpenApiFlowOperation({
48
+ owner: 'langchain',
49
+ operation,
50
+ stage: 'input-validation',
51
+ code: 'PLANNING_INPUT_INVALID',
52
+ }, () => {
53
+ try {
54
+ if (!isDeepStrictEqual(description, describeNativeInstanceSelectionReview(input)) ||
55
+ !isDeepStrictEqual(rejectedProposals, validateNativePlanningRejections({
56
+ stage: 'selection-review',
57
+ requestFingerprint,
58
+ rejectedProposals: input.rejectedProposals,
59
+ })))
60
+ throw new Error('Native selection review source changed during model invocation');
61
+ }
62
+ catch (error) {
63
+ if (originalFailure !== undefined)
64
+ throw new AggregateError([originalFailure, error], 'Native review input changed while a failed model call was received', { cause: error });
65
+ throw error;
66
+ }
67
+ });
68
+ };
69
+ const output = await invokeStructuredModel({
70
+ operation,
71
+ model,
72
+ schema: serializeStructuredOutputSchema(createNativeInstanceSelectionReviewSchema(description), 'draft-2020-12'),
73
+ name: 'review_native_instance_selection',
74
+ method: 'jsonSchema',
75
+ strict: true,
76
+ messages: [
77
+ new SystemMessage(nativeInstanceSelectionReviewPrompt),
78
+ new HumanMessage(JSON.stringify({
79
+ ...description,
80
+ ...(rejectedProposals.length === 0 ? {} : { rejectedProposals }),
81
+ })),
82
+ ],
83
+ ...(input.signal === undefined ? {} : { signal: input.signal }),
84
+ }).catch((error) => {
85
+ checkCurrent(error);
86
+ throw error;
87
+ });
88
+ checkCurrent();
89
+ try {
90
+ return createNativeInstanceSelectionReview({ ...input, proposal: output });
91
+ }
92
+ catch (cause) {
93
+ if (!(cause instanceof Error))
94
+ throw cause;
95
+ throw new NativeInstanceSelectionReviewError({ output, requestFingerprint }, cause);
96
+ }
97
+ }
@@ -0,0 +1,2 @@
1
+ import type { NativePlanningRejectedProposal, NativePlanningRejectionValidationInput } from '../../types/native-planning-rejection.js';
2
+ export declare function validateNativePlanningRejections(input: NativePlanningRejectionValidationInput): NativePlanningRejectedProposal[];
@@ -0,0 +1,14 @@
1
+ import { isDeepStrictEqual } from 'node:util';
2
+ import { nativePlanningRejectionSchema } from '../../schemas/native-planning-rejection-schema.js';
3
+ export function validateNativePlanningRejections(input) {
4
+ if (input.rejectedProposals === undefined)
5
+ return [];
6
+ const parsed = nativePlanningRejectionSchema
7
+ .array()
8
+ .parse(input.rejectedProposals);
9
+ if (!isDeepStrictEqual(parsed, input.rejectedProposals) ||
10
+ parsed.some((entry) => entry.stage !== input.stage ||
11
+ entry.requestFingerprint !== input.requestFingerprint))
12
+ throw new Error('Native rejectedProposals belong to a changed source or different planning stage');
13
+ return structuredClone(parsed);
14
+ }
@@ -1,13 +1,15 @@
1
1
  import { resolveNativeNodeParameterSource } from './resolve-native-node-parameter-source.js';
2
2
  /** Structural projection only: no values, identities or unmet requirements are repaired. */
3
3
  export function resolveNativeNodePlanningOutput(output) {
4
- if (!('decision' in output))
4
+ if ('nativeNodes' in output)
5
5
  return {
6
6
  proposal: {
7
7
  nativeNodes: output.nativeNodes.map(resolveNativeNodeParameterSource),
8
8
  gaps: output.gaps,
9
9
  },
10
10
  };
11
+ if ('gaps' in output)
12
+ return { proposal: { nativeNodes: [], gaps: output.gaps } };
11
13
  const { decision } = output;
12
14
  if ('additions' in decision)
13
15
  return {
@@ -1,21 +1,40 @@
1
1
  import { HumanMessage, SystemMessage } from '@langchain/core/messages';
2
2
  import { isDeepStrictEqual } from 'node:util';
3
- import { createNativeInstanceSelectionSchema, describeNativeInstanceSelection, resolveNativeInstanceSelection, } from '@openapi-flow/core';
3
+ import { createNativeInstanceSelectionSchema, resolveNativeInstanceSelection, } from '@openapi-flow/core';
4
4
  import { serializeStructuredOutputSchema } from '../schemas/serialize-structured-output-schema.js';
5
5
  import { nativeInstanceSelectionPrompt } from '../prompts/native-node-planning-prompt.js';
6
6
  import { NativeNodePlanningError } from './native-node-planning-error.js';
7
+ import { describeNativeSelectionRequest } from './native-selection/describe-native-planning-request.js';
8
+ import { validateNativePlanningRejections } from './native-selection/validate-native-planning-rejections.js';
7
9
  /** One checkpointable role/ownership selection; parameter values are a separate public stage. */
8
10
  export async function selectNativeNodeInstances(input) {
9
11
  input.signal?.throwIfAborted();
10
12
  if (input.model !== undefined &&
11
13
  (!input.model || typeof input.model.withStructuredOutput !== 'function'))
12
14
  throw new Error('selectNativeNodeInstances.model must support structured output when supplied');
13
- const { context } = describeNativeInstanceSelection(input);
14
- const originalOptions = JSON.stringify([
15
- input.planId,
16
- input.allowRuntimeParameters,
17
- input.includeExplanations,
18
- ]);
15
+ const request = describeNativeSelectionRequest(input);
16
+ const { context, feedback, requestFingerprint } = request;
17
+ const rejectedProposals = validateNativePlanningRejections({
18
+ stage: 'instance-selection',
19
+ requestFingerprint,
20
+ rejectedProposals: input.rejectedProposals,
21
+ });
22
+ const checkCurrent = (failure) => {
23
+ try {
24
+ if (!isDeepStrictEqual(request, describeNativeSelectionRequest(input)) ||
25
+ !isDeepStrictEqual(rejectedProposals, validateNativePlanningRejections({
26
+ stage: 'instance-selection',
27
+ requestFingerprint,
28
+ rejectedProposals: input.rejectedProposals,
29
+ })))
30
+ throw new Error('Native instance source contracts changed during selection; no automatic rebase');
31
+ }
32
+ catch (cause) {
33
+ if (failure !== undefined)
34
+ throw new AggregateError([failure, cause], 'Native selection input changed while a failed model call was received', { cause });
35
+ throw cause;
36
+ }
37
+ };
19
38
  const schema = createNativeInstanceSelectionSchema(input);
20
39
  if (!context.capabilities.length)
21
40
  return resolveNativeInstanceSelection({
@@ -38,22 +57,30 @@ export async function selectNativeNodeInstances(input) {
38
57
  })
39
58
  .invoke([
40
59
  new SystemMessage(nativeInstanceSelectionPrompt),
41
- new HumanMessage(JSON.stringify(context)),
42
- ], input.signal === undefined ? undefined : { signal: input.signal });
60
+ new HumanMessage(JSON.stringify({
61
+ ...context,
62
+ ...(feedback === undefined ? {} : { selectionFeedback: feedback }),
63
+ ...(rejectedProposals.length === 0 ? {} : { rejectedProposals }),
64
+ })),
65
+ ], input.signal === undefined ? undefined : { signal: input.signal })
66
+ .catch((error) => {
67
+ checkCurrent(error);
68
+ throw error;
69
+ });
43
70
  input.signal?.throwIfAborted();
71
+ let unchanged = false;
44
72
  try {
45
- if (!isDeepStrictEqual(describeNativeInstanceSelection(input).context, context) ||
46
- JSON.stringify([
47
- input.planId,
48
- input.allowRuntimeParameters,
49
- input.includeExplanations,
50
- ]) !== originalOptions)
51
- throw new Error('Native instance source contracts changed during selection; no automatic rebase');
73
+ checkCurrent();
74
+ unchanged = true;
52
75
  return resolveNativeInstanceSelection({ ...input, proposal: output });
53
76
  }
54
77
  catch (cause) {
55
78
  if (!(cause instanceof Error))
56
79
  throw cause;
57
- throw new NativeNodePlanningError({ stage: 'instance-selection', output }, cause);
80
+ throw new NativeNodePlanningError({
81
+ stage: 'instance-selection',
82
+ output,
83
+ ...(unchanged ? { requestFingerprint } : {}),
84
+ }, cause);
58
85
  }
59
86
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openapi-flow/langchain",
3
- "version": "0.3.18",
3
+ "version": "0.4.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Composable LangChain planning for OpenAPI workflows",
@@ -28,7 +28,7 @@
28
28
  "typecheck": "tsc -p tsconfig.json --noEmit"
29
29
  },
30
30
  "dependencies": {
31
- "@openapi-flow/core": "0.3.18"
31
+ "@openapi-flow/core": "0.4.1"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@langchain/core": "^1.0.0",