Skip to content

feat(ai): support provider-managed files#1460

Merged
hwbrzzl merged 4 commits into
masterfrom
bowen/optimize-files-1
May 3, 2026
Merged

feat(ai): support provider-managed files#1460
hwbrzzl merged 4 commits into
masterfrom
bowen/optimize-files-1

Conversation

@hwbrzzl

@hwbrzzl hwbrzzl commented May 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add provider-managed document and image handles that can retrieve, delete, and reuse stored AI files by ID.
  • Let OpenAI conversations attach previously uploaded file IDs so large files can be referenced without re-uploading their content.
  • Extend the AI file provider contract and generated mocks to cover the full upload, get, and delete lifecycle.

Why

Goravel already supported uploading attachments, but it stopped at returning a provider file ID. That left no user-facing way to fetch a stored file later, delete it, or reuse it in a later conversation like the Laravel AI SDK files guide describes.

conversation, err := facades.AI().Agent(&agents.DocumentAnalyzer{})
if err != nil {
    return ctx.Response().Json(http.StatusInternalServerError, http.Json{"error": err.Error()})
}

stored, err := document.FromPath("storage/app/reports/quarterly.pdf").Put(ctx.Request().Context())
if err != nil {
    return ctx.Response().Json(http.StatusInternalServerError, http.Json{"error": err.Error()})
}

response, err := conversation.Prompt("Summarize this document", ai.WithAttachments(
    document.FromID(stored.ID()),
))
if err != nil {
    return ctx.Response().Json(http.StatusInternalServerError, http.Json{"error": err.Error()})
}

file, err := document.FromID(stored.ID()).Get(ctx.Request().Context())
if err != nil {
    return ctx.Response().Json(http.StatusInternalServerError, http.Json{"error": err.Error()})
}

if err := document.FromID(file.ID()).Delete(ctx.Request().Context()); err != nil {
    return ctx.Response().Json(http.StatusInternalServerError, http.Json{"error": err.Error()})
}

return ctx.Response().Json(http.StatusOK, http.Json{
    "response": response.Text(),
})

This change closes that gap by making ID-backed files first-class handles in the AI package and teaching the OpenAI provider to resolve and delete stored files as well as serialize from ID attachments with file_id references.

Copilot AI review requested due to automatic review settings May 3, 2026 03:46
@hwbrzzl
hwbrzzl requested a review from a team as a code owner May 3, 2026 03:46
@codecov

codecov Bot commented May 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 67.93893% with 42 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.27%. Comparing base (40421cc) to head (744ebe1).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
ai/file.go 72.22% 14 Missing and 6 partials ⚠️
ai/openai/provider.go 68.75% 6 Missing and 4 partials ⚠️
ai/application.go 60.00% 4 Missing and 4 partials ⚠️
ai/document/file.go 0.00% 2 Missing ⚠️
ai/image/file.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1460      +/-   ##
==========================================
- Coverage   69.28%   69.27%   -0.01%     
==========================================
  Files         368      368              
  Lines       29151    29276     +125     
==========================================
+ Hits        20196    20281      +85     
- Misses       8042     8069      +27     
- Partials      913      926      +13     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds first-class, provider-managed AI file handles (by ID) so callers can reuse previously uploaded files in later prompts, retrieve their content, and delete them—bringing Goravel’s AI attachments closer to a full upload/get/delete lifecycle across providers.

Changes:

  • Extend contracts/ai.FileProvider with GetFile and DeleteFile, plus new FileResponse/ProviderFile contracts.
  • Add DocumentFromID / ImageFromID constructors (and ai/document + ai/image wrappers) to attach stored file IDs and later Get/Delete them.
  • Update OpenAI provider to serialize from ID attachments via file_id references and implement file get/delete, with expanded tests and mocks.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
contracts/ai/provider.go Extends FileProvider contract with GetFile/DeleteFile.
contracts/ai/attachment.go Introduces FileResponse and ProviderFile interfaces for stored-file handles.
ai/application.go Adds getFile / deleteFile routing through provider resolution and capability checks.
errors/list.go Adds a centralized error for empty stored file IDs.
ai/file.go Implements ID-backed attachments (stored) supporting Get/Delete and file_id reuse.
ai/document/file.go Re-exports FromID for document handles.
ai/image/file.go Re-exports FromID for image handles.
ai/openai/provider.go Adds OpenAI GetFile/DeleteFile and serializes ID-backed attachments as file_id.
ai/openai/response.go Adds OpenAI fileResponse implementation for FileResponse.
ai/openai/provider_test.go Adds tests for file_id attachment serialization and OpenAI get/delete file flows.
ai/application_test.go Adds tests for Application.getFile/deleteFile including empty-id validation.
ai/file_test.go Adds tests for DocumentFromID get/delete behavior and facade-not-set errors.
mocks/ai/FileProvider.go Updates mock to include new GetFile/DeleteFile methods.
mocks/ai/FileResponse.go Adds mock for new contracts/ai.FileResponse.
mocks/ai/ProviderFile.go Adds mock for new contracts/ai.ProviderFile.

Comment thread ai/file.go
Comment thread ai/file.go Outdated
Comment thread ai/file.go Outdated
Comment thread ai/openai/provider.go Outdated
Copilot AI review requested due to automatic review settings May 3, 2026 04:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.

Comment thread ai/file.go
Comment thread ai/file.go Outdated
Comment thread ai/file.go Outdated
Comment thread ai/openai/provider.go Outdated
Comment thread ai/openai/provider_test.go
Copilot AI review requested due to automatic review settings May 3, 2026 14:36
@hwbrzzl
hwbrzzl force-pushed the bowen/optimize-files-1 branch from eee9e94 to 744ebe1 Compare May 3, 2026 14:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Comment thread ai/file.go
}
r.mu.Unlock()

return content, nil
Comment thread ai/file.go
Comment on lines +336 to +341
r.mu.RLock()
if len(r.content) > 0 {
content := bytes.Clone(r.content)
r.mu.RUnlock()
return content, nil
}
@hwbrzzl
hwbrzzl merged commit 1eb30e3 into master May 3, 2026
21 of 23 checks passed
@hwbrzzl
hwbrzzl deleted the bowen/optimize-files-1 branch May 3, 2026 14:53
LinboLen added a commit to LinboLen/framework that referenced this pull request May 3, 2026
* origin/master:
  fix(ai): remove context from image response content (goravel#1462)
  feat(ai): support provider-managed files (goravel#1460)
  feat(ai): add image generation support (goravel#1461)
  fix: [goravel#946] stop WithContext from leaking framework context keys (goravel#1456)
  feat(ai): add attachment upload support (goravel#1459)
  feat(ai): add attachment helper subpackages (goravel#1458)
  feat(ai): switch OpenAI provider to responses API (goravel#1457)
  feat(ai): add attachment support (goravel#1455)
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.

2 participants