MCPcopy Index your code
hub / github.com/coder/coder / ReadSkillFile

Function ReadSkillFile

coderd/x/chatd/chattool/skill.go:349–418  ·  view source on GitHub ↗

ReadSkillFile returns an AgentTool that reads a supporting file from a skill's directory.

(options ReadSkillOptions)

Source from the content-addressed store, hash-verified

347// ReadSkillFile returns an AgentTool that reads a supporting file
348// from a skill's directory.
349func ReadSkillFile(options ReadSkillOptions) fantasy.AgentTool {
350 return fantasy.NewAgentTool(
351 "read_skill_file",
352 "Read a supporting file from a skill's directory "+
353 "(e.g. roles/security-reviewer.md).",
354 func(ctx context.Context, args ReadSkillFileArgs, _ fantasy.ToolCall) (fantasy.ToolResponse, error) {
355 if args.Name == "" {
356 return fantasy.NewTextErrorResponse(
357 "name is required",
358 ), nil
359 }
360 if args.Path == "" {
361 return fantasy.NewTextErrorResponse(
362 "path is required",
363 ), nil
364 }
365
366 resolved, err := resolveSkillAlias(options, args.Name)
367 if err != nil {
368 return skillResolveErrorResponse(args.Name, err), nil
369 }
370 if resolved.Source == skillspkg.SourcePersonal {
371 return fantasy.NewTextErrorResponse(
372 "read_skill_file is not supported for personal skills (no supporting files)",
373 ), nil
374 }
375 if resolved.Source != skillspkg.SourceWorkspace {
376 return skillNotFoundResponse(args.Name), nil
377 }
378
379 skill, ok := findSkill(options.GetSkills, resolved.Name)
380 if !ok {
381 return skillNotFoundResponse(args.Name), nil
382 }
383
384 // Validate the path early so we reject bad
385 // inputs before dialing the workspace agent.
386 if err := validateSkillFilePath(args.Path); err != nil {
387 return fantasy.NewTextErrorResponse(
388 err.Error(),
389 ), nil
390 }
391
392 if options.GetWorkspaceConn == nil {
393 return fantasy.NewTextErrorResponse(
394 "workspace connection resolver is not configured",
395 ), nil
396 }
397 conn, err := options.GetWorkspaceConn(ctx)
398 if err != nil {
399 return fantasy.NewTextErrorResponse(
400 err.Error(),
401 ), nil
402 }
403
404 content, err := LoadSkillFile(
405 ctx, conn, skill, args.Path,
406 )

Callers 2

runChatMethod · 0.92
TestReadSkillFileToolFunction · 0.92

Calls 8

resolveSkillAliasFunction · 0.85
skillNotFoundResponseFunction · 0.85
findSkillFunction · 0.85
validateSkillFilePathFunction · 0.85
LoadSkillFileFunction · 0.85
toolResponseFunction · 0.85
ErrorMethod · 0.45

Tested by 1

TestReadSkillFileToolFunction · 0.74