Skip to content

fix: README 5-minute tutorial inaccuracies (closes #51)#121

Merged
KunalJavelin merged 4 commits intomainfrom
fix-readme-inaccuracies-51
May 6, 2026
Merged

fix: README 5-minute tutorial inaccuracies (closes #51)#121
KunalJavelin merged 4 commits intomainfrom
fix-readme-inaccuracies-51

Conversation

@rsharath
Copy link
Copy Markdown
Contributor

@rsharath rsharath commented May 5, 2026

Summary

Closes #51. Fixes the three remaining points in @safayavatsal's documentation report:

  1. There are several references to a ghost function `build_jwt_assertion`, this does not appear to exist in ZeroID.
  2. In step 2 of the 5 minute tutorial (Delegate to a Sub-Agent). We do not have an example in typescript, only python.
  3. The python example in step 2 references a variable `sub_agent_private_key`, but it is not shown how this is generated.

(Points 1 and 2 — `@highflame/zeroid` → `@highflame/sdk` package name + import — were fixed in a prior README pass and are already on main.)

Changes

All in README.md. No code changes.

Step 2 — Delegate to a Sub-Agent

  • Inlined generate_ec_keypair and build_jwt_assertion helpers at the top of the Python snippet so readers can actually run the tutorial. Both use only the cryptography stdlib package. A pointer to the production-grade reference at examples/openclaw/agent-identity-sidecar.py:450 lives above the snippet — that file does the same DER → IEEE P1363 signature conversion ES256 requires, with full validation.
  • Showed sub_agent_private_key being generated via the new generate_ec_keypair() helper. The public PEM is registered with ZeroID in client.agents.register(public_key_pem=...); the private PEM stays with the agent.
  • Added a parallel TypeScript snippet using the jose package (SignJWT, generateKeyPair, exportJWK, importJWK) plus node:crypto for the JWK → SPKI PEM conversion needed for agents.register. Same flow as the Python version, byte-for-byte equivalent ES256 assertion.

Pattern 3 / Pattern 4 — multi-agent and user-delegation examples

  • Fixed the argument order: previous calls were build_jwt_assertion(wimse_uri, private_key) (the ghost function's fictional signature). Now build_jwt_assertion(private_key, wimse_uri) to match the inlined helper.
  • Added explicit generate_ec_keypair() calls so the *_private_key variables don't appear from nowhere.
  • Added a # build_jwt_assertion is defined in §2 above. back-reference at the top of each example so a reader landing mid-document knows where to find the helper.

What's NOT in this PR

  • Adding build_jwt_assertion to the Python or TypeScript SDKs would be the proper long-term fix — the helper is generic enough that every consumer will reinvent it. That's a separate PR against @highflame/sdk (Python) and @highflame/sdk (npm), which live outside this repo. Filing a follow-up issue is reasonable; for now, the inlined helper unblocks tutorial readers.

Test plan

  • Python snippet matches the production-grade build_actor_assertion at examples/openclaw/agent-identity-sidecar.py:450 (same DER → P1363 conversion, same JWT shape).
  • TypeScript snippet uses standard jose + node:crypto APIs that are stable in Node 18+.
  • All build_jwt_assertion call sites in the README now use the new (private_pem, wimse_uri) signature consistent with the helper definition (was previously (wimse_uri, private_key) — wrong order, fictional helper).
  • No code changes; integration suite unaffected.

Issue #51 reported five problems in the Quick Start / 5-Minute Tutorial.
Two were already fixed (the @highflame/zeroid → @highflame/sdk package
name correction and the corresponding TS import). Three remained:

3. `build_jwt_assertion` was a ghost function — referenced 5 times in
   the README but defined nowhere in the SDK or codebase. Tutorial
   readers couldn't actually run the snippets.

4. Step 2 (Delegate to a Sub-Agent) had a Python example but no
   TypeScript example, breaking parity with the rest of the tutorial.

5. The Python example in step 2 referenced a `sub_agent_private_key`
   variable but never showed how to generate it.

## Fix

- Defined `generate_ec_keypair` and `build_jwt_assertion` inline at the
  top of step 2's Python snippet, with a pointer at the production-grade
  reference (examples/openclaw/agent-identity-sidecar.py:450) that does
  the full DER → IEEE P1363 signature conversion ES256 requires.
- Added a parallel TypeScript snippet using the `jose` package's
  SignJWT + generateKeyPair / exportJWK helpers, mirroring the Python
  flow byte-for-byte (header + payload + sign).
- Updated the multi-agent example (Pattern 3) and the
  authorization_code example (Pattern 4) to match the new helper
  signature `build_jwt_assertion(private_pem, wimse_uri)` (was the
  arguments-flipped fictional version) and added explicit
  `generate_ec_keypair()` calls so a reader can actually run them.
- Added back-references in the later examples noting the helpers were
  defined in §2.

No code changes — README only.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the README.md to provide complete, runnable examples for sub-agent registration and token exchange. It introduces Python helper functions for key generation and JWT signing, adds a corresponding TypeScript example, and updates existing snippets for consistency. Review feedback suggests adding descriptive comments to the TypeScript example for parity with the Python version and fixing an undefined variable in the Pattern 4 Python snippet.

Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
rsharath and others added 3 commits May 5, 2026 16:12
- TypeScript ZEROID_ISSUER: add 'set to your ZeroID base URL' comment for
  parity with the Python snippet.
- TypeScript subAgent registration: annotate public_key_pem with
  'required for token_exchange' for parity with Python.
- Pattern 4 (authorization_code): generate the assistant's keypair
  explicitly with generate_ec_keypair() so assistant_private_key does
  not appear from nowhere; widen the cross-reference comment to mention
  both helpers.
@KunalJavelin KunalJavelin merged commit 8843988 into main May 6, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inaccuracies in README.md

2 participants