@dawn-ai/langchain 0.1.4 → 0.1.6

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.
@@ -7,13 +7,19 @@ interface DawnToolDefinition {
7
7
  }) => Promise<unknown> | unknown;
8
8
  readonly schema?: unknown;
9
9
  }
10
- export declare function executeAgent(options: {
10
+ export interface AgentStreamChunk {
11
+ readonly type: "token" | "tool_call" | "tool_result" | "done";
12
+ readonly data: unknown;
13
+ }
14
+ export interface AgentOptions {
11
15
  readonly entry: unknown;
12
16
  readonly input: unknown;
13
17
  readonly routeParamNames: readonly string[];
14
18
  readonly signal: AbortSignal;
15
19
  readonly stateFields?: readonly ResolvedStateField[];
16
20
  readonly tools: readonly DawnToolDefinition[];
17
- }): Promise<unknown>;
21
+ }
22
+ export declare function executeAgent(options: AgentOptions): Promise<unknown>;
23
+ export declare function streamAgent(options: AgentOptions): AsyncGenerator<AgentStreamChunk>;
18
24
  export {};
19
25
  //# sourceMappingURL=agent-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-adapter.d.ts","sourceRoot":"","sources":["../src/agent-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAA0B,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAGpF,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,CACZ,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;KAAE,KACtC,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAC1B;AAuDD,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACpD,QAAQ,CAAC,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAC9C,GAAG,OAAO,CAAC,OAAO,CAAC,CA0CnB"}
1
+ {"version":3,"file":"agent-adapter.d.ts","sourceRoot":"","sources":["../src/agent-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAA0B,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAGpF,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,CACZ,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;KAAE,KACtC,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAC1B;AAuDD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,aAAa,GAAG,MAAM,CAAA;IAC7D,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACpD,QAAQ,CAAC,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAC9C;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ1E;AAED,wBAAuB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,cAAc,CAAC,gBAAgB,CAAC,CAwB1F"}
@@ -36,6 +36,32 @@ async function materializeAgent(descriptor, tools, stateFields) {
36
36
  return compiled;
37
37
  }
38
38
  export async function executeAgent(options) {
39
+ let result;
40
+ for await (const chunk of streamAgent(options)) {
41
+ if (chunk.type === "done") {
42
+ result = chunk.data;
43
+ }
44
+ }
45
+ return result;
46
+ }
47
+ export async function* streamAgent(options) {
48
+ const { agentInput, config } = prepareAgentCall(options);
49
+ const messages = extractMessages(agentInput);
50
+ // DawnAgent descriptor path — materialize on first use
51
+ if (isDawnAgent(options.entry)) {
52
+ const materializedAgent = await materializeAgent(options.entry, options.tools, options.stateFields);
53
+ yield* streamFromRunnable(materializedAgent, { messages }, config);
54
+ return;
55
+ }
56
+ // Legacy path — raw Runnable with .invoke()
57
+ assertAgentLike(options.entry);
58
+ const langchainTools = options.tools.map((tool) => convertToolToLangChain(tool));
59
+ if (langchainTools.length > 0) {
60
+ config.tools = langchainTools;
61
+ }
62
+ yield* streamFromRunnable(options.entry, { messages }, config);
63
+ }
64
+ function prepareAgentCall(options) {
39
65
  const inputRecord = (options.input ?? {});
40
66
  const params = {};
41
67
  const agentInput = {};
@@ -53,20 +79,67 @@ export async function executeAgent(options) {
53
79
  if (Object.keys(params).length > 0) {
54
80
  config.configurable = params;
55
81
  }
56
- // DawnAgent descriptor path — materialize on first use
57
- if (isDawnAgent(options.entry)) {
58
- const materializedAgent = await materializeAgent(options.entry, options.tools, options.stateFields);
59
- const messages = [new HumanMessage(formatAgentMessage(agentInput))];
60
- return await materializedAgent.invoke({ messages }, config);
82
+ return { agentInput, config };
83
+ }
84
+ async function* streamFromRunnable(runnable, input, config) {
85
+ const streamable = runnable;
86
+ if (typeof streamable.streamEvents !== "function") {
87
+ // Fallback: invoke and emit a single done event
88
+ const result = await runnable.invoke(input, config);
89
+ yield { type: "done", data: result };
90
+ return;
61
91
  }
62
- // Legacy path — raw Runnable with .invoke()
63
- assertAgentLike(options.entry);
64
- const langchainTools = options.tools.map((tool) => convertToolToLangChain(tool));
65
- if (langchainTools.length > 0) {
66
- config.tools = langchainTools;
92
+ let finalOutput;
93
+ for await (const event of streamable.streamEvents(input, { ...config, version: "v2" })) {
94
+ switch (event.event) {
95
+ case "on_chat_model_stream": {
96
+ const content = event.data.chunk?.content;
97
+ if (content && typeof content === "string" && content.length > 0) {
98
+ yield { type: "token", data: content };
99
+ }
100
+ break;
101
+ }
102
+ case "on_tool_start": {
103
+ yield {
104
+ type: "tool_call",
105
+ data: { name: event.name, input: event.data.chunk ?? event.data.output },
106
+ };
107
+ break;
108
+ }
109
+ case "on_tool_end": {
110
+ yield {
111
+ type: "tool_result",
112
+ data: { name: event.name, output: event.data.output },
113
+ };
114
+ break;
115
+ }
116
+ case "on_chain_end": {
117
+ if (event.name === "LangGraph") {
118
+ finalOutput = event.data.output;
119
+ }
120
+ break;
121
+ }
122
+ }
123
+ }
124
+ yield { type: "done", data: finalOutput };
125
+ }
126
+ function isInputMessageArray(value) {
127
+ return (Array.isArray(value) &&
128
+ value.length > 0 &&
129
+ value.every((item) => typeof item === "object" &&
130
+ item !== null &&
131
+ typeof item.role === "string" &&
132
+ typeof item.content === "string"));
133
+ }
134
+ function extractMessages(input) {
135
+ // LangGraph protocol format: {messages: [{role, content}, ...]}
136
+ if (isInputMessageArray(input.messages)) {
137
+ return input.messages
138
+ .filter((msg) => msg.role === "user")
139
+ .map((msg) => new HumanMessage(msg.content));
67
140
  }
68
- const messages = [new HumanMessage(formatAgentMessage(agentInput))];
69
- return await options.entry.invoke({ messages }, config);
141
+ // Legacy flat-object format: {key: value, ...}
142
+ return [new HumanMessage(formatAgentMessage(input))];
70
143
  }
71
144
  function formatAgentMessage(input) {
72
145
  const entries = Object.entries(input);
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export { executeAgent } from "./agent-adapter.js";
1
+ export type { AgentStreamChunk } from "./agent-adapter.js";
2
+ export { executeAgent, streamAgent } from "./agent-adapter.js";
2
3
  export { chainAdapter } from "./chain-adapter.js";
3
4
  export { materializeStateSchema } from "./state-adapter.js";
4
5
  export { convertToolToLangChain } from "./tool-converter.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { executeAgent } from "./agent-adapter.js";
1
+ export { executeAgent, streamAgent } from "./agent-adapter.js";
2
2
  export { chainAdapter } from "./chain-adapter.js";
3
3
  export { materializeStateSchema } from "./state-adapter.js";
4
4
  export { convertToolToLangChain } from "./tool-converter.js";
@@ -1,7 +1,7 @@
1
1
  import { DynamicStructuredTool } from "@langchain/core/tools";
2
2
  import { z } from "zod";
3
3
  export function convertToolToLangChain(tool) {
4
- const schema = isZodObject(tool.schema) ? tool.schema : z.record(z.string(), z.unknown());
4
+ const schema = toZodSchema(tool.schema);
5
5
  // Cast through unknown to bridge the dual-Zod version type incompatibility
6
6
  // (package uses zod@3.24.4; @langchain/core uses zod@3.25.x — structurally identical at runtime)
7
7
  return new DynamicStructuredTool({
@@ -15,6 +15,13 @@ export function convertToolToLangChain(tool) {
15
15
  },
16
16
  });
17
17
  }
18
+ function toZodSchema(value) {
19
+ if (isZodObject(value))
20
+ return value;
21
+ if (isJsonSchemaObject(value))
22
+ return jsonSchemaToZod(value);
23
+ return z.record(z.string(), z.unknown());
24
+ }
18
25
  function isZodObject(value) {
19
26
  return (typeof value === "object" &&
20
27
  value !== null &&
@@ -22,3 +29,44 @@ function isZodObject(value) {
22
29
  typeof value._def === "object" &&
23
30
  value._def !== null);
24
31
  }
32
+ function isJsonSchemaObject(value) {
33
+ return (typeof value === "object" &&
34
+ value !== null &&
35
+ value.type === "object" &&
36
+ typeof value.properties === "object");
37
+ }
38
+ function jsonSchemaToZod(schema) {
39
+ const shape = {};
40
+ const required = new Set(schema.required ?? []);
41
+ for (const [key, prop] of Object.entries(schema.properties ?? {})) {
42
+ let field = jsonSchemaFieldToZod(prop);
43
+ if (!required.has(key)) {
44
+ field = field.optional();
45
+ }
46
+ shape[key] = field;
47
+ }
48
+ return z.object(shape);
49
+ }
50
+ function jsonSchemaFieldToZod(prop) {
51
+ switch (prop.type) {
52
+ case "string":
53
+ return z.string();
54
+ case "number":
55
+ case "integer":
56
+ return z.number();
57
+ case "boolean":
58
+ return z.boolean();
59
+ case "array": {
60
+ const items = prop.items;
61
+ if (items?.type === "string")
62
+ return z.array(z.string());
63
+ if (items?.type === "number" || items?.type === "integer")
64
+ return z.array(z.number());
65
+ if (items?.type === "boolean")
66
+ return z.array(z.boolean());
67
+ return z.array(z.unknown());
68
+ }
69
+ default:
70
+ return z.unknown();
71
+ }
72
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dawn-ai/langchain",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -32,7 +32,7 @@
32
32
  "dependencies": {
33
33
  "@langchain/langgraph": "^0.2.71",
34
34
  "@langchain/openai": "^0.3.17",
35
- "@dawn-ai/sdk": "0.1.4"
35
+ "@dawn-ai/sdk": "0.1.6"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@langchain/core": ">=0.3.0"
@@ -43,7 +43,7 @@
43
43
  "@langchain/openai": "0.3.17",
44
44
  "@types/node": "25.6.0",
45
45
  "zod": "3.24.4",
46
- "@dawn-ai/config-typescript": "0.1.4"
46
+ "@dawn-ai/config-typescript": "0.1.6"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "tsc -b tsconfig.json",