Files
DeepSeek-Reasonix/internal/contract/delivery/delivery.go
T
SivanCola e1159a4685 Add structured file deliveries and workbench document previews
Problem: AI-created documents could not be handed off as validated, durable
file cards, and binary files could not be read through the text editor route.

Root cause: delivery identity lived only in ordinary tool output, while file
reading, view selection and auxiliary actions lacked a shared preview path.

Fix: add a bounded root-confined reader, Controller and raw-byte preview APIs,
and host-confirmed present_files results projected through live and stored
history. Add lazy PDF, worker CSV and sandboxed HTML viewers, responsive file
cards, type icons, current-file state and accessible shared tooltips. Preserve
dirty drafts while surfacing deletion/revocation and avoid metadata reads per
keystroke. Keep the current workbench request-consumption contract intact.

Verification: root and desktop Go tests, go vet, make lint/check, frontend
typecheck, 498 related tests and production build. Browser checks cover PDF
navigation, CSV literals, menus, request consumption and responsive themes.
The builtin schema inventory grows by 143 measured tokens; boot effect tests
verify stable schemas within a turn for direct and capability-proxy calls.
2026-10-21 03:32:25 +08:00

42 lines
1.1 KiB
Go

// Package delivery defines persisted file declarations and their UI projection.
package delivery
import (
"encoding/json"
"path/filepath"
)
const (
ToolName = "present_files"
Identity = "tool:present_files"
MaxFiles = 4
)
type File struct {
Path string `json:"path"`
Root string `json:"root,omitempty"`
Description string `json:"description,omitempty"`
}
type Result struct {
Version int `json:"version"`
Files []File `json:"files"`
}
// Decode requires the host's resolved builtin identity and a successful result.
func Decode(name, identity string, failed bool, output string) []File {
if failed || name != ToolName || identity != Identity || len(output) > 32<<10 {
return nil
}
var result Result
if json.Unmarshal([]byte(output), &result) != nil || result.Version != 1 || len(result.Files) == 0 || len(result.Files) > MaxFiles {
return nil
}
for _, file := range result.Files {
if !filepath.IsLocal(filepath.FromSlash(file.Path)) || file.Path == "." || len(file.Description) > 1024 {
return nil
}
}
return result.Files
}