Skip to content

refactor(tool): unify integrations on gollem-dev/tools, add Jira and Falcon#225

Open
m-mizutani wants to merge 3 commits into
mainfrom
worktree-effervescent-mixing-key
Open

refactor(tool): unify integrations on gollem-dev/tools, add Jira and Falcon#225
m-mizutani wants to merge 3 commits into
mainfrom
worktree-effervescent-mixing-key

Conversation

@m-mizutani

Copy link
Copy Markdown
Contributor

Summary

Unifies all external integrations under pkg/tool/* (backed by github.com/gollem-dev/tools) and retires the legacy pkg/agents "sub-agent" framework.

  • Dependency modernization: bump gollem-dev/tools slack/github/webfetch to v0.2.0; add falcon/jira.
  • New tools: pkg/tool/falcon (CrowdStrike Falcon, WARREN_FALCON_*) and pkg/tool/jira (Jira Cloud, WARREN_JIRA_*), both read-only wrappers over gollem-dev/tools, registered in pkg/cli/utils.go.
  • Removed pkg/agents entirely: the Falcon, Slack, and BigQuery sub-agents plus the framework (agents.go/factory.go) and their serve/chat wiring. Falcon → pkg/tool/falcon; Slack → existing pkg/tool/slack; BigQuery → existing pkg/tool/bigquery (a functional superset of the old agent).
  • Removed the chat "sub-agent" budget concept: subAgentToolNames and the unused context-tracker sharing machinery (withBudgetTracker/budgetTrackerFrom/newContextAwareBudgetMiddleware) in both aster and bluebell. The per-task fixed-tracker path is unchanged.
  • Docs: new tool READMEs, updated root README.md / alert-investigation.md / configuration.md (including the previously-undocumented BigQuery tool settings), removed the stale "Agent Memory" section, and added doc/migration/v0.18.0.md.

Breaking changes (configuration only — no data migration)

Operators must rename environment variables:

Old New
WARREN_AGENT_FALCON_* WARREN_FALCON_*
WARREN_AGENT_SLACK_USER_TOKEN WARREN_SLACK_TOOL_USER_TOKEN
WARREN_AGENT_BIGQUERY_* WARREN_BIGQUERY_*

See doc/migration/v0.18.0.md for full details.

Verification

  • go vet ./... — clean
  • go test ./... — all pass
  • golangci-lint run ./... — 0 issues
  • gosec — no findings

Known follow-up

.claude/rules/subagent-development.md was removed, but .claude/rules/documentation-updates.md still references the removed sub-agent flow — that edit was blocked by the self-modification guard and needs to be applied separately.

🤖 Generated with Claude Code

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors Warren (v0.18.0) by retiring the legacy pkg/agents sub-agent framework and unifying all external integrations as standard tools under pkg/tool/*. Specifically, CrowdStrike Falcon and Slack search are migrated to standard tools, a new read-only Jira tool is introduced, and the budget tracking logic is simplified. The code review feedback focuses on cleaning up the configuration logic for the new Falcon and Jira tools, recommending the removal of unused fields, the dynamic construction of configuration options inside the Configure methods rather than during flag parsing, and the simplification of associated test helpers.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread pkg/tool/falcon/action.go
Comment on lines +22 to +29
type Action struct {
clientID string
clientSecret string
baseURL string

opts []extfalcon.Option
inner gollem.ToolSet
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The opts field in the Action struct is used to accumulate configuration options during flag parsing. However, this is fragile and can lead to duplicate options if flags are parsed multiple times. It is cleaner to construct the options slice dynamically inside the Configure method.

type Action struct {
	clientID     string
	clientSecret string
	baseURL      string

	inner gollem.ToolSet
}

Comment thread pkg/tool/falcon/action.go
Comment on lines +61 to +72
&cli.StringFlag{
Name: "falcon-base-url",
Usage: "CrowdStrike Falcon API base URL",
Destination: &x.baseURL,
Category: "Tool",
Value: defaultBaseURL,
Sources: cli.EnvVars("WARREN_FALCON_BASE_URL"),
Action: func(_ context.Context, _ *cli.Command, v string) error {
x.opts = append(x.opts, extfalcon.WithBaseURL(v))
return nil
},
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Remove the Action callback from the falcon-base-url flag. Appending to a slice in a flag callback is fragile. Instead, we can read the parsed x.baseURL directly in the Configure method.

		&cli.StringFlag{
			Name:        "falcon-base-url",
			Usage:       "CrowdStrike Falcon API base URL",
			Destination: &x.baseURL,
			Category:    "Tool",
			Value:       defaultBaseURL,
			Sources:     cli.EnvVars("WARREN_FALCON_BASE_URL"),
		},

Comment thread pkg/tool/falcon/action.go
Comment on lines +76 to +87
func (x *Action) Configure(_ context.Context) error {
if x.clientID == "" || x.clientSecret == "" {
return errutil.ErrActionUnavailable
}

ts, err := extfalcon.New(x.clientID, x.clientSecret, x.opts...)
if err != nil {
return goerr.Wrap(err, "failed to configure Falcon tool")
}
x.inner = ts
return nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Construct the opts slice dynamically inside Configure using x.baseURL instead of relying on the flag callback.

func (x *Action) Configure(_ context.Context) error {
	if x.clientID == "" || x.clientSecret == "" {
		return errutil.ErrActionUnavailable
	}

	var opts []extfalcon.Option
	if x.baseURL != "" {
		opts = append(opts, extfalcon.WithBaseURL(x.baseURL))
	}

	ts, err := extfalcon.New(x.clientID, x.clientSecret, opts...)
	if err != nil {
		return goerr.Wrap(err, "failed to configure Falcon tool")
	}
	x.inner = ts
	return nil
}

Comment on lines +11 to +14
// SetTestURL points the underlying toolset at a stub server (test-only).
func (x *Action) SetTestURL(url string) {
x.opts = append(x.opts, extfalcon.WithBaseURL(url))
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since we removed the opts field from the Action struct, simplify SetTestURL to set x.baseURL directly.

Suggested change
// SetTestURL points the underlying toolset at a stub server (test-only).
func (x *Action) SetTestURL(url string) {
x.opts = append(x.opts, extfalcon.WithBaseURL(url))
}
// SetTestURL points the underlying toolset at a stub server (test-only).
func (x *Action) SetTestURL(url string) {
x.baseURL = url
}

Comment thread pkg/tool/jira/action.go
Comment on lines +19 to +26
type Action struct {
baseURL string
email string
apiToken string

opts []extjira.Option
inner gollem.ToolSet
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The opts field in the Action struct is completely unused. We can remove it to simplify the struct.

type Action struct {
	baseURL  string
	email    string
	apiToken string

	inner gollem.ToolSet
}

Comment thread pkg/tool/jira/action.go
Comment on lines +68 to +79
func (x *Action) Configure(_ context.Context) error {
if x.baseURL == "" || x.email == "" || x.apiToken == "" {
return errutil.ErrActionUnavailable
}

ts, err := extjira.New(x.baseURL, x.email, x.apiToken, x.opts...)
if err != nil {
return goerr.Wrap(err, "failed to configure Jira tool")
}
x.inner = ts
return nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Remove the unused x.opts... argument from the extjira.New call.

Suggested change
func (x *Action) Configure(_ context.Context) error {
if x.baseURL == "" || x.email == "" || x.apiToken == "" {
return errutil.ErrActionUnavailable
}
ts, err := extjira.New(x.baseURL, x.email, x.apiToken, x.opts...)
if err != nil {
return goerr.Wrap(err, "failed to configure Jira tool")
}
x.inner = ts
return nil
}
func (x *Action) Configure(_ context.Context) error {
if x.baseURL == "" || x.email == "" || x.apiToken == "" {
return errutil.ErrActionUnavailable
}
ts, err := extjira.New(x.baseURL, x.email, x.apiToken)
if err != nil {
return goerr.Wrap(err, "failed to configure Jira tool")
}
x.inner = ts
return nil
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant