Repository navigation
Conversation
|
| if self.mime_type: | ||
| file_dict["format"] = self.mime_type | ||
| if self.resolution: | ||
| file_dict["resolution"] = self.resolution |
There was a problem hiding this comment.
File-ID Metadata Blocks Requests
When from_file_id sets a MIME type or resolution, format() emits format or resolution in the file block. Native conversion rejects either field, so a native Gemini request using the new metadata fails before reaching the provider. This must be fixed before merging.
Knowledge Base Used: Language model integration
Artifacts
Executable Gemini file-ID reproduction script
- The authored script runs both revisions through the same DSPy call and mocks only the provider boundary, making pre-provider rejection observable.
Gemini file-ID run before the change
- The captured baseline run shows a plain file ID reaching the mock provider while the constructor rejects the two optional arguments.
Gemini file-ID run after the change
- The captured HEAD run shows both optional fields rejected during native conversion with zero provider calls.
| if file_input.mime_type is not None: | ||
| result["format"] = file_input.mime_type |
There was a problem hiding this comment.
File(existing_file) converts an existing mime_type into a format field, which the File model forbids. Copying a file with MIME metadata therefore raises a validation error instead of producing a usable copy. This is a non-blocking concern, but callers cannot reliably reuse those files.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Artifacts
Executed File constructor reproduction script
- The authored script constructs and copies Files with and without a MIME type, asserting the observed constructor outcomes.
Constructor output without a MIME type
- The executed control command copied an existing File without a MIME type successfully.
Constructor output with a MIME type
- The executed command copied an existing File with a MIME type and captured a `format` extra-forbidden validation error.
There was a problem hiding this comment.
The File model has aalready been updated in this fix to inlcude mime_type and resolution fields.
There was a problem hiding this comment.
Thanks for pointing that out. In the revision under review, File declares mime_type and resolution, but it does not declare a format field. format is only the outbound key produced by format(); model_config still has extra="forbid".
Therefore, File(existing_file) still fails when either new field is set: encode_file_to_dict() emits {"format": ..., "resolution": ...}, which is passed back into Pydantic, where format is rejected as an extra field. The copy path should preserve the model field name (mime_type) and translate it to format only when serializing for the provider.
Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.
There was a problem hiding this comment.
You're right that File now declares both fields; the issue is the conversion key, not the model definition. encode_file_to_dict() is used by File(existing_file) and returns {"format": ...} here, but format is not a File model field (extra="forbid"), so copying a file with mime_type still raises a validation error.
format should only be emitted by the adapter-facing format() method. The constructor normalization should preserve the model field name:
| if file_input.mime_type is not None: | |
| result["format"] = file_input.mime_type | |
| if file_input.mime_type is not None: | |
| result["mime_type"] = file_input.mime_type |
The resolution mapping can remain unchanged. This lets File(existing_file) retain both mime_type and resolution, while File.format() still translates mime_type to LiteLLM’s format key.
This is a very simple fix that adds
mime_typeandresolutionarguments to the functions that instantiate a dspy.File object. This is necessary when using gemini features (e.g., File api and different resolutions for media objects), which is not possible at the current version of dspy.Now, dspy files can be instantiated like this:
I have to admit that I still don't finish understanding the implications of the 3.4.X update at the deeper level and my changes cover just the dspy.File contract.
I just added the LiteLLM-required fields ('format' and 'resolution') and it works fine on my side and passes the tests.
This fix is a modern solution (3.4.X) for the issue raise in this PR #9114 .
Please feel to free to reject this PR and let me know if more attention is needed on this.
Cheers,
Gustavo