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
3 changes: 1 addition & 2 deletions src/agents/definitions/debug.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ prompts:
taskPrompt: |
Analyze and process the work item with ID: <%= it.cardId %>. The work item data has been pre-loaded.

backend:
needsGitHubToken: false
backend: {}


hint: Analyze the current issue fully before moving to the next.
3 changes: 1 addition & 2 deletions src/agents/definitions/email-joke.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ prompts:
Only emails from **<%= it.senderEmail %>** were included in the search.
<% } %>

backend:
needsGitHubToken: false
backend: {}


trailingMessage: {}
Expand Down
1 change: 0 additions & 1 deletion src/agents/definitions/implementation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ prompts:
Analyze and process the work item with ID: <%= it.cardId %>. The work item data has been pre-loaded.

backend:
needsGitHubToken: true
hooks:
scm:
enableStopHooks: true
Expand Down
3 changes: 1 addition & 2 deletions src/agents/definitions/planning.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ prompts:
taskPrompt: |
Analyze and process the work item with ID: <%= it.cardId %>. The work item data has been pre-loaded.

backend:
needsGitHubToken: false
backend: {}


hint: Complete the current planning step efficiently before moving to the next.
17 changes: 16 additions & 1 deletion src/agents/definitions/profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import type { AgentInput } from '../../types/index.js';
import type { Capability, IntegrationChecker } from '../capabilities/index.js';
import {
deriveRequiredIntegrations,
getGadgetNamesFromCapabilities,
getSdkToolsFromCapabilities,
resolveEffectiveCapabilities,
Expand Down Expand Up @@ -115,6 +116,20 @@ function getAllCapabilities(caps: AgentCapabilities): Capability[] {
return [...caps.required, ...caps.optional];
}

/**
* Derive whether an agent requires GitHub token access.
*
* Checks explicit integrations first (def.integrations.required contains 'scm'),
* then falls back to capability-derived integrations when explicit integrations
* are not declared.
*/
function requiresScmIntegration(def: AgentDefinition): boolean {
if (def.integrations?.required) {
return def.integrations.required.includes('scm');
}
return deriveRequiredIntegrations(def.capabilities.required).includes('scm');
}

/**
* Resolve the context pipeline for a given trigger event.
*
Expand Down Expand Up @@ -186,7 +201,7 @@ function buildProfileFromDefinition(def: AgentDefinition, agentType: string): Ag
},
sdkTools,
enableStopHooks: scmHooks.enableStopHooks ?? false,
needsGitHubToken: def.backend.needsGitHubToken,
needsGitHubToken: requiresScmIntegration(def),
...(scmHooks.blockGitPush !== undefined && { blockGitPush: scmHooks.blockGitPush }),
...(scmHooks.requiresPR && { requiresPR: true }),
...(scmHooks.requiresReview && { requiresReview: true }),
Expand Down
1 change: 0 additions & 1 deletion src/agents/definitions/respond-to-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ prompts:
CI checks have failed. Analyze the failures and fix them.

backend:
needsGitHubToken: true
hooks:
scm:
enableStopHooks: true
Expand Down
3 changes: 1 addition & 2 deletions src/agents/definitions/respond-to-planning-comment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ prompts:
The work item data (title, description, checklists, attachments, comments) has been pre-loaded above.
Read the user's comment carefully and classify it: if they ask a question or request clarification, reply with a thorough answer via PostComment (do not modify the plan). If they request plan changes, make surgical, targeted updates. If the comment contains both a question and a change request, do both. Default to plan updates when intent is ambiguous.

backend:
needsGitHubToken: false
backend: {}


hint: Complete the current task efficiently before moving to the next.
1 change: 0 additions & 1 deletion src/agents/definitions/respond-to-pr-comment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ prompts:
Read the comment carefully and respond accordingly. If they ask for code changes, make the changes, commit, and push. If they ask a question, reply with a PR comment. Default to surgical, targeted changes unless they clearly ask for something broader.

backend:
needsGitHubToken: true
hooks:
scm:
enableStopHooks: true
Expand Down
1 change: 0 additions & 1 deletion src/agents/definitions/respond-to-review.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ prompts:
Carefully read each review comment and make the requested changes. Commit and push your changes when done. Use the ReplyToReviewComment tool to respond to individual review comments as you address them. Focus on surgical, targeted fixes unless the reviewer clearly asks for broader changes.

backend:
needsGitHubToken: true
hooks:
scm:
enableStopHooks: true
Expand Down
1 change: 0 additions & 1 deletion src/agents/definitions/review.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ prompts:
Examine the code changes carefully and submit your review using CreatePRReview.

backend:
needsGitHubToken: true
hooks:
scm:
enableStopHooks: false
Expand Down
7 changes: 6 additions & 1 deletion src/agents/definitions/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,12 @@ const BackendSchema = z.object({
* Kept for backward compatibility — new format wins when both are present.
*/
enableStopHooks: z.boolean().optional(),
needsGitHubToken: z.boolean(),
/**
* @deprecated No longer read from agent definitions.
* GitHub token access is now derived from `integrations.required` containing 'scm'.
* Kept optional for backward compatibility — ignored during parsing.
*/
needsGitHubToken: z.boolean().optional(),
/**
* @deprecated Use hooks.scm.blockGitPush instead.
* Kept for backward compatibility — new format wins when both are present.
Expand Down
3 changes: 1 addition & 2 deletions src/agents/definitions/splitting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ prompts:
taskPrompt: |
Analyze and process the work item with ID: <%= it.cardId %>. The work item data has been pre-loaded.

backend:
needsGitHubToken: false
backend: {}


hint: Gather all context needed for the current step before proceeding.
8 changes: 4 additions & 4 deletions tests/unit/agents/definitions/loader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ describe('YAML agent definitions loader', () => {
expect(caps.canUpdateChecklists).toBe(true);
expect(caps.isReadOnly).toBe(false);
expect(def.backend.hooks?.scm?.enableStopHooks).toBe(true);
expect(def.backend.needsGitHubToken).toBe(true);
expect(def.integrations?.required).toContain('scm');
});

it('review agent is read-only', async () => {
Expand All @@ -269,15 +269,15 @@ describe('YAML agent definitions loader', () => {
expect(caps.canEditFiles).toBe(false);
expect(caps.isReadOnly).toBe(true);
expect(def.backend.hooks?.scm?.enableStopHooks).toBe(false);
expect(def.backend.needsGitHubToken).toBe(true);
expect(def.integrations?.required).toContain('scm');
});

it('respond-to-ci agent has needsGitHubToken', async () => {
it('respond-to-ci agent requires scm integration', async () => {
const def = loadAgentDefinition('respond-to-ci');
const caps = await getAgentCapabilities('respond-to-ci');

expect(caps.canEditFiles).toBe(true);
expect(def.backend.needsGitHubToken).toBe(true);
expect(def.integrations?.required).toContain('scm');
});

it('capabilities from getAgentCapabilities are derived correctly for all agents', async () => {
Expand Down
1 change: 0 additions & 1 deletion tests/unit/agents/definitions/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,6 @@ describe('AgentDefinitionSchema', () => {
strategies: {},
backend: {
enableStopHooks: false,
needsGitHubToken: false,
},
hint: 'Do the thing efficiently.',
prompts: {
Expand Down
1 change: 0 additions & 1 deletion tests/unit/api/routers/agentDefinitions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ function createMockDefinition(overrides?: Partial<AgentDefinition>): AgentDefini
strategies: {},
backend: {
enableStopHooks: true,
needsGitHubToken: true,
},
hint: 'A test agent',
trailingMessage: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const mockDefinition: AgentDefinition = {
},
backend: {
enableStopHooks: false,
needsGitHubToken: true,
blockGitPush: false,
},
hint: 'test hint',
Expand Down
13 changes: 1 addition & 12 deletions web/src/components/settings/agent-definition-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -431,17 +431,6 @@ function BackendSection({
/>
</div>
</div>

{/* Backend Settings */}
<div className="rounded-md border border-border p-3 space-y-2">
<div className="text-sm font-medium">Backend Settings</div>
<Toggle
checked={def.backend.needsGitHubToken}
onChange={(v) => setBackend('needsGitHubToken', v)}
label="Needs GitHub Token"
description="Agent receives GitHub token for API access. Required for PR creation and code reviews."
/>
</div>
</section>
);
}
Expand Down Expand Up @@ -968,7 +957,7 @@ const EMPTY_DEFINITION: AgentDefinition = {
},
triggers: [],
strategies: {},
backend: { needsGitHubToken: false },
backend: {},
hint: '',
trailingMessage: undefined,
prompts: {
Expand Down