@agentskit/adapters 0.16.0 → 0.17.0

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.
@@ -0,0 +1,232 @@
1
+ 'use strict';
2
+
3
+ var chat_models = require('@langchain/core/language_models/chat_models');
4
+ var messages = require('@langchain/core/messages');
5
+ var outputs = require('@langchain/core/outputs');
6
+ var function_calling = require('@langchain/core/utils/function_calling');
7
+
8
+ // src/langchain-bridge.ts
9
+ function contentText(content) {
10
+ if (typeof content === "string") return content;
11
+ return content.map((part) => typeof part === "object" && part !== null && "text" in part && typeof part.text === "string" ? part.text : "").filter(Boolean).join("\n");
12
+ }
13
+ function toolCallArgs(args) {
14
+ if (typeof args === "string") {
15
+ try {
16
+ const parsed = JSON.parse(args);
17
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : { value: parsed };
18
+ } catch {
19
+ return {};
20
+ }
21
+ }
22
+ return args && typeof args === "object" && !Array.isArray(args) ? args : {};
23
+ }
24
+ function toAgentsKitMessages(messages) {
25
+ const createdAt = /* @__PURE__ */ new Date();
26
+ const output = [];
27
+ const systemParts = [];
28
+ messages.forEach((message, index) => {
29
+ const type = message.type;
30
+ const id = message.id ?? `lc-${type}-${index}`;
31
+ if (type === "system") {
32
+ const content = contentText(message.content);
33
+ systemParts.push(content);
34
+ output.push({ id, role: "system", content, status: "complete", createdAt });
35
+ return;
36
+ }
37
+ if (type === "ai") {
38
+ const ai = message;
39
+ output.push({
40
+ id,
41
+ role: "assistant",
42
+ content: contentText(ai.content),
43
+ status: "complete",
44
+ createdAt,
45
+ toolCalls: ai.tool_calls?.map((call, callIndex) => ({
46
+ id: call.id ?? `${id}-call-${callIndex}`,
47
+ name: call.name,
48
+ args: toolCallArgs(call.args),
49
+ status: "complete"
50
+ }))
51
+ });
52
+ return;
53
+ }
54
+ if (type === "tool") {
55
+ const toolCallId = message.tool_call_id;
56
+ output.push({ id, role: "tool", content: contentText(message.content), status: "complete", createdAt, toolCallId });
57
+ return;
58
+ }
59
+ output.push({ id, role: "user", content: contentText(message.content), status: "complete", createdAt });
60
+ });
61
+ return { messages: output, systemPrompt: systemParts.length > 0 ? systemParts.join("\n\n") : void 0 };
62
+ }
63
+ function toToolDefinitions(tools) {
64
+ if (!tools || tools.length === 0) return void 0;
65
+ return tools.map((tool) => {
66
+ const converted = function_calling.convertToOpenAITool(tool);
67
+ const fn = converted.function;
68
+ return {
69
+ name: fn.name,
70
+ description: fn.description,
71
+ schema: fn.parameters ?? { type: "object", properties: {} }
72
+ };
73
+ });
74
+ }
75
+ function usageMetadata(chunk) {
76
+ if (!chunk.usage) return void 0;
77
+ return {
78
+ input_tokens: chunk.usage.promptTokens,
79
+ output_tokens: chunk.usage.completionTokens,
80
+ total_tokens: chunk.usage.totalTokens
81
+ };
82
+ }
83
+ function invalidToolCall(call, error) {
84
+ return { id: call.id, name: call.name, args: call.args, error, type: "invalid_tool_call" };
85
+ }
86
+ var AgentsKitChatModel = class _AgentsKitChatModel extends chat_models.BaseChatModel {
87
+ constructor(adapter, options = {}) {
88
+ const { modelName, context, profile, ...params } = options;
89
+ super(params);
90
+ this.lc_namespace = ["agentskit", "adapters", "langchain_bridge"];
91
+ this.lc_serializable = false;
92
+ this.adapter = adapter;
93
+ this.modelName = modelName ?? "agentskit";
94
+ this.baseContext = context ?? {};
95
+ this.profileOverride = profile;
96
+ }
97
+ static lc_name() {
98
+ return "AgentsKitChatModel";
99
+ }
100
+ _llmType() {
101
+ return "agentskit";
102
+ }
103
+ get profile() {
104
+ return { toolCalling: this.adapter.capabilities?.tools !== false, ...this.profileOverride };
105
+ }
106
+ bindTools(tools, kwargs) {
107
+ return this.withConfig({ tools, ...kwargs });
108
+ }
109
+ invocationParams(options) {
110
+ return {
111
+ model: this.modelName,
112
+ tools: toToolDefinitions(options?.tools)?.map((tool) => ({ name: tool.name, description: tool.description })),
113
+ tool_choice: options?.tool_choice
114
+ };
115
+ }
116
+ getLsParams(options) {
117
+ return {
118
+ ls_provider: "agentskit",
119
+ ls_model_name: this.modelName,
120
+ ls_model_type: "chat",
121
+ ls_temperature: this.baseContext.temperature,
122
+ ls_max_tokens: this.baseContext.maxTokens,
123
+ ls_stop: options.stop
124
+ };
125
+ }
126
+ buildRequest(messages, options) {
127
+ const { messages: converted, systemPrompt } = toAgentsKitMessages(messages);
128
+ const tools = toToolDefinitions(options.tools);
129
+ const metadata = options.tool_choice === void 0 ? this.baseContext.metadata : { ...this.baseContext.metadata, toolChoice: options.tool_choice };
130
+ const context = { ...this.baseContext, systemPrompt, tools, metadata };
131
+ return { messages: converted, context };
132
+ }
133
+ async *chunks(messages, options) {
134
+ const source = this.adapter.createSource(this.buildRequest(messages, options));
135
+ const signal = options.signal;
136
+ const onAbort = () => source.abort();
137
+ if (signal?.aborted) {
138
+ source.abort();
139
+ throw signal.reason instanceof Error ? signal.reason : new Error("Aborted");
140
+ }
141
+ signal?.addEventListener("abort", onAbort, { once: true });
142
+ try {
143
+ for await (const chunk of source.stream()) {
144
+ if (chunk.type === "error") {
145
+ const cause = chunk.metadata?.error;
146
+ throw cause instanceof Error ? cause : new Error(chunk.content ?? "AgentsKit adapter stream failed");
147
+ }
148
+ if (chunk.type === "done") return;
149
+ yield chunk;
150
+ }
151
+ } finally {
152
+ signal?.removeEventListener("abort", onAbort);
153
+ }
154
+ }
155
+ static collect(response, chunk) {
156
+ if (chunk.metadata) Object.assign(response.metadata, chunk.metadata);
157
+ switch (chunk.type) {
158
+ case "text":
159
+ response.text += chunk.content ?? "";
160
+ break;
161
+ case "reasoning":
162
+ response.reasoning += chunk.content ?? "";
163
+ break;
164
+ case "tool_call":
165
+ if (!chunk.toolCall) break;
166
+ try {
167
+ response.toolCalls.push({ id: chunk.toolCall.id, name: chunk.toolCall.name, args: toolCallArgs(chunk.toolCall.args), type: "tool_call" });
168
+ } catch (error) {
169
+ response.invalidToolCalls.push(invalidToolCall(chunk.toolCall, error instanceof Error ? error.message : String(error)));
170
+ }
171
+ break;
172
+ case "usage":
173
+ response.usage = usageMetadata(chunk);
174
+ break;
175
+ }
176
+ }
177
+ async _generate(messages$1, options, runManager) {
178
+ const response = { text: "", reasoning: "", toolCalls: [], invalidToolCalls: [], metadata: {} };
179
+ for await (const chunk of this.chunks(messages$1, options)) {
180
+ _AgentsKitChatModel.collect(response, chunk);
181
+ if (chunk.type === "text" && chunk.content) await runManager?.handleLLMNewToken(chunk.content);
182
+ }
183
+ const message = new messages.AIMessage({
184
+ content: response.text,
185
+ tool_calls: response.toolCalls,
186
+ invalid_tool_calls: response.invalidToolCalls,
187
+ usage_metadata: response.usage,
188
+ additional_kwargs: response.reasoning ? { reasoning: response.reasoning } : {},
189
+ response_metadata: { ...response.metadata, model_name: this.modelName }
190
+ });
191
+ return {
192
+ generations: [{ text: response.text, message }],
193
+ llmOutput: response.usage ? { tokenUsage: { promptTokens: response.usage.input_tokens, completionTokens: response.usage.output_tokens, totalTokens: response.usage.total_tokens } } : {}
194
+ };
195
+ }
196
+ async *_streamResponseChunks(messages$1, options, runManager) {
197
+ let toolCallIndex = 0;
198
+ for await (const chunk of this.chunks(messages$1, options)) {
199
+ let message;
200
+ if (chunk.type === "text") {
201
+ message = new messages.AIMessageChunk({ content: chunk.content ?? "", response_metadata: chunk.metadata ?? {} });
202
+ } else if (chunk.type === "reasoning") {
203
+ message = new messages.AIMessageChunk({ content: "", additional_kwargs: { reasoning: chunk.content ?? "" } });
204
+ } else if (chunk.type === "tool_call" && chunk.toolCall) {
205
+ message = new messages.AIMessageChunk({
206
+ content: "",
207
+ tool_call_chunks: [{
208
+ id: chunk.toolCall.id,
209
+ name: chunk.toolCall.name,
210
+ args: typeof chunk.toolCall.args === "string" ? chunk.toolCall.args : JSON.stringify(chunk.toolCall.args ?? {}),
211
+ index: toolCallIndex++,
212
+ type: "tool_call_chunk"
213
+ }]
214
+ });
215
+ } else if (chunk.type === "usage") {
216
+ message = new messages.AIMessageChunk({ content: "", usage_metadata: usageMetadata(chunk) });
217
+ }
218
+ if (!message) continue;
219
+ const generation = new outputs.ChatGenerationChunk({ message, text: chunk.type === "text" ? chunk.content ?? "" : "" });
220
+ yield generation;
221
+ if (chunk.type === "text" && chunk.content) await runManager?.handleLLMNewToken(chunk.content, void 0, void 0, void 0, void 0, { chunk: generation });
222
+ }
223
+ }
224
+ };
225
+ function adapterToLangChainModel(adapter, options) {
226
+ return new AgentsKitChatModel(adapter, options);
227
+ }
228
+
229
+ exports.AgentsKitChatModel = AgentsKitChatModel;
230
+ exports.adapterToLangChainModel = adapterToLangChainModel;
231
+ //# sourceMappingURL=langchain-bridge.cjs.map
232
+ //# sourceMappingURL=langchain-bridge.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/langchain-bridge.ts"],"names":["convertToOpenAITool","BaseChatModel","messages","AIMessage","AIMessageChunk","ChatGenerationChunk"],"mappings":";;;;;;;;AAsDA,SAAS,YAAY,OAAA,EAAyC;AAC5D,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,OAAA;AACxC,EAAA,OAAO,OAAA,CACJ,IAAI,CAAA,IAAA,KAAS,OAAO,SAAS,QAAA,IAAY,IAAA,KAAS,IAAA,IAAQ,MAAA,IAAU,IAAA,IAAQ,OAAO,KAAK,IAAA,KAAS,QAAA,GAAW,KAAK,IAAA,GAAO,EAAG,EAC3H,MAAA,CAAO,OAAO,CAAA,CACd,IAAA,CAAK,IAAI,CAAA;AACd;AAEA,SAAS,aAAa,IAAA,EAAwC;AAC5D,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAkB,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AACvC,MAAA,OAAO,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAK,MAAA,GAAqC,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,IAChI,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AACA,EAAA,OAAO,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,CAAC,MAAM,OAAA,CAAQ,IAAI,CAAA,GAAK,IAAA,GAAmC,EAAC;AACzG;AAEA,SAAS,oBAAoB,QAAA,EAAyE;AACpG,EAAA,MAAM,SAAA,uBAAgB,IAAA,EAAK;AAC3B,EAAA,MAAM,SAAoB,EAAC;AAC3B,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,EAAS,KAAA,KAAU;AACnC,IAAA,MAAM,OAAO,OAAA,CAAQ,IAAA;AACrB,IAAA,MAAM,KAAK,OAAA,CAAQ,EAAA,IAAM,CAAA,GAAA,EAAM,IAAI,IAAI,KAAK,CAAA,CAAA;AAC5C,IAAA,IAAI,SAAS,QAAA,EAAU;AACrB,MAAA,MAAM,OAAA,GAAU,WAAA,CAAY,OAAA,CAAQ,OAAO,CAAA;AAC3C,MAAA,WAAA,CAAY,KAAK,OAAO,CAAA;AACxB,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,UAAU,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAY,SAAA,EAAW,CAAA;AAC1E,MAAA;AAAA,IACF;AACA,IAAA,IAAI,SAAS,IAAA,EAAM;AACjB,MAAA,MAAM,EAAA,GAAK,OAAA;AACX,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,EAAA;AAAA,QACA,IAAA,EAAM,WAAA;AAAA,QACN,OAAA,EAAS,WAAA,CAAY,EAAA,CAAG,OAAO,CAAA;AAAA,QAC/B,MAAA,EAAQ,UAAA;AAAA,QACR,SAAA;AAAA,QACA,WAAW,EAAA,CAAG,UAAA,EAAY,GAAA,CAAI,CAAC,MAAM,SAAA,MAAe;AAAA,UAClD,IAAI,IAAA,CAAK,EAAA,IAAM,CAAA,EAAG,EAAE,SAAS,SAAS,CAAA,CAAA;AAAA,UACtC,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,IAAA,EAAM,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA;AAAA,UAC5B,MAAA,EAAQ;AAAA,SACV,CAAE;AAAA,OACH,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,MAAA,MAAM,aAAc,OAAA,CAAsC,YAAA;AAC1D,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,QAAQ,OAAA,EAAS,WAAA,CAAY,OAAA,CAAQ,OAAO,CAAA,EAAG,MAAA,EAAQ,UAAA,EAAY,SAAA,EAAW,YAAY,CAAA;AAClH,MAAA;AAAA,IACF;AACA,IAAA,MAAA,CAAO,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,WAAA,CAAY,OAAA,CAAQ,OAAO,CAAA,EAAG,MAAA,EAAQ,UAAA,EAAY,WAAW,CAAA;AAAA,EACxG,CAAC,CAAA;AACD,EAAA,OAAO,EAAE,QAAA,EAAU,MAAA,EAAQ,YAAA,EAAc,WAAA,CAAY,MAAA,GAAS,CAAA,GAAI,WAAA,CAAY,IAAA,CAAK,MAAM,CAAA,GAAI,MAAA,EAAU;AACzG;AAEA,SAAS,kBAAkB,KAAA,EAA4E;AACrG,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,MAAA,KAAW,GAAG,OAAO,MAAA;AACzC,EAAA,OAAO,KAAA,CAAM,IAAI,CAAA,IAAA,KAAQ;AACvB,IAAA,MAAM,SAAA,GAAYA,qCAAoB,IAAiD,CAAA;AACvF,IAAA,MAAM,KAAK,SAAA,CAAU,QAAA;AACrB,IAAA,OAAO;AAAA,MACL,MAAM,EAAA,CAAG,IAAA;AAAA,MACT,aAAa,EAAA,CAAG,WAAA;AAAA,MAChB,MAAA,EAAS,GAAG,UAAA,IAAc,EAAE,MAAM,QAAA,EAAU,UAAA,EAAY,EAAC;AAAE,KAC7D;AAAA,EACF,CAAC,CAAA;AACH;AAEA,SAAS,cAAc,KAAA,EAA+C;AACpE,EAAA,IAAI,CAAC,KAAA,CAAM,KAAA,EAAO,OAAO,MAAA;AACzB,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,MAAM,KAAA,CAAM,YAAA;AAAA,IAC1B,aAAA,EAAe,MAAM,KAAA,CAAM,gBAAA;AAAA,IAC3B,YAAA,EAAc,MAAM,KAAA,CAAM;AAAA,GAC5B;AACF;AAEA,SAAS,eAAA,CAAgB,MAA4C,KAAA,EAAgC;AACnG,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,CAAK,EAAA,EAAI,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,mBAAA,EAAoB;AAC3F;AAYO,IAAM,kBAAA,GAAN,MAAM,mBAAA,SAA2BC,yBAAA,CAA6C;AAAA,EAanF,WAAA,CAAY,OAAA,EAAyB,OAAA,GAA0C,EAAC,EAAG;AACjF,IAAA,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,OAAA,EAAS,GAAG,QAAO,GAAI,OAAA;AACnD,IAAA,KAAA,CAAM,MAAM,CAAA;AAVd,IAAA,IAAA,CAAS,YAAA,GAAe,CAAC,WAAA,EAAa,UAAA,EAAY,kBAAkB,CAAA;AACpE,IAAA,IAAA,CAAS,eAAA,GAAkB,KAAA;AAUzB,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,IAAA,IAAA,CAAK,YAAY,SAAA,IAAa,WAAA;AAC9B,IAAA,IAAA,CAAK,WAAA,GAAc,WAAW,EAAC;AAC/B,IAAA,IAAA,CAAK,eAAA,GAAkB,OAAA;AAAA,EACzB;AAAA,EAnBA,OAAgB,OAAA,GAAkB;AAChC,IAAA,OAAO,oBAAA;AAAA,EACT;AAAA,EAmBA,QAAA,GAAmB;AACjB,IAAA,OAAO,WAAA;AAAA,EACT;AAAA,EAEA,IAAa,OAAA,GAAwB;AACnC,IAAA,OAAO,EAAE,aAAa,IAAA,CAAK,OAAA,CAAQ,cAAc,KAAA,KAAU,KAAA,EAAO,GAAG,IAAA,CAAK,eAAA,EAAgB;AAAA,EAC5F;AAAA,EAES,SAAA,CACP,OACA,MAAA,EACiF;AACjF,IAAA,OAAO,KAAK,UAAA,CAAW,EAAE,KAAA,EAAO,GAAG,QAAQ,CAAA;AAAA,EAC7C;AAAA,EAES,iBAAiB,OAAA,EAA8D;AACtF,IAAA,OAAO;AAAA,MACL,OAAO,IAAA,CAAK,SAAA;AAAA,MACZ,KAAA,EAAO,iBAAA,CAAkB,OAAA,EAAS,KAAK,GAAG,GAAA,CAAI,CAAA,IAAA,MAAS,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,WAAA,EAAa,IAAA,CAAK,aAAY,CAAE,CAAA;AAAA,MAC1G,aAAa,OAAA,EAAS;AAAA,KACxB;AAAA,EACF;AAAA,EAES,YAAY,OAAA,EAAqD;AACxE,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,WAAA;AAAA,MACb,eAAe,IAAA,CAAK,SAAA;AAAA,MACpB,aAAA,EAAe,MAAA;AAAA,MACf,cAAA,EAAgB,KAAK,WAAA,CAAY,WAAA;AAAA,MACjC,aAAA,EAAe,KAAK,WAAA,CAAY,SAAA;AAAA,MAChC,SAAS,OAAA,CAAQ;AAAA,KACnB;AAAA,EACF;AAAA,EAEQ,YAAA,CAAa,UAAyB,OAAA,EAAoD;AAChG,IAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,YAAA,EAAa,GAAI,oBAAoB,QAAQ,CAAA;AAC1E,IAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,OAAA,CAAQ,KAAK,CAAA;AAC7C,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,WAAA,KAAgB,MAAA,GACrC,KAAK,WAAA,CAAY,QAAA,GACjB,EAAE,GAAG,IAAA,CAAK,WAAA,CAAY,QAAA,EAAU,UAAA,EAAY,QAAQ,WAAA,EAAY;AACpE,IAAA,MAAM,UAA0B,EAAE,GAAG,KAAK,WAAA,EAAa,YAAA,EAAc,OAAO,QAAA,EAAS;AACrF,IAAA,OAAO,EAAE,QAAA,EAAU,SAAA,EAAW,OAAA,EAAQ;AAAA,EACxC;AAAA,EAEA,OAAe,MAAA,CAAO,QAAA,EAAyB,OAAA,EAAwE;AACrH,IAAA,MAAM,MAAA,GAAS,KAAK,OAAA,CAAQ,YAAA,CAAa,KAAK,YAAA,CAAa,QAAA,EAAU,OAAO,CAAC,CAAA;AAC7E,IAAA,MAAM,SAAS,OAAA,CAAQ,MAAA;AACvB,IAAA,MAAM,OAAA,GAAU,MAAY,MAAA,CAAO,KAAA,EAAM;AACzC,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,MAAA,CAAO,KAAA,EAAM;AACb,MAAA,MAAM,OAAO,MAAA,YAAkB,KAAA,GAAQ,OAAO,MAAA,GAAS,IAAI,MAAM,SAAS,CAAA;AAAA,IAC5E;AACA,IAAA,MAAA,EAAQ,iBAAiB,OAAA,EAAS,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AACzD,IAAA,IAAI;AACF,MAAA,WAAA,MAAiB,KAAA,IAAS,MAAA,CAAO,MAAA,EAAO,EAAG;AACzC,QAAA,IAAI,KAAA,CAAM,SAAS,OAAA,EAAS;AAC1B,UAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,EAAU,KAAA;AAC9B,UAAA,MAAM,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,KAAA,CAAM,WAAW,iCAAiC,CAAA;AAAA,QACrG;AACA,QAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AAC3B,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAA,EAAQ,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,OAAe,OAAA,CAAQ,QAAA,EAA6B,KAAA,EAA0B;AAC5E,IAAA,IAAI,MAAM,QAAA,EAAU,MAAA,CAAO,OAAO,QAAA,CAAS,QAAA,EAAU,MAAM,QAAQ,CAAA;AACnE,IAAA,QAAQ,MAAM,IAAA;AAAM,MAClB,KAAK,MAAA;AACH,QAAA,QAAA,CAAS,IAAA,IAAQ,MAAM,OAAA,IAAW,EAAA;AAClC,QAAA;AAAA,MACF,KAAK,WAAA;AACH,QAAA,QAAA,CAAS,SAAA,IAAa,MAAM,OAAA,IAAW,EAAA;AACvC,QAAA;AAAA,MACF,KAAK,WAAA;AACH,QAAA,IAAI,CAAC,MAAM,QAAA,EAAU;AACrB,QAAA,IAAI;AACF,UAAA,QAAA,CAAS,UAAU,IAAA,CAAK,EAAE,IAAI,KAAA,CAAM,QAAA,CAAS,IAAI,IAAA,EAAM,KAAA,CAAM,SAAS,IAAA,EAAM,IAAA,EAAM,aAAa,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA,EAAG,IAAA,EAAM,aAAa,CAAA;AAAA,QAC1I,SAAS,KAAA,EAAO;AACd,UAAA,QAAA,CAAS,gBAAA,CAAiB,IAAA,CAAK,eAAA,CAAgB,KAAA,CAAM,QAAA,EAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA;AAAA,QACxH;AACA,QAAA;AAAA,MACF,KAAK,OAAA;AACH,QAAA,QAAA,CAAS,KAAA,GAAQ,cAAc,KAAK,CAAA;AACpC,QAAA;AAEA;AACJ,EACF;AAAA,EAEA,MAAM,SAAA,CACJC,UAAA,EACA,OAAA,EACA,UAAA,EACqB;AACrB,IAAA,MAAM,QAAA,GAA8B,EAAE,IAAA,EAAM,EAAA,EAAI,WAAW,EAAA,EAAI,SAAA,EAAW,EAAC,EAAG,gBAAA,EAAkB,EAAC,EAAG,QAAA,EAAU,EAAC,EAAE;AACjH,IAAA,WAAA,MAAiB,KAAA,IAAS,IAAA,CAAK,MAAA,CAAOA,UAAA,EAAU,OAAO,CAAA,EAAG;AACxD,MAAA,mBAAA,CAAmB,OAAA,CAAQ,UAAU,KAAK,CAAA;AAC1C,MAAA,IAAI,KAAA,CAAM,SAAS,MAAA,IAAU,KAAA,CAAM,SAAS,MAAM,UAAA,EAAY,iBAAA,CAAkB,KAAA,CAAM,OAAO,CAAA;AAAA,IAC/F;AACA,IAAA,MAAM,OAAA,GAAU,IAAIC,kBAAA,CAAU;AAAA,MAC5B,SAAS,QAAA,CAAS,IAAA;AAAA,MAClB,YAAY,QAAA,CAAS,SAAA;AAAA,MACrB,oBAAoB,QAAA,CAAS,gBAAA;AAAA,MAC7B,gBAAgB,QAAA,CAAS,KAAA;AAAA,MACzB,iBAAA,EAAmB,SAAS,SAAA,GAAY,EAAE,WAAW,QAAA,CAAS,SAAA,KAAc,EAAC;AAAA,MAC7E,mBAAmB,EAAE,GAAG,SAAS,QAAA,EAAU,UAAA,EAAY,KAAK,SAAA;AAAU,KACvE,CAAA;AACD,IAAA,OAAO;AAAA,MACL,aAAa,CAAC,EAAE,MAAM,QAAA,CAAS,IAAA,EAAM,SAAS,CAAA;AAAA,MAC9C,SAAA,EAAW,SAAS,KAAA,GAAQ,EAAE,YAAY,EAAE,YAAA,EAAc,SAAS,KAAA,CAAM,YAAA,EAAc,kBAAkB,QAAA,CAAS,KAAA,CAAM,eAAe,WAAA,EAAa,QAAA,CAAS,MAAM,YAAA,EAAa,KAAM;AAAC,KACzL;AAAA,EACF;AAAA,EAEA,OAAgB,qBAAA,CACdD,UAAA,EACA,OAAA,EACA,UAAA,EACqC;AACrC,IAAA,IAAI,aAAA,GAAgB,CAAA;AACpB,IAAA,WAAA,MAAiB,KAAA,IAAS,IAAA,CAAK,MAAA,CAAOA,UAAA,EAAU,OAAO,CAAA,EAAG;AACxD,MAAA,IAAI,OAAA;AACJ,MAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AACzB,QAAA,OAAA,GAAU,IAAIE,uBAAA,CAAe,EAAE,OAAA,EAAS,KAAA,CAAM,OAAA,IAAW,EAAA,EAAI,iBAAA,EAAmB,KAAA,CAAM,QAAA,IAAY,EAAC,EAAG,CAAA;AAAA,MACxG,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,WAAA,EAAa;AACrC,QAAA,OAAA,GAAU,IAAIA,uBAAA,CAAe,EAAE,OAAA,EAAS,EAAA,EAAI,iBAAA,EAAmB,EAAE,SAAA,EAAW,KAAA,CAAM,OAAA,IAAW,EAAA,EAAG,EAAG,CAAA;AAAA,MACrG,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,WAAA,IAAe,MAAM,QAAA,EAAU;AACvD,QAAA,OAAA,GAAU,IAAIA,uBAAA,CAAe;AAAA,UAC3B,OAAA,EAAS,EAAA;AAAA,UACT,kBAAkB,CAAC;AAAA,YACjB,EAAA,EAAI,MAAM,QAAA,CAAS,EAAA;AAAA,YACnB,IAAA,EAAM,MAAM,QAAA,CAAS,IAAA;AAAA,YACrB,IAAA,EAAM,OAAO,KAAA,CAAM,QAAA,CAAS,SAAS,QAAA,GAAW,KAAA,CAAM,QAAA,CAAS,IAAA,GAAO,KAAK,SAAA,CAAU,KAAA,CAAM,QAAA,CAAS,IAAA,IAAQ,EAAE,CAAA;AAAA,YAC9G,KAAA,EAAO,aAAA,EAAA;AAAA,YACP,IAAA,EAAM;AAAA,WACP;AAAA,SACF,CAAA;AAAA,MACH,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,OAAA,EAAS;AACjC,QAAA,OAAA,GAAU,IAAIA,wBAAe,EAAE,OAAA,EAAS,IAAI,cAAA,EAAgB,aAAA,CAAc,KAAK,CAAA,EAAG,CAAA;AAAA,MACpF;AACA,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,MAAM,UAAA,GAAa,IAAIC,2BAAA,CAAoB,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,CAAM,IAAA,KAAS,MAAA,GAAS,KAAA,CAAM,OAAA,IAAW,EAAA,GAAK,IAAI,CAAA;AAC9G,MAAA,MAAM,UAAA;AACN,MAAA,IAAI,MAAM,IAAA,KAAS,MAAA,IAAU,KAAA,CAAM,OAAA,QAAe,UAAA,EAAY,iBAAA,CAAkB,KAAA,CAAM,OAAA,EAAS,QAAW,MAAA,EAAW,MAAA,EAAW,QAAW,EAAE,KAAA,EAAO,YAAY,CAAA;AAAA,IAClK;AAAA,EACF;AACF;AAiBO,SAAS,uBAAA,CAAwB,SAAyB,OAAA,EAA8D;AAC7H,EAAA,OAAO,IAAI,kBAAA,CAAmB,OAAA,EAAS,OAAO,CAAA;AAChD","file":"langchain-bridge.cjs","sourcesContent":["import type { AdapterContext, AdapterFactory, AdapterRequest, Message, StreamChunk, ToolDefinition } from '@agentskit/core'\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager'\nimport {\n BaseChatModel,\n type BaseChatModelCallOptions,\n type BaseChatModelParams,\n type BindToolsInput,\n type LangSmithParams,\n} from '@langchain/core/language_models/chat_models'\nimport type { ModelProfile } from '@langchain/core/language_models/profile'\nimport type { BaseLanguageModelInput } from '@langchain/core/language_models/base'\nimport {\n AIMessage,\n AIMessageChunk,\n type BaseMessage,\n type InvalidToolCall,\n type ToolCall as LangChainToolCall,\n type UsageMetadata,\n} from '@langchain/core/messages'\nimport { ChatGenerationChunk, type ChatResult } from '@langchain/core/outputs'\nimport type { Runnable } from '@langchain/core/runnables'\nimport { convertToOpenAITool } from '@langchain/core/utils/function_calling'\n\n/**\n * Call options accepted by the bridged model. `tools` and `tool_choice` are\n * populated by `bindTools()` and by LangChain's agent machinery.\n */\nexport interface AgentsKitChatModelCallOptions extends BaseChatModelCallOptions {\n tools?: BindToolsInput[]\n}\n\nexport interface AdapterToLangChainModelOptions extends BaseChatModelParams {\n /** Reported as the LangSmith model name and `_llmType()` suffix. Default: `agentskit`. */\n modelName?: string\n /** Static `AdapterContext` fields (temperature, maxTokens, metadata) sent with every request. */\n context?: Omit<AdapterContext, 'systemPrompt' | 'tools'>\n /**\n * LangChain model profile. Defaults to `toolCalling` from the adapter's\n * capabilities (assumed supported when unknown) and no native\n * `structuredOutput`, so `createAgent({ responseFormat })` uses its tool\n * strategy, which every tool-calling adapter can satisfy.\n */\n profile?: ModelProfile\n}\n\ninterface CollectedResponse {\n text: string\n reasoning: string\n toolCalls: LangChainToolCall[]\n invalidToolCalls: InvalidToolCall[]\n usage?: UsageMetadata\n metadata: Record<string, unknown>\n}\n\nfunction contentText(content: BaseMessage['content']): string {\n if (typeof content === 'string') return content\n return content\n .map(part => (typeof part === 'object' && part !== null && 'text' in part && typeof part.text === 'string' ? part.text : ''))\n .filter(Boolean)\n .join('\\n')\n}\n\nfunction toolCallArgs(args: unknown): Record<string, unknown> {\n if (typeof args === 'string') {\n try {\n const parsed: unknown = JSON.parse(args)\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? (parsed as Record<string, unknown>) : { value: parsed }\n } catch {\n return {}\n }\n }\n return args && typeof args === 'object' && !Array.isArray(args) ? (args as Record<string, unknown>) : {}\n}\n\nfunction toAgentsKitMessages(messages: BaseMessage[]): { messages: Message[]; systemPrompt?: string } {\n const createdAt = new Date()\n const output: Message[] = []\n const systemParts: string[] = []\n messages.forEach((message, index) => {\n const type = message.type\n const id = message.id ?? `lc-${type}-${index}`\n if (type === 'system') {\n const content = contentText(message.content)\n systemParts.push(content)\n output.push({ id, role: 'system', content, status: 'complete', createdAt })\n return\n }\n if (type === 'ai') {\n const ai = message as AIMessage\n output.push({\n id,\n role: 'assistant',\n content: contentText(ai.content),\n status: 'complete',\n createdAt,\n toolCalls: ai.tool_calls?.map((call, callIndex) => ({\n id: call.id ?? `${id}-call-${callIndex}`,\n name: call.name,\n args: toolCallArgs(call.args),\n status: 'complete' as const,\n })),\n })\n return\n }\n if (type === 'tool') {\n const toolCallId = (message as { tool_call_id?: string }).tool_call_id\n output.push({ id, role: 'tool', content: contentText(message.content), status: 'complete', createdAt, toolCallId })\n return\n }\n output.push({ id, role: 'user', content: contentText(message.content), status: 'complete', createdAt })\n })\n return { messages: output, systemPrompt: systemParts.length > 0 ? systemParts.join('\\n\\n') : undefined }\n}\n\nfunction toToolDefinitions(tools: readonly BindToolsInput[] | undefined): ToolDefinition[] | undefined {\n if (!tools || tools.length === 0) return undefined\n return tools.map(tool => {\n const converted = convertToOpenAITool(tool as Parameters<typeof convertToOpenAITool>[0])\n const fn = converted.function\n return {\n name: fn.name,\n description: fn.description,\n schema: (fn.parameters ?? { type: 'object', properties: {} }) as ToolDefinition['schema'],\n }\n })\n}\n\nfunction usageMetadata(chunk: StreamChunk): UsageMetadata | undefined {\n if (!chunk.usage) return undefined\n return {\n input_tokens: chunk.usage.promptTokens,\n output_tokens: chunk.usage.completionTokens,\n total_tokens: chunk.usage.totalTokens,\n }\n}\n\nfunction invalidToolCall(call: NonNullable<StreamChunk['toolCall']>, error: string): InvalidToolCall {\n return { id: call.id, name: call.name, args: call.args, error, type: 'invalid_tool_call' }\n}\n\n/**\n * A LangChain `BaseChatModel` backed by any AgentsKit `AdapterFactory`.\n *\n * Drop it into any LangChain `model:` slot (`createAgent`, `AgentNode`, a\n * plain chain). `bindTools()` forwards LangChain tools as AgentsKit\n * `ToolDefinition`s on `context.tools`; `tool_call` chunks come back as\n * `AIMessage.tool_calls` so LangChain's agent loop, middleware, and\n * tool-strategy structured output work unchanged. Every response is a real\n * `AIMessage`/`AIMessageChunk` instance.\n */\nexport class AgentsKitChatModel extends BaseChatModel<AgentsKitChatModelCallOptions> {\n static override lc_name(): string {\n return 'AgentsKitChatModel'\n }\n\n override lc_namespace = ['agentskit', 'adapters', 'langchain_bridge']\n override lc_serializable = false\n\n readonly adapter: AdapterFactory\n readonly modelName: string\n private readonly baseContext: Omit<AdapterContext, 'systemPrompt' | 'tools'>\n private readonly profileOverride?: ModelProfile\n\n constructor(adapter: AdapterFactory, options: AdapterToLangChainModelOptions = {}) {\n const { modelName, context, profile, ...params } = options\n super(params)\n this.adapter = adapter\n this.modelName = modelName ?? 'agentskit'\n this.baseContext = context ?? {}\n this.profileOverride = profile\n }\n\n _llmType(): string {\n return 'agentskit'\n }\n\n override get profile(): ModelProfile {\n return { toolCalling: this.adapter.capabilities?.tools !== false, ...this.profileOverride }\n }\n\n override bindTools(\n tools: BindToolsInput[],\n kwargs?: Partial<AgentsKitChatModelCallOptions>,\n ): Runnable<BaseLanguageModelInput, AIMessageChunk, AgentsKitChatModelCallOptions> {\n return this.withConfig({ tools, ...kwargs })\n }\n\n override invocationParams(options?: this['ParsedCallOptions']): Record<string, unknown> {\n return {\n model: this.modelName,\n tools: toToolDefinitions(options?.tools)?.map(tool => ({ name: tool.name, description: tool.description })),\n tool_choice: options?.tool_choice,\n }\n }\n\n override getLsParams(options: this['ParsedCallOptions']): LangSmithParams {\n return {\n ls_provider: 'agentskit',\n ls_model_name: this.modelName,\n ls_model_type: 'chat',\n ls_temperature: this.baseContext.temperature,\n ls_max_tokens: this.baseContext.maxTokens,\n ls_stop: options.stop,\n }\n }\n\n private buildRequest(messages: BaseMessage[], options: this['ParsedCallOptions']): AdapterRequest {\n const { messages: converted, systemPrompt } = toAgentsKitMessages(messages)\n const tools = toToolDefinitions(options.tools)\n const metadata = options.tool_choice === undefined\n ? this.baseContext.metadata\n : { ...this.baseContext.metadata, toolChoice: options.tool_choice }\n const context: AdapterContext = { ...this.baseContext, systemPrompt, tools, metadata }\n return { messages: converted, context }\n }\n\n private async *chunks(messages: BaseMessage[], options: this['ParsedCallOptions']): AsyncIterableIterator<StreamChunk> {\n const source = this.adapter.createSource(this.buildRequest(messages, options))\n const signal = options.signal\n const onAbort = (): void => source.abort()\n if (signal?.aborted) {\n source.abort()\n throw signal.reason instanceof Error ? signal.reason : new Error('Aborted')\n }\n signal?.addEventListener('abort', onAbort, { once: true })\n try {\n for await (const chunk of source.stream()) {\n if (chunk.type === 'error') {\n const cause = chunk.metadata?.error\n throw cause instanceof Error ? cause : new Error(chunk.content ?? 'AgentsKit adapter stream failed')\n }\n if (chunk.type === 'done') return\n yield chunk\n }\n } finally {\n signal?.removeEventListener('abort', onAbort)\n }\n }\n\n private static collect(response: CollectedResponse, chunk: StreamChunk): void {\n if (chunk.metadata) Object.assign(response.metadata, chunk.metadata)\n switch (chunk.type) {\n case 'text':\n response.text += chunk.content ?? ''\n break\n case 'reasoning':\n response.reasoning += chunk.content ?? ''\n break\n case 'tool_call':\n if (!chunk.toolCall) break\n try {\n response.toolCalls.push({ id: chunk.toolCall.id, name: chunk.toolCall.name, args: toolCallArgs(chunk.toolCall.args), type: 'tool_call' })\n } catch (error) {\n response.invalidToolCalls.push(invalidToolCall(chunk.toolCall, error instanceof Error ? error.message : String(error)))\n }\n break\n case 'usage':\n response.usage = usageMetadata(chunk)\n break\n default:\n break\n }\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun,\n ): Promise<ChatResult> {\n const response: CollectedResponse = { text: '', reasoning: '', toolCalls: [], invalidToolCalls: [], metadata: {} }\n for await (const chunk of this.chunks(messages, options)) {\n AgentsKitChatModel.collect(response, chunk)\n if (chunk.type === 'text' && chunk.content) await runManager?.handleLLMNewToken(chunk.content)\n }\n const message = new AIMessage({\n content: response.text,\n tool_calls: response.toolCalls,\n invalid_tool_calls: response.invalidToolCalls,\n usage_metadata: response.usage,\n additional_kwargs: response.reasoning ? { reasoning: response.reasoning } : {},\n response_metadata: { ...response.metadata, model_name: this.modelName },\n })\n return {\n generations: [{ text: response.text, message }],\n llmOutput: response.usage ? { tokenUsage: { promptTokens: response.usage.input_tokens, completionTokens: response.usage.output_tokens, totalTokens: response.usage.total_tokens } } : {},\n }\n }\n\n override async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun,\n ): AsyncGenerator<ChatGenerationChunk> {\n let toolCallIndex = 0\n for await (const chunk of this.chunks(messages, options)) {\n let message: AIMessageChunk | undefined\n if (chunk.type === 'text') {\n message = new AIMessageChunk({ content: chunk.content ?? '', response_metadata: chunk.metadata ?? {} })\n } else if (chunk.type === 'reasoning') {\n message = new AIMessageChunk({ content: '', additional_kwargs: { reasoning: chunk.content ?? '' } })\n } else if (chunk.type === 'tool_call' && chunk.toolCall) {\n message = new AIMessageChunk({\n content: '',\n tool_call_chunks: [{\n id: chunk.toolCall.id,\n name: chunk.toolCall.name,\n args: typeof chunk.toolCall.args === 'string' ? chunk.toolCall.args : JSON.stringify(chunk.toolCall.args ?? {}),\n index: toolCallIndex++,\n type: 'tool_call_chunk',\n }],\n })\n } else if (chunk.type === 'usage') {\n message = new AIMessageChunk({ content: '', usage_metadata: usageMetadata(chunk) })\n }\n if (!message) continue\n const generation = new ChatGenerationChunk({ message, text: chunk.type === 'text' ? chunk.content ?? '' : '' })\n yield generation\n if (chunk.type === 'text' && chunk.content) await runManager?.handleLLMNewToken(chunk.content, undefined, undefined, undefined, undefined, { chunk: generation })\n }\n }\n}\n\n/**\n * Wraps any AgentsKit `AdapterFactory` (mock, ollama, CLI-backed, ...) as a\n * LangChain `BaseChatModel` so it can replace `ChatAnthropic`/`ChatOpenAI`\n * in `createAgent`, `AgentNode`, or any chain.\n *\n * ```ts\n * import { createAgent } from 'langchain'\n * import { mockAdapter } from '@agentskit/adapters'\n * import { adapterToLangChainModel } from '@agentskit/adapters/langchain-bridge'\n *\n * const agent = createAgent({ model: adapterToLangChainModel(mockAdapter({ response })), tools: [add] })\n * ```\n *\n * Requires `@langchain/core` (optional peer dependency).\n */\nexport function adapterToLangChainModel(adapter: AdapterFactory, options?: AdapterToLangChainModelOptions): AgentsKitChatModel {\n return new AgentsKitChatModel(adapter, options)\n}\n"]}
@@ -0,0 +1,77 @@
1
+ import { AdapterContext, AdapterFactory } from '@agentskit/core';
2
+ import { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
3
+ import { BaseChatModelParams, BaseChatModel, BaseChatModelCallOptions, BindToolsInput, LangSmithParams } from '@langchain/core/language_models/chat_models';
4
+ import { ModelProfile } from '@langchain/core/language_models/profile';
5
+ import { BaseLanguageModelInput } from '@langchain/core/language_models/base';
6
+ import { AIMessageChunk, BaseMessage } from '@langchain/core/messages';
7
+ import { ChatResult, ChatGenerationChunk } from '@langchain/core/outputs';
8
+ import { Runnable } from '@langchain/core/runnables';
9
+
10
+ /**
11
+ * Call options accepted by the bridged model. `tools` and `tool_choice` are
12
+ * populated by `bindTools()` and by LangChain's agent machinery.
13
+ */
14
+ interface AgentsKitChatModelCallOptions extends BaseChatModelCallOptions {
15
+ tools?: BindToolsInput[];
16
+ }
17
+ interface AdapterToLangChainModelOptions extends BaseChatModelParams {
18
+ /** Reported as the LangSmith model name and `_llmType()` suffix. Default: `agentskit`. */
19
+ modelName?: string;
20
+ /** Static `AdapterContext` fields (temperature, maxTokens, metadata) sent with every request. */
21
+ context?: Omit<AdapterContext, 'systemPrompt' | 'tools'>;
22
+ /**
23
+ * LangChain model profile. Defaults to `toolCalling` from the adapter's
24
+ * capabilities (assumed supported when unknown) and no native
25
+ * `structuredOutput`, so `createAgent({ responseFormat })` uses its tool
26
+ * strategy, which every tool-calling adapter can satisfy.
27
+ */
28
+ profile?: ModelProfile;
29
+ }
30
+ /**
31
+ * A LangChain `BaseChatModel` backed by any AgentsKit `AdapterFactory`.
32
+ *
33
+ * Drop it into any LangChain `model:` slot (`createAgent`, `AgentNode`, a
34
+ * plain chain). `bindTools()` forwards LangChain tools as AgentsKit
35
+ * `ToolDefinition`s on `context.tools`; `tool_call` chunks come back as
36
+ * `AIMessage.tool_calls` so LangChain's agent loop, middleware, and
37
+ * tool-strategy structured output work unchanged. Every response is a real
38
+ * `AIMessage`/`AIMessageChunk` instance.
39
+ */
40
+ declare class AgentsKitChatModel extends BaseChatModel<AgentsKitChatModelCallOptions> {
41
+ static lc_name(): string;
42
+ lc_namespace: string[];
43
+ lc_serializable: boolean;
44
+ readonly adapter: AdapterFactory;
45
+ readonly modelName: string;
46
+ private readonly baseContext;
47
+ private readonly profileOverride?;
48
+ constructor(adapter: AdapterFactory, options?: AdapterToLangChainModelOptions);
49
+ _llmType(): string;
50
+ get profile(): ModelProfile;
51
+ bindTools(tools: BindToolsInput[], kwargs?: Partial<AgentsKitChatModelCallOptions>): Runnable<BaseLanguageModelInput, AIMessageChunk, AgentsKitChatModelCallOptions>;
52
+ invocationParams(options?: this['ParsedCallOptions']): Record<string, unknown>;
53
+ getLsParams(options: this['ParsedCallOptions']): LangSmithParams;
54
+ private buildRequest;
55
+ private chunks;
56
+ private static collect;
57
+ _generate(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): Promise<ChatResult>;
58
+ _streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
59
+ }
60
+ /**
61
+ * Wraps any AgentsKit `AdapterFactory` (mock, ollama, CLI-backed, ...) as a
62
+ * LangChain `BaseChatModel` so it can replace `ChatAnthropic`/`ChatOpenAI`
63
+ * in `createAgent`, `AgentNode`, or any chain.
64
+ *
65
+ * ```ts
66
+ * import { createAgent } from 'langchain'
67
+ * import { mockAdapter } from '@agentskit/adapters'
68
+ * import { adapterToLangChainModel } from '@agentskit/adapters/langchain-bridge'
69
+ *
70
+ * const agent = createAgent({ model: adapterToLangChainModel(mockAdapter({ response })), tools: [add] })
71
+ * ```
72
+ *
73
+ * Requires `@langchain/core` (optional peer dependency).
74
+ */
75
+ declare function adapterToLangChainModel(adapter: AdapterFactory, options?: AdapterToLangChainModelOptions): AgentsKitChatModel;
76
+
77
+ export { type AdapterToLangChainModelOptions, AgentsKitChatModel, type AgentsKitChatModelCallOptions, adapterToLangChainModel };
@@ -0,0 +1,77 @@
1
+ import { AdapterContext, AdapterFactory } from '@agentskit/core';
2
+ import { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
3
+ import { BaseChatModelParams, BaseChatModel, BaseChatModelCallOptions, BindToolsInput, LangSmithParams } from '@langchain/core/language_models/chat_models';
4
+ import { ModelProfile } from '@langchain/core/language_models/profile';
5
+ import { BaseLanguageModelInput } from '@langchain/core/language_models/base';
6
+ import { AIMessageChunk, BaseMessage } from '@langchain/core/messages';
7
+ import { ChatResult, ChatGenerationChunk } from '@langchain/core/outputs';
8
+ import { Runnable } from '@langchain/core/runnables';
9
+
10
+ /**
11
+ * Call options accepted by the bridged model. `tools` and `tool_choice` are
12
+ * populated by `bindTools()` and by LangChain's agent machinery.
13
+ */
14
+ interface AgentsKitChatModelCallOptions extends BaseChatModelCallOptions {
15
+ tools?: BindToolsInput[];
16
+ }
17
+ interface AdapterToLangChainModelOptions extends BaseChatModelParams {
18
+ /** Reported as the LangSmith model name and `_llmType()` suffix. Default: `agentskit`. */
19
+ modelName?: string;
20
+ /** Static `AdapterContext` fields (temperature, maxTokens, metadata) sent with every request. */
21
+ context?: Omit<AdapterContext, 'systemPrompt' | 'tools'>;
22
+ /**
23
+ * LangChain model profile. Defaults to `toolCalling` from the adapter's
24
+ * capabilities (assumed supported when unknown) and no native
25
+ * `structuredOutput`, so `createAgent({ responseFormat })` uses its tool
26
+ * strategy, which every tool-calling adapter can satisfy.
27
+ */
28
+ profile?: ModelProfile;
29
+ }
30
+ /**
31
+ * A LangChain `BaseChatModel` backed by any AgentsKit `AdapterFactory`.
32
+ *
33
+ * Drop it into any LangChain `model:` slot (`createAgent`, `AgentNode`, a
34
+ * plain chain). `bindTools()` forwards LangChain tools as AgentsKit
35
+ * `ToolDefinition`s on `context.tools`; `tool_call` chunks come back as
36
+ * `AIMessage.tool_calls` so LangChain's agent loop, middleware, and
37
+ * tool-strategy structured output work unchanged. Every response is a real
38
+ * `AIMessage`/`AIMessageChunk` instance.
39
+ */
40
+ declare class AgentsKitChatModel extends BaseChatModel<AgentsKitChatModelCallOptions> {
41
+ static lc_name(): string;
42
+ lc_namespace: string[];
43
+ lc_serializable: boolean;
44
+ readonly adapter: AdapterFactory;
45
+ readonly modelName: string;
46
+ private readonly baseContext;
47
+ private readonly profileOverride?;
48
+ constructor(adapter: AdapterFactory, options?: AdapterToLangChainModelOptions);
49
+ _llmType(): string;
50
+ get profile(): ModelProfile;
51
+ bindTools(tools: BindToolsInput[], kwargs?: Partial<AgentsKitChatModelCallOptions>): Runnable<BaseLanguageModelInput, AIMessageChunk, AgentsKitChatModelCallOptions>;
52
+ invocationParams(options?: this['ParsedCallOptions']): Record<string, unknown>;
53
+ getLsParams(options: this['ParsedCallOptions']): LangSmithParams;
54
+ private buildRequest;
55
+ private chunks;
56
+ private static collect;
57
+ _generate(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): Promise<ChatResult>;
58
+ _streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
59
+ }
60
+ /**
61
+ * Wraps any AgentsKit `AdapterFactory` (mock, ollama, CLI-backed, ...) as a
62
+ * LangChain `BaseChatModel` so it can replace `ChatAnthropic`/`ChatOpenAI`
63
+ * in `createAgent`, `AgentNode`, or any chain.
64
+ *
65
+ * ```ts
66
+ * import { createAgent } from 'langchain'
67
+ * import { mockAdapter } from '@agentskit/adapters'
68
+ * import { adapterToLangChainModel } from '@agentskit/adapters/langchain-bridge'
69
+ *
70
+ * const agent = createAgent({ model: adapterToLangChainModel(mockAdapter({ response })), tools: [add] })
71
+ * ```
72
+ *
73
+ * Requires `@langchain/core` (optional peer dependency).
74
+ */
75
+ declare function adapterToLangChainModel(adapter: AdapterFactory, options?: AdapterToLangChainModelOptions): AgentsKitChatModel;
76
+
77
+ export { type AdapterToLangChainModelOptions, AgentsKitChatModel, type AgentsKitChatModelCallOptions, adapterToLangChainModel };
@@ -0,0 +1,229 @@
1
+ import { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import { AIMessage, AIMessageChunk } from '@langchain/core/messages';
3
+ import { ChatGenerationChunk } from '@langchain/core/outputs';
4
+ import { convertToOpenAITool } from '@langchain/core/utils/function_calling';
5
+
6
+ // src/langchain-bridge.ts
7
+ function contentText(content) {
8
+ if (typeof content === "string") return content;
9
+ return content.map((part) => typeof part === "object" && part !== null && "text" in part && typeof part.text === "string" ? part.text : "").filter(Boolean).join("\n");
10
+ }
11
+ function toolCallArgs(args) {
12
+ if (typeof args === "string") {
13
+ try {
14
+ const parsed = JSON.parse(args);
15
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : { value: parsed };
16
+ } catch {
17
+ return {};
18
+ }
19
+ }
20
+ return args && typeof args === "object" && !Array.isArray(args) ? args : {};
21
+ }
22
+ function toAgentsKitMessages(messages) {
23
+ const createdAt = /* @__PURE__ */ new Date();
24
+ const output = [];
25
+ const systemParts = [];
26
+ messages.forEach((message, index) => {
27
+ const type = message.type;
28
+ const id = message.id ?? `lc-${type}-${index}`;
29
+ if (type === "system") {
30
+ const content = contentText(message.content);
31
+ systemParts.push(content);
32
+ output.push({ id, role: "system", content, status: "complete", createdAt });
33
+ return;
34
+ }
35
+ if (type === "ai") {
36
+ const ai = message;
37
+ output.push({
38
+ id,
39
+ role: "assistant",
40
+ content: contentText(ai.content),
41
+ status: "complete",
42
+ createdAt,
43
+ toolCalls: ai.tool_calls?.map((call, callIndex) => ({
44
+ id: call.id ?? `${id}-call-${callIndex}`,
45
+ name: call.name,
46
+ args: toolCallArgs(call.args),
47
+ status: "complete"
48
+ }))
49
+ });
50
+ return;
51
+ }
52
+ if (type === "tool") {
53
+ const toolCallId = message.tool_call_id;
54
+ output.push({ id, role: "tool", content: contentText(message.content), status: "complete", createdAt, toolCallId });
55
+ return;
56
+ }
57
+ output.push({ id, role: "user", content: contentText(message.content), status: "complete", createdAt });
58
+ });
59
+ return { messages: output, systemPrompt: systemParts.length > 0 ? systemParts.join("\n\n") : void 0 };
60
+ }
61
+ function toToolDefinitions(tools) {
62
+ if (!tools || tools.length === 0) return void 0;
63
+ return tools.map((tool) => {
64
+ const converted = convertToOpenAITool(tool);
65
+ const fn = converted.function;
66
+ return {
67
+ name: fn.name,
68
+ description: fn.description,
69
+ schema: fn.parameters ?? { type: "object", properties: {} }
70
+ };
71
+ });
72
+ }
73
+ function usageMetadata(chunk) {
74
+ if (!chunk.usage) return void 0;
75
+ return {
76
+ input_tokens: chunk.usage.promptTokens,
77
+ output_tokens: chunk.usage.completionTokens,
78
+ total_tokens: chunk.usage.totalTokens
79
+ };
80
+ }
81
+ function invalidToolCall(call, error) {
82
+ return { id: call.id, name: call.name, args: call.args, error, type: "invalid_tool_call" };
83
+ }
84
+ var AgentsKitChatModel = class _AgentsKitChatModel extends BaseChatModel {
85
+ constructor(adapter, options = {}) {
86
+ const { modelName, context, profile, ...params } = options;
87
+ super(params);
88
+ this.lc_namespace = ["agentskit", "adapters", "langchain_bridge"];
89
+ this.lc_serializable = false;
90
+ this.adapter = adapter;
91
+ this.modelName = modelName ?? "agentskit";
92
+ this.baseContext = context ?? {};
93
+ this.profileOverride = profile;
94
+ }
95
+ static lc_name() {
96
+ return "AgentsKitChatModel";
97
+ }
98
+ _llmType() {
99
+ return "agentskit";
100
+ }
101
+ get profile() {
102
+ return { toolCalling: this.adapter.capabilities?.tools !== false, ...this.profileOverride };
103
+ }
104
+ bindTools(tools, kwargs) {
105
+ return this.withConfig({ tools, ...kwargs });
106
+ }
107
+ invocationParams(options) {
108
+ return {
109
+ model: this.modelName,
110
+ tools: toToolDefinitions(options?.tools)?.map((tool) => ({ name: tool.name, description: tool.description })),
111
+ tool_choice: options?.tool_choice
112
+ };
113
+ }
114
+ getLsParams(options) {
115
+ return {
116
+ ls_provider: "agentskit",
117
+ ls_model_name: this.modelName,
118
+ ls_model_type: "chat",
119
+ ls_temperature: this.baseContext.temperature,
120
+ ls_max_tokens: this.baseContext.maxTokens,
121
+ ls_stop: options.stop
122
+ };
123
+ }
124
+ buildRequest(messages, options) {
125
+ const { messages: converted, systemPrompt } = toAgentsKitMessages(messages);
126
+ const tools = toToolDefinitions(options.tools);
127
+ const metadata = options.tool_choice === void 0 ? this.baseContext.metadata : { ...this.baseContext.metadata, toolChoice: options.tool_choice };
128
+ const context = { ...this.baseContext, systemPrompt, tools, metadata };
129
+ return { messages: converted, context };
130
+ }
131
+ async *chunks(messages, options) {
132
+ const source = this.adapter.createSource(this.buildRequest(messages, options));
133
+ const signal = options.signal;
134
+ const onAbort = () => source.abort();
135
+ if (signal?.aborted) {
136
+ source.abort();
137
+ throw signal.reason instanceof Error ? signal.reason : new Error("Aborted");
138
+ }
139
+ signal?.addEventListener("abort", onAbort, { once: true });
140
+ try {
141
+ for await (const chunk of source.stream()) {
142
+ if (chunk.type === "error") {
143
+ const cause = chunk.metadata?.error;
144
+ throw cause instanceof Error ? cause : new Error(chunk.content ?? "AgentsKit adapter stream failed");
145
+ }
146
+ if (chunk.type === "done") return;
147
+ yield chunk;
148
+ }
149
+ } finally {
150
+ signal?.removeEventListener("abort", onAbort);
151
+ }
152
+ }
153
+ static collect(response, chunk) {
154
+ if (chunk.metadata) Object.assign(response.metadata, chunk.metadata);
155
+ switch (chunk.type) {
156
+ case "text":
157
+ response.text += chunk.content ?? "";
158
+ break;
159
+ case "reasoning":
160
+ response.reasoning += chunk.content ?? "";
161
+ break;
162
+ case "tool_call":
163
+ if (!chunk.toolCall) break;
164
+ try {
165
+ response.toolCalls.push({ id: chunk.toolCall.id, name: chunk.toolCall.name, args: toolCallArgs(chunk.toolCall.args), type: "tool_call" });
166
+ } catch (error) {
167
+ response.invalidToolCalls.push(invalidToolCall(chunk.toolCall, error instanceof Error ? error.message : String(error)));
168
+ }
169
+ break;
170
+ case "usage":
171
+ response.usage = usageMetadata(chunk);
172
+ break;
173
+ }
174
+ }
175
+ async _generate(messages, options, runManager) {
176
+ const response = { text: "", reasoning: "", toolCalls: [], invalidToolCalls: [], metadata: {} };
177
+ for await (const chunk of this.chunks(messages, options)) {
178
+ _AgentsKitChatModel.collect(response, chunk);
179
+ if (chunk.type === "text" && chunk.content) await runManager?.handleLLMNewToken(chunk.content);
180
+ }
181
+ const message = new AIMessage({
182
+ content: response.text,
183
+ tool_calls: response.toolCalls,
184
+ invalid_tool_calls: response.invalidToolCalls,
185
+ usage_metadata: response.usage,
186
+ additional_kwargs: response.reasoning ? { reasoning: response.reasoning } : {},
187
+ response_metadata: { ...response.metadata, model_name: this.modelName }
188
+ });
189
+ return {
190
+ generations: [{ text: response.text, message }],
191
+ llmOutput: response.usage ? { tokenUsage: { promptTokens: response.usage.input_tokens, completionTokens: response.usage.output_tokens, totalTokens: response.usage.total_tokens } } : {}
192
+ };
193
+ }
194
+ async *_streamResponseChunks(messages, options, runManager) {
195
+ let toolCallIndex = 0;
196
+ for await (const chunk of this.chunks(messages, options)) {
197
+ let message;
198
+ if (chunk.type === "text") {
199
+ message = new AIMessageChunk({ content: chunk.content ?? "", response_metadata: chunk.metadata ?? {} });
200
+ } else if (chunk.type === "reasoning") {
201
+ message = new AIMessageChunk({ content: "", additional_kwargs: { reasoning: chunk.content ?? "" } });
202
+ } else if (chunk.type === "tool_call" && chunk.toolCall) {
203
+ message = new AIMessageChunk({
204
+ content: "",
205
+ tool_call_chunks: [{
206
+ id: chunk.toolCall.id,
207
+ name: chunk.toolCall.name,
208
+ args: typeof chunk.toolCall.args === "string" ? chunk.toolCall.args : JSON.stringify(chunk.toolCall.args ?? {}),
209
+ index: toolCallIndex++,
210
+ type: "tool_call_chunk"
211
+ }]
212
+ });
213
+ } else if (chunk.type === "usage") {
214
+ message = new AIMessageChunk({ content: "", usage_metadata: usageMetadata(chunk) });
215
+ }
216
+ if (!message) continue;
217
+ const generation = new ChatGenerationChunk({ message, text: chunk.type === "text" ? chunk.content ?? "" : "" });
218
+ yield generation;
219
+ if (chunk.type === "text" && chunk.content) await runManager?.handleLLMNewToken(chunk.content, void 0, void 0, void 0, void 0, { chunk: generation });
220
+ }
221
+ }
222
+ };
223
+ function adapterToLangChainModel(adapter, options) {
224
+ return new AgentsKitChatModel(adapter, options);
225
+ }
226
+
227
+ export { AgentsKitChatModel, adapterToLangChainModel };
228
+ //# sourceMappingURL=langchain-bridge.js.map
229
+ //# sourceMappingURL=langchain-bridge.js.map