botinabox 2.16.16 → 2.16.17

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.
@@ -117,6 +117,27 @@ export interface ChatPipelineV2Config {
117
117
  messageText: string;
118
118
  channel: string;
119
119
  }) => Promise<ContextFile[]> | ContextFile[];
120
+ /**
121
+ * Optional per-turn tool-context resolver. Called once per inbound message
122
+ * with the resolved conversation coordinates (the same shape passed to
123
+ * `resolveContextFiles`). The returned fields are merged into the
124
+ * `ToolContext` handed to every tool handler for that turn — letting an app
125
+ * thread per-turn identity (e.g. which user the primary agent is acting on
126
+ * behalf of) into tool execution, which the static config cannot express.
127
+ *
128
+ * The base `ToolContext` fields (`taskId`, `agentId`, `hooks`, `db`,
129
+ * `resolveFilePath`) are applied first and cannot be overridden by the
130
+ * resolver — returned keys that collide with them are ignored. If the
131
+ * resolver throws, the error propagates to the turn's try/catch and fails
132
+ * loudly; there is no silent fallback.
133
+ */
134
+ resolveToolContext?: (ctx: {
135
+ channelId: string;
136
+ threadId: string;
137
+ userId?: string;
138
+ messageText: string;
139
+ channel: string;
140
+ }) => Promise<Record<string, unknown>> | Record<string, unknown>;
120
141
  }
121
142
  export declare class ChatPipelineV2 {
122
143
  private db;
package/dist/index.js CHANGED
@@ -2345,13 +2345,24 @@ ${ctx2}`;
2345
2345
 
2346
2346
  ${contextFilesBlock}`;
2347
2347
  }
2348
+ let toolContextExtra = {};
2349
+ if (this.config.resolveToolContext) {
2350
+ toolContextExtra = await this.config.resolveToolContext({
2351
+ channelId,
2352
+ threadId: threadTs,
2353
+ userId: msg.from,
2354
+ messageText: msg.body,
2355
+ channel: this.channel
2356
+ }) ?? {};
2357
+ }
2348
2358
  const { text, tasksDispatched } = await this.think(
2349
2359
  systemPrompt,
2350
2360
  history,
2351
2361
  msg.body,
2352
2362
  threadTs,
2353
2363
  channelId,
2354
- msg.attachmentBlocks
2364
+ msg.attachmentBlocks,
2365
+ toolContextExtra
2355
2366
  );
2356
2367
  await this.hooks.emit("typing.stop", { channel: this.channel, threadId: threadTs });
2357
2368
  if (text) {
@@ -2399,7 +2410,7 @@ ${contextFilesBlock}`;
2399
2410
  /**
2400
2411
  * Primary agent tool loop — adapted from ExecutionEngine pattern.
2401
2412
  */
2402
- async think(systemPrompt, history, currentMessage, threadTs, channelId, attachmentBlocks) {
2413
+ async think(systemPrompt, history, currentMessage, threadTs, channelId, attachmentBlocks, toolContextExtra) {
2403
2414
  const model = this.config.model ?? "claude-sonnet-4-6";
2404
2415
  const maxIterations = this.config.maxIterations ?? DEFAULT_MAX_ITERATIONS;
2405
2416
  const maxTokens = this.config.maxTokens ?? DEFAULT_MAX_TOKENS;
@@ -2432,6 +2443,9 @@ ${contextFilesBlock}`;
2432
2443
  if (handler) {
2433
2444
  try {
2434
2445
  const toolCtx = {
2446
+ // Per-turn extras first; base fields applied last so the
2447
+ // resolver can never override taskId/agentId/hooks/db.
2448
+ ...toolContextExtra,
2435
2449
  taskId: "",
2436
2450
  agentId: "primary",
2437
2451
  hooks: this.hooks,
package/package.json CHANGED
@@ -1,100 +1,100 @@
1
- {
2
- "name": "botinabox",
3
- "version": "2.16.16",
4
- "description": "Bot in a Box — framework for building multi-agent bots",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
12
- },
13
- "./anthropic": {
14
- "import": "./dist/providers/anthropic/index.js",
15
- "types": "./dist/providers/anthropic/index.d.ts"
16
- },
17
- "./openai": {
18
- "import": "./dist/providers/openai/index.js",
19
- "types": "./dist/providers/openai/index.d.ts"
20
- },
21
- "./ollama": {
22
- "import": "./dist/providers/ollama/index.js",
23
- "types": "./dist/providers/ollama/index.d.ts"
24
- },
25
- "./slack": {
26
- "import": "./dist/channels/slack/index.js",
27
- "types": "./dist/channels/slack/index.d.ts"
28
- },
29
- "./discord": {
30
- "import": "./dist/channels/discord/index.js",
31
- "types": "./dist/channels/discord/index.d.ts"
32
- },
33
- "./webhook": {
34
- "import": "./dist/channels/webhook/index.js",
35
- "types": "./dist/channels/webhook/index.d.ts"
36
- },
37
- "./google": {
38
- "import": "./dist/connectors/google/index.js",
39
- "types": "./dist/connectors/google/index.d.ts"
40
- }
41
- },
42
- "bin": {
43
- "botinabox": "./bin/botinabox.mjs"
44
- },
45
- "files": [
46
- "dist",
47
- "bin"
48
- ],
49
- "engines": {
50
- "node": ">=18"
51
- },
52
- "scripts": {
53
- "build": "tsup && tsc --emitDeclarationOnly",
54
- "test": "vitest run",
55
- "typecheck": "tsc --noEmit",
56
- "check-docs": "echo 'Documentation check passed'",
57
- "prepublishOnly": "npm run build && npm run typecheck && npm test"
58
- },
59
- "dependencies": {
60
- "@types/uuid": "^10.0.0",
61
- "ajv": "^8.17.1",
62
- "cron-parser": "^4.9.0",
63
- "latticesql": "^1.16.4",
64
- "uuid": "^13.0.0",
65
- "yaml": "^2.7.0"
66
- },
67
- "optionalDependencies": {
68
- "whisper-node": "^1.1.1"
69
- },
70
- "peerDependencies": {
71
- "@anthropic-ai/sdk": "^0.52.0",
72
- "googleapis": ">=140.0.0 <200.0.0",
73
- "openai": "^4.104.0"
74
- },
75
- "peerDependenciesMeta": {
76
- "@anthropic-ai/sdk": {
77
- "optional": true
78
- },
79
- "openai": {
80
- "optional": true
81
- },
82
- "googleapis": {
83
- "optional": true
84
- }
85
- },
86
- "repository": {
87
- "type": "git",
88
- "url": "https://github.com/automated-industries/botinabox.git"
89
- },
90
- "devDependencies": {
91
- "@anthropic-ai/sdk": "^0.52.0",
92
- "@types/better-sqlite3": "^7.6.12",
93
- "@types/node": "^22.10.0",
94
- "googleapis": "^171.4.0",
95
- "openai": "^4.104.0",
96
- "tsup": "^8.3.5",
97
- "typescript": "^5.7.2",
98
- "vitest": "^3.0.0"
99
- }
100
- }
1
+ {
2
+ "name": "botinabox",
3
+ "version": "2.16.17",
4
+ "description": "Bot in a Box — framework for building multi-agent bots",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./anthropic": {
14
+ "import": "./dist/providers/anthropic/index.js",
15
+ "types": "./dist/providers/anthropic/index.d.ts"
16
+ },
17
+ "./openai": {
18
+ "import": "./dist/providers/openai/index.js",
19
+ "types": "./dist/providers/openai/index.d.ts"
20
+ },
21
+ "./ollama": {
22
+ "import": "./dist/providers/ollama/index.js",
23
+ "types": "./dist/providers/ollama/index.d.ts"
24
+ },
25
+ "./slack": {
26
+ "import": "./dist/channels/slack/index.js",
27
+ "types": "./dist/channels/slack/index.d.ts"
28
+ },
29
+ "./discord": {
30
+ "import": "./dist/channels/discord/index.js",
31
+ "types": "./dist/channels/discord/index.d.ts"
32
+ },
33
+ "./webhook": {
34
+ "import": "./dist/channels/webhook/index.js",
35
+ "types": "./dist/channels/webhook/index.d.ts"
36
+ },
37
+ "./google": {
38
+ "import": "./dist/connectors/google/index.js",
39
+ "types": "./dist/connectors/google/index.d.ts"
40
+ }
41
+ },
42
+ "bin": {
43
+ "botinabox": "./bin/botinabox.mjs"
44
+ },
45
+ "files": [
46
+ "dist",
47
+ "bin"
48
+ ],
49
+ "engines": {
50
+ "node": ">=18"
51
+ },
52
+ "scripts": {
53
+ "build": "tsup && tsc --emitDeclarationOnly",
54
+ "test": "vitest run",
55
+ "typecheck": "tsc --noEmit",
56
+ "check-docs": "echo 'Documentation check passed'",
57
+ "prepublishOnly": "npm run build && npm run typecheck && npm test"
58
+ },
59
+ "dependencies": {
60
+ "@types/uuid": "^10.0.0",
61
+ "ajv": "^8.17.1",
62
+ "cron-parser": "^4.9.0",
63
+ "latticesql": "^1.16.4",
64
+ "uuid": "^13.0.0",
65
+ "yaml": "^2.7.0"
66
+ },
67
+ "optionalDependencies": {
68
+ "whisper-node": "^1.1.1"
69
+ },
70
+ "peerDependencies": {
71
+ "@anthropic-ai/sdk": "^0.52.0",
72
+ "googleapis": ">=140.0.0 <200.0.0",
73
+ "openai": "^4.104.0"
74
+ },
75
+ "peerDependenciesMeta": {
76
+ "@anthropic-ai/sdk": {
77
+ "optional": true
78
+ },
79
+ "openai": {
80
+ "optional": true
81
+ },
82
+ "googleapis": {
83
+ "optional": true
84
+ }
85
+ },
86
+ "repository": {
87
+ "type": "git",
88
+ "url": "https://github.com/automated-industries/botinabox.git"
89
+ },
90
+ "devDependencies": {
91
+ "@anthropic-ai/sdk": "^0.52.0",
92
+ "@types/better-sqlite3": "^7.6.12",
93
+ "@types/node": "^22.10.0",
94
+ "googleapis": "^171.4.0",
95
+ "openai": "^4.104.0",
96
+ "tsup": "^8.3.5",
97
+ "typescript": "^5.7.2",
98
+ "vitest": "^3.0.0"
99
+ }
100
+ }