feat: Add intelligent auto-router and enhanced integrations
- Add intelligent-router.sh hook for automatic agent routing - Add AUTO-TRIGGER-SUMMARY.md documentation - Add FINAL-INTEGRATION-SUMMARY.md documentation - Complete Prometheus integration (6 commands + 4 tools) - Complete Dexto integration (12 commands + 5 tools) - Enhanced Ralph with access to all agents - Fix /clawd command (removed disable-model-invocation) - Update hooks.json to v5 with intelligent routing - 291 total skills now available - All 21 commands with automatic routing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
212
dexto/packages/core/src/image/define-image.ts
Normal file
212
dexto/packages/core/src/image/define-image.ts
Normal file
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* Image definition helper
|
||||
*
|
||||
* Provides type-safe API for defining base images.
|
||||
*/
|
||||
|
||||
import type { ImageDefinition } from './types.js';
|
||||
|
||||
/**
|
||||
* Define a Dexto base image.
|
||||
*
|
||||
* This function provides type checking and validation for image definitions.
|
||||
* Use this in your dexto.image.ts file.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // dexto.image.ts
|
||||
* import { defineImage } from '@dexto/core';
|
||||
* import { localBlobProvider } from './providers/blob.js';
|
||||
*
|
||||
* export default defineImage({
|
||||
* name: 'local',
|
||||
* version: '1.0.0',
|
||||
* description: 'Local development base image',
|
||||
* target: 'local-development',
|
||||
*
|
||||
* providers: {
|
||||
* blobStore: {
|
||||
* providers: [localBlobProvider],
|
||||
* },
|
||||
* },
|
||||
*
|
||||
* defaults: {
|
||||
* storage: {
|
||||
* blob: { type: 'local', storePath: './data/blobs' },
|
||||
* },
|
||||
* },
|
||||
*
|
||||
* constraints: ['filesystem-required', 'offline-capable'],
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param definition - Image definition object
|
||||
* @returns The same definition (for type inference)
|
||||
*/
|
||||
export function defineImage(definition: ImageDefinition): ImageDefinition {
|
||||
// Validation
|
||||
if (!definition.name) {
|
||||
throw new Error('Image definition must have a name');
|
||||
}
|
||||
if (!definition.version) {
|
||||
throw new Error('Image definition must have a version');
|
||||
}
|
||||
if (!definition.description) {
|
||||
throw new Error('Image definition must have a description');
|
||||
}
|
||||
|
||||
// Validate provider categories have at least one of: providers or register
|
||||
for (const [category, config] of Object.entries(definition.providers)) {
|
||||
if (!config) continue;
|
||||
if (!config.providers && !config.register) {
|
||||
throw new Error(
|
||||
`Provider category '${category}' must have either 'providers' array or 'register' function`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create a provider category configuration.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { defineProviderCategory } from '@dexto/core';
|
||||
*
|
||||
* const blobStore = defineProviderCategory({
|
||||
* providers: [localBlobProvider, s3BlobProvider],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function defineProviderCategory(config: {
|
||||
providers?: any[];
|
||||
register?: () => void | Promise<void>;
|
||||
}) {
|
||||
if (!config.providers && !config.register) {
|
||||
throw new Error('Provider category must have either providers or register function');
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an image definition.
|
||||
* Throws if the definition is invalid.
|
||||
*
|
||||
* Used by bundler to validate images before building.
|
||||
*/
|
||||
export function validateImageDefinition(definition: ImageDefinition): void {
|
||||
// Basic validation
|
||||
if (!definition.name || typeof definition.name !== 'string') {
|
||||
throw new Error('Image name must be a non-empty string');
|
||||
}
|
||||
|
||||
if (!definition.version || typeof definition.version !== 'string') {
|
||||
throw new Error('Image version must be a non-empty string');
|
||||
}
|
||||
|
||||
if (!definition.description || typeof definition.description !== 'string') {
|
||||
throw new Error('Image description must be a non-empty string');
|
||||
}
|
||||
|
||||
// Validate version format (basic semver check)
|
||||
const versionRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/;
|
||||
if (!versionRegex.test(definition.version)) {
|
||||
throw new Error(
|
||||
`Image version '${definition.version}' is not valid semver. Expected format: x.y.z`
|
||||
);
|
||||
}
|
||||
|
||||
// Validate target if provided
|
||||
const validTargets = [
|
||||
'local-development',
|
||||
'cloud-production',
|
||||
'edge-serverless',
|
||||
'embedded-iot',
|
||||
'enterprise',
|
||||
'custom',
|
||||
];
|
||||
if (definition.target && !validTargets.includes(definition.target)) {
|
||||
throw new Error(
|
||||
`Invalid target '${definition.target}'. Valid targets: ${validTargets.join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
// Validate provider categories
|
||||
// Allow empty providers if extending a base image (providers inherited from base)
|
||||
const hasProviders =
|
||||
definition.providers &&
|
||||
Object.values(definition.providers).some((config) => config !== undefined);
|
||||
|
||||
if (!hasProviders && !definition.extends) {
|
||||
throw new Error(
|
||||
'Image must either define at least one provider category or extend a base image'
|
||||
);
|
||||
}
|
||||
|
||||
for (const [category, config] of Object.entries(definition.providers)) {
|
||||
if (!config) continue;
|
||||
|
||||
if (!config.providers && !config.register) {
|
||||
throw new Error(
|
||||
`Provider category '${category}' must have either 'providers' array or 'register' function`
|
||||
);
|
||||
}
|
||||
|
||||
if (config.providers && !Array.isArray(config.providers)) {
|
||||
throw new Error(`Provider category '${category}' providers must be an array`);
|
||||
}
|
||||
|
||||
if (config.register && typeof config.register !== 'function') {
|
||||
throw new Error(`Provider category '${category}' register must be a function`);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate constraints if provided
|
||||
const validConstraints = [
|
||||
'filesystem-required',
|
||||
'network-required',
|
||||
'offline-capable',
|
||||
'serverless-compatible',
|
||||
'cold-start-optimized',
|
||||
'low-memory',
|
||||
'edge-compatible',
|
||||
'browser-compatible',
|
||||
];
|
||||
|
||||
if (definition.constraints) {
|
||||
if (!Array.isArray(definition.constraints)) {
|
||||
throw new Error('Image constraints must be an array');
|
||||
}
|
||||
|
||||
for (const constraint of definition.constraints) {
|
||||
if (!validConstraints.includes(constraint)) {
|
||||
throw new Error(
|
||||
`Invalid constraint '${constraint}'. Valid constraints: ${validConstraints.join(', ')}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate utils if provided
|
||||
if (definition.utils) {
|
||||
for (const [name, path] of Object.entries(definition.utils)) {
|
||||
if (typeof path !== 'string') {
|
||||
throw new Error(`Utility '${name}' path must be a string`);
|
||||
}
|
||||
if (!path.startsWith('./')) {
|
||||
throw new Error(
|
||||
`Utility '${name}' path must be relative (start with './'). Got: ${path}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate extends if provided
|
||||
if (definition.extends) {
|
||||
if (typeof definition.extends !== 'string') {
|
||||
throw new Error('Image extends must be a string (parent image name)');
|
||||
}
|
||||
}
|
||||
}
|
||||
68
dexto/packages/core/src/image/index.ts
Normal file
68
dexto/packages/core/src/image/index.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Base Image Infrastructure
|
||||
*
|
||||
* Provides types and helpers for defining Dexto base images.
|
||||
* Base images are pre-configured backend surfaces that bundle providers,
|
||||
* utilities, and defaults for specific deployment targets.
|
||||
*
|
||||
* @example Creating a base image
|
||||
* ```typescript
|
||||
* // dexto.image.ts
|
||||
* import { defineImage } from '@dexto/core';
|
||||
*
|
||||
* export default defineImage({
|
||||
* name: 'local',
|
||||
* version: '1.0.0',
|
||||
* description: 'Local development base image',
|
||||
* target: 'local-development',
|
||||
*
|
||||
* providers: {
|
||||
* blobStore: {
|
||||
* providers: [localBlobProvider],
|
||||
* },
|
||||
* database: {
|
||||
* register: async () => {
|
||||
* const { sqliteProvider } = await import('./providers/database.js');
|
||||
* databaseRegistry.register(sqliteProvider);
|
||||
* },
|
||||
* },
|
||||
* },
|
||||
*
|
||||
* defaults: {
|
||||
* storage: {
|
||||
* blob: { type: 'local', storePath: './data/blobs' },
|
||||
* database: { type: 'sqlite', path: './data/agent.db' },
|
||||
* },
|
||||
* },
|
||||
*
|
||||
* constraints: ['filesystem-required', 'offline-capable'],
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example Using a base image
|
||||
* ```typescript
|
||||
* // my-app/src/index.ts
|
||||
* import { createAgent, enrichConfigForLocal } from '@dexto/image-local';
|
||||
*
|
||||
* const config = enrichConfigForLocal(rawConfig);
|
||||
* const agent = createAgent(config); // Providers already registered!
|
||||
* ```
|
||||
*/
|
||||
|
||||
// Core types
|
||||
export type {
|
||||
ImageProvider,
|
||||
ProviderMetadata,
|
||||
ProviderRegistrationFn,
|
||||
ProviderCategoryConfig,
|
||||
ImageDefinition,
|
||||
ImageTarget,
|
||||
ImageConstraint,
|
||||
ImageDefaults,
|
||||
ImageMetadata,
|
||||
ImageBuildResult,
|
||||
ImageBuildOptions,
|
||||
} from './types.js';
|
||||
|
||||
// Definition helpers
|
||||
export { defineImage, defineProviderCategory, validateImageDefinition } from './define-image.js';
|
||||
278
dexto/packages/core/src/image/types.ts
Normal file
278
dexto/packages/core/src/image/types.ts
Normal file
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* Dexto Base Image Definition
|
||||
*
|
||||
* Base images are pre-configured backend surfaces that bundle providers,
|
||||
* utilities, and defaults for specific deployment targets.
|
||||
*
|
||||
* Like Alpine Linux or Ubuntu, but for AI agents.
|
||||
*/
|
||||
|
||||
import type { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Generic provider interface that all provider types should extend.
|
||||
* Provides common structure for type-safe provider registration.
|
||||
*
|
||||
* Note: This is a simplified interface for image definitions.
|
||||
* Actual provider implementations should use the specific provider
|
||||
* interfaces from their respective modules (e.g., BlobStoreProvider).
|
||||
*/
|
||||
export interface ImageProvider<TType extends string = string> {
|
||||
/** Unique type identifier for this provider (e.g., 'sqlite', 'local', 's3') */
|
||||
type: TType;
|
||||
/** Zod schema for validating provider configuration */
|
||||
configSchema: z.ZodType<any>;
|
||||
/** Factory function to create provider instance */
|
||||
create: (config: any, deps: any) => any;
|
||||
/** Optional metadata about the provider */
|
||||
metadata?: ProviderMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata about a provider's characteristics and requirements
|
||||
*/
|
||||
export interface ProviderMetadata {
|
||||
/** Human-readable display name */
|
||||
displayName?: string;
|
||||
/** Brief description of what this provider does */
|
||||
description?: string;
|
||||
/** Whether this provider requires network connectivity */
|
||||
requiresNetwork?: boolean;
|
||||
/** Whether this provider requires filesystem access */
|
||||
requiresFilesystem?: boolean;
|
||||
/** Persistence level of storage providers */
|
||||
persistenceLevel?: 'ephemeral' | 'persistent';
|
||||
/** Platforms this provider is compatible with */
|
||||
platforms?: ('node' | 'browser' | 'edge' | 'worker')[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Registry function that registers providers on module initialization.
|
||||
* Called automatically when the image is imported.
|
||||
*/
|
||||
export type ProviderRegistrationFn = () => void | Promise<void>;
|
||||
|
||||
/**
|
||||
* Configuration for a single provider category in an image.
|
||||
* Supports both direct provider objects and registration functions.
|
||||
*/
|
||||
export interface ProviderCategoryConfig {
|
||||
/** Direct provider objects to register */
|
||||
providers?: ImageProvider[];
|
||||
/** Registration function for complex initialization */
|
||||
register?: ProviderRegistrationFn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete image definition structure.
|
||||
* This is what dexto.image.ts exports.
|
||||
*/
|
||||
export interface ImageDefinition {
|
||||
/** Unique name for this image (e.g., 'local', 'cloud', 'edge') */
|
||||
name: string;
|
||||
/** Semantic version of this image */
|
||||
version: string;
|
||||
/** Brief description of this image's purpose and target environment */
|
||||
description: string;
|
||||
/** Target deployment environment (for documentation and validation) */
|
||||
target?: ImageTarget;
|
||||
|
||||
/**
|
||||
* Provider categories to register.
|
||||
* Each category can include direct providers or a registration function.
|
||||
*/
|
||||
providers: {
|
||||
/** Blob storage providers (e.g., local filesystem, S3, R2) */
|
||||
blobStore?: ProviderCategoryConfig;
|
||||
/** Database providers (e.g., SQLite, PostgreSQL, D1) */
|
||||
database?: ProviderCategoryConfig;
|
||||
/** Cache providers (e.g., in-memory, Redis, KV) */
|
||||
cache?: ProviderCategoryConfig;
|
||||
/** Custom tool providers (e.g., datetime helpers, API integrations) */
|
||||
customTools?: ProviderCategoryConfig;
|
||||
/** Plugin providers (e.g., audit logging, content filtering) */
|
||||
plugins?: ProviderCategoryConfig;
|
||||
/** Compression strategy providers (e.g., sliding window, summarization) */
|
||||
compression?: ProviderCategoryConfig;
|
||||
};
|
||||
|
||||
/**
|
||||
* Default configuration values.
|
||||
* Used when agent config doesn't specify values.
|
||||
* Merged with agent config during agent creation.
|
||||
*/
|
||||
defaults?: ImageDefaults;
|
||||
|
||||
/**
|
||||
* Runtime constraints this image requires.
|
||||
* Used for validation and error messages.
|
||||
*/
|
||||
constraints?: ImageConstraint[];
|
||||
|
||||
/**
|
||||
* Utilities exported by this image.
|
||||
* Maps utility name to file path (relative to image root).
|
||||
*
|
||||
* Example:
|
||||
* {
|
||||
* configEnrichment: './utils/config.js',
|
||||
* lifecycle: './utils/lifecycle.js'
|
||||
* }
|
||||
*/
|
||||
utils?: Record<string, string>;
|
||||
|
||||
/**
|
||||
* Selective named exports from packages.
|
||||
* Allows re-exporting specific types and values from dependencies.
|
||||
*
|
||||
* Example:
|
||||
* {
|
||||
* '@dexto/core': ['logger', 'createAgentCard', 'type DextoAgent'],
|
||||
* '@dexto/utils': ['formatDate', 'parseConfig']
|
||||
* }
|
||||
*/
|
||||
exports?: Record<string, string[]>;
|
||||
|
||||
/**
|
||||
* Parent image to extend (for image inheritance).
|
||||
* Optional: enables creating specialized images from base images.
|
||||
*/
|
||||
extends?: string;
|
||||
|
||||
/**
|
||||
* Bundled plugin paths.
|
||||
* Absolute paths to plugin directories containing .dexto-plugin or .claude-plugin manifests.
|
||||
* These plugins are automatically discovered alongside user/project plugins.
|
||||
*
|
||||
* Example:
|
||||
* ```typescript
|
||||
* import { PLUGIN_PATH as planToolsPluginPath } from '@dexto/tools-plan';
|
||||
*
|
||||
* bundledPlugins: [planToolsPluginPath]
|
||||
* ```
|
||||
*/
|
||||
bundledPlugins?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Target deployment environments for images.
|
||||
* Helps users choose the right image for their use case.
|
||||
*/
|
||||
export type ImageTarget =
|
||||
| 'local-development'
|
||||
| 'cloud-production'
|
||||
| 'edge-serverless'
|
||||
| 'embedded-iot'
|
||||
| 'enterprise'
|
||||
| 'custom';
|
||||
|
||||
/**
|
||||
* Runtime constraints that an image requires.
|
||||
* Used for validation and helpful error messages.
|
||||
*/
|
||||
export type ImageConstraint =
|
||||
| 'filesystem-required'
|
||||
| 'network-required'
|
||||
| 'offline-capable'
|
||||
| 'serverless-compatible'
|
||||
| 'cold-start-optimized'
|
||||
| 'low-memory'
|
||||
| 'edge-compatible'
|
||||
| 'browser-compatible';
|
||||
|
||||
/**
|
||||
* Default configuration values provided by an image.
|
||||
* These are used when agent config doesn't specify values.
|
||||
*/
|
||||
export interface ImageDefaults {
|
||||
/** Default storage configuration */
|
||||
storage?: {
|
||||
database?: {
|
||||
type: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
blob?: {
|
||||
type: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
cache?: {
|
||||
type: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
/** Default logging configuration */
|
||||
logging?: {
|
||||
level?: 'debug' | 'info' | 'warn' | 'error';
|
||||
fileLogging?: boolean;
|
||||
[key: string]: any;
|
||||
};
|
||||
/** Default LLM configuration */
|
||||
llm?: {
|
||||
provider?: string;
|
||||
model?: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
/** Default tool configuration */
|
||||
tools?: {
|
||||
internalTools?: string[];
|
||||
[key: string]: any;
|
||||
};
|
||||
/** Other default values */
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata about a built image (generated by bundler).
|
||||
* Included in the compiled image output.
|
||||
*/
|
||||
export interface ImageMetadata {
|
||||
/** Image name */
|
||||
name: string;
|
||||
/** Image version */
|
||||
version: string;
|
||||
/** Description */
|
||||
description: string;
|
||||
/** Target environment */
|
||||
target?: ImageTarget;
|
||||
/** Runtime constraints */
|
||||
constraints: ImageConstraint[];
|
||||
/** Build timestamp */
|
||||
builtAt: string;
|
||||
/** Core version this image was built for */
|
||||
coreVersion: string;
|
||||
/** Base image this extends (if any) */
|
||||
extends?: string;
|
||||
/** Bundled plugin paths (absolute paths to plugin directories) */
|
||||
bundledPlugins?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of building an image.
|
||||
* Contains the generated code and metadata.
|
||||
*/
|
||||
export interface ImageBuildResult {
|
||||
/** Generated JavaScript code for the image entry point */
|
||||
code: string;
|
||||
/** Generated TypeScript definitions */
|
||||
types: string;
|
||||
/** Image metadata */
|
||||
metadata: ImageMetadata;
|
||||
/** Warnings encountered during build */
|
||||
warnings?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for building an image.
|
||||
*/
|
||||
export interface ImageBuildOptions {
|
||||
/** Path to dexto.image.ts file */
|
||||
imagePath: string;
|
||||
/** Output directory for built image */
|
||||
outDir: string;
|
||||
/** Whether to generate source maps */
|
||||
sourcemap?: boolean;
|
||||
/** Whether to minify output */
|
||||
minify?: boolean;
|
||||
/** Additional validation rules */
|
||||
strict?: boolean;
|
||||
}
|
||||
Reference in New Issue
Block a user