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
15 changes: 15 additions & 0 deletions .github/aw/actions-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
"version": "v5.0.5",
"sha": "27d5ce7f107fe9357f9df03efb73ab90386fccae"
},
"actions/checkout@v4": {
"repo": "actions/checkout",
"version": "v4",
"sha": "34e114876b0b11c390a56381ad16ebd13914f8d5"
},
"actions/checkout@v6.0.2": {
"repo": "actions/checkout",
"version": "v6.0.2",
Expand Down Expand Up @@ -88,6 +93,11 @@
"version": "v6.4.0",
"sha": "48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e"
},
"actions/setup-python@v5": {
"repo": "actions/setup-python",
"version": "v5",
"sha": "a26af69be951a213d495a4c3e4e4022e16d87065"
},
"actions/setup-python@v6.2.0": {
"repo": "actions/setup-python",
"version": "v6.2.0",
Expand Down Expand Up @@ -153,6 +163,11 @@
"version": "v9.0.11",
"sha": "56718cc2bafc8c0fc5fd66751e0b32a33ed36c22"
},
"github/stale-repos@v9.0.8": {
"repo": "github/stale-repos",
"version": "v9.0.8",
"sha": "5f2e18fc5432823f96c1feb69327f665c2acab59"
},
"haskell-actions/setup@v2.11.0": {
"repo": "haskell-actions/setup",
"version": "v2.11.0",
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/daily-geo-optimizer.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/smoke-otel-backends.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions .github/workflows/stale-repo-identifier.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion actions/setup/md/agentic_workflows_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ Call all operations as MCP tools with JSON parameters.
- Logs are saved to `/tmp/gh-aw/aw-mcp/logs/`

#### `audit` — Inspect a specific run
- `run_id_or_url`: numeric run ID, run URL, job URL, or job URL with step anchor
- `run_id`: run ID or run/job URL (including step anchors), as string or number (alias for `run_id_or_url`)
- `run_id_or_url`: run ID or run/job URL (including step anchors), as string or number
</agentic-workflows-guide>
1 change: 1 addition & 0 deletions pkg/cli/mcp_argument_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ func TestMCPToolParams(t *testing.T) {
case "audit":
// experiment and variant were previously missing from the hardcoded map;
// reflection must now include them automatically.
assert.Contains(t, toolParams, "run_id", "audit tool must include 'run_id' alias param")
assert.Contains(t, toolParams, "experiment", "audit tool must include 'experiment' param")
assert.Contains(t, toolParams, "variant", "audit tool must include 'variant' param")
}
Expand Down
51 changes: 46 additions & 5 deletions pkg/cli/mcp_tools_privileged.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"os"
"os/exec"
"strconv"
Expand Down Expand Up @@ -250,14 +251,39 @@ from where the previous request stopped due to timeout.`,

// auditArgs holds the input parameters for the audit tool.
type auditArgs struct {
RunIDOrURL string `json:"run_id_or_url,omitempty" jsonschema:"Deprecated: use run_ids_or_urls instead. Single GitHub Actions workflow run ID or URL."`
RunID any `json:"run_id,omitempty" jsonschema:"Alias for run_id_or_url. Accepts run ID or run/job URL (including step anchors). String or number."`
RunIDOrURL any `json:"run_id_or_url,omitempty" jsonschema:"Deprecated: use run_ids_or_urls instead. Accepts run ID or run/job URL (including step anchors). String or number."`
RunIDsOrURLs []string `json:"run_ids_or_urls,omitempty" jsonschema:"One or more workflow run IDs or URLs. Single item: detailed audit report. Multiple items: diff mode with first as base (see tool description for accepted formats)."`
Artifacts []string `json:"artifacts,omitempty" jsonschema:"Artifact sets to download (default: all). Valid sets: all, activation, agent, detection, firewall, github-api, mcp"`
MaxTokens int `json:"max_tokens,omitempty" jsonschema:"Deprecated: accepted for backward compatibility but ignored."`
Experiment string `json:"experiment,omitempty" jsonschema:"Filter to runs that include this experiment name. When set, runs whose experiment artifact does not contain an assignment for this experiment name are skipped."`
Variant string `json:"variant,omitempty" jsonschema:"Filter to runs assigned this specific variant value. Requires experiment to be set."`
}

// normalizeAuditRunInput converts a single-run audit input (run_id or
// run_id_or_url) from supported MCP argument types into the CLI positional
// argument format. The bool return indicates whether a non-empty value was
// provided.
func normalizeAuditRunInput(input any, fieldName string) (string, bool, error) {
switch v := input.(type) {
case nil:
return "", false, nil
case string:
if strings.TrimSpace(v) == "" {
return "", false, nil
}
return v, true, nil
case float64:
return strconv.FormatFloat(v, 'f', -1, 64), true, nil
case int:
return strconv.Itoa(v), true, nil
case int64:
return strconv.FormatInt(v, 10), true, nil
default:
return "", false, fmt.Errorf("%s must be a string or number", fieldName)
}
}

// registerAuditTool registers the audit tool with the MCP server.
// The audit tool requires write+ access and checks actor permissions.
// Returns an error if schema generation fails.
Expand Down Expand Up @@ -329,13 +355,28 @@ Multi-run diff returns JSON describing changes between the base and each compari
}

// Resolve the list of run IDs/URLs to pass to the audit command.
// run_ids_or_urls takes precedence; fall back to the deprecated run_id_or_url field.
// run_ids_or_urls takes precedence; fall back to run_id, then deprecated run_id_or_url.
runItems := args.RunIDsOrURLs
if len(runItems) == 0 && args.RunIDOrURL != "" {
runItems = []string{args.RunIDOrURL}
if len(runItems) == 0 {
runID, hasRunID, err := normalizeAuditRunInput(args.RunID, "run_id")
if err != nil {
return nil, nil, newMCPError(jsonrpc.CodeInvalidParams, err.Error(), nil)
}
if hasRunID {
runItems = []string{runID}
}
}
if len(runItems) == 0 {
runIDOrURL, hasRunIDOrURL, err := normalizeAuditRunInput(args.RunIDOrURL, "run_id_or_url")
if err != nil {
return nil, nil, newMCPError(jsonrpc.CodeInvalidParams, err.Error(), nil)
}
if hasRunIDOrURL {
runItems = []string{runIDOrURL}
}
}
if len(runItems) == 0 {
return nil, nil, newMCPError(jsonrpc.CodeInvalidParams, "at least one run ID or URL must be provided via run_ids_or_urls or run_id_or_url", nil)
return nil, nil, newMCPError(jsonrpc.CodeInvalidParams, "at least one run ID or URL must be provided via run_ids_or_urls, run_id, or run_id_or_url", nil)
}

// Build command arguments.
Expand Down
Loading
Loading