Skip to content

Collapse Conduit public API surface#64

Closed
christopherkarani wants to merge 4 commits into
mainfrom
cleanup
Closed

Collapse Conduit public API surface#64
christopherkarani wants to merge 4 commits into
mainfrom
cleanup

Conversation

@christopherkarani
Copy link
Copy Markdown
Owner

Summary

  • Collapse Conduit down to a single public Conduit library surface and remove the old ConduitFacade target file.
  • Preserve the unified facade API through the canonical Conduit import, including structured output and streaming flows.
  • Tighten provider request/streaming behavior across OpenAI-compatible providers, Anthropic, HuggingFace, Kimi, MiniMax, MLX, and Llama.
  • Add docs, DocC, example workflow coverage, and an MLX test app for the updated package shape.
  • Add regression tests for canonical imports, package manifest stability, provider adapters, macros, structured output, chat session concurrency, and MLX support.

Verification

  • swift build
  • swift test (385 tests passed)

Notes

  • Local generated build caches were intentionally left uncommitted: .build-default/ and Examples/MLXTestApp/.build/.

- Add prompt injection for .jsonObject and .jsonSchema via
  responseFormatInstruction(), matching Anthropic's proven pattern
- Strip markdown code fences from model output when JSON format is
  requested (on-device FM wraps JSON in fences despite instructions)
- Add native generate(returning:) overrides using Apple's
  respond(to:generating:) for types conforming to both Conduit.Generable
  and FoundationModels.Generable (constrained decoding)
- Wire responseFormat through all code paths: generate, stream,
  streamWithMetadata
- Add 4 integration tests and 9 unit tests for fence stripping edge cases
- Extract shared ResponseFormat.promptInstruction computed property,
  removing duplicate responseFormatInstruction() from both
  AnthropicProvider and FoundationModelsProvider
- Make stripCodeFences internal so tests use production code directly,
  eliminating duplicated test implementation
- Consolidate two generate(returning:) overloads into shared
  respondStructured() private helper
Make Conduit the single public library surface, remove the ConduitAdvanced facade target, and preserve compatibility through the unified API.

Stabilize provider dependency traits, docs, examples, and request/streaming behavior across OpenAI-compatible providers.

Add regression coverage for canonical imports, package manifest stability, provider requests, structured output, macros, and MLX support.
Copy link
Copy Markdown

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

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: 98fc93ddb7

ℹ️ 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 on lines 970 to 974
withLock {
if isGenerating {
isGenerating = false
lastError = AIError.cancelled
if _isGenerating {
_isGenerating = false
_lastError = AIError.cancelled
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Clear active request marker when canceling

After cancel() completes, this path only flips _isGenerating/_lastError and never clears activeRequestID. Because new send/streamResponse calls require activeRequestID == nil, callers can immediately hit "already has an in-progress generation" right after await cancel(), and the session can remain blocked if the canceled task never reaches its cleanup block.

Useful? React with 👍 / 👎.

Comment on lines +422 to +425
return Provider(
makeSession: sessionProvider.makeSession,
imageGenerator: AnyImageGenerator(provider)
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use separate provider instance for image facade

This wires the same OpenAIProvider instance into both session generation and images. Since OpenAIProvider.cancelGeneration() cancels both text and image tasks, calling conduit.images.cancel() can cancel an unrelated in-flight text request (and text cancellation can kill image generation) when both flows share one Conduit instance.

Useful? React with 👍 / 👎.

@christopherkarani
Copy link
Copy Markdown
Owner Author

Closing as superseded by the newer provider/API expansion work in PR #65. This branch is stale/conflicting, overlaps heavily with #65, and still has unresolved cancellation review findings.

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.

1 participant