Files
aego/app/edit/agentbridge/material_source.go
sanspie 5eb1832907
ci-platforms / darwin amd64 smoke (push) Skipped
ci / build (amd64, linux, ubuntu-24.04) (push) Failing after 15m28s
ci / release (push) Skipped
ci-platforms / windows amd64 smoke (push) Skipped
ci-platforms / darwin arm64 smoke (push) Skipped
ci / checks (push) Successful in 7m47s
Complete Stage 12 for v0.12.0
2026-11-05 11:46:53 +03:00

81 lines
2.1 KiB
Go

package agentbridge
import (
"errors"
"fmt"
"io"
"io/fs"
"path"
"strings"
"aego/app/agent/mcp"
"aego/core/ids"
"aego/editor/core/document"
)
// materialText reads only authored shader/material text inside the project.
// The shared source buffer covers both the code editor and structured material inspector.
func materialText(docs *document.Manager, name string) (string, error) {
const limit = 256 << 10
if !fs.ValidPath(name) || strings.ContainsAny(name, "\\:") || (path.Ext(name) != ".aeshader" && path.Ext(name) != ".aemat") {
return "", errors.New("expected a project-relative .aeshader or .aemat")
}
if docs == nil {
return "", errors.New("editor documents unavailable")
}
var source []byte
if d := docs.Script(name); d != nil {
source = d.Code.Bytes()
} else {
f, err := docs.OpenSource(name)
if err != nil {
return "", err
}
defer f.Close()
source, err = io.ReadAll(io.LimitReader(f, limit+1))
if err != nil {
return "", err
}
}
if len(source) > limit {
return "", fmt.Errorf("asset source exceeds %d bytes", limit)
}
return string(source), nil
}
func (b *Bridge) materialSourceTool() mcp.Tool {
return mcp.Tool{Name: "editor_material_source", ReadOnly: true,
Description: "Read the current project .aeshader or .aemat source by relative path or AssetID, including unsaved edits.",
Schema: visualSchema([]string{"asset"}, map[string]any{"asset": map[string]any{"type": "string"}}),
Run: func(args map[string]any) (string, bool) {
name, _ := args["asset"].(string)
var text string
var err error
generation := b.panelGeneration.Load()
if e := b.main(func() {
if b.cancelled(generation) {
err = errCancelled
return
}
if id, e := ids.ParseAssetID(name); e == nil {
if b.ctx.Pipeline == nil {
err = errors.New("asset index unavailable")
return
}
var ok bool
if name, ok = b.ctx.Pipeline.PathOf(id); !ok {
err = errors.New("asset not found")
return
}
}
text, err = materialText(b.ctx.Docs, name)
}); e != nil {
return e.Error(), true
}
if err != nil {
return err.Error(), true
}
return text, false
}}
}