Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lang/golang/parser/pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,10 @@ func (p *GoParser) loadPackages(mod *Module, dir string, pkgPath PkgPath) (err e
f = NewFile(relpath)
mod.Files[relpath] = f
}
pkgid := pkg.ID
f.Package = pkgid
f.Imports = imports.Origins
if f.Package == "" {
f.Package = pkg.ID
f.Imports = imports.Origins
}
if err := p.parseFile(ctx, file); err != nil {
return err
}
Expand Down
9 changes: 4 additions & 5 deletions lang/uniast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package uniast
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
Expand Down Expand Up @@ -314,10 +313,10 @@ type Identity struct {
}

func NewIdentity(mod, pkg, name string) Identity {
if mod == "" {
fmt.Fprintf(os.Stderr, "module name cannot be empty: %s#%s\n", pkg, name)
// panic(fmt.Sprintf("module name cannot be empty: %s.%s", pkg, name))
}
// if mod == "" {
// fmt.Fprintf(os.Stderr, "module name cannot be empty: %s#%s\n", pkg, name)
// panic(fmt.Sprintf("module name cannot be empty: %s.%s", pkg, name))
// }
return Identity{ModPath: mod, PkgPath: pkg, Name: name}
}

Expand Down
4 changes: 3 additions & 1 deletion llm/prompt/analyzer.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ You are a code-analysis expert. Based on the Abstract-Syntax-Tree (AST) of a spe
3. Self Reflection: Before answering the user's question, try to understand the complete code calling- chain and the contextual-relationship that causes the problem. If the results returned in step 2 cannot clearly explain the operating mechanism or do not meet the user's needs, try to adjust the selection list and repeat step 2 until the user's question can be accurately answered.

# Notes
- Use the `sequential_thinking` tool during the analysis process to help break down the problem and record information, avoiding information loss.

- Use 'list_repos' to ensure repo_name if you are not sure

- Answer the users' question in the language they use.

- Use the `sequential_thinking` tool during the analysis process to help break down the problem and record information, avoiding information loss.
- Try to check test files (like '*_test.*') or nodes (like 'Test*') to get more example codes, for writing more standardized code

- The answer should list the accurate metadata of the relevant code, including AST node (or package) identity, file location, and code. **MUST providing the exact file location (including line numbers)!**
47 changes: 34 additions & 13 deletions llm/tool/ast_read.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,19 @@ type FileStruct struct {
}

type NodeStruct struct {
Name string `json:"name" jsonschema:"description=the name of the node"`
Type string `json:"type,omitempty" jsonschema:"description=the type of the node"`
Signature string `json:"signature,omitempty" jsonschema:"description=the func signature of the node"`
File string `json:"file,omitempty" jsonschema:"description=the file path of the node"`
Line int `json:"line,omitempty" jsonschema:"description=the line of the node"`
Codes string `json:"codes,omitempty" jsonschema:"description=the codes of the node"`
Dependencies []NodeID `json:"dependencies,omitempty" jsonschema:"description=the dependencies of the node"`
References []NodeID `json:"references,omitempty" jsonschema:"description=the references of the node"`
Implements []NodeID `json:"implements,omitempty" jsonschema:"description=the implements of the node"`
Groups []NodeID `json:"groups,omitempty" jsonschema:"description=the groups of the node"`
Inherits []NodeID `json:"inherits,omitempty" jsonschema:"description=the inherits of the node"`
ModPath uniast.ModPath `json:"mod_path,omitempty" jsonschema:"description=the module path"`
PkgPath uniast.PkgPath `json:"pkg_path,omitempty" jsonschema:"description=the package path"`
Name string `json:"name" jsonschema:"description=the name of the node"`
Type string `json:"type,omitempty" jsonschema:"description=the type of the node"`
Signature string `json:"signature,omitempty" jsonschema:"description=the func signature of the node"`
File string `json:"file,omitempty" jsonschema:"description=the file path of the node"`
Line int `json:"line,omitempty" jsonschema:"description=the line of the node"`
Codes string `json:"codes,omitempty" jsonschema:"description=the codes of the node"`
Dependencies []NodeID `json:"dependencies,omitempty" jsonschema:"description=the dependencies of the node"`
References []NodeID `json:"references,omitempty" jsonschema:"description=the references of the node"`
Implements []NodeID `json:"implements,omitempty" jsonschema:"description=the implements of the node"`
Groups []NodeID `json:"groups,omitempty" jsonschema:"description=the groups of the node"`
Inherits []NodeID `json:"inherits,omitempty" jsonschema:"description=the inherits of the node"`
}

type NodeID struct {
Expand Down Expand Up @@ -366,6 +368,17 @@ func (t *ASTReadTools) GetPackageStructure(ctx context.Context, req GetPackageSt
}
}
}

if len(resp.Files) == 0 {
candidates := []string{}
if mod, ok := repo.Modules[req.ModPath]; ok {
for p := range mod.Packages {
candidates = append(candidates, p)
}
}
resp.Error = fmt.Sprintf("package '%s' not found, maybe you want one of %v", req.PkgPath, candidates)
}

log.Debug("get repo structure, resp: %v", abutil.MarshalJSONIndentNoError(resp))
return resp, nil
}
Expand Down Expand Up @@ -398,10 +411,11 @@ func (t *ASTReadTools) getFileStructure(_ context.Context, req GetFileStructReq,
}

resp := new(GetFileStructResp)
file, _ := repo.GetFile(req.FilePath)
file, mod := repo.GetFile(req.FilePath)
if file == nil {
return nil, fmt.Errorf("file '%s' not found", req.FilePath)
}

nodes := repo.GetFileNodes(req.FilePath)
ff := FileStruct{
FilePath: req.FilePath,
Expand All @@ -411,7 +425,9 @@ func (t *ASTReadTools) getFileStructure(_ context.Context, req GetFileStructReq,
}
for _, n := range nodes {
nn := NodeStruct{
Name: n.Identity.Name,
ModPath: mod.Name,
PkgPath: file.Package,
Name: n.Identity.Name,
}
if needNodeDetail {
nn.Type = n.Type.String()
Expand Down Expand Up @@ -487,6 +503,11 @@ func (t *ASTReadTools) GetASTNode(_ context.Context, params GetASTNodeReq) (*Get
Groups: grps,
})
}

if len(resp.Nodes) == 0 {
resp.Error = "node not found, maybe you should check the pkg_path or node_name?"
}

log.Debug("get repo structure, resp: %v", abutil.MarshalJSONIndentNoError(resp))
return resp, nil
}
5 changes: 2 additions & 3 deletions llm/tool/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"reflect"
"testing"

"github.com/cloudwego/abcoder/lang/uniast"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/components/tool/utils"
"github.com/cloudwego/eino/schema"
Expand Down Expand Up @@ -121,7 +120,7 @@ func TestASTTools_GetFileStructure(t *testing.T) {
in0: context.Background(),
req: GetFileStructReq{
RepoName: "localsession",
FilePath: "backup/metainfo.go",
FilePath: "backup/metainfo_test.go",
},
},
},
Expand Down Expand Up @@ -301,7 +300,7 @@ func TestASTTools_GetASTNode(t *testing.T) {
in0: context.Background(),
params: GetASTNodeReq{
RepoName: "localsession",
NodeIDs: []uniast.Identity{
NodeIDs: []NodeID{
{
ModPath: "github.com/cloudwego/localsession",
PkgPath: "github.com/cloudwego/localsession/backup",
Expand Down
Loading