-
Notifications
You must be signed in to change notification settings - Fork 15
feat: add generic explore agent #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
626639a
cb51891
c5950b4
7c14322
d3971cd
508affc
78a5160
d5778aa
981760c
297af25
fdfe25e
bdda3b1
a4fd578
1f20a90
1e9200b
3cb9c95
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # Explore Agent | ||
|
|
||
| Inspects a work item (GitHub issue or Jira ticket), gathers technical context from the target codebase, referenced repos, related work, and public web sources, then produces a structured exploration result for downstream agents. | ||
|
|
||
| ## How the agent works | ||
|
|
||
| The explore agent runs after a work item enters the refinement pipeline. A host pre-script fetches issue context and optionally shallow-clones public GitHub repos referenced in the issue. The agent researches inside a sandbox with read-only GitHub/Jira/web access, writes a schema-validated JSON result, and a post-script attaches the result, posts a sticky summary comment, and optionally applies pipeline labels. | ||
|
|
||
| Host pre-script uses runner credentials to fetch issue context and shallow-clone | ||
| public repos. The sandbox receives `GH_TOKEN` / Jira env via the harness for | ||
| read API fallbacks, constrained by OpenShell network policy (github.com, | ||
| api.github.com, configured Jira host). Prefer pre-cloned trees so the agent | ||
| rarely needs live git. | ||
|
|
||
| ## How it helps | ||
|
|
||
| - Downstream agents receive structured technical landscape, related work, and definition gaps instead of raw issue text. | ||
| - Referenced repos are pre-cloned so the agent can grep and inspect code without live git clones in the sandbox. | ||
| - Confidence scoring and optional pipeline labels signal when a work item is ready for the next stage. | ||
|
|
||
| ## Platform support | ||
|
|
||
| | Source | Pre-script | Post-script | | ||
| |--------|------------|-------------| | ||
| | GitHub | `gh issue view`, sub-issues | Sticky comment via `fullsend post-comment`, optional labels | | ||
| | Jira | REST API + ADF conversion, hierarchy | Attachment + sticky ADF comment, optional labels | | ||
|
|
||
| Set `ISSUE_SOURCE` to `jira` or `github`. The agent prompt also accepts `text` and `web` as input source values in the output JSON when the work item did not originate from a tracker. | ||
|
|
||
| ## Optional pipeline labels | ||
|
|
||
| Labels are opt-in via runner env vars — the generic agent does not hardcode team-specific label names: | ||
|
|
||
| | Env var | Purpose | | ||
| |---------|---------| | ||
| | `EXPLORE_READY_LABEL` | Applied when confidence ≥ threshold | | ||
| | `EXPLORE_NEEDS_INFO_LABEL` | Applied when confidence < threshold | | ||
| | `EXPLORE_CONFIDENCE_THRESHOLD` | Minimum confidence for ready label (default: 2.5, scale 0–5) | | ||
|
|
||
| GitHub labels must already exist in the repo; the post-script will not auto-create them. | ||
|
|
||
| ## Configuration and extension | ||
|
|
||
| Register the agent via harness `base:` composition. Downstream configs (e.g. team refinement hubs) add skills and env overrides: | ||
|
|
||
| ```yaml | ||
| base: https://raw.githubusercontent.com/fullsend-ai/agents/main/harness/explore.yaml | ||
| skills: | ||
| - skills/jira-routing # team-specific | ||
| env: | ||
| runner: | ||
| EXPLORE_READY_LABEL: ready-to-refine | ||
| EXPLORE_NEEDS_INFO_LABEL: needs-info | ||
| ``` | ||
|
|
||
| Built-in skills: `public-research`, `jira-read`. | ||
|
|
||
| ## Output | ||
|
|
||
| The agent writes `agent-result.json` validated against `schemas/explore-result.schema.json`. The post-script copies it to `exploration_context.json` and attaches it to Jira issues for re-runs. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| export ISSUE_CONTEXT=/tmp/workspace/issue-context.json | ||
| export FULLSEND_OUTPUT_DIR=/sandbox/workspace/output | ||
| export REFERENCED_REPOS_DIR=/sandbox/workspace/referenced-repos | ||
| export ORG_KNOWLEDGE=/sandbox/workspace/org-knowledge.md |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| --- | ||
| doc: docs/explore.md | ||
| agent: agents/explore.md | ||
| model: opus | ||
| image: ghcr.io/fullsend-ai/fullsend-sandbox:latest | ||
| policy: policies/explore.yaml | ||
|
|
||
| role: explore | ||
| slug: fullsend-ai-explore | ||
|
|
||
| host_files: | ||
| - src: common/env/gcp-vertex.env | ||
| dest: /sandbox/workspace/.env.d/gcp-vertex.env | ||
| expand: true | ||
| - src: env/explore.env | ||
| dest: /sandbox/workspace/.env.d/explore.env | ||
| expand: true | ||
| - src: ${GOOGLE_APPLICATION_CREDENTIALS} | ||
| dest: /tmp/.gcp-credentials.json | ||
| - src: ${GCP_OIDC_TOKEN_FILE} | ||
| dest: /sandbox/workspace/.gcp-oidc-token | ||
| optional: true | ||
|
|
||
| skills: | ||
| - skills/public-research | ||
| - skills/jira-read | ||
|
|
||
| pre_script: scripts/pre-explore.sh | ||
| post_script: scripts/post-explore.sh | ||
|
|
||
| validation_loop: | ||
| script: scripts/validate-output-schema.sh | ||
| schema: schemas/explore-result.schema.json | ||
| max_iterations: 2 | ||
|
|
||
| env: | ||
| runner: | ||
| ISSUE_KEY: ${ISSUE_KEY} | ||
| ISSUE_SOURCE: ${ISSUE_SOURCE} | ||
| REPO_FULL_NAME: ${REPO_FULL_NAME} | ||
| GITHUB_ISSUE_NUMBER: ${GITHUB_ISSUE_NUMBER} | ||
| GH_TOKEN: ${GH_TOKEN} | ||
| JIRA_HOST: ${JIRA_HOST} | ||
| JIRA_EMAIL: ${JIRA_EMAIL} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [medium] secret-exposure The harness passes JIRA_EMAIL, JIRA_HOST, and JIRA_API_TOKEN into the sandbox (env.sandbox). docs/explore.md states 'Credentials stay on the runner — they never enter the sandbox' which is a factual contradiction. Suggested fix: Either remove JIRA_* credentials from env.sandbox or update docs/explore.md to accurately reflect that Jira credentials do enter the sandbox. |
||
| JIRA_API_TOKEN: ${JIRA_API_TOKEN} | ||
| EXPLORE_CONFIDENCE_THRESHOLD: ${EXPLORE_CONFIDENCE_THRESHOLD} | ||
| EXPLORE_READY_LABEL: ${EXPLORE_READY_LABEL} | ||
| EXPLORE_NEEDS_INFO_LABEL: ${EXPLORE_NEEDS_INFO_LABEL} | ||
| REFERENCED_REPOS_DIR: /sandbox/workspace/referenced-repos | ||
| FULLSEND_OUTPUT_SCHEMA: ${FULLSEND_DIR}/schemas/explore-result.schema.json | ||
| sandbox: | ||
| ISSUE_KEY: "${ISSUE_KEY}" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [medium] secret-exposure The harness config passes JIRA_EMAIL, JIRA_HOST, and JIRA_API_TOKEN into the sandbox environment (env.sandbox block). docs/explore.md states 'Credentials stay on the runner -- they never enter the sandbox' which is a factual contradiction. The credentials are present inside the sandbox and the agent prompt instructs their use. Suggested fix: Either remove JIRA_* credentials from env.sandbox and have the pre-script fetch all needed Jira data, or update docs/explore.md to accurately reflect that Jira credentials do enter the sandbox. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [medium] secret-exposure The harness config passes JIRA_EMAIL, JIRA_HOST, and JIRA_API_TOKEN into the sandbox environment (env.sandbox block). The docs/explore.md states 'Credentials stay on the runner — they never enter the sandbox' which is a factual contradiction. The agent prompt acknowledges the credentials are in-sandbox. Suggested fix: Either remove JIRA credentials from env.sandbox and have the pre-script fetch all needed Jira data, or update docs/explore.md to accurately reflect that Jira credentials enter the sandbox. |
||
| ISSUE_SOURCE: "${ISSUE_SOURCE}" | ||
| REPO_FULL_NAME: "${REPO_FULL_NAME}" | ||
| # Read-only Jira lookups for related projects (KFLUXUI/STONEINTG/etc.). | ||
| JIRA_HOST: "${JIRA_HOST}" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [medium] secret-exposure The harness config passes JIRA_EMAIL, JIRA_HOST, and JIRA_API_TOKEN into the sandbox environment (env.sandbox block). docs/explore.md (line 9) states Credentials stay on the runner -- they never enter the sandbox which is a factual contradiction. The agent prompt correctly acknowledges the credentials are in-sandbox. Suggested fix: Update docs/explore.md to accurately reflect that Jira credentials do enter the sandbox for read-only related-project lookups. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [medium] secret-exposure The harness config passes JIRA_EMAIL, JIRA_HOST, JIRA_API_TOKEN into the sandbox environment. docs/explore.md line 9 states Credentials stay on the runner which is a factual contradiction. The network policy enforces read-only access but the documentation is misleading. Suggested fix: Update docs/explore.md to accurately reflect that Jira credentials enter the sandbox for read-only related-project lookups. |
||
| JIRA_EMAIL: "${JIRA_EMAIL}" | ||
| JIRA_API_TOKEN: "${JIRA_API_TOKEN}" | ||
|
|
||
| timeout_minutes: 20 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| version: 1 | ||
|
|
||
| filesystem_policy: | ||
| include_workdir: true | ||
| read_only: [/usr, /lib, /proc, /dev/urandom, /app, /etc, /var/log] | ||
| read_write: [/sandbox, /tmp, /dev/null] | ||
| landlock: | ||
| compatibility: best_effort | ||
| process: | ||
| run_as_user: sandbox | ||
| run_as_group: sandbox | ||
|
|
||
| network_policies: | ||
| vertex_ai: | ||
| name: vertex-ai | ||
| endpoints: | ||
| - host: "api.anthropic.com" | ||
| port: 443 | ||
| protocol: rest | ||
| enforcement: enforce | ||
| access: read-write | ||
| - host: "*.googleapis.com" | ||
| port: 443 | ||
| protocol: rest | ||
| enforcement: enforce | ||
| access: read-write | ||
| binaries: | ||
| - path: "**/claude" | ||
| - path: "**/node" | ||
|
|
||
| github_api: | ||
| name: github-api | ||
| endpoints: | ||
| - host: "api.github.com" | ||
| port: 443 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [moderate] The explore agent is described as read-only, and the post-script handles all writes from the host. But this policy grants |
||
| protocol: rest | ||
| enforcement: enforce | ||
| access: read-write | ||
| - host: "github.com" | ||
| port: 443 | ||
| protocol: rest | ||
| enforcement: enforce | ||
| access: read-write | ||
| - host: "raw.githubusercontent.com" | ||
| port: 443 | ||
| protocol: rest | ||
| enforcement: enforce | ||
| access: read-only | ||
| binaries: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [medium] security *.google.com wildcard allows connections to any Google subdomain including storage.googleapis.com which could be used for data exfiltration. Suggested fix: Restrict to specific subdomains needed for search (e.g., www.google.com)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in |
||
| - path: "**/gh" | ||
| - path: "**/git" | ||
| - path: "**/node" | ||
| - path: "**/curl" | ||
|
|
||
| jira_api: | ||
| name: jira-api | ||
| endpoints: | ||
| - host: "*.atlassian.net" | ||
| port: 443 | ||
| protocol: rest | ||
| enforcement: enforce | ||
| access: read-only | ||
| binaries: | ||
| - path: "**/curl" | ||
| - path: "**/node" | ||
|
|
||
| web_search: | ||
| name: web-search | ||
| endpoints: | ||
| - host: "api.tavily.com" | ||
| port: 443 | ||
| protocol: rest | ||
| enforcement: enforce | ||
| access: read-write | ||
| - host: "www.google.com" | ||
| port: 443 | ||
| protocol: rest | ||
| enforcement: enforce | ||
| access: read-only | ||
| binaries: | ||
| - path: "**/curl" | ||
| - path: "**/node" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] (non-blocking) The example label
ready-to-refinebakes in a pipeline-specific name. Since the docs emphasize labels are generic and opt-in, something likeexplore-completewould reinforce that.