diff --git a/services/heretic2-nvfp4-quant/extract_soong_tools.py b/services/heretic2-nvfp4-quant/extract_soong_tools.py new file mode 100644 index 0000000..8fffc96 --- /dev/null +++ b/services/heretic2-nvfp4-quant/extract_soong_tools.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +"""Extract soong-lab's live 9 design-tool schemas as OpenAI-function form. + +Run inside the deployed soong-lab venv (backend/.venv) with cwd=backend so +`soong_lab` imports. Monkeypatches register_tool to capture each tool's +name/input_schema/description at registration (handlers are never invoked, so +dummy store/portrait_service are fine). Emits a `tools` array in the shape the +NVFP4 calib tool-call-XML slice needs (brokkr R36 spec, 2026-07-14). +""" +import json +import soong_lab.bifrost.tools as T + +captured = [] + + +def _fake_register_tool(registry, name, input_schema, handler=None, description=None, **kw): + captured.append({ + "type": "function", + "function": { + "name": name, + "description": description or "", + "parameters": input_schema, + }, + }) + + +T.register_tool = _fake_register_tool + + +class _Dummy: + def __getattr__(self, k): + return _Dummy() + + def __call__(self, *a, **k): + return _Dummy() + + +T.register_design_tools(_Dummy(), _Dummy(), _Dummy()) + +out = "/tmp/soong_tools_v0313.json" +with open(out, "w") as f: + json.dump(captured, f, indent=2) +print(f"captured {len(captured)} tools -> {out}") +print("names:", [c["function"]["name"] for c in captured]) diff --git a/services/heretic2-nvfp4-quant/soong-tools-v0.3.13.json b/services/heretic2-nvfp4-quant/soong-tools-v0.3.13.json new file mode 100644 index 0000000..a28679d --- /dev/null +++ b/services/heretic2-nvfp4-quant/soong-tools-v0.3.13.json @@ -0,0 +1,222 @@ +[ + { + "type": "function", + "function": { + "name": "set_name", + "description": "Set the agent's name (its display name; export slugifies it).", + "parameters": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 128 + } + }, + "required": [ + "name" + ], + "additionalProperties": false + } + } + }, + { + "type": "function", + "function": { + "name": "set_role", + "description": "Set the agent's model-role \u2014 one of: assistant (general), thoughtful-assistant (reasoning general), character (RP/writing-tuned), thoughtful-character (reasoning RP). Export ships it as the native agents.define `role`.", + "parameters": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "assistant", + "thoughtful-assistant", + "character", + "thoughtful-character" + ] + } + }, + "required": [ + "role" + ], + "additionalProperties": false + } + } + }, + { + "type": "function", + "function": { + "name": "set_ocean", + "description": "Merge OCEAN dials (each in [-1,1]); re-derives the disposition.", + "parameters": { + "type": "object", + "properties": { + "O": { + "type": "number", + "minimum": -1, + "maximum": 1 + }, + "C": { + "type": "number", + "minimum": -1, + "maximum": 1 + }, + "E": { + "type": "number", + "minimum": -1, + "maximum": 1 + }, + "A": { + "type": "number", + "minimum": -1, + "maximum": 1 + }, + "N": { + "type": "number", + "minimum": -1, + "maximum": 1 + } + }, + "minProperties": 1, + "additionalProperties": false + } + } + }, + { + "type": "function", + "function": { + "name": "edit_prompt", + "description": "Replace the authored role/instructions block (the exported system prompt).", + "parameters": { + "type": "object", + "properties": { + "system_prompt": { + "type": "string", + "minLength": 1, + "maxLength": 32768 + } + }, + "required": [ + "system_prompt" + ], + "additionalProperties": false + } + } + }, + { + "type": "function", + "function": { + "name": "attach_tool", + "description": "Attach (upsert by id) a tool the designed agent will bind via Bifrost.", + "parameters": { + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 256 + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 256 + }, + "description": { + "type": "string", + "maxLength": 2048 + } + }, + "required": [ + "id", + "name" + ], + "additionalProperties": false + } + } + }, + { + "type": "function", + "function": { + "name": "author_first_message", + "description": "Set the agent's in-character opening turn (tone + format by example).", + "parameters": { + "type": "object", + "properties": { + "first_message": { + "type": "string", + "minLength": 1, + "maxLength": 32768 + } + }, + "required": [ + "first_message" + ], + "additionalProperties": false + } + } + }, + { + "type": "function", + "function": { + "name": "edit_psych_profile", + "description": "Author the character's Psychological Profile & Experience \u2014 a ~150-300 word prose lens (the self-report producer reads it every turn) covering four dimensions: disposition/appraisal bent, attention/salience focus, values/yardstick, and formative history. Integrate them as one paragraph and CLOSE ON ATTENTION \u2014 what the character characteristically notices ('...notices who is unwell, what is left unsaid'). Guardrails: (1) NEVER name a per-event output emotion ('is anxious', 'feels hurt') \u2014 naming PRIMES it, so it fires regardless of the event; describe the bent and let emotion follow from the appraisal. (2) Magnitude lives in the OCEAN dials, not the prose (don't narrate 'comes apart'/'takes it hard'). (3) Appraisal-STYLE yes ('reads others charitably until she can't'), output-emotion no. (4) Salience is character-relative \u2014 never rewrite what happened.", + "parameters": { + "type": "object", + "properties": { + "psych_profile": { + "type": "string", + "minLength": 1, + "maxLength": 8192 + } + }, + "required": [ + "psych_profile" + ], + "additionalProperties": false + } + } + }, + { + "type": "function", + "function": { + "name": "generate_portrait", + "description": "Generate the agent's persona portrait NOW from a visual `description` you author \u2014 the persona's LOOK (e.g. 'a stern woman in her 40s, short dark hair, sharp jaw'). A persona is personality, not appearance, so YOU compose the appearance in conversation and pass it here; describe only the subject, never the art style. `style_mode` (anime | cartoon | photoreal) selects the curated render style \u2014 the style preset owns the look. Generation runs in the background; the portrait pane shows it when ready. Offer/generate a portrait once the look is settled.", + "parameters": { + "type": "object", + "properties": { + "description": { + "type": "string", + "minLength": 1, + "maxLength": 500 + }, + "style_mode": { + "type": "string", + "enum": [ + "anime", + "cartoon", + "photoreal" + ] + } + }, + "required": [ + "description" + ], + "additionalProperties": false + } + } + }, + { + "type": "function", + "function": { + "name": "export", + "description": "Export the native payload + sidecar bundle (stub \u2014 lands in E5).", + "parameters": { + "type": "object", + "properties": {}, + "additionalProperties": false + } + } + } +] \ No newline at end of file