Private content composition v0¶
The existing content-ops capability owns video preparation, render attempts
and result readback. The TypeScript owner is
loopx/control_plane/capabilities/content_media.ts. Python handles private
files and transport; the optional loopx-media extension performs specialized
image, audio and video computation. This is a local composition slice, not a
new generic capability or a replacement publication lifecycle.
The active callers are the Agent-facing CLI and the Goal's packaged Content production workbench. A prepared brief is shared between them. The Agent absorbs source discovery, identifiers, hashes and timing. The owner selects a prepared composition, starts/cancels its render and reads the result in place; there is no browser source-directory or JSON-entry step. Lark can convey the request to an Agent but does not gain an independent renderer or upload action.
Plan and source scope¶
content_ops_media_plan_v0 contains:
| Field | Meaning |
|---|---|
title, width, height, fps |
Name and bounded output geometry/clock; dimensions must be even. |
layout_template_id |
Existing content-ops layout template, default monochrome-editorial; style tokens enter the digest. |
shots |
Ordered distinct id, kind, frame-aligned seconds, title, optional body, source_ref, explicit boundary. |
assets |
Distinct id, relative path, exact sha256, image/video/audio, source_ref and local_private/public_safe source classification. |
captions |
Ordered nonoverlapping start, end, text, language cues inside the composition. One sequential caption track is emitted. |
narration |
Explicit silent, supplied with audio asset_id, or system_speech with installed voice and optional words-per-minute. |
Caption text is plain text. Single line breaks are supported; an internal
blank line is refused before preparation because it terminates a subtitle
cue. Use single line breaks or separate timed cues instead. Angle brackets
and entity syntax (such as < or <) are also refused: literal markup
and entity preservation is not qualified for this SubRip export. Write spoken plain text instead. The
renderer repeats these format checks, escapes ordinary ampersands in VTT,
and preserves plain text in SRT and the transcript. This bounded subset is
qualified with the native browser track and real FFmpeg subtitle decoding.
Shots are title, diagram (two to five nodes), excerpt (image/video
asset_id and optional start_seconds) or blender (declarative scene
geometry). These are composition-local rendering choices. They do not extend
Goal/Todo state. Likewise prepared/rendering/ready/failed/cancelled/interrupted
describe private render attempts, never published content or Agent liveness. An
old saved running attempt is shown as interrupted after its bounded execution
window; a read does not restart it.
Preparation takes an explicit local source directory. Absolute paths,
traversal, symlinks and wrong source digests are refused. The prepared record
contains immutable private source copies; editing the original afterward does
not change an admitted composition. No URL is fetched. A source_ref records
provenance supplied by the caller; a public_safe label does not prove rights,
truth, current product behavior or public publication permission.
The canonical digest binds story, sources, source boundaries, layout tokens, geometry, timing, captions and narration. Canonical plans can be revalidated without changing that digest. A changed plan requires the expected revision and invalidates old content approval. Existing layout tokens are reused; static page-density rules do not certify a timed movie or its learning effect.
body is supported for title and diagram shots. Excerpt and Blender layouts
show a title and source boundary, and reject nonempty body text at admission
and rendering. A qualifier must be retained in a supported visible field,
separate title scene or timed caption; it must not silently disappear. Existing
prepared spatial plans with nonempty body now fail explicitly and need a new
revision that preserves that meaning in a supported field.
Execution and readback¶
loopx content-ops media prepare --goal-id example-goal \
--plan-json examples/content-ops-media-brief.json --source-directory . \
--format json
loopx content-ops media render --goal-id example-goal \
--composition-id COMPOSITION_FROM_PREPARE --expected-revision 1 --format json
loopx content-ops media inspect --goal-id example-goal \
--composition-id COMPOSITION_FROM_PREPARE --format json
list discovers the latest 100 private compositions; cancel requires the
current composition and revision. An already running render is returned without
a second effect. Cancel is a request until the worker settles. After a failed,
cancelled, interrupted or damaged attempt, explicit render can retry. Intact
completed bytes are reused. A changed story uses prepare --composition-id …
--expected-revision … first. The render lock spans the actual effect, in
addition to revision-bound record writes.
The existing extension lifecycle owns installation, enablement, doctor,
entrypoint identity and the content_media_write permission. Loading the page
or preparing a plan never installs a provider. Disabled/unavailable extensions
block new effects while preserving prepared sources and verified downloads.
See installation, dependency and disable instructions.
The private content_ops_media_renderer_v0 envelope carries the validated plan,
layout tokens, digest, frame count, immutable snapshots, exclusive attempt
directory and attempt-scoped cancel flag. Only a verified installed extension
receives those paths. The result projection accepts fixed output names and
exact SHA256/byte counts; paths and undeclared provider fields are discarded.
The core reads every actual file before committing ready. Required outputs
are video.mp4, poster.png, captions.vtt, captions.srt and transcript.txt,
plus narration.wav for audible modes. Full decode must match the admitted
timeline, geometry and narration mode. Audio checks report peak and clipped
PCM samples; subjective listening remains untested.
Both plan and output bytes bind the existing content_ops_item_v0. Producing
or re-encoding a movie revises its content digest and clears any approval and
delivery intent. This renderer neither approves nor posts. Publication and
its account/channel/timing/readback remain with the
existing item lifecycle.
HTTP boundary and failure behavior¶
The loopback Chat server exposes POST /api/chat/content-media for list,
inspect, render and cancel. Render/cancel use the current revision; the server
binds the registered Goal/source route and rejects a different selected Goal,
foreign origin or filesystem fields. Rendering runs in a bounded background
worker so the page remains responsive. The packaged production path is Goal →
Files → Content artifacts, reached from the existing Goal conversation. Capability
settings do not host production or reference workbenches. Returning to the
conversation retains its Goal and does not send a message. Delivery requirements
and checks reuse the existing Goal acceptance owner used by non-media artifacts;
this media transport owns neither generic acceptance nor a second approval store.
This route remains Goal-scoped; ordinary project conversations without a Goal
are not silently assigned one.
Reading saved work does not start polling. An explicit render observes its own pending operation until terminal readback, a failed read or leaving the view; opening a previously pending record only reads saved state. Stopping observation does not cancel the renderer or a cloud operation.
GET /api/chat/content-media/file serves only fixed verified files from that
composition, with byte ranges for playback, no-store and same-origin resource
policy. It refuses escaping filenames, non-ready and damaged artifacts; it
does not serve the private manifest or source files. Browser error projections
do not include provider stderr or private paths.
New preview/download links include both revision and the exact file sha256.
The transport validates the current record revision and hashes the opened file
descriptor before serving a full or ranged response. Missing, duplicated or
invalid version fields, a changed composition revision and different bytes are
unavailable; a prior link cannot silently return a replacement. Immutable image
and footage records retain their separate original identities. Both version
fields are optional together for compatibility with existing verified current-file
links. Neither form certifies creative quality, independent review or acceptance.
中文:制作与预览从当前 Goal 的“成果 → 内容作品”进入,设置页仅保留配置。 “返回当前对话”不发送消息;交付检查复用已有 Goal 验收,不增加媒体私有审批。 此入口尚不支持无 Goal 的普通项目对话,也不会自动创建 Goal。预览与下载绑定修订和 文件摘要;旧修订或不同字节不会被静默替换。浏览保存状态不启动制作、生成或轮询。
Missing provider, changed source, stale revision, text/glyph overflow, short footage, invalid narration timing, cancellation, stopped host and damaged bytes remain distinguishable from success. Repair the source/brief as a new revision or repair the existing extension and retry. No failure creates publication authority, fills missing footage, infers a creative pass or changes a Goal.
Mechanical rendering, creative quality, audience understanding and operations impact have separate evidence. The optional generated-footage path below shares this owner; interactive learning and other providers are not silently activated by this protocol.
impact have separate evidence. Generated image/video assets and footage from authored HTML, game or mini-world works can reuse this source-bound composition path. Choose their authoring tools for the requested work; a new form does not require another core workbench or activate an unconfigured provider.
Blender shot and project readback¶
The optional loopx-media provider can compute a blender shot inside the same
composition. scene is a bounded declarative object: an orthographic camera
with start/end position and target, box/sphere objects with material values
and optional position keyframes, area lights and connections between object
IDs. The shared content_media TypeScript owner validates it; provider Python
does not choose the work, sources, publication state or execution authority.
See the runnable synthetic example
and activation/recovery guide.
Scene IDs and geometry are bound to the plan digest. Position keys must start at frame 1, end at the scene's final frame and increase strictly; the first position must match the object's declared initial position. A scene supports at most 16 primitives, 3 lights, 24 connections and 120 frames. At most 3 Blender scenes fit inside a composition. Existing dimension/timeline/output/process bounds apply unchanged. Arbitrary scripts, uploaded blend files and external asset references are rejected. Ordinary scene-free plans retain their existing normalized structure and digest.
Blender 4.5 LTS/Cycles/CPU produces actual RGBA and depth PNG sequences; depth is
16-bit Z distance normalized over 0–50, with farther values clamped. A fresh
process opens the saved blend with scripts disabled and checks its geometry,
animation, camera and timeline. Ready results additionally require the exact
admitted scene IDs/frame counts, both complete passes, reopen checks and the
fixed blender-project.zip artifact. The archive contains relative-path blend
projects, exact scene inputs, the replay builder and frames. It is subject to
the same digest/readback/download scope as the movie; it cannot be attached
to a scene-free result to bypass admission.
The existing workbench renders/cancels/retries the composition and exposes the verified project download. Installation of the Blender extra is explicit; missing bpy does not disable ordinary 2D work. A failed 3D attempt retains its prepared input and supports retry after dependency repair. No fallback replaces 3D with a code projection. Mechanical readiness still does not establish creative quality, audience understanding or publication approval.
Optional cloud-footage intents¶
content-ops generation prepare/submit/check/collect/inspect/list/cancel uses
the existing Goal-scoped media workspace and optional loopx-media provider.
The shared content_media_generation TypeScript owner validates immutable
content_ops_generation_plan_v0 drafts, quote freshness/nominal bounds,
reference roles and source scope, task identity, observations and collection.
Python adapts file snapshots and one provider effect; it does not choose work,
infer publication approval or start a scheduling loop.
The existing runtime protocol accepts additive generation.* operations only
through the separately declared content_media_generate permission. A normal
render request is unchanged and has no network/account effects. The bounded
video provider supports Seedance 2.5; the separate single-image path is described below.
Other models and unopened account access remain unavailable. Setup, process-local credentials,
supported frames, prices and recovery are in the
provider guide.
The parent commits submitting before POST. A successful response is only
submitted, not an observed queued/running worker. A provider-side fsynced
journal binds the returned task id to the plan digest before stdout returns.
An explicit check can recover that id after a stopped parent. If the response
was lost before an id could be saved, the intent stays submission_unknown;
neither reload nor repeated submit creates a new paid task. Reconciliation of
an unknown external effect precedes any new generation decision.
Cloud succeeded means collection is possible, not local artifact readiness.
Collection obtains a current expiring URL, downloads within origin/time/byte
bounds, fully decodes the movie, measures duration and hashes the fixed
generated.mp4, poster.png and optional last-frame.jpg outputs. The core
checks those bytes before projecting ready. Download URLs, API credentials,
private paths and raw provider responses never enter browser projections.
Reference alpha preprocessing retains original and transmitted hashes. The
returned token count, caller-supplied rate estimate and unknown invoice remain
distinct; the nominal estimate bound is not a guaranteed maximum bill.
The existing /api/chat/content-media accepts generation_list and
revision-bound generation_submit/check/collect/cancel actions. Its file route
accepts exactly one generation or composition id, serves only verified fixed
artifacts and retains selected-Goal, origin, byte-range and no-store rules.
The shipped workbench shows draft/consequence, submission, bounded optional
status checking, errors and saved files through this backend. Pure list/inspect
reads never call the cloud. Automatic browser checks stop after five minutes,
on a terminal observation or when the owner stops them; they never POST a job.
The five-minute window uses elapsed monotonic time across status changes and
in-flight reads. A failed read, Goal change or unmount stops further checks.
Stopping observation leaves any already-sent request and cloud task intact.
Both providers share the package's atomic journal writer. It retains file flush/fsync and same-directory replacement on supported platforms, and syncs the directory on POSIX only; Windows never attempts a CRT directory open. POSIX directory-sync failures remain visible rather than being ignored.
Ark DELETE has no documented atomic queued-only precondition and can erase a
task that finishes between GET and DELETE. cancel therefore reads the
original task and reports atomic_cancellation_unavailable, without deleting
it or claiming that local observation stopped remote usage. The same limitation
is visible in the workbench. Failed/expired/cancelled states, unavailable
observation, unknown submission and damaged local artifacts remain separate.
Creative quality, continuity, visible watermark, audience comprehension and
actual billed cost require their own evidence; no generated clip changes
content publication state.
Optional single-image intents¶
content-ops image prepare/submit/collect/inspect/list shares this capability,
Goal-local workspace and optional provider. The content_media_image TypeScript
owner validates content_ops_image_plan_v0, its immutable digest, a dated
per-image nominal quote and local transitions. Provider-specific account access
is checked separately. This is a synchronous image request, not a video job:
there is no task ID, cloud status polling or remote cancellation contract.
The plan contains title, pinned model, prompt, explicit width/height,
watermark, zero or one references entries and quote. A reference binds its
relative path, exact sha256, opaque source_ref and explicit public_safe
classification. Quote fields are cny_per_image, timezone-aware checked_at,
official source_url and max_estimated_cny. The quote must be current within
24 hours and fit the declared nominal bound; it is neither authorization nor
a guaranteed maximum bill. Supported model, dimensional/upload limits,
separate image credential and lifecycle setup are in the
provider guide.
The parent persists submitting before the optional provider effect. The
provider journals the intent before POST, then fsyncs a private response cache
before returning. Exact received HTTP bytes, digest and request-ID observations
are private, bounded recovery evidence; interpretation failure can be retried
locally from that saved response. Loss before response persistence cannot be
recovered by issuing another POST. Missing provider/key keeps prepared; confirmed provider
rejection remains rejected; an unconfirmed effect remains
submission_unknown. None of these states permits automatic paid retries.
collect recovers only cached bytes, without network activity. An intact ready
result is reused; damage can be repaired from the original response, with the
original accepted SHA preserved. Unknown external effects without cached bytes
require reconciliation before choosing any new intent.
The result binds exactly one generated image to the request model and digest,
full PNG decode and requested geometry. The core verifies original.png and
normalized generated.png bytes/hashes before readiness or download. Reported
generated-image/token counts, caller's nominal estimate and unknown invoice
remain distinct. Watermark request, visual watermark inspection and creative
acceptance are separate. Source metadata and returned paths are not exposed.
The existing HTTP route adds image_list and revision-bound
image_submit/collect. The fixed-file route accepts exactly one composition,
generation or image ID and preserves selected-Goal, origin, byte-range and
no-store boundaries. The packaged workbench can generate an Agent-prepared
intent, display unavailable/unconfirmed states, recover saved bytes and show
verified image/downloads. It never requests arbitrary local paths or a key.
Reuse a resulting image as an ordinary hash-bound composition asset, retaining
its illustration boundary and adding precise text through local rendering.
This path does not approve or publish content, qualify learning effects or
change long-horizon Goal state.
Per-shot picture framing¶
An excerpt or blender shot can opt into framing: "full_frame" with
loopx-media 0.3.0. The source fits the available width/height without cropping
or changing its aspect ratio; a small image may be enlarged. Its complete
boundary is wrapped in a separate measured strip below the picture. Neither
that strip nor the optional player captions are baked over source pixels.
The shot title remains timeline/source metadata; put a title that the viewer
must see in the source artwork, a title shot or timed captions. The fixed studio
header, drawn shot title and progress bar are omitted for this shot. The
selected layout's background/text tokens still apply. This is a rendering
choice, not an audience-understanding or creative-quality judgment.
Omitted framing and explicit "editorial" normalize to the original plan
structure and retain the existing digest/layout. Other values and framing on
non-spatial shot kinds are refused. Nonempty spatial body remains refused.
Full-frame framing changes the source-bound digest and needs a new revision;
it cannot inherit earlier content approval. The result additionally requires
qa.full_frame_shots to match the admitted ordered shot IDs. An older provider
that ignores the field cannot produce a ready result; explicitly upgrade the
optional package/manifest and retry after doctor. Default framing remains
compatible with the older provider. No core setting or global installation is
changed by preparing a full-frame plan.
The Agent prepares this choice in the same brief; the packaged workbench shows “Full frame” beside its timeline/source entry and renders, cancels, retries and reads back the same composition. Users do not enter source paths or JSON again. Disabling the existing extension blocks new renders and keeps verified movies readable. To return to editorial framing, prepare a revision without the field and render it; an older LoopX core will refuse a plan containing the new field.
中文:excerpt 与 blender 镜头可选 framing: "full_frame"。素材按原比例
完整放入较大的画面区,必要时放大;来源说明在独立底栏完整换行,工作室页眉、
片内标题和进度条不再绘制。标题仍在分镜与来源信息中,需要观众看到的标题由素材、
标题镜头或字幕承载。省略该字段或显式选择 editorial 保留原计划摘要与构图。
此选项需要显式升级 loopx-media 0.3.0、注册新 manifest 并运行 doctor;旧渲染器
若忽略新字段,结果会被拒绝就绪。修改构图需新修订,仍会撤销旧内容批准。
工作台沿现有入口显示“大画面”并制作、取消、重试和查看;停用扩展阻止新制作但
保留已校验影片。回到旧构图时,移除字段后保存新修订再制作;旧版核心不会接受
含新字段的计划。该选项不改变来源可见性、发布权限或全局配置。
Authoring and comparison practice¶
The existing brief, revision and verified-file operations support this practical
author workflow. These are creative decisions; ready retains the mechanical
contract above.
Start with the audience, message and factual source revision. Give each scene a communication job, then choose the form that serves it: readable 2D for exact guidance, actual interface states for product evidence, or authored spatial and interactive scenes when their relationships or actions help. A film need not contain every available technique. Keep edited, synthetic and illustrative material identified; an association, screenshot or source label does not prove an outcome. Preserve missing links and other qualifiers when reframing a source.
Inspect the result at its intended viewing size. A source that fits its frame can still have unreadable text. For supplied artwork, resolve transparency on the intended background and inspect any crop before encoding. Titles that must be seen belong in supported visible content. Player captions, exported subtitle files and words drawn into source pixels are different deliverables. Check the actual speech and caption windows too: a system speech rate parameter does not establish the resulting phrase duration, naturalness or comprehension.
Revise the work in response to an observed problem, keeping the earlier version and the reason for the change. Controlled excerpts answer a narrow question only when the compared script, sources, timing and other relevant conditions are recorded. Fully developed films may deliberately change those conditions to serve the same brief. Review each complete film for message, picture, sound, pacing, readability, possible misreadings and task fit; do not align different scripts at the same timestamp or infer a universal medium ranking. Record author judgment separately from independent audience observations. No audience evidence means no audience conclusion.
Keep research, setup, paid calls, failed attempts, rework, rendering and review in the cost account. A timed render is one stage; missing costs stay unknown. Retain an editable project and its sources beside the verified outputs. A portable handoff benefits from an actual download, extraction and revised export, including playback seeking when comparison depends on it. Reusing a technique in the next requested work tests that specific reuse; it does not by itself establish audience benefit or lower total cost. Publication remains with the existing content-item lifecycle.
中文:以下为创作建议,ready 仍代表上述机械合同。先明确读者、表达目的和事实版本,
再给镜头分配叙事作用,按作用选二维、
实际界面、空间或交互场景,不必把所有形式塞进一部片。重构图时保留缺口与限定,
不把截图、关联或来源标签当结果证明。在实际观看尺寸检查文字、透明背景、裁切、
可见标题及声音/字幕时序;播放器字幕、导出的字幕文件和素材内文字分别核对。
系统语速参数不等于实际句长、自然度或理解效果。
按观察到的问题实质改稿,保留旧版与修改原因。同条件片段用于回答具体问题, 充分发展的整片允许按同一 brief 重写,但要记录脚本、来源、时序等混杂,不能 将异稿按同秒伪装对照。分别审阅表达、画面、声音、节奏、可读性、误读与任务适用性, 区分作者判断和独立观众证据;没有观众证据就保留未知。成本包含调研、搭建、 付费调用和失败、返工、渲染、审核,不把局部计时当总成本。保留可修改工程及来源, 可通过实际下载、解压、改稿导出和所需的播放寻址核对交付。下一作品的真实复用只证明 该次复用, 不自动证明理解收益或提效;原生就绪和发布权限的含义保持。