@auvira.ai/sdk
v0.29.2
Published
Cursor-SDK-compatible visual coding agent with custom model support
Readme
@auvira.ai/sdk
Cursor-SDK-compatible TypeScript agent SDK with custom model support, local repo workspaces, GitLab cloning, visual context (screenshots + selected DOM), and safe post-edit validation.
v0.7.0: provider: "custom" only (OpenHands removed). See docs/architecture.md for dispatch and harness pipeline details.
v0.22.1: Republish — maps real Cline AgentEvent schema to Auvira stream events (model.request, builtin tool.start/tool.end), fixes session_snapshot usage path, accepts in-repo absolute paths in path guard. MiniMax smoke e2e converges.
v0.22.0: Harness protocol hardening — tool-time finishGate (file-change), post-turn requiredContent gate, terminal tool aliasing (attempt_completion/submit_and_exit), session-end finish fallback, trusted workspace approval, direct JSON planner, skill inlining. See docs/api-invariants.md.
v0.21.1: Phase-scoped strong model routing (AUVIRA_STRONG_DESIGN_PHASES, default plan); run.diagnostic failure classification; cooperative phase timeouts; explicit strong-design routing; harness plan JSON repair. See docs/api-invariants.md.
v0.18.0: Removed JSON CustomModelProvider, stage-decision eval, temporal/ stubs, and legacy parallel-read batching. Cline Core is the only runtime. See docs/architecture.md.
v0.13.0: Cline Core is the only runtime for Agent.send. Legacy agentLoop.ts and AUVIRA_RUNTIME=legacy were removed. See docs/cline-migration.md.
Runtime backend
# Cline Core + Auvira plugin (default and only path since v0.13.0)
# (omit AUVIRA_RUNTIME or set AUVIRA_RUNTIME=cline)@cline/core is a runtime dependency (pinned in package.json). Public Agent.send API is unchanged — see docs/api-invariants.md.
v0.22.8: We overlay @cline/core (see patches/) for MiniMax run_commands arg coercion and editor whitespace retry. The overlay applies during local prepare only — not on consumer installs (SDK middleware covers the same cases). Regenerate after any @cline/core bump — details in patches/README.md.
v0.23.1: Removed postinstall: patch-package from the published package. It required patch-package in consumer node_modules and failed on Vercel (exit 127) even though the tarball shipped no patches/ folder.
v0.24.0: Unified host tool capabilities (mutation-force + finish gates), terminal run.early_finish for harness runs without completion rules, and @cline/llms openai-compatible deprecation cleanup. Published tarball ships patches/@cline+core+0.0.54.patch plus scripts/apply-cline-core-patch.mjs — hosts apply overlays explicitly (no postinstall). See Host Cline overlays below.
v0.25.3: Serialize hostSkills in sandbox job.json — VM runner mounts load_skill / read_skill_resource from JSON skill definitions (512KB max). Generic hostTools remain non-serializable. See sandbox-runner.md.
v0.25.2: Expose host-configurable clineToolRouting on Agent.send, pipeline input, and sandbox jobs — defaults unchanged; docs for clone-website / fetch vs pre-ingest. See Cline tool routing.
v0.25.1: Remove run_commands / fetch_web_content from the model tool schema for section/harness profiles via Cline toolRoutingRules — fixes MiniMax wasting turns on blocked shell calls (NO_CHANGES flake).
v0.25.0: Lean install footprint — consumers should install with --omit=optional (or set omit=optional in .npmrc) to skip ~409MB of unused codex/claude native binaries pulled transitively via @cline/llms. See Install footprint below.
Install footprint
@auvira.ai/sdk depends on @cline/core, which pulls @cline/llms and many LLM provider wrappers. The default Auvira path uses a custom MiniMax provider — not codex, claude-agent, dify, or sap runners.
Codex and Claude native binaries (~409MB) are declared as optionalDependencies deeper in the graph. They are only needed when a host explicitly selects those runners.
Recommended for Next.js / Vercel hosts:
# One-time per project (or add to your host repo .npmrc)
echo "omit=optional" >> .npmrc
npm install @auvira.ai/sdk --omit=optionalWith omit=optional, a fresh production install is typically ~225MB instead of ~634MB (measured with @cline/* transitive closure). Required runtime deps (@cline/core, @vercel/sandbox, @modelcontextprotocol/sdk, etc.) remain installed.
Verify after install:
npm run check:deps:full # from SDK repo; fresh lean consumer install guardAdvanced (optional): npm ignores overrides from dependencies. Hosts that want to trim unused provider JS further can add root-level overrides in their consumer package.json (at your own risk — only if you never use those providers):
{
"overrides": {
"ai-sdk-provider-codex-cli": "npm:@auvira.ai/[email protected]",
"ai-sdk-provider-claude-code": "npm:@auvira.ai/[email protected]"
}
}Prefer omit=optional first; it removes the native binaries safely without touching @cline/llms static imports.
Install
Option A — npm (recommended if you have npm Pro for private)
Private (requires npm Pro, ~$7/mo):
npm publish --access restricted # from this repo, after npm login
npm install @auvira.ai/sdk # in consuming projects (same npm account or granted access)Public (free on npm):
npm publish --access public
npm install @auvira.ai/sdkOption B — private GitHub repo (free, no npm publish)
npm install github:athan37/auvira-sdkRequires GitHub auth (gh auth login or a PAT). Builds from source on install.
For local development (SDK contributors — vitest/rollup need their optional platform binaries):
npm install --include=optional
npm run buildThis repo's .npmrc sets omit=optional by default to mirror lean consumer installs. Use --include=optional when developing or running tests here.
Host Cline overlays
The SDK does not run patch-package on postinstall (avoids Vercel exit 127 and undeclared devDependency issues). Hosts that bundle @cline/core / @cline/llms and want the same MiniMax/editor fixes can apply overlays after npm install:
Option A — apply script (recommended; covers @cline/core + @cline/llms):
node node_modules/@auvira.ai/sdk/scripts/apply-cline-core-patch.mjsFrom a git checkout of this repo: npm run apply-cline-patches.
Option B — patch-package for @cline/core only (15KB patch ships in the npm tarball):
mkdir -p patches
cp node_modules/@auvira.ai/sdk/patches/@cline+core+0.0.54.patch patches/
# optional: add "postinstall": "patch-package" to your host app if you accept that tradeoff
npx patch-packageOption C — skip overlays: SDK middleware (normalizeRunCommandsArgs, mutation-force recovery, suppressAiSdkWarnings, beforeModel key migration) covers the same failure modes without patching node_modules.
Details and regeneration steps: patches/README.md.
Vercel Sandbox runner
For website edit harnesses that run on Vercel (preview + edits in a persistent sandbox VM), use the in-VM runner CLI instead of calling Agent.send() from Lambda:
auvira-sdk-run --job <editJobId>See docs/sandbox-runner.md for job schema, NDJSON protocol, host integration, and session resume.
For image placement (attachments, completion rules, host tools, Plan → Apply → Polish and Preset → Apply → Polish host pipelines, polish helpers), see docs/host-integration-image-placement.md.
Quick start (local repo)
import { Agent } from "@auvira.ai/sdk";
const agent = await Agent.create({
model: {
id: "MiniMax-M3",
provider: "custom",
// baseURL and apiKey optional when CUSTOM_MODEL_* env vars are set
},
local: {
cwd: "/path/to/repo",
},
});
const result = await agent.send(
"Change the hero headline to Fast Emergency AC Repair in Houston",
{
selectedDom: {
tagName: "h1",
text: "Reliable HVAC Service When You Need It",
componentHint: "Hero",
route: "/",
},
validation: {
command: "npm run build",
},
},
);
const runResult = await result.wait();
console.log(runResult.status, runResult.summary, runResult.changedFiles);Streaming (Cursor SDK parity)
const agent = await Agent.create({ /* ... */ });
const run = await agent.send("Update hero colors to match the reference image", {
validation: { skip: true },
});
for await (const event of run.stream()) {
if (event.type === "assistant") {
for (const block of event.message.content) {
if (block.type === "text") process.stdout.write(block.text);
}
}
if (event.type === "tool.start") {
console.log("tool:", event.name);
}
if (event.type === "run.diagnostic") {
console.log("diagnostic:", event.failureCategory, event.failureEvidence);
}
if (event.type === "phase.timeout") {
console.log("phase timeout:", event.phase, event.timeoutCode);
}
}
const result = await run.wait();
console.log(result.status, result.id, result.changedFiles);
// Follow-up keeps conversation context on the same agent instance.
const run2 = await agent.send("Make the accent color warmer");
await run2.wait();
await agent.close();run.text() blocks on wait() and returns the final assistant string (including synthetic run.final_summary when the model exits silently). run.iterText() yields assistant text and run.final_summary events from the stream.
One-shot API
import { Agent } from "@auvira.ai/sdk";
const result = await Agent.prompt(
"Change the hero headline to Fast Emergency AC Repair in Houston",
{
model: {
id: "MiniMax-M3",
provider: "custom",
},
local: { cwd: "/path/to/repo" },
validation: { command: "npm run build" },
},
);GitLab source
Environment variables (.env):
GITLAB_TOKEN=...
GITLAB_BASE_URL=https://gitlab.com/api/v4
GITLAB_GROUP_ID=135136695By project URL:
const agent = await Agent.create({
model: { id: "MiniMax-M3", provider: "custom" },
gitlab: {
projectUrl: "https://gitlab.com/auvira-group/generated-site-o4rz7l-rehs.git",
token: process.env.GITLAB_TOKEN,
branch: "main",
},
});By GitLab numeric project ID (resolved via GITLAB_BASE_URL API; token from env):
const agent = await Agent.create({
model: { id: "MiniMax-M3", provider: "custom" },
gitlab: {
projectId: 83611012,
},
});Auvira MongoDB project ID 6a382fe1e5fa82e481384836 maps to GitLab project 83611012 (auvira-group/generated-site-o4rz7l-rehs). Pass the GitLab numeric ID to gitlab.projectId.
Skip validation when a repo has known pre-existing build issues:
await agent.send("Change the hero headline to ...", {
validation: { skip: true },
});GitLab mode clones over HTTPS, creates an auvira/edit-* branch, and returns a diff only (no push by default).
Custom model support
Pass model settings inline or via .env. Authentication uses CUSTOM_MODEL_API_KEY only (there is no separate AUVIRA_AGENT_API_KEY env var).
CUSTOM_MODEL_BASE_URL=https://api.minimax.io/v1
CUSTOM_MODEL_API_KEY=...
CUSTOM_MODEL_ID=MiniMax-M3model: {
id: "MiniMax-M3",
provider: "custom",
// baseURL and apiKey optional when CUSTOM_MODEL_* env vars are set
}| Provider route | CUSTOM_MODEL_BASE_URL | Model id |
|----------------|-------------------------|------------|
| MiniMax direct (global) | https://api.minimax.io/v1 | MiniMax-M3 |
| MiniMax direct (China) | https://api.minimaxi.com/v1 | MiniMax-M3 |
Strong design model routing (explicit opt-in): Harness plan/execute and image-section profiles use CUSTOM_MODEL_* by default. Set these only when you want hard design tasks routed to a stronger model:
AUVIRA_STRONG_DESIGN_MODEL_ID=MiniMax-M3
AUVIRA_STRONG_DESIGN_BASE_URL=https://api.minimax.io/v1
AUVIRA_STRONG_DESIGN_API_KEY=... # or falls back to CUSTOM_MODEL_API_KEY
# Phase-scoped routing (default when unset: plan only — cheap)
AUVIRA_STRONG_DESIGN_PHASES=plan # strong model for plan + JSON repair only (same as unset)
AUVIRA_STRONG_DESIGN_PHASES=plan,execute # full harness quality (expensive)
AUVIRA_STRONG_DESIGN_PHASES=all # image-to-section + skill-only hard design
AUVIRA_STRONG_DESIGN_PHASES=none # disable strong-design phase swap → routingSkippedReason=phase_not_enabledBy default (unset or plan), execute subtasks and normal edits stay on MiniMax. Setting none is not the default — it explicitly disables phase routing (you will see routing skipped: phase_not_enabled | phases=none). For image-to-section quality (no harness phase), use all or plan,execute.
Planner latency (separate from phases): roleModels.planner / CUSTOM_MODEL_ID_PLANNER routes the JSON planner + repair calls to a faster model without changing which harness phases use the strong design model. Use this when plan latency matters; do not set AUVIRA_STRONG_DESIGN_PHASES=none unless you intend to disable strong-model routing entirely.
Routing is never applied without AUVIRA_STRONG_DESIGN_MODEL_ID. run.harness_ready and AgentRunResult.routing report modelId, routedModelId, routingApplied, routingPhase, routingSkippedReason, and enabledPhases.
Run diagnostics: On failure, the SDK emits run.diagnostic with failureCategory and redacted failureEvidence (routing context, tool names, zero-edit retries, planParseFailures). Handle it in stream consumers alongside run.failed.
Production path: provider: "custom" with MiniMax (or compatible OpenAI-style chat API). The SDK runs an agentic tool loop for harness prompts and a json single-shot edit plan for exploratory prompts. See docs/architecture.md.
Visual assets and image generation (v0.5.0)
Reference images uploaded with a run are saved under .auvira/ as stable names (input-image-0.png, input-image-1.png, …). The agent can:
| Tool | Purpose |
|------|---------|
| publish_reference_image | Copy a reference image into public/ |
| generate_image | Generate via MiniMax image-01 (POST /v1/image_generation) |
Chat vs image API: MiniMax-M3 chat (/chat/completions) is vision-only. Image generation uses a separate endpoint — never append /image_generation to non-MiniMax chat hosts.
# Image generation (default off)
AUVIRA_IMAGE_GEN_ENABLED=false
AUVIRA_IMAGE_GEN_MAX_PER_RUN=2
AUVIRA_IMAGE_BASE_URL= # optional; defaults to api.minimax.io/v1 or CN from chat host
AUVIRA_IMAGE_MODEL=image-01Tool results include publicUrl (site-root path like /assets/edits/hero.png). Wire that in TSX/CSS — not destPath or /public/....
Hosts must allowlist public/assets/edits/ (or similar) in ALLOWED_WRITE_PATHS.
HTTP usage
Optional built-in server:
npm run build
node dist/server/server.jsPOST /agent/prompt accepts the same JSON shape as Agent.prompt and returns AgentRunResult.
GET /health returns { "ok": true }.
Bind to localhost or protect with a reverse proxy; v1 has no built-in auth.
Security notes
- Validation commands are allowlisted (
npm/pnpm/yarn build|testonly). - Shell chaining, installs, curl pipes, and destructive commands are rejected.
- GitLab URLs must be
https://gitlab.com/.../*.git(no SSH, credentials in URL, or shell metacharacters). - Tokens and API keys are masked in error output and never logged.
- Workspaces are copied/cloned to temp dirs; originals are not modified directly.
Test commands
See docs/testing-standards.md for the four-tier pyramid, naming rules, and checklist for new tests.
Always run MiniMax end-to-end smoke after unit tests — mock/flex tests do not validate live model behavior, parallel tool batching against real M3 responses, or API queue behavior under real latency.
# 1) Unit only (no flex, no live)
npm run test:unit
# 1b) Flex (mocked Cline agent loops)
npm run test:flex
# 2) MiniMax e2e smoke (required after every SDK change; uses .env CUSTOM_MODEL_API_KEY)
npm run test:real:smoke
# Full suite (all vitest workspace projects)
npm test
# All real integration tests (most skip without env flags)
npm run test:real
npm run typecheck
npm run buildtest:real:smoke runs:
| Test | Validates |
|------|-----------|
| minimax-api.test.ts | MiniMax API reachable |
| agent-run-stream.e2e.test.ts | Live agent loop + stream events |
| agent-parallel-read-tools.e2e.test.ts | v0.6.2 parallel read batches + harness edit |
Real tests require in .env:
GITLAB_TOKEN=...
GITLAB_BASE_URL=https://gitlab.com/api/v4
CUSTOM_MODEL_BASE_URL=https://api.minimax.io/v1
CUSTOM_MODEL_API_KEY=...
CUSTOM_MODEL_ID=MiniMax-M3Real tests call MiniMax-M3 via the custom provider and clone from GitLab when configured.
Optional visual asset / image generation e2e (opt-in, costs API credits)
These are not run by npm test or npm run test:real by default:
# Publish reference + wire publicUrl in page (M3 chat only)
npm run test:runner:asset
# generate_image img2i + wiring (M3 + image-01; expensive)
npm run test:runner:image-gen
# Single image-01 HTTP smoke (no agent loop)
npm run test:real:image-api
# Multi-image drag-in: reference vs decoration, combine, animation (M3 + LLM judge)
npm run test:real:multi-image| Env flag | Required for |
|----------|----------------|
| AUVIRA_REAL_ASSET_E2E=true | test:runner:asset |
| AUVIRA_REAL_IMAGE_GEN_E2E=true + AUVIRA_IMAGE_GEN_ENABLED=true | test:runner:image-gen |
| AUVIRA_REAL_IMAGE_API=true + AUVIRA_IMAGE_GEN_ENABLED=true | test:real:image-api |
| AUVIRA_REAL_MULTI_IMAGE_E2E=true | test:real:multi-image |
| AUVIRA_REAL_ATTACHMENT_E2E=true | test:real:attachment-placement |
All still require CUSTOM_MODEL_API_KEY (and related CUSTOM_MODEL_* vars).
Vibe replication real tests use an LLM-as-judge verifier (vision + diff) for every vibe case — not keyword heuristics. Heuristic checks remain in flex/unit tests only (vibe-palette.flex.test.ts).
Optional tuning:
AUVIRA_VIBE_VERIFY_CONFIDENCE=0.75 # default threshold
AUVIRA_VIBE_VERIFY_TIMEOUT_MS=30000
AUVIRA_VIBE_VERIFY_MODEL=MiniMax-M3 # optional overrideMulti-image harness e2e (test:real:multi-image) uses fixture pairs (Doraemon style reference + village texture decoration) with three scenarios:
Phase 3 attachment placement e2e (test:real:attachment-placement) verifies pre-uploaded attachments metadata, get_attachment_urls, serializable completion.rules, and an LLM judge — no vision bytes.
- Reference style + decoration publish — index:0 drives CSS palette only; index:1 published to
public/assets/edits/and wired viapublicUrl. - Combined styles + animation — merge both vibes in CSS, publish index:1, add
@keyframes/animation. - Explicit reference vs decoration — strict role split; LLM judge verifies roles were not swapped.
Verification uses the same vision+diff LLM judge pattern with structured checks (referenceStyleApplied, decorationAssetPublished, decorationPublicUrlWired, etc.). Optional tuning:
AUVIRA_MULTI_IMAGE_VERIFY_CONFIDENCE=0.75
AUVIRA_MULTI_IMAGE_VERIFY_TIMEOUT_MS=45000
AUVIRA_MULTI_IMAGE_VERIFY_MODEL=MiniMax-M3Harness integration (cursor-agent-edit-website)
When embedding the SDK as a drop-in Cursor SDK replacement for the website edit harness:
- Pass the full compiled harness prompt unchanged via
agent.send(system rules +ALLOWED WRITE PATHS+ owner request). - Pass
selectedDomwithsectionIndex,sectionType,sectionTitle, andkindwhen the host has structured pin metadata from the preview UI. DOM pin metadata wins over harness-only pin parsing and is required for reliable pinned section edits on single-page sites. - Pass
validation: { skip: true }— the harness runs its own build gate viavalidateWorkspace; the SDK defaultnpm run buildconflicts with harness system rules ("Do not run npm/shell builds").
await agent.send(sendPayload, {
selectedDom: {
sectionIndex: 6,
sectionType: "services",
sectionTitle: "Our Services",
kind: "section",
componentHint: "Services · Our Services",
},
validation: { skip: true },
});Agent runtime (v0.18+)
All harness and exploratory runs use the Cline tool loop via Agent.send. The legacy JSON single-shot path and AUVIRA_AGENT_MODE were removed in v0.18.0. completion.executionMode (direct_requirements / workflow) was removed in 0.29.0 — completion is gated by the Outcome Verifier (evaluateOutcome).
Tool budget and context:
AUVIRA_CLINE_MAX_ITERATIONS=40 # Cline iteration cap (profile-specific default)
AUVIRA_AGENT_HISTORY_TOOL_ROUNDS=3 # tool rounds kept in trimmed history
AUVIRA_CONTEXT_TOKEN_BUDGET=32000 # Priompt-style context capTerminal outcomes (v0.7.x)
One Agent.send → one agent decision. No hidden repair loops.
| status | Meaning |
|----------|---------|
| finished | Edits applied; validation passed (when enabled) |
| needs_clarification | Structured clarification questionnaire — host renders choices; user answer starts a new send with editContext |
| impossible | Request cannot be satisfied — impossible.message + reason |
| error | Execution failure — error.code: EDIT_NOT_APPLIED, VALIDATION_FAILED, COMPLETION_RULES_UNMET, TOOL_BUDGET_EXCEEDED, INVALID_TERMINAL_OUTCOME |
Use finish({ outcome: "needs_clarification", clarification: { question, reason, choices, allowCustomAnswer } }) when required info is missing. Edits are inferred from mutating tools — finish({ outcome: "edited" }) is optional.
Parallel tool execution (Cline runtime):
When the model returns multiple tool calls in one turn, the Cline runtime executes them concurrently (toolExecution: "parallel"). Mutating tools in the same turn may also run in parallel — models should avoid mixing unrelated writes in a single turn.
AUVIRA_API_MAX_CONCURRENT=3 # global in-flight limit for external API callsAUVIRA_API_MAX_CONCURRENT applies to all model-like external API calls: chat completions, completion evaluator, image generation, and test judges. Legacy aliases AUVIRA_MODEL_MAX_CONCURRENT and CUSTOM_MODEL_MAX_CONCURRENT are still honored.
Host tools may set definition.parallelSafe: true to document read-only/idempotent tools (metadata only; Cline parallelizes all tools in a turn).
MiniMax request tuning (custom provider):
CUSTOM_MODEL_THINKING=adaptive|disabled # override thinking mode (default: adaptive for ALL profiles)
AUVIRA_MINIMAX_CLINE_THINKING=adaptive|disabled # Cline direct api.minimax.io only (default: adaptive + reasoning_split)
CUSTOM_MODEL_ID_PLANNER=... # optional faster model for JSON planner/repair (roleModels.planner)
CUSTOM_MODEL_ID_EVALUATOR=... # optional evaluator/verifier model
AUVIRA_REASONING_RESERVE_TOKENS=256 # headroom subtracted from tool-call char budget on MiniMax (default 256)
CUSTOM_MODEL_MAX_COMPLETION_TOKENS=... # global cap override
CUSTOM_MODEL_MAX_COMPLETION_TOKENS_AGENTIC=2048
CUSTOM_MODEL_MAX_COMPLETION_TOKENS_VISION=4096
CUSTOM_MODEL_MAX_COMPLETION_TOKENS_JSON=8192MiniMax two-knob invariant: thinking controls how much the model reasons; reasoning_split controls where it goes. On native MiniMax (api.minimax.io), reasoning_split: true is always set for every profile (agentic and json). Do not turn the split off — that leaks <think> tags into the content channel.
On M3, thinking: disabled is best-effort and observed unreliable (the model still reasons). With split on it is harmless, but it is not a latency lever. Route planner/evaluator via models.planner / models.evaluator (or CUSTOM_MODEL_ID_PLANNER / CUSTOM_MODEL_ID_EVALUATOR) to a faster non-reasoning model instead.
AUVIRA_MINIMAX_CLINE_THINKING=disabled still keeps reasoning_split — only the adaptive/disabled thinking mode changes. CUSTOM_MODEL_THINKING is the provider-defaults override for the same thinking knob on json/agentic chat bodies.
All custom-provider chat requests default to service_tier: "priority". Production should leave CUSTOM_MODEL_API_COOLDOWN_MS unset (0); tests set a 3s cooldown locally for rate-limit safety.
Stream events (v0.2.3+)
Live run.stream() / run.messages() events are enriched for host UIs. Model-facing tool output strings are unchanged — sanitization applies only to emitted stream payloads.
| Event | Purpose |
|-------|---------|
| tool.start / tool.end | Tool lifecycle; tool.end.ok reflects ToolExecutionResult.ok |
| tool.end.output | Structured metadata (grep pattern/count, read preview, edit previews, etc.) |
| edit.diff | Per-file unified patch after successful edit (path, patch, truncated, line stats) |
| edit.applied | Edit outcome with optional linesAdded / linesRemoved / errorMessage |
| run.diff | Run-level workspace checkpoint diff after agent run (agent-run changes only) |
| completion.evaluated | Post-checkpoint LLM task completion verdict (source: llm, cached, skipped, error; includes isComplete, confidence, reason, missingWork) |
| run.early_finish | Harness mode: emitted when an allowlisted checkpoint diff passes completion evaluation (reason: diff_detected, completion_contract_met, completion_satisfied, or max_turns) |
| run.continue | Harness continues when completion is incomplete (reason: style_only_incomplete, completion_callback, min_turns_pending) |
| agent.thinking | Curated host UX reasoning (phase: planning, tool_selection, reflection, completion_check; includes summary, optional nextTools) |
| agent.raw_model_trace | Opt-in raw provider reasoning when AUVIRA_STREAM_RAW_MODEL_TRACE=true |
| run.failed | Optional abortReason, toolCallCount, editsApplied, providerCode (includes INCOMPLETE_MULTI_STEP when wiring never arrives) |
Stream caps (env overrides):
AUVIRA_EVENT_DIFF_MAX_CHARS=12000 # edit.diff / run.diff patch cap (default 12000)
AUVIRA_TASK_COMPLETION_TIMEOUT_MS=15000
AUVIRA_TASK_COMPLETION_CONFIDENCE=0.75
AUVIRA_COMPLETION_MAX_CONTINUES=2
AUVIRA_TASK_COMPLETION_MODEL= # optional override; defaults to agent model — use a fast/cheap model in production
AUVIRA_STREAM_RAW_MODEL_TRACE=true # optional: emit agent.raw_model_trace (default off)Completion evaluator performance (v0.2.9+):
- Per-turn evaluation: The LLM completion evaluator runs once at the end of each model tool batch (not after every mutating tool). Evaluation still runs if a later tool in the batch fails or aborts, as long as at least one mutating tool applied.
- Verdict cache: Repeated identical evaluator inputs within a run reuse the last verdict (
completion.evaluatedwithsource: "cached"). - Smaller diffs: Checkpoint diffs use line-based hunks (not full-file replace) and are memoized until the next mutating tool or
restore(). - Vision gating: Reference images are sent to the evaluator on the first check and on style-only diffs; subsequent wiring checks are text-only.
- Non-harness globs:
includeGlobs/excludeGlobson workspace checkpoints filter full-repo snapshots.
For production harness runs, set AUVIRA_TASK_COMPLETION_MODEL to a smaller/faster model than the main agent model to reduce evaluator latency and cost.
Workspace checkpoints (v0.2.8+): Before the agent edits, the SDK snapshots allowed files into an in-memory checkpoint. No git add, git commit, or index mutation occurs. changedFiles, run.diff, completion.evaluated, and harness early finish all use checkpoint diff (agent-run changes only — not pre-existing dirty git state).
Post-checkpoint completion evaluation (v0.2.8+): After a model turn produces an allowlisted checkpoint diff, the SDK calls a generic LLM evaluator with the owner request, selected DOM, reference images (when gated), diff patch, and recent tool results. If isComplete with confidence ≥ threshold → run.early_finish with reason: "completion_satisfied". If incomplete → targeted user nudge and the loop continues. Opt out with completion.auto: false to use deterministic fallback only.
await agent.send(payload, {
selectedDom,
completion: {
auto: true, // default in harness mode
confidenceThreshold: 0.8, // optional override
// Explicit deterministic contract still supported (v0.2.7):
requireWiringAfterStyle: true,
isComplete: ({ changedFiles }) => /* in-process only */,
},
});Harness early finish (v0.2.5+): When harnessPrompt is active and a model turn produces an allowlisted checkpoint diff, the loop evaluates completion before stopping.
Image placement primitives (v0.6+)
- Attachments — pass
attachments: AgentAttachmentMeta[]when files are already underpublic/. Vision bytes remain optional viaimages[]. - Serializable rules —
completion.rulesgates file-class changes, paths (globs), and content regex (requiredContent) without anisCompletecallback. - Host tools — register on
Agent.createorAgent.send(not both required); built-inget_attachment_urlswhen attachments are present. v0.6.1 fixes duplicate registration when tools are passed on send.
await agent.send(
{
text: harnessPrompt,
attachments: [{ index: 0, publicUrl: "/uploads/bg.jpg", role: "decoration" }],
},
{
hostTools: [placeUploadedImageTool],
completion: {
mode: "multi_file_required",
wiringPatterns: ["siteConfig\\.ts", "page\\.tsx"],
rules: {
requiredContent: [
{
pathPattern: "siteConfig",
contentPattern: 'backgroundImageUrl\\s*:\\s*["\']/uploads/',
},
],
requireAssetPublish: false,
},
wiringHints: { requiredFields: ["presentation.backgroundImageUrl"] },
},
},
);Stream events emit Cursor-compatible tool names: grep, read, glob, list_dir, search_replace, write.
Current limitations
- No HTTP SSE streaming (
POST /agent/run); in-processrun.stream()only. - No
Agent.resume/ cloud VM runtime (local cwd or GitLab clone only). - No MCP server configuration.
- No cloud push or PR creation.
- GitLab sanitizer supports
gitlab.comHTTPS URLs only in v1. - Validation is limited to build/test allowlist commands.
- Local workspace copy excludes
node_modules; SDK auto-runsnpm installinternally before build validation when needed.
Cursor SDK compatibility matrix
| Cursor SDK | Auvira SDK |
|------------|------------|
| Agent.create | Yes (+ close() / await using) |
| Agent.prompt | Yes |
| agent.send → AgentRun | Yes |
| run.stream() / messages() | Yes |
| run.wait() | Yes (status, id) |
| run.text() / iterText() | Yes |
| run.cancel() | Yes |
| run.conversation() | Yes (after first completed run) |
| Native grep/read/edit tools | Yes (agentic mode) |
| Agent.resume | No |
| Cloud / MCP | No |
License
MIT
