chore: checkpoint 第一版
ci / verify (push) Canceled after 0s

This commit is contained in:
Codex Local
2026-09-06 17:04:11 +08:00
parent a8cdec98d1
commit 0c2151ace9
659 changed files with 185855 additions and 554 deletions
+90 -35
View File
@@ -20,10 +20,12 @@ import (
"data-terminal-cloud/internal/dataexport"
"data-terminal-cloud/internal/device"
"data-terminal-cloud/internal/deviceauth"
"data-terminal-cloud/internal/devicereset"
"data-terminal-cloud/internal/diagnostics"
"data-terminal-cloud/internal/embeddingprovider"
"data-terminal-cloud/internal/externalprobe"
"data-terminal-cloud/internal/extraction"
"data-terminal-cloud/internal/hardwareprovision"
"data-terminal-cloud/internal/health"
"data-terminal-cloud/internal/httpapi"
"data-terminal-cloud/internal/idempotency"
@@ -46,6 +48,7 @@ import (
"data-terminal-cloud/internal/rtc"
"data-terminal-cloud/internal/saas"
"data-terminal-cloud/internal/sharing"
"data-terminal-cloud/internal/vikingmemory"
"data-terminal-cloud/internal/voiceprovider"
"data-terminal-cloud/internal/webevents"
@@ -80,7 +83,15 @@ func Run(ctx context.Context, serviceName string) error {
var exportStore *objectstore.Store
var memoryEmbedding embeddingprovider.Provider
var providerMemoryClient providermemory.Client
var vikingMemory *vikingmemory.Service
if serviceName == "api" || serviceName == "worker" {
if cfg.VikingResourceID != "" {
client, vikingErr := vikingmemory.NewClient(vikingmemory.Options{ResourceID: cfg.VikingResourceID, APIKey: cfg.VikingAPIKey, EventType: cfg.VikingEventType, ProfileType: cfg.VikingProfileType, Timeout: 8 * time.Second})
if vikingErr != nil {
return fmt.Errorf("configure Viking memory: %w", vikingErr)
}
vikingMemory = vikingmemory.NewService(databasePool, client)
}
memoryEmbedding, err = newMemoryEmbeddingProvider(cfg)
if err != nil {
return fmt.Errorf("create memory embedding provider: %w", err)
@@ -140,6 +151,8 @@ func Run(ctx context.Context, serviceName string) error {
var memoryToolSigner *memorytool.TokenSigner
var contentModelService *contentmodel.Service
var contentModelRegistry *contentmodel.Registry
var hardwareProvisioningService *hardwareprovision.Service
var deviceFactoryResetService *devicereset.Service
if serviceName == "api" || serviceName == "worker" {
var fallback extraction.Generator = extraction.DeterministicGenerator{}
if cfg.ContentGenerator == "ark" {
@@ -233,6 +246,21 @@ func Run(ctx context.Context, serviceName string) error {
if err != nil {
return fmt.Errorf("create device verifier: %w", err)
}
hardwareProvisioningService, err = hardwareprovision.NewService(databasePool, audit.NewRepository(), hardwareprovision.Options{
Enabled: cfg.VolcHardwareProvisioningEnabled, InstanceID: cfg.VolcHardwareInstanceID,
ProductKey: cfg.VolcHardwareProductKey, BotID: cfg.VolcHardwareAgentBotID,
Transport: cfg.VolcHardwareTransport, MinimumSDKVersion: cfg.VolcHardwareMinimumSDKVersion,
ProductSecret: cfg.VolcHardwareProductSecret,
CredentialMasterKey: cfg.VolcHardwareDeviceCredentialMasterKey, RegisterURL: cfg.VolcHardwareRegisterURL,
RegisterTimeout: cfg.VolcHardwareRegisterTimeout, DeviceNamePrefix: cfg.VolcHardwareDeviceNamePrefix,
})
if err != nil {
return fmt.Errorf("create hardware provider provisioning service: %w", err)
}
deviceFactoryResetService, err = devicereset.NewService(databasePool, idempotency.NewExecutor(databasePool), audit.NewRepository())
if err != nil {
return fmt.Errorf("create device factory reset service: %w", err)
}
deviceRepository = device.NewRepository(databasePool)
deviceTelemetryService, err = device.NewTelemetryService(databasePool, idempotency.NewExecutor(databasePool))
if err != nil {
@@ -257,6 +285,8 @@ func Run(ctx context.Context, serviceName string) error {
orchestration.ServiceOptions{
RTCAppID: cfg.RTCAppID, VoiceProvider: cfg.VoiceProvider, EngineMode: "s2s_hybrid", AllocationTTL: cfg.AllocationTTL,
TokenTTL: cfg.RTCTokenTTL, HeartbeatInterval: cfg.HeartbeatInterval, RequirePublishedRouting: cfg.Environment == config.EnvironmentProd,
HardwareBotID: cfg.VolcHardwareAgentBotID, HardwareTransport: cfg.VolcHardwareTransport,
SubtitleCallbackURL: cfg.SubtitleCallbackURL, SubtitleCallbackSecret: []byte(cfg.SubtitleCallbackSecret), SubtitlePrimary: cfg.SubtitlePrimary,
},
)
if err != nil {
@@ -265,6 +295,13 @@ func Run(ctx context.Context, serviceName string) error {
if err = conversationCreator.ConfigureMemoryEmbedding(databasePool, memoryEmbedding); err != nil {
return fmt.Errorf("configure conversation memory embedding: %w", err)
}
conversationCreator.ConfigureVikingMemory(vikingMemory)
memoryToolService.ConfigureVikingMemory(vikingMemory)
if cfg.MemoryToolBaseURL != "" {
if err = conversationCreator.ConfigureHardwareMemoryTool(memoryToolSigner, cfg.MemoryToolBaseURL, cfg.MemoryToolTokenTTL); err != nil {
return fmt.Errorf("configure hardware memory tool: %w", err)
}
}
credentialRenewalWindow := cfg.RTCTokenTTL / 3
minimumRenewalWindow := time.Duration(cfg.HeartbeatInterval*2) * time.Second
if credentialRenewalWindow < minimumRenewalWindow {
@@ -387,7 +424,17 @@ func Run(ctx context.Context, serviceName string) error {
if processorErr != nil {
return fmt.Errorf("create content extraction processor: %w", processorErr)
}
outboxWorker.Register("conversation.content_extraction_requested", extractionProcessor.Handle)
if vikingMemory != nil {
outboxWorker.Register(vikingmemory.SyncEvent, vikingMemory.Handle)
outboxWorker.Register("conversation.content_extraction_requested", func(ctx context.Context, event outbox.Event) error {
if err := vikingMemory.Enqueue(ctx, event); err != nil {
return err
}
return extractionProcessor.Handle(ctx, event)
})
} else {
outboxWorker.Register("conversation.content_extraction_requested", extractionProcessor.Handle)
}
memoryIndexProcessor, processorErr := memoryindex.NewProcessor(databasePool, memoryEmbedding)
if processorErr != nil {
return fmt.Errorf("create memory index processor: %w", processorErr)
@@ -415,6 +462,9 @@ func Run(ctx context.Context, serviceName string) error {
if processorErr != nil {
return fmt.Errorf("create privacy delete processor: %w", processorErr)
}
if vikingMemory != nil {
privacyDeleteProcessor.ConfigureVikingMemory(vikingMemory)
}
outboxWorker.Register("privacy.delete_requested", privacyDeleteProcessor.Handle)
exportProcessor, processorErr := dataexport.NewProcessor(databasePool, exportStore, cfg.ExportObjectTTL)
if processorErr != nil {
@@ -470,40 +520,45 @@ func Run(ctx context.Context, serviceName string) error {
}()
}
router := httpapi.NewRouter(httpapi.RouterOptions{
ServiceName: serviceName,
Logger: logger,
RateLimiter: rateLimiterAdapter{limiter},
Readiness: readiness,
TokenVerifier: tokenVerifier,
IdentityRepository: identityRepository,
SaaSService: saasService,
DeviceVerifier: deviceVerifier,
DeviceService: deviceRepository,
DeviceTelemetrySubmitter: deviceTelemetryService,
MediaService: mediaService,
WebEventService: webEventService,
SharingService: sharingService,
OpsConfigService: opsConfigService,
BillingService: billingService,
AlertService: alertService,
DiagnosticService: diagnosticService,
OpsAccessService: opsAccessService,
OpsDeviceService: opsDeviceService,
ContentModelService: contentModelService,
ConversationCreator: conversationCreator,
ConversationActivator: conversationCreator,
DeviceConversationStateReader: conversationCreator,
ConversationHeartbeater: conversationHeartbeater,
ConversationStopper: conversationCreator,
ConversationTranscriptSubmitter: conversationTranscriptSubmitter,
ProviderCallbackSecret: []byte(cfg.ProviderCallbackSecret),
ProviderCallbackSkew: cfg.ProviderCallbackSkew,
ProviderCallbackProcessor: providerEventProcessor,
PlatformHealthCallbackSecret: []byte(cfg.PlatformHealthSecret),
PlatformHealthCallbackSkew: cfg.PlatformHealthSkew,
PlatformHealthProcessor: diagnosticService,
MemoryToolService: memoryToolService,
MemoryToolSigner: memoryToolSigner,
ServiceName: serviceName,
Logger: logger,
RateLimiter: rateLimiterAdapter{limiter},
Readiness: readiness,
TokenVerifier: tokenVerifier,
IdentityRepository: identityRepository,
SaaSService: saasService,
DeviceVerifier: deviceVerifier,
DeviceService: deviceRepository,
DeviceTelemetrySubmitter: deviceTelemetryService,
MediaService: mediaService,
WebEventService: webEventService,
SharingService: sharingService,
OpsConfigService: opsConfigService,
BillingService: billingService,
AlertService: alertService,
DiagnosticService: diagnosticService,
OpsAccessService: opsAccessService,
OpsDeviceService: opsDeviceService,
ContentModelService: contentModelService,
ConversationCreator: conversationCreator,
ConversationActivator: conversationCreator,
DeviceConversationStateReader: conversationCreator,
ConversationHeartbeater: conversationHeartbeater,
ConversationStopper: conversationCreator,
ConversationTranscriptSubmitter: conversationTranscriptSubmitter,
HardwareAgentSessionService: conversationCreator,
HardwareAgentProvisioningService: hardwareProvisioningService,
DeviceFactoryResetService: deviceFactoryResetService,
ProviderCallbackSecret: []byte(cfg.ProviderCallbackSecret),
ProviderCallbackSkew: cfg.ProviderCallbackSkew,
ProviderCallbackProcessor: providerEventProcessor,
NativeSubtitleSecret: []byte(cfg.SubtitleCallbackSecret),
NativeSubtitleProcessor: orchestration.NewNativeSubtitleService(databasePool),
PlatformHealthCallbackSecret: []byte(cfg.PlatformHealthSecret),
PlatformHealthCallbackSkew: cfg.PlatformHealthSkew,
PlatformHealthProcessor: diagnosticService,
MemoryToolService: memoryToolService,
MemoryToolSigner: memoryToolSigner,
})
server := &http.Server{
Addr: cfg.HTTPAddr,