botinabox 2.9.5 → 2.9.7

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/bin/botinabox.mjs CHANGED
@@ -1,2 +1,2 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  import('../dist/cli.js').then(m => m.main(process.argv.slice(2)));
@@ -82,6 +82,22 @@ export interface ExecutionEngineConfig {
82
82
  agent: Record<string, unknown>;
83
83
  task: Record<string, unknown>;
84
84
  }) => Promise<ContextFile[]> | ContextFile[];
85
+ /**
86
+ * Optional per-dispatch model resolver. Called once per task pickup with
87
+ * the resolved agent and task rows. Returns the model ID string to use
88
+ * for this specific task's LLM calls.
89
+ *
90
+ * When provided, the returned value overrides `config.model` for this
91
+ * dispatch only. When absent or when the resolver returns undefined,
92
+ * the global `config.model` is used as before.
93
+ *
94
+ * Use this to implement per-agent, per-task-type, or per-command model
95
+ * routing — e.g. route search tasks to Haiku and code tasks to Sonnet.
96
+ */
97
+ resolveModel?: (ctx: {
98
+ agent: Record<string, unknown>;
99
+ task: Record<string, unknown>;
100
+ }) => string | undefined;
85
101
  }
86
102
  /**
87
103
  * Wrap a set of context files in `<file path="...">...</file>` XML tags,
package/dist/index.js CHANGED
@@ -6574,6 +6574,7 @@ async function registerExecutionEngine(opts) {
6574
6574
  }
6575
6575
  const prompt = task.description ?? task.title ?? "";
6576
6576
  try {
6577
+ const taskModel = config.resolveModel ? config.resolveModel({ agent, task }) ?? model : model;
6577
6578
  const contextFiles = config.resolveContextFiles ? await config.resolveContextFiles({ agent, task }) : [];
6578
6579
  const contextFilesBlock = formatContextFilesBlock(contextFiles);
6579
6580
  const toolListing = toolDefs.length > 0 ? `
@@ -6596,7 +6597,7 @@ ${contextFilesBlock}` : "",
6596
6597
  let totalOutput = 0;
6597
6598
  for (let i = 0; i < maxIterations; i++) {
6598
6599
  const createParams = {
6599
- model,
6600
+ model: taskModel,
6600
6601
  max_tokens: 4096,
6601
6602
  system: systemPrompt,
6602
6603
  messages
@@ -6640,7 +6641,7 @@ ${contextFilesBlock}` : "",
6640
6641
  output: finalOutput,
6641
6642
  costCents,
6642
6643
  usage: { inputTokens: totalInput, outputTokens: totalOutput },
6643
- model,
6644
+ model: taskModel,
6644
6645
  provider: "anthropic"
6645
6646
  });
6646
6647
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botinabox",
3
- "version": "2.9.5",
3
+ "version": "2.9.7",
4
4
  "description": "Bot in a Box — framework for building multi-agent bots",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -60,7 +60,7 @@
60
60
  "@types/uuid": "^10.0.0",
61
61
  "ajv": "^8.17.1",
62
62
  "cron-parser": "^4.9.0",
63
- "latticesql": "^1.6.10",
63
+ "latticesql": "^1.8.0",
64
64
  "uuid": "^13.0.0",
65
65
  "yaml": "^2.7.0"
66
66
  },
@@ -1,82 +0,0 @@
1
- import { c as ContentBlock } from './provider-BHkqkSdq.js';
2
-
3
- /** Channel adapter types — Story 1.5 / 4.1 */
4
-
5
- type ChatType = "direct" | "group" | "channel";
6
- type FormattingMode = "markdown" | "mrkdwn" | "html" | "plain";
7
- interface ChannelCapabilities {
8
- chatTypes: ChatType[];
9
- threads: boolean;
10
- reactions: boolean;
11
- editing: boolean;
12
- media: boolean;
13
- polls: boolean;
14
- maxTextLength: number;
15
- formattingMode: FormattingMode;
16
- }
17
- interface ChannelMeta {
18
- displayName: string;
19
- icon?: string;
20
- homepage?: string;
21
- }
22
- interface InboundMessage {
23
- id: string;
24
- channel: string;
25
- account?: string;
26
- from: string;
27
- userId?: string;
28
- body: string;
29
- threadId?: string;
30
- replyToId?: string;
31
- attachments?: Attachment[];
32
- /**
33
- * Multimodal content blocks produced by attachment enrichers.
34
- * When set, ChatPipeline builds a multimodal user message that passes
35
- * these blocks through to the LLM provider alongside `body`.
36
- */
37
- attachmentBlocks?: ContentBlock[];
38
- receivedAt: string;
39
- raw?: unknown;
40
- }
41
- type AttachmentMediaType = "image" | "video" | "audio" | "pdf" | "doc" | "excel" | "presentation" | "html" | "link" | "misc";
42
- interface Attachment {
43
- type: AttachmentMediaType;
44
- url?: string;
45
- mimeType?: string;
46
- filename?: string;
47
- size?: number;
48
- }
49
- interface OutboundPayload {
50
- text: string;
51
- threadId?: string;
52
- replyToId?: string;
53
- attachments?: Attachment[];
54
- }
55
- interface SendResult {
56
- success: boolean;
57
- messageId?: string;
58
- error?: string;
59
- }
60
- interface HealthStatus {
61
- ok: boolean;
62
- latencyMs?: number;
63
- error?: string;
64
- }
65
- type ChannelConfig = Record<string, unknown>;
66
- interface ChannelAdapter {
67
- /** Unique identifier for this adapter instance */
68
- id: string;
69
- meta: ChannelMeta;
70
- capabilities: ChannelCapabilities;
71
- connect(config: ChannelConfig): Promise<void>;
72
- disconnect(): Promise<void>;
73
- healthCheck(): Promise<HealthStatus>;
74
- send(target: {
75
- peerId: string;
76
- threadId?: string;
77
- }, payload: OutboundPayload): Promise<SendResult>;
78
- /** Called when a message arrives — set by the framework */
79
- onMessage?: (message: InboundMessage) => Promise<void>;
80
- }
81
-
82
- export type { Attachment as A, ChannelAdapter as C, FormattingMode as F, HealthStatus as H, InboundMessage as I, OutboundPayload as O, SendResult as S, AttachmentMediaType as a, ChannelCapabilities as b, ChannelConfig as c, ChannelMeta as d, ChatType as e };
@@ -1,73 +0,0 @@
1
- /** Channel adapter types — Story 1.5 / 4.1 */
2
- type ChatType = "direct" | "group" | "channel";
3
- type FormattingMode = "markdown" | "mrkdwn" | "html" | "plain";
4
- interface ChannelCapabilities {
5
- chatTypes: ChatType[];
6
- threads: boolean;
7
- reactions: boolean;
8
- editing: boolean;
9
- media: boolean;
10
- polls: boolean;
11
- maxTextLength: number;
12
- formattingMode: FormattingMode;
13
- }
14
- interface ChannelMeta {
15
- displayName: string;
16
- icon?: string;
17
- homepage?: string;
18
- }
19
- interface InboundMessage {
20
- id: string;
21
- channel: string;
22
- account?: string;
23
- from: string;
24
- userId?: string;
25
- body: string;
26
- threadId?: string;
27
- replyToId?: string;
28
- attachments?: Attachment[];
29
- receivedAt: string;
30
- raw?: unknown;
31
- }
32
- type AttachmentMediaType = "image" | "video" | "audio" | "pdf" | "doc" | "excel" | "presentation" | "html" | "link" | "misc";
33
- interface Attachment {
34
- type: AttachmentMediaType;
35
- url?: string;
36
- mimeType?: string;
37
- filename?: string;
38
- size?: number;
39
- }
40
- interface OutboundPayload {
41
- text: string;
42
- threadId?: string;
43
- replyToId?: string;
44
- attachments?: Attachment[];
45
- }
46
- interface SendResult {
47
- success: boolean;
48
- messageId?: string;
49
- error?: string;
50
- }
51
- interface HealthStatus {
52
- ok: boolean;
53
- latencyMs?: number;
54
- error?: string;
55
- }
56
- type ChannelConfig = Record<string, unknown>;
57
- interface ChannelAdapter {
58
- /** Unique identifier for this adapter instance */
59
- id: string;
60
- meta: ChannelMeta;
61
- capabilities: ChannelCapabilities;
62
- connect(config: ChannelConfig): Promise<void>;
63
- disconnect(): Promise<void>;
64
- healthCheck(): Promise<HealthStatus>;
65
- send(target: {
66
- peerId: string;
67
- threadId?: string;
68
- }, payload: OutboundPayload): Promise<SendResult>;
69
- /** Called when a message arrives — set by the framework */
70
- onMessage?: (message: InboundMessage) => Promise<void>;
71
- }
72
-
73
- export type { Attachment as A, ChannelAdapter as C, FormattingMode as F, HealthStatus as H, InboundMessage as I, OutboundPayload as O, SendResult as S, AttachmentMediaType as a, ChannelCapabilities as b, ChannelConfig as c, ChannelMeta as d, ChatType as e };