@openapi-flow/langchain 0.4.1 → 0.4.2
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 +10 -5
- package/dist/bindings/plan-api-call-bindings.js +3 -2
- package/dist/bindings/select-api-binding-sources.js +3 -2
- 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 +5 -3
- package/dist/schemas/api-literal-generation-output-schema.js +12 -6
- 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 +1 -1
- 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
|
@@ -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.2",
|
|
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.2"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@langchain/core": "^1.0.0",
|