Skip to content

genx/transformers: separate StreamKit and provider packages - #370

Merged
idy merged 16 commits into
mainfrom
codex/issue-362-provider-packages
Jul 20, 2026
Merged

genx/transformers: separate StreamKit and provider packages#370
idy merged 16 commits into
mainfrom
codex/issue-362-provider-packages

Conversation

@idy

@idy idy commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

  • move Doubao AST, Realtime, Realtime Duplex, ASR/TTS, DashScope Realtime, and MiniMax TTS implementations out of the flat transformers package into package-owned typed constructors
  • replace the misleading agentkit package with provider-neutral internal/streamkit lifecycle primitives and delete the unused response-wrapper layer
  • keep ASR, TTS, AST, and Doubao Realtime Dialogue outside the Toolkit boundary while preserving per-Transform session isolation and concurrent use
  • move public TTS container normalization to audio/codecconv, cut all repository consumers over directly, and retain no compatibility wrappers
  • add StreamKit lifecycle/race coverage, direct provider E2E coverage, and bilingual final-state documentation

Validation

  • go test -race ./pkgs/genx/transformers/internal/streamkit/... ./pkgs/genx/transformers/doubaoasr/... ./pkgs/genx/transformers/doubaotts/... ./pkgs/genx/transformers/doubaoast/... ./pkgs/genx/transformers/doubaorealtime/... ./pkgs/genx/transformers/doubaorealtimeduplex/... ./pkgs/genx/transformers/dashscoperealtime/... ./pkgs/genx/transformers/minimaxtts/...
  • go test -run '^$' -tags gizclaw_genx_e2e ./tests/genx-e2e/...
  • go test -count=1 -v -tags gizclaw_genx_e2e ./tests/genx-e2e/transformer -run '^(TestDoubaoSAUCASR|TestDoubaoSeedV2TTS|TestMiniMaxTTS)$' (all three live provider cases passed without skip)
  • go test -count=1 -v -tags gizclaw_genx_e2e tests/genx-e2e/transformer/doubao_realtime_duplex_test.go -run '^TestDoubaoRealtimeDuplexConversation$' (two live rounds passed with transcript, assistant text/audio, interruption, and session restart)
  • go test ./...
  • go vet ./pkgs/audio/codecconv/... ./pkgs/genx/modelloader/... ./pkgs/genx/transformers/... ./pkgs/gizclaw/services/ai/openaiapi/... ./pkgs/gizclaw/services/ai/peergenx/...
  • npm --prefix guides ci && npm --prefix guides run build:site
  • all nested Go modules: go mod tidy -diff and GOFLAGS=-mod=readonly go test -count=1 ./...
  • StreamKit/provider static acceptance checks and git diff --check
  • bash tests/gizclaw-e2e/run_tests.sh ran for 1,693 seconds: all live AST, Doubao Realtime, Flowcraft, push-to-talk, realtime, history, auto-split, and interrupt phases passed; the overall command remains nonzero only for pre-existing chat unit test TestVerifyAssistantAudioASRIgnoresFailedTailAfterExpectedTextIsCovered, reproduced unchanged on main

Fixes #362
Closes #404

Move AST, Doubao realtime and Duplex, and DashScope realtime provider runtimes and tests into typed packages.\n\nCut model loader, peer GenX, E2E callers, and docs over to the package constructors while preserving per-call sessions and stream lifecycle behavior.\n\nFixes #362
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

@codex review

Remove checksums that are no longer reachable after moving realtime provider dependencies out of the root transformers package.
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2dd78c7db5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkgs/genx/transformers/doubaorealtime/implementation.go
Document the package-specific Config and New entry points required by issue 362 instead of promising deleted flat constructors.
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 1ac570c3f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

The agentkit name mixed provider-neutral Stream lifecycle with agent/tool
ownership, while the remaining ASR and TTS adapters still lived in the flat
transformers package.

- Move buffering, response lifecycle, interruption, and shared TTS processing into internal/streamkit
- Give Doubao ASR/TTS and MiniMax TTS package-owned typed constructors with per-call state
- Cut repository consumers over without compatibility wrappers and move audio normalization to codecconv
- Add race coverage, direct provider E2E coverage, and final bilingual package documentation
@idy idy changed the title refactor(genx): move provider implementations into packages genx/transformers: separate StreamKit and provider packages Jul 20, 2026
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

@codex

Remove stale provider and audio transitive checksums after the transformer package split changed the example module dependency graph.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

// It does not configure tools or function-call execution.

P1 Badge Restore Realtime Duplex tool wiring

When callers construct Doubao Realtime Duplex sessions that need provider tools, this new public Config has no way to pass []doubaospeech.RealtimeDuplexFunctionTool into the transformer, even though realtimeConfig still sends t.tools to Session.Tools and the pre-split API exposed WithDoubaoRealtimeDuplexTools. Those sessions now always start with an empty tool list, so function-call/toolkit flows cannot be advertised to the provider; add a Tools field and wire it through withTools in New.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

idy added 2 commits July 20, 2026 13:23
Expose provider-native function declarations through the typed Realtime Duplex Config, wire them into each provider session, and deep-copy nested schema data at construction time.
Ignore delayed terminal events from an already interrupted response when collecting the next Realtime Duplex round, while preserving errors for the active round.
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

Addressed the Realtime Duplex tool-wiring P1 in f86939d: the typed Config now exposes provider-native Tools, New wires them through to each session, and nested tool schemas are defensively copied. The follow-up E2E collector fix in 6ffa51f correlates delayed interrupted EOS events by StreamID.

@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

@codex review

Ignore only delayed errors from prior Stream IDs so normal assistant output remains observable while the next realtime round is collected.
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 6ffa51fdeb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Role: genx.RoleModel,
Part: genx.Text(event.Delta),
Ctrl: &genx.StreamCtrl{StreamID: streamID},
}

P2 Badge Allocate a separate DashScope response StreamID

When DashScope emits both input transcription and model text for the same turn (the default ASR/text+audio configuration), this reuses the input streamID for assistant text. The user transcript path has already emitted a text/plain EOS for that same route, and the deleted ResponseStream wrapper used to rewrite model chunks onto a fresh response ID; without that, route-aware consumers can merge the transcript with the assistant response or see text data after EOS. Generate/use a response-local StreamID for model output before pushing these chunks.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Keep input transcription on the caller's input route while allocating a fresh StreamID for each bound model response. This prevents model text and audio from following a text/plain EOS emitted for the user transcript.
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

Fixed the current-head DashScope StreamID finding in 47b06d0f6:

  • input transcription remains correlated to the caller input StreamID
  • every bound model response gets a fresh StreamID for text/audio routes
  • added regression coverage for repeated input chunks and consecutive turns
  • go test ./..., tagged genx E2E compilation, DashScope race tests, and vet pass locally

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47b06d0f6a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkgs/genx/transformers/minimaxtts/transformer.go Outdated
Comment thread pkgs/genx/transformers/dashscoperealtime/implementation.go Outdated
Keep MiniMax synthesis on a per-chunk WebSocket stream and independently bind DashScope transcription and response events to queued turns. This preserves first-audio latency while preventing ASR completion from consuming the next turn's StreamID.
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

Addressed both current-head P2 findings in 07bfa774a:

  • MiniMax TTS uses the SDK WebSocket streaming API and emits provider audio chunks incrementally; live E2E passed with 62,208 bytes of audio/mpeg
  • DashScope tracks transcription and response bindings independently across buffered consecutive turns and preserves provider response correlation
  • targeted race tests, go test ./..., tagged GenX E2E compilation, vet, and diff checks pass

@codex review

MiniMax transformer tests exercise the public WebSocket transport directly, so keep coder/websocket in the direct requirement block required by go mod tidy.
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

CI tidy failure fixed in 65ff3a8f9: github.com/coder/websocket is now correctly classified as a direct dependency. go mod tidy -diff and the affected provider tests pass locally.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: 07bfa774a4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 65ff3a8f93

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

Moved the MP3 stream filter to the final public pkgs/genx/transformers/audiostream boundary in a546d45b4:

  • replaced the ambiguous TTSAudioNormalizer with audiostream.MP3ID3Stripper
  • made the MP3-to-MP3, ID3v2-only contract explicit
  • kept StreamKit codec-neutral and updated TTS/OpenAI consumers and bilingual guides
  • targeted race tests, go test ./..., vet, guides build, and live Doubao Seed V2/MiniMax TTS E2E pass

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: a546d45b4e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

The previous TTSAudioNormalizer ownership mixed Transformer stream processing
with codec conversion, while an MP3-specific replacement would expose a
current implementation detail as the public contract.

- Add a MIME-dispatched audiostream.Normalizer that preserves codec and MIME
- Pass through formats without special handling and keep MP3 ID3v2 filtering internal
- Update TTS providers, OpenAI speech consumers, tests, and guides to use the generic API
@idy
idy force-pushed the codex/issue-362-provider-packages branch from a546d45 to f8be694 Compare July 20, 2026 17:54
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

Corrected the audio-stream public contract in f8be69438:

  • callers now always construct audiostream.NewNormalizer(actualMIME)
  • input/output preserve the same codec and MIME
  • formats without special handling pass through unchanged
  • MP3 ID3v2 removal is an internal current handler, not the public type or caller-side condition
  • updated genx/transformers: Separate StreamKit and non-agent adapters #404, consumers, tests, and bilingual guides
  • targeted race/vet, go test ./..., guides build, and live Doubao Seed V2/MiniMax TTS E2E pass

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f8be694386

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkgs/genx/transformers/internal/streamkit/tts.go
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review


P1 Badge Allocate a separate translation stream ID

When AST emits both source subtitles and translated subtitles for one segment, assigning translation.streamID to the same id as source puts the user transcript and model translation on the same StreamID/text/plain channel; after the source side emits its text EOS, translation text can arrive on an already-ended channel. The previous doubaoast.New path wrapped the legacy adapter in agentkit.NewResponseStream, which rewrote RoleModel chunks onto a response-local ID, but this raw implementation no longer does that, so route-aware consumers can reject or mis-record the translated text. Use a fresh response StreamID for translation/model text, or restore equivalent response isolation.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkgs/genx/transformers/doubaorealtime/transformer.go
Comment thread pkgs/genx/transformers/audiostream/normalizer.go
Comment thread pkgs/genx/transformers/dashscoperealtime/implementation.go Outdated
Comment thread pkgs/genx/transformers/doubaorealtimeduplex/transformer.go
@idy

idy commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

@codex

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 9ce19d3107

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@idy
idy merged commit 7e8ac2f into main Jul 20, 2026
11 checks passed
@idy
idy deleted the codex/issue-362-provider-packages branch July 20, 2026 20:04
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.

genx/transformers: Separate StreamKit and non-agent adapters genx/transformers: Move provider implementations into independent packages

1 participant