Skip to content

Conversation

@hhieuu
Copy link
Contributor

@hhieuu hhieuu commented Jan 14, 2026

Summary

This PR allows tool parameter and jsonschema's additionalProperties to be either bool or object to make bifrost work with Claude Code's tools.

Changes

In recent versions, Claude Code built-in tools include an object in additionalProperties of tool params. This makes bifrost fails to parse the request due to the internal Chat Completion request struct only allows bool for additionalProperties in tool params. However, in jsonschema spec, additionalProperties can actually be either an object or a bool, making bifrost behavior a bug. See doc here: https://json-schema.org/understanding-json-schema/reference/object#additionalproperties

Additionally, I also apply the change to additionalProperties in ResponsesTextConfigFormatJSONSchema.

This is the Claude Code tool that breaks bifrost. This tool only seems to get added when there are other MCP added as well.

        {
            "name": "ExitPlanMode",
            "description": "Use this tool when you are in plan mode and have finished writing your plan to the plan file and are ready for user approval.\n\n## How This Tool Works\n- You should have already written your plan to the plan file specified in the plan mode system message\n- This tool does NOT take the plan content as a parameter - it will read the plan from the file you wrote\n- This tool simply signals that you're done planning and ready for the user to review and approve\n- The user will see the contents of your plan file when they review it\n\n## Requesting Permissions (allowedPrompts)\nWhen calling this tool, you can request prompt-based permissions for bash commands your plan will need. These are semantic descriptions of actions, not literal commands.\n\n**How to use:**\n```json\n{\n  \"allowedPrompts\": [\n    { \"tool\": \"Bash\", \"prompt\": \"run tests\" },\n    { \"tool\": \"Bash\", \"prompt\": \"install dependencies\" },\n    { \"tool\": \"Bash\", \"prompt\": \"build the project\" }\n  ]\n}\n```\n\n**Guidelines for prompts:**\n- Use semantic descriptions that capture the action's purpose, not specific commands\n- \"run tests\" matches: npm test, pytest, go test, bun test, etc.\n- \"install dependencies\" matches: npm install, pip install, cargo build, etc.\n- \"build the project\" matches: npm run build, make, cargo build, etc.\n- Keep descriptions concise but descriptive\n- Only request permissions you actually need for the plan\n- Scope permissions narrowly, like a security-conscious human would:\n  - **Never combine multiple actions into one permission** - split them into separate, specific permissions (e.g. \"list pods in namespace X\", \"view logs in namespace X\")\n  - Prefer \"run read-only database queries\" over \"run database queries\"\n  - Prefer \"run tests in the project\" over \"run code\"\n  - Add constraints like \"read-only\", \"local\", \"non-destructive\" whenever possible. If you only need read-only access, you must only request read-only access.\n  - Prefer not to request overly broad permissions that would grant dangerous access, especially any access to production data or to make irrecoverable changes\n  - When interacting with cloud environments, add constraints like \"in the foobar project\", \"in the baz namespace\", \"in the foo DB table\"\n  - Never request broad tool access like \"run k8s commands\" - always scope to specific actions and namespaces, ideally with constraints such as read-only\n\n**Benefits:**\n- Commands matching approved prompts won't require additional permission prompts\n- The user sees the requested permissions when approving the plan\n- Permissions are session-scoped and cleared when the session ends\n\n## When to Use This Tool\nIMPORTANT: Only use this tool when the task requires planning the implementation steps of a task that requires writing code. For research tasks where you're gathering information, searching files, reading files or in general trying to understand the codebase - do NOT use this tool.\n\n## Before Using This Tool\nEnsure your plan is complete and unambiguous:\n- If you have unresolved questions about requirements or approach, use AskUserQuestion first (in earlier phases)\n- Once your plan is finalized, use THIS tool to request approval\n\n**Important:** Do NOT use AskUserQuestion to ask \"Is this plan okay?\" or \"Should I proceed?\" - that's exactly what THIS tool does. ExitPlanMode inherently requests user approval of your plan.\n\n## Examples\n\n1. Initial task: \"Search for and understand the implementation of vim mode in the codebase\" - Do not use the exit plan mode tool because you are not planning the implementation steps of a task.\n2. Initial task: \"Help me implement yank mode for vim\" - Use the exit plan mode tool after you have finished planning the implementation steps of the task.\n3. Initial task: \"Add a new feature to handle user authentication\" - If unsure about auth method (OAuth, JWT, etc.), use AskUserQuestion first, then use exit plan mode tool after clarifying the approach.\n",
            "input_schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "type": "object",
                "properties": {
                    "allowedPrompts": {
                        "description": "Prompt-based permissions needed to implement the plan. These describe categories of actions rather than specific commands.",
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "tool": {
                                    "description": "The tool this prompt applies to",
                                    "type": "string",
                                    "enum": [
                                        "Bash"
                                    ]
                                },
                                "prompt": {
                                    "description": "Semantic description of the action, e.g. \"run tests\", \"install dependencies\"",
                                    "type": "string"
                                }
                            },
                            "required": [
                                "tool",
                                "prompt"
                            ],
                            "additionalProperties": false
                        }
                    }
                },
                "additionalProperties": {} # <- this one here
            }
        },

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (Next.js)
  • Docs

How to test

Test with Claude Code

Screenshots/Recordings

If UI changes, add before/after screenshots or short clips.

Breaking changes

  • Yes
  • No

If yes, describe impact and migration instructions.

Related issues

Link related issues and discussions. Example: Closes #123

Security considerations

Note any security implications (auth, secrets, PII, sandboxing, etc.).

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Enhanced structured outputs support for JSON schemas: additionalProperties now accepts both boolean and object-type values, enabling more flexible schema definitions for tool parameters.
  • Refactor

    • Updated schema conversion and serialization logic across AI provider integrations (Anthropic, Cohere, Gemini) to properly handle flexible additionalProperties representations.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Replaced additionalProperties boolean pointers with a new AdditionalProperties struct (BoolValue and ObjectValue) across schema types, provider utils, and tests; added custom JSON (un)marshalling and conversion branches to support both boolean and object forms.

Changes

Cohort / File(s) Summary
Schema type definitions
core/schemas/chatcompletions.go, core/schemas/responses.go
Added public AdditionalProperties struct (BoolValue *bool, ObjectValue *map[string]any); changed ToolFunctionParameters.AdditionalProperties and ResponsesTextConfigFormatJSONSchema.AdditionalProperties from *bool to *AdditionalProperties; implemented MarshalJSON/UnmarshalJSON for the new type and updated ToolFunctionParameters JSON handling.
Provider utility implementations
core/providers/anthropic/utils.go, core/providers/cohere/utils.go, core/providers/gemini/utils.go
Updated JSON-schema conversion logic to detect additionalProperties as either boolean or object and wrap into schemas.AdditionalProperties using BoolValue or ObjectValue accordingly; added branching to process map/object cases where applicable.
Tests and test utilities
core/internal/testutil/structured_outputs.go, core/providers/gemini/gemini_test.go
Updated test fixtures and utilities to construct AdditionalProperties as &schemas.AdditionalProperties{BoolValue: Ptr(false)} (or object form) instead of using *bool pointers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 I nibbled at schemas, both object and bool,
Now AdditionalProperties sings, tidy and full,
BoolValue or ObjectValue — I hop and I cheer,
Wrapping the forms so each parser is clear,
A tiny rabbit pat on the code, hip-hip hooray!

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR addresses additionalProperties schema handling but is unrelated to the linked issue #123 about Files API support. This PR should not be linked to issue #123. Either unlink the issue or ensure the PR scope aligns with Files API support requirements.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately describes the main change: allowing additionalProperties to accept object type in addition to boolean.
Description check ✅ Passed The PR description follows the template, includes summary, changes, type of change, affected areas, and testing information, though some sections lack detail.
Out of Scope Changes check ✅ Passed All changes are within scope: modifying additionalProperties handling in schemas and provider utilities directly supports the stated objective.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🧹 Recent nitpick comments
core/schemas/chatcompletions.go (1)

337-347: Consider adding mutual exclusivity validation for consistency.

The MarshalJSON method silently prioritizes ObjectValue when both fields are set. Other similar types in this file (e.g., ChatToolChoice.MarshalJSON at lines 477-490) validate that only one field is set before marshalling. Adding similar validation would make the behavior explicit and catch programming errors early.

♻️ Suggested validation
 func (t *AdditionalProperties) MarshalJSON() ([]byte, error) {
+	if t.ObjectValue != nil && t.BoolValue != nil {
+		return nil, fmt.Errorf("both BoolValue and ObjectValue are set; only one should be non-nil")
+	}
 	if t.ObjectValue != nil {
 		return Marshal(t.ObjectValue)
 	}
 	if t.BoolValue != nil {
 		return Marshal(t.BoolValue)
 	}
 	return Marshal(nil)
 }

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 36bdb9e and b6a9dd9.

📒 Files selected for processing (1)
  • core/schemas/chatcompletions.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

always check the stack if there is one for the current PR. do not give localized reviews for the PR, always see all changes in the light of the whole stack of PRs (if there is a stack, if there is no stack you can continue to make localized suggestions/reviews)

Files:

  • core/schemas/chatcompletions.go
🧠 Learnings (5)
📚 Learning: 2025-12-09T17:07:42.007Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/schemas/account.go:9-18
Timestamp: 2025-12-09T17:07:42.007Z
Learning: In core/schemas/account.go, the HuggingFaceKeyConfig field within the Key struct is currently unused and reserved for future Hugging Face inference endpoint deployments. Do not flag this field as missing from OpenAPI documentation or require its presence in the API spec until the feature is actively implemented and used. When the feature is added, update the OpenAPI docs accordingly; otherwise, treat this field as non-breaking and not part of the current API surface.

Applied to files:

  • core/schemas/chatcompletions.go
📚 Learning: 2025-12-29T11:54:55.836Z
Learnt from: akshaydeo
Repo: maximhq/bifrost PR: 1153
File: framework/configstore/rdb.go:2221-2246
Timestamp: 2025-12-29T11:54:55.836Z
Learning: In Go reviews, do not flag range-over-int patterns like for i := range n as compile-time errors, assuming Go 1.22+ semantics. Only flag actual range-capable values (slices, arrays, maps, channels, strings) and other compile-time issues. This applies to all Go files across the repository.

Applied to files:

  • core/schemas/chatcompletions.go
📚 Learning: 2026-01-14T04:40:11.480Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1312
File: framework/modelcatalog/pricing.go:276-426
Timestamp: 2026-01-14T04:40:11.480Z
Learning: In the Bifrost codebase, ImageUsage and other usage types guarantee that TotalTokens is populated (computed as InputTokens + OutputTokens if providers don’t supply TotalTokens). Reviewers can rely on this invariant and should not assume TotalTokens may be missing when input/output tokens exist. When implementing tiering logic or token-based decisions, you can safely use TotalTokens without extra null/zero guards, provided you’re in a context where InputTokens and OutputTokens are present. If a branch might discard tokens, ensure the invariant is preserved or add explicit checks only where the inputs are confirmed to be valid.

Applied to files:

  • core/schemas/chatcompletions.go
📚 Learning: 2026-01-14T13:30:28.760Z
Learnt from: Radheshg04
Repo: maximhq/bifrost PR: 1326
File: plugins/semanticcache/test_utils.go:545-559
Timestamp: 2026-01-14T13:30:28.760Z
Learning: In the maximhq/bifrost repository, prefer using bifrost.Ptr() to create pointers instead of the address operator (&) even when & would be valid syntactically. Apply this consistently across all code paths, including test utilities, to improve consistency and readability. Replace occurrences of &value where a *T is expected with bifrost.Ptr(value) (or an equivalent call) and ensure the function is in scope and used correctly for the target pointer type.

Applied to files:

  • core/schemas/chatcompletions.go
📚 Learning: 2025-12-17T08:44:08.788Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1114
File: core/schemas/chatcompletions.go:224-228
Timestamp: 2025-12-17T08:44:08.788Z
Learning: In core/schemas/chatcompletions.go, ensure the schema structures mirror OpenAI's API specifications exactly. Use the valid values for fields like ChatAudioParameters.Format and ChatAudioParameters.Voice as defined by OpenAI's documentation, and avoid adding additional inline documentation or constants to maintain direct compatibility with OpenAI's API.

Applied to files:

  • core/schemas/chatcompletions.go
🧬 Code graph analysis (1)
core/schemas/chatcompletions.go (2)
core/schemas/json_native.go (2)
  • Unmarshal (18-20)
  • Marshal (8-10)
core/schemas/json_wasm.go (2)
  • Unmarshal (22-24)
  • Marshal (8-10)
🔇 Additional comments (3)
core/schemas/chatcompletions.go (3)

276-282: LGTM!

The field type change from *bool to *AdditionalProperties correctly models JSON Schema's additionalProperties which can be either a boolean or an object. The AI summary confirms that related provider utilities and tests have been updated accordingly.


318-335: LGTM!

The UnmarshalJSON implementation correctly handles the union type by trying boolean first, then falling back to object. The error handling pattern is appropriate—only propagating the error when both parse attempts fail.


310-316: LGTM!

Good documentation linking to the JSON Schema specification. The use of pointer types for both fields correctly distinguishes between "not set" (nil) and "set to false/empty object" states.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@core/schemas/chatcompletions.go`:
- Around line 339-341: The docstring for AdditionalProperties.MarshalJSON is
incorrect: it references "UnmarshalJSON" and should describe the marshal
behavior; update the comment above the MarshalJSON method
(AdditionalProperties.MarshalJSON) to read that MarshalJSON implements custom
JSON marshalling for AdditionalProperties and clarify the precedence rule (if
object value exists it takes precedence, otherwise the bool value is used).
- Around line 7-8: The code currently imports "github.com/bytedance/sonic" and
calls sonic.Unmarshal/sonic.Marshal directly inside
AdditionalProperties.UnmarshalJSON and AdditionalProperties.MarshalJSON, which
bypasses the platform-abstracting wrappers and can break WASM builds; change
those calls to use the package-level Unmarshal and Marshal wrapper functions
instead, and remove the direct sonic import so the file relies on the
json_native/json_wasm abstraction; update the calls in the
AdditionalProperties.UnmarshalJSON, AdditionalProperties.MarshalJSON methods to
call Unmarshal(...) and Marshal(...) respectively.
🧹 Nitpick comments (2)
core/internal/testutil/structured_outputs.go (1)

421-425: Correct migration to the new AdditionalProperties type.

The construction of AdditionalProperties with BoolValue correctly adapts to the new structured type.

Based on learnings, consider using bifrost.Ptr() for creating the bool pointer for consistency:

AdditionalProperties: &schemas.AdditionalProperties{BoolValue: bifrost.Ptr(additionalProps)},
core/providers/gemini/utils.go (1)

1145-1149: Use schemas.Ptr() for pointer creation to maintain codebase consistency.

The logic correctly handles both boolean and object forms of additionalProperties per the JSON Schema specification. However, for consistency with the codebase conventions, prefer using schemas.Ptr() instead of the address operator for the inner pointer values.

Based on learnings, the repository prefers schemas.Ptr() over & for creating pointers.

♻️ Suggested refactor
 	// Extract additionalProperties
 	if additionalProps, ok := normalizedSchemaMap["additionalProperties"].(bool); ok {
-		jsonSchema.AdditionalProperties = &schemas.AdditionalProperties{BoolValue: &additionalProps}
+		jsonSchema.AdditionalProperties = &schemas.AdditionalProperties{BoolValue: schemas.Ptr(additionalProps)}
 	} else if additionalProps, ok := normalizedSchemaMap["additionalProperties"].(map[string]any); ok {
-		jsonSchema.AdditionalProperties = &schemas.AdditionalProperties{ObjectValue: &additionalProps}
+		jsonSchema.AdditionalProperties = &schemas.AdditionalProperties{ObjectValue: schemas.Ptr(additionalProps)}
 	}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ccd661f and 36bdb9e.

📒 Files selected for processing (7)
  • core/internal/testutil/structured_outputs.go
  • core/providers/anthropic/utils.go
  • core/providers/cohere/utils.go
  • core/providers/gemini/gemini_test.go
  • core/providers/gemini/utils.go
  • core/schemas/chatcompletions.go
  • core/schemas/responses.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

always check the stack if there is one for the current PR. do not give localized reviews for the PR, always see all changes in the light of the whole stack of PRs (if there is a stack, if there is no stack you can continue to make localized suggestions/reviews)

Files:

  • core/schemas/responses.go
  • core/providers/anthropic/utils.go
  • core/schemas/chatcompletions.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/gemini_test.go
  • core/internal/testutil/structured_outputs.go
  • core/providers/cohere/utils.go
🧠 Learnings (14)
📚 Learning: 2025-12-09T17:07:42.007Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/schemas/account.go:9-18
Timestamp: 2025-12-09T17:07:42.007Z
Learning: In core/schemas/account.go, the HuggingFaceKeyConfig field within the Key struct is currently unused and reserved for future Hugging Face inference endpoint deployments. Do not flag this field as missing from OpenAPI documentation or require its presence in the API spec until the feature is actively implemented and used. When the feature is added, update the OpenAPI docs accordingly; otherwise, treat this field as non-breaking and not part of the current API surface.

Applied to files:

  • core/schemas/responses.go
  • core/providers/anthropic/utils.go
  • core/schemas/chatcompletions.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/gemini_test.go
  • core/internal/testutil/structured_outputs.go
  • core/providers/cohere/utils.go
📚 Learning: 2025-12-29T11:54:55.836Z
Learnt from: akshaydeo
Repo: maximhq/bifrost PR: 1153
File: framework/configstore/rdb.go:2221-2246
Timestamp: 2025-12-29T11:54:55.836Z
Learning: In Go reviews, do not flag range-over-int patterns like for i := range n as compile-time errors, assuming Go 1.22+ semantics. Only flag actual range-capable values (slices, arrays, maps, channels, strings) and other compile-time issues. This applies to all Go files across the repository.

Applied to files:

  • core/schemas/responses.go
  • core/providers/anthropic/utils.go
  • core/schemas/chatcompletions.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/gemini_test.go
  • core/internal/testutil/structured_outputs.go
  • core/providers/cohere/utils.go
📚 Learning: 2026-01-14T04:40:11.480Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1312
File: framework/modelcatalog/pricing.go:276-426
Timestamp: 2026-01-14T04:40:11.480Z
Learning: In the Bifrost codebase, ImageUsage and other usage types guarantee that TotalTokens is populated (computed as InputTokens + OutputTokens if providers don’t supply TotalTokens). Reviewers can rely on this invariant and should not assume TotalTokens may be missing when input/output tokens exist. When implementing tiering logic or token-based decisions, you can safely use TotalTokens without extra null/zero guards, provided you’re in a context where InputTokens and OutputTokens are present. If a branch might discard tokens, ensure the invariant is preserved or add explicit checks only where the inputs are confirmed to be valid.

Applied to files:

  • core/schemas/responses.go
  • core/providers/anthropic/utils.go
  • core/schemas/chatcompletions.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/gemini_test.go
  • core/internal/testutil/structured_outputs.go
  • core/providers/cohere/utils.go
📚 Learning: 2026-01-14T13:30:28.760Z
Learnt from: Radheshg04
Repo: maximhq/bifrost PR: 1326
File: plugins/semanticcache/test_utils.go:545-559
Timestamp: 2026-01-14T13:30:28.760Z
Learning: In the maximhq/bifrost repository, prefer using bifrost.Ptr() to create pointers instead of the address operator (&) even when & would be valid syntactically. Apply this consistently across all code paths, including test utilities, to improve consistency and readability. Replace occurrences of &value where a *T is expected with bifrost.Ptr(value) (or an equivalent call) and ensure the function is in scope and used correctly for the target pointer type.

Applied to files:

  • core/schemas/responses.go
  • core/providers/anthropic/utils.go
  • core/schemas/chatcompletions.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/gemini_test.go
  • core/internal/testutil/structured_outputs.go
  • core/providers/cohere/utils.go
📚 Learning: 2025-12-19T09:26:54.961Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/providers/utils/utils.go:1050-1051
Timestamp: 2025-12-19T09:26:54.961Z
Learning: Update streaming end-marker handling so HuggingFace is treated as a non-[DONE] provider for backends that do not emit a DONE marker (e.g., meta llama on novita). In core/providers/utils/utils.go, adjust ProviderSendsDoneMarker() (or related logic) to detect providers that may not emit DONE and avoid relying on DONE as the sole end signal. Add tests to cover both DONE-emitting and non-DONE backends, with clear documentation in code comments explaining the rationale and any fallback behavior.

Applied to files:

  • core/providers/anthropic/utils.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/gemini_test.go
  • core/providers/cohere/utils.go
📚 Learning: 2026-01-10T11:27:47.535Z
Learnt from: Radheshg04
Repo: maximhq/bifrost PR: 1256
File: core/providers/openai/openai.go:2276-2385
Timestamp: 2026-01-10T11:27:47.535Z
Learning: Validate image generation requests for nil and missing prompts before dispatch. Follow the same pattern used here: core/bifrost.go validates nil/empty prompts, providerUtils.CheckContextAndGetRequestBody returns a structured error when the request converter yields nil, and apply this across all providers (including OpenAI) to avoid sending null bodies.

Applied to files:

  • core/providers/anthropic/utils.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/gemini_test.go
  • core/providers/cohere/utils.go
📚 Learning: 2026-01-11T14:08:10.341Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1298
File: core/providers/anthropic/anthropic.go:682-699
Timestamp: 2026-01-11T14:08:10.341Z
Learning: In Anthroplic streaming implementations (and analogous providers), ensure that the final 'summary' chunk, which carries usage information and metadata, is emitted after all delta chunks and uses a chunk index of last_delta_index + 1. This differentiates the summary chunk from content delta chunks. Apply this convention consistently in the anthropic provider code and in similar streaming providers, and consider adding a targeted test to assert the ordering and chunk index logic.

Applied to files:

  • core/providers/anthropic/utils.go
📚 Learning: 2026-01-13T13:36:35.221Z
Learnt from: TejasGhatte
Repo: maximhq/bifrost PR: 1319
File: core/providers/anthropic/responses.go:937-937
Timestamp: 2026-01-13T13:36:35.221Z
Learning: In core/providers/anthropic/responses.go, when handling Anthropic API streaming responses, ensure that content_block_start events include a signature field set to an empty string (e.g., contentBlock.Signature = ""). The actual signature is delivered later via signature_delta events. This behavior is per Anthropic's specification and should not be treated as an error. This guideline should apply to all Anthropic response handling files under core/providers/anthropic/ and similar go files that process streaming blocks.

Applied to files:

  • core/providers/anthropic/utils.go
📚 Learning: 2026-01-14T06:57:42.750Z
Learnt from: TejasGhatte
Repo: maximhq/bifrost PR: 1319
File: core/providers/anthropic/types.go:248-336
Timestamp: 2026-01-14T06:57:42.750Z
Learning: For Anthropic citation types (page_location, char_location, content_block_location), ensure there is an optional string field file_id to reference uploaded files. Update the Go structs modeling these citations to include FileID *string (or string with omitempty) and document its optionality in comments, so code consuming these types can handle absence of file_id gracefully.

Applied to files:

  • core/providers/anthropic/utils.go
📚 Learning: 2026-01-14T06:57:42.750Z
Learnt from: TejasGhatte
Repo: maximhq/bifrost PR: 1319
File: core/providers/anthropic/types.go:248-336
Timestamp: 2026-01-14T06:57:42.750Z
Learning: In core/providers/anthropic/types.go, ensure the web_search_result_location citation type includes a string field named 'url' alongside the existing fields 'encrypted_index', 'title', and 'cited_text'. If the field is missing, add it with type string and appropriate struct tags (e.g., json and/or db tags) and update any related serialization or usage accordingly.

Applied to files:

  • core/providers/anthropic/utils.go
📚 Learning: 2026-01-14T10:53:44.658Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1326
File: core/providers/gemini/gemini.go:1679-1754
Timestamp: 2026-01-14T10:53:44.658Z
Learning: Validate image generation inputs in core/bifrost.go before invoking any provider handler. Ensure in all provider implementations (e.g., core/providers/gemini/gemini.go) that the request and request.Input are non-nil before use, to prevent nil dereferences and provide clear error handling. Apply this invariant broadly to all providers and add tests for nil input scenarios.

Applied to files:

  • core/providers/anthropic/utils.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/gemini_test.go
  • core/providers/cohere/utils.go
📚 Learning: 2025-12-17T08:44:08.788Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1114
File: core/schemas/chatcompletions.go:224-228
Timestamp: 2025-12-17T08:44:08.788Z
Learning: In core/schemas/chatcompletions.go, ensure the schema structures mirror OpenAI's API specifications exactly. Use the valid values for fields like ChatAudioParameters.Format and ChatAudioParameters.Voice as defined by OpenAI's documentation, and avoid adding additional inline documentation or constants to maintain direct compatibility with OpenAI's API.

Applied to files:

  • core/schemas/chatcompletions.go
📚 Learning: 2025-12-15T10:16:21.909Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/providers/huggingface/huggingface_test.go:12-63
Timestamp: 2025-12-15T10:16:21.909Z
Learning: In provider tests under core/providers/<provider>/*_test.go, do not require or flag the use of defer for Shutdown(); instead call client.Shutdown() at the end of each test function. This pattern appears consistent across all provider tests. Apply this rule only within this path; for other tests or resources, defer may still be appropriate.

Applied to files:

  • core/providers/gemini/gemini_test.go
📚 Learning: 2025-12-19T08:29:20.286Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1095
File: core/internal/testutil/count_tokens.go:30-67
Timestamp: 2025-12-19T08:29:20.286Z
Learning: In core/internal/testutil test files, enforce using GetTestRetryConfigForScenario() to obtain a generic retry config, then construct a typed retry config (e.g., CountTokensRetryConfig, EmbeddingRetryConfig, TranscriptionRetryConfig) with an empty Conditions slice. Copy only MaxAttempts, BaseDelay, MaxDelay, OnRetry, and OnFinalFail from the generic config. This convention should be consistently applied across all test files in this directory.

Applied to files:

  • core/internal/testutil/structured_outputs.go
🧬 Code graph analysis (7)
core/schemas/responses.go (1)
core/schemas/chatcompletions.go (1)
  • AdditionalProperties (315-318)
core/providers/anthropic/utils.go (1)
core/schemas/chatcompletions.go (1)
  • AdditionalProperties (315-318)
core/schemas/chatcompletions.go (2)
core/schemas/json_native.go (2)
  • Unmarshal (18-20)
  • Marshal (8-10)
core/schemas/json_wasm.go (2)
  • Unmarshal (22-24)
  • Marshal (8-10)
core/providers/gemini/utils.go (1)
core/schemas/chatcompletions.go (1)
  • AdditionalProperties (315-318)
core/providers/gemini/gemini_test.go (2)
core/schemas/chatcompletions.go (1)
  • AdditionalProperties (315-318)
core/schemas/utils.go (1)
  • Ptr (14-16)
core/internal/testutil/structured_outputs.go (1)
core/schemas/chatcompletions.go (1)
  • AdditionalProperties (315-318)
core/providers/cohere/utils.go (1)
core/schemas/chatcompletions.go (1)
  • AdditionalProperties (315-318)
🔇 Additional comments (6)
core/providers/cohere/utils.go (1)

76-80: LGTM! Correct handling of additionalProperties as bool or object.

The implementation correctly handles both JSON Schema forms: boolean and object. The type assertion pattern (try bool first, then map) aligns with the approach used in other providers (anthropic, gemini).

core/providers/anthropic/utils.go (1)

768-772: LGTM! Consistent with the new AdditionalProperties type.

The implementation correctly handles both boolean and object forms for additionalProperties, consistent with the changes in the cohere provider and the JSON Schema specification.

core/schemas/chatcompletions.go (1)

312-337: Well-designed union type for AdditionalProperties.

The struct design with BoolValue and ObjectValue pointers cleanly represents the JSON Schema specification where additionalProperties can be either a boolean or a schema object. The precedence logic (ObjectValue over BoolValue) in marshalling is sensible.

core/schemas/responses.go (1)

132-140: LGTM! Consistent type update for AdditionalProperties.

The field type change from *bool to *AdditionalProperties aligns with the new structured type defined in chatcompletions.go, enabling both boolean and object representations of additionalProperties in the Responses API schema format.

core/internal/testutil/structured_outputs.go (1)

534-539: Correct adaptation to new AdditionalProperties type.

Same pattern as above - correctly constructs the new type. Consider using bifrost.Ptr() for the inner bool pointer for consistency with codebase conventions.

core/providers/gemini/gemini_test.go (1)

559-559: LGTM!

The test correctly updates to the new AdditionalProperties struct type, properly wrapping the boolean value in BoolValue. This aligns with the schema changes and tests the boolean case for the responses API.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@hhieuu
Copy link
Contributor Author

hhieuu commented Jan 15, 2026

@akshaydeo Can I also have a review here and for #1331 ? Would be really nice if these go into the next release. Thanks a lot!

@hhieuu
Copy link
Contributor Author

hhieuu commented Jan 17, 2026

Closing this since #1319 already contains the fix and was merged.

@hhieuu hhieuu closed this Jan 17, 2026
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.

Files API Support

1 participant