@shuttle-ai/agent 0.0.5 → 0.0.7

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.
@@ -1,5 +1,5 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const b=require("@langchain/core/runnables"),_=require("langchain"),l=require("@langchain/core/messages"),u=require("@langchain/core/tools"),c=require("zod"),g=require("node:crypto"),p=require("../middleware/dynamicToolInterceptor.cjs"),d=require("../callback/LLMMessage.cjs");class i extends b.Runnable{constructor(t){super(),this.options=t,this.id=t.id||g.randomUUID(),t.single?.addEventListener("abort",()=>{this.stop()})}static MAIN_AGENT_NAME="main_agent";static CALL_SUB_AGENT_NAME="call_sub_agent";lc_namespace=["shuttle-ai","agent","cluster"];id;messages=[];abortController=new AbortController;addMessage(t){this.messages.push(t),this.options.messageCollector?.saveMessage(t)}async invoke(t,s){const e=await this.options.hooks.onAgentStart({agentId:this.id,agentName:i.MAIN_AGENT_NAME,content:t}),a=this.createAgent(e,this.id);this.addMessage({id:g.randomUUID(),workId:this.id,agentId:this.id,role:"user",content:t});const r=await this.revokeMessages(this.id),o=a.streamEvents({messages:[...r,{role:"user",content:t}]},{signal:this.abortController.signal,context:{...s?.context||{},_agentCluster:this,_agentId:this.id},callbacks:[new d.default({agentCluster:this,agentId:this.id})]});return await Array.fromAsync(o),this.options.hooks.onAgentEnd?.(this.id),this.getLastAiMessage(this.id)?.content||""}stop(t="stop"){this.abortController.abort(t)}createAgent({tools:t,subAgents:s,middleware:e,...a},r){let o=[];return t?.length&&(o=this.normalizationTools(t)),s?.length&&o.push(this.subAgentToDynamicTool(s,r)),_.createAgent({...a,middleware:[...e||[],p.default],tools:o})}normalizationTools(t){return t.map(s=>"lc_namespace"in s||"lc_name"in s?s:this.customToolToDynamicTool(s))}customToolToDynamicTool(t){return u.tool(s=>"",t)}subAgentToDynamicTool(t,s){return u.tool(async(e,a)=>{if(!t.find(M=>M.name===e.subAgentName))throw new Error(`Sub-agent ${e.subAgentName} not found.`);const o=this.getLastAiMessage(s),n=a.toolCall.id,h=await this.options.hooks.onAgentStart({agentId:n,agentName:e.subAgentName,beloneMessageId:o?.id,parentAgentId:s,content:e.request}),m=this.createAgent(h,n);this.addMessage({id:g.randomUUID(),workId:this.id,agentId:n,role:"user",content:e.request});const A=m.streamEvents({messages:[{role:"user",content:e.request}]},{signal:this.abortController.signal,context:{...a.context||{},_agentCluster:this,_agentId:n,_parentAgentId:s},callbacks:[new d.default({agentCluster:this,agentId:n})]});return await Array.fromAsync(A),this.options.hooks.onAgentEnd?.(n),this.getLastAiMessage(n)?.content||""},{name:i.CALL_SUB_AGENT_NAME,description:`Call a sub-agent to handle the user request.
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const b=require("@langchain/core/runnables"),p=require("langchain"),l=require("@langchain/core/messages"),u=require("@langchain/core/tools"),c=require("zod"),g=require("node:crypto"),T=require("../middleware/dynamicToolInterceptor.cjs"),d=require("../callback/LLMMessage.cjs");class i extends b.Runnable{constructor(e){super(),this.options=e,this.id=e.id||g.randomUUID(),e.single?.addEventListener("abort",()=>{this.stop()})}static MAIN_AGENT_NAME="main_agent";static CALL_SUB_AGENT_NAME="call_sub_agent";lc_namespace=["shuttle-ai","agent","cluster"];id;messages=[];abortController=new AbortController;addMessage(e){this.messages.push(e),this.options.messageCollector?.saveMessage(e)}async invoke(e,s){const t=await this.options.hooks.onAgentStart({agentId:this.id,agentName:i.MAIN_AGENT_NAME,content:e}),n=this.createAgent(t,this.id);this.addMessage({id:g.randomUUID(),workId:this.id,agentId:this.id,role:"user",content:e});const r=await this.revokeMessages(this.id),a=n.streamEvents({messages:[...r,{role:"user",content:e}]},{signal:this.abortController.signal,context:{...s?.context||{},_agentCluster:this,_agentId:this.id},callbacks:[new d.default({agentCluster:this,agentId:this.id})]});return await Array.fromAsync(a),this.options.hooks.onAgentEnd?.(this.id),this.getLastAiMessage(this.id)?.content||""}stop(e="stop"){this.abortController.abort(e)}createAgent({tools:e,subAgents:s,middleware:t,...n},r){let a=[];return e?.length&&(a=this.normalizationTools(e)),s?.length&&a.push(this.subAgentToDynamicTool(s,r)),p.createAgent({...n,middleware:[...t||[],T.default],tools:a})}normalizationTools(e){return e.map(s=>"lc_namespace"in s||"lc_name"in s?s:this.customToolToDynamicTool(s))}customToolToDynamicTool(e){return u.tool(s=>"",e)}subAgentToDynamicTool(e,s){return u.tool(async(t,n)=>{if(!e.find(M=>M.name===t.subAgentName))throw new Error(`Sub-agent ${t.subAgentName} not found.`);const a=this.getLastAiMessage(s),o=n.toolCall.id,h=await this.options.hooks.onAgentStart({agentId:o,agentName:t.subAgentName,beloneMessageId:a?.id,parentAgentId:s,content:t.request}),m=this.createAgent(h,o);this.addMessage({id:g.randomUUID(),workId:this.id,agentId:o,role:"user",content:t.request});const A=m.streamEvents({messages:[{role:"user",content:t.request}]},{signal:this.abortController.signal,context:{...n.context||{},_agentCluster:this,_agentId:o,_parentAgentId:s},callbacks:[new d.default({agentCluster:this,agentId:o})]});return await Array.fromAsync(A),this.options.hooks.onAgentEnd?.(o),this.getLastAiMessage(o)?.content||""},{name:i.CALL_SUB_AGENT_NAME,description:`Call a sub-agent to handle the user request.
2
2
  The sub-agents are:
3
- ${t.map(e=>`- ${e.name}: ${e.description}`).join(`
3
+ ${e.map(t=>`- ${t.name}: ${t.description}`).join(`
4
4
  `)}
5
- `,schema:c.z.object({subAgentName:c.z.literal(t.map(e=>e.name)).describe("The name of the sub-agent to call."),request:c.z.string().describe("The request to send to the sub-agent.")}),extras:{scope:"autoRun",skipReport:!0}})}getLastAiMessage(t){for(let s=this.messages.length-1;s>=0;s--){const e=this.messages[s];if(e.agentId===t&&e.role==="assistant")return e}}getMessages(){return this.messages}async revokeMessages(t){return this.options.messageCollector?(await this.options.messageCollector.getMessagesByAgentId(this.id,t)).map(e=>e.role==="user"?new l.HumanMessage(e.content):e.role==="assistant"?new l.AIMessage({content:e.content,tool_calls:e.toolCalls}):new l.ToolMessage({content:e.content||e.confirm?.result,tool_call_id:e.id})):[]}}exports.default=i;
5
+ `,schema:c.z.object({subAgentName:c.z.literal(e.map(t=>t.name)).describe("The name of the sub-agent to call."),request:c.z.string().describe("The request to send to the sub-agent.")}),extras:{scope:"autoRun",skipReport:!0}})}getLastAiMessage(e){for(let s=this.messages.length-1;s>=0;s--){const t=this.messages[s];if(t.agentId===e&&t.role==="assistant")return t}}getMessages(){return this.messages}async revokeMessages(e){return this.options.messageCollector?(await this.options.messageCollector.getMessagesByAgentId(this.id,e)).map(t=>{if(t.role==="user")return new l.HumanMessage(t.content);if(t.role==="assistant")return new l.AIMessage({content:t.content,tool_calls:t.toolCalls});const n=t.result||t.confirm?.result;return new l.ToolMessage({content:(n?.type==="success"?this.anyToString(n.content):n?.reason)||"",tool_call_id:t.id})}):[]}anyToString(e){return typeof e=="object"?JSON.stringify(e):e}}exports.default=i;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./cluster/instance.cjs"),r=require("./cluster/readableHook.cjs"),t=require("./cluster/fileMessageCollector.cjs"),o=require("./callback/LLMMessage.cjs"),l=require("./middleware/dynamicToolInterceptor.cjs");require("@shuttle-ai/type");exports.AgentCluster=e.default;exports.readableHook=r.default;exports.FileMessageCollector=t.default;exports.LLMMessage=o.default;exports.dynamicToolInterceptorMiddleware=l.default;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./cluster/instance.cjs"),o=require("./cluster/readableHook.cjs"),a=require("./cluster/fileMessageCollector.cjs"),l=require("./callback/LLMMessage.cjs"),c=require("./middleware/dynamicToolInterceptor.cjs"),t=require("@shuttle-ai/type");exports.AgentCluster=r.default;exports.readableHook=o.default;exports.FileMessageCollector=a.default;exports.LLMMessage=l.default;exports.dynamicToolInterceptorMiddleware=c.default;Object.keys(t).forEach(e=>{e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const C=require("langchain"),u=require("@langchain/core/tools"),s=require("@langchain/core/messages"),M=require("../cluster/instance.cjs"),p=C.createMiddleware({name:"dynamicToolInterceptorMiddleware",wrapToolCall:async(o,i)=>{const e=o.runtime.context,a={role:"tool",name:o.toolCall.name,id:o.toolCall.id||"",aiMessageId:"",agentId:e._agentId,workId:e._agentCluster.id};let t;if(o.tool instanceof u.DynamicTool||o.tool instanceof u.DynamicStructuredTool||o.tool&&"extras"in o.tool){const l=o.tool.extras||{};if(!l.skipReport){const f=!w(l,e._agentCluster),r=e._agentCluster.getLastAiMessage(e._agentId);a.aiMessageId=r?.id||"";const _=r?.toolCalls?.find(c=>c.id===o.toolCall.id),n=await e._agentCluster.options.hooks.onToolStart({role:"assistant_tool",toolCall:_,needConfirm:l.remote||f,id:r?.id||"",agentId:e._agentId,workId:e._agentCluster.id});if(a.confirm=n,n.type==="reject"||n.type==="confirm"&&l.remote)return e._agentCluster.addMessage(a),new s.ToolMessage({content:n.reason||"can not run tool",tool_call_id:o.toolCall.id||""});if(n.type==="confirmWithResult")return e._agentCluster.addMessage(a),new s.ToolMessage({content:typeof n.result=="object"?JSON.stringify(n.result):n.result||"success",tool_call_id:o.toolCall.id||""});const d={agentId:e._agentId,messageId:r?.id||"",toolId:o.toolCall.id||""};if(n.newArgs){o.toolCall.args=n.newArgs;const g=o.state.messages[o.state.messages.length-1].tool_calls?.find(m=>m.id===o.toolCall.id);g&&(g.args=n.newArgs)}try{t=await i(o),t instanceof s.ToolMessage||"content"in t?e._agentCluster.options.hooks.onToolEnd?.(d,t.content):e._agentCluster.options.hooks.onToolEnd?.(d,"{}")}catch(c){t=new s.ToolMessage({content:c.message||"can not run tool",tool_call_id:o.toolCall.id||""})}}}if(!t)try{t=await i(o)}catch(l){t=new s.ToolMessage({content:l.message||"can not run tool",tool_call_id:o.toolCall.id||""})}return"lg_name"in t&&t.lg_name==="Command"&&(t=t?.update?.messages?.[0]),t instanceof s.ToolMessage&&t.name!==M.default.CALL_SUB_AGENT_NAME&&(a.content=t.content,e._agentCluster.addMessage(a)),t}});function w(o,i){return o.scope==="autoRun"||i.options.autoRunScope==="always"||i.options.autoRunScope==="read"&&o.scope!=="write"}exports.default=p;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const C=require("langchain"),f=require("@langchain/core/tools"),l=require("@langchain/core/messages"),M=require("../cluster/instance.cjs"),y=C.createMiddleware({name:"dynamicToolInterceptorMiddleware",wrapToolCall:async(o,i)=>{const e=o.runtime.context,a={role:"tool",name:o.toolCall.name,id:o.toolCall.id||"",aiMessageId:"",agentId:e._agentId,workId:e._agentCluster.id};let t,d=!1;if(o.tool instanceof f.DynamicTool||o.tool instanceof f.DynamicStructuredTool||o.tool&&"extras"in o.tool){const s=o.tool.extras||{};if(!s.skipReport){const _=!T(s,e._agentCluster),r=e._agentCluster.getLastAiMessage(e._agentId);a.aiMessageId=r?.id||"";const m=r?.toolCalls?.find(c=>c.id===o.toolCall.id),n=await e._agentCluster.options.hooks.onToolStart({role:"assistant_tool",toolCall:m,needConfirm:s.remote||_,id:r?.id||"",agentId:e._agentId,workId:e._agentCluster.id});if(a.confirm=n,n.type==="reject"||n.type==="confirm"&&s.remote)return e._agentCluster.addMessage(a),new l.ToolMessage({content:n.reason||"can not run tool",tool_call_id:o.toolCall.id||""});if(n.type==="confirmWithResult")return e._agentCluster.addMessage(a),new l.ToolMessage({content:typeof n.result=="object"?JSON.stringify(n.result):n.result||"success",tool_call_id:o.toolCall.id||""});const g={agentId:e._agentId,messageId:r?.id||"",toolId:o.toolCall.id||""};if(n.newArgs){o.toolCall.args=n.newArgs;const u=o.state.messages[o.state.messages.length-1].tool_calls?.find(p=>p.id===o.toolCall.id);u&&(u.args=n.newArgs)}try{t=await i(o),t instanceof l.ToolMessage||"content"in t?e._agentCluster.options.hooks.onToolEnd?.(g,{type:"success",content:t.content}):e._agentCluster.options.hooks.onToolEnd?.(g,{type:"success",content:"{}"})}catch(c){t=new l.ToolMessage({content:c.message||"can not run tool",tool_call_id:o.toolCall.id||""}),d=!0,e._agentCluster.options.hooks.onToolEnd?.(g,{type:"fail",reason:t.content})}}}if(!t)try{t=await i(o)}catch(s){d=!0,t=new l.ToolMessage({content:s.message||"can not run tool",tool_call_id:o.toolCall.id||""})}return"lg_name"in t&&t.lg_name==="Command"&&(t=t?.update?.messages?.[0]),t instanceof l.ToolMessage&&t.name!==M.default.CALL_SUB_AGENT_NAME&&(a.result=d?{type:"fail",reason:t.content}:{type:"success",content:t.content},e._agentCluster.addMessage(a)),t}});function T(o,i){return o.scope==="autoRun"||i.options.autoRunScope==="always"||i.options.autoRunScope==="read"&&o.scope!=="write"}exports.default=y;
@@ -1,14 +1,14 @@
1
- import { Runnable as M } from "@langchain/core/runnables";
2
- import { createAgent as p } from "langchain";
3
- import { HumanMessage as b, AIMessage as f, ToolMessage as T } from "@langchain/core/messages";
1
+ import { Runnable as p } from "@langchain/core/runnables";
2
+ import { createAgent as M } from "langchain";
3
+ import { HumanMessage as f, AIMessage as b, ToolMessage as T } from "@langchain/core/messages";
4
4
  import { tool as c } from "@langchain/core/tools";
5
5
  import { z as i } from "zod";
6
6
  import { randomUUID as l } from "node:crypto";
7
7
  import _ from "../middleware/dynamicToolInterceptor.mjs";
8
- import d from "../callback/LLMMessage.mjs";
9
- class g extends M {
10
- constructor(e) {
11
- super(), this.options = e, this.id = e.id || l(), e.single?.addEventListener("abort", () => {
8
+ import h from "../callback/LLMMessage.mjs";
9
+ class g extends p {
10
+ constructor(t) {
11
+ super(), this.options = t, this.id = t.id || l(), t.single?.addEventListener("abort", () => {
12
12
  this.stop();
13
13
  });
14
14
  }
@@ -18,25 +18,25 @@ class g extends M {
18
18
  id;
19
19
  messages = [];
20
20
  abortController = new AbortController();
21
- addMessage(e) {
22
- this.messages.push(e), this.options.messageCollector?.saveMessage(e);
21
+ addMessage(t) {
22
+ this.messages.push(t), this.options.messageCollector?.saveMessage(t);
23
23
  }
24
- async invoke(e, s) {
25
- const t = await this.options.hooks.onAgentStart({
24
+ async invoke(t, s) {
25
+ const e = await this.options.hooks.onAgentStart({
26
26
  agentId: this.id,
27
27
  agentName: g.MAIN_AGENT_NAME,
28
- content: e
29
- }), a = this.createAgent(t, this.id);
28
+ content: t
29
+ }), n = this.createAgent(e, this.id);
30
30
  this.addMessage({
31
31
  id: l(),
32
32
  workId: this.id,
33
33
  agentId: this.id,
34
34
  role: "user",
35
- content: e
35
+ content: t
36
36
  });
37
- const r = await this.revokeMessages(this.id), o = a.streamEvents(
37
+ const r = await this.revokeMessages(this.id), a = n.streamEvents(
38
38
  {
39
- messages: [...r, { role: "user", content: e }]
39
+ messages: [...r, { role: "user", content: t }]
40
40
  },
41
41
  {
42
42
  signal: this.abortController.signal,
@@ -46,92 +46,92 @@ class g extends M {
46
46
  _agentId: this.id
47
47
  },
48
48
  callbacks: [
49
- new d({
49
+ new h({
50
50
  agentCluster: this,
51
51
  agentId: this.id
52
52
  })
53
53
  ]
54
54
  }
55
55
  );
56
- return await Array.fromAsync(o), this.options.hooks.onAgentEnd?.(this.id), this.getLastAiMessage(this.id)?.content || "";
56
+ return await Array.fromAsync(a), this.options.hooks.onAgentEnd?.(this.id), this.getLastAiMessage(this.id)?.content || "";
57
57
  }
58
- stop(e = "stop") {
59
- this.abortController.abort(e);
58
+ stop(t = "stop") {
59
+ this.abortController.abort(t);
60
60
  }
61
61
  createAgent({
62
- tools: e,
62
+ tools: t,
63
63
  subAgents: s,
64
- middleware: t,
65
- ...a
64
+ middleware: e,
65
+ ...n
66
66
  }, r) {
67
- let o = [];
68
- return e?.length && (o = this.normalizationTools(e)), s?.length && o.push(this.subAgentToDynamicTool(s, r)), p({
69
- ...a,
67
+ let a = [];
68
+ return t?.length && (a = this.normalizationTools(t)), s?.length && a.push(this.subAgentToDynamicTool(s, r)), M({
69
+ ...n,
70
70
  middleware: [
71
- ...t || [],
71
+ ...e || [],
72
72
  _
73
73
  ],
74
- tools: o
74
+ tools: a
75
75
  });
76
76
  }
77
- normalizationTools(e) {
78
- return e.map((s) => "lc_namespace" in s || "lc_name" in s ? s : this.customToolToDynamicTool(s));
77
+ normalizationTools(t) {
78
+ return t.map((s) => "lc_namespace" in s || "lc_name" in s ? s : this.customToolToDynamicTool(s));
79
79
  }
80
- customToolToDynamicTool(e) {
81
- return c((s) => "", e);
80
+ customToolToDynamicTool(t) {
81
+ return c((s) => "", t);
82
82
  }
83
- subAgentToDynamicTool(e, s) {
83
+ subAgentToDynamicTool(t, s) {
84
84
  return c(
85
- async (t, a) => {
86
- if (!e.find(
87
- (A) => A.name === t.subAgentName
85
+ async (e, n) => {
86
+ if (!t.find(
87
+ (A) => A.name === e.subAgentName
88
88
  ))
89
- throw new Error(`Sub-agent ${t.subAgentName} not found.`);
90
- const o = this.getLastAiMessage(s), n = a.toolCall.id, h = await this.options.hooks.onAgentStart({
91
- agentId: n,
92
- agentName: t.subAgentName,
93
- beloneMessageId: o?.id,
89
+ throw new Error(`Sub-agent ${e.subAgentName} not found.`);
90
+ const a = this.getLastAiMessage(s), o = n.toolCall.id, u = await this.options.hooks.onAgentStart({
91
+ agentId: o,
92
+ agentName: e.subAgentName,
93
+ beloneMessageId: a?.id,
94
94
  parentAgentId: s,
95
- content: t.request
96
- }), u = this.createAgent(h, n);
95
+ content: e.request
96
+ }), d = this.createAgent(u, o);
97
97
  this.addMessage({
98
98
  id: l(),
99
99
  workId: this.id,
100
- agentId: n,
100
+ agentId: o,
101
101
  role: "user",
102
- content: t.request
102
+ content: e.request
103
103
  });
104
- const m = u.streamEvents(
104
+ const m = d.streamEvents(
105
105
  {
106
- messages: [{ role: "user", content: t.request }]
106
+ messages: [{ role: "user", content: e.request }]
107
107
  },
108
108
  {
109
109
  signal: this.abortController.signal,
110
110
  context: {
111
- ...a.context || {},
111
+ ...n.context || {},
112
112
  _agentCluster: this,
113
- _agentId: n,
113
+ _agentId: o,
114
114
  _parentAgentId: s
115
115
  },
116
116
  callbacks: [
117
- new d({
117
+ new h({
118
118
  agentCluster: this,
119
- agentId: n
119
+ agentId: o
120
120
  })
121
121
  ]
122
122
  }
123
123
  );
124
- return await Array.fromAsync(m), this.options.hooks.onAgentEnd?.(n), this.getLastAiMessage(n)?.content || "";
124
+ return await Array.fromAsync(m), this.options.hooks.onAgentEnd?.(o), this.getLastAiMessage(o)?.content || "";
125
125
  },
126
126
  {
127
127
  name: g.CALL_SUB_AGENT_NAME,
128
128
  description: `Call a sub-agent to handle the user request.
129
129
  The sub-agents are:
130
- ${e.map((t) => `- ${t.name}: ${t.description}`).join(`
130
+ ${t.map((e) => `- ${e.name}: ${e.description}`).join(`
131
131
  `)}
132
132
  `,
133
133
  schema: i.object({
134
- subAgentName: i.literal(e.map((t) => t.name)).describe("The name of the sub-agent to call."),
134
+ subAgentName: i.literal(t.map((e) => e.name)).describe("The name of the sub-agent to call."),
135
135
  request: i.string().describe("The request to send to the sub-agent.")
136
136
  }),
137
137
  extras: {
@@ -141,27 +141,37 @@ class g extends M {
141
141
  }
142
142
  );
143
143
  }
144
- getLastAiMessage(e) {
144
+ getLastAiMessage(t) {
145
145
  for (let s = this.messages.length - 1; s >= 0; s--) {
146
- const t = this.messages[s];
147
- if (t.agentId === e && t.role === "assistant")
148
- return t;
146
+ const e = this.messages[s];
147
+ if (e.agentId === t && e.role === "assistant")
148
+ return e;
149
149
  }
150
150
  }
151
151
  getMessages() {
152
152
  return this.messages;
153
153
  }
154
- async revokeMessages(e) {
154
+ async revokeMessages(t) {
155
155
  return this.options.messageCollector ? (await this.options.messageCollector.getMessagesByAgentId(
156
156
  this.id,
157
- e
158
- )).map((t) => t.role === "user" ? new b(t.content) : t.role === "assistant" ? new f({
159
- content: t.content,
160
- tool_calls: t.toolCalls
161
- }) : new T({
162
- content: t.content || t.confirm?.result,
163
- tool_call_id: t.id
164
- })) : [];
157
+ t
158
+ )).map((e) => {
159
+ if (e.role === "user")
160
+ return new f(e.content);
161
+ if (e.role === "assistant")
162
+ return new b({
163
+ content: e.content,
164
+ tool_calls: e.toolCalls
165
+ });
166
+ const n = e.result || e.confirm?.result;
167
+ return new T({
168
+ content: (n?.type === "success" ? this.anyToString(n.content) : n?.reason) || "",
169
+ tool_call_id: e.id
170
+ });
171
+ }) : [];
172
+ }
173
+ anyToString(t) {
174
+ return typeof t == "object" ? JSON.stringify(t) : t;
165
175
  }
166
176
  }
167
177
  export {
package/dist/es/index.mjs CHANGED
@@ -1,13 +1,13 @@
1
- import { default as a } from "./cluster/instance.mjs";
2
- import { default as l } from "./cluster/readableHook.mjs";
3
- import { default as s } from "./cluster/fileMessageCollector.mjs";
4
- import { default as m } from "./callback/LLMMessage.mjs";
5
- import { default as u } from "./middleware/dynamicToolInterceptor.mjs";
6
- import "@shuttle-ai/type";
1
+ import { default as r } from "./cluster/instance.mjs";
2
+ import { default as t } from "./cluster/readableHook.mjs";
3
+ import { default as f } from "./cluster/fileMessageCollector.mjs";
4
+ import { default as d } from "./callback/LLMMessage.mjs";
5
+ import { default as p } from "./middleware/dynamicToolInterceptor.mjs";
6
+ export * from "@shuttle-ai/type";
7
7
  export {
8
- a as AgentCluster,
9
- s as FileMessageCollector,
10
- m as LLMMessage,
11
- u as dynamicToolInterceptorMiddleware,
12
- l as readableHook
8
+ r as AgentCluster,
9
+ f as FileMessageCollector,
10
+ d as LLMMessage,
11
+ p as dynamicToolInterceptorMiddleware,
12
+ t as readableHook
13
13
  };
@@ -1,8 +1,8 @@
1
- import { createMiddleware as C } from "langchain";
2
- import { DynamicTool as p, DynamicStructuredTool as u } from "@langchain/core/tools";
1
+ import { createMiddleware as _ } from "langchain";
2
+ import { DynamicTool as C, DynamicStructuredTool as w } from "@langchain/core/tools";
3
3
  import { ToolMessage as s } from "@langchain/core/messages";
4
- import w from "../cluster/instance.mjs";
5
- const h = C({
4
+ import y from "../cluster/instance.mjs";
5
+ const k = _({
6
6
  name: "dynamicToolInterceptorMiddleware",
7
7
  wrapToolCall: async (o, i) => {
8
8
  const e = o.runtime.context, a = {
@@ -13,19 +13,19 @@ const h = C({
13
13
  agentId: e._agentId,
14
14
  workId: e._agentCluster.id
15
15
  };
16
- let t;
17
- if (o.tool instanceof p || o.tool instanceof u || o.tool && "extras" in o.tool) {
16
+ let t, d = !1;
17
+ if (o.tool instanceof C || o.tool instanceof w || o.tool && "extras" in o.tool) {
18
18
  const l = o.tool.extras || {};
19
19
  if (!l.skipReport) {
20
20
  const m = !M(l, e._agentCluster), r = e._agentCluster.getLastAiMessage(
21
21
  e._agentId
22
22
  );
23
23
  a.aiMessageId = r?.id || "";
24
- const f = r?.toolCalls?.find(
24
+ const p = r?.toolCalls?.find(
25
25
  (c) => c.id === o.toolCall.id
26
26
  ), n = await e._agentCluster.options.hooks.onToolStart({
27
27
  role: "assistant_tool",
28
- toolCall: f,
28
+ toolCall: p,
29
29
  needConfirm: l.remote || m,
30
30
  id: r?.id || "",
31
31
  agentId: e._agentId,
@@ -41,27 +41,33 @@ const h = C({
41
41
  content: typeof n.result == "object" ? JSON.stringify(n.result) : n.result || "success",
42
42
  tool_call_id: o.toolCall.id || ""
43
43
  });
44
- const d = {
44
+ const g = {
45
45
  agentId: e._agentId,
46
46
  messageId: r?.id || "",
47
47
  toolId: o.toolCall.id || ""
48
48
  };
49
49
  if (n.newArgs) {
50
50
  o.toolCall.args = n.newArgs;
51
- const g = o.state.messages[o.state.messages.length - 1].tool_calls?.find(
52
- (_) => _.id === o.toolCall.id
51
+ const f = o.state.messages[o.state.messages.length - 1].tool_calls?.find(
52
+ (u) => u.id === o.toolCall.id
53
53
  );
54
- g && (g.args = n.newArgs);
54
+ f && (f.args = n.newArgs);
55
55
  }
56
56
  try {
57
- t = await i(o), t instanceof s || "content" in t ? e._agentCluster.options.hooks.onToolEnd?.(
58
- d,
59
- t.content
60
- ) : e._agentCluster.options.hooks.onToolEnd?.(d, "{}");
57
+ t = await i(o), t instanceof s || "content" in t ? e._agentCluster.options.hooks.onToolEnd?.(g, {
58
+ type: "success",
59
+ content: t.content
60
+ }) : e._agentCluster.options.hooks.onToolEnd?.(g, {
61
+ type: "success",
62
+ content: "{}"
63
+ });
61
64
  } catch (c) {
62
65
  t = new s({
63
66
  content: c.message || "can not run tool",
64
67
  tool_call_id: o.toolCall.id || ""
68
+ }), d = !0, e._agentCluster.options.hooks.onToolEnd?.(g, {
69
+ type: "fail",
70
+ reason: t.content
65
71
  });
66
72
  }
67
73
  }
@@ -70,17 +76,23 @@ const h = C({
70
76
  try {
71
77
  t = await i(o);
72
78
  } catch (l) {
73
- t = new s({
79
+ d = !0, t = new s({
74
80
  content: l.message || "can not run tool",
75
81
  tool_call_id: o.toolCall.id || ""
76
82
  });
77
83
  }
78
- return "lg_name" in t && t.lg_name === "Command" && (t = t?.update?.messages?.[0]), t instanceof s && t.name !== w.CALL_SUB_AGENT_NAME && (a.content = t.content, e._agentCluster.addMessage(a)), t;
84
+ return "lg_name" in t && t.lg_name === "Command" && (t = t?.update?.messages?.[0]), t instanceof s && t.name !== y.CALL_SUB_AGENT_NAME && (a.result = d ? {
85
+ type: "fail",
86
+ reason: t.content
87
+ } : {
88
+ type: "success",
89
+ content: t.content
90
+ }, e._agentCluster.addMessage(a)), t;
79
91
  }
80
92
  });
81
93
  function M(o, i) {
82
94
  return o.scope === "autoRun" || i.options.autoRunScope === "always" || i.options.autoRunScope === "read" && o.scope !== "write";
83
95
  }
84
96
  export {
85
- h as default
97
+ k as default
86
98
  };
@@ -19,16 +19,17 @@ export default class AgentCluster extends Runnable {
19
19
  normalizationTools(tools: (ShuttleAi.Tool.Define | ClientTool)[]): (ClientTool | import('langchain').DynamicStructuredTool<import('@langchain/core/utils/types').ZodObjectV3, Record<string, any> | undefined, any, string, string>)[];
20
20
  customToolToDynamicTool(_tool: ShuttleAi.Tool.Define): import('langchain').DynamicStructuredTool<import('@langchain/core/utils/types').ZodObjectV3, Record<string, any> | undefined, any, string, string>;
21
21
  subAgentToDynamicTool(subAgents: ShuttleAi.SubAgent.Define[], agentId: string): import('langchain').DynamicStructuredTool<z.ZodObject<{
22
- subAgentName: z.ZodLiteral<any>;
22
+ subAgentName: z.ZodLiteral<string>;
23
23
  request: z.ZodString;
24
24
  }, z.core.$strip>, {
25
25
  subAgentName: string;
26
26
  request: string;
27
27
  }, {
28
- subAgentName: any;
28
+ subAgentName: string;
29
29
  request: string;
30
- }, any, string>;
31
- getLastAiMessage(agentId: string): any;
30
+ }, string, string>;
31
+ getLastAiMessage(agentId: string): ShuttleAi.Message.AI | undefined;
32
32
  getMessages(): ShuttleAi.Message.Define[];
33
33
  private revokeMessages;
34
+ private anyToString;
34
35
  }
@@ -1,6 +1,7 @@
1
1
  import { ClientTool } from '@langchain/core/tools';
2
2
  import { CreateAgentParams } from 'langchain';
3
3
  import { default as AgentCluster } from './cluster/instance';
4
+ export * from '@shuttle-ai/type';
4
5
  declare module '@shuttle-ai/type' {
5
6
  namespace ShuttleAi {
6
7
  namespace Cluster {
@@ -44,7 +45,7 @@ declare module '@shuttle-ai/type' {
44
45
  onAgentStart: (options: ShuttleAi.Ask.AgentStart['data']) => Promise<ToolsWithSubAgents & Omit<CreateAgentParams, 'tools'>>;
45
46
  onAgentEnd?: (agentId: string) => void;
46
47
  onToolStart: (tool: ShuttleAi.Message.AITool) => Promise<ShuttleAi.Tool.ConfirmResult>;
47
- onToolEnd?: (toolPath: ShuttleAi.Tool.Path, result: any) => void;
48
+ onToolEnd?: (toolPath: ShuttleAi.Tool.Path, result: Tool.Result) => void;
48
49
  }
49
50
  interface MessageCollector {
50
51
  saveMessage: (message: ShuttleAi.Message.Define) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shuttle-ai/agent",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "author": "Mingbing-get <1508850533@qq.com>",
5
5
  "license": "MIT",
6
6
  "description": "Shuttle AI 智能体操作库",
@@ -24,7 +24,7 @@
24
24
  "@langchain/core": "^1.1.19",
25
25
  "@langchain/openai": "^1.2.4",
26
26
  "zod": "^4.3.5",
27
- "@shuttle-ai/type": "0.0.5"
27
+ "@shuttle-ai/type": "0.0.7"
28
28
  },
29
29
  "devDependencies": {
30
30
  "typescript": "^5.3.3",