evOo-local/packages/adapters/src/background-job-handlers.ts
Claude a663764ee8
feat(media): contracts and foundation for Media Studio
Freeze the shared contracts every Media Studio slice builds on: zod DTOs,
EDL, platform profile, brand kit, gate and render plan schemas; the media
RPC surface with a scaffold router; provider interfaces for sources,
inference, rendering, motion graphics and publishing; media background
jobs; the Prisma models and migration; and the @rakazo/media domain
package signatures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0138YqDj3ttfayRwuMKKrqVj
2026-10-03 17:32:52 +00:00

147 lines
5.0 KiB
TypeScript

import type {
AgentHomeStore,
AgentRuntime,
BackgroundJobHandlers,
JobPublisher,
MediaJobHandlers,
MessagingSurface,
SandboxProvider,
} from "@rakazo/adapter-kit";
import { messagingDeliverJob } from "@rakazo/adapter-kit";
import type { PrismaClient, ThreadEvents } from "@rakazo/db";
import { getLogger } from "@rakazo/logging";
import type { CloudAgentConnection } from "./cloud-agent-factory.js";
import { pollCloudAgent } from "./cloud-agent-poll.js";
import { expireComputerControl } from "./computer-control.js";
import { scheduleComputerSleep, sleepComputerIfIdle } from "./computer-idle.js";
import { performComputerUpdate } from "./computer-update.js";
import type { createRunExecutor } from "./executor.js";
import { compactHistory } from "./history-compaction.js";
import type { MemoryProviderResolver } from "./memory-provider-factory.js";
import { deliverMessagingOutbound, mirrorMessagingOutbound } from "./messaging-delivery.js";
import { consolidateProfile } from "./profile-consolidation.js";
import type { EncryptedSecretStore } from "./secrets.js";
import { expireTaughtSkillTeaching } from "./teaching-session.js";
export function createBackgroundJobHandlers(deps: {
executor: ReturnType<typeof createRunExecutor>;
prisma: PrismaClient;
sandbox: SandboxProvider;
home: AgentHomeStore;
jobs: JobPublisher;
events: ThreadEvents;
workerId: string;
runtime: AgentRuntime;
secretStore: EncryptedSecretStore;
memoryProviders: MemoryProviderResolver;
deploymentModelKey?: string;
messaging?: MessagingSurface;
cloudAgent?: CloudAgentConnection | null;
/** Media Studio job handlers; absent when media is not configured for this worker. */
media?: MediaJobHandlers;
}): BackgroundJobHandlers {
const deliverMessaging = async (runId?: string) => {
if (!deps.messaging) return;
await deliverMessagingOutbound(
{ prisma: deps.prisma, messaging: deps.messaging, events: deps.events, jobs: deps.jobs },
{ runId },
{
operationId: `messaging.deliver:${runId ?? "drain"}`,
traceId: `messaging.deliver:${runId ?? "drain"}`,
spaceId: "",
userId: "",
signal: new AbortController().signal,
},
);
};
return {
...(deps.media ?? mediaDisabledHandlers()),
"run.continue": async (payload) => {
await deps.executor.continueRun(payload.runId, deps.workerId);
// Automatic messaging mirror: once the run's bot messages are durable,
// copy them into the outbox. Never let mirror failures fail the run.
if (deps.messaging) {
await mirrorMessagingOutbound(
{ prisma: deps.prisma, messaging: deps.messaging, events: deps.events, jobs: deps.jobs },
payload.runId,
);
await deps.jobs.enqueue(messagingDeliverJob()).catch(async (error) => {
getLogger().error("messaging.deliver enqueue error", error);
await deliverMessaging();
});
}
},
"messaging.deliver": async (payload) => {
await deliverMessaging(payload.runId);
},
"routine.wakeup": async (payload) => {
await deps.executor.wakeRoutine(payload.routineId, payload.scheduledFor);
},
"computer.update": async ({ updateId }) => {
await performComputerUpdate(deps, updateId);
},
"computer.sleep": async (payload) => {
await sleepComputerIfIdle(deps, payload.computerId);
},
"computer.control-expire": async (payload) => {
if (await expireComputerControl(deps, payload.computerId, payload.leaseId)) {
scheduleComputerSleep(deps.jobs, payload.computerId);
}
},
"skill.teaching-expire": async (payload) => {
await expireTaughtSkillTeaching(deps, payload.skillId);
},
"cloud_agent.poll": async (payload) => {
await pollCloudAgent(
{
prisma: deps.prisma,
jobs: deps.jobs,
events: deps.events,
cloudAgent: deps.cloudAgent,
},
payload,
);
},
"history.compact": async (payload) => {
await compactHistory(
{
prisma: deps.prisma,
runtime: deps.runtime,
jobs: deps.jobs,
memoryProviders: deps.memoryProviders,
deploymentModelKey: deps.deploymentModelKey,
...(deps.executor.resolveModel ? { resolveModel: deps.executor.resolveModel } : {}),
},
payload.threadId,
);
},
"profile.consolidate": async (payload) => {
await consolidateProfile(
{
prisma: deps.prisma,
runtime: deps.runtime,
jobs: deps.jobs,
memoryProviders: deps.memoryProviders,
resolveModel: (scope) => deps.executor.resolveModel(scope),
},
payload.userId,
);
},
};
}
function mediaDisabledHandlers(): MediaJobHandlers {
const skip = async () => {
getLogger().warn("media job skipped: Media Studio is not configured on this worker");
};
return {
"media.sync": skip,
"media.proxy": skip,
"media.analyze": skip,
"media.cluster": skip,
"media.render": skip,
"media.publish": skip,
};
}