mirror of
https://github.com/j3ssie/osmedeus.git
synced 2026-08-22 15:42:27 +02:00
- Add LLM executor supporting OpenAI vision, tool calling, embeddings, and structured outputs - Introduce event emitter/receiver workflows with deduplication and filtering (generate_event functions) - Add workflow extends/override system enabling inheritance chains and step merge modes - Update function naming to snake_case across all testdata (fileExists→file_exists, etc.) - Add comprehensive test fixtures for linter, events, CDN, step dependencies, and extends workflows
151 lines
3.9 KiB
Go
151 lines
3.9 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
)
|
|
|
|
// DistributedHooks provides callback functions for routing database writes
|
|
// to Redis queues when running in distributed worker mode.
|
|
// This avoids import cycles between database and distributed packages.
|
|
type DistributedHooks struct {
|
|
// SendRun is called when a Run should be sent to the master via Redis
|
|
SendRun func(ctx context.Context, run *Run) error
|
|
|
|
// SendStepResult is called when a StepResult should be sent to the master via Redis
|
|
SendStepResult func(ctx context.Context, step *StepResult) error
|
|
|
|
// SendEventLog is called when an EventLog should be sent to the master via Redis
|
|
SendEventLog func(ctx context.Context, event *EventLog) error
|
|
|
|
// SendArtifact is called when an Artifact should be sent to the master via Redis
|
|
SendArtifact func(ctx context.Context, artifact *Artifact) error
|
|
|
|
// ShouldUseRedis returns true if writes should go to Redis instead of local DB
|
|
ShouldUseRedis func() bool
|
|
}
|
|
|
|
var (
|
|
distributedHooks *DistributedHooks
|
|
hooksMu sync.RWMutex
|
|
)
|
|
|
|
// RegisterDistributedHooks registers callbacks for distributed mode.
|
|
// Called by the distributed package at worker startup.
|
|
func RegisterDistributedHooks(hooks *DistributedHooks) {
|
|
hooksMu.Lock()
|
|
defer hooksMu.Unlock()
|
|
distributedHooks = hooks
|
|
}
|
|
|
|
// UnregisterDistributedHooks removes the distributed hooks.
|
|
func UnregisterDistributedHooks() {
|
|
hooksMu.Lock()
|
|
defer hooksMu.Unlock()
|
|
distributedHooks = nil
|
|
}
|
|
|
|
// GetDistributedHooks returns the registered hooks (nil if not set).
|
|
func GetDistributedHooks() *DistributedHooks {
|
|
hooksMu.RLock()
|
|
defer hooksMu.RUnlock()
|
|
return distributedHooks
|
|
}
|
|
|
|
// shouldUseDistributedHooks checks if we should route to Redis.
|
|
func shouldUseDistributedHooks() bool {
|
|
hooksMu.RLock()
|
|
hooks := distributedHooks
|
|
hooksMu.RUnlock()
|
|
|
|
if hooks == nil || hooks.ShouldUseRedis == nil {
|
|
return false
|
|
}
|
|
return hooks.ShouldUseRedis()
|
|
}
|
|
|
|
// trySendRunToRedis attempts to send a run to Redis if in distributed worker mode.
|
|
// Returns true if sent to Redis, false if should use local DB.
|
|
func trySendRunToRedis(ctx context.Context, run *Run) bool {
|
|
if !shouldUseDistributedHooks() {
|
|
return false
|
|
}
|
|
|
|
hooksMu.RLock()
|
|
hooks := distributedHooks
|
|
hooksMu.RUnlock()
|
|
|
|
if hooks == nil || hooks.SendRun == nil {
|
|
return false
|
|
}
|
|
|
|
if err := hooks.SendRun(ctx, run); err != nil {
|
|
// Log error but don't fail - fall back to local DB
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// trySendStepResultToRedis attempts to send a step result to Redis if in distributed worker mode.
|
|
// Returns true if sent to Redis, false if should use local DB.
|
|
func trySendStepResultToRedis(ctx context.Context, step *StepResult) bool {
|
|
if !shouldUseDistributedHooks() {
|
|
return false
|
|
}
|
|
|
|
hooksMu.RLock()
|
|
hooks := distributedHooks
|
|
hooksMu.RUnlock()
|
|
|
|
if hooks == nil || hooks.SendStepResult == nil {
|
|
return false
|
|
}
|
|
|
|
if err := hooks.SendStepResult(ctx, step); err != nil {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// trySendEventLogToRedis attempts to send an event log to Redis if in distributed worker mode.
|
|
// Returns true if sent to Redis, false if should use local DB.
|
|
func trySendEventLogToRedis(ctx context.Context, event *EventLog) bool {
|
|
if !shouldUseDistributedHooks() {
|
|
return false
|
|
}
|
|
|
|
hooksMu.RLock()
|
|
hooks := distributedHooks
|
|
hooksMu.RUnlock()
|
|
|
|
if hooks == nil || hooks.SendEventLog == nil {
|
|
return false
|
|
}
|
|
|
|
if err := hooks.SendEventLog(ctx, event); err != nil {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// trySendArtifactToRedis attempts to send an artifact to Redis if in distributed worker mode.
|
|
// Returns true if sent to Redis, false if should use local DB.
|
|
func trySendArtifactToRedis(ctx context.Context, artifact *Artifact) bool {
|
|
if !shouldUseDistributedHooks() {
|
|
return false
|
|
}
|
|
|
|
hooksMu.RLock()
|
|
hooks := distributedHooks
|
|
hooksMu.RUnlock()
|
|
|
|
if hooks == nil || hooks.SendArtifact == nil {
|
|
return false
|
|
}
|
|
|
|
if err := hooks.SendArtifact(ctx, artifact); err != nil {
|
|
return false
|
|
}
|
|
return true
|
|
}
|