botinabox 2.9.1 → 2.9.2
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/README.md +2 -1
- package/dist/channels/discord/adapter.d.ts +32 -0
- package/dist/channels/discord/inbound.d.ts +25 -0
- package/dist/channels/discord/index.d.ts +8 -84
- package/dist/channels/discord/models.d.ts +8 -0
- package/dist/channels/discord/outbound.d.ts +14 -0
- package/dist/channels/slack/adapter.d.ts +33 -0
- package/dist/channels/slack/bolt-adapter.d.ts +31 -0
- package/dist/channels/slack/enrichers/enrich.d.ts +12 -0
- package/dist/channels/slack/enrichers/image-enricher.d.ts +10 -0
- package/dist/channels/slack/enrichers/index.d.ts +4 -0
- package/dist/channels/slack/enrichers/pdf-enricher.d.ts +8 -0
- package/dist/channels/slack/enrichers/types.d.ts +33 -0
- package/dist/channels/slack/inbound.d.ts +59 -0
- package/dist/channels/slack/index.d.ts +13 -252
- package/dist/channels/slack/media-type.d.ts +14 -0
- package/dist/channels/slack/models.d.ts +9 -0
- package/dist/channels/slack/outbound.d.ts +12 -0
- package/dist/channels/slack/transcribe.d.ts +41 -0
- package/dist/channels/webhook/adapter.d.ts +23 -0
- package/dist/channels/webhook/hmac.d.ts +13 -0
- package/dist/channels/webhook/index.d.ts +7 -70
- package/dist/channels/webhook/models.d.ts +9 -0
- package/dist/channels/webhook/server.d.ts +20 -0
- package/dist/cli/templates/config.yml.d.ts +7 -0
- package/dist/cli/templates/env.d.ts +1 -0
- package/dist/cli/templates/index.ts.d.ts +2 -0
- package/dist/cli/templates/package.json.d.ts +5 -0
- package/dist/cli.d.ts +1 -3
- package/dist/connectors/google/calendar-connector.d.ts +40 -0
- package/dist/connectors/google/drive-connector.d.ts +43 -0
- package/dist/connectors/google/drive-read.d.ts +81 -0
- package/dist/connectors/google/gmail-connector.d.ts +42 -0
- package/dist/connectors/google/index.d.ts +10 -369
- package/dist/connectors/google/oauth.d.ts +48 -0
- package/dist/connectors/google/types.d.ts +110 -0
- package/dist/core/chat/auto-discovery.d.ts +16 -0
- package/dist/core/chat/channel-registry.d.ts +45 -0
- package/dist/core/chat/chat-pipeline-v2.d.ts +138 -0
- package/dist/core/chat/chat-pipeline.d.ts +116 -0
- package/dist/core/chat/chat-responder.d.ts +94 -0
- package/dist/core/chat/formatter.d.ts +11 -0
- package/dist/core/chat/index.d.ts +26 -0
- package/dist/core/chat/message-interpreter.d.ts +91 -0
- package/dist/core/chat/message-store.d.ts +71 -0
- package/dist/core/chat/notification-queue.d.ts +34 -0
- package/dist/core/chat/pipeline.d.ts +38 -0
- package/dist/core/chat/policies.d.ts +16 -0
- package/dist/core/chat/routing.d.ts +17 -0
- package/dist/core/chat/session-key.d.ts +30 -0
- package/dist/core/chat/session-manager.d.ts +17 -0
- package/dist/core/chat/text-chunker.d.ts +9 -0
- package/dist/core/chat/triage-router.d.ts +75 -0
- package/dist/core/chat/types.d.ts +5 -0
- package/dist/core/config/defaults.d.ts +2 -0
- package/dist/core/config/index.d.ts +6 -0
- package/dist/core/config/interpolate.d.ts +5 -0
- package/dist/core/config/loader.d.ts +24 -0
- package/dist/core/config/schema.d.ts +5 -0
- package/dist/core/data/context-builder.d.ts +27 -0
- package/dist/core/data/core-entity-contexts.d.ts +14 -0
- package/dist/core/data/core-migrations.d.ts +5 -0
- package/dist/core/data/core-schema.d.ts +6 -0
- package/dist/core/data/data-store.d.ts +67 -0
- package/dist/core/data/domain-entity-contexts.d.ts +35 -0
- package/dist/core/data/domain-schema.d.ts +36 -0
- package/dist/core/data/index.d.ts +8 -0
- package/dist/core/data/types.d.ts +111 -0
- package/dist/core/hooks/hook-bus.d.ts +24 -0
- package/dist/core/hooks/index.d.ts +2 -0
- package/dist/core/hooks/types.d.ts +19 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/llm/auto-discovery.d.ts +11 -0
- package/dist/core/llm/cost-tracker.d.ts +6 -0
- package/dist/core/llm/default-llm-call.d.ts +35 -0
- package/dist/core/llm/index.d.ts +6 -0
- package/dist/core/llm/model-router.d.ts +25 -0
- package/dist/core/llm/provider-registry.d.ts +9 -0
- package/dist/core/llm/types.d.ts +2 -0
- package/dist/core/orchestrator/adapters/api-adapter.d.ts +34 -0
- package/dist/core/orchestrator/adapters/cli-adapter.d.ts +62 -0
- package/dist/core/orchestrator/adapters/deterministic-adapter.d.ts +35 -0
- package/dist/core/orchestrator/adapters/env-whitelist.d.ts +4 -0
- package/dist/core/orchestrator/adapters/output-extractor.d.ts +11 -0
- package/dist/core/orchestrator/adapters/process-manager.d.ts +15 -0
- package/dist/core/orchestrator/adapters/tool-loop.d.ts +22 -0
- package/dist/core/orchestrator/agent-registry.d.ts +31 -0
- package/dist/core/orchestrator/budget-controller.d.ts +19 -0
- package/dist/core/orchestrator/chain-guard.d.ts +14 -0
- package/dist/core/orchestrator/circuit-breaker.d.ts +65 -0
- package/dist/core/orchestrator/claude-stream-parser.d.ts +31 -0
- package/dist/core/orchestrator/config-revisions.d.ts +6 -0
- package/dist/core/orchestrator/dependency-resolver.d.ts +20 -0
- package/dist/core/orchestrator/execution-engine.d.ts +99 -0
- package/dist/core/orchestrator/governance-gate.d.ts +110 -0
- package/dist/core/orchestrator/learning-pipeline.d.ts +112 -0
- package/dist/core/orchestrator/loop-detector.d.ts +51 -0
- package/dist/core/orchestrator/ndjson-logger.d.ts +6 -0
- package/dist/core/orchestrator/permission-relay.d.ts +72 -0
- package/dist/core/orchestrator/run-manager.d.ts +31 -0
- package/dist/core/orchestrator/scheduler.d.ts +74 -0
- package/dist/core/orchestrator/secret-store.d.ts +57 -0
- package/dist/core/orchestrator/session-manager.d.ts +13 -0
- package/dist/core/orchestrator/task-queue.d.ts +34 -0
- package/dist/core/orchestrator/template-interpolate.d.ts +5 -0
- package/dist/core/orchestrator/tools/file-ops.d.ts +12 -0
- package/dist/core/orchestrator/tools/index.d.ts +47 -0
- package/dist/core/orchestrator/tools/management.d.ts +12 -0
- package/dist/core/orchestrator/tools/messaging.d.ts +21 -0
- package/dist/core/orchestrator/tools/read-file.d.ts +5 -0
- package/dist/core/orchestrator/tools/resolve-agent.d.ts +9 -0
- package/dist/core/orchestrator/tools/roster.d.ts +16 -0
- package/dist/core/orchestrator/tools/send-file.d.ts +5 -0
- package/dist/core/orchestrator/tools/status.d.ts +20 -0
- package/dist/core/orchestrator/tools/task-ops.d.ts +13 -0
- package/dist/core/orchestrator/user-registry.d.ts +47 -0
- package/dist/core/orchestrator/wakeup-queue.d.ts +9 -0
- package/dist/core/orchestrator/workflow-engine.d.ts +47 -0
- package/dist/core/security/audit.d.ts +20 -0
- package/dist/core/security/column-validator.d.ts +20 -0
- package/dist/core/security/index.d.ts +5 -0
- package/dist/core/security/process-env.d.ts +13 -0
- package/dist/core/security/sanitizer.d.ts +11 -0
- package/dist/core/security/types.d.ts +11 -0
- package/dist/core/update/auto-update.d.ts +21 -0
- package/dist/core/update/backup-manager.d.ts +7 -0
- package/dist/core/update/index.d.ts +8 -0
- package/dist/core/update/migration-hooks.d.ts +11 -0
- package/dist/core/update/types.d.ts +11 -0
- package/dist/core/update/update-checker.d.ts +11 -0
- package/dist/core/update/update-manager.d.ts +25 -0
- package/dist/core/update/version-utils.d.ts +6 -0
- package/dist/index.d.ts +38 -2366
- package/dist/index.js +112 -5
- package/dist/providers/anthropic/index.d.ts +5 -20
- package/dist/providers/anthropic/models.d.ts +2 -0
- package/dist/providers/anthropic/provider.d.ts +13 -0
- package/dist/providers/anthropic/tool-converter.d.ts +10 -0
- package/dist/providers/ollama/index.d.ts +4 -22
- package/dist/providers/ollama/provider.d.ts +17 -0
- package/dist/providers/openai/index.d.ts +5 -20
- package/dist/providers/openai/models.d.ts +2 -0
- package/dist/providers/openai/provider.d.ts +13 -0
- package/dist/providers/openai/tool-converter.d.ts +10 -0
- package/dist/shared/constants.d.ts +50 -0
- package/dist/shared/index.d.ts +14 -0
- package/dist/shared/types/agent.d.ts +36 -0
- package/dist/shared/types/channel.d.ts +78 -0
- package/dist/shared/types/config.d.ts +160 -0
- package/dist/shared/types/connector.d.ts +77 -0
- package/dist/shared/types/execution.d.ts +29 -0
- package/dist/shared/types/provider.d.ts +87 -0
- package/dist/shared/types/task.d.ts +47 -0
- package/dist/shared/types/workflow.d.ts +39 -0
- package/dist/shared/utils.d.ts +6 -0
- package/dist/update-check.d.ts +5 -0
- package/package.json +2 -2
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionKey — structured key for chat sessions.
|
|
3
|
+
* Story 4.3
|
|
4
|
+
*/
|
|
5
|
+
export declare class SessionKey {
|
|
6
|
+
readonly agentId: string;
|
|
7
|
+
readonly channel: string;
|
|
8
|
+
readonly scope: string;
|
|
9
|
+
constructor(agentId: string, channel: string, scope: string);
|
|
10
|
+
toString(): string;
|
|
11
|
+
toJSON(): {
|
|
12
|
+
agentId: string;
|
|
13
|
+
channel: string;
|
|
14
|
+
scope: string;
|
|
15
|
+
};
|
|
16
|
+
static fromString(key: string): SessionKey;
|
|
17
|
+
/**
|
|
18
|
+
* Build a session key from structured parameters.
|
|
19
|
+
*
|
|
20
|
+
* @param agentId - The agent identifier
|
|
21
|
+
* @param channel - The channel identifier
|
|
22
|
+
* @param chatType - 'dm' or 'group'
|
|
23
|
+
* @param peerId - The peer/user ID
|
|
24
|
+
* @param dmScope - DM scoping strategy
|
|
25
|
+
* - 'main' → single session per agent+channel regardless of peer
|
|
26
|
+
* - 'per-peer' → one session per (agent, peer)
|
|
27
|
+
* - 'per-channel-peer' → one session per (agent, channel, peer)
|
|
28
|
+
*/
|
|
29
|
+
static build(agentId: string, channel: string, chatType: "dm" | "group", peerId: string, dmScope: "main" | "per-peer" | "per-channel-peer"): SessionKey;
|
|
30
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChatSessionManager — wraps orchestrator SessionManager with SessionKey-based lookup.
|
|
3
|
+
* Story 4.3
|
|
4
|
+
*/
|
|
5
|
+
import type { DataStore } from "../data/data-store.js";
|
|
6
|
+
import { SessionKey } from "./session-key.js";
|
|
7
|
+
export declare class ChatSessionManager {
|
|
8
|
+
private readonly inner;
|
|
9
|
+
constructor(db: DataStore);
|
|
10
|
+
save(key: SessionKey, params: Record<string, unknown>): Promise<string>;
|
|
11
|
+
load(key: SessionKey): Promise<Record<string, unknown> | undefined>;
|
|
12
|
+
clear(key: SessionKey): Promise<void>;
|
|
13
|
+
shouldClear(session: Record<string, unknown>, opts: {
|
|
14
|
+
maxRuns?: number;
|
|
15
|
+
maxAgeHours?: number;
|
|
16
|
+
}): Promise<boolean>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text chunker — splits long text into chunks at natural boundaries.
|
|
3
|
+
* Story 4.4
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Split text into chunks of at most maxLen characters.
|
|
7
|
+
* Splits at paragraph boundaries first, then sentence, then word, then hard-cuts.
|
|
8
|
+
*/
|
|
9
|
+
export declare function chunkText(text: string, maxLen: number): string[];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TriageRouter — content-based routing with deterministic-first resolution.
|
|
3
|
+
* Story 6.3
|
|
4
|
+
*
|
|
5
|
+
* Replaces the simple channel→agent binding with intelligent routing:
|
|
6
|
+
* 1. Keyword/regex rules evaluated first (deterministic, ~4ms)
|
|
7
|
+
* 2. LLM classification only for ambiguous messages (async, ~2-4s)
|
|
8
|
+
* 3. Ownership chain logged for every routing decision
|
|
9
|
+
*
|
|
10
|
+
* Key constraint: specialists return to triage, never to another specialist.
|
|
11
|
+
*/
|
|
12
|
+
import type { DataStore } from '../data/data-store.js';
|
|
13
|
+
import type { HookBus } from '../hooks/hook-bus.js';
|
|
14
|
+
import type { InboundMessage } from './types.js';
|
|
15
|
+
export interface RoutingRule {
|
|
16
|
+
/** Target agent slug */
|
|
17
|
+
agentSlug: string;
|
|
18
|
+
/** Keywords that trigger this rule (case-insensitive) */
|
|
19
|
+
keywords?: string[];
|
|
20
|
+
/** Regex patterns that trigger this rule */
|
|
21
|
+
patterns?: string[];
|
|
22
|
+
/** Priority — lower number wins ties. Default: 50 */
|
|
23
|
+
priority?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface RoutingDecision {
|
|
26
|
+
timestamp: string;
|
|
27
|
+
source: string;
|
|
28
|
+
target: string;
|
|
29
|
+
reason: string;
|
|
30
|
+
method: 'deterministic' | 'llm';
|
|
31
|
+
messageId?: string;
|
|
32
|
+
channel?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface TriageRouterConfig {
|
|
35
|
+
/** Static routing rules evaluated deterministically */
|
|
36
|
+
rules: RoutingRule[];
|
|
37
|
+
/** Fallback agent if no rule matches and LLM is unavailable */
|
|
38
|
+
fallbackAgent?: string;
|
|
39
|
+
/** Whether to use LLM for ambiguous messages. Default: true */
|
|
40
|
+
llmFallback?: boolean;
|
|
41
|
+
/** Log decisions to the database. Default: true */
|
|
42
|
+
persist?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare class TriageRouter {
|
|
45
|
+
private db;
|
|
46
|
+
private hooks;
|
|
47
|
+
private readonly rules;
|
|
48
|
+
private readonly fallbackAgent?;
|
|
49
|
+
private readonly llmFallback;
|
|
50
|
+
private readonly persist;
|
|
51
|
+
private readonly compiledRules;
|
|
52
|
+
constructor(db: DataStore, hooks: HookBus, config: TriageRouterConfig);
|
|
53
|
+
/**
|
|
54
|
+
* Route an inbound message to the best agent.
|
|
55
|
+
* Returns the agent slug and the routing decision.
|
|
56
|
+
*/
|
|
57
|
+
route(msg: InboundMessage): Promise<{
|
|
58
|
+
agentSlug: string | undefined;
|
|
59
|
+
decision: RoutingDecision;
|
|
60
|
+
}>;
|
|
61
|
+
/**
|
|
62
|
+
* Query the ownership chain for a given message or channel.
|
|
63
|
+
*/
|
|
64
|
+
getDecisionHistory(filter?: {
|
|
65
|
+
channel?: string;
|
|
66
|
+
limit?: number;
|
|
67
|
+
}): Promise<RoutingDecision[]>;
|
|
68
|
+
/**
|
|
69
|
+
* LLM classification — emits a hook for external LLM integration.
|
|
70
|
+
* Returns agent slug + reason, or undefined if LLM is unavailable.
|
|
71
|
+
*/
|
|
72
|
+
private classifyWithLLM;
|
|
73
|
+
private buildDecision;
|
|
74
|
+
private logDecision;
|
|
75
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat types — re-exports from @botinabox/shared channel types.
|
|
3
|
+
* Story 4.1
|
|
4
|
+
*/
|
|
5
|
+
export type { ChatType, FormattingMode, ChannelCapabilities, ChannelMeta, InboundMessage, Attachment, OutboundPayload, SendResult, HealthStatus, ChannelConfig, ChannelAdapter, } from "../../shared/index.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { loadConfig, getConfig, initConfig, _resetConfig } from "./loader.js";
|
|
2
|
+
export type { ConfigLoadError, ConfigLoadResult } from "./loader.js";
|
|
3
|
+
export { interpolateEnv } from "./interpolate.js";
|
|
4
|
+
export { validateConfig } from "./schema.js";
|
|
5
|
+
export type { SchemaError } from "./schema.js";
|
|
6
|
+
export { DEFAULT_CONFIG } from "./defaults.js";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { BotConfig } from "../../shared/index.js";
|
|
2
|
+
export interface ConfigLoadError {
|
|
3
|
+
field: string;
|
|
4
|
+
message: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ConfigLoadResult {
|
|
7
|
+
config: BotConfig;
|
|
8
|
+
errors: ConfigLoadError[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Load and merge config from file, with env var interpolation and runtime overrides.
|
|
12
|
+
* Merge order: defaults < config file < runtime overrides
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadConfig(opts?: {
|
|
15
|
+
configPath?: string;
|
|
16
|
+
overrides?: Partial<BotConfig>;
|
|
17
|
+
env?: Record<string, string | undefined>;
|
|
18
|
+
}): ConfigLoadResult;
|
|
19
|
+
/** Get the loaded config singleton. Auto-initializes with defaults if not loaded. */
|
|
20
|
+
export declare function getConfig(): BotConfig;
|
|
21
|
+
/** Initialize the config singleton. Returns errors if any. */
|
|
22
|
+
export declare function initConfig(opts?: Parameters<typeof loadConfig>[0]): ConfigLoadError[];
|
|
23
|
+
/** Reset the singleton (for testing) */
|
|
24
|
+
export declare function _resetConfig(): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SystemContextBuilder — loads entity data from the database and formats
|
|
3
|
+
* it as markdown for injection into LLM system prompts.
|
|
4
|
+
*
|
|
5
|
+
* Used by both the ChatPipeline (ack layer) and ExecutionEngine (agent layer)
|
|
6
|
+
* to give LLMs awareness of the system state.
|
|
7
|
+
*/
|
|
8
|
+
import type { DataStore } from './data-store.js';
|
|
9
|
+
export interface SystemContextOptions {
|
|
10
|
+
/** Include users. Default: true */
|
|
11
|
+
users?: boolean;
|
|
12
|
+
/** Include agents. Default: true */
|
|
13
|
+
agents?: boolean;
|
|
14
|
+
/** Include projects. Default: true */
|
|
15
|
+
projects?: boolean;
|
|
16
|
+
/** Include clients. Default: true */
|
|
17
|
+
clients?: boolean;
|
|
18
|
+
/** Include files. Default: true */
|
|
19
|
+
files?: boolean;
|
|
20
|
+
/** Include org. Default: true */
|
|
21
|
+
org?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build a markdown-formatted system context string from the database.
|
|
25
|
+
* Queries users, agents, projects, clients, files, and org.
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildSystemContext(db: DataStore, options?: SystemContextOptions): Promise<string>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DataStore } from "./data-store.js";
|
|
2
|
+
/**
|
|
3
|
+
* Define default entity context rendering for botinabox core tables.
|
|
4
|
+
* Call after defineCoreTables() and before or after init().
|
|
5
|
+
*
|
|
6
|
+
* Renders:
|
|
7
|
+
* - agents/ — per-agent context (AGENT.md, PROJECTS.md if agent_project exists)
|
|
8
|
+
* - users/ — per-user context (USER.md) — protected
|
|
9
|
+
* - skills/ — per-skill context (SKILL.md)
|
|
10
|
+
*
|
|
11
|
+
* Apps can override by calling db.defineEntityContext() with the same table name
|
|
12
|
+
* BEFORE calling defineCoreEntityContexts().
|
|
13
|
+
*/
|
|
14
|
+
export declare function defineCoreEntityContexts(db: DataStore): void;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { HookBus } from '../hooks/hook-bus.js';
|
|
2
|
+
import type { EntityContextDef, PkLookup, QueryOptions, Row, SeedItem, TableDefinition, TableInfoRow } from './types.js';
|
|
3
|
+
export declare class DataStoreError extends Error {
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Thin wrapper around Lattice that provides the botinabox DataStore API.
|
|
8
|
+
*
|
|
9
|
+
* Delegates all data operations to the latticesql package. Application-level
|
|
10
|
+
* events (task.created, run.completed, etc.) remain on the HookBus — they are
|
|
11
|
+
* emitted by orchestrator modules, not the data layer.
|
|
12
|
+
*/
|
|
13
|
+
export declare class DataStore {
|
|
14
|
+
private lattice;
|
|
15
|
+
private readonly hooks;
|
|
16
|
+
private readonly outputDir;
|
|
17
|
+
private _initialized;
|
|
18
|
+
private readonly deferredStatements;
|
|
19
|
+
constructor(opts: {
|
|
20
|
+
dbPath: string;
|
|
21
|
+
outputDir?: string;
|
|
22
|
+
wal?: boolean;
|
|
23
|
+
hooks?: HookBus;
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Register a table definition. Must be called before init().
|
|
27
|
+
*
|
|
28
|
+
* tableConstraints may contain both inline constraints (FOREIGN KEY, UNIQUE)
|
|
29
|
+
* and standalone SQL statements (CREATE INDEX). Standalone statements are
|
|
30
|
+
* deferred and executed after init() creates the tables.
|
|
31
|
+
*/
|
|
32
|
+
define(name: string, def: TableDefinition): void;
|
|
33
|
+
/**
|
|
34
|
+
* Register an entity context definition for per-entity file rendering.
|
|
35
|
+
*/
|
|
36
|
+
defineEntityContext(name: string, def: EntityContextDef): void;
|
|
37
|
+
init(opts?: {
|
|
38
|
+
migrations?: Array<{
|
|
39
|
+
version: string;
|
|
40
|
+
sql: string;
|
|
41
|
+
}>;
|
|
42
|
+
}): Promise<void>;
|
|
43
|
+
private assertInitialized;
|
|
44
|
+
insert(table: string, row: Row): Promise<Row>;
|
|
45
|
+
upsert(table: string, row: Row): Promise<Row>;
|
|
46
|
+
update(table: string, pk: PkLookup, changes: Row): Promise<Row>;
|
|
47
|
+
delete(table: string, pk: PkLookup): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Get a single row by primary key.
|
|
50
|
+
* Returns undefined if not found (Lattice returns null).
|
|
51
|
+
*/
|
|
52
|
+
get(table: string, pk: PkLookup): Promise<Row | undefined>;
|
|
53
|
+
query(table: string, opts?: QueryOptions): Promise<Row[]>;
|
|
54
|
+
count(table: string, opts?: QueryOptions): Promise<number>;
|
|
55
|
+
link(junctionTable: string, row: Row): Promise<void>;
|
|
56
|
+
unlink(junctionTable: string, row: Row): Promise<void>;
|
|
57
|
+
migrate(migrations: Array<{
|
|
58
|
+
version: string;
|
|
59
|
+
sql: string;
|
|
60
|
+
}>): Promise<void>;
|
|
61
|
+
seed(items: SeedItem[]): Promise<void>;
|
|
62
|
+
render(): Promise<void>;
|
|
63
|
+
reconcile(): Promise<void>;
|
|
64
|
+
tableInfo(table: string): TableInfoRow[];
|
|
65
|
+
close(): void;
|
|
66
|
+
on(event: string, handler: (context: Record<string, unknown>) => void): void;
|
|
67
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DataStore } from "./data-store.js";
|
|
2
|
+
/**
|
|
3
|
+
* Options for domain entity context generation.
|
|
4
|
+
* Match the options used in defineDomainTables().
|
|
5
|
+
*/
|
|
6
|
+
export interface DomainEntityContextOptions {
|
|
7
|
+
clients?: boolean;
|
|
8
|
+
repositories?: boolean;
|
|
9
|
+
files?: boolean;
|
|
10
|
+
channels?: boolean;
|
|
11
|
+
rules?: boolean;
|
|
12
|
+
/** Column used as directory name for each entity type. Default: 'id'. */
|
|
13
|
+
orgSlugColumn?: string;
|
|
14
|
+
projectSlugColumn?: string;
|
|
15
|
+
clientSlugColumn?: string;
|
|
16
|
+
fileSlugColumn?: string;
|
|
17
|
+
channelSlugColumn?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Define entity context rendering for standard domain tables.
|
|
21
|
+
* Call after defineDomainTables() and defineCoreTables().
|
|
22
|
+
*
|
|
23
|
+
* Renders per-entity directories with context files for:
|
|
24
|
+
* org, project, + optional client, file, channel entities.
|
|
25
|
+
* Also adds PROJECTS.md, RULES.md, SKILLS.md, REPOS.md to agent context.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* defineCoreTables(db);
|
|
30
|
+
* defineDomainTables(db);
|
|
31
|
+
* defineCoreEntityContexts(db); // agents, users, skills
|
|
32
|
+
* defineDomainEntityContexts(db); // org, project, client, file, channel
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function defineDomainEntityContexts(db: DataStore, options?: DomainEntityContextOptions): void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { DataStore } from "./data-store.js";
|
|
2
|
+
/**
|
|
3
|
+
* Options for domain table generation.
|
|
4
|
+
* Enable/disable optional tables based on your app's needs.
|
|
5
|
+
*/
|
|
6
|
+
export interface DomainSchemaOptions {
|
|
7
|
+
/** Include client + invoice tables (default: true) */
|
|
8
|
+
clients?: boolean;
|
|
9
|
+
/** Include repository table (default: true) */
|
|
10
|
+
repositories?: boolean;
|
|
11
|
+
/** Include file table (default: true) */
|
|
12
|
+
files?: boolean;
|
|
13
|
+
/** Include channel table (default: true) */
|
|
14
|
+
channels?: boolean;
|
|
15
|
+
/** Include rule table + junction tables (default: true) */
|
|
16
|
+
rules?: boolean;
|
|
17
|
+
/** Include event audit log (default: true) */
|
|
18
|
+
events?: boolean;
|
|
19
|
+
/** Include cross-domain junction tables (default: true) */
|
|
20
|
+
junctions?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Define standard domain tables that most multi-agent apps need.
|
|
24
|
+
* Call after defineCoreTables() and before db.init().
|
|
25
|
+
*
|
|
26
|
+
* Provides: org, project, + optional client, invoice, repository,
|
|
27
|
+
* file, channel, rule, event tables with appropriate junction tables.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* defineCoreTables(db);
|
|
32
|
+
* defineDomainTables(db); // all tables
|
|
33
|
+
* defineDomainTables(db, { clients: false }); // skip client/invoice
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function defineDomainTables(db: DataStore, options?: DomainSchemaOptions): void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './data-store.js';
|
|
3
|
+
export * from './core-schema.js';
|
|
4
|
+
export * from './core-migrations.js';
|
|
5
|
+
export * from './core-entity-contexts.js';
|
|
6
|
+
export * from './domain-schema.js';
|
|
7
|
+
export * from './domain-entity-contexts.js';
|
|
8
|
+
export * from './context-builder.js';
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export interface TableDefinition {
|
|
2
|
+
columns: Record<string, string>;
|
|
3
|
+
primaryKey?: string | string[];
|
|
4
|
+
tableConstraints?: string[];
|
|
5
|
+
relations?: Record<string, RelationDef>;
|
|
6
|
+
render?: string | ((rows: Row[]) => string);
|
|
7
|
+
outputFile?: string;
|
|
8
|
+
filter?: (rows: Row[]) => Row[];
|
|
9
|
+
}
|
|
10
|
+
export interface RelationDef {
|
|
11
|
+
type: 'belongsTo' | 'hasMany';
|
|
12
|
+
table: string;
|
|
13
|
+
foreignKey: string;
|
|
14
|
+
references?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface EntityContextDef {
|
|
17
|
+
table: string;
|
|
18
|
+
directory: string;
|
|
19
|
+
slugColumn: string;
|
|
20
|
+
files: Record<string, EntityFileSpec>;
|
|
21
|
+
indexFile?: string;
|
|
22
|
+
/** Custom index render function. If omitted, a default listing is generated. */
|
|
23
|
+
indexRender?: (rows: Row[]) => string;
|
|
24
|
+
protectedFiles?: string[];
|
|
25
|
+
/** When true, this entity's data is never rendered into other entities' context files. */
|
|
26
|
+
protected?: boolean;
|
|
27
|
+
/** Enable at-rest encryption. Requires encryptionKey in Lattice options. */
|
|
28
|
+
encrypted?: boolean | {
|
|
29
|
+
columns: string[];
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export interface EntityFileSpec {
|
|
33
|
+
source: EntitySource;
|
|
34
|
+
render: string | ((rows: Row[]) => string);
|
|
35
|
+
junctionColumns?: string[];
|
|
36
|
+
omitIfEmpty?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export type EntitySource = {
|
|
39
|
+
type: 'self';
|
|
40
|
+
} | {
|
|
41
|
+
type: 'hasMany';
|
|
42
|
+
table: string;
|
|
43
|
+
foreignKey: string;
|
|
44
|
+
filters?: Filter[];
|
|
45
|
+
softDelete?: boolean;
|
|
46
|
+
orderBy?: string;
|
|
47
|
+
limit?: number;
|
|
48
|
+
} | {
|
|
49
|
+
type: 'manyToMany';
|
|
50
|
+
junctionTable: string;
|
|
51
|
+
localKey: string;
|
|
52
|
+
remoteKey: string;
|
|
53
|
+
remoteTable: string;
|
|
54
|
+
filters?: Filter[];
|
|
55
|
+
softDelete?: boolean;
|
|
56
|
+
orderBy?: string;
|
|
57
|
+
limit?: number;
|
|
58
|
+
} | {
|
|
59
|
+
type: 'belongsTo';
|
|
60
|
+
table: string;
|
|
61
|
+
foreignKey: string;
|
|
62
|
+
} | {
|
|
63
|
+
type: 'enriched';
|
|
64
|
+
include: Record<string, EntitySource>;
|
|
65
|
+
} | {
|
|
66
|
+
type: 'custom';
|
|
67
|
+
resolve: (row: Row, adapter: SqliteAdapter) => Row[];
|
|
68
|
+
};
|
|
69
|
+
export interface Filter {
|
|
70
|
+
col: string;
|
|
71
|
+
op: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'in' | 'isNull' | 'isNotNull';
|
|
72
|
+
val?: unknown;
|
|
73
|
+
}
|
|
74
|
+
export interface QueryOptions {
|
|
75
|
+
where?: Record<string, unknown>;
|
|
76
|
+
filters?: Filter[];
|
|
77
|
+
orderBy?: string | Array<{
|
|
78
|
+
col: string;
|
|
79
|
+
dir: 'asc' | 'desc';
|
|
80
|
+
}>;
|
|
81
|
+
orderDir?: 'asc' | 'desc';
|
|
82
|
+
limit?: number;
|
|
83
|
+
offset?: number;
|
|
84
|
+
}
|
|
85
|
+
export type Row = Record<string, unknown>;
|
|
86
|
+
export type PkLookup = string | Record<string, unknown>;
|
|
87
|
+
export interface SqliteAdapter {
|
|
88
|
+
run(sql: string, params?: unknown[]): import('better-sqlite3').RunResult;
|
|
89
|
+
get<T = Row>(sql: string, params?: unknown[]): T | undefined;
|
|
90
|
+
all<T = Row>(sql: string, params?: unknown[]): T[];
|
|
91
|
+
tableInfo(table: string): TableInfoRow[];
|
|
92
|
+
invalidateTableCache(table: string): void;
|
|
93
|
+
}
|
|
94
|
+
export interface TableInfoRow {
|
|
95
|
+
cid: number;
|
|
96
|
+
name: string;
|
|
97
|
+
type: string;
|
|
98
|
+
notnull: number;
|
|
99
|
+
dflt_value: unknown;
|
|
100
|
+
pk: number;
|
|
101
|
+
}
|
|
102
|
+
export interface SeedItem {
|
|
103
|
+
table: string;
|
|
104
|
+
rows: Row[];
|
|
105
|
+
naturalKey?: string | string[];
|
|
106
|
+
junctions?: Array<{
|
|
107
|
+
table: string;
|
|
108
|
+
items: Array<Row>;
|
|
109
|
+
}>;
|
|
110
|
+
softDeleteMissing?: boolean;
|
|
111
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { HookHandler, HookOptions, Unsubscribe } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Priority-ordered event bus for decoupled inter-layer communication.
|
|
4
|
+
* Story 1.1 — handlers run in priority order, errors are isolated,
|
|
5
|
+
* and registrations are unsubscribable.
|
|
6
|
+
*/
|
|
7
|
+
export declare class HookBus {
|
|
8
|
+
private readonly registrations;
|
|
9
|
+
private nextId;
|
|
10
|
+
register(event: string, handler: HookHandler, opts?: HookOptions): Unsubscribe;
|
|
11
|
+
emit(event: string, context: Record<string, unknown>): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Emit an event and collect handler errors instead of swallowing them.
|
|
14
|
+
* Handlers still run in priority order and one handler's error does not
|
|
15
|
+
* block subsequent handlers. Returns the array of errors (empty = success).
|
|
16
|
+
*/
|
|
17
|
+
emitCollectingErrors(event: string, context: Record<string, unknown>): Promise<Error[]>;
|
|
18
|
+
/** Emit synchronously (use only when async is not needed) */
|
|
19
|
+
emitSync(event: string, context: Record<string, unknown>): void;
|
|
20
|
+
hasListeners(event: string): boolean;
|
|
21
|
+
listRegistered(): string[];
|
|
22
|
+
/** Remove all handlers for an event, or all handlers if no event given */
|
|
23
|
+
clear(event?: string): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type HookHandler = (context: Record<string, unknown>) => Promise<void> | void;
|
|
2
|
+
export type Unsubscribe = () => void;
|
|
3
|
+
export interface HookOptions {
|
|
4
|
+
/** 0–100, default 50. Lower = runs first. */
|
|
5
|
+
priority?: number;
|
|
6
|
+
/** Auto-unsubscribe after first invocation. */
|
|
7
|
+
once?: boolean;
|
|
8
|
+
/** Only fire if context matches all filter key/value pairs. */
|
|
9
|
+
filter?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export interface HookRegistration {
|
|
12
|
+
event: string;
|
|
13
|
+
handler: HookHandler;
|
|
14
|
+
priority: number;
|
|
15
|
+
once: boolean;
|
|
16
|
+
filter?: Record<string, unknown>;
|
|
17
|
+
/** Internal auto-increment for stable sort within same priority */
|
|
18
|
+
id: number;
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { LLMProvider } from "./types.js";
|
|
2
|
+
type Importer = (packageName: string) => Promise<unknown>;
|
|
3
|
+
/**
|
|
4
|
+
* Scans nodeModulesPath/@botinabox/{pkg}/package.json for each package in the scope.
|
|
5
|
+
* If pkg.botinabox?.type === 'provider', dynamically imports the package
|
|
6
|
+
* and returns the discovered LLMProvider instances.
|
|
7
|
+
*
|
|
8
|
+
* The optional importer parameter allows injection for testing.
|
|
9
|
+
*/
|
|
10
|
+
export declare function discoverProviders(nodeModulesPath: string, importer?: Importer): Promise<LLMProvider[]>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HookBus } from "../hooks/hook-bus.js";
|
|
2
|
+
import type { DataStore } from "../data/data-store.js";
|
|
3
|
+
import type { ModelInfo } from "./types.js";
|
|
4
|
+
export declare function setupCostTracker(hooks: HookBus, db: DataStore, opts?: {
|
|
5
|
+
modelCatalog?: ModelInfo[];
|
|
6
|
+
}): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default LLM call function — ready-to-use wrapper around the Anthropic SDK.
|
|
3
|
+
*
|
|
4
|
+
* Handles model routing (fast → Haiku, default → Sonnet), message formatting,
|
|
5
|
+
* and response extraction. Apps can use this directly or provide their own.
|
|
6
|
+
*/
|
|
7
|
+
import type { ChatResponderConfig } from '../chat/chat-responder.js';
|
|
8
|
+
export interface DefaultLLMCallConfig {
|
|
9
|
+
/** Fast model ID (for acks, interpretation). Default: claude-haiku-4-5-20251001 */
|
|
10
|
+
fastModel?: string;
|
|
11
|
+
/** Standard model ID (for execution). Default: claude-sonnet-4-20250514 */
|
|
12
|
+
defaultModel?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a default LLM call function using the Anthropic SDK.
|
|
16
|
+
*
|
|
17
|
+
* @param anthropicClient - An initialized Anthropic client instance
|
|
18
|
+
* @param config - Optional model configuration
|
|
19
|
+
*/
|
|
20
|
+
export declare function createDefaultLLMCall(anthropicClient: {
|
|
21
|
+
messages: {
|
|
22
|
+
create: (params: Record<string, unknown>) => Promise<{
|
|
23
|
+
content: Array<{
|
|
24
|
+
type: string;
|
|
25
|
+
text?: string;
|
|
26
|
+
}>;
|
|
27
|
+
model: string;
|
|
28
|
+
stop_reason: string;
|
|
29
|
+
usage: {
|
|
30
|
+
input_tokens: number;
|
|
31
|
+
output_tokens: number;
|
|
32
|
+
};
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
}, config?: DefaultLLMCallConfig): ChatResponderConfig['llmCall'];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ProviderRegistry } from "./provider-registry.js";
|
|
2
|
+
export { ModelRouter } from "./model-router.js";
|
|
3
|
+
export { discoverProviders } from "./auto-discovery.js";
|
|
4
|
+
export type { LLMProvider, ModelInfo, ResolvedModel, ChatParams, ChatResult, ChatMessage, ContentBlock, TokenUsage, ToolDefinition, ToolUse, } from "./types.js";
|
|
5
|
+
export { createDefaultLLMCall } from "./default-llm-call.js";
|
|
6
|
+
export type { DefaultLLMCallConfig } from "./default-llm-call.js";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ModelConfig } from "../../shared/index.js";
|
|
2
|
+
import type { ModelInfo, ResolvedModel } from "./types.js";
|
|
3
|
+
import type { ProviderRegistry } from "./provider-registry.js";
|
|
4
|
+
export declare class ModelRouter {
|
|
5
|
+
private readonly registry;
|
|
6
|
+
private readonly config;
|
|
7
|
+
constructor(registry: ProviderRegistry, config: ModelConfig);
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a model ID or alias to a ResolvedModel.
|
|
10
|
+
* 1. Look up alias in config.aliases (or use as-is)
|
|
11
|
+
* 2. Search all registered providers for a model with that id
|
|
12
|
+
*/
|
|
13
|
+
resolve(modelIdOrAlias: string): ResolvedModel | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Try primary model, then each in config.fallbackChain.
|
|
16
|
+
* Throws if none found.
|
|
17
|
+
*/
|
|
18
|
+
resolveWithFallback(modelIdOrAlias: string): ResolvedModel;
|
|
19
|
+
/**
|
|
20
|
+
* Use config.routing[purpose] ?? config.default, then resolveWithFallback.
|
|
21
|
+
*/
|
|
22
|
+
resolveForPurpose(purpose: string): ResolvedModel;
|
|
23
|
+
/** Returns all models from all registered providers. */
|
|
24
|
+
listAvailable(): ModelInfo[];
|
|
25
|
+
}
|