@jterrazz/intelligence 1.1.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +65 -60
  2. package/dist/adapters/agents/{chat-agent.adapter.d.ts → autonomous-agent.adapter.d.ts} +4 -4
  3. package/dist/adapters/agents/{chat-agent.adapter.js → autonomous-agent.adapter.js} +16 -13
  4. package/dist/adapters/agents/autonomous-agent.adapter.js.map +1 -0
  5. package/dist/adapters/agents/basic-agent.adapter.d.ts +26 -0
  6. package/dist/adapters/agents/basic-agent.adapter.js +303 -0
  7. package/dist/adapters/agents/basic-agent.adapter.js.map +1 -0
  8. package/dist/adapters/agents/query-agent.adapter.d.ts +4 -4
  9. package/dist/adapters/agents/query-agent.adapter.js +6 -6
  10. package/dist/adapters/agents/query-agent.adapter.js.map +1 -1
  11. package/dist/adapters/models/openrouter-model.adapter.js +6 -0
  12. package/dist/adapters/models/openrouter-model.adapter.js.map +1 -1
  13. package/dist/adapters/prompts/__tests__/presets.test.js +4 -4
  14. package/dist/adapters/prompts/__tests__/presets.test.js.map +1 -1
  15. package/dist/adapters/prompts/library/categories/response.d.ts +1 -1
  16. package/dist/adapters/prompts/library/categories/response.js +1 -1
  17. package/dist/adapters/prompts/library/categories/response.js.map +1 -1
  18. package/dist/adapters/prompts/library/index.d.ts +3 -3
  19. package/dist/adapters/prompts/library/index.js +4 -4
  20. package/dist/adapters/prompts/library/index.js.map +1 -1
  21. package/dist/adapters/prompts/library/presets.js +4 -4
  22. package/dist/adapters/prompts/library/presets.js.map +1 -1
  23. package/dist/index.cjs +37 -28
  24. package/dist/index.d.ts +3 -3
  25. package/dist/index.js +3 -3
  26. package/dist/index.js.map +1 -1
  27. package/package.json +1 -1
  28. package/dist/adapters/agents/chat-agent.adapter.js.map +0 -1
package/README.md CHANGED
@@ -30,22 +30,22 @@ Get your first agent running in under a minute. This example uses a preset to cr
30
30
 
31
31
  ```typescript
32
32
  import {
33
- ChatAgentAdapter,
34
- OpenRouterModelAdapter,
33
+ AutonomousAgentAdapter,
34
+ OpenRouterAdapter,
35
35
  SystemPromptAdapter,
36
- PROMPTS,
36
+ PROMPT_LIBRARY,
37
37
  } from '@jterrazz/intelligence';
38
38
 
39
39
  // 1. Set up the model provider
40
- const model = new OpenRouterModelAdapter({
40
+ const model = new OpenRouterAdapter({
41
41
  apiKey: process.env.OPENROUTER_API_KEY!, // Make sure to set this environment variable
42
42
  modelName: 'anthropic/claude-3.5-sonnet',
43
43
  });
44
44
 
45
45
  // 2. Create an agent using a preset prompt
46
- const agent = new ChatAgentAdapter('discord-bot', {
46
+ const agent = new AutonomousAgentAdapter('discord-bot', {
47
47
  model,
48
- systemPrompt: new SystemPromptAdapter(PROMPTS.PRESETS.DISCORD_COMMUNITY_ANIMATOR),
48
+ systemPrompt: new SystemPromptAdapter(PROMPT_LIBRARY.PRESETS.COMMUNITY_ANIMATOR),
49
49
  });
50
50
 
51
51
  // 3. Run the agent
@@ -63,10 +63,14 @@ console.log(response);
63
63
 
64
64
  Instead of writing monolithic prompts, the library provides a collection of composable string constants. Mix and match them to build a precise, fine-grained system prompt that defines your agent's behavior.
65
65
 
66
- - **`PERSONA`**: Who the agent is (e.g., `EXPERT_ADVISOR`).
67
- - **`TONE`**: How the agent communicates (e.g., `PROFESSIONAL`, `EMPATHETIC`).
68
- - **`FORMAT`** How the agent structures its response (e.g., `MARKDOWN`, `JSON`).
69
- - **`DIRECTIVES`**: Core rules the agent must follow (e.g., `BE_SAFE`, `BE_FACTUAL`).
66
+ - **`FOUNDATIONS`**: Core, non-negotiable rules (e.g., `PROMPT_LIBRARY.FOUNDATIONS.ETHICAL_CONDUCT`).
67
+ - **`PERSONAS`**: The agent's identity and purpose (e.g., `PROMPT_LIBRARY.PERSONAS.EXPERT_ADVISOR`).
68
+ - **`DOMAINS`**: The agent's area of expertise (e.g., `PROMPT_LIBRARY.DOMAINS.SOFTWARE_ENGINEERING`).
69
+ - **`TONES`**: The emotional flavor of communication (e.g., `PROMPT_LIBRARY.TONES.PROFESSIONAL`).
70
+ - **`FORMATS`**: The structural format of the output (e.g., `PROMPT_LIBRARY.FORMATS.JSON`).
71
+ - **`LANGUAGES`**: The natural language for the response (e.g., `PROMPT_LIBRARY.LANGUAGES.ENGLISH_NATIVE`).
72
+ - **`VERBOSITY`**: The level of detail in the response (e.g., `PROMPT_LIBRARY.VERBOSITY.DETAILED`).
73
+ - **`RESPONSES`**: The strategic approach to responding (e.g., `PROMPT_LIBRARY.RESPONSES.ALWAYS_ENGAGE`).
70
74
 
71
75
  This approach makes agent behavior more predictable and easier to modify.
72
76
 
@@ -100,7 +104,7 @@ The adapter handles errors gracefully and integrates seamlessly with the agent,
100
104
  The library is built on a hexagonal architecture.
101
105
 
102
106
  - **Ports (`/ports`)**: Define the contracts (interfaces) for core components like `Agent`, `Model`, and `Tool`.
103
- - **Adapters (`/adapters`)**: Provide concrete implementations. For example, `ChatAgentAdapter` is an adapter that uses LangChain, and `OpenRouterModelAdapter` is an adapter for the OpenRouter API.
107
+ - **Adapters (`/adapters`)**: Provide concrete implementations. For example, `AutonomousAgentAdapter` is an adapter that uses LangChain, and `OpenRouterAdapter` is an adapter for the OpenRouter API.
104
108
 
105
109
  This separation of concerns means you can easily create your own adapters to support different models or services without changing the application's core logic.
106
110
 
@@ -120,26 +124,26 @@ This recipe creates an agent that acts as an expert software engineer, providing
120
124
 
121
125
  ```typescript
122
126
  import {
123
- ChatAgentAdapter,
124
- OpenRouterModelAdapter,
127
+ AutonomousAgentAdapter,
128
+ OpenRouterAdapter,
125
129
  SystemPromptAdapter,
126
130
  UserPromptAdapter,
127
- PROMPTS,
131
+ PROMPT_LIBRARY,
128
132
  } from '@jterrazz/intelligence';
129
133
 
130
- const model = new OpenRouterModelAdapter({
134
+ const model = new OpenRouterAdapter({
131
135
  apiKey: process.env.OPENROUTER_API_KEY!,
132
136
  modelName: 'anthropic/claude-3.5-sonnet',
133
137
  });
134
138
 
135
139
  // 1. Compose the system prompt from multiple parts (using rest arguments)
136
140
  const systemPrompt = new SystemPromptAdapter(
137
- PROMPTS.PERSONA.EXPERT_ADVISOR,
138
- PROMPTS.DOMAIN.SOFTWARE_ENGINEERING,
139
- PROMPTS.TONE.PROFESSIONAL,
140
- PROMPTS.VERBOSITY.DETAILED,
141
- PROMPTS.FORMAT.MARKDOWN,
142
- PROMPTS.DIRECTIVES.BE_FACTUAL,
141
+ PROMPT_LIBRARY.PERSONAS.EXPERT_ADVISOR,
142
+ PROMPT_LIBRARY.DOMAINS.SOFTWARE_ENGINEERING,
143
+ PROMPT_LIBRARY.TONES.PROFESSIONAL,
144
+ PROMPT_LIBRARY.VERBOSITY.DETAILED,
145
+ PROMPT_LIBRARY.FORMATS.MARKDOWN,
146
+ PROMPT_LIBRARY.FOUNDATIONS.FACTUAL_ACCURACY,
143
147
  );
144
148
 
145
149
  // 2. Create the user request (using a single array)
@@ -149,7 +153,7 @@ const userPrompt = new UserPromptAdapter([
149
153
  ]);
150
154
 
151
155
  // 3. Configure and run the agent
152
- const agent = new ChatAgentAdapter('code-reviewer', {
156
+ const agent = new AutonomousAgentAdapter('code-reviewer', {
153
157
  model,
154
158
  systemPrompt,
155
159
  });
@@ -159,34 +163,34 @@ const response = await agent.run(userPrompt);
159
163
  console.log(response);
160
164
  ```
161
165
 
162
- ### Recipe: Simple Text Processor (QueryAgent)
166
+ ### Recipe: Simple Text Processor (BasicAgent)
163
167
 
164
- This example shows how to use the simpler `QueryAgentAdapter` for one-shot responses without tools.
168
+ This example shows how to use the simpler `BasicAgentAdapter` for one-shot responses without tools.
165
169
 
166
170
  ```typescript
167
171
  import {
168
- QueryAgentAdapter,
169
- OpenRouterModelAdapter,
172
+ BasicAgentAdapter,
173
+ OpenRouterAdapter,
170
174
  SystemPromptAdapter,
171
175
  UserPromptAdapter,
172
- PROMPTS,
176
+ PROMPT_LIBRARY,
173
177
  } from '@jterrazz/intelligence';
174
178
 
175
- const model = new OpenRouterModelAdapter({
179
+ const model = new OpenRouterAdapter({
176
180
  apiKey: process.env.OPENROUTER_API_KEY!,
177
181
  modelName: 'anthropic/claude-3.5-sonnet',
178
182
  });
179
183
 
180
184
  // 1. Create a simple system prompt for text processing
181
185
  const systemPrompt = new SystemPromptAdapter(
182
- PROMPTS.PERSONA.EXPERT_ADVISOR,
183
- PROMPTS.TONE.PROFESSIONAL,
184
- PROMPTS.FORMAT.MARKDOWN,
186
+ PROMPT_LIBRARY.PERSONAS.EXPERT_ADVISOR,
187
+ PROMPT_LIBRARY.TONES.PROFESSIONAL,
188
+ PROMPT_LIBRARY.FORMATS.MARKDOWN,
185
189
  'You are a helpful assistant that improves text clarity and grammar.',
186
190
  );
187
191
 
188
- // 2. Create a query agent (no tools needed)
189
- const agent = new QueryAgentAdapter('text-processor', {
192
+ // 2. Create a basic agent (no tools needed)
193
+ const agent = new BasicAgentAdapter('text-processor', {
190
194
  model,
191
195
  systemPrompt,
192
196
  });
@@ -201,21 +205,21 @@ console.log(response);
201
205
  // Expected output: A grammatically corrected and improved version of the text
202
206
  ```
203
207
 
204
- ### Recipe: Structured Data Extraction (QueryAgent with Schema)
208
+ ### Recipe: Structured Data Extraction (BasicAgent with Schema)
205
209
 
206
- This example shows how to use `QueryAgentAdapter` with schema parsing for structured responses.
210
+ This example shows how to use `BasicAgentAdapter` with schema parsing for structured responses.
207
211
 
208
212
  ```typescript
209
213
  import {
210
- QueryAgentAdapter,
211
- OpenRouterModelAdapter,
214
+ BasicAgentAdapter,
215
+ OpenRouterAdapter,
212
216
  SystemPromptAdapter,
213
217
  UserPromptAdapter,
214
- PROMPTS,
218
+ PROMPT_LIBRARY,
215
219
  } from '@jterrazz/intelligence';
216
220
  import { z } from 'zod/v4';
217
221
 
218
- const model = new OpenRouterModelAdapter({
222
+ const model = new OpenRouterAdapter({
219
223
  apiKey: process.env.OPENROUTER_API_KEY!,
220
224
  modelName: 'anthropic/claude-3.5-sonnet',
221
225
  });
@@ -230,14 +234,14 @@ const extractionSchema = z.object({
230
234
 
231
235
  // 2. Create a system prompt for data extraction
232
236
  const systemPrompt = new SystemPromptAdapter(
233
- PROMPTS.PERSONA.EXPERT_ADVISOR,
234
- PROMPTS.TONE.PROFESSIONAL,
235
- PROMPTS.FORMAT.JSON,
237
+ PROMPT_LIBRARY.PERSONAS.EXPERT_ADVISOR,
238
+ PROMPT_LIBRARY.TONES.PROFESSIONAL,
239
+ PROMPT_LIBRARY.FORMATS.JSON,
236
240
  'You extract contact information from text and return it as JSON.',
237
241
  );
238
242
 
239
- // 3. Create a query agent with schema parsing
240
- const agent = new QueryAgentAdapter('contact-extractor', {
243
+ // 3. Create a basic agent with schema parsing
244
+ const agent = new BasicAgentAdapter('contact-extractor', {
241
245
  model,
242
246
  schema: extractionSchema,
243
247
  systemPrompt,
@@ -262,11 +266,12 @@ This example shows how to give an agent a tool and have it respond to a user que
262
266
 
263
267
  ```typescript
264
268
  import {
265
- ChatAgentAdapter,
266
- OpenRouterModelAdapter,
269
+ AutonomousAgentAdapter,
270
+ OpenRouterAdapter,
267
271
  SafeToolAdapter,
268
272
  SystemPromptAdapter,
269
- PROMPTS,
273
+ UserPromptAdapter,
274
+ PROMPT_LIBRARY,
270
275
  } from '@jterrazz/intelligence';
271
276
  import { z } from 'zod/v4';
272
277
 
@@ -286,14 +291,14 @@ const weatherTool = new SafeToolAdapter(
286
291
  );
287
292
 
288
293
  // 2. Create an agent that knows how to use tools
289
- const agent = new ChatAgentAdapter('weather-bot', {
294
+ const agent = new AutonomousAgentAdapter('weather-bot', {
290
295
  model,
291
- systemPrompt: new SystemPromptAdapter(PROMPTS.PRESETS.EMPATHETIC_SUPPORT_AGENT), // A good general-purpose preset
296
+ systemPrompt: new SystemPromptAdapter(PROMPT_LIBRARY.PRESETS.EMPATHETIC_SUPPORT_AGENT), // A good general-purpose preset
292
297
  tools: [weatherTool], // Pass the tool instance directly
293
298
  });
294
299
 
295
300
  // 3. Run the agent with a user query that requires the tool
296
- const response = await agent.run({ generate: () => "What's the weather like in Boston?" });
301
+ const response = await agent.run(new UserPromptAdapter("What's the weather like in Boston?"));
297
302
 
298
303
  console.log(response);
299
304
  // Expected output: "The weather in Boston is 75°F and sunny."
@@ -305,16 +310,16 @@ console.log(response);
305
310
 
306
311
  ### Core Components
307
312
 
308
- | Class | Description |
309
- | ------------------------ | -------------------------------------------------------------------------- |
310
- | `ChatAgentAdapter` | The main agent implementation. Runs prompts and coordinates tools. |
311
- | `QueryAgentAdapter` | A simpler agent for one-shot responses without tools or complex logic. |
312
- | `OpenRouterModelAdapter` | An adapter for connecting to any model on the OpenRouter platform. |
313
- | `SafeToolAdapter` | A type-safe wrapper for creating tools with validation and error handling. |
314
- | `SystemPromptAdapter` | A simple adapter to generate a system prompt string from a prompt array. |
315
- | `UserPromptAdapter` | A simple adapter to generate a user prompt string from a prompt array. |
316
- | `AIResponseParser` | A utility to parse a model's string output into a typed object using Zod. |
317
- | `PROMPTS` | A frozen object containing the entire composable prompt library. |
313
+ | Class | Description |
314
+ | ------------------------ | ------------------------------------------------------------------------------- |
315
+ | `AutonomousAgentAdapter` | The main agent implementation. Runs prompts and coordinates tools autonomously. |
316
+ | `BasicAgentAdapter` | A basic agent for one-shot responses without tools or complex logic. |
317
+ | `OpenRouterModelAdapter` | An adapter for connecting to any model on the OpenRouter platform. |
318
+ | `SafeToolAdapter` | A type-safe wrapper for creating tools with validation and error handling. |
319
+ | `SystemPromptAdapter` | A simple adapter to generate a system prompt string from a prompt array. |
320
+ | `UserPromptAdapter` | A simple adapter to generate a user prompt string from a prompt array. |
321
+ | `AIResponseParser` | A utility to parse a model's string output into a typed object using Zod. |
322
+ | `PROMPT_LIBRARY` | A frozen object containing the entire composable prompt library. |
318
323
 
319
324
  ## Contributing
320
325
 
@@ -5,7 +5,7 @@ import type { ModelPort } from '../../ports/model.port.js';
5
5
  import type { PromptPort } from '../../ports/prompt.port.js';
6
6
  import type { ToolPort } from '../../ports/tool.port.js';
7
7
  import type { SystemPromptAdapter } from '../prompts/system-prompt.adapter.js';
8
- export interface ChatAgentOptions<T = unknown> {
8
+ export interface AutonomousAgentOptions<T = unknown> {
9
9
  logger?: LoggerPort;
10
10
  model: ModelPort;
11
11
  schema?: z.ZodSchema<T>;
@@ -14,13 +14,13 @@ export interface ChatAgentOptions<T = unknown> {
14
14
  verbose?: boolean;
15
15
  }
16
16
  /**
17
- * An advanced agent that uses tools and a structured prompt to engage in conversational chat.
17
+ * An autonomous agent that uses tools and a structured prompt to accomplish tasks.
18
18
  * It can decide whether to respond or remain silent and supports schema-validated responses.
19
19
  */
20
- export declare class ChatAgentAdapter<T = unknown> implements AgentPort {
20
+ export declare class AutonomousAgentAdapter<T = unknown> implements AgentPort {
21
21
  readonly name: string;
22
22
  private readonly options;
23
- constructor(name: string, options: ChatAgentOptions<T>);
23
+ constructor(name: string, options: AutonomousAgentOptions<T>);
24
24
  run(userPrompt?: PromptPort): Promise<null | string>;
25
25
  private createExecutor;
26
26
  private parseAgentOutput;
@@ -160,20 +160,20 @@ function _ts_generator(thisArg, body) {
160
160
  import { ChatPromptTemplate } from '@langchain/core/prompts';
161
161
  import { AgentExecutor, createStructuredChatAgent } from 'langchain/agents';
162
162
  import { AIResponseParser } from '../utils/ai-response-parser.js';
163
- var SYSTEM_PROMPT_TEMPLATE = '\n<OBJECTIVE>\n{mission_prompt}\n</OBJECTIVE>\n\n<OUTPUT_FORMAT>\nCRITICAL: The format instructions in this section are the ONLY valid way to structure your response. Any formatting guidelines within the <OBJECTIVE> section (like message templates) apply ONLY to the content that goes inside the "RESPOND: " part of your final answer.\n\nYou have two ways to respond:\n\n1. **Call a tool** to gather information. For this, you MUST output a JSON blob with the tool\'s name and its input.\n *Valid tool names are: {tool_names}*\n ```json\n {{\n "action": "tool_name_to_use",\n "action_input": "the input for the tool, or an empty object {{}} if no input is needed"\n }}\n ```\n\n2. **Provide the Final Answer** once you have enough information. For this, you MUST output a JSON blob with the "Final Answer" action. The input must start with "RESPOND: " or "SILENT: ".\n - To send a message:\n ```json\n {{\n "action": "Final Answer",\n "action_input": "RESPOND: <your response message>"\n }}\n ```\n - To stay silent:\n ```json\n {{\n "action": "Final Answer",\n "action_input": "SILENT: <your reason for staying silent>"\n }}\n ```\n</OUTPUT_FORMAT>\n\n<EXECUTION_CONTEXT>\nThis is internal data for your reference.\n\n<TOOLS>\n{tools}\n</TOOLS>\n\n<WORKING_MEMORY>\nThis is your internal thought process and previous tool usage.\n{agent_scratchpad}\n</WORKING_MEMORY>\n</EXECUTION_CONTEXT>\n';
163
+ var SYSTEM_PROMPT_TEMPLATE = '\n<OBJECTIVE>\n{mission_prompt}\n</OBJECTIVE>\n\n<OUTPUT_FORMAT>\nCRITICAL: The format instructions in this section are the ONLY valid way to structure your response. Your entire response MUST be a single JSON markdown code block. Any formatting guidelines within the <OBJECTIVE> section apply ONLY to the content inside the "RESPOND:" part of your final "action_input".\n\nREQUIRED: You have two ways to respond:\n\n1. **Call a tool** to gather information. For this, you MUST output a JSON blob with the tool\'s name and its input.\n *Valid tool names are: {tool_names}*\n ```json\n {{\n "action": "tool_name_to_use",\n "action_input": "the input for the tool, or an empty object {{}} if no input is needed"\n }}\n ```\n\n2. **Provide the Final Answer** once you have enough information. For this, you MUST output a JSON blob with the "Final Answer" action.\n The "action_input" for a "Final Answer" MUST be a string that begins with either "RESPOND: " for a message or "SILENT: " for no message. This prefix is a literal part of the output string and MUST NOT be omitted.\n - To send a message:\n ```json\n {{\n "action": "Final Answer",\n "action_input": "RESPOND: <your response message>"\n }}\n ```\n - To stay silent:\n ```json\n {{\n "action": "Final Answer",\n "action_input": "SILENT: <your reason for staying silent>"\n }}\n ```\n\n YOU MUST ALWAYS INCLUDE "RESPOND:" OR "SILENT:" IN YOUR FINAL ANSWER\'S "action_input". FAILURE TO DO SO WILL CAUSE AN ERROR.\n</OUTPUT_FORMAT>\n\n<EXECUTION_CONTEXT>\nThis is internal data for your reference.\n\n<TOOLS>\n{tools}\n</TOOLS>\n\n<WORKING_MEMORY>\nThis is your internal thought process and previous tool usage.\n{agent_scratchpad}\n</WORKING_MEMORY>\n</EXECUTION_CONTEXT>\n';
164
164
  /**
165
- * An advanced agent that uses tools and a structured prompt to engage in conversational chat.
165
+ * An autonomous agent that uses tools and a structured prompt to accomplish tasks.
166
166
  * It can decide whether to respond or remain silent and supports schema-validated responses.
167
- */ export var ChatAgentAdapter = /*#__PURE__*/ function() {
167
+ */ export var AutonomousAgentAdapter = /*#__PURE__*/ function() {
168
168
  "use strict";
169
- function ChatAgentAdapter(name, options) {
170
- _class_call_check(this, ChatAgentAdapter);
169
+ function AutonomousAgentAdapter(name, options) {
170
+ _class_call_check(this, AutonomousAgentAdapter);
171
171
  _define_property(this, "name", void 0);
172
172
  _define_property(this, "options", void 0);
173
173
  this.name = name;
174
174
  this.options = options;
175
175
  }
176
- _create_class(ChatAgentAdapter, [
176
+ _create_class(AutonomousAgentAdapter, [
177
177
  {
178
178
  key: "run",
179
179
  value: function run(userPrompt) {
@@ -213,6 +213,12 @@ var SYSTEM_PROMPT_TEMPLATE = '\n<OBJECTIVE>\n{mission_prompt}\n</OBJECTIVE>\n\n<
213
213
  throw new Error('Agent returned an invalid result structure.');
214
214
  }
215
215
  agentResponse = this.parseAgentOutput(result.output);
216
+ if (!agentResponse) {
217
+ return [
218
+ 2,
219
+ null
220
+ ];
221
+ }
216
222
  if (!agentResponse.shouldRespond) {
217
223
  ;
218
224
  (_this_options_logger2 = this.options.logger) === null || _this_options_logger2 === void 0 ? void 0 : _this_options_logger2.info("[".concat(this.name, "] Agent chose to remain silent."), {
@@ -318,13 +324,10 @@ var SYSTEM_PROMPT_TEMPLATE = '\n<OBJECTIVE>\n{mission_prompt}\n</OBJECTIVE>\n\n<
318
324
  shouldRespond: false
319
325
  };
320
326
  }
321
- (_this_options_logger = this.options.logger) === null || _this_options_logger === void 0 ? void 0 : _this_options_logger.warn("[".concat(this.name, "] Agent output was missing 'RESPOND:' or 'SILENT:' prefix. Treating as a direct response."), {
327
+ (_this_options_logger = this.options.logger) === null || _this_options_logger === void 0 ? void 0 : _this_options_logger.error("[".concat(this.name, "] Agent output was missing 'RESPOND:' or 'SILENT:' prefix."), {
322
328
  rawOutput: output
323
329
  });
324
- return {
325
- message: text,
326
- shouldRespond: true
327
- };
330
+ return null;
328
331
  }
329
332
  },
330
333
  {
@@ -352,7 +355,7 @@ var SYSTEM_PROMPT_TEMPLATE = '\n<OBJECTIVE>\n{mission_prompt}\n</OBJECTIVE>\n\n<
352
355
  }
353
356
  }
354
357
  ]);
355
- return ChatAgentAdapter;
358
+ return AutonomousAgentAdapter;
356
359
  }();
357
360
 
358
- //# sourceMappingURL=chat-agent.adapter.js.map
361
+ //# sourceMappingURL=autonomous-agent.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/agents/autonomous-agent.adapter.ts"],"sourcesContent":["import { type LoggerPort } from '@jterrazz/logger';\nimport { ChatPromptTemplate } from '@langchain/core/prompts';\nimport { AgentExecutor, createStructuredChatAgent } from 'langchain/agents';\nimport { type z } from 'zod/v4';\n\nimport { type AgentPort } from '../../ports/agent.port.js';\nimport type { ModelPort } from '../../ports/model.port.js';\nimport type { PromptPort } from '../../ports/prompt.port.js';\nimport type { ToolPort } from '../../ports/tool.port.js';\n\nimport { AIResponseParser } from '../utils/ai-response-parser.js';\n\nimport type { SystemPromptAdapter } from '../prompts/system-prompt.adapter.js';\n\nexport interface AutonomousAgentOptions<T = unknown> {\n logger?: LoggerPort;\n model: ModelPort;\n schema?: z.ZodSchema<T>;\n systemPrompt: SystemPromptAdapter;\n tools: ToolPort[];\n verbose?: boolean;\n}\n\nconst SYSTEM_PROMPT_TEMPLATE = `\n<OBJECTIVE>\n{mission_prompt}\n</OBJECTIVE>\n\n<OUTPUT_FORMAT>\nCRITICAL: The format instructions in this section are the ONLY valid way to structure your response. Your entire response MUST be a single JSON markdown code block. Any formatting guidelines within the <OBJECTIVE> section apply ONLY to the content inside the \"RESPOND:\" part of your final \"action_input\".\n\nREQUIRED: You have two ways to respond:\n\n1. **Call a tool** to gather information. For this, you MUST output a JSON blob with the tool's name and its input.\n *Valid tool names are: {tool_names}*\n \\`\\`\\`json\n {{\n \"action\": \"tool_name_to_use\",\n \"action_input\": \"the input for the tool, or an empty object {{}} if no input is needed\"\n }}\n \\`\\`\\`\n\n2. **Provide the Final Answer** once you have enough information. For this, you MUST output a JSON blob with the \"Final Answer\" action.\n The \"action_input\" for a \"Final Answer\" MUST be a string that begins with either \"RESPOND: \" for a message or \"SILENT: \" for no message. This prefix is a literal part of the output string and MUST NOT be omitted.\n - To send a message:\n \\`\\`\\`json\n {{\n \"action\": \"Final Answer\",\n \"action_input\": \"RESPOND: <your response message>\"\n }}\n \\`\\`\\`\n - To stay silent:\n \\`\\`\\`json\n {{\n \"action\": \"Final Answer\",\n \"action_input\": \"SILENT: <your reason for staying silent>\"\n }}\n \\`\\`\\`\n\n YOU MUST ALWAYS INCLUDE \"RESPOND:\" OR \"SILENT:\" IN YOUR FINAL ANSWER'S \"action_input\". FAILURE TO DO SO WILL CAUSE AN ERROR.\n</OUTPUT_FORMAT>\n\n<EXECUTION_CONTEXT>\nThis is internal data for your reference.\n\n<TOOLS>\n{tools}\n</TOOLS>\n\n<WORKING_MEMORY>\nThis is your internal thought process and previous tool usage.\n{agent_scratchpad}\n</WORKING_MEMORY>\n</EXECUTION_CONTEXT>\n`;\n\n/**\n * An autonomous agent that uses tools and a structured prompt to accomplish tasks.\n * It can decide whether to respond or remain silent and supports schema-validated responses.\n */\nexport class AutonomousAgentAdapter<T = unknown> implements AgentPort {\n constructor(\n public readonly name: string,\n private readonly options: AutonomousAgentOptions<T>,\n ) {}\n\n async run(userPrompt?: PromptPort): Promise<null | string> {\n this.options.logger?.debug(`[${this.name}] Starting chat execution.`);\n\n try {\n const executor = await this.createExecutor();\n const userInput = this.resolveUserInput(userPrompt);\n\n const result = await executor.invoke({ input: userInput });\n\n this.options.logger?.debug(`[${this.name}] Agent execution completed.`, {\n hasOutput: 'output' in result,\n });\n\n if (!result || typeof result.output !== 'string') {\n throw new Error('Agent returned an invalid result structure.');\n }\n\n const agentResponse = this.parseAgentOutput(result.output);\n\n if (!agentResponse) {\n return null;\n }\n\n if (!agentResponse.shouldRespond) {\n this.options.logger?.info(`[${this.name}] Agent chose to remain silent.`, {\n reason: agentResponse.reason,\n });\n return null;\n }\n\n const message = agentResponse.message ?? '';\n\n if (this.options.schema) {\n this.validateResponseContent(message, this.options.schema);\n this.options.logger?.info(\n `[${this.name}] Execution finished; response content validated.`,\n );\n } else {\n this.options.logger?.info(`[${this.name}] Execution finished.`);\n }\n\n return message;\n } catch (error) {\n this.options.logger?.error(`[${this.name}] Chat execution failed.`, {\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n return null;\n }\n }\n\n private async createExecutor(): Promise<AgentExecutor> {\n const model = this.options.model.getModel();\n const tools = this.options.tools.map((tool) => tool.getDynamicTool());\n\n const prompt = ChatPromptTemplate.fromMessages([\n [\n 'system',\n SYSTEM_PROMPT_TEMPLATE.replace(\n '{mission_prompt}',\n this.options.systemPrompt.generate(),\n ),\n ],\n ['human', '{input}'],\n ]);\n\n const agent = await createStructuredChatAgent({\n llm: model,\n prompt,\n tools,\n });\n\n return AgentExecutor.fromAgentAndTools({\n agent,\n tools,\n verbose: this.options.verbose,\n });\n }\n\n private parseAgentOutput(output: string): null | {\n message?: string;\n reason?: string;\n shouldRespond: boolean;\n } {\n const text = output.trim();\n\n const respondMatch = text.match(/^RESPOND:\\s*([\\s\\S]+)$/i);\n if (respondMatch) {\n return { message: respondMatch[1].trim(), shouldRespond: true };\n }\n\n const silentMatch = text.match(/^SILENT:\\s*([\\s\\S]+)$/i);\n if (silentMatch) {\n return { reason: silentMatch[1].trim(), shouldRespond: false };\n }\n\n this.options.logger?.error(\n `[${this.name}] Agent output was missing 'RESPOND:' or 'SILENT:' prefix.`,\n { rawOutput: output },\n );\n\n return null;\n }\n\n private resolveUserInput(userPrompt?: PromptPort): string {\n if (userPrompt) {\n return userPrompt.generate();\n }\n return 'Proceed with your instructions.';\n }\n\n private validateResponseContent<TResponse>(\n content: string,\n schema: z.ZodSchema<TResponse>,\n ): void {\n try {\n new AIResponseParser(schema).parse(content);\n } catch (error) {\n this.options.logger?.error(\n `[${this.name}] Failed to validate response content against schema.`,\n {\n error: error instanceof Error ? error.message : 'Unknown error',\n rawContent: content,\n },\n );\n throw new Error('Invalid response content from model.');\n }\n }\n}\n"],"names":["ChatPromptTemplate","AgentExecutor","createStructuredChatAgent","AIResponseParser","SYSTEM_PROMPT_TEMPLATE","AutonomousAgentAdapter","name","options","run","userPrompt","executor","userInput","result","agentResponse","message","error","logger","debug","createExecutor","resolveUserInput","invoke","input","hasOutput","output","Error","parseAgentOutput","shouldRespond","info","reason","schema","validateResponseContent","model","tools","prompt","agent","getModel","map","tool","getDynamicTool","fromMessages","replace","systemPrompt","generate","llm","fromAgentAndTools","verbose","text","trim","respondMatch","match","silentMatch","rawOutput","content","parse","rawContent"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type LoggerPort } from '@jterrazz/logger';
2
+ import { type z } from 'zod/v4';
3
+ import { type AgentPort } from '../../ports/agent.port.js';
4
+ import type { ModelPort } from '../../ports/model.port.js';
5
+ import type { PromptPort } from '../../ports/prompt.port.js';
6
+ import type { SystemPromptAdapter } from '../prompts/system-prompt.adapter.js';
7
+ export interface BasicAgentOptions<T = string> {
8
+ logger?: LoggerPort;
9
+ model: ModelPort;
10
+ schema?: z.ZodSchema<T>;
11
+ systemPrompt: SystemPromptAdapter;
12
+ verbose?: boolean;
13
+ }
14
+ /**
15
+ * A basic agent for direct, one-shot interactions with a model.
16
+ * It supports optional response parsing against a Zod schema but does not use tools.
17
+ */
18
+ export declare class BasicAgentAdapter<T = string> implements AgentPort {
19
+ readonly name: string;
20
+ private readonly options;
21
+ constructor(name: string, options: BasicAgentOptions<T>);
22
+ run(userPrompt?: PromptPort): Promise<null | string>;
23
+ private invokeModel;
24
+ private parseResponse;
25
+ private resolveUserInput;
26
+ }