diff --git a/server/src/addie/mcp/member-tools.ts b/server/src/addie/mcp/member-tools.ts index 92dffdbe18..a1cb4150eb 100644 --- a/server/src/addie/mcp/member-tools.ts +++ b/server/src/addie/mcp/member-tools.ts @@ -76,7 +76,7 @@ import { getTestKitForStoryboard } from '../../services/storyboards.js'; import { hostedComplianceTarget, hostedComplianceOptions, - HOSTED_FULL_COMPLIANCE_TIMEOUT_MS, + HOSTED_INTERACTIVE_COMPLIANCE_TIMEOUT_MS, hostedAuthProbeTaskForProfile, withHostedStoryboardRunOptions, withHostedTestOptions, @@ -4650,7 +4650,7 @@ export function createMemberToolHandlers( const complyOptions: ComplyOptions = { test_session_id: `quality-eval-${Date.now()}`, - timeout_ms: HOSTED_FULL_COMPLIANCE_TIMEOUT_MS, + timeout_ms: HOSTED_INTERACTIVE_COMPLIANCE_TIMEOUT_MS, auth: authOption, }; if (tracks) complyOptions.tracks = tracks; diff --git a/server/src/services/hosted-compliance-version.ts b/server/src/services/hosted-compliance-version.ts index a829023366..fda49be15f 100644 --- a/server/src/services/hosted-compliance-version.ts +++ b/server/src/services/hosted-compliance-version.ts @@ -25,6 +25,14 @@ export const HOSTED_COMPLIANCE_TARGET_PREFERENCE = [ // a single hung call hold a connection for 10 minutes. export const HOSTED_FULL_COMPLIANCE_TIMEOUT_MS = 600_000; +// Interactive full-suite runs (evaluate_agent_quality via Addie) need a higher +// ceiling: 67 storyboards × 17s worst-case step pacing = ~1139s, plus headroom +// for target discovery and network jitter. The background callers (heartbeat, +// registry refresh) keep the shared 600s constant so heartbeat lock TTLs and +// hung-call risk stay bounded. +// TODO(adcontextprotocol/adcp-client#2221): collapse when upstream per-call timeout is restored +export const HOSTED_INTERACTIVE_COMPLIANCE_TIMEOUT_MS = 1_200_000; + export interface HostedComplianceTarget { requested: string; version: string; diff --git a/server/tests/unit/storyboards.test.ts b/server/tests/unit/storyboards.test.ts index 65e7ce70b0..cb28930e04 100644 --- a/server/tests/unit/storyboards.test.ts +++ b/server/tests/unit/storyboards.test.ts @@ -15,6 +15,7 @@ import { DEFAULT_HOSTED_COMPLIANCE_LINE, DEFAULT_HOSTED_COMPLIANCE_VERSION, HOSTED_FULL_COMPLIANCE_TIMEOUT_MS, + HOSTED_INTERACTIVE_COMPLIANCE_TIMEOUT_MS, badgeEligibleVersionsForHostedComplianceTarget, hostedAuthProbeTaskForProfile, hostedStaticApiKeyForProfile, @@ -194,6 +195,7 @@ describe('wrapper contract', () => { expect(DEFAULT_HOSTED_COMPLIANCE_VERSION).toBe('3.0.25'); expect(DEFAULT_HOSTED_COMPLIANCE_LINE).toBe('3.0'); expect(HOSTED_FULL_COMPLIANCE_TIMEOUT_MS).toBe(600_000); + expect(HOSTED_INTERACTIVE_COMPLIANCE_TIMEOUT_MS).toBe(1_200_000); expect(target.requested).toBe(DEFAULT_HOSTED_COMPLIANCE_LINE); expect(target.version).toBe(DEFAULT_HOSTED_COMPLIANCE_VERSION); expect(target.version).toMatch(/^3\.0\.\d+$/); diff --git a/tests/addie/member-tools.test.ts b/tests/addie/member-tools.test.ts index 4b4b9a0428..841526ca53 100644 --- a/tests/addie/member-tools.test.ts +++ b/tests/addie/member-tools.test.ts @@ -68,6 +68,7 @@ import { MEMBER_TOOLS, createMemberToolHandlers } from '../../server/src/addie/m import { getGitHubAccessToken } from '../../server/src/services/pipes.js'; import { AgentContextDatabase } from '../../server/src/db/agent-context-db.js'; import { ComplianceDatabase } from '../../server/src/db/compliance-db.js'; +import { HOSTED_INTERACTIVE_COMPLIANCE_TIMEOUT_MS } from '../../server/src/services/hosted-compliance-version.js'; import { AgentSnapshotDatabase } from '../../server/src/db/agent-snapshot-db.js'; import * as wgService from '../../server/src/services/working-group-membership-service.js'; @@ -1164,6 +1165,13 @@ describe('createMemberToolHandlers', () => { expect(result).toContain('Quality Evaluation: Seller Agent'); expect(result).not.toContain('diagnostic only'); + expect(memberToolMocks.comply).toHaveBeenCalledWith( + expect.any(String), + expect.objectContaining({ + timeout_ms: HOSTED_INTERACTIVE_COMPLIANCE_TIMEOUT_MS, + }), + expect.objectContaining({ requested: '3.0' }), + ); expect(ComplianceDatabase.prototype.recordComplianceRun).toHaveBeenCalledTimes(1); expect(ComplianceDatabase.prototype.recordComplianceRun).toHaveBeenCalledWith( expect.objectContaining({