
Image Edit
Attribute paid sc-proxy API calls from skill subprocesses to the right user turn and cost ledger when building Starchild-hosted agent skills.
Overview
image-edit (Starchild official-skills) is an agent skill most often used in Build (also Operate) that records sc-proxy credit usage from skill subprocesses into Starchild’s per-turn cost ledger.
Install
npx skills add https://github.com/starchild-ai-agent/official-skills --skill image-editWhat is this skill?
- Stdlib-only helpers—drop into any skill folder without starchild-clawd coupling
- SC-CALLER-ID tagging ties paid calls back to the triggering user turn
- Parses sc-proxy headers X-Credits-Used and X-Credits-Api-Type into the cost ledger
- Graceful fallback when STARCHILD_TOOL_CALLER_ID / USER_TURN_ID env vars are absent
- Optional STARCHILD_COST_LEDGER_DIR override for ledger directory
- Zero third-party dependencies (stdlib only)
- Default ledger directory /data/.starchild/cost_ledger
Adoption & trust: 2 installs on skills.sh; 13 GitHub stars; trending (+100% hot-view momentum).
What problem does it solve?
You run skills that bill through sc-proxy in a subprocess, but your agent’s per-turn cost card never shows those credits because nothing ties the call back to the user turn.
Who is it for?
Indie builders packaging Starchild skills that hit paid APIs from isolated bash subprocesses and need billing parity with in-agent tool calls.
Skip if: Teams not on Starchild/sc-proxy or skills with no metered network calls—skip unless you are wiring subprocess cost attribution.
When should I use this skill?
A Starchild-dispatched skill subprocess calls sc-proxy or other paid APIs via requests and you need per-turn cost_summary alignment.
What do I get? / Deliverables
Paid subprocess calls carry caller IDs, ledger rows match proxy headers, and the parent agent can emit an accurate cost_summary for the turn.
- Ledger rows with credits parsed from proxy response headers
- Caller-tagged paid API requests from skill code
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Cost attribution sits with agent tooling because it wires skill bash subprocesses into Starchild’s per-turn billing and ledger, not a standalone image product. agent-tooling is where skills are dispatched, env vars are injected, and subprocess side effects must reconcile with the parent agent’s cost cards.
Where it fits
Drop the helper next to an image-edit skill so each generation writes credit rows before you ship the skill pack.
Verify launch QA runs show subprocess charges on the same card as orchestrator tools before going live.
Reconcile ledger files under /data/.starchild/cost_ledger when users report mismatched turn totals.
How it compares
Use as a small ledger bridge inside skills, not as a general observability platform or MCP billing server.
Common Questions / FAQ
Who is image-edit for?
Solo and indie developers authoring Starchild official skills that trigger paid sc-proxy requests from subprocesses and need those charges on the same turn-level cost summary as the main agent.
When should I use image-edit?
During Build when wiring image or other paid skills; during Ship or Operate when auditing per-turn credits; whenever a skill uses requests against sc-proxy instead of the agent’s native tool path.
Is image-edit safe to install?
Review the Security Audits panel on this Prism page for the repo snapshot; the helper touches filesystem ledger paths and assumes trusted agent-injected env vars.
SKILL.md
READMESKILL.md - Image Edit
"""Cost tracking helper for skill subprocesses. Skills that call sc-proxy via plain `requests` need to: 1. Tag every paid call with a SC-CALLER-ID that ties it back to the user turn that triggered the skill (so the agent's per-turn cost summary shows the cost in the right cost card). 2. After each call, parse the sc-proxy response headers (`X-Credits-Used`, `X-Credits-Api-Type`) and write a row to the cost ledger that the agent reads back when it builds the SSE `cost_summary` event. This file is intentionally zero-dependency (stdlib only) so it can be dropped into any skill folder without coupling to starchild-clawd internals. Env vars consumed (set by the agent before dispatching the bash subprocess): - STARCHILD_TOOL_CALLER_ID — opaque tag for the current tool call - STARCHILD_USER_TURN_ID — uuid of the current user turn - STARCHILD_COST_LEDGER_DIR — optional override for ledger directory When env vars are absent (e.g. running the script outside an agent), the helpers degrade gracefully: caller-id falls back to a synthetic string so the call still goes through, and ledger writes still happen for audit but the user-turn reader will skip them. """ from __future__ import annotations import fcntl import json import os import time from datetime import datetime, timezone from pathlib import Path from typing import Any, Dict, Optional from urllib.parse import urlparse _DEFAULT_LEDGER_DIR = "/data/.starchild/cost_ledger" # Allowlisted request payload keys we forward into the ledger row's # `details` field. MUST stay in sync with starchild-clawd's # core/http_client._record_cost_to_ledger allowlist — anything not in # that allowlist won't be picked up by the agent and won't render in # the frontend cost card. _PAYLOAD_ALLOWLIST = ( # Identity "model", "provider", # Image geometry "aspect_ratio", "quality", "resolution", "image_size", "size", # Video / motion "duration", "duration_s", "fps", "motion_strength", # Quantity "n", "count", # Generation knobs "seed", "steps", "guidance_scale", "cfg_scale", "strength", "scheduler", "sampler", # Reference / mode hints "image_to_image", "image_to_video", "use_reference", "reference_count", ) def caller_headers(extra: Optional[Dict[str, str]] = None, tool_default: str = "skill") -> Dict[str, str]: """Return an HTTP-headers dict with SC-CALLER-ID filled in. Resolution order: 1. `extra["SC-CALLER-ID"]` (case-insensitive) — caller wins. 2. STARCHILD_TOOL_CALLER_ID env (set by the agent) 3. Synthetic `f"{tool_default}:{int(time.time())}"` — tags the call so charges are attributable to *some* identifier even when the agent didn't inject one (standalone CLI runs, tests, cron). """ merged: Dict[str, str] = dict(extra or {}) has_caller = any(k.lower() == "sc-caller-id" for k in merged) if not has_caller: cid = os.environ.get("STARCHILD_TOOL_CALLER_ID") \ or f"{tool_default}:{int(time.time())}" merged["SC-CALLER-ID"] = cid return merged def record_response(response, request_url: str, request_payload: Optional[Dict[str, Any]] = None, api_type_hint: Optional[str] = None) -> None: """Inspect a sc-proxy response and append a ledger row when paid. Best-effort. Silently no-ops when: - response carries no X-Credits-Used / X-Credits-Api-Type - cost is 0 or unparseable - file write fails Never raises — must not break a real request flow. """ try: headers = getattr(response, "headers", None) or {} used = headers.get("X-Credits-Used") or headers.get("x-credits-used") api_type = (headers.get("X-Credits-Api-Type") or headers.get("x-credits-api-type") or api_type_hint) if not used or not api_type: return try: