Voice Iterate Widget (Preview)
The repository contains an embeddable Web Component that captures a typed or browser-transcribed instruction, submits it to an owned OpenFactory app, and polls the resulting repair ticket. The integration is preview-only.
The package source is in tools/voice-iterate in the OpenFactory monorepo. Do
not assume @openfactory/voice-iterate or its CDN bundle is publicly published;
build and pin a reviewed artifact from the repository until a release is
explicitly listed in the package registry.
Current boundary
The endpoint accepts an instruction for an app with a Git source and dispatches
the shared repair workflow. Stage 0 changes the deployed sandbox copy and can
redeploy that preview. It does not guarantee that the change is committed to
the upstream repository. A ticket marked done proves only the recorded agent
task outcome; review its result and verify the app yourself.
The service allows at most two in-flight iterations per app. Additional
requests return 429 until a ticket reaches a terminal state.
Prerequisites
- An owned OpenFactory app with
source.git_url. - A real account; guest sessions cannot dispatch autonomous code edits.
- An
of_mcp_account key kept on a server, never in browser JavaScript. - HTTPS or a localhost development origin if microphone input is used.
Build the widget from source
From the monorepo:
cd tools/voice-iterate
npm ci
npm test
npm run lint
npm run buildVendor the resulting versioned bundle or install it from your own controlled registry. Record the source commit and checksum used by your application.
Use a same-origin proxy
The browser-facing widget calls:
POST {endpoint}/iterate
GET {endpoint}/agent-status
GET {endpoint}/agent-status?thread_id={thread_id}Your server should pin the target app ID and forward those requests to:
POST https://console.openfactory.tech/api/apps/{APP_ID}/iterate
GET https://console.openfactory.tech/api/apps/{APP_ID}/agent-statusAttach Authorization: Bearer <of_mcp_key> only on the server. Authenticate
and rate-limit your own proxy users; otherwise every visitor able to reach the
route can spend your account’s authority on changes to the pinned app. Allow
only the three paths and two methods above, enforce request-size limits, and do
not forward arbitrary headers or app IDs.
Mount the locally built module with the proxy endpoint:
import { createVoiceIterate } from './vendor/openfactory-voice-iterate/index.mjs';
const widget = createVoiceIterate({
appId: '550e8400-e29b-41d4-a716-446655440000',
endpoint: '/api/voice-iterate',
fallback: 'text',
onStatusChange: ({ status, thread }) => {
console.log(status, thread.taskResult);
},
});The custom element and its styles run in a Shadow DOM. The default text fallback remains usable when browser speech recognition is unavailable. Browser speech services and privacy behavior vary by browser and deployment; obtain consent and test the exact supported browser set. OpenFactory receives the resulting text on this path, while the browser or a configured speech service may process audio separately.
Acceptance test
- Submit a harmless, reversible change against a non-production app.
- Confirm the proxy cannot target any other app and rejects unauthenticated callers.
- Observe
queued/workingthrough a terminaldone,failed,lost, orstalestate. - Inspect the task result and preview manually.
- Confirm the upstream Git repository is unchanged unless a separate, reviewed source-persistence workflow reports a commit or pull request.
- Revert or rebuild the sandbox from the canonical source.
See Prompt-to-app agent and App deployment for the same persistence and promotion boundaries.