Add public run API with injectable LLM

This commit is contained in:
2026-07-04 14:21:37 +00:00
parent 14a7e7e04c
commit 4ac2038331
6 changed files with 538 additions and 27 deletions

View File

@@ -21,7 +21,19 @@ import (
// ErrInvalidConfig indicates invalid public engine configuration.
var ErrInvalidConfig = errors.New("invalid engine configuration")
// Engine prepares Scriptorium prompt requests.
var (
ErrInvalidRequest = errors.New("invalid run request")
ErrPromptNotFound = errors.New("prompt not found")
ErrProfileNotFound = errors.New("profile not found")
ErrPromptLoad = errors.New("failed to load prompt definition")
ErrProfileLoad = errors.New("failed to load execution profile")
ErrArtifactLoad = errors.New("failed to load artifact")
ErrPromptRender = errors.New("failed to render prompt")
ErrLLMGenerate = errors.New("failed to generate output")
ErrValidation = errors.New("failed to validate output")
)
// Engine prepares and runs Scriptorium prompt requests.
type Engine struct {
runner *usecase.Runner
}
@@ -38,7 +50,20 @@ type Config struct {
// Option customizes engine construction.
type Option func(*engineOptions) error
type engineOptions struct{}
type engineOptions struct {
llmClient llm.Client
}
// WithLLMClient injects a custom LLM client for execution.
func WithLLMClient(client LLMClient) Option {
return func(options *engineOptions) error {
if client == nil {
return ErrInvalidConfig
}
options.llmClient = publicLLMClientAdapter{client: client}
return nil
}
}
// NewEngine constructs an Engine using the same default internal components as
// the CLI and HTTP adapters.
@@ -65,12 +90,16 @@ func NewEngine(cfg Config, opts ...Option) (*Engine, error) {
schemaDir = defaults.SchemaDirDefault
}
llmClient, err := llm.NewOpenAICompatibleClient(llm.OpenAICompatibleConfig{
Timeout: cfg.Timeout,
HTTPClient: cfg.HTTPClient,
})
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrInvalidConfig, err)
llmClient := options.llmClient
if llmClient == nil {
var err error
llmClient, err = llm.NewOpenAICompatibleClient(llm.OpenAICompatibleConfig{
Timeout: cfg.Timeout,
HTTPClient: cfg.HTTPClient,
})
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrInvalidConfig, err)
}
}
return &Engine{
@@ -93,7 +122,20 @@ func (e *Engine) Prepare(ctx context.Context, req RunRequest) (*PreparedRun, err
prepared, err := e.runner.Prepare(ctx, toDomainRunRequest(req))
if err != nil {
return nil, err
return nil, mapPublicError(err)
}
return fromDomainPreparedRun(prepared), nil
}
// Run executes a prompt request and returns the generated artifact and metadata.
func (e *Engine) Run(ctx context.Context, req RunRequest) (*RunResult, error) {
if e == nil || e.runner == nil {
return nil, fmt.Errorf("%w: engine is nil", ErrInvalidConfig)
}
result, err := e.runner.Run(ctx, toDomainRunRequest(req))
if err != nil {
return nil, mapPublicError(err)
}
return fromDomainRunResult(result), nil
}