@mongodb-js/agent-engine-sdk-langgraph 0.11.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/CHANGELOG.md +39 -0
- package/LICENSE.md +201 -0
- package/README.md +149 -0
- package/dist/agent.d.ts +53 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +508 -0
- package/dist/agent.js.map +1 -0
- package/dist/backends/tool_sandbox.d.ts +15 -0
- package/dist/backends/tool_sandbox.d.ts.map +1 -0
- package/dist/backends/tool_sandbox.js +15 -0
- package/dist/backends/tool_sandbox.js.map +1 -0
- package/dist/backends/toolpod.d.ts +68 -0
- package/dist/backends/toolpod.d.ts.map +1 -0
- package/dist/backends/toolpod.js +451 -0
- package/dist/backends/toolpod.js.map +1 -0
- package/dist/call_interrupt.d.ts +20 -0
- package/dist/call_interrupt.d.ts.map +1 -0
- package/dist/call_interrupt.js +23 -0
- package/dist/call_interrupt.js.map +1 -0
- package/dist/checkpoint_branch.d.ts +58 -0
- package/dist/checkpoint_branch.d.ts.map +1 -0
- package/dist/checkpoint_branch.js +239 -0
- package/dist/checkpoint_branch.js.map +1 -0
- package/dist/checkpointer.d.ts +21 -0
- package/dist/checkpointer.d.ts.map +1 -0
- package/dist/checkpointer.js +31 -0
- package/dist/checkpointer.js.map +1 -0
- package/dist/deep_agent.d.ts +49 -0
- package/dist/deep_agent.d.ts.map +1 -0
- package/dist/deep_agent.js +110 -0
- package/dist/deep_agent.js.map +1 -0
- package/dist/deep_agent_checkpointer.d.ts +11 -0
- package/dist/deep_agent_checkpointer.d.ts.map +1 -0
- package/dist/deep_agent_checkpointer.js +19 -0
- package/dist/deep_agent_checkpointer.js.map +1 -0
- package/dist/deep_agent_task.d.ts +26 -0
- package/dist/deep_agent_task.d.ts.map +1 -0
- package/dist/deep_agent_task.js +49 -0
- package/dist/deep_agent_task.js.map +1 -0
- package/dist/durable_deep_agent.d.ts +23 -0
- package/dist/durable_deep_agent.d.ts.map +1 -0
- package/dist/durable_deep_agent.js +176 -0
- package/dist/durable_deep_agent.js.map +1 -0
- package/dist/durable_message_identity.d.ts +5 -0
- package/dist/durable_message_identity.d.ts.map +1 -0
- package/dist/durable_message_identity.js +106 -0
- package/dist/durable_message_identity.js.map +1 -0
- package/dist/durable_session.d.ts +30 -0
- package/dist/durable_session.d.ts.map +1 -0
- package/dist/durable_session.js +400 -0
- package/dist/durable_session.js.map +1 -0
- package/dist/durable_subgraphs.d.ts +13 -0
- package/dist/durable_subgraphs.d.ts.map +1 -0
- package/dist/durable_subgraphs.js +82 -0
- package/dist/durable_subgraphs.js.map +1 -0
- package/dist/durable_tools.d.ts +12 -0
- package/dist/durable_tools.d.ts.map +1 -0
- package/dist/durable_tools.js +41 -0
- package/dist/durable_tools.js.map +1 -0
- package/dist/execution_session.d.ts +63 -0
- package/dist/execution_session.d.ts.map +1 -0
- package/dist/execution_session.js +300 -0
- package/dist/execution_session.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/llm_adapter.d.ts +41 -0
- package/dist/llm_adapter.d.ts.map +1 -0
- package/dist/llm_adapter.js +177 -0
- package/dist/llm_adapter.js.map +1 -0
- package/dist/messages.d.ts +56 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +592 -0
- package/dist/messages.js.map +1 -0
- package/dist/node_logger_adapter.d.ts +51 -0
- package/dist/node_logger_adapter.d.ts.map +1 -0
- package/dist/node_logger_adapter.js +163 -0
- package/dist/node_logger_adapter.js.map +1 -0
- package/dist/platform_checkpointer.d.ts +70 -0
- package/dist/platform_checkpointer.d.ts.map +1 -0
- package/dist/platform_checkpointer.js +252 -0
- package/dist/platform_checkpointer.js.map +1 -0
- package/dist/query.d.ts +103 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +623 -0
- package/dist/query.js.map +1 -0
- package/dist/runtime.d.ts +336 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +881 -0
- package/dist/runtime.js.map +1 -0
- package/dist/secure_llm.d.ts +93 -0
- package/dist/secure_llm.d.ts.map +1 -0
- package/dist/secure_llm.js +423 -0
- package/dist/secure_llm.js.map +1 -0
- package/dist/session_factory.d.ts +6 -0
- package/dist/session_factory.d.ts.map +1 -0
- package/dist/session_factory.js +29 -0
- package/dist/session_factory.js.map +1 -0
- package/dist/session_fork.d.ts +76 -0
- package/dist/session_fork.d.ts.map +1 -0
- package/dist/session_fork.js +428 -0
- package/dist/session_fork.js.map +1 -0
- package/dist/subagents.d.ts +37 -0
- package/dist/subagents.d.ts.map +1 -0
- package/dist/subagents.js +67 -0
- package/dist/subagents.js.map +1 -0
- package/dist/suspend.d.ts +27 -0
- package/dist/suspend.d.ts.map +1 -0
- package/dist/suspend.js +87 -0
- package/dist/suspend.js.map +1 -0
- package/dist/thread_id.d.ts +30 -0
- package/dist/thread_id.d.ts.map +1 -0
- package/dist/thread_id.js +69 -0
- package/dist/thread_id.js.map +1 -0
- package/dist/workflow_json.d.ts +11 -0
- package/dist/workflow_json.d.ts.map +1 -0
- package/dist/workflow_json.js +49 -0
- package/dist/workflow_json.js.map +1 -0
- package/dist/workflow_message.d.ts +11 -0
- package/dist/workflow_message.d.ts.map +1 -0
- package/dist/workflow_message.js +179 -0
- package/dist/workflow_message.js.map +1 -0
- package/dist/workflow_state.d.ts +7 -0
- package/dist/workflow_state.d.ts.map +1 -0
- package/dist/workflow_state.js +62 -0
- package/dist/workflow_state.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** Shared execution-session contract and native LangGraph implementation. */
|
|
2
|
+
import { type BaseMessage } from "@langchain/core/messages";
|
|
3
|
+
import type { RunnableConfig } from "@langchain/core/runnables";
|
|
4
|
+
import { Command, type CompiledStateGraph, type Interrupt } from "@langchain/langgraph";
|
|
5
|
+
import type { AgentInput, AgentOutput, RequestContext, StreamEvent } from "@mongodb-js/agent-engine-sdk";
|
|
6
|
+
import { checkpointMetadata } from "./checkpoint_branch.js";
|
|
7
|
+
import type { DurableSubgraphResolver } from "./durable_subgraphs.js";
|
|
8
|
+
export type PrepareAgentInput = (input: AgentInput, ctx: RequestContext) => unknown;
|
|
9
|
+
export type ResolveThreadId = (ctx: RequestContext) => string;
|
|
10
|
+
export interface PreparedRun {
|
|
11
|
+
readonly graphInput: unknown;
|
|
12
|
+
readonly config: RunnableConfig;
|
|
13
|
+
}
|
|
14
|
+
type ExecutionMetadata = ReturnType<typeof checkpointMetadata>;
|
|
15
|
+
export interface SessionOptions {
|
|
16
|
+
readonly callbacks: readonly unknown[];
|
|
17
|
+
readonly prepareInput: PrepareAgentInput | null;
|
|
18
|
+
readonly resolveThreadId: ResolveThreadId | null;
|
|
19
|
+
readonly durableSubgraphs: DurableSubgraphResolver | null;
|
|
20
|
+
}
|
|
21
|
+
export declare function explicitCheckpointId(ctx: RequestContext): string | undefined;
|
|
22
|
+
export declare abstract class ExecutionSession {
|
|
23
|
+
abstract readonly resumed: boolean;
|
|
24
|
+
readonly threadId: string;
|
|
25
|
+
protected readonly graph: CompiledStateGraph<unknown, unknown>;
|
|
26
|
+
protected readonly ctx: RequestContext;
|
|
27
|
+
protected readonly input: AgentInput;
|
|
28
|
+
protected readonly callbacks: readonly unknown[];
|
|
29
|
+
protected readonly prepareInput: PrepareAgentInput | null;
|
|
30
|
+
protected readonly durableSubgraphs: DurableSubgraphResolver | null;
|
|
31
|
+
protected constructor(graph: CompiledStateGraph<unknown, unknown>, ctx: RequestContext, input: AgentInput, options: SessionOptions);
|
|
32
|
+
protected baseConfig(): RunnableConfig;
|
|
33
|
+
protected freshGraphInput(ctx?: RequestContext): unknown;
|
|
34
|
+
abstract prepareRun(): Promise<PreparedRun>;
|
|
35
|
+
abstract invokeInterrupt(config: RunnableConfig, response: string, messages: readonly unknown[]): Promise<Command | AgentOutput | null>;
|
|
36
|
+
abstract streamInterrupt(config: RunnableConfig, captured: readonly Interrupt[], messages: readonly BaseMessage[]): Promise<Command | StreamEvent | null>;
|
|
37
|
+
abstract complete(): Promise<ExecutionMetadata | void>;
|
|
38
|
+
abstract close(): Promise<void>;
|
|
39
|
+
runInGraphScope<T>(fn: () => T): T;
|
|
40
|
+
iterateInGraphScope<T>(iterable: AsyncIterable<T>): AsyncIterable<T>;
|
|
41
|
+
}
|
|
42
|
+
export declare class NativeSession extends ExecutionSession {
|
|
43
|
+
readonly resumed: boolean;
|
|
44
|
+
private readonly config;
|
|
45
|
+
private readonly branchSource;
|
|
46
|
+
private readonly resumeCommand;
|
|
47
|
+
constructor(graph: CompiledStateGraph<unknown, unknown>, ctx: RequestContext, input: AgentInput, options: SessionOptions);
|
|
48
|
+
prepareRun(): Promise<PreparedRun>;
|
|
49
|
+
/**
|
|
50
|
+
* After an in-app fork, the destination's first continue carries no user
|
|
51
|
+
* message; invoke(null) so LangGraph resumes from the copied checkpoint
|
|
52
|
+
* instead of appending an empty HumanMessage (docs/session-fork.md).
|
|
53
|
+
*/
|
|
54
|
+
private firstDestContinueInput;
|
|
55
|
+
invokeInterrupt(config: RunnableConfig, response: string, messages: readonly unknown[]): Promise<AgentOutput | null>;
|
|
56
|
+
streamInterrupt(_config: RunnableConfig, captured: readonly Interrupt[], messages: readonly BaseMessage[]): Promise<StreamEvent | null>;
|
|
57
|
+
complete(): Promise<ExecutionMetadata>;
|
|
58
|
+
close(): Promise<void>;
|
|
59
|
+
private getCheckpointId;
|
|
60
|
+
private fenceCancelledPredecessorWrites;
|
|
61
|
+
}
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=execution_session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution_session.d.ts","sourceRoot":"","sources":["../src/execution_session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/** Shared execution-session contract and native LangGraph implementation. */
|
|
2
|
+
import { HumanMessage } from "@langchain/core/messages";
|
|
3
|
+
import { Command, } from "@langchain/langgraph";
|
|
4
|
+
import { isDeepStrictEqual } from "node:util";
|
|
5
|
+
import { getLogger } from "@mongodb-js/agent-engine-runner-shared";
|
|
6
|
+
import { initializeCheckpointBranch, branchPointFromMetadata, checkpointMetadata, } from "./checkpoint_branch.js";
|
|
7
|
+
import { PlatformCheckpointer } from "./platform_checkpointer.js";
|
|
8
|
+
import { takeContinueWithoutUserMessage } from "./session_fork.js";
|
|
9
|
+
import { interruptSnapshot, invokeSuspendOutput, streamHitlSuspendEvent, validateInterruptValue, } from "./suspend.js";
|
|
10
|
+
import { checkpointThreadId } from "./thread_id.js";
|
|
11
|
+
const logger = getLogger("agent_engine_sdk_langgraph.execution_session");
|
|
12
|
+
function interruptValuesFromState(state) {
|
|
13
|
+
const values = [];
|
|
14
|
+
const seen = new Map();
|
|
15
|
+
for (const task of state.tasks ?? []) {
|
|
16
|
+
for (const interrupt of task.interrupts ?? []) {
|
|
17
|
+
validateInterruptValue(interrupt.id ?? "<unknown>", interrupt.value);
|
|
18
|
+
const id = typeof interrupt.id === "string" ? interrupt.id : "";
|
|
19
|
+
// A nested subgraph's interrupt can repeat under its parent task with
|
|
20
|
+
// an identical value; project each native id once. A repeated id with
|
|
21
|
+
// a different value is conflicting framework state — fail closed the
|
|
22
|
+
// same way the stream and durable paths do.
|
|
23
|
+
if (id) {
|
|
24
|
+
const previous = seen.get(id);
|
|
25
|
+
if (previous !== undefined) {
|
|
26
|
+
if (isDeepStrictEqual(previous, interrupt.value))
|
|
27
|
+
continue;
|
|
28
|
+
throw new Error("LangGraph returned duplicate interrupt ids");
|
|
29
|
+
}
|
|
30
|
+
seen.set(id, interrupt.value);
|
|
31
|
+
}
|
|
32
|
+
values.push(interrupt.value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return values;
|
|
36
|
+
}
|
|
37
|
+
function payloadDict(input) {
|
|
38
|
+
if (input.payload === null ||
|
|
39
|
+
typeof input.payload !== "object" ||
|
|
40
|
+
Array.isArray(input.payload)) {
|
|
41
|
+
throw new TypeError(`Expected dict payload, got ${typeof input.payload}`);
|
|
42
|
+
}
|
|
43
|
+
return input.payload;
|
|
44
|
+
}
|
|
45
|
+
function resolveCheckpointThreadId(ctx, resolveThreadId) {
|
|
46
|
+
return checkpointThreadId(ctx, resolveThreadId);
|
|
47
|
+
}
|
|
48
|
+
function normalizeCheckpointId(value) {
|
|
49
|
+
if (value === null || value === undefined)
|
|
50
|
+
return undefined;
|
|
51
|
+
const checkpointId = String(value).trim();
|
|
52
|
+
if (checkpointId === "" || checkpointId.toLowerCase() === "none") {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
return checkpointId;
|
|
56
|
+
}
|
|
57
|
+
export function explicitCheckpointId(ctx) {
|
|
58
|
+
const checkpointId = normalizeCheckpointId(ctx.metadata?.["checkpoint_id"]);
|
|
59
|
+
return checkpointId?.startsWith("thread:") ? undefined : checkpointId;
|
|
60
|
+
}
|
|
61
|
+
export class ExecutionSession {
|
|
62
|
+
threadId;
|
|
63
|
+
graph;
|
|
64
|
+
ctx;
|
|
65
|
+
input;
|
|
66
|
+
callbacks;
|
|
67
|
+
prepareInput;
|
|
68
|
+
durableSubgraphs;
|
|
69
|
+
constructor(graph, ctx, input, options) {
|
|
70
|
+
this.graph = graph;
|
|
71
|
+
this.ctx = ctx;
|
|
72
|
+
this.input = input;
|
|
73
|
+
this.callbacks = options.callbacks;
|
|
74
|
+
this.prepareInput = options.prepareInput;
|
|
75
|
+
this.durableSubgraphs = options.durableSubgraphs;
|
|
76
|
+
this.threadId = resolveCheckpointThreadId(ctx, options.resolveThreadId);
|
|
77
|
+
}
|
|
78
|
+
baseConfig() {
|
|
79
|
+
const config = {
|
|
80
|
+
configurable: {
|
|
81
|
+
thread_id: this.threadId,
|
|
82
|
+
request_context: this.ctx,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
if (this.callbacks.length > 0) {
|
|
86
|
+
config.callbacks = [...this.callbacks];
|
|
87
|
+
}
|
|
88
|
+
return config;
|
|
89
|
+
}
|
|
90
|
+
freshGraphInput(ctx = this.ctx) {
|
|
91
|
+
if (this.prepareInput !== null) {
|
|
92
|
+
return this.prepareInput(this.input, ctx);
|
|
93
|
+
}
|
|
94
|
+
const payload = payloadDict(this.input);
|
|
95
|
+
const graphInput = {
|
|
96
|
+
messages: [
|
|
97
|
+
new HumanMessage({ content: String(payload["message"] ?? "") }),
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
if (ctx.userId)
|
|
101
|
+
graphInput["user_id"] = ctx.userId;
|
|
102
|
+
if (ctx.sessionId)
|
|
103
|
+
graphInput["session_id"] = ctx.sessionId;
|
|
104
|
+
return graphInput;
|
|
105
|
+
}
|
|
106
|
+
runInGraphScope(fn) {
|
|
107
|
+
return fn();
|
|
108
|
+
}
|
|
109
|
+
async *iterateInGraphScope(iterable) {
|
|
110
|
+
const iterator = iterable[Symbol.asyncIterator]();
|
|
111
|
+
try {
|
|
112
|
+
while (true) {
|
|
113
|
+
const result = await this.runInGraphScope(() => iterator.next());
|
|
114
|
+
if (result.done)
|
|
115
|
+
return;
|
|
116
|
+
yield result.value;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
const close = iterator.return;
|
|
121
|
+
if (close !== undefined) {
|
|
122
|
+
await this.runInGraphScope(() => close.call(iterator));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export class NativeSession extends ExecutionSession {
|
|
128
|
+
resumed;
|
|
129
|
+
config;
|
|
130
|
+
branchSource;
|
|
131
|
+
resumeCommand;
|
|
132
|
+
constructor(graph, ctx, input, options) {
|
|
133
|
+
super(graph, ctx, input, options);
|
|
134
|
+
this.resumed = ctx.resume === true;
|
|
135
|
+
const resumeData = ctx.resumeData;
|
|
136
|
+
if (ctx.resume === true &&
|
|
137
|
+
(resumeData === undefined || resumeData === null)) {
|
|
138
|
+
throw new Error("ctx.resume is true but resume_data is missing. " +
|
|
139
|
+
"Provide resume_data to resume a suspended graph.");
|
|
140
|
+
}
|
|
141
|
+
this.resumeCommand =
|
|
142
|
+
ctx.resume === true && resumeData !== undefined && resumeData !== null
|
|
143
|
+
? new Command({ resume: resumeData })
|
|
144
|
+
: null;
|
|
145
|
+
this.branchSource = this.resumed
|
|
146
|
+
? undefined
|
|
147
|
+
: branchPointFromMetadata(ctx.metadata);
|
|
148
|
+
const config = this.baseConfig();
|
|
149
|
+
const checkpointId = explicitCheckpointId(ctx);
|
|
150
|
+
if (checkpointId !== undefined) {
|
|
151
|
+
config.configurable = {
|
|
152
|
+
...config.configurable,
|
|
153
|
+
checkpoint_id: checkpointId,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
this.config = config;
|
|
157
|
+
}
|
|
158
|
+
async prepareRun() {
|
|
159
|
+
// A null graph input is meaningful (continue the copied checkpoint without
|
|
160
|
+
// a user turn), so the branches stay explicit: `??` would fall through it.
|
|
161
|
+
let graphInput;
|
|
162
|
+
if (this.resumeCommand !== null) {
|
|
163
|
+
graphInput = this.resumeCommand;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
graphInput =
|
|
167
|
+
this.firstDestContinueInput() === null ? null : this.freshGraphInput();
|
|
168
|
+
}
|
|
169
|
+
// HITL resume continues a thread that already received any branch copy;
|
|
170
|
+
// clients and OE dispatch may still send the source branch point.
|
|
171
|
+
if (!this.resumed && this.branchSource !== undefined) {
|
|
172
|
+
await initializeCheckpointBranch(this.graph, this.config, this.branchSource);
|
|
173
|
+
}
|
|
174
|
+
if (this.ctx.previousExecutionCancelled === true && !this.resumed) {
|
|
175
|
+
await this.fenceCancelledPredecessorWrites();
|
|
176
|
+
}
|
|
177
|
+
return { graphInput, config: this.config };
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* After an in-app fork, the destination's first continue carries no user
|
|
181
|
+
* message; invoke(null) so LangGraph resumes from the copied checkpoint
|
|
182
|
+
* instead of appending an empty HumanMessage (docs/session-fork.md).
|
|
183
|
+
*/
|
|
184
|
+
firstDestContinueInput() {
|
|
185
|
+
if (this.resumed)
|
|
186
|
+
return undefined;
|
|
187
|
+
if (!takeContinueWithoutUserMessage(this.threadId))
|
|
188
|
+
return undefined;
|
|
189
|
+
const raw = this.input.payload;
|
|
190
|
+
const payload = raw !== null && typeof raw === "object" && !Array.isArray(raw)
|
|
191
|
+
? raw
|
|
192
|
+
: {};
|
|
193
|
+
if (String(payload["message"] ?? "").trim() !== "")
|
|
194
|
+
return undefined;
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
async invokeInterrupt(config, response, messages) {
|
|
198
|
+
const graph = this.graph;
|
|
199
|
+
const state = await graph.getState(config);
|
|
200
|
+
if (!state.next || state.next.length === 0)
|
|
201
|
+
return null;
|
|
202
|
+
const interruptValues = interruptValuesFromState(state);
|
|
203
|
+
const checkpointId = await this.getCheckpointId();
|
|
204
|
+
return invokeSuspendOutput({
|
|
205
|
+
response,
|
|
206
|
+
threadId: this.threadId,
|
|
207
|
+
checkpointId,
|
|
208
|
+
interruptValues,
|
|
209
|
+
messageCount: messages.length,
|
|
210
|
+
resumed: this.resumed,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
async streamInterrupt(_config, captured, messages) {
|
|
214
|
+
if (captured.length === 0)
|
|
215
|
+
return null;
|
|
216
|
+
const interrupts = interruptSnapshot(captured);
|
|
217
|
+
const checkpointId = await this.getCheckpointId();
|
|
218
|
+
return streamHitlSuspendEvent({
|
|
219
|
+
interrupts,
|
|
220
|
+
checkpointId,
|
|
221
|
+
resumed: this.resumed,
|
|
222
|
+
messages,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
async complete() {
|
|
226
|
+
const checkpointId = await this.getCheckpointId();
|
|
227
|
+
return checkpointMetadata(checkpointId === undefined
|
|
228
|
+
? undefined
|
|
229
|
+
: { threadId: this.threadId, checkpointId });
|
|
230
|
+
}
|
|
231
|
+
close() {
|
|
232
|
+
return Promise.resolve();
|
|
233
|
+
}
|
|
234
|
+
async getCheckpointId() {
|
|
235
|
+
const checkpointer = this.graph
|
|
236
|
+
.checkpointer;
|
|
237
|
+
if (checkpointer === null || checkpointer === undefined)
|
|
238
|
+
return undefined;
|
|
239
|
+
const saver = checkpointer;
|
|
240
|
+
if (typeof saver.getTuple !== "function")
|
|
241
|
+
return undefined;
|
|
242
|
+
try {
|
|
243
|
+
const tuple = (await saver.getTuple({
|
|
244
|
+
configurable: { thread_id: this.threadId },
|
|
245
|
+
}));
|
|
246
|
+
const checkpoint = tuple?.checkpoint;
|
|
247
|
+
if (checkpoint !== null &&
|
|
248
|
+
typeof checkpoint === "object" &&
|
|
249
|
+
!Array.isArray(checkpoint)) {
|
|
250
|
+
const id = checkpoint["id"];
|
|
251
|
+
return typeof id === "string" ? id : undefined;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch (exc) {
|
|
255
|
+
logger.warn(`Failed to get checkpoint ID for thread ${this.threadId} — degrading to undefined ` +
|
|
256
|
+
`without changing the agent execution outcome: ${exc instanceof Error ? exc.message : String(exc)}`);
|
|
257
|
+
}
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
async fenceCancelledPredecessorWrites() {
|
|
261
|
+
// A cancelled pod can leave half-finished writes on the latest checkpoint.
|
|
262
|
+
// Remove only those writes before a fresh turn can fold them into its state.
|
|
263
|
+
const graphSaver = this.graph.checkpointer;
|
|
264
|
+
const saver = (graphSaver instanceof PlatformCheckpointer
|
|
265
|
+
? graphSaver.native
|
|
266
|
+
: graphSaver);
|
|
267
|
+
if (!saver?.db?.collection ||
|
|
268
|
+
typeof saver.checkpointCollectionName !== "string" ||
|
|
269
|
+
typeof saver.checkpointWritesCollectionName !== "string") {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
try {
|
|
273
|
+
const checkpoints = saver.db.collection(saver.checkpointCollectionName);
|
|
274
|
+
const writes = saver.db.collection(saver.checkpointWritesCollectionName);
|
|
275
|
+
const namespaces = await checkpoints.distinct("checkpoint_ns", {
|
|
276
|
+
thread_id: this.threadId,
|
|
277
|
+
});
|
|
278
|
+
let removed = 0;
|
|
279
|
+
for (const namespace of namespaces) {
|
|
280
|
+
const latest = await checkpoints.findOne({ thread_id: this.threadId, checkpoint_ns: namespace }, { sort: { checkpoint_id: -1 }, projection: { checkpoint_id: 1 } });
|
|
281
|
+
if (!latest)
|
|
282
|
+
continue;
|
|
283
|
+
const result = await writes.deleteMany({
|
|
284
|
+
thread_id: this.threadId,
|
|
285
|
+
checkpoint_ns: namespace,
|
|
286
|
+
checkpoint_id: latest["checkpoint_id"],
|
|
287
|
+
});
|
|
288
|
+
removed += result.deletedCount ?? 0;
|
|
289
|
+
}
|
|
290
|
+
if (removed > 0) {
|
|
291
|
+
logger.info(`Discarded ${removed} pending checkpoint writes left by a cancelled run (thread ${this.threadId})`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
catch (exc) {
|
|
295
|
+
logger.warn(`Failed to fence a cancelled run's pending writes (thread ${this.threadId}): ` +
|
|
296
|
+
`${exc instanceof Error ? exc.message : String(exc)}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=execution_session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution_session.js","sourceRoot":"","sources":["../src/execution_session.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangChain SDK for Atlas Agent Engine.
|
|
3
|
+
*
|
|
4
|
+
* Port of `agent_engine_sdk_langgraph/__init__.py`.
|
|
5
|
+
*/
|
|
6
|
+
export { LangGraphBaseAgent } from "./agent.js";
|
|
7
|
+
export type { PrepareAgentInput, ResolveThreadId } from "./agent.js";
|
|
8
|
+
export { LangGraphQueryPlugin } from "./query.js";
|
|
9
|
+
export type { LangGraphQueryPluginParams } from "./query.js";
|
|
10
|
+
export { App } from "./runtime.js";
|
|
11
|
+
export type { DeepAgentOptions } from "./runtime.js";
|
|
12
|
+
export type { SessionFinishStatus } from "@mongodb-js/agent-engine-runner-shared";
|
|
13
|
+
export { getCallAbortSignal } from "@mongodb-js/agent-engine-runner-shared";
|
|
14
|
+
export { withCallInterruptSupport } from "./call_interrupt.js";
|
|
15
|
+
export { createAgentEngineDeepAgent, type CreateAgentEngineDeepAgentOptions, } from "./deep_agent.js";
|
|
16
|
+
export { validateSubagentTree, MAX_SUBAGENT_NESTING_DEPTH, } from "./subagents.js";
|
|
17
|
+
export { AgentEngineToolPodBackend } from "./backends/toolpod.js";
|
|
18
|
+
export { AgentEngineToolSandboxBackend } from "./backends/tool_sandbox.js";
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EACL,0BAA0B,EAC1B,KAAK,iCAAiC,GACvC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Copyright 2026 MongoDB, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* LangChain SDK for Atlas Agent Engine.
|
|
5
|
+
*
|
|
6
|
+
* Port of `agent_engine_sdk_langgraph/__init__.py`.
|
|
7
|
+
*/
|
|
8
|
+
export { LangGraphBaseAgent } from "./agent.js";
|
|
9
|
+
export { LangGraphQueryPlugin } from "./query.js";
|
|
10
|
+
export { App } from "./runtime.js";
|
|
11
|
+
export { getCallAbortSignal } from "@mongodb-js/agent-engine-runner-shared";
|
|
12
|
+
export { withCallInterruptSupport } from "./call_interrupt.js";
|
|
13
|
+
export { createAgentEngineDeepAgent, } from "./deep_agent.js";
|
|
14
|
+
export { validateSubagentTree, MAX_SUBAGENT_NESTING_DEPTH, } from "./subagents.js";
|
|
15
|
+
export { AgentEngineToolPodBackend } from "./backends/toolpod.js";
|
|
16
|
+
export { AgentEngineToolSandboxBackend } from "./backends/tool_sandbox.js";
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,sCAAsC;AAEtC;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EACL,0BAA0B,GAE3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight adapter wrapping a LangChain `BaseChatModel` as `BaseLLM`.
|
|
3
|
+
*
|
|
4
|
+
* Used by the Tool Pod (`server/tool.ts`) to invoke LLMs through the
|
|
5
|
+
* framework-neutral `BaseLLM` protocol while the underlying provider is
|
|
6
|
+
* still a LangChain ChatModel.
|
|
7
|
+
*
|
|
8
|
+
* Eventually runtime `createLlm` will return `BaseLLM` directly,
|
|
9
|
+
* and this adapter will only be used internally by agent-engine-sdk-langgraph.
|
|
10
|
+
*
|
|
11
|
+
* Port of `agent_engine_sdk_langgraph/llm_adapter.py`.
|
|
12
|
+
*
|
|
13
|
+
* **Sync vs async note:** Python's `BaseLLM` exposes both `invoke` (sync) and
|
|
14
|
+
* `ainvoke` (async). JavaScript has no synchronous network I/O, so the TS
|
|
15
|
+
* port collapses both into a single async `invoke`.
|
|
16
|
+
*/
|
|
17
|
+
import type { BaseMessage, BaseMessageChunk } from "@langchain/core/messages";
|
|
18
|
+
import { type BaseLLM, type JsonValue, type LLMResponse, type LLMStreamChunk, type LLMToolSchema, type Message } from "@mongodb-js/agent-engine-sdk";
|
|
19
|
+
/**
|
|
20
|
+
* Structural contract for the LangChain chat model wrapped by the adapter.
|
|
21
|
+
*
|
|
22
|
+
* Avoids tying the public adapter to a specific LangChain class — any object
|
|
23
|
+
* with `invoke`/`stream`/`bindTools` (or a subset of those) will satisfy it,
|
|
24
|
+
* which keeps tests trivial to write.
|
|
25
|
+
*/
|
|
26
|
+
export interface LangChainChatModelLike {
|
|
27
|
+
invoke(input: readonly BaseMessage[], config?: Record<string, unknown>): Promise<BaseMessage>;
|
|
28
|
+
stream?(input: readonly BaseMessage[], config?: Record<string, unknown>): AsyncIterable<BaseMessageChunk> | Promise<AsyncIterable<BaseMessageChunk>>;
|
|
29
|
+
bindTools?(tools: ReadonlyArray<Record<string, JsonValue>>, kwargs?: {
|
|
30
|
+
tool_choice?: unknown;
|
|
31
|
+
}): LangChainChatModelLike;
|
|
32
|
+
}
|
|
33
|
+
export declare class LangChainLLMAdapter implements BaseLLM {
|
|
34
|
+
private readonly llm;
|
|
35
|
+
constructor(llm: LangChainChatModelLike, tools?: readonly LLMToolSchema[], toolChoice?: unknown);
|
|
36
|
+
/** LLM invocation. */
|
|
37
|
+
invoke(messages: readonly Message[], kwargs?: Readonly<Record<string, unknown>>): Promise<LLMResponse>;
|
|
38
|
+
/** Streaming LLM invocation. Matches `BaseLLM.stream` from agent-engine-sdk. */
|
|
39
|
+
stream(messages: readonly Message[], kwargs?: Readonly<Record<string, unknown>>): AsyncIterable<LLMStreamChunk>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=llm_adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm_adapter.d.ts","sourceRoot":"","sources":["../src/llm_adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE9E,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,cAAc,EAEnB,KAAK,aAAa,EAClB,KAAK,OAAO,EAEb,MAAM,8BAA8B,CAAC;AActC;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,CACJ,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,WAAW,CAAC,CAAC;IACxB,MAAM,CAAC,CACL,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,aAAa,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC9E,SAAS,CAAC,CACR,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,EAC/C,MAAM,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,GACjC,sBAAsB,CAAC;CAC3B;AAMD,qBAAa,mBAAoB,YAAW,OAAO;IACjD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;gBAG3C,GAAG,EAAE,sBAAsB,EAC3B,KAAK,CAAC,EAAE,SAAS,aAAa,EAAE,EAChC,UAAU,CAAC,EAAE,OAAO;IA0BtB,sBAAsB;IAChB,MAAM,CACV,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,MAAM,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,GAC7C,OAAO,CAAC,WAAW,CAAC;IAMvB,gFAAgF;IACzE,MAAM,CACX,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,MAAM,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,GAC7C,aAAa,CAAC,cAAc,CAAC;CAqBjC"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight adapter wrapping a LangChain `BaseChatModel` as `BaseLLM`.
|
|
3
|
+
*
|
|
4
|
+
* Used by the Tool Pod (`server/tool.ts`) to invoke LLMs through the
|
|
5
|
+
* framework-neutral `BaseLLM` protocol while the underlying provider is
|
|
6
|
+
* still a LangChain ChatModel.
|
|
7
|
+
*
|
|
8
|
+
* Eventually runtime `createLlm` will return `BaseLLM` directly,
|
|
9
|
+
* and this adapter will only be used internally by agent-engine-sdk-langgraph.
|
|
10
|
+
*
|
|
11
|
+
* Port of `agent_engine_sdk_langgraph/llm_adapter.py`.
|
|
12
|
+
*
|
|
13
|
+
* **Sync vs async note:** Python's `BaseLLM` exposes both `invoke` (sync) and
|
|
14
|
+
* `ainvoke` (async). JavaScript has no synchronous network I/O, so the TS
|
|
15
|
+
* port collapses both into a single async `invoke`.
|
|
16
|
+
*/
|
|
17
|
+
import {} from "@mongodb-js/agent-engine-sdk";
|
|
18
|
+
import { LLMResult, accumulateStreamUsage, jsonSafeMetadata, normalizeContent, normalizeToolCallArgs, } from "@mongodb-js/agent-engine-runner-shared";
|
|
19
|
+
import { platformMessagesToLc } from "./messages.js";
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// LangChainLLMAdapter
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
export class LangChainLLMAdapter {
|
|
24
|
+
llm;
|
|
25
|
+
constructor(llm, tools, toolChoice) {
|
|
26
|
+
const serializedTools = tools && tools.length > 0
|
|
27
|
+
? tools.map((tool) => tool.toLangchainDict())
|
|
28
|
+
: undefined;
|
|
29
|
+
if (serializedTools) {
|
|
30
|
+
if (typeof llm.bindTools !== "function") {
|
|
31
|
+
// Match Python's behavior: raise loudly when tools are supplied but
|
|
32
|
+
// the underlying model has no `bind_tools` / `bindTools` method.
|
|
33
|
+
throw new Error("LLM does not support tool binding (missing `bindTools` method).");
|
|
34
|
+
}
|
|
35
|
+
// tool_choice (e.g. a function name from withStructuredOutput) is the
|
|
36
|
+
// force point: LangChain translates it against the bound tools to
|
|
37
|
+
// require the call. A choice without tools cannot bind to anything.
|
|
38
|
+
this.llm = llm.bindTools(serializedTools, toolChoice != null ? { tool_choice: toolChoice } : undefined);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.llm = llm;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** LLM invocation. */
|
|
45
|
+
async invoke(messages, kwargs = {}) {
|
|
46
|
+
const lcMessages = platformMessagesToLc(messages);
|
|
47
|
+
const response = await this.llm.invoke(lcMessages, kwargs);
|
|
48
|
+
return responseToLlmResponse(response);
|
|
49
|
+
}
|
|
50
|
+
/** Streaming LLM invocation. Matches `BaseLLM.stream` from agent-engine-sdk. */
|
|
51
|
+
async *stream(messages, kwargs = {}) {
|
|
52
|
+
const lcMessages = platformMessagesToLc(messages);
|
|
53
|
+
if (typeof this.llm.stream !== "function") {
|
|
54
|
+
throw new Error("Underlying LLM does not support streaming (no `stream` method).");
|
|
55
|
+
}
|
|
56
|
+
const streamResult = this.llm.stream(lcMessages, kwargs);
|
|
57
|
+
// LangChain.js streams are AsyncIterable directly; some adapters return a Promise<AsyncIterable>.
|
|
58
|
+
const stream = isPromise(streamResult) ? await streamResult : streamResult;
|
|
59
|
+
let running;
|
|
60
|
+
for await (const chunk of stream) {
|
|
61
|
+
const streamChunk = chunkToLlmStreamChunk(chunk);
|
|
62
|
+
running = accumulateStreamUsage(running, streamChunk.usage);
|
|
63
|
+
yield running !== undefined
|
|
64
|
+
? { ...streamChunk, usage: running }
|
|
65
|
+
: streamChunk;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Conversion helpers
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
/** Convert a LangChain response to sdk-core `LLMResponse`. */
|
|
73
|
+
function responseToLlmResponse(response) {
|
|
74
|
+
return LLMResult.fromResponse(response).toResponse();
|
|
75
|
+
}
|
|
76
|
+
function optionalStrAttr(message, attr) {
|
|
77
|
+
const value = message[attr];
|
|
78
|
+
return typeof value === "string" ? value : undefined;
|
|
79
|
+
}
|
|
80
|
+
function optionalJsonDictAttr(message, attr) {
|
|
81
|
+
const value = message[attr];
|
|
82
|
+
return jsonSafeMetadata(value);
|
|
83
|
+
}
|
|
84
|
+
/** Convert a LangChain stream chunk to sdk-core `LLMStreamChunk`. */
|
|
85
|
+
function chunkToLlmStreamChunk(chunk) {
|
|
86
|
+
const rawContent = chunk.content;
|
|
87
|
+
const content = normalizeContent(rawContent);
|
|
88
|
+
let toolCalls;
|
|
89
|
+
const rawChunks = chunk["tool_call_chunks"];
|
|
90
|
+
if (Array.isArray(rawChunks) && rawChunks.length > 0) {
|
|
91
|
+
toolCalls = [];
|
|
92
|
+
for (const tc of rawChunks) {
|
|
93
|
+
const tcDict = coerceToDict(tc);
|
|
94
|
+
if (tcDict === undefined)
|
|
95
|
+
continue;
|
|
96
|
+
toolCalls.push(buildToolCallChunk(tcDict, /* includeIndex */ true));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Fall back to merged tool_calls when no tool_call_chunks are present.
|
|
100
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
101
|
+
const rawCalls = chunk["tool_calls"];
|
|
102
|
+
if (Array.isArray(rawCalls) && rawCalls.length > 0) {
|
|
103
|
+
toolCalls = [];
|
|
104
|
+
for (const tc of rawCalls) {
|
|
105
|
+
if (isPlainObject(tc)) {
|
|
106
|
+
toolCalls.push(buildToolCallChunk(tc,
|
|
107
|
+
/* includeIndex */ false));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const usage = LLMResult.extractUsage(chunk);
|
|
113
|
+
const id = optionalStrAttr(chunk, "id");
|
|
114
|
+
const name = optionalStrAttr(chunk, "name");
|
|
115
|
+
const responseMetadata = optionalJsonDictAttr(chunk, "response_metadata");
|
|
116
|
+
const additionalKwargs = optionalJsonDictAttr(chunk, "additional_kwargs");
|
|
117
|
+
// Emit camelCase keys to match the sdk-core `LLMStreamChunk` contract.
|
|
118
|
+
// (Python's LLMStreamChunk uses snake_case fields, but the TS model is
|
|
119
|
+
// camelCase — the port must translate, not copy Python's key names.)
|
|
120
|
+
return {
|
|
121
|
+
...(content !== "" ? { content } : {}),
|
|
122
|
+
...(toolCalls && toolCalls.length > 0 ? { toolCalls } : {}),
|
|
123
|
+
...(usage !== undefined ? { usage } : {}),
|
|
124
|
+
...(id !== undefined ? { id } : {}),
|
|
125
|
+
...(name !== undefined ? { name } : {}),
|
|
126
|
+
...(responseMetadata !== undefined ? { responseMetadata } : {}),
|
|
127
|
+
...(additionalKwargs !== undefined ? { additionalKwargs } : {}),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function buildToolCallChunk(data, includeIndex) {
|
|
131
|
+
const id = data["id"];
|
|
132
|
+
const name = data["name"];
|
|
133
|
+
const type = data["type"];
|
|
134
|
+
const index = data["index"];
|
|
135
|
+
const argsRaw = data["args"];
|
|
136
|
+
const args = argsRaw !== undefined && argsRaw !== null
|
|
137
|
+
? normalizeToolCallArgs(argsRaw)
|
|
138
|
+
: null;
|
|
139
|
+
return {
|
|
140
|
+
...(typeof id === "string" ? { id } : {}),
|
|
141
|
+
...(typeof name === "string" ? { name } : {}),
|
|
142
|
+
...(args !== null ? { args } : {}),
|
|
143
|
+
...(typeof type === "string" ? { type } : {}),
|
|
144
|
+
...(includeIndex && typeof index === "number" ? { index } : {}),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function coerceToDict(tc) {
|
|
148
|
+
if (isPlainObject(tc))
|
|
149
|
+
return tc;
|
|
150
|
+
// LangChain.js sometimes ships Pydantic-style class instances; honour them
|
|
151
|
+
// when they expose a `toDict()` / `toJSON()` accessor like the Python original.
|
|
152
|
+
if (tc !== null && typeof tc === "object") {
|
|
153
|
+
const obj = tc;
|
|
154
|
+
if (typeof obj.toDict === "function") {
|
|
155
|
+
const result = obj.toDict();
|
|
156
|
+
return isPlainObject(result)
|
|
157
|
+
? result
|
|
158
|
+
: undefined;
|
|
159
|
+
}
|
|
160
|
+
if (typeof obj.toJSON === "function") {
|
|
161
|
+
const result = obj.toJSON();
|
|
162
|
+
return isPlainObject(result)
|
|
163
|
+
? result
|
|
164
|
+
: undefined;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
function isPlainObject(value) {
|
|
170
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
171
|
+
}
|
|
172
|
+
function isPromise(value) {
|
|
173
|
+
return (value !== null &&
|
|
174
|
+
typeof value === "object" &&
|
|
175
|
+
typeof value.then === "function");
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=llm_adapter.js.map
|