@agentionai/agents 1.3.0 → 1.4.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.
@@ -16,6 +16,27 @@ export interface CommonAgentConfig {
16
16
  description: string;
17
17
  /** API key for authenticating with the LLM provider */
18
18
  apiKey: string;
19
+ /**
20
+ * Extra HTTP headers sent with every request to the provider.
21
+ *
22
+ * Useful for gateway and proxy attribution, tracing, or corporate egress
23
+ * requirements. OpenRouter, for example, uses `HTTP-Referer` and `X-Title`
24
+ * to attribute traffic to your app:
25
+ *
26
+ * ```typescript
27
+ * defaultHeaders: {
28
+ * "HTTP-Referer": "https://myapp.example",
29
+ * "X-Title": "My App",
30
+ * }
31
+ * ```
32
+ *
33
+ * These override headers the agent would otherwise set, including
34
+ * `Authorization` / `x-api-key`. That follows the Anthropic and OpenAI SDKs'
35
+ * own `defaultHeaders` behaviour and is deliberate — it lets a gateway swap
36
+ * in its own auth scheme. The flip side is that setting an auth header here
37
+ * replaces `apiKey`, so do it only when that is what you mean.
38
+ */
39
+ defaultHeaders?: Record<string, string>;
19
40
  /** Enable debug logging for troubleshooting (default: false) */
20
41
  debug?: boolean;
21
42
  /** Maximum number of messages to retain in conversation history */
@@ -40,8 +40,8 @@ class ClaudeAgent extends BaseAgent_1.BaseAgent {
40
40
  const authType = config.authType ?? vendorConfig.authType ?? "apiKey";
41
41
  const thinkingBudgetTokens = config.thinkingBudgetTokens ?? vendorConfig.thinkingBudgetTokens;
42
42
  this.client = new sdk_1.Anthropic(authType === "oauth"
43
- ? { authToken: config.apiKey }
44
- : { apiKey: config.apiKey });
43
+ ? { authToken: config.apiKey, defaultHeaders: config.defaultHeaders }
44
+ : { apiKey: config.apiKey, defaultHeaders: config.defaultHeaders });
45
45
  this.config = {
46
46
  model: config.model || "claude-haiku-4-5",
47
47
  maxTokens: config.maxTokens || 1024,
@@ -47,9 +47,7 @@ class GeminiAgent extends BaseAgent_1.BaseAgent {
47
47
  responseSchema,
48
48
  };
49
49
  // Initialize the model
50
- this.generativeModel = this.client.getGenerativeModel({
51
- model: this.config.model,
52
- });
50
+ this.generativeModel = this.client.getGenerativeModel({ model: this.config.model }, config.defaultHeaders ? { customHeaders: config.defaultHeaders } : undefined);
53
51
  // Add system message to history (skips if already exists with same content)
54
52
  this.addSystemMessage(this.getSystemMessage());
55
53
  }
@@ -26,6 +26,16 @@ type AgentConfig = BaseAgentConfig & {
26
26
  * const response = await agent.execute("Hello!");
27
27
  * ```
28
28
  */
29
+ /**
30
+ * Build a `beforeRequest` hook that adds custom headers to every request.
31
+ *
32
+ * The Mistral SDK has no `defaultHeaders` option like the Anthropic and OpenAI
33
+ * clients, so headers are injected at the HTTP layer instead. They overwrite
34
+ * headers the SDK already set, so that `defaultHeaders` means the same thing on
35
+ * every provider — see `CommonAgentConfig.defaultHeaders`. Verified against the
36
+ * OpenAI SDK on the wire: its `defaultHeaders` win over the client's own auth.
37
+ */
38
+ export declare function defaultHeadersHook(headers: Record<string, string>): (request: Request) => void;
29
39
  export declare class MistralAgent extends BaseAgent {
30
40
  private client;
31
41
  protected config: Partial<AgentConfig>;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MistralAgent = void 0;
4
+ exports.defaultHeadersHook = defaultHeadersHook;
4
5
  const mistralai_1 = require("@mistralai/mistralai");
6
+ const http_1 = require("@mistralai/mistralai/lib/http");
5
7
  const BaseAgent_1 = require("../BaseAgent");
6
8
  const AgentEvent_1 = require("../AgentEvent");
7
9
  const AgentError_1 = require("../errors/AgentError");
@@ -25,13 +27,34 @@ const VizConfig_1 = require("../../viz/VizConfig");
25
27
  * const response = await agent.execute("Hello!");
26
28
  * ```
27
29
  */
30
+ /**
31
+ * Build a `beforeRequest` hook that adds custom headers to every request.
32
+ *
33
+ * The Mistral SDK has no `defaultHeaders` option like the Anthropic and OpenAI
34
+ * clients, so headers are injected at the HTTP layer instead. They overwrite
35
+ * headers the SDK already set, so that `defaultHeaders` means the same thing on
36
+ * every provider — see `CommonAgentConfig.defaultHeaders`. Verified against the
37
+ * OpenAI SDK on the wire: its `defaultHeaders` win over the client's own auth.
38
+ */
39
+ function defaultHeadersHook(headers) {
40
+ return (request) => {
41
+ for (const [name, value] of Object.entries(headers)) {
42
+ request.headers.set(name, value);
43
+ }
44
+ };
45
+ }
28
46
  class MistralAgent extends BaseAgent_1.BaseAgent {
29
47
  constructor(config, history) {
30
48
  super({ ...config, vendor: "mistral" }, history);
31
49
  /** Count of tool calls in current execution */
32
50
  this.currentToolCallCount = 0;
51
+ const httpClient = new http_1.HTTPClient();
52
+ if (config.defaultHeaders) {
53
+ httpClient.addHook("beforeRequest", defaultHeadersHook(config.defaultHeaders));
54
+ }
33
55
  this.client = new mistralai_1.Mistral({
34
56
  apiKey: config.apiKey,
57
+ httpClient,
35
58
  });
36
59
  // Merge flat config (deprecated) with nested vendorConfig
37
60
  // Flat config takes precedence for backward compatibility
@@ -80,6 +80,7 @@ class OllamaAgent extends BaseAgent_1.BaseAgent {
80
80
  this.config = {
81
81
  model: config.model || "llama3.2",
82
82
  host,
83
+ defaultHeaders: config.defaultHeaders,
83
84
  maxTokens: config.maxTokens,
84
85
  temperature: config.temperature,
85
86
  topP: config.topP,
@@ -99,7 +100,10 @@ class OllamaAgent extends BaseAgent_1.BaseAgent {
99
100
  if (!OllamaClass) {
100
101
  throw new Error("Could not find Ollama class in ollama package");
101
102
  }
102
- this._client = new OllamaClass({ host: this.config.host });
103
+ this._client = new OllamaClass({
104
+ host: this.config.host,
105
+ headers: this.config.defaultHeaders,
106
+ });
103
107
  }
104
108
  catch (err) {
105
109
  throw new AgentError_1.ExecutionError(`Failed to load 'ollama' package. Install it with: npm install ollama\n${err instanceof Error ? err.message : String(err)}`);
@@ -58,6 +58,7 @@ class OpenAiAgent extends BaseAgent_1.BaseAgent {
58
58
  this.currentToolCallCount = 0;
59
59
  this.client = new openai_1.default({
60
60
  apiKey: config.apiKey,
61
+ defaultHeaders: config.defaultHeaders,
61
62
  });
62
63
  // Merge flat config (deprecated) with nested vendorConfig
63
64
  // Flat config takes precedence for backward compatibility
@@ -28,6 +28,7 @@ class OpenAICompatibleAgent extends BaseAgent_1.BaseAgent {
28
28
  this.client = new openai_1.default({
29
29
  apiKey: config.apiKey || "not-needed",
30
30
  baseURL: config.baseURL,
31
+ defaultHeaders: config.defaultHeaders,
31
32
  });
32
33
  this.config = {
33
34
  model: config.model,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agentionai/agents",
3
3
  "author": "Laurent Zuijdwijk",
4
- "version": "1.3.0",
4
+ "version": "1.4.0",
5
5
  "description": "Agent Library",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",