@openapi-flow/langchain 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/arguments/analyze-api-request-media-type.js +3 -2
- package/dist/arguments/generate-api-arguments.js +19 -7
- package/dist/arguments/interpret-api-argument-enums.js +2 -0
- package/dist/arguments/resolve-api-literal-generation-output.js +5 -1
- package/dist/bindings/plan-api-call-bindings.js +3 -2
- package/dist/bindings/select-api-binding-sources.js +3 -2
- package/dist/prompts/api-arguments-prompt.js +2 -0
- package/dist/prompts/native-instance-selection-review-prompt.d.ts +1 -1
- package/dist/prompts/native-instance-selection-review-prompt.js +6 -3
- package/dist/prompts/native-node-planning-prompt.d.ts +2 -2
- package/dist/prompts/native-node-planning-prompt.js +5 -0
- package/dist/prompts/workflow-connection-goal-review-prompt.d.ts +1 -1
- package/dist/prompts/workflow-connection-goal-review-prompt.js +2 -2
- package/dist/prompts/workflow-connections-prompt.d.ts +1 -1
- package/dist/prompts/workflow-connections-prompt.js +1 -0
- package/dist/prompts/workflow-intent-prompt.d.ts +1 -0
- package/dist/prompts/workflow-intent-prompt.js +8 -0
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.js +1 -0
- package/dist/schemas/api-call-binding-plan-schema.d.ts +2 -2
- package/dist/schemas/api-call-binding-plan-schema.js +7 -3
- package/dist/schemas/api-literal-generation-output-schema.d.ts +7 -4
- package/dist/schemas/api-literal-generation-output-schema.js +30 -12
- package/dist/schemas/api-request-media-type-schema.d.ts +1 -1
- package/dist/schemas/api-request-media-type-schema.js +6 -1
- package/dist/schemas/api-selection-analysis-schema.d.ts +36 -1
- package/dist/schemas/api-selection-analysis-schema.js +4 -4
- package/dist/schemas/api-selection-schema.d.ts +14 -1
- package/dist/schemas/api-selection-schema.js +3 -3
- package/dist/schemas/reviewable-workflow-graph-schema.d.ts +14 -3
- package/dist/schemas/with-api-selection-explanation.d.ts +11 -3
- package/dist/schemas/with-api-selection-explanation.js +21 -8
- package/dist/schemas/workflow-connection-execution-schema.d.ts +5 -0
- package/dist/schemas/workflow-connection-execution-schema.js +22 -0
- package/dist/schemas/workflow-connection-goal-review-schema.d.ts +1 -1
- package/dist/schemas/workflow-connection-goal-review-schema.js +8 -10
- package/dist/schemas/workflow-connection-selection-schema.d.ts +33 -0
- package/dist/schemas/workflow-connection-selection-schema.js +34 -0
- package/dist/selection/analyze-api-selection.js +6 -5
- package/dist/selection/select-api-operations.js +5 -4
- package/dist/types/argument-generation.d.ts +6 -6
- package/dist/types/incremental-connection-planning.d.ts +2 -0
- package/dist/types/native-instance-selection-review.d.ts +2 -2
- package/dist/types/reviewable-workflow-planning.d.ts +2 -1
- package/dist/types/workflow-connection-selection.d.ts +19 -0
- package/dist/types/workflow-connection-selection.js +1 -0
- package/dist/types/workflow-intent.d.ts +6 -0
- package/dist/types/workflow-intent.js +1 -0
- package/dist/types/workflow-orchestration.d.ts +2 -1
- package/dist/workflow/connections/invoke-connection-planning-model.js +4 -1
- package/dist/workflow/connections/review-workflow-connection-goals.js +1 -0
- package/dist/workflow/generate-native-node-parameters.js +6 -2
- package/dist/workflow/native-selection/review-native-instance-selection.js +2 -2
- package/dist/workflow/plan-workflow-connections.js +9 -8
- package/dist/workflow/plan-workflow-intent.d.ts +4 -0
- package/dist/workflow/plan-workflow-intent.js +49 -0
- package/dist/workflow/resolve-workflow-connection-output.d.ts +3 -2
- package/dist/workflow/resolve-workflow-connection-output.js +30 -18
- package/dist/workflow/resolve-workflow-connection-selection.d.ts +4 -0
- package/dist/workflow/resolve-workflow-connection-selection.js +24 -0
- package/package.json +2 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
2
2
|
import type { ReviewableWorkflowGraphProposal, ReviewableWorkflowPlanningContext, WorkflowReviewGap, PlannedNativeNode, ExplainedWorkflowConnection, ExplainedWorkflowBlockedCall } from '@openapi-flow/core';
|
|
3
3
|
import type { ExplainedGraphNativeNode } from './workflow-planning.js';
|
|
4
|
+
import type { WorkflowConnectionSelectionOutput } from './workflow-connection-selection.js';
|
|
4
5
|
export interface PlanReviewableWorkflowGraphInput extends ReviewableWorkflowPlanningContext {
|
|
5
6
|
scenario: string;
|
|
6
7
|
model: BaseChatModel;
|
|
@@ -13,7 +14,7 @@ export type ReviewableWorkflowGraphPlanningFailure = {
|
|
|
13
14
|
output: unknown;
|
|
14
15
|
} | {
|
|
15
16
|
stage: 'graph-validation';
|
|
16
|
-
output: ReviewableWorkflowGraphModelOutput;
|
|
17
|
+
output: ReviewableWorkflowGraphModelOutput | WorkflowConnectionSelectionOutput;
|
|
17
18
|
};
|
|
18
19
|
export type ReviewableWorkflowGraphOutput = Omit<ReviewableWorkflowGraphProposal, 'nativeNodes' | 'blockedCalls'> & {
|
|
19
20
|
additionalNativeNodes?: ReviewableWorkflowGraphProposal['nativeNodes'];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { createWorkflowConnectionSelectionSchema } from '../schemas/workflow-connection-selection-schema.js';
|
|
3
|
+
import type { WorkflowConnectionProposal, BlockedWorkflowCall, WorkflowPlanEdge } from '@openapi-flow/core';
|
|
4
|
+
export type WorkflowConnectionSelectionOutput = z.infer<ReturnType<typeof createWorkflowConnectionSelectionSchema>>;
|
|
5
|
+
export type WorkflowConnectionExecutionEdge = Omit<WorkflowConnectionSelectionOutput['edges'][number], 'reason'> & {
|
|
6
|
+
reason?: unknown;
|
|
7
|
+
};
|
|
8
|
+
export type WorkflowConnectionExecutionBlockedCall = BlockedWorkflowCall & {
|
|
9
|
+
reason?: unknown;
|
|
10
|
+
};
|
|
11
|
+
export interface WorkflowConnectionExecutionOutput extends Omit<WorkflowConnectionProposal, 'edges' | 'blockedCalls'> {
|
|
12
|
+
reason?: unknown;
|
|
13
|
+
edges: WorkflowConnectionExecutionEdge[];
|
|
14
|
+
blockedCalls?: WorkflowConnectionExecutionBlockedCall[];
|
|
15
|
+
}
|
|
16
|
+
export type ResolvedWorkflowConnectionSelectionEdge = WorkflowPlanEdge & Pick<WorkflowConnectionExecutionEdge, 'reason'>;
|
|
17
|
+
export interface ResolvedWorkflowConnectionSelection extends Omit<WorkflowConnectionExecutionOutput, 'edges'> {
|
|
18
|
+
edges: ResolvedWorkflowConnectionSelectionEdge[];
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
2
|
+
import type { WorkflowIntentInput } from '@openapi-flow/core';
|
|
3
|
+
export interface PlanWorkflowIntentInput extends WorkflowIntentInput {
|
|
4
|
+
model: BaseChatModel;
|
|
5
|
+
signal?: AbortSignal;
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
2
|
-
import type { PlannedNativeNode, WorkflowConnectionPlanningInput, WorkflowConnectionDecision, WorkflowConnectionProposal, ExplainedWorkflowBlockedCall, ExplainedWorkflowConnection } from '@openapi-flow/core';
|
|
2
|
+
import type { PlannedNativeNode, WorkflowConnectionPlanningInput, WorkflowConnectionDecision, WorkflowConnectionProposal, ExplainedWorkflowBlockedCall, ExplainedWorkflowConnection, WorkflowConnectionExplanationIssue } from '@openapi-flow/core';
|
|
3
3
|
import type { ReviewableWorkflowGraphOutput } from './reviewable-workflow-planning.js';
|
|
4
4
|
export interface PlanWorkflowConnectionsInput extends WorkflowConnectionPlanningInput {
|
|
5
5
|
model: BaseChatModel;
|
|
@@ -18,4 +18,5 @@ export type WorkflowConnectionPlanningOutput = ReviewableWorkflowGraphOutput | W
|
|
|
18
18
|
export interface ResolvedWorkflowConnectionOutput {
|
|
19
19
|
proposal: WorkflowConnectionProposal;
|
|
20
20
|
decision?: WorkflowConnectionDecision;
|
|
21
|
+
explanationIssues?: WorkflowConnectionExplanationIssue[];
|
|
21
22
|
}
|
|
@@ -33,7 +33,10 @@ export async function invokeConnectionPlanningModel(input) {
|
|
|
33
33
|
? {}
|
|
34
34
|
: { requestFingerprint: input.requestFingerprint }),
|
|
35
35
|
}, () => {
|
|
36
|
-
const
|
|
36
|
+
const receiver = input.validationSchema === undefined
|
|
37
|
+
? input.schema
|
|
38
|
+
: input.validationSchema;
|
|
39
|
+
const parsed = receiver.parse(output);
|
|
37
40
|
if (!isDeepStrictEqual(parsed, output))
|
|
38
41
|
throw new Error('Connection output schema must not default, coerce or transform model data');
|
|
39
42
|
return parsed;
|
|
@@ -33,6 +33,7 @@ export async function reviewWorkflowConnectionGoals(input) {
|
|
|
33
33
|
operation,
|
|
34
34
|
name: 'review_workflow_connection_goals',
|
|
35
35
|
schema: createWorkflowConnectionGoalReviewSchema(description),
|
|
36
|
+
validationSchema: createWorkflowConnectionGoalReviewSchema(description, false),
|
|
36
37
|
sourceFingerprint: description.sourceFingerprint,
|
|
37
38
|
messages: [
|
|
38
39
|
new SystemMessage(workflowConnectionGoalReviewPrompt),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
|
|
2
|
-
import { createNativeNodeParametersSchema, describeNativeNodeConfiguration, resolveNativeNodeParameters, } from '@openapi-flow/core';
|
|
2
|
+
import { createNativeNodeParametersSchema, describeNativeNodeConfiguration, resolveNativeNodeParameters, resolveNativeProducerParameters, } from '@openapi-flow/core';
|
|
3
3
|
import { serializeStructuredOutputSchema } from '../schemas/serialize-structured-output-schema.js';
|
|
4
4
|
import { nativeNodeParametersPrompt } from '../prompts/native-node-planning-prompt.js';
|
|
5
5
|
import { NativeNodePlanningError } from './native-node-planning-error.js';
|
|
@@ -9,6 +9,9 @@ export async function generateNativeNodeParameters(input) {
|
|
|
9
9
|
if (input.model !== undefined &&
|
|
10
10
|
(!input.model || typeof input.model.withStructuredOutput !== 'function'))
|
|
11
11
|
throw new Error('generateNativeNodeParameters.model must support structured output when supplied');
|
|
12
|
+
const derived = resolveNativeProducerParameters(input);
|
|
13
|
+
if (derived !== undefined)
|
|
14
|
+
return derived;
|
|
12
15
|
const description = describeNativeNodeConfiguration(input);
|
|
13
16
|
if (!description.instance.hasLiteralParameters)
|
|
14
17
|
return resolveNativeNodeParameters({
|
|
@@ -29,6 +32,7 @@ export async function generateNativeNodeParameters(input) {
|
|
|
29
32
|
if (!input.model || typeof input.model.withStructuredOutput !== 'function')
|
|
30
33
|
throw new Error('generateNativeNodeParameters.model must support structured output for remaining values');
|
|
31
34
|
const schema = createNativeNodeParametersSchema(input);
|
|
35
|
+
const validationSchema = createNativeNodeParametersSchema(input, false);
|
|
32
36
|
const capability = description.context.capabilities.find((entry) => entry.name === description.instance.capability);
|
|
33
37
|
if (!capability)
|
|
34
38
|
throw new Error('Native parameter generation has no selected capability material');
|
|
@@ -67,7 +71,7 @@ export async function generateNativeNodeParameters(input) {
|
|
|
67
71
|
input.signal?.throwIfAborted();
|
|
68
72
|
try {
|
|
69
73
|
// Validate output separately so callers can distinguish a malformed reply from stale source material.
|
|
70
|
-
|
|
74
|
+
validationSchema.parse(output);
|
|
71
75
|
}
|
|
72
76
|
catch (cause) {
|
|
73
77
|
if (!(cause instanceof Error))
|
|
@@ -27,7 +27,7 @@ export async function reviewNativeInstanceSelection(input) {
|
|
|
27
27
|
requestFingerprint,
|
|
28
28
|
rejectedProposals: input.rejectedProposals,
|
|
29
29
|
});
|
|
30
|
-
if (!description.gaps.length)
|
|
30
|
+
if (!description.gaps.length && description.reviewInstances !== true)
|
|
31
31
|
return createNativeInstanceSelectionReview({
|
|
32
32
|
...input,
|
|
33
33
|
proposal: { assessments: {} },
|
|
@@ -40,7 +40,7 @@ export async function reviewNativeInstanceSelection(input) {
|
|
|
40
40
|
}, () => {
|
|
41
41
|
if (!input.model ||
|
|
42
42
|
typeof input.model.withStructuredOutput !== 'function')
|
|
43
|
-
throw new Error('reviewNativeInstanceSelection.model must support structured output for
|
|
43
|
+
throw new Error('reviewNativeInstanceSelection.model must support structured output for the requested review');
|
|
44
44
|
return input.model;
|
|
45
45
|
});
|
|
46
46
|
const checkCurrent = (originalFailure) => {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
|
|
2
2
|
import { isDeepStrictEqual } from 'node:util';
|
|
3
3
|
import { describeWorkflowConnectionPlanning, createWorkflowConnectionPlan, createWorkflowConnectionPlanningRecord, } from '@openapi-flow/core';
|
|
4
|
-
import {
|
|
4
|
+
import { createWorkflowConnectionSelectionSchema } from '../schemas/workflow-connection-selection-schema.js';
|
|
5
|
+
import { createWorkflowConnectionExecutionSchema } from '../schemas/workflow-connection-execution-schema.js';
|
|
6
|
+
import { resolveWorkflowConnectionSelection } from './resolve-workflow-connection-selection.js';
|
|
5
7
|
import { resolveWorkflowConnectionOutput } from './resolve-workflow-connection-output.js';
|
|
6
8
|
import { workflowConnectionsPrompt } from '../prompts/workflow-connections-prompt.js';
|
|
7
9
|
import { assertSelectionInput } from '../legacy/planning/select-operation.js';
|
|
@@ -15,8 +17,7 @@ export async function planWorkflowConnections(input) {
|
|
|
15
17
|
includeExplanations: input.includeExplanations,
|
|
16
18
|
});
|
|
17
19
|
const { input: snapshot, context, sources, } = describeWorkflowConnectionPlanning(input);
|
|
18
|
-
const
|
|
19
|
-
const schema = createReviewableWorkflowGraphSchema([], readyIds, options.includeExplanations === true ? 'connections' : 'none');
|
|
20
|
+
const schema = createWorkflowConnectionSelectionSchema(context, options.includeExplanations === true);
|
|
20
21
|
const output = await input.model
|
|
21
22
|
.withStructuredOutput(serializeStructuredOutputSchema(schema, 'draft-2020-12'), {
|
|
22
23
|
name: 'plan_workflow_connections',
|
|
@@ -29,10 +30,10 @@ export async function planWorkflowConnections(input) {
|
|
|
29
30
|
]);
|
|
30
31
|
let resolved;
|
|
31
32
|
try {
|
|
32
|
-
const parsed = parseStructuredOutput(
|
|
33
|
+
const parsed = parseStructuredOutput(createWorkflowConnectionExecutionSchema(context, options.includeExplanations === true), output, 'model workflow connections');
|
|
33
34
|
if (!isDeepStrictEqual(parsed, output))
|
|
34
35
|
throw new Error('connection model schema must validate without defaults, coercion or transformation');
|
|
35
|
-
resolved = resolveWorkflowConnectionOutput(parsed,
|
|
36
|
+
resolved = resolveWorkflowConnectionOutput(resolveWorkflowConnectionSelection(parsed, context), options.includeExplanations === true);
|
|
36
37
|
}
|
|
37
38
|
catch (error) {
|
|
38
39
|
if (!(error instanceof Error))
|
|
@@ -48,15 +49,15 @@ export async function planWorkflowConnections(input) {
|
|
|
48
49
|
...snapshot,
|
|
49
50
|
proposal: resolved.proposal,
|
|
50
51
|
});
|
|
51
|
-
if (
|
|
52
|
-
if (!resolved.decision)
|
|
53
|
-
throw new Error('model workflow connections are missing the explanation decision');
|
|
52
|
+
if (resolved.decision !== undefined) {
|
|
54
53
|
plan.connectionPlanning = createWorkflowConnectionPlanningRecord({
|
|
55
54
|
...snapshot,
|
|
56
55
|
plan,
|
|
57
56
|
decision: resolved.decision,
|
|
58
57
|
});
|
|
59
58
|
}
|
|
59
|
+
if (resolved.explanationIssues !== undefined)
|
|
60
|
+
plan.connectionExplanationIssues = resolved.explanationIssues;
|
|
60
61
|
return plan;
|
|
61
62
|
}
|
|
62
63
|
catch (error) {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WorkflowIntentPlan } from '@openapi-flow/core';
|
|
2
|
+
import type { PlanWorkflowIntentInput } from '../types/workflow-intent.js';
|
|
3
|
+
/** One semantic planning call; the host owns invocation order, checkpointing, human review and revision. */
|
|
4
|
+
export declare function planWorkflowIntent(input: PlanWorkflowIntentInput): Promise<WorkflowIntentPlan>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
|
|
2
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
3
|
+
import { createWorkflowIntentProposalSchema, workflowIntentInputSchema, resolveWorkflowIntent, runOpenApiFlowOperation, } from '@openapi-flow/core';
|
|
4
|
+
import { workflowIntentPrompt } from '../prompts/workflow-intent-prompt.js';
|
|
5
|
+
import { serializeStructuredOutputSchema } from '../schemas/serialize-structured-output-schema.js';
|
|
6
|
+
import { modelSignalSchema } from '../schemas/model-signal-schema.js';
|
|
7
|
+
import { invokeStructuredModel } from '../model/invoke-structured-model.js';
|
|
8
|
+
/** One semantic planning call; the host owns invocation order, checkpointing, human review and revision. */
|
|
9
|
+
export async function planWorkflowIntent(input) {
|
|
10
|
+
const operation = 'planWorkflowIntent';
|
|
11
|
+
const source = runOpenApiFlowOperation({
|
|
12
|
+
owner: 'langchain',
|
|
13
|
+
operation,
|
|
14
|
+
stage: 'input-validation',
|
|
15
|
+
code: 'PLANNING_INPUT_INVALID',
|
|
16
|
+
}, () => {
|
|
17
|
+
modelSignalSchema.parse(input.signal);
|
|
18
|
+
return workflowIntentInputSchema.parse({
|
|
19
|
+
scenario: input.scenario,
|
|
20
|
+
messages: input.messages,
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
const proposal = await invokeStructuredModel({
|
|
24
|
+
model: input.model,
|
|
25
|
+
operation,
|
|
26
|
+
name: 'plan_workflow_intent',
|
|
27
|
+
schema: serializeStructuredOutputSchema(createWorkflowIntentProposalSchema(source), 'draft-2020-12'),
|
|
28
|
+
method: 'jsonSchema',
|
|
29
|
+
strict: true,
|
|
30
|
+
signal: input.signal,
|
|
31
|
+
messages: [
|
|
32
|
+
new SystemMessage(workflowIntentPrompt),
|
|
33
|
+
new HumanMessage(JSON.stringify(source)),
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
return runOpenApiFlowOperation({
|
|
37
|
+
owner: 'langchain',
|
|
38
|
+
operation,
|
|
39
|
+
stage: 'contract-validation',
|
|
40
|
+
code: 'WORKFLOW_GRAPH_PLANNING_FAILED',
|
|
41
|
+
}, () => {
|
|
42
|
+
if (!isDeepStrictEqual(source, workflowIntentInputSchema.parse({
|
|
43
|
+
scenario: input.scenario,
|
|
44
|
+
messages: input.messages,
|
|
45
|
+
})))
|
|
46
|
+
throw new Error('Workflow intent source changed during model invocation');
|
|
47
|
+
return resolveWorkflowIntent({ ...source, proposal });
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import type { ResolvedWorkflowConnectionOutput
|
|
1
|
+
import type { ResolvedWorkflowConnectionOutput } from '../types/workflow-orchestration.js';
|
|
2
|
+
import type { ResolvedWorkflowConnectionSelection } from '../types/workflow-connection-selection.js';
|
|
2
3
|
/** Fill only context-fixed omissions, then separate reasons from executable edges. */
|
|
3
|
-
export declare function resolveWorkflowConnectionOutput(output:
|
|
4
|
+
export declare function resolveWorkflowConnectionOutput(output: ResolvedWorkflowConnectionSelection, includeExplanations: boolean): ResolvedWorkflowConnectionOutput;
|
|
@@ -1,22 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { completeReviewableWorkflowGraphProposal } from './complete-reviewable-workflow-graph-proposal.js';
|
|
1
|
+
import { workflowConnectionDecisionSchema } from '@openapi-flow/core';
|
|
3
2
|
/** Fill only context-fixed omissions, then separate reasons from executable edges. */
|
|
4
|
-
export function resolveWorkflowConnectionOutput(output,
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
export function resolveWorkflowConnectionOutput(output, includeExplanations) {
|
|
4
|
+
const proposal = {
|
|
5
|
+
edges: output.edges.map(({ from, output, to, input }) => ({
|
|
6
|
+
from,
|
|
7
|
+
output,
|
|
8
|
+
to,
|
|
9
|
+
input,
|
|
10
|
+
})),
|
|
11
|
+
additionalGaps: structuredClone(output.additionalGaps),
|
|
12
|
+
blockedCalls: output.blockedCalls === undefined
|
|
13
|
+
? []
|
|
14
|
+
: output.blockedCalls.map(({ callId, gapIds }) => ({
|
|
15
|
+
callId,
|
|
16
|
+
gapIds: structuredClone(gapIds),
|
|
17
|
+
})),
|
|
18
|
+
};
|
|
19
|
+
if (!includeExplanations)
|
|
20
|
+
return { proposal };
|
|
21
|
+
const presentation = workflowConnectionDecisionSchema.safeParse({
|
|
22
|
+
...output,
|
|
23
|
+
blockedCalls: output.blockedCalls === undefined ? [] : output.blockedCalls,
|
|
24
|
+
});
|
|
25
|
+
if (presentation.success)
|
|
26
|
+
return { proposal, decision: presentation.data };
|
|
15
27
|
return {
|
|
16
|
-
proposal
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
},
|
|
28
|
+
proposal,
|
|
29
|
+
explanationIssues: presentation.error.issues.map((issue) => ({
|
|
30
|
+
path: issue.path.map((segment) => typeof segment === 'symbol' ? String(segment) : segment),
|
|
31
|
+
code: issue.code,
|
|
32
|
+
})),
|
|
21
33
|
};
|
|
22
34
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WorkflowConnectionPlanningContext } from '@openapi-flow/core';
|
|
2
|
+
import type { WorkflowConnectionExecutionOutput, ResolvedWorkflowConnectionSelection } from '../types/workflow-connection-selection.js';
|
|
3
|
+
/** Resolve explicit new-gap references. Never repair, alias or approximate a supplied node ID. */
|
|
4
|
+
export declare function resolveWorkflowConnectionSelection(output: WorkflowConnectionExecutionOutput, context: WorkflowConnectionPlanningContext): ResolvedWorkflowConnectionSelection;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Resolve explicit new-gap references. Never repair, alias or approximate a supplied node ID. */
|
|
2
|
+
export function resolveWorkflowConnectionSelection(output, context) {
|
|
3
|
+
const known = new Set(context.nodes.map((node) => node.id));
|
|
4
|
+
const gaps = new Set(output.additionalGaps.map((gap) => gap.id));
|
|
5
|
+
for (const edge of output.edges)
|
|
6
|
+
for (const endpoint of [edge.from, edge.to]) {
|
|
7
|
+
if (typeof endpoint === 'string') {
|
|
8
|
+
if (!known.has(endpoint))
|
|
9
|
+
throw new Error('Connection selection references an unknown supplied node');
|
|
10
|
+
}
|
|
11
|
+
else if (!gaps.has(endpoint.gapId) || known.has(endpoint.gapId)) {
|
|
12
|
+
throw new Error('Connection gap reference must name a newly declared gap, not a supplied node');
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const canonical = {
|
|
16
|
+
...output,
|
|
17
|
+
edges: output.edges.map((edge) => ({
|
|
18
|
+
...edge,
|
|
19
|
+
from: typeof edge.from === 'string' ? edge.from : edge.from.gapId,
|
|
20
|
+
to: typeof edge.to === 'string' ? edge.to : edge.to.gapId,
|
|
21
|
+
})),
|
|
22
|
+
};
|
|
23
|
+
return canonical;
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openapi-flow/langchain",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
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.4.
|
|
31
|
+
"@openapi-flow/core": "0.4.3"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@langchain/core": "^1.0.0",
|