This commit is contained in:
+56
-12
@@ -30,14 +30,17 @@ import (
|
||||
"data-terminal-cloud/internal/media"
|
||||
"data-terminal-cloud/internal/memoryindex"
|
||||
"data-terminal-cloud/internal/memorylifecycle"
|
||||
"data-terminal-cloud/internal/memorytool"
|
||||
"data-terminal-cloud/internal/objectstore"
|
||||
"data-terminal-cloud/internal/observability"
|
||||
"data-terminal-cloud/internal/opsaccess"
|
||||
"data-terminal-cloud/internal/opsconfig"
|
||||
"data-terminal-cloud/internal/opsdevice"
|
||||
"data-terminal-cloud/internal/orchestration"
|
||||
"data-terminal-cloud/internal/outbox"
|
||||
"data-terminal-cloud/internal/pagination"
|
||||
"data-terminal-cloud/internal/privacy"
|
||||
"data-terminal-cloud/internal/providermemory"
|
||||
"data-terminal-cloud/internal/ratelimit"
|
||||
"data-terminal-cloud/internal/rtc"
|
||||
"data-terminal-cloud/internal/saas"
|
||||
@@ -75,11 +78,18 @@ func Run(ctx context.Context, serviceName string) error {
|
||||
defer func() { _ = redisClient.Close() }()
|
||||
var exportStore *objectstore.Store
|
||||
var memoryEmbedding embeddingprovider.Provider
|
||||
var providerMemoryClient providermemory.Client
|
||||
if serviceName == "api" || serviceName == "worker" {
|
||||
memoryEmbedding, err = newMemoryEmbeddingProvider(cfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create memory embedding provider: %w", err)
|
||||
}
|
||||
if cfg.ProviderMemoryMode == "managed_http" {
|
||||
providerMemoryClient, err = providermemory.NewHTTPClient(cfg.ProviderMemoryBaseURL, cfg.ProviderMemoryAPIKey, cfg.ProviderMemoryTimeout)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create provider memory client: %w", err)
|
||||
}
|
||||
}
|
||||
exportStore, err = objectstore.New(cfg.ObjectStoreEndpoint, cfg.ObjectStorePublic, cfg.ObjectStoreAccessKey, cfg.ObjectStoreSecretKey, cfg.ObjectStoreBucket, cfg.ObjectStoreRegion, cfg.ObjectStoreSecure, cfg.ObjectStorePublicSecure)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create private export object store: %w", err)
|
||||
@@ -124,6 +134,9 @@ func Run(ctx context.Context, serviceName string) error {
|
||||
var alertService *alerts.Service
|
||||
var diagnosticService *diagnostics.Service
|
||||
var opsAccessService *opsaccess.Service
|
||||
var opsDeviceService *opsdevice.Service
|
||||
var memoryToolService *memorytool.Service
|
||||
var memoryToolSigner *memorytool.TokenSigner
|
||||
if serviceName == "api" || serviceName == "callbacks" {
|
||||
diagnosticService, err = diagnostics.NewService(databasePool, idempotency.NewExecutor(databasePool), audit.NewRepository())
|
||||
if err != nil {
|
||||
@@ -131,12 +144,21 @@ func Run(ctx context.Context, serviceName string) error {
|
||||
}
|
||||
}
|
||||
if serviceName == "api" {
|
||||
memoryToolSigner, err = memorytool.NewTokenSigner([]byte(cfg.MemoryToolSigningSecret))
|
||||
if err != nil {
|
||||
return fmt.Errorf("create memory tool signer: %w", err)
|
||||
}
|
||||
memoryToolService, err = memorytool.NewService(databasePool, memoryEmbedding, audit.NewRepository())
|
||||
if err != nil {
|
||||
return fmt.Errorf("create memory tool service: %w", err)
|
||||
}
|
||||
webEventService = webevents.NewService(databasePool)
|
||||
cursorCodec, cursorErr := pagination.NewCodec([]byte(cfg.CursorSigningSecret))
|
||||
if cursorErr != nil {
|
||||
return fmt.Errorf("create pagination cursor codec: %w", cursorErr)
|
||||
}
|
||||
saasService = saas.NewService(databasePool, audit.NewRepository(), redisClient, cursorCodec)
|
||||
saasService.ConfigureProviderMemory(cfg.ProviderMemoryMode == "managed_http")
|
||||
opsConfigService, err = opsconfig.NewService(databasePool, audit.NewRepository())
|
||||
if err != nil {
|
||||
return fmt.Errorf("create operations configuration service: %w", err)
|
||||
@@ -166,21 +188,22 @@ func Run(ctx context.Context, serviceName string) error {
|
||||
}
|
||||
}
|
||||
deviceIdentityRepository := deviceauth.NewRepository(databasePool)
|
||||
var deviceSecretResolver deviceauth.SecretResolver
|
||||
if cfg.DeviceSecretDirectory != "" {
|
||||
deviceSecretResolver, err = deviceauth.NewDirectorySecretResolver(cfg.DeviceSecretDirectory)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create per-device secret resolver: %w", err)
|
||||
}
|
||||
} else {
|
||||
// The local environment provides one already-bound simulator and one
|
||||
// unbound simulator so the family portal's one-time claim flow can be
|
||||
// exercised without provisioning production device secrets.
|
||||
deviceSecretResolver = deviceauth.StaticSecretResolver{
|
||||
deviceSecretResolver, err := deviceauth.NewDatabaseSecretResolver(databasePool, cfg.DeviceCredentialMasterKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create database device secret resolver: %w", err)
|
||||
}
|
||||
if len(cfg.DeviceLocalSecret) >= 32 {
|
||||
if err := deviceSecretResolver.ImportMissingLegacyCredentials(ctx, map[string][]byte{
|
||||
"local-dev://simulated-terminal-1": []byte(cfg.DeviceLocalSecret),
|
||||
"local-dev://unbound-terminal-2": []byte(cfg.DeviceLocalSecret),
|
||||
}); err != nil {
|
||||
return fmt.Errorf("import legacy device credentials: %w", err)
|
||||
}
|
||||
}
|
||||
opsDeviceService, err = opsdevice.NewService(databasePool, deviceSecretResolver, audit.NewRepository())
|
||||
if err != nil {
|
||||
return fmt.Errorf("create operations device service: %w", err)
|
||||
}
|
||||
deviceVerifier, err = deviceauth.NewVerifier(
|
||||
deviceIdentityRepository,
|
||||
deviceSecretResolver,
|
||||
@@ -259,6 +282,7 @@ func Run(ctx context.Context, serviceName string) error {
|
||||
"tenant": {RatePerSecond: cfg.RateLimitTenantRPS, Burst: cfg.RateLimitTenantBurst},
|
||||
"device": {RatePerSecond: cfg.RateLimitDeviceRPS, Burst: cfg.RateLimitDeviceBurst},
|
||||
"provider_start": {RatePerSecond: cfg.ProviderStartRPS, Burst: cfg.ProviderStartBurst},
|
||||
"memory_tool": {RatePerSecond: cfg.MemoryToolRateRPS, Burst: cfg.MemoryToolRateBurst},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("create rate limiter: %w", err)
|
||||
@@ -313,6 +337,15 @@ func Run(ctx context.Context, serviceName string) error {
|
||||
if processorErr = startProcessor.ConfigureStartProtection(limiter, cfg.ProviderMaxActiveTasks); processorErr != nil {
|
||||
return fmt.Errorf("configure provider start protection: %w", processorErr)
|
||||
}
|
||||
if cfg.MemoryToolBaseURL != "" {
|
||||
workerMemoryToolSigner, signerErr := memorytool.NewTokenSigner([]byte(cfg.MemoryToolSigningSecret))
|
||||
if signerErr != nil {
|
||||
return fmt.Errorf("create worker memory tool signer: %w", signerErr)
|
||||
}
|
||||
if processorErr = startProcessor.ConfigureMemoryTool(workerMemoryToolSigner, cfg.MemoryToolBaseURL, cfg.MemoryToolTokenTTL); processorErr != nil {
|
||||
return fmt.Errorf("configure provider memory tool: %w", processorErr)
|
||||
}
|
||||
}
|
||||
outboxWorker.Register("conversation.agent_start_requested", startProcessor.Handle)
|
||||
outboxWorker.Register("conversation.agent_start_reconcile_requested", startProcessor.Handle)
|
||||
stopProcessor, processorErr := orchestration.NewStopProcessor(databasePool, providerClient, providerHealth)
|
||||
@@ -347,6 +380,14 @@ func Run(ctx context.Context, serviceName string) error {
|
||||
return fmt.Errorf("create memory index processor: %w", processorErr)
|
||||
}
|
||||
outboxWorker.Register("memory.index_requested", memoryIndexProcessor.Handle)
|
||||
if providerMemoryClient != nil {
|
||||
providerMemoryProcessor, providerMemoryErr := providermemory.NewProcessor(databasePool, providerMemoryClient)
|
||||
if providerMemoryErr != nil {
|
||||
return fmt.Errorf("create provider memory processor: %w", providerMemoryErr)
|
||||
}
|
||||
outboxWorker.Register("memory.provider_sync_requested", providerMemoryProcessor.HandleSync)
|
||||
outboxWorker.Register("memory.provider_delete_requested", providerMemoryProcessor.HandleDelete)
|
||||
}
|
||||
memoryDeleteProcessor, processorErr := memorylifecycle.NewDeleteProcessor(databasePool)
|
||||
if processorErr != nil {
|
||||
return fmt.Errorf("create memory delete processor: %w", processorErr)
|
||||
@@ -357,7 +398,7 @@ func Run(ctx context.Context, serviceName string) error {
|
||||
return fmt.Errorf("create privacy access processor: %w", processorErr)
|
||||
}
|
||||
outboxWorker.Register("privacy.access_requested", privacyAccessProcessor.Handle)
|
||||
privacyDeleteProcessor, processorErr := privacy.NewDeleteProcessor(databasePool, redisClient, exportStore)
|
||||
privacyDeleteProcessor, processorErr := privacy.NewDeleteProcessor(databasePool, redisClient, exportStore, providerMemoryClient)
|
||||
if processorErr != nil {
|
||||
return fmt.Errorf("create privacy delete processor: %w", processorErr)
|
||||
}
|
||||
@@ -434,6 +475,7 @@ func Run(ctx context.Context, serviceName string) error {
|
||||
AlertService: alertService,
|
||||
DiagnosticService: diagnosticService,
|
||||
OpsAccessService: opsAccessService,
|
||||
OpsDeviceService: opsDeviceService,
|
||||
ConversationCreator: conversationCreator,
|
||||
ConversationActivator: conversationCreator,
|
||||
DeviceConversationStateReader: conversationCreator,
|
||||
@@ -446,6 +488,8 @@ func Run(ctx context.Context, serviceName string) error {
|
||||
PlatformHealthCallbackSecret: []byte(cfg.PlatformHealthSecret),
|
||||
PlatformHealthCallbackSkew: cfg.PlatformHealthSkew,
|
||||
PlatformHealthProcessor: diagnosticService,
|
||||
MemoryToolService: memoryToolService,
|
||||
MemoryToolSigner: memoryToolSigner,
|
||||
})
|
||||
server := &http.Server{
|
||||
Addr: cfg.HTTPAddr,
|
||||
|
||||
Reference in New Issue
Block a user