Add session mode for pre-funded request processing

Implement session-based API endpoints for creating, managing, and interacting with pre-funded sessions, including deposit and top-up invoice generation, macaroon authentication, and per-request debiting of compute costs.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 2dc3847e-7186-4a22-9c7e-16cd31bca8d9
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/9f85e954-647c-46a5-90a7-396e495a805a/418bf6f8-212b-4bb0-a7a5-8231a061da4e/sPDHkg8
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
alexpaynex
2026-03-18 20:00:24 +00:00
parent dfc9ecdc7b
commit ab2cc06a79
29 changed files with 1075 additions and 978 deletions

View File

@@ -11,7 +11,9 @@ tags:
- name: health
description: Health operations
- name: jobs
description: Payment-gated agent job operations
description: Payment-gated agent job operations (Mode 1 -- per-job)
- name: sessions
description: Pre-funded session balance mode (Mode 2 -- pay once, run many)
- name: demo
description: Free demo endpoint (rate-limited)
paths:
@@ -143,6 +145,165 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/sessions:
post:
operationId: createSession
tags: [sessions]
summary: Create a pre-funded session
description: |
Opens a new session. Pay the returned Lightning invoice to activate it.
Once active, use the `macaroon` from GET /sessions/:id to authenticate requests.
Deposits: 10010,000 sats. Sessions expire after 24 h of inactivity.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateSessionRequest"
responses:
"201":
description: Session created -- awaiting deposit payment
content:
application/json:
schema:
$ref: "#/components/schemas/CreateSessionResponse"
"400":
description: Invalid amount
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Server error
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/sessions/{id}:
get:
operationId: getSession
tags: [sessions]
summary: Get session status
description: Returns current state, balance, and pending invoice info. Auto-advances on payment.
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: Session status
content:
application/json:
schema:
$ref: "#/components/schemas/SessionStatusResponse"
"404":
description: Session not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/sessions/{id}/request:
post:
operationId: submitSessionRequest
tags: [sessions]
summary: Submit a request against a session balance
description: |
Runs eval + work and debits the actual compute cost from the session balance.
Rejected requests still incur a small eval fee. Requires `Authorization: Bearer <macaroon>`.
parameters:
- name: id
in: path
required: true
schema:
type: string
security:
- sessionMacaroon: []
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SessionRequestBody"
responses:
"200":
description: Request completed (or rejected)
content:
application/json:
schema:
$ref: "#/components/schemas/SessionRequestResponse"
"401":
description: Missing or invalid macaroon
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"402":
description: Insufficient balance
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"409":
description: Session not active
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"410":
description: Session expired
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/sessions/{id}/topup:
post:
operationId: topupSession
tags: [sessions]
summary: Add sats to a session
description: |
Creates a new Lightning invoice to top up the session balance.
Only one pending topup at a time. Paying it resumes a paused session.
parameters:
- name: id
in: path
required: true
schema:
type: string
security:
- sessionMacaroon: []
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateSessionRequest"
responses:
"200":
description: Topup invoice created
content:
application/json:
schema:
$ref: "#/components/schemas/TopupSessionResponse"
"400":
description: Invalid amount
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Invalid macaroon
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"409":
description: Session not active/paused, or topup already pending
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/demo:
get:
operationId: runDemo
@@ -309,6 +470,109 @@ components:
$ref: "#/components/schemas/CostLedger"
errorMessage:
type: string
SessionState:
type: string
enum: [awaiting_payment, active, paused, expired]
SessionInvoiceInfo:
type: object
properties:
paymentRequest:
type: string
amountSats:
type: integer
paymentHash:
type: string
description: Only present in stub/dev mode
CreateSessionRequest:
type: object
required: [amount_sats]
properties:
amount_sats:
type: integer
description: Deposit amount (10010,000 sats)
minimum: 100
maximum: 10000
CreateSessionResponse:
type: object
required: [sessionId, state, invoice]
properties:
sessionId:
type: string
state:
$ref: "#/components/schemas/SessionState"
invoice:
$ref: "#/components/schemas/SessionInvoiceInfo"
SessionStatusResponse:
type: object
required: [sessionId, state, balanceSats]
properties:
sessionId:
type: string
state:
$ref: "#/components/schemas/SessionState"
balanceSats:
type: integer
minimumBalanceSats:
type: integer
macaroon:
type: string
description: Bearer token for authenticating requests; present when active or paused
expiresAt:
type: string
format: date-time
invoice:
$ref: "#/components/schemas/SessionInvoiceInfo"
description: Present when state is awaiting_payment
pendingTopup:
$ref: "#/components/schemas/SessionInvoiceInfo"
description: Present when a topup invoice is outstanding
SessionRequestBody:
type: object
required: [request]
properties:
request:
type: string
minLength: 1
SessionCostBreakdown:
type: object
properties:
evalSats:
type: integer
workSats:
type: integer
totalSats:
type: integer
btcPriceUsd:
type: number
SessionRequestResponse:
type: object
required: [requestId, state, debitedSats, balanceRemaining]
properties:
requestId:
type: string
state:
type: string
enum: [complete, rejected, failed]
result:
type: string
reason:
type: string
errorMessage:
type: string
debitedSats:
type: integer
balanceRemaining:
type: integer
cost:
$ref: "#/components/schemas/SessionCostBreakdown"
TopupSessionResponse:
type: object
required: [sessionId, topup]
properties:
sessionId:
type: string
topup:
$ref: "#/components/schemas/SessionInvoiceInfo"
ClaimRefundRequest:
type: object
required:
@@ -340,3 +604,8 @@ components:
properties:
result:
type: string
securitySchemes:
sessionMacaroon:
type: http
scheme: bearer
description: Session macaroon issued when a session activates. Pass as `Authorization: Bearer <macaroon>`.