@shuttle-ai/client 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ ## `@shuttle-ai/client`
2
+
3
+ #### 说明
4
+
5
+ 该部分是shuttle-ai的客户端操作包
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});class n{constructor(s){this.options=s,this._messages=[...s.history||[]],this._status=s.status||"idle"}_children=[];_messages=[];_status="idle";listener={status:[],messages:[],aiMessage:[],toolMessage:[],subAgents:[]};addChild(s,t){this._children.push(s),this.trigger("subAgents",void 0);const e=this.findAiMessageById(t);e&&(e.subAgents=[...e.subAgents||[],{id:s.options.id,name:s.options.name}],this.trigger("aiMessage",e))}run(){this._status="running",this.trigger("status",this._status)}end(){this._status="idle",this.trigger("status",this._status)}addChunk(s){const t=this._messages[this._messages.length-1];t.role==="assistant"&&t.id===s.id?(t.content+=s.content,this.trigger("aiMessage",t)):(this._messages.push({role:"assistant",content:s.content,id:s.id,agentId:this.options.id,workId:this.options.work.id}),this.trigger("messages",this._messages))}addMessage(s){this._messages.push(s),this.trigger("messages",this._messages)}revokeMessages(s){this._messages=s,this._status="idle",this.trigger("messages",this._messages),this.trigger("status",this._status)}addToolCall(s){const t=this.findAiMessageById(s.id);t&&(t.toolCalls=[...t.toolCalls||[],s.toolCall],this._messages.push({role:"tool",name:s.toolCall.name,id:s.toolCall.id,aiMessageId:s.id,agentId:this.options.id,workId:this.options.work.id,confirm:s.needConfirm?void 0:{type:"confirm"}}),this.trigger("aiMessage",t),this.trigger("messages",this._messages),s.needConfirm&&this.checkAutoRun(s.toolCall.name)&&this.confirmTool(s.toolCall.id,{type:"confirm"}))}endTool(s){const t=this.findToolMessageById(s.toolPath.toolId);t&&(t.content=s.toolResult,this.trigger("toolMessage",t))}async confirmTool(s,t){const e=this.findToolMessageById(s);if(!e)return;const i=this.findAiMessageById(e.aiMessageId);if(i){if(t.type!=="reject"){const o=this.options.tools?.find(r=>r.name===e.name);if(o?.run.type==="fn"){const r=i.toolCalls?.find(a=>a.id===e.id);t.result=await this.runTool(o.run.fn,r),t.type="confirmWithResult"}}await this.options.work.options.transporter.report({type:"toolConfirm",workId:this.options.work.id,data:{toolId:s,result:t}}),e.confirm=t,this.trigger("toolMessage",e)}}findToolMessageById(s){let t;for(let e=this._messages.length-1;e>=0;e--){const i=this._messages[e];if(i.role==="tool"&&i.id===s){t=i;break}}return t}findAiMessageById(s){let t;for(let e=this._messages.length-1;e>=0;e--){const i=this._messages[e];if(i.role==="assistant"&&i.id===s){t=i;break}}return t}revoke(){return this.options.work.revokeAgent(this.options.id,this.options.name)}checkAutoRun(s){const t=this.options.tools?.find(e=>e.name===s);return t?t.extras?.onlyShow||t.extras?.scope==="autoRun"||this.options.work.autoRunScope==="always"?!0:this.options.work.autoRunScope==="read"?t.extras?.scope==="read":!1:!1}async runTool(s,t){if(!t)return{status:"error",message:"toolCall is required"};try{return await s(t.args||{})}catch(e){return{status:"error",message:e.message}}}trigger(s,t){this.listener[s].forEach(e=>e(t))}on(s,t){return this.listener[s].push(t),()=>{this.listener[s]=this.listener[s].filter(e=>e!==t)}}get children(){return this._children}get messages(){return this._messages}get status(){return this._status}}exports.default=n;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./transporter/http/index.cjs");require("@shuttle-ai/type");const t=require("./work.cjs"),r=require("./agent.cjs");exports.HttpTransporter=e.default;exports.AgentWork=t.default;exports.Agent=r.default;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const n=require("axios");class u{constructor(t){this._options=t}async request(t,a,{defaultPath:o,defaultMethod:i="POST"}){let e=t?.path||o;e.startsWith("/")||(e=`/${e}`);const r=t?.method||i,s=await n({url:`${this._options?.baseUrl||""}${e}`,method:r,headers:this._options?.requestHeaders,[r==="GET"?"params":"data"]:await t?.beforeSend?.(a)||a});return await this._options?.afterSend?.(s),await t?.afterSend?.(s),s.data}}exports.default=u;
@@ -0,0 +1,3 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const l=require("./base.cjs");class p extends l.default{constructor(t){super(t),this.options=t}async*invoke(t){let r=this.options?.invoke?.path||"/invoke";r.startsWith("/")||(r=`/${r}`);const s="POST",e=await this.options?.invoke?.beforeSend?.(t)||t,o=await fetch(`${this.options?.baseUrl||""}${r}`,{method:s,headers:this.options?.requestHeaders,body:JSON.stringify(e)});if(!o.ok)throw new Error("Failed to start work");const n=o.body?.getReader();if(!n)throw new Error("Failed to get reader");const i=new TextDecoder("utf-8");for(;;)try{const{done:a,value:c}=await n.read();if(a)break;const h=i.decode(c),d=this.mergeChunkContent(this.parseJsonStream(h));for(const u of d)yield u}catch{break}}parseJsonStream(t){const r=[],s=t.split(`
2
+
3
+ `).filter(Boolean);for(let e=0;e<s.length;e++){const o=s[e];try{r.push(JSON.parse(o))}catch{e+1<s.length&&(s[e+1]=o+s[e+1])}}return r}mergeChunkContent(t){let r;return t.reduce((s,e)=>(e.type==="chunk"?!r||r.data.chunk.id!==e.data.chunk.id?(r=e,s.push(e)):r.data.chunk.content+=e.data.chunk.content:s.push(e),s),[])}async report(t){await this.request(this.options?.report,t,{defaultPath:"/report"})}async revokeMessage(t){return await this.request(this.options?.revokeMessage,t,{defaultPath:"/revokeMessage"})}}exports.default=p;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const g=require("./agent.cjs");class u{constructor(t){this.options=t,this._autoRunScope=t.autoRunScope||"none"}static MAIN_AGENT_NAME="main_agent";static CALL_SUB_AGENT_NAME="call_sub_agent";_id="";_status="idle";_autoRunScope="none";agentMap=new Map;listenerMap={autoRunScope:[],status:[],agent:[]};get id(){return this._id}get status(){return this._status}get autoRunScope(){return this._autoRunScope}setAutoRunScope(t){this._autoRunScope=t,this.trigger("autoRunScope")}async invoke(t){this.setStatus("pending");const s=this.options.transporter.invoke({prompt:t,autoRunScope:this._autoRunScope,workId:this._id});for await(const e of s)e.type==="startWork"?(this._id=e.data.workId,this.setStatus("running")):e.type==="endWork"?this.setStatus("idle"):e.type==="agentStart"?await this.initAgent(e.data):e.type==="agentEnd"?this.agentMap.get(e.data.agentId)?.end():e.type==="chunk"?this.agentMap.get(e.data.chunk.agentId)?.addChunk(e.data.chunk):e.type==="toolStart"?this.agentMap.get(e.data.tool.agentId)?.addToolCall(e.data.tool):e.type==="toolEnd"&&this.agentMap.get(e.data.toolPath.agentId)?.endTool(e.data)}async revoke(t){this._id=t,this.agentMap.clear(),await this.revokeAgent(t,u.MAIN_AGENT_NAME)}async revokeAgent(t,s){const e=await this.options.transporter.revokeMessage({workId:this._id,agentId:t}),a=e.filter(n=>n.agentId===t);let i=this.agentMap.get(t);if(i)i.revokeMessages(a);else{const n=await this.getAgentParams(s);i=new g.default({id:t,name:s,work:this,history:a,status:"idle",tools:n.tools}),this.agentMap.set(t,i)}for(const n of e)if(!(n.role!=="assistant"||!n.subAgents?.length))for(const o of n.subAgents){const r=await this.getAgentParams(o.name),d=new g.default({id:o.id,name:o.name,work:this,history:e.filter(p=>p.agentId===o.id),status:"waitRevoke",tools:r.tools});this.agentMap.set(o.id,d),i.addChild(d,n.id)}this.trigger("agent")}on(t,s){const e=this.listenerMap[t];return e.push(s),()=>{const a=e.indexOf(s);a!==-1&&e.splice(a,1)}}getAgent(t){return this.agentMap.get(t)}getRootAgent(){return this.agentMap.get(this._id)}trigger(t){this.listenerMap[t].forEach(e=>e())}setStatus(t){this._status=t,this.trigger("status")}addAgent(t,s){if(t.options.parentId&&s){const e=this.agentMap.get(t.options.parentId);e&&e.addChild(t,s)}this.agentMap.set(t.options.id,t),this.trigger("agent")}async initAgent(t){const s={type:"agentStart",workId:this._id,data:{agentId:t.agentId,params:{}}},e=await this.getAgentParams(t.agentName);s.data.params={...e,tools:e.tools?.filter(n=>!n.extras?.disableExport)?.map(n=>{const{run:o,...r}=n;return r})};const a={role:"user",content:t.content,id:new Date().toISOString(),agentId:t.agentId,workId:this._id},i=this.agentMap.get(t.agentId);if(i)i.addMessage(a);else{const n=new g.default({id:t.agentId,name:t.agentName,work:this,history:[a],status:"running",parentId:t.parentAgentId,tools:e.tools});this.addAgent(n,t.beloneMessageId)}return this.options.transporter.report(s)}async getAgentParams(t){return typeof this.options.initAgent=="function"?await this.options.initAgent(t):this.options.initAgent?this.options.initAgent[t]||{}:{}}}exports.default=u;
@@ -0,0 +1,160 @@
1
+ class g {
2
+ constructor(s) {
3
+ this.options = s, this._messages = [...s.history || []], this._status = s.status || "idle";
4
+ }
5
+ _children = [];
6
+ _messages = [];
7
+ _status = "idle";
8
+ listener = {
9
+ status: [],
10
+ messages: [],
11
+ aiMessage: [],
12
+ toolMessage: [],
13
+ subAgents: []
14
+ };
15
+ addChild(s, t) {
16
+ this._children.push(s), this.trigger("subAgents", void 0);
17
+ const e = this.findAiMessageById(t);
18
+ e && (e.subAgents = [
19
+ ...e.subAgents || [],
20
+ {
21
+ id: s.options.id,
22
+ name: s.options.name
23
+ }
24
+ ], this.trigger("aiMessage", e));
25
+ }
26
+ run() {
27
+ this._status = "running", this.trigger("status", this._status);
28
+ }
29
+ end() {
30
+ this._status = "idle", this.trigger("status", this._status);
31
+ }
32
+ addChunk(s) {
33
+ const t = this._messages[this._messages.length - 1];
34
+ t.role === "assistant" && t.id === s.id ? (t.content += s.content, this.trigger("aiMessage", t)) : (this._messages.push({
35
+ role: "assistant",
36
+ content: s.content,
37
+ id: s.id,
38
+ agentId: this.options.id,
39
+ workId: this.options.work.id
40
+ }), this.trigger("messages", this._messages));
41
+ }
42
+ addMessage(s) {
43
+ this._messages.push(s), this.trigger("messages", this._messages);
44
+ }
45
+ revokeMessages(s) {
46
+ this._messages = s, this._status = "idle", this.trigger("messages", this._messages), this.trigger("status", this._status);
47
+ }
48
+ addToolCall(s) {
49
+ const t = this.findAiMessageById(s.id);
50
+ t && (t.toolCalls = [...t.toolCalls || [], s.toolCall], this._messages.push({
51
+ role: "tool",
52
+ name: s.toolCall.name,
53
+ id: s.toolCall.id,
54
+ aiMessageId: s.id,
55
+ agentId: this.options.id,
56
+ workId: this.options.work.id,
57
+ confirm: s.needConfirm ? void 0 : {
58
+ type: "confirm"
59
+ }
60
+ }), this.trigger("aiMessage", t), this.trigger("messages", this._messages), s.needConfirm && this.checkAutoRun(s.toolCall.name) && this.confirmTool(s.toolCall.id, { type: "confirm" }));
61
+ }
62
+ endTool(s) {
63
+ const t = this.findToolMessageById(s.toolPath.toolId);
64
+ t && (t.content = s.toolResult, this.trigger("toolMessage", t));
65
+ }
66
+ async confirmTool(s, t) {
67
+ const e = this.findToolMessageById(s);
68
+ if (!e) return;
69
+ const i = this.findAiMessageById(e.aiMessageId);
70
+ if (i) {
71
+ if (t.type !== "reject") {
72
+ const o = this.options.tools?.find(
73
+ (r) => r.name === e.name
74
+ );
75
+ if (o?.run.type === "fn") {
76
+ const r = i.toolCalls?.find(
77
+ (a) => a.id === e.id
78
+ );
79
+ t.result = await this.runTool(o.run.fn, r), t.type = "confirmWithResult";
80
+ }
81
+ }
82
+ await this.options.work.options.transporter.report({
83
+ type: "toolConfirm",
84
+ workId: this.options.work.id,
85
+ data: {
86
+ toolId: s,
87
+ result: t
88
+ }
89
+ }), e.confirm = t, this.trigger("toolMessage", e);
90
+ }
91
+ }
92
+ findToolMessageById(s) {
93
+ let t;
94
+ for (let e = this._messages.length - 1; e >= 0; e--) {
95
+ const i = this._messages[e];
96
+ if (i.role === "tool" && i.id === s) {
97
+ t = i;
98
+ break;
99
+ }
100
+ }
101
+ return t;
102
+ }
103
+ findAiMessageById(s) {
104
+ let t;
105
+ for (let e = this._messages.length - 1; e >= 0; e--) {
106
+ const i = this._messages[e];
107
+ if (i.role === "assistant" && i.id === s) {
108
+ t = i;
109
+ break;
110
+ }
111
+ }
112
+ return t;
113
+ }
114
+ revoke() {
115
+ return this.options.work.revokeAgent(this.options.id, this.options.name);
116
+ }
117
+ checkAutoRun(s) {
118
+ const t = this.options.tools?.find(
119
+ (e) => e.name === s
120
+ );
121
+ return t ? t.extras?.onlyShow || t.extras?.scope === "autoRun" || this.options.work.autoRunScope === "always" ? !0 : this.options.work.autoRunScope === "read" ? t.extras?.scope === "read" : !1 : !1;
122
+ }
123
+ async runTool(s, t) {
124
+ if (!t)
125
+ return {
126
+ status: "error",
127
+ message: "toolCall is required"
128
+ };
129
+ try {
130
+ return await s(t.args || {});
131
+ } catch (e) {
132
+ return {
133
+ status: "error",
134
+ message: e.message
135
+ };
136
+ }
137
+ }
138
+ trigger(s, t) {
139
+ this.listener[s].forEach((e) => e(t));
140
+ }
141
+ on(s, t) {
142
+ return this.listener[s].push(t), () => {
143
+ this.listener[s] = this.listener[s].filter(
144
+ (e) => e !== t
145
+ );
146
+ };
147
+ }
148
+ get children() {
149
+ return this._children;
150
+ }
151
+ get messages() {
152
+ return this._messages;
153
+ }
154
+ get status() {
155
+ return this._status;
156
+ }
157
+ }
158
+ export {
159
+ g as default
160
+ };
@@ -0,0 +1,9 @@
1
+ import { default as o } from "./transporter/http/index.mjs";
2
+ import "@shuttle-ai/type";
3
+ import { default as f } from "./work.mjs";
4
+ import { default as m } from "./agent.mjs";
5
+ export {
6
+ m as Agent,
7
+ f as AgentWork,
8
+ o as HttpTransporter
9
+ };
@@ -0,0 +1,23 @@
1
+ import p from "axios";
2
+ class c {
3
+ constructor(t) {
4
+ this._options = t;
5
+ }
6
+ async request(t, e, {
7
+ defaultPath: o,
8
+ defaultMethod: i = "POST"
9
+ }) {
10
+ let s = t?.path || o;
11
+ s.startsWith("/") || (s = `/${s}`);
12
+ const r = t?.method || i, a = await p({
13
+ url: `${this._options?.baseUrl || ""}${s}`,
14
+ method: r,
15
+ headers: this._options?.requestHeaders,
16
+ [r === "GET" ? "params" : "data"]: await t?.beforeSend?.(e) || e
17
+ });
18
+ return await this._options?.afterSend?.(a), await t?.afterSend?.(a), a.data;
19
+ }
20
+ }
21
+ export {
22
+ c as default
23
+ };
@@ -0,0 +1,63 @@
1
+ import p from "./base.mjs";
2
+ class k extends p {
3
+ constructor(t) {
4
+ super(t), this.options = t;
5
+ }
6
+ async *invoke(t) {
7
+ let r = this.options?.invoke?.path || "/invoke";
8
+ r.startsWith("/") || (r = `/${r}`);
9
+ const s = "POST", e = await this.options?.invoke?.beforeSend?.(t) || t, o = await fetch(`${this.options?.baseUrl || ""}${r}`, {
10
+ method: s,
11
+ headers: this.options?.requestHeaders,
12
+ body: JSON.stringify(e)
13
+ });
14
+ if (!o.ok)
15
+ throw new Error("Failed to start work");
16
+ const n = o.body?.getReader();
17
+ if (!n)
18
+ throw new Error("Failed to get reader");
19
+ const i = new TextDecoder("utf-8");
20
+ for (; ; )
21
+ try {
22
+ const { done: a, value: h } = await n.read();
23
+ if (a)
24
+ break;
25
+ const c = i.decode(h), d = this.mergeChunkContent(this.parseJsonStream(c));
26
+ for (const u of d)
27
+ yield u;
28
+ } catch {
29
+ break;
30
+ }
31
+ }
32
+ parseJsonStream(t) {
33
+ const r = [], s = t.split(`
34
+
35
+ `).filter(Boolean);
36
+ for (let e = 0; e < s.length; e++) {
37
+ const o = s[e];
38
+ try {
39
+ r.push(JSON.parse(o));
40
+ } catch {
41
+ e + 1 < s.length && (s[e + 1] = o + s[e + 1]);
42
+ }
43
+ }
44
+ return r;
45
+ }
46
+ mergeChunkContent(t) {
47
+ let r;
48
+ return t.reduce((s, e) => (e.type === "chunk" ? !r || r.data.chunk.id !== e.data.chunk.id ? (r = e, s.push(e)) : r.data.chunk.content += e.data.chunk.content : s.push(e), s), []);
49
+ }
50
+ async report(t) {
51
+ await this.request(this.options?.report, t, {
52
+ defaultPath: "/report"
53
+ });
54
+ }
55
+ async revokeMessage(t) {
56
+ return await this.request(this.options?.revokeMessage, t, {
57
+ defaultPath: "/revokeMessage"
58
+ });
59
+ }
60
+ }
61
+ export {
62
+ k as default
63
+ };
@@ -0,0 +1,149 @@
1
+ import g from "./agent.mjs";
2
+ class d {
3
+ constructor(t) {
4
+ this.options = t, this._autoRunScope = t.autoRunScope || "none";
5
+ }
6
+ static MAIN_AGENT_NAME = "main_agent";
7
+ static CALL_SUB_AGENT_NAME = "call_sub_agent";
8
+ _id = "";
9
+ _status = "idle";
10
+ _autoRunScope = "none";
11
+ agentMap = /* @__PURE__ */ new Map();
12
+ listenerMap = {
13
+ autoRunScope: [],
14
+ status: [],
15
+ agent: []
16
+ };
17
+ get id() {
18
+ return this._id;
19
+ }
20
+ get status() {
21
+ return this._status;
22
+ }
23
+ get autoRunScope() {
24
+ return this._autoRunScope;
25
+ }
26
+ setAutoRunScope(t) {
27
+ this._autoRunScope = t, this.trigger("autoRunScope");
28
+ }
29
+ async invoke(t) {
30
+ this.setStatus("pending");
31
+ const s = this.options.transporter.invoke({
32
+ prompt: t,
33
+ autoRunScope: this._autoRunScope,
34
+ workId: this._id
35
+ });
36
+ for await (const e of s)
37
+ e.type === "startWork" ? (this._id = e.data.workId, this.setStatus("running")) : e.type === "endWork" ? this.setStatus("idle") : e.type === "agentStart" ? await this.initAgent(e.data) : e.type === "agentEnd" ? this.agentMap.get(e.data.agentId)?.end() : e.type === "chunk" ? this.agentMap.get(e.data.chunk.agentId)?.addChunk(e.data.chunk) : e.type === "toolStart" ? this.agentMap.get(e.data.tool.agentId)?.addToolCall(e.data.tool) : e.type === "toolEnd" && this.agentMap.get(e.data.toolPath.agentId)?.endTool(e.data);
38
+ }
39
+ async revoke(t) {
40
+ this._id = t, this.agentMap.clear(), await this.revokeAgent(t, d.MAIN_AGENT_NAME);
41
+ }
42
+ async revokeAgent(t, s) {
43
+ const e = await this.options.transporter.revokeMessage({
44
+ workId: this._id,
45
+ agentId: t
46
+ }), a = e.filter(
47
+ (n) => n.agentId === t
48
+ );
49
+ let i = this.agentMap.get(t);
50
+ if (i)
51
+ i.revokeMessages(a);
52
+ else {
53
+ const n = await this.getAgentParams(s);
54
+ i = new g({
55
+ id: t,
56
+ name: s,
57
+ work: this,
58
+ history: a,
59
+ status: "idle",
60
+ tools: n.tools
61
+ }), this.agentMap.set(t, i);
62
+ }
63
+ for (const n of e)
64
+ if (!(n.role !== "assistant" || !n.subAgents?.length))
65
+ for (const o of n.subAgents) {
66
+ const r = await this.getAgentParams(o.name), u = new g({
67
+ id: o.id,
68
+ name: o.name,
69
+ work: this,
70
+ history: e.filter((p) => p.agentId === o.id),
71
+ status: "waitRevoke",
72
+ tools: r.tools
73
+ });
74
+ this.agentMap.set(o.id, u), i.addChild(u, n.id);
75
+ }
76
+ this.trigger("agent");
77
+ }
78
+ on(t, s) {
79
+ const e = this.listenerMap[t];
80
+ return e.push(s), () => {
81
+ const a = e.indexOf(s);
82
+ a !== -1 && e.splice(a, 1);
83
+ };
84
+ }
85
+ getAgent(t) {
86
+ return this.agentMap.get(t);
87
+ }
88
+ getRootAgent() {
89
+ return this.agentMap.get(this._id);
90
+ }
91
+ trigger(t) {
92
+ this.listenerMap[t].forEach((e) => e());
93
+ }
94
+ setStatus(t) {
95
+ this._status = t, this.trigger("status");
96
+ }
97
+ addAgent(t, s) {
98
+ if (t.options.parentId && s) {
99
+ const e = this.agentMap.get(t.options.parentId);
100
+ e && e.addChild(t, s);
101
+ }
102
+ this.agentMap.set(t.options.id, t), this.trigger("agent");
103
+ }
104
+ async initAgent(t) {
105
+ const s = {
106
+ type: "agentStart",
107
+ workId: this._id,
108
+ data: {
109
+ agentId: t.agentId,
110
+ params: {}
111
+ }
112
+ }, e = await this.getAgentParams(t.agentName);
113
+ s.data.params = {
114
+ ...e,
115
+ tools: e.tools?.filter((n) => !n.extras?.disableExport)?.map((n) => {
116
+ const { run: o, ...r } = n;
117
+ return r;
118
+ })
119
+ };
120
+ const a = {
121
+ role: "user",
122
+ content: t.content,
123
+ id: (/* @__PURE__ */ new Date()).toISOString(),
124
+ agentId: t.agentId,
125
+ workId: this._id
126
+ }, i = this.agentMap.get(t.agentId);
127
+ if (i)
128
+ i.addMessage(a);
129
+ else {
130
+ const n = new g({
131
+ id: t.agentId,
132
+ name: t.agentName,
133
+ work: this,
134
+ history: [a],
135
+ status: "running",
136
+ parentId: t.parentAgentId,
137
+ tools: e.tools
138
+ });
139
+ this.addAgent(n, t.beloneMessageId);
140
+ }
141
+ return this.options.transporter.report(s);
142
+ }
143
+ async getAgentParams(t) {
144
+ return typeof this.options.initAgent == "function" ? await this.options.initAgent(t) : this.options.initAgent ? this.options.initAgent[t] || {} : {};
145
+ }
146
+ }
147
+ export {
148
+ d as default
149
+ };
@@ -0,0 +1,28 @@
1
+ import { ShuttleAi } from '@shuttle-ai/type';
2
+ export default class Agent {
3
+ readonly options: ShuttleAi.Client.Agent.Options;
4
+ private _children;
5
+ private _messages;
6
+ private _status;
7
+ private listener;
8
+ constructor(options: ShuttleAi.Client.Agent.Options);
9
+ addChild(agent: Agent, belongMessageId: string): void;
10
+ run(): void;
11
+ end(): void;
12
+ addChunk(chunk: ShuttleAi.Message.AIChunk): void;
13
+ addMessage(message: ShuttleAi.Message.Define): void;
14
+ revokeMessages(messages: ShuttleAi.Message.Define[]): void;
15
+ addToolCall(aiTool: ShuttleAi.Message.AITool): void;
16
+ endTool(info: ShuttleAi.Ask.ToolEnd['data']): void;
17
+ confirmTool(toolId: string, confirmResult: ShuttleAi.Tool.ConfirmResult): Promise<void>;
18
+ findToolMessageById(toolId: string): ShuttleAi.Message.Tool | undefined;
19
+ findAiMessageById(aiId: string): ShuttleAi.Message.AI | undefined;
20
+ revoke(): Promise<void>;
21
+ private checkAutoRun;
22
+ private runTool;
23
+ private trigger;
24
+ on<K extends keyof ShuttleAi.Client.Agent.EventMap>(type: K, cb: (data: ShuttleAi.Client.Agent.EventMap[K]) => void): () => void;
25
+ get children(): Agent[];
26
+ get messages(): ShuttleAi.Message.Define[];
27
+ get status(): ShuttleAi.Client.Agent.Status;
28
+ }
@@ -0,0 +1,4 @@
1
+ export * from './transporter';
2
+ export * from './type';
3
+ export { default as AgentWork } from './work';
4
+ export { default as Agent } from './agent';
@@ -0,0 +1,10 @@
1
+ import { Method } from 'axios';
2
+ import { NHttpTransporter } from './type';
3
+ export default class BaseHttpTransporter {
4
+ private _options?;
5
+ constructor(_options?: NHttpTransporter.Options | undefined);
6
+ protected request<T>(methodConfig: NHttpTransporter.MethodConfig<T> | undefined, data: any, { defaultPath, defaultMethod, }: {
7
+ defaultPath: string;
8
+ defaultMethod?: Method;
9
+ }): Promise<any>;
10
+ }
@@ -0,0 +1,14 @@
1
+ import { ShuttleAi } from '@shuttle-ai/type';
2
+ import { default as BaseHttpTransporter } from './base';
3
+ export default class HttpTransporter extends BaseHttpTransporter implements ShuttleAi.Client.Transporter {
4
+ private options?;
5
+ constructor(options?: ShuttleAi.Client.HttpTransporterOptions | undefined);
6
+ invoke(data: ShuttleAi.Client.StartWork): AsyncGenerator<ShuttleAi.Ask.Define, void, unknown>;
7
+ private parseJsonStream;
8
+ private mergeChunkContent;
9
+ report(data: ShuttleAi.Report.Define): Promise<void>;
10
+ revokeMessage(data: {
11
+ workId: string;
12
+ agentId: string;
13
+ }): Promise<any>;
14
+ }
@@ -0,0 +1,14 @@
1
+ import { RawAxiosRequestHeaders, AxiosResponse, Method } from 'axios';
2
+ export declare namespace NHttpTransporter {
3
+ interface MethodConfig<T> {
4
+ path?: string;
5
+ method?: Method;
6
+ beforeSend?: (data: T) => Promise<T>;
7
+ afterSend?: (response: AxiosResponse) => Promise<void>;
8
+ }
9
+ interface Options {
10
+ baseUrl?: string;
11
+ requestHeaders?: RawAxiosRequestHeaders;
12
+ afterSend?: (response: AxiosResponse) => Promise<void>;
13
+ }
14
+ }
@@ -0,0 +1 @@
1
+ export { default as HttpTransporter } from './http';
@@ -0,0 +1,76 @@
1
+ import { NHttpTransporter } from './transporter/http/type';
2
+ import { default as Work } from './work';
3
+ declare module '@shuttle-ai/type' {
4
+ namespace ShuttleAi {
5
+ namespace Tool {
6
+ interface Extras {
7
+ disableExport?: boolean;
8
+ onlyShow?: boolean;
9
+ }
10
+ }
11
+ namespace Client {
12
+ namespace Agent {
13
+ type Status = 'idle' | 'running' | 'waitRevoke';
14
+ interface Options {
15
+ id: string;
16
+ name: string;
17
+ work: Work;
18
+ status?: Status;
19
+ history?: Message.Define[];
20
+ parentId?: string;
21
+ tools?: WithRunTool[];
22
+ }
23
+ interface EventMap {
24
+ status: Status;
25
+ messages: Message.Define[];
26
+ subAgents: undefined;
27
+ aiMessage: Message.AI;
28
+ toolMessage: Message.Tool;
29
+ }
30
+ interface FnTool {
31
+ type: 'fn';
32
+ fn: (args: Record<string, any>) => Promise<any>;
33
+ }
34
+ interface RenderTool {
35
+ type: 'render';
36
+ }
37
+ interface WithRunTool extends Tool.Define {
38
+ run: FnTool | RenderTool;
39
+ }
40
+ interface WithRunToolParams extends Omit<Report.AgentStart['data']['params'], 'tools'> {
41
+ tools?: WithRunTool[];
42
+ }
43
+ }
44
+ namespace Work {
45
+ type Status = 'idle' | 'pending' | 'running';
46
+ type AutoRunScope = 'always' | 'read' | 'none';
47
+ interface Options {
48
+ transporter: Transporter;
49
+ initAgent?: Record<string, Agent.WithRunToolParams> | ((agentName: string) => Agent.WithRunToolParams | Promise<Agent.WithRunToolParams>);
50
+ autoRunScope?: AutoRunScope;
51
+ }
52
+ }
53
+ interface StartWork {
54
+ prompt: string;
55
+ workId?: string;
56
+ autoRunScope?: Work.AutoRunScope;
57
+ }
58
+ interface Transporter {
59
+ invoke: (data: StartWork) => AsyncGenerator<ShuttleAi.Ask.Define, void, unknown>;
60
+ report: (data: Report.Define) => Promise<void>;
61
+ revokeMessage: (data: {
62
+ workId: string;
63
+ agentId: string;
64
+ }) => Promise<ShuttleAi.Message.Define[]>;
65
+ }
66
+ interface HttpTransporterOptions extends NHttpTransporter.Options {
67
+ invoke?: Pick<NHttpTransporter.MethodConfig<StartWork>, 'path' | 'beforeSend'>;
68
+ report?: NHttpTransporter.MethodConfig<Report.Define>;
69
+ revokeMessage?: NHttpTransporter.MethodConfig<{
70
+ workId: string;
71
+ agentId: string;
72
+ }>;
73
+ }
74
+ }
75
+ }
76
+ }
@@ -0,0 +1,30 @@
1
+ import { ShuttleAi } from '@shuttle-ai/type';
2
+ import { default as Agent } from './agent';
3
+ type ListenerType = 'autoRunScope' | 'status' | 'agent';
4
+ export default class Work {
5
+ readonly options: ShuttleAi.Client.Work.Options;
6
+ static MAIN_AGENT_NAME: string;
7
+ static CALL_SUB_AGENT_NAME: string;
8
+ private _id;
9
+ private _status;
10
+ private _autoRunScope;
11
+ private agentMap;
12
+ private listenerMap;
13
+ constructor(options: ShuttleAi.Client.Work.Options);
14
+ get id(): string;
15
+ get status(): ShuttleAi.Client.Work.Status;
16
+ get autoRunScope(): ShuttleAi.Client.Work.AutoRunScope;
17
+ setAutoRunScope(scope: ShuttleAi.Client.Work.AutoRunScope): void;
18
+ invoke(prompt: string): Promise<void>;
19
+ revoke(workId: string): Promise<void>;
20
+ revokeAgent(agentId: string, agentName: string): Promise<void>;
21
+ on(type: ListenerType, cb: () => void): () => void;
22
+ getAgent(id: string): Agent | undefined;
23
+ getRootAgent(): Agent | undefined;
24
+ private trigger;
25
+ private setStatus;
26
+ private addAgent;
27
+ private initAgent;
28
+ private getAgentParams;
29
+ }
30
+ export {};
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@shuttle-ai/client",
3
+ "version": "0.0.1",
4
+ "author": "Mingbing-get <1508850533@qq.com>",
5
+ "license": "MIT",
6
+ "description": "Shuttle AI 客户端操作库",
7
+ "main": "dist/cjs/index.cjs",
8
+ "module": "dist/es/index.mjs",
9
+ "types": "dist/types/index.d.ts",
10
+ "type": "module",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/types/index.d.ts",
14
+ "import": "./dist/es/index.mjs",
15
+ "require": "./dist/cjs/index.cjs"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "dependencies": {
23
+ "zod": "^4.3.5",
24
+ "axios": "^1.13.2",
25
+ "@shuttle-ai/type": "0.0.1"
26
+ },
27
+ "devDependencies": {
28
+ "typescript": "^5.3.3"
29
+ },
30
+ "access": "public",
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "scripts": {
35
+ "build": "vite build",
36
+ "clean": "rm -rf dist",
37
+ "type-check": "tsc --noEmit",
38
+ "test": "echo \"Error: no test specified\" && exit 1"
39
+ }
40
+ }