Files
nanobot-ts/src/config/types.ts
Joe Fleming b6df31fcbf fix: require a model, default to empty value during onboarding
and add a WORKSPACE_PATH constant to make tracking that path easier
2026-03-13 20:42:05 -06:00

127 lines
4.7 KiB
TypeScript

import { z } from 'zod';
import { WORKSPACE_PATH } from './constants.ts'
// ---------------------------------------------------------------------------
// Mattermost
// ---------------------------------------------------------------------------
export const MattermostDmConfigSchema = z.object({
enabled: z.boolean().default(true),
allowFrom: z.array(z.string()).default([]),
});
export type MattermostDmConfig = z.infer<typeof MattermostDmConfigSchema>;
export const MattermostConfigSchema = z.object({
serverUrl: z.string(),
token: z.string(),
scheme: z.enum(['https', 'http']).default('https'),
port: z.number().int().default(443),
basePath: z.string().default(''),
allowFrom: z.array(z.string()).default([]),
groupPolicy: z.enum(['open', 'mention', 'allowlist']).default('mention'),
groupAllowFrom: z.array(z.string()).default([]),
dm: MattermostDmConfigSchema.default(() => ({ enabled: true, allowFrom: [] })),
replyInThread: z.boolean().default(true),
});
export type MattermostConfig = z.infer<typeof MattermostConfigSchema>;
// ---------------------------------------------------------------------------
// Channels
// ---------------------------------------------------------------------------
export const ChannelsConfigSchema = z.object({
mattermost: MattermostConfigSchema.optional(),
sendProgress: z.boolean().default(true),
sendToolHints: z.boolean().default(true),
});
export type ChannelsConfig = z.infer<typeof ChannelsConfigSchema>;
// ---------------------------------------------------------------------------
// Agent
// ---------------------------------------------------------------------------
export const AgentConfigSchema = z.object({
model: z.string().default('anthropic/claude-sonnet-4-5'),
workspacePath: z.string().default(WORKSPACE_PATH),
maxTokens: z.number().int().default(4096),
contextWindowTokens: z.number().int().default(65536),
temperature: z.number().default(0.7),
maxToolIterations: z.number().int().default(40),
});
export type AgentConfig = z.infer<typeof AgentConfigSchema>;
// ---------------------------------------------------------------------------
// Providers
// ---------------------------------------------------------------------------
export const ProviderConfigSchema = z.object({
apiKey: z.string().optional(),
apiBase: z.string().optional(),
});
export type ProviderConfig = z.infer<typeof ProviderConfigSchema>;
export const ProvidersConfigSchema = z.object({
anthropic: ProviderConfigSchema.optional(),
openai: ProviderConfigSchema.optional(),
google: ProviderConfigSchema.optional(),
openrouter: ProviderConfigSchema.optional(),
ollama: ProviderConfigSchema.optional(),
});
export type ProvidersConfig = z.infer<typeof ProvidersConfigSchema>;
// ---------------------------------------------------------------------------
// Tools
// ---------------------------------------------------------------------------
export const ExecToolConfigSchema = z.object({
timeout: z.number().int().default(120),
pathAppend: z.string().optional(),
denyPatterns: z.array(z.string()).default([]),
restrictToWorkspace: z.boolean().default(false),
});
export type ExecToolConfig = z.infer<typeof ExecToolConfigSchema>;
export const WebToolConfigSchema = z.object({
braveApiKey: z.string().optional(),
proxy: z.string().optional(),
});
export type WebToolConfig = z.infer<typeof WebToolConfigSchema>;
export const ToolsConfigSchema = z.object({
exec: ExecToolConfigSchema.default(() => ({
timeout: 120,
denyPatterns: [],
restrictToWorkspace: false,
})),
web: WebToolConfigSchema.default(() => ({})),
restrictToWorkspace: z.boolean().default(false),
});
export type ToolsConfig = z.infer<typeof ToolsConfigSchema>;
// ---------------------------------------------------------------------------
// Heartbeat
// ---------------------------------------------------------------------------
export const HeartbeatConfigSchema = z.object({
enabled: z.boolean().default(false),
intervalMinutes: z.number().int().default(30),
});
export type HeartbeatConfig = z.infer<typeof HeartbeatConfigSchema>;
// ---------------------------------------------------------------------------
// Root config
// ---------------------------------------------------------------------------
export const ConfigSchema = z.object({
providers: ProvidersConfigSchema.default(() => ({})),
agent: AgentConfigSchema,
heartbeat: HeartbeatConfigSchema.default(() => ({ enabled: false, intervalMinutes: 30 })),
channels: ChannelsConfigSchema.default(() => ({ sendProgress: true, sendToolHints: true })),
tools: ToolsConfigSchema.default(() => ({
exec: { timeout: 120, denyPatterns: [], restrictToWorkspace: false },
web: {},
restrictToWorkspace: false,
})),
});
export type Config = z.infer<typeof ConfigSchema>;