import { policyCall } from 'atlibs/oauth/index.js' import { hostCall, sessionXrpc } from 'atlibs/run-module/host-call.js' import { runModule } from 'atlibs/run-module/index.js' // The page logic, apart from the DOM so a test can run it: the cocore modules, each held to its own session. export const NAMES = ['cocore-inference', 'cocore-keys'] /** The host's allowlist: cocore.dev/api/v1, each request with a service-auth token minted from the user's session. */ export const HTTP = { 'https://cocore.dev': { serviceAuth: { aud: 'did:web:cocore.dev', lxm: 'dev.cocore.inference.dispatch' } } } /** Each module's session scope (records/.json): the policy policyCall holds every run to. */ export async function loadPolicy(base, fetchImpl = globalThis.fetch) { const scopes = await Promise.all(NAMES.map(async (name) => (await (await fetchImpl(new URL(`records/${name}.json`, base))).json()).clientMetadata.scope)) return { sessions: Object.fromEntries(NAMES.map((name, i) => [name, { scope: scopes[i] }])), modules: Object.fromEntries(NAMES.map((name) => [name, { session: name }])), } } // A completion can take a minute or so: more than runModule's default 60 s of wall time. const BUDGET = { wallMs: 180_000 } /** * Run one action as the signed-in session, held to that module's own scope; with no session, signed out * (no token: the public model directory works, inference answers 401). Resolves to the run's result. */ export async function runAction({ ctx, policy, modules, session }, name, entry, fields) { const call = session ? policyCall(policy, name, { [name]: hostCall({ ctx, xrpc: sessionXrpc(session), canHeader: false }) }) : hostCall({ ctx, canHeader: false }) const ran = await runModule(ctx, await modules[name], entry, session ? { ...fields, did: session.did } : fields, call, { budget: BUDGET, http: session ? HTTP : { 'https://cocore.dev': {} } }) if (ran.error !== undefined) throw new Error(ran.error) return ran.result }