SDK-Test Preprocessor Plugin
The Antigravity preprocessor plugin that enriches user prompts via DeepSeek before the main agent executes, implementing a TCG turn-based workflow with Unicode token signaling.
SDK-Test Preprocessor Plugin
The preprocessor is a hook-based plugin that intercepts the first invocation of a conversation (invocationNum == 0) and enriches the user's prompt with deep project context before the main agent sees it. It uses a secondary AI model (DeepSeek V4 Flash via a local OpenCode sidecar) to research the workspace, transcript, and external sources, producing an enriched prompt artifact that the main agent then uses as its input.
This plugin bridges the gap between a raw user request and the deep contextual understanding required for complex tasks. It is the mechanical implementation of the Rule 02 (Epistemic Search Protocol) — ensuring that research happens before execution.
Architecture Overview
User Prompt
|
v
[Hook: PreInvocation] ─── invocationNum == 0?
| |
| YES | NO (continuation)
v v
preprocessor.py Pass through ({})
|
v
[OpenCode Sidecar :8765]
|
v
[DeepSeek V4 Flash]
|
v
enriched_prompt.md
|
v
[ephemeralMessage with Unicode tokens]
|
v
Main Agent presents artifact to user
|
v
User reviews, selects model, proceeds
|
v
[Hook: PreInvocation] ─── invocationNum == 1, no force tag
|
v
Pass through ({}) — agent executes with enriched context
Plugin Configuration
plugin.json
Minimal configuration — just the plugin name:
{
"name": "preprocessor"
}
hooks.json
The hook registration is currently commented out in the production configuration:
{
"preprocessor": {
"PreInvocation": [
{
"type": "command",
"command": "uv run ./preprocessor.py",
"timeout": 60
}
]
}
}
When active, this hook fires on every PreInvocation event. The Python script checks invocationNum internally — if it is not the first invocation and no force tag is present, it returns {} (empty JSON), passing through without modification.
The Python Implementation
File: preprocessor.py
PEP 723 dependencies: httpx>=0.27.0
Runtime: uv run .agents/plugins/preprocessor/preprocessor.py
Input Protocol
The script reads a JSON payload from stdin with these fields:
| Field | Description |
|---|---|
prompt | The user's raw prompt ($ARGUMENTS from the workflow) |
conversationId | Current conversation UUID |
workspacePaths | Array of active workspace paths |
artifactDirectoryPath | Where to write the enriched prompt |
transcriptPath | Path to transcript.jsonl for context |
System Prompt Architecture
The system prompt sent to DeepSeek is structured as a rigid frame:
╔══════════════════════════════════════════════════╗
║ PROMPT TO ENRICH — IMMUTABLE — DO NOT CONFUSE ║
║ WITH TRANSCRIPT ║
║ ║
║ {user_prompt} ║
║ ║
║ This is the ONLY message to enrich. The ║
║ transcript exists ONLY as background context, ║
║ never as prompt. ║
╚══════════════════════════════════════════════════╝
This framing solves what the code comments call "the N-1 bug" — the tendency of enrichment models to confuse transcript content with the actual prompt. By placing the user prompt in a visually distinct, immutable frame, the system ensures DeepSeek enriches the correct input.
Session Management
The script creates an idempotent session with OpenCode:
session_id = f"ses-{conversation_id[:20]}"
client.post("/api/session", json={
"id": session_id,
"model": {"providerID": "deepseek", "id": "deepseek-v4-flash"},
"location": {"directory": workspace_path},
"permission": [{"action": "*", "resource": "*", "effect": "allow"}]
})
The session ID is derived from the conversation ID (first 20 characters), ensuring the same conversation always maps to the same DeepSeek session. Idempotent creation means re-running the script does not create duplicate sessions.
Research Sources
The system prompt instructs DeepSeek to consult four sources in order:
- Transcript (background context) — Previous decisions, established constraints, project direction. Explicitly marked as NOT the prompt.
- Session Artifacts — Plans, discoveries, specs in the artifact directory.
- Workspace — Deep exploration of project files, wiki, code, configurations, reverse-engineering output.
- Online Search — For APIs, libraries, external documentation. Zero-trust inference enforced.
Output Protocol
The script returns a JSON object to stdout:
{
"artifact_path": "/path/exact/created",
"recommended_model": "exact model name",
"rationale": "1-2 sentences"
}
Available models for recommendation:
| Model | Use Case |
|---|---|
| Gemini 3.5 Flash (Low) | Simple queries, quick searches |
| Gemini 3.5 Flash (Medium) | Code analysis, moderate review |
| Gemini 3.5 Flash (High) | Technical tasks without deep reasoning |
| Gemini 3.1 Pro (Low) | Technical reasoning, light architecture |
| Gemini 3.1 Pro (High) | Complex technical reasoning |
| Claude Sonnet 4.6 (Thinking) | Agentic code, implementation, debugging |
| Claude Opus 4.6 (Thinking) | Critical architecture, multi-file refactoring |
| GPT-OSS 120B (Medium) | General alternative |
Artifact Structure
The enriched prompt artifact (enriched_prompt.md) follows this structure:
# Enriched Prompt
## Original Prompt
{user_prompt}
## Researched Context
[file:// links to relevant files with one-line descriptions]
[links to online documentation consulted]
[transcript excerpts that CONTEXTUALIZE — do not replace the prompt]
## Flags
[OPTIONAL: missing information, unverified assumptions]
## Enriched Version
[prompt with integrated technical context, links, explicit subtasks]
[preserves 100% of ORIGINAL PROMPT intent]
The Unicode Token Protocol
The preprocessor uses a set of Unicode emoji tokens as a signaling protocol between the hook and the main agent. Each token has precise semantics and defined behavior.
Token Dictionary
Wait Turn (injected by hook via ephemeralMessage)
Signal: PreProcessor enriched the prompt and created the artifact. The workflow is in a Wait Turn. Alefita has not yet approved execution.
Agent must:
- Present the
file://link to the enriched artifact - State the recommended model and rationale
- State that it is waiting for Alefita to review, select the model in the UI, and proceed
- STOP — do not start any task, do not ask questions about the task, do not produce code or substantive analysis
Response template:
"O PreProcessor enriqueceu o prompt. -> enriched_prompt.md Modelo recomendado: X . Rationale: Y Revise o artefato, selecione o modelo na UI e prossiga quando estiver pronta."
Manual Bypass (sent by Alefita in the message)
Signal: Alefita is intentionally skipping enrichment. Execute normally as if the hook did not exist.
Force Enrichment (sent by Alefita in the message)
Signal: Alefita wants enrichment even on a continuation (invocationNum > 0). The hook processes normally. Wait for the enrichment result before proceeding.
The TCG Turn Workflow
The workflow operates in turns, analogous to a trading card game:
Turn 1 (Hook): The hook enriches the prompt via DeepSeek, creates the artifact, injects ephemeralMessage.
Turn 1b (Model): The main agent presents the link, states the recommended model, STOPS and yields control.
[Alefita reviews, selects model in UI, proceeds]
Turn 2 (Hook): invocationNum=1, no force tag -> hook passes through without interference ({}).
Turn 2 (Model): Executes normally with the enriched prompt context.
This turn-based design enforces a human-in-the-loop checkpoint between research and execution. It is the mechanical implementation of Rule 03 (Human Guardrails) — the conversation state IS the incubation phase.
The /enhance Workflow
The preprocessor is invoked via the /enhance workflow, defined in .agents/workflows/enhance.md.
Usage: /enhance <your prompt here>
Execution steps:
- Build the payload JSON with real session values (conversation ID, workspace paths, artifact directory, transcript path)
- Execute the enrichment script via stdin pipe:
echo '<payload_json>' | uv run .agents/plugins/preprocessor/preprocessor.py - Present the result to Alefita with the
file://link, recommended model, and rationale - Wait for Alefita to review the artifact and select the model before proceeding
The workflow description emphasizes: "Do not execute any task until she confirms."
Relationship to Agent Rules
The preprocessor implements several agent rules mechanically:
- Rule 02 (Epistemic Search Protocol): The preprocessor performs the search-before-execute pattern. DeepSeek researches the workspace, transcript, and online sources before the main agent begins.
- Rule 03 (Human Guardrails): The TCG turn workflow enforces the Poincare Incubation principle. The human reviews the enriched prompt before execution begins.
- Rule 05 (Cognitive Steganography): The preprocessor itself uses compressed reasoning patterns when building the enriched prompt — the system prompt template is a form of cognitive framing that shapes DeepSeek's reasoning density.
- Rule 06 (Harness Awareness): The preprocessor operates as a sidecar within the Antigravity 2 harness, using the harness's hook mechanism for invocation.
- Rule 10 (Transcript Primacy): The transcript is explicitly positioned as background context, not prompt. The immutable frame prevents the N-1 bug where transcript content contaminates the prompt.
Relationship to Channel Protocol
The preprocessor's Unicode token signaling operates at a higher level than the channel protocol tokens defined in Rule 04. Where channel tokens (<|channel>, <|think|>, <|tool_call>) manage the tokenizer-level mechanics of reasoning and tool invocation, the Unicode tokens manage the workflow-level mechanics of human-AI coordination.
The two protocols are complementary:
- Channel tokens are invisible to the user — they manage the model's internal state
- Unicode tokens are visible to the user — they manage the conversation's external state
Both protocols share the same design principle: explicit signaling over implicit inference. Just as <|channel>thought\n* must be emitted to activate thinking mode, the Wait Turn token must be emitted to activate the human review checkpoint.
Cross-References
- sdk-test-agent-rules — The behavioral rules this plugin implements
- sdk-test-tools — Batch decompilation scripts that benefit from enriched prompts
- sdk-test-samurai-analogy — How platform classifiers interact with prompt content
- unit-distance-channel-protocol — The tokenizer-level protocol this plugin complements
- unit-distance-steganographic-cot — Cognitive density patterns in enrichment reasoning
- antigravity-2.0 — The harness that hosts this plugin