with one click
go-ai-upstream-sync
// Sync go-ai with upstream @earendil-works/pi-ai changes — audit upstream version deltas, regenerate models, port API/type/provider changes, update docs, and validate parity.
// Sync go-ai with upstream @earendil-works/pi-ai changes — audit upstream version deltas, regenerate models, port API/type/provider changes, update docs, and validate parity.
| name | go-ai-upstream-sync |
| description | Sync go-ai with upstream @earendil-works/pi-ai changes — audit upstream version deltas, regenerate models, port API/type/provider changes, update docs, and validate parity. |
| distribution | private |
Use this skill when @earendil-works/pi-ai has been updated and go-ai needs to track those changes.
pi-ai version bumptypes.d.ts changes/usr/local/lib/bun/install/global/node_modules/@earendil-works/pi-ai/usr/local/lib/bun/install/global/node_modules/@mariozechner/pi-aigo-ai repo state as canonical for file layout.overflow.go, validation.go, sanitize.go, copilot_headers.go, generate-models.ts, etc.).go test ./... and go vet ./... before pushing.go-ai code before declaring the release synced. Do not treat any release as “just a diff” without this audit.Important current files:
types.goevents.goregistry.gocontext.gotransform.goharness.goenv.gocompat.goretry.gologger.goazure.gosimple_options.goutils.gomodels_generated.godoc.goinference/provider/*/oauth/*.goscripts/generate-models.goscripts/check-logging.shdocs/GAP_ANALYSIS.mddocs/TEST_MATRIX.mddocs/AUDIT_REPORT.mdcat /usr/local/lib/bun/install/global/node_modules/@earendil-works/pi-ai/package.json | jq -r .version
cd /workspace/projects/go-ai
sed -n '1,20p' docs/GAP_ANALYSIS.md
sed -n '1,5p' models_generated.go
cd /workspace/projects/go-ai
git status --short
PI_AI=/usr/local/lib/bun/install/global/node_modules/@earendil-works/pi-ai
find "$PI_AI/dist" -maxdepth 3 -type f | sort
Read at minimum:
package.jsonREADME.mddist/index.d.tsdist/types.d.tsdist/api-registry.d.tsdist/providers/register-builtins.d.tsdist/providers/*.js / .d.tsdist/oauth.d.tsUse the Go generator, not the old TS one.
cd /workspace/projects/go-ai
go run scripts/generate-models.go
go test ./... -count=1
go vet ./...
This picks up:
Compare upstream dist/types.d.ts against:
types.goevents.gocompat.goenv.gosimple_options.goLook for:
KnownApi valuesKnownProvider valuesStreamOptions fieldsCompare upstream registry/types against:
registry.goinit() registrationsLook for:
For each upstream provider under dist/providers/, compare to the Go implementation under inference/provider/.
Current provider mapping:
| go-ai | upstream |
|---|---|
inference/provider/openai/ | dist/providers/openai-completions.* |
inference/provider/openairesponses/ | dist/providers/openai-responses.* |
inference/provider/openaicodex/ | dist/providers/openai-codex-responses.* |
inference/provider/anthropic/ | dist/providers/anthropic.* |
inference/provider/google/ | dist/providers/google.* |
inference/provider/geminicli/ | dist/providers/google-gemini-cli.* |
inference/provider/mistral/ | dist/providers/mistral.* |
inference/provider/bedrock/ | dist/bedrock-provider.* and/or bedrock provider module |
inference/provider/faux/ | dist/providers/faux.* |
Check for:
Compare upstream OAuth surface against oauth/*.go.
Check for:
ModifyModels() behavior changesAfter the mechanical per-version sync, do a deliberate second pass over the upstream release code and the current go-ai code. This is mandatory for every upstream release, including metadata-only, docs-only, patch, and no-op-looking releases. Never declare a release synced until this audit is complete.
The audit must compare the upstream release artifacts/code against the Go implementation, not only the changelog. Start from the release notes when available, then verify each note and any actual code diff against go-ai.
Audit at least:
dist/types.d.ts, dist/index.d.ts, dist/api-registry.d.tsKnownApi, KnownProvider, message fields such as responseId / responseModelStreamOptions / simple options changes (serviceTier, reasoningSummary, timeoutMs, maxRetries, cache/session options)max_tokens, max_completion_tokens, max_output_tokens, prompt_cache_key, prompt_cache_retention, reasoning, reasoning_effort, provider-specific thinking blocks)strict, tool stream flags, tool result names, function call ID normalization)Authorization, X-Api-Key, cf-aig-authorization, Copilot dynamic headers){CLOUDFLARE_*})cached_tokens, cache_write_tokens, prompt_cache_hit_tokens)message_start without message_stop)promptMode vs reasoningEffortModifyModels() equivalents and token refresh behaviorPractical diff commands:
PREV=/tmp/pi-ai-prev/package/dist
NEW=/tmp/pi-ai-new/package/dist
# Surface-level deltas
diff -u "$PREV/types.d.ts" "$NEW/types.d.ts" | sed -n '1,220p'
diff -u "$PREV/providers/openai-completions.js" "$NEW/providers/openai-completions.js" | sed -n '1,260p'
diff -u "$PREV/providers/openai-responses.js" "$NEW/providers/openai-responses.js" | sed -n '1,260p'
diff -u "$PREV/providers/anthropic.js" "$NEW/providers/anthropic.js" | sed -n '1,260p'
diff -u "$PREV/providers/mistral.js" "$NEW/providers/mistral.js" | sed -n '1,220p'
diff -u "$PREV/providers/google-shared.js" "$NEW/providers/google-shared.js" | sed -n '1,220p'
diff -u "$PREV/providers/amazon-bedrock.js" "$NEW/providers/amazon-bedrock.js" | sed -n '1,220p'
diff -u "$PREV/env-api-keys.js" "$NEW/env-api-keys.js" | sed -n '1,160p'
# Focused searches in the new upstream tree
grep -R "responseModel\|prompt_cache\|cache_write\|prompt_cache_hit\|cf-aig\|reasoningEffort\|reasoning_effort\|message_stop\|baseURL\|supportsStrictMode\|maxTokensField" "$NEW"/providers "$NEW"/*.js
For every release and every gap found, either:
docs/AUDIT_REPORT.md and docs/GAP_ANALYSIS.md.The final response/commit notes must explicitly say the complete comparative audit was performed and summarize the result.
Add fake-server or parser tests for high-risk payload/API changes, especially:
responseId, responseModel)Update these when needed:
README.mddocs/basic-usage.mddocs/context-hooks.mddocs/HARNESS.mddocs/model-selection.mddocs/GAP_ANALYSIS.mddocs/TEST_MATRIX.mddocs/AUDIT_REPORT.mdcd /workspace/projects/go-ai
go test ./... -count=1
go vet ./...
go build ./examples/...
CGO_ENABLED=1 go test -race ./... -count=1
./scripts/check-logging.sh
Optional extra pass:
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out | sort -k3 | sed -n '1,120p'
Always sync one patch release at a time, in order.
Do not skip versions. If upstream went from v0.70.0 to v0.70.3, sync v0.70.1 first, then v0.70.2, then v0.70.3 — each as a separate commit + tag.
Why:
git bisect and rollback straightforward.Workflow when multiple releases are pending:
# Check what's available
npm view @earendil-works/pi-ai versions --json | tail -n 10
# Download each release tarball individually
curl -sSL "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-X.Y.Z.tgz" -o /tmp/pi-ai-X.Y.Z.tgz
# Diff against previous, port, test, commit, tag — then repeat for next version
A correct sync pass should usually do all of these when appropriate:
models_generated.go if model metadata changeddocs/GAP_ANALYSIS.md to the new upstream versiondocs/AUDIT_REPORT.md when the deep audit finds residual gaps or intentional divergencesgit tag -a vX.Y.Z -m "Sync with upstream pi-ai vX.Y.Z" and git push origin vX.Y.ZWhen adding or updating a provider:
init()OnPayload if the provider sends request payloads directlyOnResponse where HTTP response headers existRetryConfig for HTTP-based providersErrorEventAt minimum for HTTP providers:
Debug("stream start", ...)Debug("HTTP request", ...)Warn("HTTP error response", ...)Debug("request aborted", ...) or Warn("network error", ...)For retry/reconnect-sensitive paths:
ErrorEventUse a commit like:
Sync upstream pi-ai vX.Y.Z
- regenerated model registry
- updated provider metadata parity
- ported [specific provider/type/oauth] changes
- updated docs/GAP_ANALYSIS.md
If the bump is metadata-only, say so explicitly in the commit body and in docs/GAP_ANALYSIS.md.