tirtc-device-builder 0.7.3 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +26 -0
- package/README.md +61 -16
- package/bin/tirtc-device-builder.js +33 -1
- package/package.json +1 -1
- package/skills/tirtc-esp32-builder/SKILL.md +150 -39
- package/skills/tirtc-esp32-builder/USAGE.md +17 -2
- package/skills/tirtc-esp32-builder/VERSION +1 -1
- package/skills/tirtc-esp32-builder/agents/openai.yaml +1 -1
- package/skills/tirtc-esp32-builder/assets/board-audio-contract.example.json +3 -0
- package/skills/tirtc-esp32-builder/assets/board-identity.example.json +16 -0
- package/skills/tirtc-esp32-builder/assets/developer-intake-prompt.md +3 -3
- package/skills/tirtc-esp32-builder/assets/hardware-ir-v2.example.json +9 -1
- package/skills/tirtc-esp32-builder/assets/lckfb-szpi-esp32s3-portable-prompt.md +5 -5
- package/skills/tirtc-esp32-builder/assets/report-template.md +10 -2
- package/skills/tirtc-esp32-builder/assets/tirtc-runtime-contract.example.json +13 -0
- package/skills/tirtc-esp32-builder/knowledge/board-registry.json +4 -0
- package/skills/tirtc-esp32-builder/references/audio-contract.md +8 -0
- package/skills/tirtc-esp32-builder/references/board-knowledge.md +72 -0
- package/skills/tirtc-esp32-builder/references/capability-rules.md +11 -1
- package/skills/tirtc-esp32-builder/references/environment.md +21 -2
- package/skills/tirtc-esp32-builder/references/firmware-delivery.md +83 -0
- package/skills/tirtc-esp32-builder/references/hardware-ir.md +12 -3
- package/skills/tirtc-esp32-builder/references/porting-risks.md +29 -1
- package/skills/tirtc-esp32-builder/references/product-controls.md +76 -0
- package/skills/tirtc-esp32-builder/references/reporting.md +8 -4
- package/skills/tirtc-esp32-builder/references/runtime-contract.md +12 -2
- package/skills/tirtc-esp32-builder/references/tirtc-platform.md +92 -0
- package/skills/tirtc-esp32-builder/references/workflow.md +42 -11
- package/skills/tirtc-esp32-builder/scripts/audio_contract.py +2 -0
- package/skills/tirtc-esp32-builder/scripts/board_registry.py +677 -0
- package/skills/tirtc-esp32-builder/scripts/firmware_identity.py +180 -0
- package/skills/tirtc-esp32-builder/scripts/hardware_ir.py +147 -8
- package/skills/tirtc-esp32-builder/scripts/runtime_contract.py +122 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# TiRTC and ThingConnect platform contract
|
|
2
|
+
|
|
3
|
+
Read this reference when integrating the C SDK, selecting an ESP32 target, or
|
|
4
|
+
implementing H5, AI, device-call or WeChat VoIP.
|
|
5
|
+
|
|
6
|
+
## Authoritative sources
|
|
7
|
+
|
|
8
|
+
- TiRTC documentation: <https://docs.tange.ai/products/tirtc/>
|
|
9
|
+
- C API: <https://docs.tange.ai/products/tirtc/api-reference/c.html>
|
|
10
|
+
- C SDK integration: <https://docs.tange.ai/products/tirtc/guides/sdk-integration/c.html>
|
|
11
|
+
- ESP32-S3 notes: <https://docs.tange.ai/products/tirtc/guides/integration-notes/espressif/esp32-s3.html>
|
|
12
|
+
- ESP32-P4 notes: <https://docs.tange.ai/products/tirtc/guides/integration-notes/espressif/esp32-p4.html>
|
|
13
|
+
- ThingConnect reference platform: <https://github.com/tangeai/tirtc-server-example>
|
|
14
|
+
- Demo platform: <https://demo-open.tange-ai.com/>
|
|
15
|
+
|
|
16
|
+
Use the locked SDK header/build contract and a pinned ThingConnect commit during
|
|
17
|
+
generation. Public pages explain the contract but do not replace the exact files
|
|
18
|
+
used by a build.
|
|
19
|
+
|
|
20
|
+
## SDK lifecycle
|
|
21
|
+
|
|
22
|
+
TiRTC is one process-wide runtime. The exact selected header governs API and
|
|
23
|
+
option availability. For SDK 2.3.0 the important order is:
|
|
24
|
+
|
|
25
|
+
1. Set `TIRTC_OPT_MAX_SEND_BUFFER` before `TiRtcInit()` when overriding it.
|
|
26
|
+
2. Call `TiRtcInit()` once.
|
|
27
|
+
3. Set `TIRTC_OPT_DEVICE_SECRET_KEY`, `TIRTC_OPT_CLIENT_ID`, the discovered
|
|
28
|
+
service endpoint, and applicable network options before `TiRtcStart()`.
|
|
29
|
+
4. Call `TiRtcStart(device_id, &callbacks)` once and wait for
|
|
30
|
+
`TIRTC_EVENT_SYS_STARTED`; return value zero only accepts the request.
|
|
31
|
+
5. Establish or accept connections, then use `TiRtcSendVideoStream()` and
|
|
32
|
+
`TiRtcSendAudioStream()` with the selected complete-frame contract.
|
|
33
|
+
6. Stop sessions and connections through deferred lifecycle work before the one
|
|
34
|
+
final `TiRtcStop()` / `TiRtcUninit()` sequence.
|
|
35
|
+
|
|
36
|
+
The callback table and its context outlive the SDK runtime. Callback payloads
|
|
37
|
+
are borrowed; copy required data into bounded application-owned storage before
|
|
38
|
+
returning.
|
|
39
|
+
|
|
40
|
+
## Product features
|
|
41
|
+
|
|
42
|
+
### H5 live view and talkback
|
|
43
|
+
|
|
44
|
+
The device starts as a listener, accepts the H5 connection, sends the selected
|
|
45
|
+
audio/video streams, receives talkback, and handles refresh/key-frame requests.
|
|
46
|
+
Browser rendering and audible talkback are HIL evidence.
|
|
47
|
+
|
|
48
|
+
### AI intercom
|
|
49
|
+
|
|
50
|
+
Obtain the current AI connection parameters, connect, send `start_session`,
|
|
51
|
+
validate the authoritative session ID and input/output formats, then start
|
|
52
|
+
media. Remote or local `end_session` converges through the runtime task and
|
|
53
|
+
restores the H5 baseline.
|
|
54
|
+
|
|
55
|
+
### Device-to-device call
|
|
56
|
+
|
|
57
|
+
Follow the pinned `device-call.md`: contact authorization, `POST
|
|
58
|
+
/v1/call/request`, incoming MQTT routing, accept through `POST
|
|
59
|
+
/v1/call/device/info`, reject/cancel/hangup, room recovery and `TiRtcConnect`.
|
|
60
|
+
Expose `call <device_id> [video|audio]` only after those paths and conflict rules
|
|
61
|
+
are implemented.
|
|
62
|
+
|
|
63
|
+
### WeChat VoIP
|
|
64
|
+
|
|
65
|
+
Follow the pinned `device-voip.md`: report the device media profile, maintain the
|
|
66
|
+
authorized contact list, route WeChat MQTT events, and use `POST
|
|
67
|
+
/v1/voip/device/call` for device-originated calls. `wxcall [N] [video|audio]`
|
|
68
|
+
selects an authorized contact; it is not a direct SDK API. Mini-program
|
|
69
|
+
authorization and plugin behavior are separate platform acceptance evidence.
|
|
70
|
+
|
|
71
|
+
## Simulator before hardware
|
|
72
|
+
|
|
73
|
+
For the four-feature portfolio, use the pinned Linux C reference implementation
|
|
74
|
+
with file-backed media to prove platform credentials, HTTP/MQTT fields,
|
|
75
|
+
connection tokens, commands and the session arbiter before replacing media with
|
|
76
|
+
board drivers. Record this separately from ESP32 L1-L7 evidence.
|
|
77
|
+
|
|
78
|
+
The managed ESP32-S3 starter may expose fewer businesses than the full reference
|
|
79
|
+
repository. Missing generated modules are implementation work, not permission to
|
|
80
|
+
drop a requested feature or call it verified.
|
|
81
|
+
|
|
82
|
+
## ESP32 targets
|
|
83
|
+
|
|
84
|
+
The current managed generator and Device Kit automate ESP32-S3. Official SDK
|
|
85
|
+
2.3.0 also provides a distinct ESP32-P4 package. P4 needs ESP-IDF 5.5.4, matching
|
|
86
|
+
RISC-V toolchain/build contract, PSRAM, and an evidenced network path such as
|
|
87
|
+
ESP-Hosted with C6/C61 or Ethernet. P4 and S3 archives are not interchangeable.
|
|
88
|
+
|
|
89
|
+
Use FreeRTOS tasks, bounded queues and explicit memory capabilities. PSRAM is
|
|
90
|
+
suitable for large media, fixed pools and eligible background stacks; internal
|
|
91
|
+
RAM remains necessary for DMA descriptors/buffers, ISR-visible state, control
|
|
92
|
+
objects and allocations required while flash cache is unavailable.
|
|
@@ -4,13 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
### Registered board
|
|
6
6
|
|
|
7
|
-
Use this branch when
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
Use this branch only when `board_registry.py match` returns `exact` with
|
|
8
|
+
`safe_registered_reuse=true` and the package has a Hardware IR plus matching
|
|
9
|
+
board adapter.
|
|
10
|
+
|
|
11
|
+
1. Recheck every required runtime probe and reject a changed sensor/codec as a
|
|
12
|
+
new variant.
|
|
13
|
+
2. Validate and assess the saved Hardware IR against the requested features.
|
|
14
|
+
3. Confirm that its BSP, ESP-IDF, TiRTC SDK, business protocol, and adapter
|
|
15
|
+
revisions are still resolvable.
|
|
16
|
+
4. Generate a new starter project without overwriting an existing path.
|
|
17
|
+
5. Install the matching board adapter and configuration overlay.
|
|
18
|
+
6. Build, optionally flash, execute the requested acceptance levels, and issue a fresh report.
|
|
14
19
|
|
|
15
20
|
The branch is complete when the new run has its own build and verification evidence; an older board report is provenance, not proof of the new artifact.
|
|
16
21
|
|
|
@@ -18,10 +23,16 @@ The branch is complete when the new run has its own build and verification evide
|
|
|
18
23
|
|
|
19
24
|
Use this branch when the user supplies a board model, vendor URL, schematic, BOM, pin map, BSP, datasheets, photographs, or peripheral example projects without a verified adapter.
|
|
20
25
|
|
|
21
|
-
1.
|
|
26
|
+
1. Create `board-identity.json`, combine the developer's full model/PCB marking
|
|
27
|
+
with safe SoC/component probes, and query the board registry. Treat different
|
|
28
|
+
revisions or conflicting required probes as different variants. A probable
|
|
29
|
+
or component match supplies hypotheses only.
|
|
22
30
|
2. Freeze the user-supplied product contract: selected video profile, audio/stream formats, duplex/AEC policy, supported Wi-Fi credential methods, selected onboarding method, transport staging, output path, and mutation boundary. Use `unknown` where the prompt lacks an answer.
|
|
23
31
|
3. Prefer official schematic/BOM and BSP facts. For a PDF schematic, inspect page labels and net names; prefer an exported netlist, pin CSV, or vendor board definition when available.
|
|
24
32
|
4. Cross-check critical pins, clocks, power enables, reset lines, sensor/codec variants, ESP-IDF version, resource ownership, and onboarding behavior across at least two independent artifacts when possible.
|
|
33
|
+
For buttons, power keys and enclosure labels, identify the full physical
|
|
34
|
+
product including carrier/PMIC layers; a working control missing from the
|
|
35
|
+
baseboard schematic is a variant or evidence gap, not proof that it is absent.
|
|
25
36
|
5. Create the Hardware IR v2. Use `null` for unknown facts and retain contradictory values as an explicit issue instead of selecting one silently. Store concrete board values in the IR/adapter rather than Skill files.
|
|
26
37
|
6. Validate and run the intake assessment. Classify unresolved facts by their next evidence source: source, implementation, build, HIL, or user input. Ask only for `user_blocked` facts that prevent a safe design. SoftAP is optional when another evidenced Wi-Fi credential method is available, keeps credentials outside source, and defines reprovisioning.
|
|
27
38
|
7. When hardware identity, wiring, product contracts, and an evidenced resource plan reach `READY_TO_PORT`, generate the starter and implement the board adapter. Generate a compile-safe adapter by default when remaining uncertainty is implementation-, build-, or HIL-resolvable. Stop at the IR/report only when missing user evidence or an incompatible dependency makes a safe implementation impossible.
|
|
@@ -46,13 +57,16 @@ Read only the documents for the active branch, but read each selected document c
|
|
|
46
57
|
- ESP32 starter or adapter work: `device-sim/device-sim-esp32/README.md`, `device-sim/ESP32_STARTER.md`, the selected SDK package README, and the generated template README.
|
|
47
58
|
- H5 live view or talkback: `device-h5-live.md`.
|
|
48
59
|
- AI intercom: `device-ai.md`.
|
|
60
|
+
- Device-to-device call: `device-call.md` and the applicable API reference.
|
|
61
|
+
- WeChat VoIP: `device-voip.md`, the mini-program integration document, and the
|
|
62
|
+
applicable API reference.
|
|
49
63
|
- H5/AI switching, delayed callbacks, ownership, or timeouts: `device-session-model.md` and `device-session-arbiter.md`.
|
|
50
64
|
- Onboarding, binding, MQTT, token, or identity: `device-integration.md`.
|
|
51
65
|
- Public HTTP field or error changes: `api-reference.md` and `error-response-policy.md`.
|
|
52
66
|
|
|
53
67
|
## Generation and board seam
|
|
54
68
|
|
|
55
|
-
The runtime-facing `starter_media` interface stays stable. A reusable board integration should implement an internal `BoardMediaAdapterV1`-style adapter owned by `starter_media` rather than editing H5, AI, `starter_runtime`, or `starter_tirtc` for each board.
|
|
69
|
+
The runtime-facing `starter_media` interface stays stable. A reusable board integration should implement an internal `BoardMediaAdapterV1`-style adapter owned by `starter_media` rather than editing H5, AI, CALL, VOIP, `starter_runtime`, or `starter_tirtc` for each board.
|
|
56
70
|
|
|
57
71
|
The adapter owns:
|
|
58
72
|
|
|
@@ -62,13 +76,30 @@ The adapter owns:
|
|
|
62
76
|
- DMA buffers, hardware clocks, power, reset, GPIO, refresh/key-frame requests, and realtime task allocation;
|
|
63
77
|
- bounded stop, resource release, and generation-aware flushing.
|
|
64
78
|
|
|
65
|
-
The stable modules own the discovered TiRTC service endpoint, stream IDs,
|
|
79
|
+
The stable modules own the discovered TiRTC service endpoint, stream IDs,
|
|
80
|
+
negotiated/contracted formats, HTTP/MQTT business fields, TiRTC callback copying,
|
|
81
|
+
connection handles, pending calls, monotonic deadlines, session generation, and
|
|
82
|
+
H5/AI/CALL/VOIP sequencing. SDK lifecycle changes such as disconnect run in a
|
|
83
|
+
worker/state-machine context, never directly inside an SDK callback.
|
|
84
|
+
|
|
85
|
+
A separate product-controls adapter owns physical input setup, debounce,
|
|
86
|
+
boot-held suppression and gestures. It queues bounded intents into the stable
|
|
87
|
+
runtime. It never manipulates TiRTC/session state directly or keeps a competing
|
|
88
|
+
session Boolean. Prefer an atomic runtime-owned toggle intent; when only explicit
|
|
89
|
+
start/stop intents exist, follow
|
|
90
|
+
[product-controls.md](product-controls.md) for snapshot mapping and authoritative
|
|
91
|
+
runtime revalidation.
|
|
66
92
|
|
|
67
93
|
## Verification loop
|
|
68
94
|
|
|
69
95
|
Use a bounded loop per layer: diagnose one failing invariant, make the smallest correction, and rerun that layer before moving forward. Change one high-risk variable per HIL comparison. Turn reusable invariants into tests or post-link gates. Stop and report when the remaining failure requires unavailable hardware, credentials, a new SDK binary, a public protocol change, or a user choice.
|
|
70
96
|
|
|
71
|
-
For every generated H5/AI project, validate `tirtc-runtime-contract.json` and run `install_runtime_gate.py <project>` before the ordinary build. Audio and video projects additionally install their media gates. A build that bypasses any applicable gate is not `BUILD_VERIFIED`.
|
|
97
|
+
For every generated H5/AI/call/VoIP project, validate `tirtc-runtime-contract.json` and run `install_runtime_gate.py <project>` before the ordinary build. Audio and video projects additionally install their media gates. AI/call/VoIP also require the full-duplex AEC result from the audio gate. A build that bypasses any applicable gate is not `BUILD_VERIFIED`.
|
|
98
|
+
|
|
99
|
+
When CALL or VOIP is requested, the runtime contract must also bind the project
|
|
100
|
+
to the pinned business protocol and unified session arbiter. First prove those
|
|
101
|
+
flows with the Linux C simulator. Simulator success establishes the protocol
|
|
102
|
+
baseline but cannot replace the ESP32 build or HIL levels.
|
|
72
103
|
|
|
73
104
|
Run the assessor once per layer:
|
|
74
105
|
|
|
@@ -383,6 +383,8 @@ def verify_contract(contract_path: Path, project_path: Path) -> dict[str, Any]:
|
|
|
383
383
|
f"simultaneous={shared.get('directions_simultaneous')} "
|
|
384
384
|
f"aec={aec.get('enabled', False)}"
|
|
385
385
|
),
|
|
386
|
+
"simultaneous_capture_playback": shared.get("directions_simultaneous") is True,
|
|
387
|
+
"echo_cancellation_enabled": aec.get("enabled") is True,
|
|
386
388
|
"inputs": inputs,
|
|
387
389
|
"errors": errors,
|
|
388
390
|
}
|