@atgs/tapeworm 0.1.6 → 0.1.8

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.
Files changed (67) hide show
  1. package/README.md +45 -35
  2. package/dist/agent/agent.d.ts +102 -5
  3. package/dist/conversation/conversation.d.ts +15 -2
  4. package/dist/conversation/message.d.ts +12 -0
  5. package/dist/index.d.ts +7 -0
  6. package/dist/model/OllamaModel.d.ts +11 -1
  7. package/dist/model/model.d.ts +10 -0
  8. package/dist/tapeworm.cjs.js +1 -1
  9. package/dist/tapeworm.es.js +150 -91
  10. package/dist/tapeworm.umd.js +1 -1
  11. package/dist/tool/tool.d.ts +4 -7
  12. package/dist/tool/toolCall.d.ts +8 -0
  13. package/dist/tool/toolDecorators.d.ts +1 -1
  14. package/dist/tool/toolschema.d.ts +13 -1
  15. package/docs/.nojekyll +1 -0
  16. package/docs/assets/hierarchy.js +1 -0
  17. package/docs/assets/highlight.css +85 -0
  18. package/docs/assets/icons.js +18 -0
  19. package/docs/assets/icons.svg +1 -0
  20. package/docs/assets/main.js +60 -0
  21. package/docs/assets/navigation.js +1 -0
  22. package/docs/assets/search.js +1 -0
  23. package/docs/assets/style.css +1633 -0
  24. package/docs/classes/agent_agent.Agent.html +48 -0
  25. package/docs/classes/agent_agent.AgentBuilder.html +26 -0
  26. package/docs/classes/conversation_conversation.Conversation.html +10 -0
  27. package/docs/classes/conversation_conversation.ConversationManager.html +8 -0
  28. package/docs/classes/conversation_conversation.DefaultConversationManager.html +7 -0
  29. package/docs/classes/conversation_message.Content.html +18 -0
  30. package/docs/classes/conversation_message.Message.html +15 -0
  31. package/docs/classes/conversation_message.MessageBuilder.html +32 -0
  32. package/docs/classes/conversation_message.MessageComponent.html +6 -0
  33. package/docs/classes/conversation_message.Thinking.html +18 -0
  34. package/docs/classes/conversation_message.ToolResult.html +20 -0
  35. package/docs/classes/model_OllamaModel.OllamaModel.html +32 -0
  36. package/docs/classes/model_model.Model.html +7 -0
  37. package/docs/classes/model_model.ModelRequest.html +11 -0
  38. package/docs/classes/model_model.ModelRequestBuilder.html +12 -0
  39. package/docs/classes/tool_tool.Tool.html +15 -0
  40. package/docs/classes/tool_toolCall.ToolCall.html +22 -0
  41. package/docs/classes/tool_toolCall.ToolCallBuilder.html +26 -0
  42. package/docs/classes/tool_toolCall.ToolNotFoundError.html +7 -0
  43. package/docs/classes/tool_toolschema.Parameter.html +23 -0
  44. package/docs/classes/tool_toolschema.ParameterBuilder.html +18 -0
  45. package/docs/classes/tool_toolschema.ToolSchema.html +14 -0
  46. package/docs/classes/tool_toolschema.ToolSchemaBuilder.html +14 -0
  47. package/docs/functions/agent_agent.defaultCallback.html +6 -0
  48. package/docs/functions/tool_toolDecorators.ToolDescription.html +1 -0
  49. package/docs/functions/tool_toolDecorators.ToolName.html +1 -0
  50. package/docs/functions/tool_toolDecorators.ToolOutput.html +1 -0
  51. package/docs/functions/tool_toolDecorators.ToolParameter.html +1 -0
  52. package/docs/hierarchy.html +1 -0
  53. package/docs/index.html +58 -0
  54. package/docs/modules/agent_agent.html +8 -0
  55. package/docs/modules/conversation_conversation.html +5 -0
  56. package/docs/modules/conversation_message.html +18 -0
  57. package/docs/modules/index.html +3 -0
  58. package/docs/modules/model_OllamaModel.html +6 -0
  59. package/docs/modules/model_model.html +5 -0
  60. package/docs/modules/tool_tool.html +1 -0
  61. package/docs/modules/tool_toolCall.html +4 -0
  62. package/docs/modules/tool_toolDecorators.html +3 -0
  63. package/docs/modules/tool_toolschema.html +3 -0
  64. package/docs/modules.html +1 -0
  65. package/docs/types/conversation_message.MessageComponentType.html +1 -0
  66. package/docs/variables/conversation_message.MessageComponentType.html +3 -0
  67. package/package.json +7 -3
package/README.md CHANGED
@@ -1,13 +1,11 @@
1
1
  ![Tapeworm Logo](https://raw.githubusercontent.com/andygrace227/tapeworm/main/tapeworm.svg)
2
2
 
3
- # Tapeworm
3
+ # Tapeworm Core
4
4
 
5
- <h3>In-browser and Node agent framework.</h3>
5
+ <h3>In-browser and Node Agent Framework.</h3>
6
6
 
7
7
  [![npm version](https://img.shields.io/npm/v/@atgs/tapeworm.svg?style=flat-square)](https://www.npmjs.org/package/@atgs/tapeworm.svg)
8
-
9
8
  [![npm downloads](https://img.shields.io/npm/dm/@atgs/tapeworm?style=flat-square)](https://npm-stat.com/charts.html?package=@atgs/tapeworm)
10
-
11
9
  [repo link](https://github.com/andygrace227/tapeworm)
12
10
 
13
11
  This is the root package for Tapeworm. You can consume other packages like @atgs/tapeworm_bedrock for AWS Bedrock support.
@@ -18,13 +16,22 @@ It provides an object-oriented API to create agents that run either on Node or w
18
16
 
19
17
  ## Current Features
20
18
 
21
- - Base API Defined.
22
19
  - Supports `function` tools.
23
20
  - Supports Ollama models.
24
- - Has a Babel plugin to make tool creation really easy.
21
+ - Has a Babel plugin to make tool creation easy.
22
+ - Has TS decorators to make tool creation really easy, too!
23
+ - Supports browser and Node.
24
+
25
+ ## Tapeworm's Tenets
26
+
27
+ - **Be the most ergonomic agentic solution for Node and the browser.** Each commit should make it easier to develop and deploy agentic AI solutions.
28
+ - **Be as model-agnostic as possible.** Use your own machine, AWS, Google, a literal potato... we don't care.
29
+ - **Keep things light.** We already waste so much water and energy with AI. The overhead from Tapeworm should be kept to a minimum when possible.
25
30
 
26
31
  ## Examples
27
32
 
33
+ ### How do I define a tool?
34
+
28
35
  #### With the babel plugin (@atgs/@atgs/babel-plugin-tapeworm-decorator) (recommended, super concise)
29
36
 
30
37
  ```js
@@ -50,22 +57,37 @@ class AdditionTool extends Tool {
50
57
  return a + b;
51
58
  }
52
59
  }
60
+ ```
53
61
 
54
- const ollama = new OllamaModel("http://localhost:11434", "gpt-oss:20b", {
55
- stream: false,
56
- });
57
-
58
- const agent = Agent.builder()
59
- .name("calculatorAgent")
60
- .tools([new AdditionTool()])
61
- .systemPrompt("You are an agent that runs math operations.")
62
- .model(ollama)
63
- .build();
64
-
65
- await agent.invoke("What is 9 + 10?");
62
+ #### With Typescript Decorators
63
+
64
+ ```ts
65
+ @ToolName("AdditionTool")
66
+ @ToolDescription("Adds two numbers together.")
67
+ @ToolParameter({
68
+ name: "a",
69
+ description: "The first number to add",
70
+ required: true,
71
+ type: "number",
72
+ })
73
+ @ToolParameter({
74
+ name: "b",
75
+ description: "The second number to add",
76
+ required: true,
77
+ type: "number",
78
+ })
79
+ @ToolOutput("The sum of inputs a and b")
80
+ class AdditionTool extends Tool {
81
+ execute(input: any) {
82
+ let a = +input.a;
83
+ let b = +input.b;
84
+ console.log("Adding " + a + " and " + b + ": " + (a + b));
85
+ return a + b;
86
+ }
87
+ }
66
88
  ```
67
89
 
68
- #### Without the plugin (still pretty readable.)
90
+ #### Without the plugin (still pretty readable)
69
91
 
70
92
  ```js
71
93
  import {
@@ -77,18 +99,10 @@ import {
77
99
  } from "../../dist/tapeworm.es.js";
78
100
 
79
101
  class AdditionTool extends Tool {
80
- /**
81
- * Unique name used to reference this tool.
82
- * @returns Tool identifier string.
83
- */
84
102
  getName() {
85
103
  return "AdditionTool";
86
104
  }
87
105
 
88
- /**
89
- * Short description provided to the model.
90
- * @returns Human-readable explanation of the tool.
91
- */
92
106
  getDescription() {
93
107
  return "Adds two numbers together.";
94
108
  }
@@ -117,9 +131,11 @@ class AdditionTool extends Tool {
117
131
  return a + b;
118
132
  }
119
133
  }
134
+ ```
120
135
 
121
- // Because this is a test file, we are going to run this locally using Ollama
136
+ #### Then calling the agent:
122
137
 
138
+ ```js
123
139
  const ollama = new OllamaModel("http://localhost:11434", "gpt-oss:20b", {
124
140
  stream: false,
125
141
  });
@@ -131,15 +147,9 @@ const agent = Agent.builder()
131
147
  .model(ollama)
132
148
  .build();
133
149
 
134
- await agent.invoke("What is 9 + 10");
150
+ await agent.invoke("What is 9 + 10?");
135
151
  ```
136
152
 
137
- ## Tapeworm's Tenets
138
-
139
- - **Be the most ergonomic agentic solution for Node and the browser.** Each commit should make it easier to develop and deploy agentic AI solutions.
140
- - **Be as model-agnostic as possible.** Use your own machine, AWS, Google, a literal potato... we don't care.
141
- - **Keep things light.** We already waste so much water and energy with AI. The overhead from Tapeworm should be kept to a minimum when possible.
142
-
143
153
  ## Roadmap
144
154
 
145
155
  Tapeworm seeks to be the most ergonomic agentic solution for Node and the browser.
@@ -1,27 +1,90 @@
1
+ /**
2
+ * The Agent module contains all things related to Agents, including:
3
+ * - the Agent class
4
+ * - the AgentBuilder class
5
+ * - the default callback handler for an Agent.
6
+ *
7
+ * This module contains most of the business logic for running the main agent loop.
8
+ *
9
+ * @module
10
+ */
1
11
  import Conversation, { ConversationManager } from "../conversation/conversation";
2
12
  import Message from "../conversation/message";
3
13
  import { type Model } from "../model/model";
4
14
  import type Tool from "../tool/tool";
5
15
  import type ToolCall from "../tool/toolCall";
6
16
  /**
7
- * Coordinates a model, its tools, and the running conversation to fulfill user queries.
17
+ * Agents combine a model with your tools.
18
+ *
19
+ * To build an agent, use the AgentBuilder class:
20
+ *
21
+ * ```ts
22
+ * const agent = Agent.builder()
23
+ * .name("yourAgent")
24
+ * .tools([new YourTool()])
25
+ * .systemPrompt("You are an agent.")
26
+ * .model(yourModel)
27
+ * .build();
28
+ * ```
29
+ *
8
30
  */
9
31
  export default class Agent {
32
+ /**
33
+ * The name of the agent.
34
+ */
10
35
  name: string;
36
+ /**
37
+ * The system prompt (if any) for the agent.
38
+ */
11
39
  systemPrompt?: string;
40
+ /**
41
+ * The tools this agent knows about and can run.
42
+ */
12
43
  tools: Tool[];
44
+ /**
45
+ * The underlying model for the agent.
46
+ */
13
47
  model: Model;
48
+ /**
49
+ * The conversation for the agent.
50
+ * You do not normally need to set this parameter unless you are building a use case
51
+ * where you have a persistent session with an agent.
52
+ */
14
53
  conversation: Conversation;
54
+ /**
55
+ * The conversation manager for the agent.
56
+ * Normally, a converstation manager that does nothing will be used.
57
+ * When SummarizingConversationManager or RAGConversationManager is implemented, these will help you avoid
58
+ * token overflow.
59
+ */
15
60
  conversationManager?: ConversationManager;
16
- toolNameToIndexMap: any | undefined;
61
+ /**
62
+ * A cache for looking up tools in the Tools array.
63
+ * DO NOT MANUALLY SET THIS VALUE. AGENT AUTOMATICALLY TAKES CARE OF IT.
64
+ */
65
+ private toolNameToIndexMap;
66
+ /**
67
+ * The callback function, invoked for every response from the model.
68
+ * The default implementation just prints to std.out or your console.
69
+ */
17
70
  callback: (m: Message) => void;
71
+ /**
72
+ * This is the constructor for an Agent.
73
+ *
74
+ * i IMPLORE YOU not to use this method. You CAN, but you should be using the Builder instead
75
+ * for the best results, as this method WILL change with future updates.
76
+ *
77
+ * Builder will be a lot more stable and will always be backwards compatible.
78
+ */
18
79
  constructor(name: string, tools: Tool[], model: Model, conversationManager: ConversationManager, callback: (m: Message) => void);
19
80
  /**
20
81
  * Run the full agent loop for a user query: seed the conversation, invoke the model,
21
82
  * and execute any returned tool calls until completion.
83
+ * *
22
84
  * @param query User-provided input to hand to the agent.
85
+ * @param callback A function that handles the messages coming from the agent.
23
86
  */
24
- invoke(query: string): Promise<void>;
87
+ invoke(query: string, callback?: (m: Message) => void): Promise<void>;
25
88
  /**
26
89
  * Ask the backing model for the next response given the current conversation state.
27
90
  * @returns Parsed model response including content, thinking, and tool calls.
@@ -37,9 +100,12 @@ export default class Agent {
37
100
  * Build a lookup from tool name to index for efficient resolution of tool calls.
38
101
  */
39
102
  generateToolNameToIndexMap(): void;
103
+ /**
104
+ * Get a builder to build an Agent.
105
+ */
40
106
  static builder(): AgentBuilder;
41
107
  }
42
- declare class AgentBuilder {
108
+ export declare class AgentBuilder {
43
109
  _name: string;
44
110
  _systemPrompt?: string;
45
111
  _tools: Tool[];
@@ -48,14 +114,45 @@ declare class AgentBuilder {
48
114
  _conversationManager: ConversationManager;
49
115
  _toolNameToIndexMap: any | undefined;
50
116
  _callback: (m: Message) => void;
117
+ /**
118
+ * Set the name of the agent.
119
+ */
51
120
  name(name: string): AgentBuilder;
121
+ /**
122
+ * Set the system prompt of the agent.
123
+ */
52
124
  systemPrompt(systemPrompt: string | undefined): AgentBuilder;
125
+ /**
126
+ * Set the tools of the agent, if you already have an array of tools.
127
+ */
53
128
  tools(tools: Tool[]): AgentBuilder;
129
+ /**
130
+ * Add a tool, 1 by 1, to the agent..
131
+ */
54
132
  addTool(tool: Tool): AgentBuilder;
133
+ /**
134
+ * Set the underlying model for the agent.
135
+ */
55
136
  model(model: Model): AgentBuilder;
137
+ /**
138
+ * Set the conversation manager for the agent.
139
+ */
56
140
  conversationManager(mgr: ConversationManager): AgentBuilder;
141
+ /**
142
+ * Set the callback for the agent.
143
+ */
57
144
  callback(callback: (m: Message) => void): AgentBuilder;
145
+ /**
146
+ * Build the agent.
147
+ */
58
148
  build(): Agent;
59
149
  }
150
+ /**
151
+ * This function is Tapeworm's default callback function.
152
+ * If you do not specify your own callback function, then this will be called and all
153
+ * it will do is log output to the screen.
154
+ *
155
+ * You can override this per invocation or on the Agent itself to do other things
156
+ * with the LLM output.
157
+ */
60
158
  export declare function defaultCallback(m: Message): void;
61
- export {};
@@ -1,7 +1,20 @@
1
+ /**
2
+ * The Conversation module contains the Conversation class and the ConversationManager prototypes.
3
+ *
4
+ * The Conversation is a wrapper around both a manager and an array of messages.
5
+ *
6
+ * The Conversation Manager is an object that can perform operations on only the conversation.
7
+ *
8
+ * While no Conversation Managers have been implemented yet, they will allow resilience to overflowing context windows.
9
+ *
10
+ * @module
11
+ */
1
12
  import type { Message } from "..";
2
13
  import type { Model } from "../model/model";
3
14
  /**
4
- * Maintains ordered chat messages and delegates to a conversation manager for compaction.
15
+ * A Conversation holds an array of messages and its associated manager.
16
+ *
17
+ * Conversations are (mostly) immutable, until the manager steps in and compacts the conversation.
5
18
  */
6
19
  export default class Conversation {
7
20
  messages: Message[];
@@ -17,7 +30,7 @@ export default class Conversation {
17
30
  append(message: Message): void;
18
31
  }
19
32
  /**
20
- * Strategy interface for pruning or transforming a conversation history.
33
+ * Interface for compacting a Conversation. Future implementations can summarize or do RAG-based compaction
21
34
  */
22
35
  export declare class ConversationManager {
23
36
  /**
@@ -1,3 +1,15 @@
1
+ /**
2
+ * The Messages module contains all the shapes that make up a single Message.
3
+ * - The actual Message class, which is a role + an array of MessageComponents
4
+ * - And a builder, too, which you should use 99.999% of the time!
5
+ * - An enum called MessageComponentType
6
+ * - The MessageComponents
7
+ * - **Content** - normal text from the LLM
8
+ * - **Thinking** - chain-of-thought reasoning from the LLM
9
+ * - **ToolCall** is not technically contained here, but it is a message component type
10
+ * - **ToolResult** - encodes the result of a tool call.
11
+ * @module
12
+ */
1
13
  import type ToolCall from "../tool/toolCall";
2
14
  /**
3
15
  * Messages are the units of a Conversation
package/dist/index.d.ts CHANGED
@@ -1,3 +1,10 @@
1
+ /**
2
+ * The index module gathers the exports from Tapeworm.
3
+ *
4
+ * This file should be modified when new classes are introduced to Tapeworm
5
+ *
6
+ * @module
7
+ */
1
8
  export { default as Agent } from "./agent/agent";
2
9
  export { default as Conversation, ConversationManager, DefaultConversationManager, } from "./conversation/conversation";
3
10
  export { Model, ModelRequest, ModelRequestBuilder } from "./model/model";
@@ -1,8 +1,18 @@
1
+ /**
2
+ * Tapeworm's first mostly-working model is OllamaModel,
3
+ * which routes model requests to an Ollama endpoint on your local machine.
4
+ *
5
+ * Other Models will be housed in separate NPM packages to allow better portability
6
+ * and to leverage the existing NPM packages (for example, the AWS SDK in the case of Bedrock)
7
+ * for those models.
8
+ *
9
+ * @module
10
+ */
1
11
  import { Message } from "..";
2
12
  import ToolCall from "../tool/toolCall";
3
13
  import { Model, ModelRequest } from "./model";
4
14
  /**
5
- * Model adapter that translates between Tapeworm message/tool shapes and the Ollama chat API.
15
+ * The Ollama Model class. This translates between Tapeworm message/tool shapes and the Ollama chat API.
6
16
  */
7
17
  export default class OllamaModel extends Model {
8
18
  endpoint: string;
@@ -1,3 +1,13 @@
1
+ /**
2
+ * The Model module lays out the interface for a Tapeworm model.
3
+ *
4
+ * It contains the base Model class, which doesn't do anything other than throw errors and specify an interface,
5
+ * and also the ModelRequest and ModelRequestBuilder classes, which show what kind of shape a model expects to
6
+ * recieve upon invocation.
7
+ *
8
+ *
9
+ * @module
10
+ */
1
11
  import type Message from "../conversation/message";
2
12
  import type Tool from "../tool/tool";
3
13
  /**
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class w{messages;manager;constructor(){this.messages=[],this.manager=new g}append(e){this.messages.push(e),this.messages=this.manager.compact(this.messages)}}class M{compact(e){throw new y("No implementation for conversation manager!")}configure(e){throw new y("No implementation for conversation manager!")}}class g extends M{compact(e){return e}configure(e){}}class y extends Error{constructor(e){super(e),this.name="ConversationManagerNotImplemented"}}class u{role;content;constructor(e,o){this.role=e,this.content=o}static builder(){return new b}filter(e){return this.content.filter(o=>o.getMessageComponentType()==e)}}class b{_role;_content;role(e){return this._role=e,this}init(){this._content==null&&(this._content=[])}toolCall(e){return e==null?this:(this.init(),this._content.push(e),this)}toolCalls(e){if(e==null)return this;this.init();for(const o of e)this._content.push(o);return this}toolResult(e){return e==null?this:(this.init(),this._content.push(e),this)}thinking(e){return e==null?this:(this.init(),this._content.push(C.of(e)),this)}content(e){return e==null?this:(this.init(),this._content.push(N.of(e)),this)}build(){if(this._content==null||this._content.length==0)throw new Error("Role-only messages are not supported by Tapeworm.");return new u(this._role,this._content)}}const a={Content:"content",Thinking:"thinking",ToolCall:"toolcall",ToolResult:"toolresult"};class m{getMessageComponentType(){throw new Error("Message components that do not have a message component type are not allowed.")}}class N extends m{text;constructor(e){super(),this.text=e}getMessageComponentType(){return a.Content}get(){return this.text}static of(e){return new this(e)}}class C extends m{thought;constructor(e){super(),this.thought=e}getMessageComponentType(){return a.Thinking}get(){return this.thought}static of(e){return new this(e)}}class c extends m{id;toolName;toolResult;constructor(e,o,s){super(),this.id=e,this.toolName=o,this.toolResult=s}getMessageComponentType(){return a.ToolResult}static of(e,o){return new this(e.id,e.name,o)}}class P{async invoke(e){throw new v("The invoke function for this model was not correctly implemented.")}tokenLimit(){throw new v("The tokenLimit function for this model was not correctly implemented.")}}class q{messages;tools;constructor(e,o){this.messages=e,this.tools=o}static builder(){return new f}}class f{_messages;_tools;messages(e){return this._messages=e,this}tools(e){return this._tools=e,this}build(){if(this._tools==null&&(this._tools=[]),this._messages==null)throw new j("Requests to the model should include content.");return new q(this._messages,this._tools)}}class v extends Error{constructor(e){super(e),this.name="ModelNotImplementedError"}}class j extends Error{constructor(e){super(e),this.name="MessagesNotDefinedError"}}class _ extends m{sequence;name;parameters;type;id;getMessageComponentType(){return a.ToolCall}constructor(e,o,s,n,r){super(),this.sequence=e,this.name=o,this.parameters=s,this.type=n,this.id=r}static builder(){return new x}}class x{_sequence;_name;_parameters;_type;_id;sequence(e){return this._sequence=e,this}name(e){return this._name=e,this}parameters(e){return this._parameters=e,this}type(e){return this._type=e,this}id(e){return e!=null&&(this._id=e),this}build(){return this._sequence==null&&(this._sequence=0),this._id==null&&(this._id=(Math.random()+1).toString(36).slice(2,7)),new _(this._sequence,this._name,this._parameters,this._type,this._id)}}class D extends Error{constructor(e){super(e),this.name="ToolNotFoundError"}}class k{name;systemPrompt;tools;model;conversation;conversationManager;toolNameToIndexMap;callback;constructor(e,o,s,n,r){this.name=e,this.model=s,this.conversationManager=n,this.tools=o,this.callback=r,this.conversationManager.configure(s)}async invoke(e){this.conversation==null&&(this.conversation=new w,this.conversationManager!=null&&(this.conversation.manager=this.conversationManager),this.systemPrompt!=null&&this.conversation.append(u.builder().role("system").content(this.systemPrompt).build())),this.conversation.append(u.builder().role("user").content(e).build());let o=!1;for(;!o;){let s=await this._runQuery();this.callback(s),this.conversation.append(s),o=!0;const n=s.filter(a.ToolCall);if(n!=null&&n.length!=0){o=!1,n.sort((r,l)=>(r.sequence??0)<(l.sequence??0)?-1:1);for(let r of n)await this._runTool(r)}}}async _runQuery(){return await this.model.invoke(new f().messages(this.conversation?.messages).tools(this.tools).build())}async _runTool(e){if(this.generateToolNameToIndexMap(),!(e.name in this.toolNameToIndexMap)){this.conversation.append(u.builder().role("tool").toolResult(c.of(e,new D("Agent does not have a tool with this name."))).build());return}let o=this.tools[this.toolNameToIndexMap[e.name]];try{let s=await o.execute(e.parameters);this.conversation.append(u.builder().role("tool").toolResult(c.of(e,s)).build())}catch(s){this.conversation.append(u.builder().role("tool").toolResult(c.of(e,JSON.stringify(s))).build())}}generateToolNameToIndexMap(){if(this.toolNameToIndexMap==null){this.toolNameToIndexMap={};for(let e=0;e<this.tools.length;e++)this.toolNameToIndexMap[this.tools[e].getName()]=e}}static builder(){return new A}}class A{_name;_systemPrompt;_tools;_model;_conversation;_conversationManager=new g;_toolNameToIndexMap;_callback=e=>J(e);name(e){return this._name=e,this}systemPrompt(e){return this._systemPrompt=e,this}tools(e){return this._tools=e,this}addTool(e){return this._tools==null&&(this._tools=[]),this._tools.push(e),this}model(e){return this._model=e,this}conversationManager(e){return this._conversationManager=e,this}callback(e){return this._callback=e,this}build(){let e=new k(this._name,this._tools,this._model,this._conversationManager,this._callback);return this._conversation!=null&&(e.conversation=this._conversation),this._systemPrompt!=null&&(e.systemPrompt=this._systemPrompt),e}}function J(t){for(const e of t.filter(a.Thinking))console.log("\x1B[90m"+e.get()+"\x1B[0m");for(const e of t.filter(a.Content))console.log(e.get());for(const e of t.filter(a.ToolCall))console.log("\x1B[32mCalling Tool: "+e.name+"\x1B[0m")}class d extends Error{constructor(e){super(e),this.name="ToolNotDefinedError"}}class F{name;description;tool_schema;constructor(){this.name=this.getName(),this.description=this.getDescription(),this.tool_schema=this.getToolSchema()}getName(){throw new d("Tool name not defined.")}getDescription(){throw new d("Tool description not defined.")}getToolSchema(){throw new d("Tool parameter schema not defined.")}execute(e){return null}}class p{parameters;output;constructor(e,o){this.parameters=e,this.output=o}static builder(){return new O}}class O{_parameters;_output;addParameter(e){return this._parameters==null&&(this._parameters=[]),this._parameters.push(e),this}output(e){return this._output=e,this}build(){return this._parameters==null&&(this._parameters=[]),new p(this._parameters,this._output)}}class T{name;description;type;required;constructor(e,o,s,n){this.name=e,this.description=o,this.type=s,this.required=n,this.assertValidType()}assertValidType(){}static builder(){return new S}}class S{_name;_description;_type;_required;name(e){return this._name=e,this}description(e){return this._description=e,this}type(e){return this._type=e,this}required(e){return this._required=e,this}build(){return this._required==null&&(this._required=!1),new T(this._name,this._description,this._type,this._required)}}class L extends P{endpoint;model;options;constructor(e,o,s){super(),this.endpoint=e,this.model=o,this.options=s}async invoke(e){let o={model:this.model,messages:this._formatMessages(e),tools:this._formatTools(e),...this.options},s=await fetch(this.endpoint+"/api/chat",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!s.ok)throw new Error(`HTTP error! status: ${s.status}`);let n=await s.json(),r=[];if(n.message.tool_calls)for(let l in n.message.tool_calls){const i=n.message.tool_calls[l];let h="function",R=i[h]?.name,E=i[h]?.index,B=i.id??void 0,I=typeof i[h]?.arguments=="string"?JSON.parse(i[h]?.arguments):i[h]?.arguments;r.push(_.builder().name(R).type(h).parameters(I).sequence(E).id(B).build())}return u.builder().toolCalls(r).role(n.message.role).content(n.message.content).thinking(n.message.thinking).build()}_formatTools(e){let o=[];for(let s of e.tools){let n={},r=[];for(let i of s.getToolSchema().parameters)n[i.name]={},n[i.name].type=i.type,n[i.name].description=i.description,i.required&&r.push(i.name);let l={type:"function",function:{name:s.getName(),description:s.getDescription(),parameters:{type:"object",properties:n,required:r}}};o.push(l)}return o}_formatMessages(e){let o=[];for(let s of e.messages){if(s.role=="assistant"||s.role=="system"||s.role=="user"){o.push(this._formatSingleMessage(s));continue}if(s.role=="tool"){for(const n of s.content)if(n.getMessageComponentType()==a.ToolResult){const r=n;o.push({role:s.role,name:r.toolName,content:JSON.stringify(r.toolResult)})}}}return o}_formatSingleMessage(e){let o={role:e.role},s,n,r;for(const l of e.content){if(l.getMessageComponentType()==a.Content){const i=l;s==null&&(s=""),s+=i.get()}if(l.getMessageComponentType()==a.Thinking){const i=l;r==null&&(r=""),r+=i.get()}if(l.getMessageComponentType()==a.ToolCall){const i=l;n==null&&(n=[]),n.push(this._formatToolCall(i))}}return s!=null&&(o.content=s),n!=null&&(o.tool_calls=n),r!=null&&(o.thinking=r),o}_formatToolCall(e){return{function:{name:e.name,arguments:e.parameters}}}}function Q(t){return e=>{e.prototype.getName=()=>t}}function V(t){return e=>{Object.defineProperty(e.prototype,"getDescription",{value:function(){return t},enumerable:!0,configurable:!0,writable:!0})}}function H(t){return e=>{e.prototype.tapewormParams==null&&(e.prototype.tapewormParams=[]),e.prototype.tapewormParamsOutput==null&&(e.prototype.tapewormParamsOutput=""),e.prototype.tapewormParams.push(T.builder().name(t.name).description(t.description).required(t.required).type(t.type).build()),e.prototype.getToolSchema=()=>new p(e.prototype.tapewormParams,e.prototype.tapewormParamsOutput)}}function K(t){return e=>{e.prototype.tapewormParams==null&&(e.prototype.tapewormParams=[]),e.prototype.tapewormParamsOutput==null&&(e.prototype.tapewormParamsOutput=""),e.prototype.tapewormParamsOutput=t,e.prototype.getToolSchema=()=>new p(e.prototype.tapewormParams,e.prototype.tapewormParamsOutput)}}exports.Agent=k;exports.Content=N;exports.Conversation=w;exports.ConversationManager=M;exports.DefaultConversationManager=g;exports.Message=u;exports.MessageBuilder=b;exports.MessageComponent=m;exports.MessageComponentType=a;exports.Model=P;exports.ModelRequest=q;exports.ModelRequestBuilder=f;exports.OllamaModel=L;exports.Parameter=T;exports.ParameterBuilder=S;exports.Thinking=C;exports.Tool=F;exports.ToolCall=_;exports.ToolCallBuilder=x;exports.ToolDescription=V;exports.ToolName=Q;exports.ToolOutput=K;exports.ToolParameter=H;exports.ToolResult=c;exports.ToolSchema=p;exports.ToolSchemaBuilder=O;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class w{messages;manager;constructor(){this.messages=[],this.manager=new g}append(e){this.messages.push(e),this.messages=this.manager.compact(this.messages)}}class M{compact(e){throw new T("No implementation for conversation manager!")}configure(e){throw new T("No implementation for conversation manager!")}}class g extends M{compact(e){return e}configure(e){}}class T extends Error{constructor(e){super(e),this.name="ConversationManagerNotImplemented"}}class u{role;content;constructor(e,s){this.role=e,this.content=s}static builder(){return new b}filter(e){return this.content.filter(s=>s.getMessageComponentType()==e)}}class b{_role;_content;role(e){return this._role=e,this}init(){this._content==null&&(this._content=[])}toolCall(e){return e==null?this:(this.init(),this._content.push(e),this)}toolCalls(e){if(e==null)return this;this.init();for(const s of e)this._content.push(s);return this}toolResult(e){return e==null?this:(this.init(),this._content.push(e),this)}thinking(e){return e==null?this:(this.init(),this._content.push(N.of(e)),this)}content(e){return e==null?this:(this.init(),this._content.push(C.of(e)),this)}build(){if(this._content==null||this._content.length==0)throw new Error("Role-only messages are not supported by Tapeworm.");return new u(this._role,this._content)}}const l={Content:"content",Thinking:"thinking",ToolCall:"toolcall",ToolResult:"toolresult"};class m{getMessageComponentType(){throw new Error("Message components that do not have a message component type are not allowed.")}}class C extends m{text;constructor(e){super(),this.text=e}getMessageComponentType(){return l.Content}get(){return this.text}static of(e){return new this(e)}}class N extends m{thought;constructor(e){super(),this.thought=e}getMessageComponentType(){return l.Thinking}get(){return this.thought}static of(e){return new this(e)}}class c extends m{id;toolName;toolResult;constructor(e,s,o){super(),this.id=e,this.toolName=s,this.toolResult=o}getMessageComponentType(){return l.ToolResult}static of(e,s){return new this(e.id,e.name,s)}}class P{async invoke(e){throw new v("The invoke function for this model was not correctly implemented.")}tokenLimit(){throw new v("The tokenLimit function for this model was not correctly implemented.")}}class q{messages;tools;constructor(e,s){this.messages=e,this.tools=s}static builder(){return new f}}class f{_messages;_tools;messages(e){return this._messages=e,this}tools(e){return this._tools=e,this}build(){if(this._tools==null&&(this._tools=[]),this._messages==null)throw new j("Requests to the model should include content.");return new q(this._messages,this._tools)}}class v extends Error{constructor(e){super(e),this.name="ModelNotImplementedError"}}class j extends Error{constructor(e){super(e),this.name="MessagesNotDefinedError"}}class _ extends m{sequence;name;parameters;type;id;getMessageComponentType(){return l.ToolCall}constructor(e,s,o,r,n){super(),this.sequence=e,this.name=s,this.parameters=o,this.type=r,this.id=n}static builder(){return new x}}class x{_sequence;_name;_parameters;_type;_id;sequence(e){return this._sequence=e,this}name(e){return this._name=e,this}parameters(e){return this._parameters=e,this}type(e){return this._type=e,this}id(e){return e!=null&&(this._id=e),this}build(){return this._sequence==null&&(this._sequence=0),this._id==null&&(this._id=(Math.random()+1).toString(36).slice(2,7)),new _(this._sequence,this._name,this._parameters,this._type,this._id)}}class D extends Error{constructor(e){super(e),this.name="ToolNotFoundError"}}class k{name;systemPrompt;tools;model;conversation;conversationManager;toolNameToIndexMap;callback;constructor(e,s,o,r,n){this.name=e,this.model=o,this.conversationManager=r,this.tools=s,this.callback=n,this.conversationManager.configure(o)}async invoke(e,s=this.callback){this.conversation==null&&(this.conversation=new w,this.conversationManager!=null&&(this.conversation.manager=this.conversationManager),this.systemPrompt!=null&&this.conversation.append(u.builder().role("system").content(this.systemPrompt).build())),this.conversation.append(u.builder().role("user").content(e).build());let o=!1;for(;!o;){let r=await this._runQuery();s(r),this.conversation.append(r),o=!0;const n=r.filter(l.ToolCall);if(n!=null&&n.length!=0){o=!1,n.sort((a,i)=>(a.sequence??0)<(i.sequence??0)?-1:1);for(let a of n)await this._runTool(a)}}}async _runQuery(){return await this.model.invoke(new f().messages(this.conversation?.messages).tools(this.tools).build())}async _runTool(e){if(this.generateToolNameToIndexMap(),!(e.name in this.toolNameToIndexMap)){this.conversation.append(u.builder().role("tool").toolResult(c.of(e,new D("Agent does not have a tool with this name."))).build());return}let s=this.tools[this.toolNameToIndexMap[e.name]];try{let o=await s.execute(e.parameters);this.conversation.append(u.builder().role("tool").toolResult(c.of(e,o)).build())}catch(o){this.conversation.append(u.builder().role("tool").toolResult(c.of(e,JSON.stringify(o))).build())}}generateToolNameToIndexMap(){if(this.toolNameToIndexMap==null){this.toolNameToIndexMap={};for(let e=0;e<this.tools.length;e++)this.toolNameToIndexMap[this.tools[e].getName()]=e}}static builder(){return new A}}class A{_name;_systemPrompt;_tools;_model;_conversation;_conversationManager=new g;_toolNameToIndexMap;_callback=e=>J(e);name(e){return this._name=e,this}systemPrompt(e){return this._systemPrompt=e,this}tools(e){return this._tools=e,this}addTool(e){return this._tools==null&&(this._tools=[]),this._tools.push(e),this}model(e){return this._model=e,this}conversationManager(e){return this._conversationManager=e,this}callback(e){return this._callback=e,this}build(){let e=new k(this._name,this._tools,this._model,this._conversationManager,this._callback);return this._conversation!=null&&(e.conversation=this._conversation),this._systemPrompt!=null&&(e.systemPrompt=this._systemPrompt),e}}function J(t){for(const e of t.filter(l.Thinking))console.log("\x1B[90m"+e.get()+"\x1B[0m");for(const e of t.filter(l.Content))console.log(e.get());for(const e of t.filter(l.ToolCall))console.log("\x1B[32mCalling Tool: "+e.name+"\x1B[0m")}class d extends Error{constructor(e){super(e),this.name="ToolNotDefinedError"}}class F{getName(){throw new d("Tool name not defined.")}getDescription(){throw new d("Tool description not defined.")}getToolSchema(){throw new d("Tool parameter schema not defined.")}execute(e){return null}}class p{parameters;output;constructor(e,s){this.parameters=e,this.output=s}static builder(){return new O}}class O{_parameters;_output;addParameter(e){return this._parameters==null&&(this._parameters=[]),this._parameters.push(e),this}output(e){return this._output=e,this}build(){return this._parameters==null&&(this._parameters=[]),new p(this._parameters,this._output)}}class y{name;description;type;required;constructor(e,s,o,r){this.name=e,this.description=s,this.type=o,this.required=r,this.assertValidType()}assertValidType(){}static builder(){return new R}}class R{_name;_description;_type;_required;name(e){return this._name=e,this}description(e){return this._description=e,this}type(e){return this._type=e,this}required(e){return this._required=e,this}build(){return this._required==null&&(this._required=!1),new y(this._name,this._description,this._type,this._required)}}class L extends P{endpoint;model;options;constructor(e,s,o){super(),this.endpoint=e,this.model=s,this.options=o}async invoke(e){let s={model:this.model,messages:this._formatMessages(e),tools:this._formatTools(e),...this.options},o=await fetch(this.endpoint+"/api/chat",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!o.ok)throw new Error(`HTTP error! status: ${o.status}`);let r=await o.json(),n=[];if(r.message.tool_calls)for(let a in r.message.tool_calls){const i=r.message.tool_calls[a];let h="function",S=i[h]?.name,E=i[h]?.index,B=i.id??void 0,I=typeof i[h]?.arguments=="string"?JSON.parse(i[h]?.arguments):i[h]?.arguments;n.push(_.builder().name(S).type(h).parameters(I).sequence(E).id(B).build())}return u.builder().toolCalls(n).role(r.message.role).content(r.message.content).thinking(r.message.thinking).build()}_formatTools(e){let s=[];for(let o of e.tools){let r={},n=[];for(let i of o.getToolSchema().parameters)r[i.name]={},r[i.name].type=i.type,r[i.name].description=i.description,i.required&&n.push(i.name);let a={type:"function",function:{name:o.getName(),description:o.getDescription(),parameters:{type:"object",properties:r,required:n}}};s.push(a)}return s}_formatMessages(e){let s=[];for(let o of e.messages){if(o.role=="assistant"||o.role=="system"||o.role=="user"){s.push(this._formatSingleMessage(o));continue}if(o.role=="tool"){for(const r of o.content)if(r.getMessageComponentType()==l.ToolResult){const n=r;s.push({role:o.role,name:n.toolName,content:JSON.stringify(n.toolResult)})}}}return s}_formatSingleMessage(e){let s={role:e.role},o,r,n;for(const a of e.content){if(a.getMessageComponentType()==l.Content){const i=a;o==null&&(o=""),o+=i.get()}if(a.getMessageComponentType()==l.Thinking){const i=a;n==null&&(n=""),n+=i.get()}if(a.getMessageComponentType()==l.ToolCall){const i=a;r==null&&(r=[]),r.push(this._formatToolCall(i))}}return o!=null&&(s.content=o),r!=null&&(s.tool_calls=r),n!=null&&(s.thinking=n),s}_formatToolCall(e){return{function:{name:e.name,arguments:e.parameters}}}}function Q(t){return e=>{e.prototype.getName=()=>t}}function V(t){return e=>{Object.defineProperty(e.prototype,"getDescription",{value:function(){return t},enumerable:!0,configurable:!0,writable:!0})}}function H(t){return e=>{e.prototype.tapewormParams==null&&(e.prototype.tapewormParams=[]),e.prototype.tapewormParamsOutput==null&&(e.prototype.tapewormParamsOutput=""),e.prototype.tapewormParams.push(y.builder().name(t.name).description(t.description).required(t.required).type(t.type).build()),e.prototype.getToolSchema=()=>new p(e.prototype.tapewormParams,e.prototype.tapewormParamsOutput)}}function K(t){return e=>{e.prototype.tapewormParams==null&&(e.prototype.tapewormParams=[]),e.prototype.tapewormParamsOutput==null&&(e.prototype.tapewormParamsOutput=""),e.prototype.tapewormParamsOutput=t,e.prototype.getToolSchema=()=>new p(e.prototype.tapewormParams,e.prototype.tapewormParamsOutput)}}exports.Agent=k;exports.Content=C;exports.Conversation=w;exports.ConversationManager=M;exports.DefaultConversationManager=g;exports.Message=u;exports.MessageBuilder=b;exports.MessageComponent=m;exports.MessageComponentType=l;exports.Model=P;exports.ModelRequest=q;exports.ModelRequestBuilder=f;exports.OllamaModel=L;exports.Parameter=y;exports.ParameterBuilder=R;exports.Thinking=N;exports.Tool=F;exports.ToolCall=_;exports.ToolCallBuilder=x;exports.ToolDescription=V;exports.ToolName=Q;exports.ToolOutput=K;exports.ToolParameter=H;exports.ToolResult=c;exports.ToolSchema=p;exports.ToolSchemaBuilder=O;