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
11 changes: 7 additions & 4 deletions packages/cli/scripts/enterprise-package-smoke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@ function assertCliContracts() {
.map((adapter) => adapter.id)
.sort();
const expectedAdapterIds = [
'google-adk-python',
'google-adk-typescript',
'microsoft-agent-framework-dotnet',
'microsoft-agent-framework-python',
'openai-agents-python',
Expand Down Expand Up @@ -393,10 +395,11 @@ function assertCliContracts() {
fail(`published CLI is missing implemented Google ADK adapter ${googleId}`);
}
if (google.stability !== 'preview') {
fail(`${googleId} must remain preview until same-SHA qualification (observed: ${google.stability ?? 'missing'})`);
}
if (google.status === 'admitted') {
fail(`${googleId} must not be release-admitted without reviewed Linux/macOS/Windows evidence`);
fail(
`${googleId} must retain its preview stability label after release admission (observed: ${
google.stability ?? 'missing'
})`
);
}
}

Expand Down
26 changes: 18 additions & 8 deletions packages/cli/src/__tests__/agent-framework-project-kits.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import { readProjectMetadata } from '../utils/project-metadata.js';
import { listBundledAgentFrameworkReleaseAdmissions } from '../agent-frameworks/release-admission.js';

const roots: string[] = [];
const releaseAdmitted = listBundledAgentFrameworkReleaseAdmissions().length === 4;
const admittedAdapterIds = new Set(
listBundledAgentFrameworkReleaseAdmissions().map((admission) => admission.id)
);

afterEach(async () => {
await Promise.all(roots.splice(0).map((root) => fsExtra.remove(root)));
Expand Down Expand Up @@ -55,14 +57,22 @@ describe('agent framework project kits', () => {
expect(resolveAgentFrameworkProjectKit('agent.google-adk.python')?.adapterId).toBe(
'google-adk-python'
);
expect(isAdmittedAgentFrameworkProjectKit('agent.openai.python')).toBe(releaseAdmitted);
expect(isAdmittedAgentFrameworkProjectKit('agent.openai.typescript')).toBe(releaseAdmitted);
expect(isAdmittedAgentFrameworkProjectKit('agent.google-adk.python')).toBe(false);
expect(isAdmittedAgentFrameworkProjectKit('agent.google-adk.typescript')).toBe(false);
expect(isAdmittedAgentFrameworkProjectKit('agent.openai.python')).toBe(
admittedAdapterIds.has('openai-agents-python')
);
expect(isAdmittedAgentFrameworkProjectKit('agent.openai.typescript')).toBe(
admittedAdapterIds.has('openai-agents-typescript')
);
expect(isAdmittedAgentFrameworkProjectKit('agent.google-adk.python')).toBe(
admittedAdapterIds.has('google-adk-python')
);
expect(isAdmittedAgentFrameworkProjectKit('agent.google-adk.typescript')).toBe(
admittedAdapterIds.has('google-adk-typescript')
);
expect(
kits
.filter((kit) => kit.frameworkId !== 'google-adk')
.every((kit) => isAdmittedAgentFrameworkProjectKit(kit) === releaseAdmitted)
kits.every(
(kit) => isAdmittedAgentFrameworkProjectKit(kit) === admittedAdapterIds.has(kit.adapterId)
)
).toBe(true);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import {
} from '../agent-frameworks/index.js';

describe('agent framework release admission', () => {
it('admits exactly the four Microsoft and OpenAI adapters promoted from the reviewed v2 matrix', () => {
it('admits all six adapters promoted from the reviewed v2 matrix', () => {
const admissions = listBundledAgentFrameworkReleaseAdmissions();
expect(admissions.map((admission) => admission.id).sort()).toEqual([
'google-adk-python',
'google-adk-typescript',
'microsoft-agent-framework-dotnet',
'microsoft-agent-framework-python',
'openai-agents-python',
Expand All @@ -30,10 +32,6 @@ describe('agent framework release admission', () => {

for (const adapter of BUILTIN_AGENT_FRAMEWORK_ADAPTERS) {
const resolution = assessBundledAgentFrameworkRelease(adapter);
if (adapter.manifest.framework.id === 'google-adk') {
expect(resolution.status).toBe('blocked');
continue;
}
expect(resolution.status).toBe('admitted');
expect(resolution.blockers).toEqual([]);
}
Expand Down Expand Up @@ -96,7 +94,7 @@ describe('agent framework release admission', () => {
).not.toHaveProperty('releaseAdapter');
});

it('keeps stable-labeled OpenAI adapters visible and admitted after promotion', () => {
it('keeps admitted adapters visible with their declared stability after promotion', () => {
const registry = createBuiltinAgentFrameworkRegistry(
{},
{ trustReviewedReleaseAdmissions: true }
Expand All @@ -106,7 +104,7 @@ describe('agent framework release admission', () => {
status: registry.resolveAdapter(entry.manifest.adapter.id).status,
stability: entry.manifest.adapter.stability,
}));
expect(adapters.filter((adapter) => adapter.status === 'admitted')).toHaveLength(4);
expect(adapters.filter((adapter) => adapter.status === 'admitted')).toHaveLength(6);
expect(
adapters
.filter((adapter) => adapter.id.startsWith('openai-agents-'))
Expand All @@ -115,7 +113,7 @@ describe('agent framework release admission', () => {
expect(
adapters
.filter((adapter) => adapter.id.startsWith('google-adk-'))
.every((adapter) => adapter.status === 'blocked' && adapter.stability === 'preview')
.every((adapter) => adapter.status === 'admitted' && adapter.stability === 'preview')
).toBe(true);
expect(
createBuiltinAgentFrameworkRegistry().resolveAdapter('openai-agents-python').status
Expand Down
16 changes: 9 additions & 7 deletions packages/cli/src/__tests__/agent-framework-selection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import {
resolveAgentFrameworkSelection,
} from '../agent-frameworks/index.js';

const releaseAdmitted = listBundledAgentFrameworkReleaseAdmissions().length === 4;
const admittedAdapterIds = new Set(
listBundledAgentFrameworkReleaseAdmissions().map((admission) => admission.id)
);

describe('agent framework selection', () => {
it('refuses to guess Python when Microsoft and OpenAI are both published', () => {
Expand All @@ -27,7 +29,7 @@ describe('agent framework selection', () => {
).toMatchObject({
adapterId: 'microsoft-agent-framework-python',
frameworkId: 'microsoft-agent-framework',
admitted: releaseAdmitted,
admitted: admittedAdapterIds.has('microsoft-agent-framework-python'),
});
});

Expand Down Expand Up @@ -76,7 +78,7 @@ describe('agent framework selection', () => {
).toMatchObject({
adapterId: 'openai-agents-python',
frameworkId: 'openai-agents',
admitted: releaseAdmitted,
admitted: admittedAdapterIds.has('openai-agents-python'),
});
expect(
resolveAgentFrameworkSelection({
Expand All @@ -87,11 +89,11 @@ describe('agent framework selection', () => {
).toMatchObject({
adapterId: 'openai-agents-typescript',
frameworkId: 'openai-agents',
admitted: releaseAdmitted,
admitted: admittedAdapterIds.has('openai-agents-typescript'),
});
});

it('selects Google ADK by framework id without guessing or admitting it', () => {
it('selects admitted Google ADK adapters by framework id without guessing', () => {
const registry = createBuiltinAgentFrameworkRegistry(
{},
{ trustReviewedReleaseAdmissions: true }
Expand All @@ -105,7 +107,7 @@ describe('agent framework selection', () => {
).toMatchObject({
adapterId: 'google-adk-python',
frameworkId: 'google-adk',
admitted: false,
admitted: admittedAdapterIds.has('google-adk-python'),
});
expect(
resolveAgentFrameworkSelection({
Expand All @@ -116,7 +118,7 @@ describe('agent framework selection', () => {
).toMatchObject({
adapterId: 'google-adk-typescript',
frameworkId: 'google-adk',
admitted: false,
admitted: admittedAdapterIds.has('google-adk-typescript'),
});
});
});
28 changes: 26 additions & 2 deletions packages/cli/src/__tests__/agent-framework-user-flow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import { buildWorkspaceModel, writeWorkspaceModel } from '../workspace-model.js'
import { runWorkspaceIntelligenceChain } from '../workspace-intelligence-runner.js';

const roots: string[] = [];
const releaseAdmitted = listBundledAgentFrameworkReleaseAdmissions().length === 4;
const releaseAdmissions = listBundledAgentFrameworkReleaseAdmissions();
const releaseAdmitted = releaseAdmissions.some(
(admission) => admission.id === 'microsoft-agent-framework-python'
);
const googleAdmitted = releaseAdmissions.some((admission) => admission.id === 'google-adk-python');

async function fixture(
options: { secondProject?: boolean; extraProjects?: string[] } = {}
Expand Down Expand Up @@ -115,7 +119,7 @@ describe.skipIf(releaseAdmitted)('agent framework user flow fail-closed', () =>
});
});

describe('Google ADK user flow fail-closed', () => {
describe.skipIf(googleAdmitted)('Google ADK user flow fail-closed', () => {
it('refuses prepare while Google adapters remain outside the reviewed admission inventory', async () => {
const { workspacePath } = await fixture();
await expect(
Expand All @@ -130,6 +134,26 @@ describe('Google ADK user flow fail-closed', () => {
});
});

describe.skipIf(!googleAdmitted)('Google ADK user flow', () => {
it('prepares a governed attachment from the reviewed admission', async () => {
const { workspacePath } = await fixture();
await expect(
prepareAgentFrameworkAttachment({
workspacePath,
project: 'api',
runtime: 'python',
framework: 'google-adk',
instanceName: 'primary',
})
).resolves.toMatchObject({
status: 'planned',
frameworkId: 'google-adk',
adapterId: 'google-adk-python',
runtime: 'python',
});
});
});

describe.skipIf(!releaseAdmitted)('agent framework user flow', () => {
it('turns one attach request into a Goal, hash-bound plan, authorization, and owned files', async () => {
const { workspacePath, projectPath } = await fixture();
Expand Down
Loading
Loading