Skip to main content

createApprovalService

@forge/monorepo


@forge/monorepo / backend/src / createApprovalService

Function: createApprovalService()

createApprovalService(deps): object

Defined in: backend/src/hitl/service.ts:198

Parameters

deps

clock?

Clock

dispatcher

JobDispatcher

grants

ApprovalGrantStore

idFactory?

IdFactory

interactions

InteractionStore

runs?

RunStore

As on createQuestionService: without it the resumed run is never claimable. See resumeRun.

Returns

decide()

decide(input): Promise<{ grant?: ApprovalGrant; resumed: boolean; }>

Record a decision (once), issue a standing grant for allow-conversation/allow-always, and queue the continuation exactly once. The resumed run executes the stored normalized input from the pending approval — never a regenerated one; see ./approved-execution.ts.

allow-once deliberately issues no grant. A grant is standing by definition, so minting one for a one-time decision would hand over authority the human did not give. Its single execution is claimed off the interaction instead (InteractionStore.claimApproval).

Parameters

input

TenantScopeInput & object

Returns

Promise<{ grant?: ApprovalGrant; resumed: boolean; }>

pending()

pending(input): Promise<PendingApproval | null>

The approval a run is parked on, or null — the read side of decide (#163).

Same reasoning as pending on the question service: the worker raises it, a browser renders it, and the browser had only the interaction id from the event. Without this the card could not name the tool it was asking about, and an approval prompt that says "run a tool?" is one people learn to click through.

Parameters

input
runId

RunId

tenantId

TenantId

Returns

Promise<PendingApproval | null>

request()

request(context, runId, req): Promise<PendingApproval>

Persist a pending approval storing the exact normalized tool + input. Run pauses to waiting.

Parameters

context

ExecutionContext

runId

RunId

req

ApprovalRequest

Returns

Promise<PendingApproval>