Files
foundry-core/internal/platform/canvas_capabilities.go
T
codex-bot d6ee8942f1
Foundry Go checks / check (push) Successful in 2m40s
Foundry Go checks / check (pull_request) Successful in 2m36s
Implement Canvas V2 subgraphs, assets and asynchronous AI execution
2026-11-06 18:36:00 +08:00

54 lines
2.0 KiB
Go

package platform
import (
"context"
"net/http"
"time"
)
func (s *service) canvasCapabilities(w http.ResponseWriter, r *http.Request, project, account string) error {
if r.Method != http.MethodGet {
reject(w, 405, "method_not_allowed")
return nil
}
tx, err := s.db.BeginTx(r.Context(), nil)
if err != nil {
return err
}
defer tx.Rollback()
kind, _, err := lockMaterial(r.Context(), tx, project, r.PathValue("workspace"), r.PathValue("material"), account)
if err != nil {
return err
}
if kind != "board" {
reject(w, 400, "invalid_material")
return nil
}
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
models, modelErr := s.canvasAI.Models(ctx)
textAvailable, imageAvailable := false, false
if modelErr == nil {
for _, model := range models {
if model.Available {
textAvailable = textAvailable || canvasModelSupports(model, "text")
imageAvailable = imageAvailable || canvasModelSupports(model, "image")
}
}
}
ai := response{"available": textAvailable || imageAvailable, "text": textAvailable, "image": imageAvailable}
if modelErr != nil {
ai["unavailable_reason"] = "codex_unavailable"
}
reply(w, 200, response{
"contract_version": "canvas-v2-2026-11-06",
"supported_schema_versions": []int{1, 2},
"edge_features": response{"appearance": true, "markers": true, "bezier_chain": true, "animation_configuration": true, "execution_events": true},
"subgraphs": response{"create": true, "migrate": true, "undo": true, "members": true, "dissolve": true},
"ai": ai,
"limits": response{"max_depth": 8, "max_nodes": 500, "max_edges": 2000, "max_frame_ports": 4000, "max_curve_knots": 64, "max_snapshot_bytes": canvasLimit, "max_active_tasks": 128, "max_run_steps": 64, "max_execution_depth": 32, "max_input_images": 4, "max_input_image_bytes": 20 << 20, "max_coordinate": 1000000},
"retention": response{"idempotency_min_seconds": 86400, "undo_receipt_seconds": 604800},
})
return nil
}