job_kill.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package tools
  2. import (
  3. "context"
  4. _ "embed"
  5. "fmt"
  6. "charm.land/fantasy"
  7. "github.com/charmbracelet/crush/internal/shell"
  8. )
  9. const (
  10. JobKillToolName = "job_kill"
  11. )
  12. //go:embed job_kill.md
  13. var jobKillDescription []byte
  14. type JobKillParams struct {
  15. ShellID string `json:"shell_id" description:"The ID of the background shell to terminate"`
  16. }
  17. type JobKillResponseMetadata struct {
  18. ShellID string `json:"shell_id"`
  19. Command string `json:"command"`
  20. Description string `json:"description"`
  21. }
  22. func NewJobKillTool() fantasy.AgentTool {
  23. return fantasy.NewAgentTool(
  24. JobKillToolName,
  25. string(jobKillDescription),
  26. func(ctx context.Context, params JobKillParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
  27. if params.ShellID == "" {
  28. return fantasy.NewTextErrorResponse("missing shell_id"), nil
  29. }
  30. bgManager := shell.GetBackgroundShellManager()
  31. bgShell, ok := bgManager.Get(params.ShellID)
  32. if !ok {
  33. return fantasy.NewTextErrorResponse(fmt.Sprintf("background shell not found: %s", params.ShellID)), nil
  34. }
  35. metadata := JobKillResponseMetadata{
  36. ShellID: params.ShellID,
  37. Command: bgShell.Command,
  38. Description: bgShell.Description,
  39. }
  40. err := bgManager.Kill(params.ShellID)
  41. if err != nil {
  42. return fantasy.NewTextErrorResponse(err.Error()), nil
  43. }
  44. result := fmt.Sprintf("Background shell %s terminated successfully", params.ShellID)
  45. return fantasy.WithResponseMetadata(fantasy.NewTextResponse(result), metadata), nil
  46. })
  47. }