Files
copilotkit__copilotkit/scripts/__tests__/integration-intelligence-migration.test.ts

4537 lines
144 KiB
TypeScript

import { spawnSync } from "node:child_process";
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import * as ts from "typescript";
import { expect, test } from "vitest";
const repoRoot = path.resolve(__dirname, "..", "..");
const integrationsDir = path.join(repoRoot, "examples", "integrations");
const MANAGED_API_KEY = "CPK_INTELLIGENCE_API_KEY";
const MANAGED_API_KEY_SENTINEL = "cpk_secret_must_not_reach_browser_assets";
const OPTIONAL_TELEMETRY_ID = "CPK_TELEMETRY_ID";
const LEGACY_API_KEY = ["INTELLIGENCE", "API", "KEY"].join("_");
const LEGACY_TELEMETRY_ID = "COPILOTKIT_TELEMETRY_ID";
const MANAGED_LICENSE_TOKEN = "COPILOTKIT_LICENSE_TOKEN";
const MANAGED_API_KEY_SECRET_CONFIG =
"copilotkit_intelligence_api_key_secret_name";
const MANAGED_API_KEY_SECRET_VERSION_ID =
"CPK_INTELLIGENCE_API_KEY_SECRET_VERSION_ID";
const MANAGED_API_KEY_SECRET_VERSION_SENTINEL =
"agentcore-secret-version-contract";
const INTELLIGENCE_API_URL = "INTELLIGENCE_API_URL";
const INTELLIGENCE_GATEWAY_WS_URL = "INTELLIGENCE_GATEWAY_WS_URL";
const NEXT_THREADS_GATE = "NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED";
const VITE_THREADS_GATE = "VITE_COPILOTKIT_THREADS_ENABLED";
const MANAGED_DOCUMENTATION_LABEL = /\bmanaged\b/i;
const SELF_HOSTED_OR_OFFLINE_LABEL = /\b(?:self[ -]?hosted|offline)\b/i;
const LICENSE_GATING_LANGUAGE =
/(?:\blicen[cs]e\b[\s\S]{0,160}\b(?:activat(?:e[sd]?|ing)|unlock(?:s|ed|ing)?|enabl(?:e[sd]?|ing))\b[\s\S]{0,160}\b(?:threads?|inspector)\b|\b(?:threads?|inspector)\b[\s\S]{0,160}\b(?:activat(?:e[sd]?|ing)|unlock(?:s|ed|ing)?|enabl(?:e[sd]?|ing))\b[\s\S]{0,160}\blicen[cs]e\b)/i;
const INTEGRATION_PARITY_WORKFLOW = path.join(
repoRoot,
".github",
"workflows",
"integrations_parity.yml",
);
type ManagedSdkPackageName = "@copilotkit/runtime" | "@copilotkit/react-core";
interface ManagedSdkPin {
readonly packageName: ManagedSdkPackageName;
readonly packagePath: string;
readonly version: string;
}
const MANAGED_ENTITLEMENT_CONTRACT_BY_SDK_VERSION = {
"@copilotkit/runtime": {
"1.62.2": false,
"1.62.3": false,
"1.68.1": false,
"1.70.0": true,
"1.70.2": true,
},
"@copilotkit/react-core": {
"1.62.2": false,
"1.62.3": false,
"1.68.1": false,
"1.70.0": true,
"1.70.2": true,
},
} as const satisfies Readonly<
Record<ManagedSdkPackageName, Readonly<Record<string, boolean>>>
>;
const INTELLIGENCE_CLI_FRAMEWORKS = [
"langgraph-py",
"langgraph-js",
"claude-sdk-typescript",
"claude-sdk-python",
"flows",
"mastra",
"pydantic-ai",
"llamaindex",
"agno",
"adk",
"aws-strands-py",
"a2a",
"microsoft-agent-framework-dotnet",
"microsoft-agent-framework-py",
"mcp-apps",
"agentcore-langgraph",
"agentcore-strands",
"a2ui",
"opengenui",
] as const;
const INTELLIGENCE_DEV_STACKS = [
{
integration: "adk",
projectName: "copilotkit-intelligence-dev-adk",
postgresPort: "5482",
redisPort: "6389",
appApiPort: "4201",
gatewayPort: "4401",
},
{
integration: "agno",
projectName: "copilotkit-intelligence-dev-agno",
postgresPort: "5483",
redisPort: "6390",
appApiPort: "4202",
gatewayPort: "4402",
},
{
integration: "llamaindex",
projectName: "copilotkit-intelligence-dev-llamaindex",
postgresPort: "5484",
redisPort: "6391",
appApiPort: "4203",
gatewayPort: "4403",
},
{
integration: "mastra",
projectName: "copilotkit-intelligence-dev-mastra",
postgresPort: "5485",
redisPort: "6392",
appApiPort: "4204",
gatewayPort: "4404",
},
{
integration: "ms-agent-framework-python",
projectName: "copilotkit-intelligence-dev-ms-agent-framework-python",
postgresPort: "5486",
redisPort: "6393",
appApiPort: "4205",
gatewayPort: "4405",
},
{
integration: "pydantic-ai",
projectName: "copilotkit-intelligence-dev-pydantic-ai",
postgresPort: "5487",
redisPort: "6394",
appApiPort: "4206",
gatewayPort: "4406",
},
{
integration: "strands-python",
projectName: "copilotkit-intelligence-dev-strands-python",
postgresPort: "5488",
redisPort: "6395",
appApiPort: "4207",
gatewayPort: "4407",
},
] as const;
const EXPECTED_POSTGRES_INIT_SQL = [
"-- Runs once on the postgres container's first boot (docker-entrypoint-initdb.d).",
"-- The intelligence composite image's migrations oneshot + app-api connect to",
"-- intelligence_app; graphile-migrate uses intelligence_app_shadow for its shadow",
"-- database.",
"CREATE DATABASE intelligence_app;",
"CREATE DATABASE intelligence_app_shadow;",
"",
].join("\n");
type ManagedCliFramework = (typeof INTELLIGENCE_CLI_FRAMEWORKS)[number];
interface AgentOptionContract {
readonly property: string;
readonly environmentReads?: readonly string[];
readonly stringLiterals?: readonly string[];
}
type RuntimeAgentContract =
| {
readonly registration: "default";
readonly constructorName: string;
readonly options: readonly AgentOptionContract[];
}
| {
readonly registration: "factory";
readonly calleePath: readonly string[];
readonly argumentIdentifier: string;
};
interface ManagedTemplateContract {
readonly directory: string;
readonly frameworks: readonly ManagedCliFramework[];
readonly runtimePath: string;
readonly gatePath: string;
readonly envPath: string;
readonly readmePath: string;
readonly runtimeAgent?: RuntimeAgentContract;
readonly supportedPaths?: {
readonly localComposePath: string;
readonly deploymentConfigPath: string;
readonly runtimeDeploymentPath: string;
readonly frontendDeploymentPath: string;
readonly terraformRuntimeDeploymentPath: string;
readonly terraformReadmePath: string;
readonly deployScriptPaths: readonly string[];
};
}
type AgentCoreDeployScriptName = "deploy-langgraph.sh" | "deploy-strands.sh";
interface AgentCoreDeployEnvironment {
readonly apiUrl?: string;
readonly gatewayWsUrl?: string;
}
interface AgentCoreDeployHarnessOptions {
readonly scriptName: AgentCoreDeployScriptName;
readonly envFile: AgentCoreDeployEnvironment;
readonly callerEnvironment?: AgentCoreDeployEnvironment;
readonly skipBackend?: boolean;
readonly skipFrontend?: boolean;
readonly xtrace?: boolean;
}
interface AgentCoreDeployHarnessResult {
readonly status: number | null;
readonly output: string;
readonly cdkEnvironment: string | null;
readonly secretVersionId: string | null;
readonly awsCommands: readonly string[];
readonly npmCommands: readonly string[];
readonly frontendStackName: string | null;
readonly frontendSecretVersionId: string | null;
readonly secretExposureObservations: readonly string[];
readonly secretInputObservations: readonly string[];
}
const LANGGRAPH_RUNTIME_AGENT_CONTRACT = {
registration: "default",
constructorName: "LangGraphAgent",
options: [
{
property: "deploymentUrl",
environmentReads: ["AGENT_URL", "LANGGRAPH_DEPLOYMENT_URL"],
stringLiterals: ["http://localhost:8123"],
},
{ property: "graphId", stringLiterals: ["sample_agent"] },
{
property: "langsmithApiKey",
environmentReads: ["LANGSMITH_API_KEY"],
},
],
} as const satisfies RuntimeAgentContract;
const LANGGRAPH_FASTAPI_RUNTIME_AGENT_CONTRACT = {
registration: "default",
constructorName: "LangGraphHttpAgent",
options: [
{
property: "url",
environmentReads: ["AGENT_URL"],
stringLiterals: ["http://localhost:8123"],
},
],
} as const satisfies RuntimeAgentContract;
const HTTP_LOCALHOST_RUNTIME_AGENT_CONTRACT = {
registration: "default",
constructorName: "HttpAgent",
options: [
{
property: "url",
environmentReads: ["AGENT_URL"],
stringLiterals: ["http://localhost:8000"],
},
],
} as const satisfies RuntimeAgentContract;
const HTTP_LOCALHOST_SLASH_RUNTIME_AGENT_CONTRACT = {
registration: "default",
constructorName: "HttpAgent",
options: [
{
property: "url",
environmentReads: ["AGENT_URL"],
stringLiterals: ["http://localhost:8000/"],
},
],
} as const satisfies RuntimeAgentContract;
const MASTRA_RUNTIME_AGENT_CONTRACT = {
registration: "factory",
calleePath: ["MastraAgent", "getLocalAgents"],
argumentIdentifier: "mastra",
} as const satisfies RuntimeAgentContract;
const LLAMAINDEX_RUNTIME_AGENT_CONTRACT = {
registration: "default",
constructorName: "LlamaIndexAgent",
options: [
{
property: "url",
environmentReads: ["AGENT_URL"],
stringLiterals: ["http://127.0.0.1:9000", "/run"],
},
],
} as const satisfies RuntimeAgentContract;
const AGNO_RUNTIME_AGENT_CONTRACT = {
registration: "default",
constructorName: "HttpAgent",
options: [
{
property: "url",
environmentReads: ["AGENT_URL"],
stringLiterals: ["http://localhost:8000", "/agui"],
},
],
} as const satisfies RuntimeAgentContract;
const STRANDS_RUNTIME_AGENT_CONTRACT = {
registration: "default",
constructorName: "HttpAgent",
options: [
{
property: "url",
environmentReads: ["AGENT_URL", "STRANDS_AGENT_URL"],
stringLiterals: ["http://localhost:8000"],
},
],
} as const satisfies RuntimeAgentContract;
const INTELLIGENCE_TEMPLATE_CONTRACTS = [
{
directory: "langgraph-python",
frameworks: ["langgraph-py", "a2ui", "opengenui"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: LANGGRAPH_RUNTIME_AGENT_CONTRACT,
},
{
directory: "langgraph-js",
frameworks: ["langgraph-js"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: LANGGRAPH_RUNTIME_AGENT_CONTRACT,
},
{
directory: "langgraph-fastapi",
frameworks: [],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: LANGGRAPH_FASTAPI_RUNTIME_AGENT_CONTRACT,
},
{
directory: "claude-sdk-typescript",
frameworks: ["claude-sdk-typescript"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: HTTP_LOCALHOST_RUNTIME_AGENT_CONTRACT,
},
{
directory: "claude-sdk-python",
frameworks: ["claude-sdk-python"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: HTTP_LOCALHOST_RUNTIME_AGENT_CONTRACT,
},
{
directory: "crewai-flows",
frameworks: ["flows"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: HTTP_LOCALHOST_RUNTIME_AGENT_CONTRACT,
},
{
directory: "mastra",
frameworks: ["mastra"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: MASTRA_RUNTIME_AGENT_CONTRACT,
},
{
directory: "pydantic-ai",
frameworks: ["pydantic-ai"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: HTTP_LOCALHOST_SLASH_RUNTIME_AGENT_CONTRACT,
},
{
directory: "llamaindex",
frameworks: ["llamaindex"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: LLAMAINDEX_RUNTIME_AGENT_CONTRACT,
},
{
directory: "agno",
frameworks: ["agno"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: AGNO_RUNTIME_AGENT_CONTRACT,
},
{
directory: "adk",
frameworks: ["adk"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: HTTP_LOCALHOST_SLASH_RUNTIME_AGENT_CONTRACT,
},
{
directory: "strands-python",
frameworks: ["aws-strands-py"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: STRANDS_RUNTIME_AGENT_CONTRACT,
},
{
directory: "a2a-middleware",
frameworks: ["a2a"],
runtimePath: "app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
},
{
directory: "ms-agent-framework-dotnet",
frameworks: ["microsoft-agent-framework-dotnet"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: HTTP_LOCALHOST_SLASH_RUNTIME_AGENT_CONTRACT,
},
{
directory: "ms-agent-framework-python",
frameworks: ["microsoft-agent-framework-py"],
runtimePath: "src/app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
runtimeAgent: HTTP_LOCALHOST_SLASH_RUNTIME_AGENT_CONTRACT,
},
{
directory: "mcp-apps",
frameworks: ["mcp-apps"],
runtimePath: "app/api/copilotkit/[[...slug]]/route.ts",
gatePath: "next.config.ts",
envPath: ".env.example",
readmePath: "README.md",
},
{
directory: "agentcore",
frameworks: ["agentcore-langgraph", "agentcore-strands"],
runtimePath: "infra-cdk/lambdas/copilotkit-runtime/src/runtime.ts",
gatePath: "frontend/vite.config.ts",
envPath: ".env.example",
readmePath: "README.md",
supportedPaths: {
localComposePath: "docker/docker-compose.yml",
deploymentConfigPath: "config.yaml.example",
runtimeDeploymentPath: "infra-cdk/lib/backend-stack.ts",
frontendDeploymentPath: "infra-cdk/lib/amplify-hosting-stack.ts",
terraformRuntimeDeploymentPath:
"infra-terraform/modules/backend/copilotkit_runtime.tf",
terraformReadmePath: "infra-terraform/README.md",
deployScriptPaths: ["deploy-langgraph.sh", "deploy-strands.sh"],
},
},
] as const satisfies readonly ManagedTemplateContract[];
/**
* Reads one required managed-template surface from its authoritative path.
*
* @param contract - Managed template and its exact surface paths.
* @param relativePath - Surface path relative to the integration directory.
* @param surface - Human-readable surface name used in assertion failures.
* @returns The UTF-8 contents, or an empty string after a missing-file assertion.
*/
function readManagedSurface(
contract: ManagedTemplateContract,
relativePath: string,
surface: string,
): string {
const filePath = path.join(integrationsDir, contract.directory, relativePath);
const exists = fs.existsSync(filePath);
expect(
exists,
`${contract.directory} ${surface} must exist at ${relativePath}`,
).toBe(true);
return exists ? fs.readFileSync(filePath, "utf8") : "";
}
/**
* Reads one local Intelligence stack surface.
*
* @param integration - Integration directory name.
* @param relativePath - Surface path relative to that integration.
* @returns The UTF-8 file contents.
*/
function readIntelligenceDevSurface(
integration: string,
relativePath: string,
): string {
return fs.readFileSync(
path.join(integrationsDir, integration, relativePath),
"utf8",
);
}
/**
* Reads one optional local Intelligence stack surface.
*
* @param integration - Integration directory name.
* @param relativePath - Surface path relative to that integration.
* @returns The UTF-8 file contents, or an empty string when absent.
*/
function readOptionalIntelligenceDevSurface(
integration: string,
relativePath: string,
): string {
const filePath = path.join(integrationsDir, integration, relativePath);
return fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf8") : "";
}
/**
* Replaces the expected per-starter Compose differences with stable markers.
*
* @param compose - Local Intelligence Compose source.
* @returns The normalized source for drift checks.
*/
function normalizeIntelligenceComposeForDriftGuard(compose: string): string {
return compose
.replace(/^name: .+$/m, "name: <starter-project-name>")
.replace(
/\$\{POSTGRES_HOST_PORT:-\d+\}/g,
"${POSTGRES_HOST_PORT:-<postgres-host-port>}",
)
.replace(
/\$\{REDIS_HOST_PORT:-\d+\}/g,
"${REDIS_HOST_PORT:-<redis-host-port>}",
)
.replace(
/\$\{APP_API_HOST_PORT:-\d+\}/g,
"${APP_API_HOST_PORT:-<app-api-host-port>}",
)
.replace(
/\$\{GATEWAY_HOST_PORT:-\d+\}/g,
"${GATEWAY_HOST_PORT:-<gateway-host-port>}",
)
.replace(
/:[0-9]+ \(api\), :[0-9]+ \(gateway\)/g,
":<app-api-host-port> (api), :<gateway-host-port> (gateway)",
)
.replace(/:[0-9]+$/gm, (match) =>
match === ":5432" ||
match === ":6379" ||
match === ":4201" ||
match === ":4401"
? match
: ":<host-port>",
);
}
/**
* Asserts that Docker Compose accepts one local Intelligence stack.
*
* @param integration - Integration directory name.
*/
function expectDockerComposeConfigToSucceed(integration: string): void {
const composePath = path.join(
integrationsDir,
integration,
"docker-compose.intelligence.yml",
);
const result = spawnSync(
"docker",
["compose", "-f", composePath, "config", "--quiet"],
{
cwd: repoRoot,
encoding: "utf8",
},
);
if (result.status !== 0) {
throw new Error(
[
`${integration} docker-compose.intelligence.yml failed docker compose config --quiet`,
result.error ? `error: ${result.error.message}` : undefined,
result.stdout ? `stdout: ${result.stdout}` : undefined,
result.stderr ? `stderr: ${result.stderr}` : undefined,
]
.filter(Boolean)
.join("\n"),
);
}
}
/**
* Returns one two-space-indented YAML mapping section.
*
* @param contents - YAML source containing service-style mappings.
* @param name - Mapping key whose complete section should be returned.
* @returns The mapping section, or an empty string when it is absent.
*/
function yamlMappingSection(contents: string, name: string): string {
const lines = contents.split(/\r?\n/);
const start = lines.findIndex((line) => line === ` ${name}:`);
if (start < 0) {
return "";
}
const relativeEnd = lines
.slice(start + 1)
.findIndex((line) => /^ [^\s].*:\s*$/.test(line));
const end = relativeEnd < 0 ? lines.length : start + relativeEnd + 1;
return lines.slice(start, end).join("\n");
}
/** Matches a service-level reference to the generated project's root env. */
function rootManagedEnvFilePattern(): RegExp {
return /env_file:\s*(?:\r?\n\s*-\s*)?\.\.\/\.env\b/;
}
/**
* Matches an environment identifier without matching it inside a longer name.
*
* @param identifier - Exact uppercase environment identifier to match.
* @returns A pattern that excludes surrounding uppercase identifier characters.
*/
function exactEnvIdentifierPattern(identifier: string): RegExp {
return new RegExp(`(^|[^A-Z0-9_])${identifier}([^A-Z0-9_]|$)`);
}
/** Returns whether a node is the `process.env` object expression. */
function isProcessEnvObject(node: ts.Node): boolean {
return (
ts.isPropertyAccessExpression(node) &&
ts.isIdentifier(node.expression) &&
node.expression.text === "process" &&
node.name.text === "env"
);
}
/**
* Returns whether a node is a dot or bracket read from `process.env`.
*
* @param node - TypeScript syntax node under inspection.
* @param identifier - Exact environment identifier that must be read.
*/
function isProcessEnvRead(node: ts.Node, identifier: string): boolean {
if (ts.isPropertyAccessExpression(node)) {
return isProcessEnvObject(node.expression) && node.name.text === identifier;
}
return (
ts.isElementAccessExpression(node) &&
isProcessEnvObject(node.expression) &&
ts.isStringLiteral(node.argumentExpression) &&
node.argumentExpression.text === identifier
);
}
/** Returns the static text of an object-literal property name when available. */
function propertyNameText(name: ts.PropertyName): string | null {
if (ts.isIdentifier(name) || ts.isStringLiteral(name)) {
return name.text;
}
return null;
}
/** Parses managed scaffold TypeScript and rejects parser-recovered source. */
function parseManagedSource(contents: string): ts.SourceFile {
const transpiled = ts.transpileModule(contents, {
compilerOptions: {
jsx: ts.JsxEmit.Preserve,
module: ts.ModuleKind.ESNext,
target: ts.ScriptTarget.Latest,
},
fileName: "managed-integration-contract.tsx",
reportDiagnostics: true,
});
const parseDiagnostics =
transpiled.diagnostics?.filter(
(diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error,
) ?? [];
expect(
parseDiagnostics,
"managed scaffold source must parse without diagnostics",
).toHaveLength(0);
const sourceFile = ts.createSourceFile(
"managed-integration-contract.tsx",
contents,
ts.ScriptTarget.Latest,
true,
ts.ScriptKind.TSX,
);
return sourceFile;
}
/** Returns an expression without transparent TypeScript wrappers. */
function unwrapExpression(expression: ts.Expression): ts.Expression {
if (
ts.isParenthesizedExpression(expression) ||
ts.isAsExpression(expression) ||
ts.isTypeAssertionExpression(expression) ||
ts.isSatisfiesExpression(expression) ||
ts.isNonNullExpression(expression)
) {
return unwrapExpression(expression.expression);
}
return expression;
}
/** Returns one exact object-literal property assignment when present. */
function objectPropertyAssignment(
objectLiteral: ts.ObjectLiteralExpression,
name: string,
): ts.PropertyAssignment | null {
for (const property of objectLiteral.properties) {
if (
ts.isPropertyAssignment(property) &&
propertyNameText(property.name) === name
) {
return property;
}
}
return null;
}
/** Returns a direct value or conditional spread that reads one env name. */
function objectEnvironmentExpression(
objectLiteral: ts.ObjectLiteralExpression,
name: string,
): ts.Expression | null {
const direct = objectPropertyAssignment(objectLiteral, name);
if (direct) return direct.initializer;
for (const property of objectLiteral.properties) {
if (
ts.isSpreadAssignment(property) &&
expressionContainsEnvRead(property.expression, name)
) {
return property.expression;
}
}
return null;
}
/** Returns whether one expression contains the exact managed env read. */
function expressionContainsEnvRead(
expression: ts.Expression,
identifier: string,
): boolean {
let found = false;
/** Visits one initializer node looking for the required env read. */
function visit(node: ts.Node): void {
if (found) {
return;
}
if (isProcessEnvRead(node, identifier)) {
found = true;
return;
}
ts.forEachChild(node, visit);
}
visit(expression);
return found;
}
/** Returns whether an expression contains one exact string literal. */
function expressionContainsStringLiteral(
expression: ts.Expression,
expected: string,
): boolean {
let found = false;
/** Visits one initializer node looking for the required literal. */
function visit(node: ts.Node): void {
if (found) return;
if (
(ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) &&
node.text === expected
) {
found = true;
return;
}
ts.forEachChild(node, visit);
}
visit(expression);
return found;
}
/** Returns whether an expression uses the managed key without telemetry. */
function expressionUsesManagedKeyWithoutTelemetry(
expression: ts.Expression,
): boolean {
return (
expressionContainsEnvRead(expression, MANAGED_API_KEY) &&
!expressionContainsEnvRead(expression, OPTIONAL_TELEMETRY_ID)
);
}
/** Returns whether an expression is a literal boolean string projection. */
function isBooleanStringProjection(expression: ts.Expression): boolean {
const unwrapped = unwrapExpression(expression);
if (ts.isStringLiteral(unwrapped)) {
return unwrapped.text === "true" || unwrapped.text === "false";
}
if (ts.isConditionalExpression(unwrapped)) {
return (
isBooleanStringProjection(unwrapped.whenTrue) &&
isBooleanStringProjection(unwrapped.whenFalse)
);
}
if (
ts.isCallExpression(unwrapped) &&
ts.isPropertyAccessExpression(unwrapped.expression) &&
ts.isIdentifier(unwrapped.expression.expression) &&
unwrapped.expression.expression.text === "JSON" &&
unwrapped.expression.name.text === "stringify" &&
unwrapped.arguments.length === 1
) {
return isBooleanStringProjection(unwrapped.arguments[0]!);
}
return false;
}
/** Returns whether the public gate is boolean-only and keyed by the CPK credential. */
function expressionUsesManagedBooleanGate(expression: ts.Expression): boolean {
return (
expressionContainsEnvRead(expression, MANAGED_API_KEY) &&
!expressionContainsEnvRead(expression, OPTIONAL_TELEMETRY_ID) &&
isBooleanStringProjection(expression)
);
}
/** Returns the expression assigned to one exact object-literal property. */
function objectPropertyExpression(
objectLiteral: ts.ObjectLiteralExpression,
name: string,
): ts.Expression | null {
for (const property of objectLiteral.properties) {
if (
ts.isPropertyAssignment(property) &&
propertyNameText(property.name) === name
) {
return property.initializer;
}
if (
ts.isShorthandPropertyAssignment(property) &&
property.name.text === name
) {
return property.name;
}
}
return null;
}
/** Returns whether the Runtime's Intelligence client owns the API-key read. */
function hasRuntimeApiKeyRead(sourceFile: ts.SourceFile): boolean {
const clientUsesManagedKey = (clientExpression: ts.Expression): boolean => {
const client = resolveTopLevelExpression(sourceFile, clientExpression);
if (
!ts.isNewExpression(client) ||
!ts.isIdentifier(client.expression) ||
client.expression.text !== "CopilotKitIntelligence"
) {
return false;
}
const options = client.arguments?.[0]
? unwrapExpression(client.arguments[0])
: null;
if (!options || !ts.isObjectLiteralExpression(options)) return false;
const apiKey = objectPropertyAssignment(options, "apiKey");
return Boolean(
apiKey &&
expressionUsesManagedKeyWithoutTelemetry(
resolveTopLevelExpression(sourceFile, apiKey.initializer),
),
);
};
return newExpressionOptions(sourceFile, "CopilotRuntime").some(
(runtimeOptions) => {
const directIntelligence = objectPropertyExpression(
runtimeOptions,
"intelligence",
);
if (directIntelligence && clientUsesManagedKey(directIntelligence)) {
return true;
}
let found = false;
const visit = (node: ts.Node): void => {
if (
ts.isNewExpression(node) &&
ts.isIdentifier(node.expression) &&
node.expression.text === "CopilotKitIntelligence"
) {
found = clientUsesManagedKey(node);
}
if (!found) ts.forEachChild(node, visit);
};
visit(runtimeOptions);
return found;
},
);
}
/** Returns the initializer for one top-level variable identifier. */
function topLevelVariableInitializer(
sourceFile: ts.SourceFile,
identifier: string,
): ts.Expression | null {
for (const statement of sourceFile.statements) {
if (!ts.isVariableStatement(statement)) {
continue;
}
for (const declaration of statement.declarationList.declarations) {
if (
ts.isIdentifier(declaration.name) &&
declaration.name.text === identifier
) {
return declaration.initializer ?? null;
}
}
}
return null;
}
/** Returns every variable initializer with one exact identifier in a source tree. */
function variableInitializers(
root: ts.Node,
identifier: string,
): readonly ts.Expression[] {
const matches: ts.Expression[] = [];
/** Visits variable declarations for the requested identifier. */
function visit(node: ts.Node): void {
if (
ts.isVariableDeclaration(node) &&
ts.isIdentifier(node.name) &&
node.name.text === identifier &&
node.initializer
) {
matches.push(node.initializer);
}
ts.forEachChild(node, visit);
}
visit(root);
return matches;
}
/** Resolves transparent wrappers and top-level variable aliases. */
function resolveTopLevelExpression(
sourceFile: ts.SourceFile,
expression: ts.Expression,
seenIdentifiers: ReadonlySet<string> = new Set(),
): ts.Expression {
const unwrapped = unwrapExpression(expression);
if (!ts.isIdentifier(unwrapped) || seenIdentifiers.has(unwrapped.text)) {
return unwrapped;
}
const initializer = topLevelVariableInitializer(sourceFile, unwrapped.text);
if (!initializer) return unwrapped;
return resolveTopLevelExpression(
sourceFile,
initializer,
new Set([...seenIdentifiers, unwrapped.text]),
);
}
/** Resolves one registered agent through an optional top-level identifier. */
function registeredAgentExpression(
sourceFile: ts.SourceFile,
expression: ts.Expression,
): ts.Expression {
const unwrapped = unwrapExpression(expression);
if (!ts.isIdentifier(unwrapped)) return unwrapped;
const initializer = topLevelVariableInitializer(sourceFile, unwrapped.text);
return initializer ? unwrapExpression(initializer) : unwrapped;
}
/** Returns whether an object property carries one exact identifier. */
function objectPropertyIsIdentifier(
objectLiteral: ts.ObjectLiteralExpression,
propertyName: string,
identifier: string,
): boolean {
return objectLiteral.properties.some((property) => {
if (
ts.isShorthandPropertyAssignment(property) &&
property.name.text === propertyName
) {
return property.name.text === identifier;
}
if (
ts.isPropertyAssignment(property) &&
propertyNameText(property.name) === propertyName
) {
const initializer = unwrapExpression(property.initializer);
return ts.isIdentifier(initializer) && initializer.text === identifier;
}
return false;
});
}
/** Resolves a default-exported object literal through top-level variables. */
function exportedObjectLiteral(
expression: ts.Expression,
sourceFile: ts.SourceFile,
seenIdentifiers: ReadonlySet<string> = new Set(),
): ts.ObjectLiteralExpression | null {
const unwrapped = unwrapExpression(expression);
if (ts.isObjectLiteralExpression(unwrapped)) {
return unwrapped;
}
if (ts.isIdentifier(unwrapped) && !seenIdentifiers.has(unwrapped.text)) {
const initializer = topLevelVariableInitializer(sourceFile, unwrapped.text);
if (initializer) {
return exportedObjectLiteral(
initializer,
sourceFile,
new Set([...seenIdentifiers, unwrapped.text]),
);
}
}
return null;
}
/** Returns the source's default export expression when it has one. */
function defaultExportExpression(
sourceFile: ts.SourceFile,
): ts.Expression | null {
for (const statement of sourceFile.statements) {
if (ts.isExportAssignment(statement) && !statement.isExportEquals) {
return statement.expression;
}
}
return null;
}
/** Returns whether the exported Next thread gate owns the key read. */
function hasExportedGateApiKeyRead(sourceFile: ts.SourceFile): boolean {
const exported = defaultExportExpression(sourceFile);
if (!exported) {
return false;
}
const nextConfig = exportedObjectLiteral(exported, sourceFile);
return Boolean(
nextConfig &&
nestedPropertyMatches(
nextConfig,
"env",
NEXT_THREADS_GATE,
expressionUsesManagedBooleanGate,
),
);
}
/** Returns whether a nested object property satisfies an expression predicate. */
function nestedPropertyMatches(
objectLiteral: ts.ObjectLiteralExpression,
containerName: string,
propertyName: string,
predicate: (expression: ts.Expression) => boolean,
): boolean {
const container = objectPropertyAssignment(objectLiteral, containerName);
if (!container) {
return false;
}
const containerInitializer = unwrapExpression(container.initializer);
if (!ts.isObjectLiteralExpression(containerInitializer)) {
return false;
}
const property = objectPropertyAssignment(containerInitializer, propertyName);
return Boolean(property && predicate(property.initializer));
}
/** Returns the exact dotted parts of a property-access expression. */
function propertyAccessParts(expression: ts.Expression): readonly string[] {
const unwrapped = unwrapExpression(expression);
if (ts.isIdentifier(unwrapped)) {
return [unwrapped.text];
}
if (ts.isPropertyAccessExpression(unwrapped)) {
return [...propertyAccessParts(unwrapped.expression), unwrapped.name.text];
}
return [];
}
/** Returns whether an expression contains an exact dotted property path. */
function expressionContainsPropertyPath(
expression: ts.Expression,
expectedPath: readonly string[],
): boolean {
let found = false;
/** Visits one expression node for the exact configured path. */
function visit(node: ts.Node): void {
if (found) return;
if (
ts.isExpression(node) &&
propertyAccessParts(node).join(".") === expectedPath.join(".")
) {
found = true;
return;
}
ts.forEachChild(node, visit);
}
visit(expression);
return found;
}
/** Returns whether an expression resolves a value through Secrets Manager. */
function expressionContainsSecretResolution(
expression: ts.Expression,
): boolean {
let found = false;
/** Visits one expression node for an explicit Secrets Manager call. */
function visit(node: ts.Node): void {
if (found) return;
if (ts.isCallExpression(node)) {
const callee = propertyAccessParts(node.expression);
if (
callee.at(-1) === "secretsManager" &&
callee.includes("SecretValue")
) {
found = true;
return;
}
}
ts.forEachChild(node, visit);
}
visit(expression);
return found;
}
/** Returns all new-expression option objects matching a construct name and id. */
function constructOptions(
sourceFile: ts.SourceFile,
constructorPath: readonly string[],
constructId: string,
): readonly ts.ObjectLiteralExpression[] {
const matches: ts.ObjectLiteralExpression[] = [];
/** Visits construct calls for exact constructor and id ownership. */
function visit(node: ts.Node): void {
if (
ts.isNewExpression(node) &&
propertyAccessParts(node.expression).join(".") ===
constructorPath.join(".") &&
node.arguments?.[1] &&
ts.isStringLiteral(node.arguments[1]) &&
node.arguments[1].text === constructId
) {
const options = node.arguments[2]
? unwrapExpression(node.arguments[2])
: null;
if (options && ts.isObjectLiteralExpression(options)) {
matches.push(options);
}
}
ts.forEachChild(node, visit);
}
visit(sourceFile);
return matches;
}
/** Returns every object-literal options argument for one constructor. */
function newExpressionOptions(
sourceFile: ts.SourceFile,
constructorName: string,
): readonly ts.ObjectLiteralExpression[] {
const matches: ts.ObjectLiteralExpression[] = [];
/** Visits constructor calls for exact constructor ownership. */
function visit(node: ts.Node): void {
if (
ts.isNewExpression(node) &&
ts.isIdentifier(node.expression) &&
node.expression.text === constructorName
) {
const options = node.arguments?.[0]
? unwrapExpression(node.arguments[0])
: null;
if (options && ts.isObjectLiteralExpression(options)) {
matches.push(options);
}
}
ts.forEachChild(node, visit);
}
visit(sourceFile);
return matches;
}
/** Returns one constructor's object-literal options from an exact expression. */
function constructorOptionsFromExpression(
expression: ts.Expression,
constructorName: string,
): ts.ObjectLiteralExpression | null {
const unwrapped = unwrapExpression(expression);
if (
!ts.isNewExpression(unwrapped) ||
!ts.isIdentifier(unwrapped.expression) ||
unwrapped.expression.text !== constructorName
) {
return null;
}
const options = unwrapped.arguments?.[0]
? unwrapExpression(unwrapped.arguments[0])
: null;
return options && ts.isObjectLiteralExpression(options) ? options : null;
}
/** Returns whether a source contains a call to one exact function or method. */
function sourceContainsCall(
sourceFile: ts.SourceFile,
calleePath: readonly string[],
): boolean {
let found = false;
/** Visits call expressions until the required callee is found. */
function visit(node: ts.Node): void {
if (found) return;
if (
ts.isCallExpression(node) &&
propertyAccessParts(node.expression).join(".") === calleePath.join(".")
) {
found = true;
return;
}
ts.forEachChild(node, visit);
}
visit(sourceFile);
return found;
}
/** Returns calls to one exact function or method. */
function sourceCalls(
sourceFile: ts.SourceFile,
calleePath: readonly string[],
): readonly ts.CallExpression[] {
const matches: ts.CallExpression[] = [];
/** Visits source nodes for the required callee. */
function visit(node: ts.Node): void {
if (
ts.isCallExpression(node) &&
propertyAccessParts(node.expression).join(".") === calleePath.join(".")
) {
matches.push(node);
}
ts.forEachChild(node, visit);
}
visit(sourceFile);
return matches;
}
/** Returns whether source contains an exact environment read. */
function sourceContainsEnvRead(
sourceFile: ts.SourceFile,
identifier: string,
): boolean {
let found = false;
/** Visits source nodes for the required environment read. */
function visit(node: ts.Node): void {
if (found) return;
if (isProcessEnvRead(node, identifier)) {
found = true;
return;
}
ts.forEachChild(node, visit);
}
visit(sourceFile);
return found;
}
/** Returns the exported HTTP methods assigned to `handle(app)`. */
function exportedEndpointHandlers(
sourceFile: ts.SourceFile,
): ReadonlySet<string> {
const methods = new Set<string>();
for (const statement of sourceFile.statements) {
if (
!ts.isVariableStatement(statement) ||
!statement.modifiers?.some(
(modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword,
)
) {
continue;
}
for (const declaration of statement.declarationList.declarations) {
const initializer = declaration.initializer
? unwrapExpression(declaration.initializer)
: null;
if (
ts.isIdentifier(declaration.name) &&
initializer &&
ts.isCallExpression(initializer) &&
ts.isIdentifier(initializer.expression) &&
initializer.expression.text === "handle" &&
initializer.arguments.length === 1 &&
ts.isIdentifier(initializer.arguments[0]) &&
initializer.arguments[0].text === "app"
) {
methods.add(declaration.name.text);
}
}
}
return methods;
}
/** Returns static JSX tag text when the tag is not computed. */
function jsxTagNameText(name: ts.JsxTagNameExpression): string | null {
if (ts.isIdentifier(name)) {
return name.text;
}
if (ts.isPropertyAccessExpression(name)) {
return propertyAccessParts(name).join(".");
}
return null;
}
/** Returns all JSX elements and self-closing elements with one tag name. */
function jsxNodesWithTag(
root: ts.Node,
tagName: string,
): readonly (ts.JsxElement | ts.JsxSelfClosingElement)[] {
const matches: (ts.JsxElement | ts.JsxSelfClosingElement)[] = [];
/** Visits JSX nodes for the exact tag name. */
function visit(node: ts.Node): void {
if (
ts.isJsxElement(node) &&
jsxTagNameText(node.openingElement.tagName) === tagName
) {
matches.push(node);
} else if (
ts.isJsxSelfClosingElement(node) &&
jsxTagNameText(node.tagName) === tagName
) {
matches.push(node);
}
ts.forEachChild(node, visit);
}
visit(root);
return matches;
}
/** Returns the opening-like node for a JSX element. */
function jsxOpeningLikeElement(
node: ts.JsxElement | ts.JsxSelfClosingElement,
): ts.JsxOpeningLikeElement {
return ts.isJsxElement(node) ? node.openingElement : node;
}
/** Returns one exact JSX attribute. */
function jsxAttribute(
node: ts.JsxElement | ts.JsxSelfClosingElement,
attributeName: string,
): ts.JsxAttribute | null {
const opening = jsxOpeningLikeElement(node);
for (const property of opening.attributes.properties) {
if (
ts.isJsxAttribute(property) &&
property.name.getText() === attributeName
) {
return property;
}
}
return null;
}
/** Returns a stable structural identity for one JSX attribute value. */
function jsxAttributeIdentity(
attribute: ts.JsxAttribute | null,
): string | null {
if (!attribute?.initializer) {
return attribute ? "true" : null;
}
if (ts.isStringLiteral(attribute.initializer)) {
return JSON.stringify(attribute.initializer.text);
}
if (
ts.isJsxExpression(attribute.initializer) &&
attribute.initializer.expression
) {
return attribute.initializer.expression.getText();
}
return null;
}
/** Returns whether a JSX attribute is the boolean literal `false`. */
function jsxAttributeIsFalse(attribute: ts.JsxAttribute | null): boolean {
return Boolean(
attribute?.initializer &&
ts.isJsxExpression(attribute.initializer) &&
attribute.initializer.expression?.kind === ts.SyntaxKind.FalseKeyword,
);
}
/** Returns whether an object property is one exact string literal. */
function objectPropertyIsString(
objectLiteral: ts.ObjectLiteralExpression,
propertyName: string,
expected: string,
): boolean {
const property = objectPropertyAssignment(objectLiteral, propertyName);
if (!property) return false;
const initializer = unwrapExpression(property.initializer);
return ts.isStringLiteral(initializer) && initializer.text === expected;
}
/**
* Matches a documented environment assignment, including commented examples.
*
* @param identifier - Exact environment identifier expected before `=`.
* @returns A multiline assignment pattern.
*/
function envAssignmentPattern(identifier: string): RegExp {
return new RegExp(`^\\s*#?\\s*${identifier}\\s*=`, "m");
}
/** Returns every blank-line-delimited block in block-oriented text. */
function textBlocks(contents: string): readonly string[] {
return contents.split(/\r?\n\s*\r?\n/);
}
/** Returns the first blank-line-delimited text block containing a marker. */
function textBlockContaining(contents: string, marker: string): string {
return textBlocks(contents).find((block) => block.includes(marker)) ?? "";
}
/** Asserts telemetry copy describes identity without prerequisite semantics. */
function expectTelemetryIdentityDocumentation(contents: string): void {
const telemetryBlock = textBlockContaining(contents, OPTIONAL_TELEMETRY_ID);
expect(telemetryBlock).toMatch(/\boptional\b/i);
expect(telemetryBlock).toMatch(/\bnon[- ]?secret\b/i);
expect(telemetryBlock).toMatch(/\banalytics\b/i);
expect(telemetryBlock).toMatch(/\bidentity\b/i);
expect(telemetryBlock).not.toMatch(
/\b(?:auth(?:entication|orization)?|entitlements?|enabl(?:e[sd]?|ing|ement)|consent(?:s|ed|ing)?|send(?:s|ing)?|sent|transmit(?:s|ted|ting)?)\b/i,
);
}
/** Returns whether an env block has an explicit comment label. */
function envBlockHasLabel(block: string, label: RegExp): boolean {
return block
.split(/\r?\n/)
.some((line) => /^\s*#/.test(line) && label.test(line));
}
interface ManagedEnvSections {
readonly apiKey: string;
readonly telemetry: string;
}
/** Returns the exact ordered managed dotenv sections from the public contract. */
function managedEnvSections(contents: string): ManagedEnvSections | null {
const lines = contents.replaceAll("\r\n", "\n").split("\n");
const apiHeader = "# Your CopilotKit Intelligence API Key";
const telemetryHeader = "# CopilotKit Telemetry ID";
if (
lines.filter((line) => line === apiHeader).length !== 1 ||
lines.filter((line) => line === telemetryHeader).length !== 1 ||
lines.filter((line) => envAssignmentPattern(MANAGED_API_KEY).test(line))
.length !== 1 ||
lines.filter((line) =>
envAssignmentPattern(OPTIONAL_TELEMETRY_ID).test(line),
).length !== 1
) {
return null;
}
const apiHeaderIndex = lines.findIndex((line) => line === apiHeader);
if (apiHeaderIndex < 0) return null;
const projectName = lines[apiHeaderIndex + 1] ?? "";
const apiKeyAssignment = lines[apiHeaderIndex + 2] ?? "";
const separator = lines[apiHeaderIndex + 3];
const telemetryHeaderIndex = apiHeaderIndex + 4;
if (
!/^# Project Name: \S.*$/u.test(projectName) ||
!envAssignmentPattern(MANAGED_API_KEY).test(apiKeyAssignment) ||
separator !== "" ||
lines[telemetryHeaderIndex] !== telemetryHeader
) {
return null;
}
let telemetryEnd = telemetryHeaderIndex + 1;
while (telemetryEnd < lines.length && lines[telemetryEnd] !== "") {
telemetryEnd += 1;
}
const telemetry = lines.slice(telemetryHeaderIndex, telemetryEnd).join("\n");
if (!envAssignmentPattern(OPTIONAL_TELEMETRY_ID).test(telemetry)) {
return null;
}
return {
apiKey: lines.slice(apiHeaderIndex, apiHeaderIndex + 3).join("\n"),
telemetry,
};
}
/** Asserts every env license occurrence has a deployment-mode label. */
function expectEnvLicenseOccurrencesClassified(contents: string): void {
const licenseBlocks = textBlocks(contents).filter(
(block) =>
block.includes(MANAGED_LICENSE_TOKEN) ||
LICENSE_GATING_LANGUAGE.test(block),
);
expect(
licenseBlocks.every((block) =>
envBlockHasLabel(block, SELF_HOSTED_OR_OFFLINE_LABEL),
),
).toBe(true);
}
/** Returns Markdown paragraph starts containing license literals or gating copy. */
function markdownLicenseOccurrenceLines(lines: readonly string[]): number[] {
const occurrences: number[] = [];
let start = 0;
while (start < lines.length) {
while (start < lines.length && lines[start]?.trim() === "") start += 1;
if (start >= lines.length) break;
let end = start + 1;
while (end < lines.length && lines[end]?.trim() !== "") end += 1;
const block = lines.slice(start, end).join("\n");
if (
block.includes(MANAGED_LICENSE_TOKEN) ||
LICENSE_GATING_LANGUAGE.test(block)
) {
occurrences.push(start);
}
start = end + 1;
}
return occurrences;
}
interface MarkdownHeadingSection {
readonly heading: string;
readonly contents: string;
}
/** Returns every Markdown heading section through its next peer heading. */
function markdownHeadingSections(
markdown: string,
): readonly MarkdownHeadingSection[] {
const lines = markdown.split(/\r?\n/);
const sections: MarkdownHeadingSection[] = [];
for (let start = 0; start < lines.length; start += 1) {
const heading = lines[start]?.match(/^(#{1,6})\s+(.+?)\s*$/);
if (!heading) continue;
const headingLevel = heading[1]?.length ?? 0;
let end = lines.length;
for (let index = start + 1; index < lines.length; index += 1) {
const subsequent = lines[index]?.match(/^(#{1,6})\s+/);
if (subsequent && (subsequent[1]?.length ?? 0) <= headingLevel) {
end = index;
break;
}
}
sections.push({
heading: heading[2] ?? "",
contents: lines.slice(start, end).join("\n"),
});
}
return sections;
}
/** Returns the managed Markdown section containing both managed fields. */
function managedMarkdownSection(markdown: string): string {
return (
markdownHeadingSections(markdown).find(
({ heading, contents }) =>
MANAGED_DOCUMENTATION_LABEL.test(heading) &&
exactEnvIdentifierPattern(MANAGED_API_KEY).test(contents) &&
exactEnvIdentifierPattern(OPTIONAL_TELEMETRY_ID).test(contents),
)?.contents ?? ""
);
}
/** Returns distinct offline or self-hosted license-token guidance. */
function offlineOrSelfHostedLicenseSection(markdown: string): string {
return (
markdownHeadingSections(markdown).find(
({ heading, contents }) =>
SELF_HOSTED_OR_OFFLINE_LABEL.test(heading) &&
(exactEnvIdentifierPattern(MANAGED_LICENSE_TOKEN).test(contents) ||
/\blicen[cs]e\s+token\b/i.test(contents)),
)?.contents ?? ""
);
}
/** Returns whether a Markdown line has a heading ancestor with the label. */
function markdownLineHasLabeledAncestor(
lines: readonly string[],
lineIndex: number,
label: RegExp,
): boolean {
let childLevel = 7;
for (let index = lineIndex; index >= 0; index -= 1) {
const heading = lines[index]?.match(/^(#{1,6})\s+(.+?)\s*$/);
const headingLevel = heading?.[1]?.length ?? 0;
if (heading && headingLevel < childLevel) {
if (label.test(heading[2] ?? "")) {
return true;
}
childLevel = headingLevel;
}
}
return false;
}
/** Asserts every README license mention has a deployment-mode heading. */
function expectMarkdownLicenseOccurrencesClassified(markdown: string): void {
const lines = markdown.split(/\r?\n/);
const licenseLines = markdownLicenseOccurrenceLines(lines);
expect(
licenseLines.every((index) =>
markdownLineHasLabeledAncestor(
lines,
index,
SELF_HOSTED_OR_OFFLINE_LABEL,
),
),
).toBe(true);
}
/**
* Asserts the managed runtime reads only the managed project credential.
*
* @param contents - Runtime route or bridge source.
*/
function expectManagedRuntimeContract(contents: string): void {
const sourceFile = parseManagedSource(contents);
expect(hasRuntimeApiKeyRead(sourceFile)).toBe(true);
expect(contents).not.toMatch(exactEnvIdentifierPattern(LEGACY_API_KEY));
expect(contents).not.toMatch(exactEnvIdentifierPattern(LEGACY_TELEMETRY_ID));
}
/**
* Asserts the browser-safe feature gate follows the managed project credential.
*
* @param contents - Next.js or Vite gate configuration source.
*/
function expectManagedGateContract(contents: string): void {
const sourceFile = parseManagedSource(contents);
expect(hasExportedGateApiKeyRead(sourceFile)).toBe(true);
expect(contents).not.toMatch(exactEnvIdentifierPattern(LEGACY_API_KEY));
expect(contents).not.toMatch(exactEnvIdentifierPattern(LEGACY_TELEMETRY_ID));
expect(contents).not.toContain(MANAGED_LICENSE_TOKEN);
}
/**
* Asserts an env example documents the managed key and optional telemetry ID.
*
* @param contents - Managed template environment example contents.
*/
function expectManagedEnvContract(contents: string): void {
const managedSections = managedEnvSections(contents);
expect(managedSections).not.toBeNull();
if (!managedSections) return;
expect(managedSections.apiKey).toMatch(envAssignmentPattern(MANAGED_API_KEY));
expectTelemetryIdentityDocumentation(managedSections.telemetry);
expect(contents).not.toMatch(envAssignmentPattern(LEGACY_API_KEY));
expect(contents).not.toMatch(envAssignmentPattern(LEGACY_TELEMETRY_ID));
expectEnvLicenseOccurrencesClassified(contents);
}
/**
* Asserts a README documents the managed key and optional telemetry identity.
*
* @param contents - Managed template README contents.
* @param requiresLicenseSection - Whether this template documents a separate license path.
*/
function expectManagedReadmeContract(
contents: string,
requiresLicenseSection = true,
): void {
const managedSection = managedMarkdownSection(contents);
const offlineOrSelfHostedSection =
offlineOrSelfHostedLicenseSection(contents);
expect(managedSection).not.toBe("");
expect(managedSection).not.toContain(MANAGED_LICENSE_TOKEN);
expectTelemetryIdentityDocumentation(managedSection);
if (requiresLicenseSection) {
expect(offlineOrSelfHostedSection).not.toBe("");
expect(managedSection).not.toContain(offlineOrSelfHostedSection);
} else {
expect(offlineOrSelfHostedSection).toBe("");
}
expect(contents).not.toMatch(exactEnvIdentifierPattern(LEGACY_API_KEY));
expect(contents).not.toMatch(exactEnvIdentifierPattern(LEGACY_TELEMETRY_ID));
expectMarkdownLicenseOccurrencesClassified(contents);
}
/** Reads the Runtime and React pins that own one template's entitlement flow. */
function readManagedSdkPins(
contract: ManagedTemplateContract,
): readonly ManagedSdkPin[] {
const packageContracts =
contract.directory === "agentcore"
? [
{
packageName: "@copilotkit/runtime" as const,
packagePath: "infra-cdk/lambdas/copilotkit-runtime/package.json",
},
{
packageName: "@copilotkit/react-core" as const,
packagePath: "frontend/package.json",
},
]
: [
{
packageName: "@copilotkit/runtime" as const,
packagePath: "package.json",
},
{
packageName: "@copilotkit/react-core" as const,
packagePath: "package.json",
},
];
return packageContracts.map(({ packageName, packagePath }) => {
const manifest = JSON.parse(
readManagedSurface(contract, packagePath, `${packageName} manifest`),
) as {
readonly dependencies?: Readonly<Record<string, string>>;
readonly devDependencies?: Readonly<Record<string, string>>;
};
const version =
manifest.dependencies?.[packageName] ??
manifest.devDependencies?.[packageName] ??
"";
expect(
version,
`${contract.directory} must pin ${packageName} in ${packagePath}`,
).toMatch(/^\d+\.\d+\.\d+$/u);
return { packageName, packagePath, version };
});
}
/** Returns whether a classified package pin supports managed entitlements. */
function pinSupportsManagedEntitlements(pin: ManagedSdkPin): boolean {
const classifications = MANAGED_ENTITLEMENT_CONTRACT_BY_SDK_VERSION[
pin.packageName
] as Readonly<Record<string, boolean>>;
const supportsManagedEntitlements = classifications[pin.version];
expect(
supportsManagedEntitlements,
`${pin.packageName}@${pin.version} must be classified before a managed template can use it`,
).not.toBeUndefined();
return supportsManagedEntitlements === true;
}
/** Asserts one ordinary template retains its framework-specific Runtime agent. */
function expectRuntimeAgentContract(
contents: string,
contract: RuntimeAgentContract,
agentContents: string = contents,
): void {
const sourceFile = parseManagedSource(contents);
const runtimeOptions = newExpressionOptions(sourceFile, "CopilotRuntime");
expect(runtimeOptions).toHaveLength(1);
if (runtimeOptions.length !== 1) return;
const agents = objectPropertyAssignment(runtimeOptions[0]!, "agents");
expect(agents).not.toBeNull();
if (!agents) return;
const registeredAgents = unwrapExpression(agents.initializer);
if (contract.registration === "factory") {
expect(ts.isCallExpression(registeredAgents)).toBe(true);
if (!ts.isCallExpression(registeredAgents)) return;
const registeredCallee = propertyAccessParts(registeredAgents.expression);
const factoryCall =
registeredCallee.length === 1 &&
registeredCallee[0] === "createLocalAgents"
? sourceCalls(parseManagedSource(agentContents), contract.calleePath)[0]
: registeredAgents;
expect(factoryCall).not.toBeUndefined();
if (!factoryCall) return;
expect(propertyAccessParts(factoryCall.expression)).toEqual(
contract.calleePath,
);
const argument = factoryCall.arguments[0]
? unwrapExpression(factoryCall.arguments[0])
: null;
expect(argument && ts.isObjectLiteralExpression(argument)).toBe(true);
if (!argument || !ts.isObjectLiteralExpression(argument)) return;
expect(
objectPropertyIsIdentifier(
argument,
contract.argumentIdentifier,
contract.argumentIdentifier,
),
).toBe(true);
return;
}
expect(ts.isObjectLiteralExpression(registeredAgents)).toBe(true);
if (!ts.isObjectLiteralExpression(registeredAgents)) return;
const defaultAgent = objectPropertyAssignment(registeredAgents, "default");
expect(defaultAgent).not.toBeNull();
if (!defaultAgent) return;
const agent = registeredAgentExpression(sourceFile, defaultAgent.initializer);
let agentOptions: ts.ObjectLiteralExpression | null;
if (
ts.isCallExpression(agent) &&
propertyAccessParts(agent.expression).join(".") === "createDefaultAgent"
) {
const factoryAgentOptions = newExpressionOptions(
parseManagedSource(agentContents),
contract.constructorName,
);
expect(factoryAgentOptions).toHaveLength(1);
agentOptions = factoryAgentOptions[0] ?? null;
} else {
expect(ts.isNewExpression(agent)).toBe(true);
if (!ts.isNewExpression(agent)) return;
expect(propertyAccessParts(agent.expression)).toEqual([
contract.constructorName,
]);
const inlineAgentOptions = agent.arguments?.[0]
? unwrapExpression(agent.arguments[0])
: null;
expect(
inlineAgentOptions && ts.isObjectLiteralExpression(inlineAgentOptions),
).toBe(true);
if (
!inlineAgentOptions ||
!ts.isObjectLiteralExpression(inlineAgentOptions)
) {
return;
}
agentOptions = inlineAgentOptions;
}
expect(agentOptions && ts.isObjectLiteralExpression(agentOptions)).toBe(true);
if (!agentOptions || !ts.isObjectLiteralExpression(agentOptions)) return;
for (const optionContract of contract.options) {
const option = objectPropertyAssignment(
agentOptions,
optionContract.property,
);
expect(option).not.toBeNull();
if (!option) continue;
for (const identifier of optionContract.environmentReads ?? []) {
expect(expressionContainsEnvRead(option.initializer, identifier)).toBe(
true,
);
}
for (const literal of optionContract.stringLiterals ?? []) {
expect(expressionContainsStringLiteral(option.initializer, literal)).toBe(
true,
);
}
}
}
/** Asserts a Next/Hono runtime preserves its complete REST handler surface. */
function expectEndpointHandlerContract(contents: string): void {
const handlers = exportedEndpointHandlers(parseManagedSource(contents));
expect([...handlers].sort()).toEqual(["DELETE", "GET", "PATCH", "POST"]);
}
/** Asserts a frontend preserves REST transport and shared thread ownership. */
function expectFrontendThreadContract(
providerContents: string,
threadContents: string,
): void {
const providerSource = parseManagedSource(providerContents);
const threadSource = parseManagedSource(threadContents);
const providers = [
...jsxNodesWithTag(providerSource, "CopilotKit"),
...jsxNodesWithTag(providerSource, "CopilotKitProvider"),
];
const configurationProviders = jsxNodesWithTag(
threadSource,
"CopilotChatConfigurationProvider",
);
const drawers = jsxNodesWithTag(threadSource, "CopilotThreadsDrawer");
expect(providers).toHaveLength(1);
expect(configurationProviders).toHaveLength(1);
expect(drawers).toHaveLength(1);
if (
providers.length !== 1 ||
configurationProviders.length !== 1 ||
drawers.length !== 1
) {
return;
}
const provider = providers[0]!;
const configurationProvider = configurationProviders[0]!;
const drawer = drawers[0]!;
const configuredAgent = jsxAttributeIdentity(
jsxAttribute(configurationProvider, "agentId"),
);
const drawerAgent = jsxAttributeIdentity(jsxAttribute(drawer, "agentId"));
expect(jsxAttribute(provider, "runtimeUrl")).not.toBeNull();
expect(jsxAttributeIsFalse(jsxAttribute(provider, "useSingleEndpoint"))).toBe(
true,
);
expect(jsxAttribute(configurationProvider, "threadId")).toBeNull();
expect(configuredAgent).not.toBeNull();
expect(drawerAgent).toBe(configuredAgent);
expect(
jsxNodesWithTag(configurationProvider, "CopilotThreadsDrawer"),
).toHaveLength(1);
const configuredChatCount = [
"CopilotChat",
"CopilotSidebar",
"Chat",
"ResearchAssistant",
].reduce(
(count, tagName) =>
count + jsxNodesWithTag(configurationProvider, tagName).length,
0,
);
expect(configuredChatCount).toBeGreaterThan(0);
}
/** Asserts MCP Apps retains its client middleware configuration. */
function expectMcpAppsRuntimeBehavior(contents: string): void {
const sourceFile = parseManagedSource(contents);
const middlewareOptions = newExpressionOptions(
sourceFile,
"MCPAppsMiddleware",
);
const agentOptions = newExpressionOptions(sourceFile, "BuiltInAgent");
expect(middlewareOptions).toHaveLength(1);
expect(agentOptions).toHaveLength(1);
expect(sourceContainsCall(sourceFile, ["agent", "use"])).toBe(true);
if (middlewareOptions.length !== 1) return;
const serversProperty = objectPropertyAssignment(
middlewareOptions[0]!,
"mcpServers",
);
const servers = serversProperty
? unwrapExpression(serversProperty.initializer)
: null;
expect(servers && ts.isArrayLiteralExpression(servers)).toBe(true);
if (!servers || !ts.isArrayLiteralExpression(servers)) return;
const configuredServers = servers.elements.filter(
ts.isObjectLiteralExpression,
);
expect(configuredServers).toHaveLength(1);
if (configuredServers.length !== 1) return;
expect(objectPropertyIsString(configuredServers[0]!, "type", "http")).toBe(
true,
);
expect(
objectPropertyIsString(configuredServers[0]!, "serverId", "threejs"),
).toBe(true);
expect(
objectPropertyIsString(
configuredServers[0]!,
"url",
"http://localhost:3108/mcp",
),
).toBe(true);
}
/** Asserts the bundled MCP server retains its tools and UI resource. */
function expectMcpServerBehavior(
serverContents: string,
transportContents: string,
): void {
const serverSource = parseManagedSource(serverContents);
const transportSource = parseManagedSource(transportContents);
const appToolCalls = sourceCalls(serverSource, ["registerAppTool"]);
const toolCalls = sourceCalls(serverSource, ["server", "registerTool"]);
const resourceCalls = sourceCalls(serverSource, ["registerAppResource"]);
const routeCalls = sourceCalls(transportSource, ["app", "all"]);
expect(appToolCalls).toHaveLength(1);
expect(toolCalls).toHaveLength(1);
expect(resourceCalls).toHaveLength(1);
expect(routeCalls).toHaveLength(1);
expect(appToolCalls[0]?.arguments[1]).toMatchObject({
text: "show_threejs_scene",
});
expect(toolCalls[0]?.arguments[0]).toMatchObject({ text: "learn_threejs" });
expect(sourceContainsCall(serverSource, ["startServer"])).toBe(true);
expect(sourceContainsCall(transportSource, ["server", "connect"])).toBe(true);
expect(
sourceContainsCall(transportSource, ["transport", "handleRequest"]),
).toBe(true);
expect(routeCalls[0]?.arguments[0]).toMatchObject({ text: "/mcp" });
const resourceArgument = resourceCalls[0]?.arguments[1];
expect(resourceArgument && ts.isIdentifier(resourceArgument)).toBe(true);
expect(serverContents).toContain(
'const resourceUri = "ui://threejs/mcp-app.html"',
);
}
/** Returns whether source declares one class extending the expected base. */
function sourceContainsClassExtension(
sourceFile: ts.SourceFile,
className: string,
baseName: string,
): boolean {
let found = false;
/** Visits class declarations for the exact inheritance edge. */
function visit(node: ts.Node): void {
if (found) return;
if (
ts.isClassDeclaration(node) &&
node.name?.text === className &&
node.heritageClauses?.some(
(clause) =>
clause.token === ts.SyntaxKind.ExtendsKeyword &&
clause.types.some(
(type) =>
ts.isIdentifier(type.expression) &&
type.expression.text === baseName,
),
)
) {
found = true;
return;
}
ts.forEachChild(node, visit);
}
visit(sourceFile);
return found;
}
/** Asserts A2A retains isolated multi-agent routing and URL ownership. */
function expectA2ARuntimeBehavior(contents: string): void {
const sourceFile = parseManagedSource(contents);
const runtimeOptions = newExpressionOptions(
sourceFile,
"RuntimeA2AMiddlewareAgent",
).find((options) => objectPropertyAssignment(options, "agentUrls"));
expect(
sourceContainsClassExtension(
sourceFile,
"RuntimeA2AMiddlewareAgent",
"A2AMiddlewareAgent",
),
).toBe(true);
expect(newExpressionOptions(sourceFile, "A2AMiddlewareAgent")).toHaveLength(
1,
);
expect(
newExpressionOptions(sourceFile, "HttpAgent").length,
).toBeGreaterThanOrEqual(2);
expect(sourceContainsCall(sourceFile, ["isolatedAgent", "setMessages"])).toBe(
true,
);
expect(sourceContainsCall(sourceFile, ["isolatedAgent", "runAgent"])).toBe(
true,
);
for (const identifier of [
"RESEARCH_AGENT_URL",
"ANALYSIS_AGENT_URL",
"ORCHESTRATOR_URL",
]) {
expect(sourceContainsEnvRead(sourceFile, identifier)).toBe(true);
}
expect(runtimeOptions).toBeDefined();
if (!runtimeOptions) return;
expect(objectPropertyIsString(runtimeOptions, "agentId", "a2a_chat")).toBe(
true,
);
const agentUrls = objectPropertyAssignment(runtimeOptions, "agentUrls");
const orchestrationAgentUrl = objectPropertyAssignment(
runtimeOptions,
"orchestrationAgentUrl",
);
expect(agentUrls?.initializer.getText()).toBe(
"[researchAgentUrl, analysisAgentUrl]",
);
expect(orchestrationAgentUrl?.initializer.getText()).toBe("orchestratorUrl");
}
/** Asserts A2A visualization stays registered inside the configured chat. */
function expectA2AVisualizationBehavior(contents: string): void {
const sourceFile = parseManagedSource(contents);
const toolCalls = sourceCalls(sourceFile, ["useFrontendTool"]);
const visualizationTool = toolCalls.find((call) => {
const options = call.arguments[0]
? unwrapExpression(call.arguments[0])
: null;
return (
options &&
ts.isObjectLiteralExpression(options) &&
objectPropertyIsString(options, "name", "send_message_to_a2a_agent")
);
});
expect(visualizationTool).toBeDefined();
expect(jsxNodesWithTag(sourceFile, "MessageToA2A")).toHaveLength(1);
expect(jsxNodesWithTag(sourceFile, "MessageFromA2A")).toHaveLength(1);
expect(jsxNodesWithTag(sourceFile, "CopilotChat")).toHaveLength(1);
expect(jsxNodesWithTag(sourceFile, "CopilotKit")).toHaveLength(0);
expect(jsxNodesWithTag(sourceFile, "CopilotKitProvider")).toHaveLength(0);
}
/** Asserts AgentCore selects managed Intelligence or its custom local runner. */
function expectAgentCoreRuntimeBehavior(contents: string): void {
const sourceFile = parseManagedSource(contents);
const endpointCalls = sourceCalls(sourceFile, ["createCopilotEndpoint"]);
const requiredAgentUrl = sourceCalls(sourceFile, ["requireEnv"]).some(
(call) =>
call.arguments[0] &&
ts.isStringLiteral(call.arguments[0]) &&
call.arguments[0].text === "AGENTCORE_AG_UI_URL",
);
expect(
sourceContainsClassExtension(
sourceFile,
"AgentCoreRunner",
"InMemoryAgentRunner",
),
).toBe(true);
expect(requiredAgentUrl).toBe(true);
expect(newExpressionOptions(sourceFile, "HttpAgent")).toHaveLength(1);
expect(newExpressionOptions(sourceFile, "MCPAppsMiddleware")).toHaveLength(1);
const runtimeInitializers = variableInitializers(sourceFile, "runtime");
expect(runtimeInitializers).toHaveLength(1);
const runtimeSelection = runtimeInitializers[0]
? unwrapExpression(runtimeInitializers[0])
: null;
expect(runtimeSelection && ts.isConditionalExpression(runtimeSelection)).toBe(
true,
);
if (!runtimeSelection || !ts.isConditionalExpression(runtimeSelection)) {
return;
}
expect(
expressionUsesManagedKeyWithoutTelemetry(runtimeSelection.condition),
).toBe(true);
const managedOptions = constructorOptionsFromExpression(
runtimeSelection.whenTrue,
"CopilotRuntime",
);
const localOptions = constructorOptionsFromExpression(
runtimeSelection.whenFalse,
"CopilotRuntime",
);
expect(managedOptions).not.toBeNull();
expect(localOptions).not.toBeNull();
if (!managedOptions || !localOptions) return;
expect(
objectPropertyExpression(managedOptions, "intelligence"),
).not.toBeNull();
expect(objectPropertyExpression(managedOptions, "licenseToken")).toBeNull();
expect(objectPropertyExpression(managedOptions, "runner")).toBeNull();
expect(objectPropertyExpression(localOptions, "intelligence")).toBeNull();
const localRunner = objectPropertyExpression(localOptions, "runner");
expect(localRunner).not.toBeNull();
const unwrappedLocalRunner = localRunner
? unwrapExpression(localRunner)
: null;
expect(
unwrappedLocalRunner &&
ts.isNewExpression(unwrappedLocalRunner) &&
ts.isIdentifier(unwrappedLocalRunner.expression) &&
unwrappedLocalRunner.expression.text === "AgentCoreRunner",
).toBe(true);
expect(endpointCalls).toHaveLength(1);
const endpointOptions = endpointCalls[0]?.arguments[0];
const unwrappedOptions = endpointOptions
? unwrapExpression(endpointOptions)
: null;
expect(
unwrappedOptions && ts.isObjectLiteralExpression(unwrappedOptions),
).toBe(true);
if (!unwrappedOptions || !ts.isObjectLiteralExpression(unwrappedOptions)) {
return;
}
expect(
objectPropertyIsString(unwrappedOptions, "basePath", "/copilotkit"),
).toBe(true);
}
/** Asserts AgentCore local services retain bridge routing and one network. */
function expectAgentCoreNetworkingBehavior(contents: string): void {
const agent = yamlMappingSection(contents, "agent");
const bridge = yamlMappingSection(contents, "bridge");
const frontend = yamlMappingSection(contents, "frontend");
expect(agent).toMatch(/networks:\s*\n\s*- agentcore-network/);
expect(bridge).toContain("AGENTCORE_AG_UI_URL=http://agent:8080/invocations");
expect(bridge).toMatch(
/depends_on:\s*\n\s*agent:\s*\n\s*condition: service_healthy/,
);
expect(bridge).toMatch(/networks:\s*\n\s*- agentcore-network/);
expect(frontend).toMatch(
/depends_on:\s*\n\s*bridge:\s*\n\s*condition: service_started/,
);
expect(frontend).toMatch(/networks:\s*\n\s*- agentcore-network/);
expect(contents).toMatch(
/^networks:\s*\n\s*agentcore-network:\s*\n\s*driver: bridge\s*$/m,
);
}
/** Asserts an AgentCore deploy script preserves one framework variant. */
function expectAgentCoreVariantBehavior(
contents: string,
pattern: string,
suffix: string,
): void {
expect(contents).toMatch(new RegExp(`^PATTERN="${pattern}"$`, "m"));
expect(contents).toMatch(new RegExp(`^SUFFIX="${suffix}"$`, "m"));
expect(contents).toMatch(/^CONFIG="\$SCRIPT_DIR\/config\.yaml"$/m);
expect(contents).toMatch(
/npx cdk@latest deploy --all --require-approval never/,
);
expect(contents).toMatch(
/uv run --project "\$SCRIPT_DIR" "\$SCRIPT_DIR\/scripts\/deploy-frontend\.py" "\$STACK_NAME"/,
);
}
/** Returns the provider and thread-owning frontend surfaces for a template. */
function frontendBehaviorPaths(contract: ManagedTemplateContract): {
readonly providerPath: string;
readonly threadPath: string;
} {
if (contract.directory === "agentcore") {
const chatPath = "frontend/src/components/chat/CopilotKit/index.tsx";
return { providerPath: chatPath, threadPath: chatPath };
}
if (contract.directory === "a2a-middleware") {
return { providerPath: "app/page.tsx", threadPath: "app/page.tsx" };
}
if (contract.directory === "mcp-apps") {
return { providerPath: "app/layout.tsx", threadPath: "app/page.tsx" };
}
return {
providerPath: "src/app/layout.tsx",
threadPath: "src/app/page.tsx",
};
}
/** Assert AgentCore local services consume the CLI-managed root env safely. */
function expectAgentCoreLocalComposeContract(contents: string): void {
const bridge = yamlMappingSection(contents, "bridge");
const frontend = yamlMappingSection(contents, "frontend");
expect(bridge).toMatch(rootManagedEnvFilePattern());
expect(frontend).toMatch(rootManagedEnvFilePattern());
expect(frontend).not.toContain(VITE_THREADS_GATE);
expect(frontend).not.toContain(OPTIONAL_TELEMETRY_ID);
expect(bridge).not.toMatch(
new RegExp(`^\\s*-\\s*${INTELLIGENCE_API_URL}=`, "m"),
);
expect(bridge).not.toMatch(
new RegExp(`^\\s*-\\s*${INTELLIGENCE_GATEWAY_WS_URL}=`, "m"),
);
expect(contents).not.toMatch(exactEnvIdentifierPattern(LEGACY_API_KEY));
expect(contents).not.toMatch(exactEnvIdentifierPattern(LEGACY_TELEMETRY_ID));
expect(contents).not.toContain(MANAGED_LICENSE_TOKEN);
}
/** Assert AgentCore deploy configuration carries only a secret reference. */
function expectAgentCoreDeploymentConfigContract(contents: string): void {
const configuredSecretNames = contents.split(/\r?\n/).flatMap((line) => {
const match = line.match(
new RegExp(
`^${MANAGED_API_KEY_SECRET_CONFIG}\\s*:\\s*([^#\\s][^#]*?)\\s*(?:#.*)?$`,
),
);
return match?.[1] ? [match[1].trim()] : [];
});
expect(configuredSecretNames).toHaveLength(1);
expect(configuredSecretNames[0]).not.toMatch(/^\$\{|^process\.env\b/);
expect(contents).not.toMatch(exactEnvIdentifierPattern(MANAGED_API_KEY));
expect(contents).not.toMatch(
exactEnvIdentifierPattern(MANAGED_LICENSE_TOKEN),
);
expect(contents).not.toContain("copilotkit_license_token_secret_name");
}
/** Assert AgentCore's deployed Lambda resolves the managed key from a secret. */
function expectAgentCoreRuntimeDeploymentContract(contents: string): void {
const sourceFile = parseManagedSource(contents);
const lambdaOptions = constructOptions(
sourceFile,
["lambda", "Function"],
"CopilotKitRuntimeLambda",
);
expect(lambdaOptions).toHaveLength(1);
const environment = lambdaOptions[0]
? objectPropertyAssignment(lambdaOptions[0], "environment")
: null;
const environmentObject = environment
? unwrapExpression(environment.initializer)
: null;
expect(
environmentObject && ts.isObjectLiteralExpression(environmentObject),
).toBe(true);
const managedKey =
environmentObject && ts.isObjectLiteralExpression(environmentObject)
? objectPropertyAssignment(environmentObject, MANAGED_API_KEY)
: null;
const telemetryId =
environmentObject && ts.isObjectLiteralExpression(environmentObject)
? objectPropertyAssignment(environmentObject, OPTIONAL_TELEMETRY_ID)
: null;
const licenseToken =
environmentObject && ts.isObjectLiteralExpression(environmentObject)
? objectPropertyAssignment(environmentObject, MANAGED_LICENSE_TOKEN)
: null;
const apiUrl =
environmentObject && ts.isObjectLiteralExpression(environmentObject)
? objectEnvironmentExpression(environmentObject, INTELLIGENCE_API_URL)
: null;
const gatewayWsUrl =
environmentObject && ts.isObjectLiteralExpression(environmentObject)
? objectEnvironmentExpression(
environmentObject,
INTELLIGENCE_GATEWAY_WS_URL,
)
: null;
expect(managedKey).not.toBeNull();
expect(telemetryId).not.toBeNull();
expect(licenseToken).toBeNull();
expect(apiUrl).not.toBeNull();
expect(gatewayWsUrl).not.toBeNull();
if (!managedKey || !telemetryId || !apiUrl || !gatewayWsUrl) return;
expect(
expressionContainsPropertyPath(managedKey.initializer, [
"config",
MANAGED_API_KEY_SECRET_CONFIG,
]),
).toBe(true);
expect(expressionContainsSecretResolution(managedKey.initializer)).toBe(true);
expect(
expressionContainsEnvRead(
managedKey.initializer,
MANAGED_API_KEY_SECRET_VERSION_ID,
),
).toBe(true);
expect(
expressionContainsEnvRead(managedKey.initializer, MANAGED_API_KEY),
).toBe(false);
expect(
expressionContainsEnvRead(telemetryId.initializer, OPTIONAL_TELEMETRY_ID),
).toBe(true);
expect(expressionContainsSecretResolution(telemetryId.initializer)).toBe(
false,
);
expect(expressionContainsEnvRead(apiUrl, INTELLIGENCE_API_URL)).toBe(true);
expect(
expressionContainsEnvRead(gatewayWsUrl, INTELLIGENCE_GATEWAY_WS_URL),
).toBe(true);
}
/** Assert AgentCore does not carry a self-hosted license through managed AWS setup. */
function expectAgentCoreNoLicenseTokenContract(
deploymentConfig: string,
runtimeDeployment: string,
deployScripts: readonly string[],
): void {
for (const contents of [
deploymentConfig,
runtimeDeployment,
...deployScripts,
]) {
expect(contents).not.toMatch(
exactEnvIdentifierPattern(MANAGED_LICENSE_TOKEN),
);
expect(contents).not.toContain("copilotkit_license_token_secret_name");
expect(contents).not.toContain(
"COPILOTKIT_LICENSE_TOKEN_SECRET_VERSION_ID",
);
}
}
/** Assert Terraform clearly excludes the managed Intelligence credential path. */
function expectAgentCoreTerraformExclusionContract(
runtimeDeployment: string,
readme: string,
): void {
expect(runtimeDeployment).not.toMatch(
exactEnvIdentifierPattern(MANAGED_API_KEY),
);
expect(runtimeDeployment).not.toMatch(
exactEnvIdentifierPattern(OPTIONAL_TELEMETRY_ID),
);
expect(readme).toMatch(/does not project managed Intelligence credentials/i);
expect(readme).toMatch(/use the CDK deployment path/i);
}
/** Assert an AgentCore variant deploy script safely materializes its key secret. */
function expectAgentCoreDeployScriptContract(contents: string): void {
const normalized = contents.replace(/\\\r?\n\s*/g, " ");
const lines = normalized.split(/\r?\n/);
const rootEnvLoadIndex = lines.findIndex((line) =>
/(?:^|\s)(?:source|\.)\s+["']?\$\{?SCRIPT_DIR\}?\/\.env["']?(?:\s|$)/.test(
line,
),
);
const secretConfigAssignment = lines
.map((line, index) => ({
index,
match: line.match(
new RegExp(`^\\s*([A-Z][A-Z0-9_]*)=.*${MANAGED_API_KEY_SECRET_CONFIG}`),
),
}))
.find(({ match }) => match?.[1]);
const secretNameVariable = secretConfigAssignment?.match?.[1];
const secretCommands = lines
.map((line, index) => ({ index, line }))
.filter(
({ line }) =>
line.includes(`$${MANAGED_API_KEY}`) &&
/aws\s+secretsmanager\s+(?:create-secret|put-secret-value)\b/.test(
line,
),
);
const cdkDeployIndex = lines.findIndex((line) =>
/npx\s+cdk(?:@\S+)?\s+deploy\b/.test(line),
);
const skipBackendGuardIndex = lines.findIndex((line) =>
/if\s+\[\s+"\$SKIP_BACKEND"\s+=\s+true\s+\];\s+then/.test(line),
);
const backendDeployElseIndex = lines.findIndex(
(line, index) => index > skipBackendGuardIndex && line.trim() === "else",
);
const backendDeployEndIndex = lines.findIndex(
(line, index) => index > cdkDeployIndex && line.trim() === "fi",
);
const telemetryExportIndex = lines.findIndex((line) =>
new RegExp(`^\\s*export\\s+${OPTIONAL_TELEMETRY_ID}(?:=|\\s|$)`).test(line),
);
const disableAllexportIndex = lines.findIndex((line) =>
/^\s*set\s+\+a\s*$/.test(line),
);
const disableXtraceIndex = lines.findIndex((line) =>
/^\s*set\s+\+x\s*$/.test(line),
);
const managedKeyUnexportIndices = lines.flatMap((line, index) =>
new RegExp(`^\\s*export\\s+-n\\s+${MANAGED_API_KEY}\\s*$`).test(line)
? [index]
: [],
);
const managedKeyUnsetIndices = lines.flatMap((line, index) =>
new RegExp(`^\\s*unset\\s+${MANAGED_API_KEY}\\s*$`).test(line)
? [index]
: [],
);
const secretVersionExportIndex = lines.findIndex((line) =>
new RegExp(
`^\\s*export\\s+${MANAGED_API_KEY_SECRET_VERSION_ID}(?:=|\\s|$)`,
).test(line),
);
expect(contents).not.toMatch(
exactEnvIdentifierPattern(MANAGED_LICENSE_TOKEN),
);
expect(contents).not.toContain("copilotkit_license_token_secret_name");
expect(contents).not.toContain("COPILOTKIT_LICENSE_TOKEN_SECRET_VERSION_ID");
expect(rootEnvLoadIndex).toBeGreaterThanOrEqual(0);
expect(secretNameVariable).toBeDefined();
expect(secretCommands.length).toBeGreaterThan(0);
if (
secretConfigAssignment === undefined ||
secretNameVariable === undefined ||
secretCommands[0] === undefined
) {
throw new Error("AgentCore secret materialization contract is incomplete");
}
expect(skipBackendGuardIndex).toBeGreaterThanOrEqual(0);
expect(disableAllexportIndex).toBeGreaterThanOrEqual(0);
expect(disableAllexportIndex).toBeLessThan(rootEnvLoadIndex);
expect(disableXtraceIndex).toBeGreaterThanOrEqual(0);
expect(disableXtraceIndex).toBeLessThan(rootEnvLoadIndex);
expect(contents).not.toMatch(/^\s*set\s+-a\s*$/m);
expect(
managedKeyUnexportIndices.some((index) => index < rootEnvLoadIndex),
).toBe(true);
expect(
managedKeyUnexportIndices.some(
(index) => index > rootEnvLoadIndex && index < skipBackendGuardIndex,
),
).toBe(true);
expect(backendDeployElseIndex).toBeGreaterThan(skipBackendGuardIndex);
expect(secretConfigAssignment.index).toBeGreaterThan(backendDeployElseIndex);
expect(secretVersionExportIndex).toBeGreaterThan(backendDeployElseIndex);
expect(backendDeployEndIndex).toBeGreaterThan(cdkDeployIndex);
expect(telemetryExportIndex).toBeGreaterThan(rootEnvLoadIndex);
expect(cdkDeployIndex).toBeGreaterThan(
Math.max(telemetryExportIndex, ...secretCommands.map(({ index }) => index)),
);
for (const { line } of secretCommands) {
expect(line).toMatch(
new RegExp(
`printf\\s+['"]%s['"]\\s+["']\\$\\{?${MANAGED_API_KEY}\\}?["']\\s*\\|\\s*aws\\s+secretsmanager`,
),
);
expect(line).toMatch(
/--secret-string(?:=|\s+)file:\/\/\/dev\/stdin(?:\s|$)/,
);
expect(line).not.toMatch(
new RegExp(
`--secret-string(?:=|\\s+)["']?\\$\\{?${MANAGED_API_KEY}\\}?["']?(?:\\s|$)`,
),
);
expect(line).toMatch(
new RegExp(
`--(?:name|secret-id)(?:=|\\s+)["']?\\$\\{?${secretNameVariable}\\}?["']?(?:\\s|$)`,
),
);
}
expect(rootEnvLoadIndex).toBeLessThan(secretCommands[0].index);
expect(secretConfigAssignment.index).toBeLessThan(secretCommands[0].index);
expect(
managedKeyUnsetIndices.some(
(index) =>
index > skipBackendGuardIndex && index < backendDeployElseIndex,
),
).toBe(true);
expect(
managedKeyUnsetIndices.some(
(index) => index > secretCommands[0].index && index < cdkDeployIndex,
),
).toBe(true);
for (const backendOwnedIndex of [
secretConfigAssignment.index,
...secretCommands.map(({ index: commandIndex }) => commandIndex),
secretVersionExportIndex,
cdkDeployIndex,
]) {
expect(backendOwnedIndex).toBeGreaterThan(backendDeployElseIndex);
expect(backendOwnedIndex).toBeLessThan(backendDeployEndIndex);
}
}
/** Returns exact path filters for one top-level workflow event. */
function workflowEventPaths(contents: string, eventName: string): string[] {
const lines = contents.split(/\r?\n/);
const eventStart = lines.findIndex((line) => line === ` ${eventName}:`);
if (eventStart < 0) return [];
const relativeEventEnd = lines
.slice(eventStart + 1)
.findIndex((line) => /^(?:\S| {2}\S).*:\s*$/.test(line));
const eventEnd =
relativeEventEnd < 0 ? lines.length : eventStart + relativeEventEnd + 1;
const eventLines = lines.slice(eventStart, eventEnd);
const pathsStart = eventLines.findIndex((line) => line === " paths:");
if (pathsStart < 0) return [];
const paths: string[] = [];
for (const line of eventLines.slice(pathsStart + 1)) {
const match = line.match(/^ - ["']?(.+?)["']?\s*$/);
if (!match?.[1]) break;
paths.push(match[1]);
}
return paths;
}
interface WorkflowStep {
readonly name: string;
readonly run: string;
}
/** Returns named workflow steps with their complete run scripts. */
function workflowSteps(contents: string): WorkflowStep[] {
const lines = contents.split(/\r?\n/);
const stepStarts = lines.flatMap((line, index) =>
/^ - name:\s*/.test(line) ? [index] : [],
);
return stepStarts.map((start, position) => {
const end = stepStarts[position + 1] ?? lines.length;
const stepLines = lines.slice(start, end);
const name = stepLines[0]!
.replace(/^ - name:\s*/, "")
.replace(/^["']|["']$/g, "");
const runStart = stepLines.findIndex((line) =>
line.startsWith(" run:"),
);
const run =
runStart < 0
? ""
: stepLines
.slice(runStart)
.join("\n")
.replace(/^\s*run:\s*[|>-]?\s*/m, "")
.trim();
return { name, run };
});
}
/** Assert the parity workflow preserves filters and runs red contracts second. */
function expectIntegrationParityWorkflowContract(contents: string): void {
const expectedPaths = [
"examples/integrations/**",
"scripts/__tests__/integration-intelligence-migration.test.ts",
".github/workflows/integrations_parity.yml",
];
expect(workflowEventPaths(contents, "pull_request")).toEqual(expectedPaths);
expect(workflowEventPaths(contents, "push")).toEqual(expectedPaths);
const steps = workflowSteps(contents);
const parityIndex = steps.findIndex(
({ name }) => name === "Verify integration-demo parity",
);
const contractIndex = steps.findIndex(
({ name }) => name === "Verify Intelligence template credential contracts",
);
expect(parityIndex).toBeGreaterThanOrEqual(0);
expect(contractIndex).toBeGreaterThan(parityIndex);
expect(steps[parityIndex]?.run).toContain("pnpm parity:check");
expect(steps[contractIndex]?.run).toContain(
"pnpm exec vitest run scripts/__tests__/integration-intelligence-migration.test.ts",
);
}
/** Renders an exact workflow path-filter list for helper self-tests. */
function renderWorkflowPaths(values: readonly string[]): string {
return values.map((value) => ` - "${value}"`).join("\n");
}
for (const stack of INTELLIGENCE_DEV_STACKS) {
test(`${stack.integration} has a valid local Intelligence compose stack`, () => {
const compose = readIntelligenceDevSurface(
stack.integration,
"docker-compose.intelligence.yml",
);
const postgresInit = readIntelligenceDevSurface(
stack.integration,
"docker/postgres-init/01-create-databases.sql",
);
const readme = readIntelligenceDevSurface(stack.integration, "README.md");
const envExample = readOptionalIntelligenceDevSurface(
stack.integration,
".env.example",
);
expectDockerComposeConfigToSucceed(stack.integration);
expect(compose).toContain(`name: ${stack.projectName}`);
expect(compose).toContain(
`\${POSTGRES_HOST_PORT:-${stack.postgresPort}}:5432`,
);
expect(compose).toContain(`\${REDIS_HOST_PORT:-${stack.redisPort}}:6379`);
expect(compose).toContain(
`\${APP_API_HOST_PORT:-${stack.appApiPort}}:4201`,
);
expect(compose).toContain(
`\${GATEWAY_HOST_PORT:-${stack.gatewayPort}}:4401`,
);
expect(compose).toContain(
"./docker/postgres-init:/docker-entrypoint-initdb.d:ro",
);
expect(compose).not.toContain("./docker:/docker-entrypoint-initdb.d");
expect(compose).toContain("pg_isready -U intelligence -d intelligence_app");
expect(postgresInit).toBe(EXPECTED_POSTGRES_INIT_SQL);
expect(readme).toContain("## CopilotKit Intelligence & Threads (Optional)");
expect(readme).toContain("docker-compose.intelligence.yml");
expect(readme).toContain(
`INTELLIGENCE_API_URL=http://localhost:${stack.appApiPort}`,
);
expect(readme).toContain(
`INTELLIGENCE_GATEWAY_WS_URL=ws://localhost:${stack.gatewayPort}`,
);
if (envExample) {
expect(envExample).toContain(
`INTELLIGENCE_API_URL=http://localhost:${stack.appApiPort}`,
);
expect(envExample).toContain(
`INTELLIGENCE_GATEWAY_WS_URL=ws://localhost:${stack.gatewayPort}`,
);
}
}, 30_000);
}
test("local Intelligence compose host defaults do not collide", () => {
const projectNames = new Set(
INTELLIGENCE_DEV_STACKS.map((stack) => stack.projectName),
);
const postgresPorts = new Set(
INTELLIGENCE_DEV_STACKS.map((stack) => stack.postgresPort),
);
const redisPorts = new Set(
INTELLIGENCE_DEV_STACKS.map((stack) => stack.redisPort),
);
const appApiPorts = new Set(
INTELLIGENCE_DEV_STACKS.map((stack) => stack.appApiPort),
);
const gatewayPorts = new Set(
INTELLIGENCE_DEV_STACKS.map((stack) => stack.gatewayPort),
);
expect(projectNames.size).toBe(INTELLIGENCE_DEV_STACKS.length);
expect(postgresPorts.size).toBe(INTELLIGENCE_DEV_STACKS.length);
expect(redisPorts.size).toBe(INTELLIGENCE_DEV_STACKS.length);
expect(appApiPorts.size).toBe(INTELLIGENCE_DEV_STACKS.length);
expect(gatewayPorts.size).toBe(INTELLIGENCE_DEV_STACKS.length);
});
test("local Intelligence compose files drift only by declared starter ports and project names", () => {
const referenceStack = INTELLIGENCE_DEV_STACKS[0];
const remainingStacks = INTELLIGENCE_DEV_STACKS.slice(1);
const referenceCompose = normalizeIntelligenceComposeForDriftGuard(
readIntelligenceDevSurface(
referenceStack.integration,
"docker-compose.intelligence.yml",
),
);
for (const stack of remainingStacks) {
const compose = normalizeIntelligenceComposeForDriftGuard(
readIntelligenceDevSurface(
stack.integration,
"docker-compose.intelligence.yml",
),
);
expect(compose).toBe(referenceCompose);
}
});
test("managed TypeScript helpers reject API-key identifiers outside configured expressions", () => {
const unusedRuntimeRead = `
const unused = process.env.CPK_INTELLIGENCE_API_KEY;
// apiKey: process.env.CPK_INTELLIGENCE_API_KEY
const intelligence = { apiKey: "CPK_INTELLIGENCE_API_KEY" };
`;
const unusedGateRead = `
const unused = process.env["CPK_INTELLIGENCE_API_KEY"];
// NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED: process.env.CPK_INTELLIGENCE_API_KEY
export default {
env: { NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED: "false" },
};
`;
expect(() => expectManagedRuntimeContract(unusedRuntimeRead)).toThrow();
expect(() => expectManagedGateContract(unusedGateRead)).toThrow();
});
test("managed TypeScript helpers reject decoy configured properties", () => {
const decoyRuntimeRead = `
const decoy = { apiKey: process.env.CPK_INTELLIGENCE_API_KEY };
const intelligence = new CopilotKitIntelligence({ apiKey: "" });
`;
const decoyNextGateRead = `
const decoy = {
NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED:
process.env.CPK_INTELLIGENCE_API_KEY ? "true" : "false",
};
const nextConfig = {
env: { NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED: "false" },
};
export default nextConfig;
`;
expect(() => expectManagedRuntimeContract(decoyRuntimeRead)).toThrow();
expect(() => expectManagedGateContract(decoyNextGateRead)).toThrow();
});
test.each([
{
name: "inline client",
source: `
const runtime = new CopilotRuntime({
agents: {},
intelligence: new CopilotKitIntelligence({
apiKey: process.env.CPK_INTELLIGENCE_API_KEY,
}),
});
`,
},
{
name: "bound client",
source: `
const intelligence = new CopilotKitIntelligence({
apiKey: process.env.CPK_INTELLIGENCE_API_KEY,
});
const runtime = new CopilotRuntime({ agents: {}, intelligence });
`,
},
])(
"managed Runtime helper accepts a $name wired into the Runtime",
({ source }) => {
expect(() => expectManagedRuntimeContract(source)).not.toThrow();
},
);
test("managed Runtime helper rejects a configured Intelligence client that is not wired into the Runtime", () => {
const unusedConfiguredClient = `
const intelligence = new CopilotKitIntelligence({
apiKey: process.env.CPK_INTELLIGENCE_API_KEY,
});
const runtime = new CopilotRuntime({
agents: { default: new HttpAgent({ url: "http://localhost:8000" }) },
});
`;
expect(() => expectManagedRuntimeContract(unusedConfiguredClient)).toThrow();
});
test("managed gate helpers reject direct, concatenated, comment-only, and decoy key exposure", () => {
const invalidGateSources = [
`export default { env: { ${NEXT_THREADS_GATE}: process.env.${MANAGED_API_KEY} } };`,
`export default { env: { ${NEXT_THREADS_GATE}: "enabled-" + process.env.${MANAGED_API_KEY} } };`,
`
// ${NEXT_THREADS_GATE}: process.env.${MANAGED_API_KEY} ? "true" : "false"
export default { env: { ${NEXT_THREADS_GATE}: "false" } };
`,
`
const decoy = process.env.${MANAGED_API_KEY} ? "true" : "false";
export default { env: { ${NEXT_THREADS_GATE}: "false" } };
`,
];
for (const source of invalidGateSources) {
expect(() => expectManagedGateContract(source)).toThrow();
}
});
test("managed gate helpers accept a normalized Next boolean projection", () => {
const nextGate = `
export default {
env: {
${NEXT_THREADS_GATE}: process.env.${MANAGED_API_KEY}
? "true"
: "false",
},
};
`;
expect(() => expectManagedGateContract(nextGate)).not.toThrow();
});
test("AgentCore deployment does not forward the unused client entitlement marker", () => {
const contract = INTELLIGENCE_TEMPLATE_CONTRACTS.find(
({ directory }) => directory === "agentcore",
);
if (!contract || !("supportedPaths" in contract)) {
throw new Error("AgentCore managed template contract is missing");
}
const frontendDeployment = readManagedSurface(
contract,
contract.supportedPaths.frontendDeploymentPath,
"frontend deployment config",
);
const deployScripts = contract.supportedPaths.deployScriptPaths.map(
(deployScriptPath) =>
readManagedSurface(contract, deployScriptPath, "deploy script"),
);
expect(frontendDeployment).not.toMatch(
exactEnvIdentifierPattern(VITE_THREADS_GATE),
);
for (const deployScript of deployScripts) {
expect(deployScript).not.toMatch(
exactEnvIdentifierPattern(VITE_THREADS_GATE),
);
}
});
test("AgentCore structural helpers accept linked root-env, secret, and Lambda wiring", () => {
const deploymentConfig = `${MANAGED_API_KEY_SECRET_CONFIG}: cpk-managed-key`;
const runtimeDeployment = `
new lambda.Function(this, "CopilotKitRuntimeLambda", {
environment: {
${MANAGED_API_KEY}: cdk.SecretValue.secretsManager(
config.${MANAGED_API_KEY_SECRET_CONFIG},
{ versionId: process.env.${MANAGED_API_KEY_SECRET_VERSION_ID} },
).unsafeUnwrap(),
${OPTIONAL_TELEMETRY_ID}: process.env.${OPTIONAL_TELEMETRY_ID} ?? "",
${INTELLIGENCE_API_URL}: process.env.${INTELLIGENCE_API_URL} ?? "http://localhost:4201",
${INTELLIGENCE_GATEWAY_WS_URL}: process.env.${INTELLIGENCE_GATEWAY_WS_URL} ?? "ws://localhost:4401",
},
});
`;
const deployScript = `
set +a
set +x
export -n ${MANAGED_API_KEY}
source "$SCRIPT_DIR/.env"
export -n ${MANAGED_API_KEY}
export ${OPTIONAL_TELEMETRY_ID}
if [ "$SKIP_BACKEND" = true ]; then
unset ${MANAGED_API_KEY}
echo "Skipping backend"
else
CPK_SECRET_NAME=$(read_config ${MANAGED_API_KEY_SECRET_CONFIG})
printf '%s' "$${MANAGED_API_KEY}" | aws secretsmanager create-secret --name "$CPK_SECRET_NAME" --secret-string file:///dev/stdin
unset ${MANAGED_API_KEY}
export ${MANAGED_API_KEY_SECRET_VERSION_ID}
npx cdk deploy --all
fi
`;
expect(() =>
expectAgentCoreDeploymentConfigContract(deploymentConfig),
).not.toThrow();
expect(() =>
expectAgentCoreRuntimeDeploymentContract(runtimeDeployment),
).not.toThrow();
expect(() => expectAgentCoreDeployScriptContract(deployScript)).not.toThrow();
});
test("AgentCore structural helpers reject comment, unrelated-secret, and disconnected-command decoys", () => {
const runtimeDecoy = `
// ${MANAGED_API_KEY} uses config.${MANAGED_API_KEY_SECRET_CONFIG}
const unrelated = cdk.SecretValue.secretsManager("other-secret");
new lambda.Function(this, "CopilotKitRuntimeLambda", {
environment: {
${MANAGED_API_KEY}: "literal-key",
${OPTIONAL_TELEMETRY_ID}: "literal-telemetry-id",
},
});
`;
const runtimeTelemetrySecretDecoy = `
new lambda.Function(this, "CopilotKitRuntimeLambda", {
environment: {
${MANAGED_API_KEY}: cdk.SecretValue.secretsManager(
config.${MANAGED_API_KEY_SECRET_CONFIG},
).unsafeUnwrap(),
${OPTIONAL_TELEMETRY_ID}: cdk.SecretValue.secretsManager(
config.${MANAGED_API_KEY_SECRET_CONFIG},
).unsafeUnwrap(),
},
});
`;
const deployScriptDecoy = `
# source "$SCRIPT_DIR/.env"
CPK_SECRET_NAME=$(read_config ${MANAGED_API_KEY_SECRET_CONFIG})
echo "$${MANAGED_API_KEY}"
aws secretsmanager create-secret --name unrelated --secret-string literal
npx cdk deploy --all
export ${OPTIONAL_TELEMETRY_ID}
`;
const lateTelemetryExportDecoy = `
source "$SCRIPT_DIR/.env"
CPK_SECRET_NAME=$(read_config ${MANAGED_API_KEY_SECRET_CONFIG})
aws secretsmanager create-secret --name "$CPK_SECRET_NAME" --secret-string "$${MANAGED_API_KEY}"
npx cdk deploy --all
export ${OPTIONAL_TELEMETRY_ID}
`;
expect(() =>
expectAgentCoreRuntimeDeploymentContract(runtimeDecoy),
).toThrow();
expect(() =>
expectAgentCoreRuntimeDeploymentContract(runtimeTelemetrySecretDecoy),
).toThrow();
expect(() =>
expectAgentCoreDeployScriptContract(deployScriptDecoy),
).toThrow();
expect(() =>
expectAgentCoreDeployScriptContract(lateTelemetryExportDecoy),
).toThrow();
expect(() =>
expectAgentCoreDeploymentConfigContract(
`${MANAGED_API_KEY_SECRET_CONFIG}: \${${MANAGED_API_KEY}}`,
),
).toThrow();
});
test("AgentCore deployment helper rejects endpoint literals disconnected from the root env", () => {
const runtimeDeployment = `
new lambda.Function(this, "CopilotKitRuntimeLambda", {
environment: {
${MANAGED_API_KEY}: cdk.SecretValue.secretsManager(
config.${MANAGED_API_KEY_SECRET_CONFIG},
).unsafeUnwrap(),
${OPTIONAL_TELEMETRY_ID}: process.env.${OPTIONAL_TELEMETRY_ID} ?? "",
${INTELLIGENCE_API_URL}: "https://hard-coded.example",
${INTELLIGENCE_GATEWAY_WS_URL}: "wss://hard-coded.example",
},
});
`;
expect(() =>
expectAgentCoreRuntimeDeploymentContract(runtimeDeployment),
).toThrow();
});
test("AgentCore README documents caller-overridden remote endpoints for both AWS deploy variants", () => {
const readme = fs.readFileSync(
path.join(integrationsDir, "agentcore", "README.md"),
"utf8",
);
expectAgentCoreAwsEndpointReadmeContract(readme);
});
for (const scriptName of [
"deploy-langgraph.sh",
"deploy-strands.sh",
] as const) {
test(`${scriptName} validates AWS endpoint overrides before secret or CDK commands`, () => {
const deployScript = fs.readFileSync(
path.join(integrationsDir, "agentcore", scriptName),
"utf8",
);
expectAgentCoreAwsEndpointDeployContract(deployScript);
});
for (const invalidEndpoint of [
{
label: "localhost API URL",
envFile: {
apiUrl: "http://localhost:4201",
gatewayWsUrl: "wss://gateway.example.com/runtime",
},
expectedVariable: INTELLIGENCE_API_URL,
},
{
label: "127.0.0.1 gateway URL",
envFile: {
apiUrl: "https://intelligence.example.com/api",
gatewayWsUrl: "ws://127.0.0.1:4401",
},
expectedVariable: INTELLIGENCE_GATEWAY_WS_URL,
},
{
label: "Docker host API URL",
envFile: {
apiUrl: "http://host.docker.internal:4201",
gatewayWsUrl: "wss://gateway.example.com/runtime",
},
expectedVariable: INTELLIGENCE_API_URL,
expectedMessage: /reachable from AWS/i,
},
{
label: "non-TLS remote API URL",
envFile: {
apiUrl: "http://intelligence.example.com/api",
gatewayWsUrl: "wss://gateway.example.com/runtime",
},
expectedVariable: INTELLIGENCE_API_URL,
expectedMessage: /https:\/\//i,
},
{
label: "non-TLS remote gateway URL",
envFile: {
apiUrl: "https://intelligence.example.com/api",
gatewayWsUrl: "ws://gateway.example.com/runtime",
},
expectedVariable: INTELLIGENCE_GATEWAY_WS_URL,
expectedMessage: /wss:\/\//i,
},
] as const) {
test(`${scriptName} rejects ${invalidEndpoint.label} without exposing the managed key`, () => {
const result = runAgentCoreDeployHarness({
scriptName,
envFile: invalidEndpoint.envFile,
});
expect(result.status).toBe(1);
expect(result.output).toContain(invalidEndpoint.expectedVariable);
expect(result.output).toMatch(
"expectedMessage" in invalidEndpoint
? invalidEndpoint.expectedMessage
: /reachable from AWS/i,
);
expect(result.output).not.toContain(MANAGED_API_KEY_SENTINEL);
expect(result.cdkEnvironment).toBeNull();
});
}
test(`${scriptName} uses managed endpoint defaults when overrides are omitted`, () => {
const result = runAgentCoreDeployHarness({
scriptName,
envFile: {},
});
expect(result.status).toBe(0);
expect(result.cdkEnvironment).toBe("\n\n");
expect(result.output).not.toContain(MANAGED_API_KEY_SENTINEL);
});
test(`${scriptName} accepts sourced HTTPS and WSS endpoints and passes them to CDK`, () => {
const result = runAgentCoreDeployHarness({
scriptName,
envFile: {
apiUrl: "https://intelligence.example.com/api",
gatewayWsUrl: "wss://gateway.example.com/runtime",
},
});
expect(result.status).toBe(0);
expect(result.cdkEnvironment).toBe(
"https://intelligence.example.com/api\n" +
"wss://gateway.example.com/runtime\n",
);
expect(result.output).not.toContain(MANAGED_API_KEY_SENTINEL);
});
test(`${scriptName} passes the updated secret version to CDK without logging it`, () => {
const result = runAgentCoreDeployHarness({
scriptName,
envFile: {
apiUrl: "https://intelligence.example.com/api",
gatewayWsUrl: "wss://gateway.example.com/runtime",
},
});
expect(result.status).toBe(0);
expect(result.secretVersionId).toBe(
MANAGED_API_KEY_SECRET_VERSION_SENTINEL,
);
expect(result.output).not.toContain(
MANAGED_API_KEY_SECRET_VERSION_SENTINEL,
);
expect(result.output).not.toContain(MANAGED_API_KEY_SENTINEL);
});
test(`${scriptName} delivers the managed key only through Secrets Manager stdin`, () => {
const result = runAgentCoreDeployHarness({
scriptName,
envFile: {
apiUrl: "https://intelligence.example.com/api",
gatewayWsUrl: "wss://gateway.example.com/runtime",
},
skipFrontend: false,
xtrace: true,
});
expect(result.status).toBe(0);
expect(result.secretInputObservations).toEqual(["aws:key-stdin-match"]);
expect(result.secretExposureObservations).toEqual([]);
expect(result.awsCommands.join("\n")).not.toContain(
MANAGED_API_KEY_SENTINEL,
);
});
test(`${scriptName} --skip-backend leaves backend secret state untouched while deploying the frontend`, () => {
const result = runAgentCoreDeployHarness({
scriptName,
envFile: {
apiUrl: "https://intelligence.example.com/api",
gatewayWsUrl: "wss://gateway.example.com/runtime",
},
skipBackend: true,
skipFrontend: false,
});
expect(result.status).toBe(0);
expect(result.awsCommands).toEqual([
"sts get-caller-identity --query Account --output text",
]);
expect(result.npmCommands).toEqual([]);
expect(result.cdkEnvironment).toBeNull();
expect(result.secretVersionId).toBeNull();
expect(result.frontendStackName).toBe(
scriptName === "deploy-langgraph.sh"
? "agentcore-contract-lg"
: "agentcore-contract-st",
);
expect(result.frontendSecretVersionId).toBe("");
expect(result.secretExposureObservations).toEqual([]);
expect(result.secretInputObservations).toEqual([]);
expect(result.output).toContain("Skipping backend deploy (--skip-backend)");
expect(result.output).not.toContain("Managed Intelligence key stored");
expect(result.output).not.toContain(MANAGED_API_KEY_SENTINEL);
expect(result.output).not.toContain(
MANAGED_API_KEY_SECRET_VERSION_SENTINEL,
);
});
test(`${scriptName} preserves documented caller endpoint overrides over root localhost defaults`, () => {
const result = runAgentCoreDeployHarness({
scriptName,
envFile: {
apiUrl: "http://localhost:4201",
gatewayWsUrl: "ws://localhost:4401",
},
callerEnvironment: {
apiUrl: "https://managed-intelligence.example.com/api",
gatewayWsUrl: "wss://managed-gateway.example.com/runtime",
},
});
expect(result.status).toBe(0);
expect(result.cdkEnvironment).toBe(
"https://managed-intelligence.example.com/api\n" +
"wss://managed-gateway.example.com/runtime\n",
);
expect(result.output).not.toContain(MANAGED_API_KEY_SENTINEL);
});
}
test("managed TypeScript helpers reject malformed source", () => {
const malformedRuntime = `
const intelligence = new CopilotKitIntelligence({
apiKey: process.env.CPK_INTELLIGENCE_API_KEY,
});
}`;
const malformedGate = `
export default {
env: {
NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED:
process.env.CPK_INTELLIGENCE_API_KEY ? "true" : "false",
},
`;
expect(() => expectManagedRuntimeContract(malformedRuntime)).toThrow();
expect(() => expectManagedGateContract(malformedGate)).toThrow();
});
test("managed TypeScript helpers accept independent telemetry reads", () => {
const configuredRuntimeRead = `
const telemetryId = process.env.CPK_TELEMETRY_ID;
const intelligence = new CopilotKitIntelligence({
apiKey: process.env["CPK_INTELLIGENCE_API_KEY"] ?? "",
});
const runtime = new CopilotRuntime({ agents: {}, intelligence });
`;
const configuredGateRead = `
const telemetryId = process.env["CPK_TELEMETRY_ID"];
const nextConfig = {
env: {
NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED:
process.env.CPK_INTELLIGENCE_API_KEY ? "true" : "false",
},
};
export default nextConfig;
`;
expect(() =>
expectManagedRuntimeContract(configuredRuntimeRead),
).not.toThrow();
expect(() => expectManagedGateContract(configuredGateRead)).not.toThrow();
});
test("managed TypeScript helpers reject telemetry prerequisites", () => {
const telemetryGatedRuntime = `
const intelligence = new CopilotKitIntelligence({
apiKey:
process.env.CPK_INTELLIGENCE_API_KEY &&
process.env.CPK_TELEMETRY_ID,
});
const runtime = new CopilotRuntime({ agents: {}, intelligence });
`;
const telemetryGatedNextConfig = `
const nextConfig = {
env: {
NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED:
process.env.CPK_INTELLIGENCE_API_KEY &&
process.env.CPK_TELEMETRY_ID
? "true"
: "false",
},
};
export default nextConfig;
`;
expect(() => expectManagedRuntimeContract(telemetryGatedRuntime)).toThrow();
expect(() => expectManagedGateContract(telemetryGatedNextConfig)).toThrow();
});
/** Build the exact managed dotenv sections with telemetry semantics documented. */
function managedEnvExample(
telemetryDescription = "Optional, non-secret analytics identity.",
): string {
return [
"# Your CopilotKit Intelligence API Key",
"# Project Name: xxxxxxxxxx",
"CPK_INTELLIGENCE_API_KEY=xxxxx",
"",
"# CopilotKit Telemetry ID",
`# ${telemetryDescription}`,
"CPK_TELEMETRY_ID=xxxxx",
].join("\n");
}
test("managed documentation helpers reject misleading telemetry semantics", () => {
const misleadingDescriptions = [
"authentication credential",
"entitlement identity",
"feature enablement identity",
"analytics consent identity",
"telemetry send-policy identity",
];
for (const description of misleadingDescriptions) {
const envExample = managedEnvExample(
`Optional, non-secret analytics ${description}.`,
);
const readme = [
"## Managed Intelligence credentials",
"",
"Set `CPK_INTELLIGENCE_API_KEY` for the project.",
"",
`\`CPK_TELEMETRY_ID\` is an optional, non-secret analytics ${description}.`,
].join("\n");
expect(() => expectManagedEnvContract(envExample)).toThrow();
expect(() => expectManagedReadmeContract(readme)).toThrow();
}
});
test("managed documentation helpers accept an optional non-secret analytics identity", () => {
const envExample = managedEnvExample();
const readme = [
"## Managed Intelligence credentials",
"",
"Set `CPK_INTELLIGENCE_API_KEY` for the project.",
"",
"`CPK_TELEMETRY_ID` is an optional, non-secret analytics identity.",
"",
"## Offline or self-hosted licensing",
"",
"Set `COPILOTKIT_LICENSE_TOKEN` only for an offline deployment.",
].join("\n");
expect(() => expectManagedEnvContract(envExample)).not.toThrow();
expect(() => expectManagedReadmeContract(readme)).not.toThrow();
});
test("managed SDK compatibility rejects unclassified package versions", () => {
const pin = {
packageName: "@copilotkit/runtime",
packagePath: "package.json",
version: "9.9.9",
} as const satisfies ManagedSdkPin;
expect(() => pinSupportsManagedEntitlements(pin)).toThrow(
/must be classified/,
);
});
test("managed README helper rejects missing offline or self-hosted license guidance", () => {
const readme = [
"## Managed Intelligence credentials",
"",
"Set `CPK_INTELLIGENCE_API_KEY` for the project.",
"",
"`CPK_TELEMETRY_ID` is an optional, non-secret analytics identity.",
].join("\n");
expect(() => expectManagedReadmeContract(readme)).toThrow();
});
test.each([
{
invalidLayout: "two blank lines between sections",
envExample: managedEnvExample().replace(
"CPK_INTELLIGENCE_API_KEY=xxxxx\n\n# CopilotKit",
"CPK_INTELLIGENCE_API_KEY=xxxxx\n\n\n# CopilotKit",
),
},
{
invalidLayout: "duplicate telemetry section",
envExample: `${managedEnvExample()}\n\n# CopilotKit Telemetry ID\nCPK_TELEMETRY_ID=duplicate`,
},
])("managed documentation helpers reject $invalidLayout", ({ envExample }) => {
expect(() => expectManagedEnvContract(envExample)).toThrow();
});
test("managed documentation helpers reject license guidance inside the telemetry section", () => {
const envExample = `${managedEnvExample()}\nCOPILOTKIT_LICENSE_TOKEN=`;
const readme = [
"## Managed Intelligence credentials",
"",
"Set CPK_INTELLIGENCE_API_KEY for the project.",
"CPK_TELEMETRY_ID is an optional, non-secret analytics identity.",
"COPILOTKIT_LICENSE_TOKEN is not a managed credential.",
].join("\n");
expect(() => expectManagedEnvContract(envExample)).toThrow();
expect(() => expectManagedReadmeContract(readme)).toThrow();
});
test("managed documentation helpers reject separated unlabeled license guidance", () => {
const envExample = [
managedEnvExample(),
"",
"# Self-hosted / offline license",
"COPILOTKIT_LICENSE_TOKEN=",
"",
"# Troubleshooting",
"COPILOTKIT_LICENSE_TOKEN=",
].join("\n");
const readme = [
"## Managed Intelligence credentials",
"",
"Set CPK_INTELLIGENCE_API_KEY for the project.",
"CPK_TELEMETRY_ID is an optional, non-secret analytics identity.",
"",
"## Self-hosted / offline license",
"",
"Offline deployments may set COPILOTKIT_LICENSE_TOKEN.",
"",
"## Troubleshooting",
"",
"Set COPILOTKIT_LICENSE_TOKEN if the managed integration is unavailable.",
].join("\n");
expect(() => expectManagedEnvContract(envExample)).toThrow();
expect(() => expectManagedReadmeContract(readme)).toThrow();
});
test("managed documentation helpers reject reordered managed dotenv sections", () => {
const envExample = [
"# CopilotKit Telemetry ID",
"# Optional, non-secret analytics identity.",
"CPK_TELEMETRY_ID=xxxxx",
"",
"# Your CopilotKit Intelligence API Key",
"# Project Name: xxxxxxxxxx",
"CPK_INTELLIGENCE_API_KEY=xxxxx",
].join("\n");
const readme = [
"## Managed Intelligence credentials",
"",
"Set CPK_INTELLIGENCE_API_KEY for the project.",
"",
"## Analytics identity",
"",
"CPK_TELEMETRY_ID is an optional, non-secret analytics identity.",
].join("\n");
expect(() => expectManagedEnvContract(envExample)).toThrow();
expect(() => expectManagedReadmeContract(readme)).toThrow();
});
test("managed documentation helpers allow separate self-hosted and offline license guidance", () => {
const envExample = [
managedEnvExample(),
"",
"# Self-hosted / offline license",
"COPILOTKIT_LICENSE_TOKEN=",
].join("\n");
const readme = [
"## Managed Intelligence credentials",
"",
"Set CPK_INTELLIGENCE_API_KEY for the project.",
"CPK_TELEMETRY_ID is an optional, non-secret analytics identity.",
"",
"## Self-hosted / offline license",
"",
"Offline deployments may set COPILOTKIT_LICENSE_TOKEN instead.",
].join("\n");
expect(() => expectManagedEnvContract(envExample)).not.toThrow();
expect(() => expectManagedReadmeContract(readme)).not.toThrow();
});
test("managed documentation helpers reject unlabeled generic license-gating copy without an env literal", () => {
const envExample = [
managedEnvExample(),
"",
"# Product capabilities",
"# A license unlocks Threads and enables Inspector.",
].join("\n");
const readme = [
"## Managed Intelligence credentials",
"",
"Set CPK_INTELLIGENCE_API_KEY for the project.",
"CPK_TELEMETRY_ID is an optional, non-secret analytics identity.",
"",
"## Product capabilities",
"",
"A license activates Threads and unlocks Inspector.",
].join("\n");
expect(() => expectManagedEnvContract(envExample)).toThrow();
expect(() => expectManagedReadmeContract(readme)).toThrow();
});
test("managed documentation helpers allow generic license-gating copy only in self-hosted or offline sections", () => {
const envExample = [
managedEnvExample(),
"",
"# Self-hosted / offline license behavior",
"# A deployment license enables Threads and Inspector offline.",
].join("\n");
const readme = [
"## Managed Intelligence credentials",
"",
"Set CPK_INTELLIGENCE_API_KEY for the project.",
"CPK_TELEMETRY_ID is an optional, non-secret analytics identity.",
"",
"## Self-hosted / offline license behavior",
"",
"Set COPILOTKIT_LICENSE_TOKEN only for this deployment mode.",
"A deployment license enables Threads and Inspector offline.",
].join("\n");
expect(() => expectManagedEnvContract(envExample)).not.toThrow();
expect(() => expectManagedReadmeContract(readme)).not.toThrow();
});
test("route preservation helper rejects an incomplete handler export set", () => {
const route = `
const app = createCopilotEndpoint({ runtime, basePath: "/api/copilotkit" });
export const GET = handle(app);
export const POST = handle(app);
export const PATCH = handle(app);
`;
expect(() => expectEndpointHandlerContract(route)).toThrow();
});
test("frontend preservation helper rejects controlled thread state and single-endpoint transport", () => {
const frontend = `
export function App() {
return (
<CopilotKit runtimeUrl="/api/copilotkit" useSingleEndpoint={true}>
<CopilotChatConfigurationProvider agentId="default" threadId="thread-1">
<CopilotThreadsDrawer agentId="default" />
<CopilotChat />
</CopilotChatConfigurationProvider>
</CopilotKit>
);
}
`;
expect(() => expectFrontendThreadContract(frontend, frontend)).toThrow();
});
test("MCP preservation helper rejects a middleware-only scaffold without server behavior", () => {
const server = `
export function createServer() {
return new McpServer({ name: "Three.js Server", version: "1.0.0" });
}
`;
const transport = `
export function startServer() {
const app = createMcpExpressApp();
app.all("/mcp", () => undefined);
}
`;
expect(() => expectMcpServerBehavior(server, transport)).toThrow();
});
test("A2A preservation helper rejects collapsed single-agent routing", () => {
const route = `
const agent = new RuntimeA2AMiddlewareAgent({
agentId: "a2a_chat",
agentUrls: [],
orchestrationAgentUrl: "http://localhost:9000",
});
`;
expect(() => expectA2ARuntimeBehavior(route)).toThrow();
});
test("AgentCore preservation helper rejects disconnected local services", () => {
const compose = `
services:
agent:
image: agent
bridge:
image: bridge
frontend:
image: frontend
`;
expect(() => expectAgentCoreNetworkingBehavior(compose)).toThrow();
});
test("AgentCore preservation helper rejects a custom runner disconnected from Runtime selection", () => {
const runtime = `
class AgentCoreRunner extends InMemoryAgentRunner {}
const disconnectedRunner = new AgentCoreRunner();
const runtime = process.env.${MANAGED_API_KEY}
? new CopilotRuntime({
agents: {},
intelligence: new CopilotKitIntelligence({
apiKey: process.env.${MANAGED_API_KEY},
}),
identifyUser: () => ({ id: "demo-user" }),
})
: new CopilotRuntime({
agents: {},
runner: new InMemoryAgentRunner(),
});
const app = createCopilotEndpoint({ runtime, basePath: "/copilotkit" });
`;
expect(() => expectAgentCoreRuntimeBehavior(runtime)).toThrow();
});
test("integration parity workflow preserves filters and runs parity before the expected-red managed contract", () => {
const workflow = fs.readFileSync(INTEGRATION_PARITY_WORKFLOW, "utf8");
expectIntegrationParityWorkflowContract(workflow);
});
test("integration parity workflow helper rejects missing filters and reversed contract order", () => {
const paths = [
"examples/integrations/**",
"scripts/__tests__/integration-intelligence-migration.test.ts",
".github/workflows/integrations_parity.yml",
];
const workflow = (eventPaths: readonly string[], reversed: boolean) => `
on:
pull_request:
paths:
${renderWorkflowPaths(eventPaths)}
push:
paths:
${renderWorkflowPaths(paths)}
jobs:
parity-check:
steps:
- name: ${reversed ? "Verify Intelligence template credential contracts" : "Verify integration-demo parity"}
run: ${reversed ? "pnpm exec vitest run scripts/__tests__/integration-intelligence-migration.test.ts" : "pnpm parity:check"}
- name: ${reversed ? "Verify integration-demo parity" : "Verify Intelligence template credential contracts"}
run: ${reversed ? "pnpm parity:check" : "pnpm exec vitest run scripts/__tests__/integration-intelligence-migration.test.ts"}
`;
expect(() =>
expectIntegrationParityWorkflowContract(workflow(paths, true)),
).toThrow();
expect(() =>
expectIntegrationParityWorkflowContract(workflow(paths.slice(0, 2), false)),
).toThrow();
});
test("the 17 Intelligence template directories back all 19 in-repo CLI frameworks", () => {
const frameworks = INTELLIGENCE_TEMPLATE_CONTRACTS.flatMap(
(contract) => contract.frameworks,
);
const ordinaryRuntimeContracts = INTELLIGENCE_TEMPLATE_CONTRACTS.filter(
(contract) => "runtimeAgent" in contract,
);
expect(INTELLIGENCE_TEMPLATE_CONTRACTS).toHaveLength(17);
expect(ordinaryRuntimeContracts).toHaveLength(14);
expect(new Set(frameworks).size).toBe(19);
expect([...frameworks].sort()).toEqual(
[...INTELLIGENCE_CLI_FRAMEWORKS].sort(),
);
});
test("agentcore managed setup does not document a self-hosted license token", () => {
const contract = INTELLIGENCE_TEMPLATE_CONTRACTS.find(
({ directory }) => directory === "agentcore",
);
expect(contract).not.toBeUndefined();
if (!contract) return;
const readme = readManagedSurface(contract, contract.readmePath, "README");
expect(readme).not.toMatch(exactEnvIdentifierPattern(MANAGED_LICENSE_TOKEN));
});
test.each([
{
defect: "registered constructor changes",
contents: `
const defaultAgent = new WrongAgent({
url: process.env.AGENT_URL || "http://localhost:8000/",
});
new CopilotRuntime({ agents: { default: defaultAgent } });
`,
contract: HTTP_LOCALHOST_SLASH_RUNTIME_AGENT_CONTRACT,
},
{
defect: "required endpoint configuration disappears",
contents: `
const defaultAgent = new HttpAgent({
url: "http://localhost:8000/",
});
new CopilotRuntime({ agents: { default: defaultAgent } });
`,
contract: HTTP_LOCALHOST_SLASH_RUNTIME_AGENT_CONTRACT,
},
{
defect: "constructed agent is no longer registered",
contents: `
const defaultAgent = new HttpAgent({
url: process.env.AGENT_URL || "http://localhost:8000/",
});
new CopilotRuntime({ agents: { default: unregisteredAgent } });
`,
contract: HTTP_LOCALHOST_SLASH_RUNTIME_AGENT_CONTRACT,
},
{
defect: "framework factory changes",
contents: `
new CopilotRuntime({
agents: MastraAgent.getRemoteAgents({ mastra }),
});
`,
contract: MASTRA_RUNTIME_AGENT_CONTRACT,
},
])(
"the ordinary Runtime agent helper rejects when $defect",
({ contents, contract }) => {
expect(() => expectRuntimeAgentContract(contents, contract)).toThrow();
},
);
for (const contract of INTELLIGENCE_TEMPLATE_CONTRACTS) {
if ("runtimeAgent" in contract) {
test(`${contract.directory} runtime preserves its framework-specific agent wiring`, () => {
const runtime = readManagedSurface(
contract,
contract.runtimePath,
"runtime",
);
const agent =
contract.directory === "langgraph-fastapi"
? runtime
: readManagedSurface(contract, "src/agent.ts", "agent definition");
expectRuntimeAgentContract(runtime, contract.runtimeAgent, agent);
});
}
if (contract.directory !== "agentcore") {
test(`${contract.directory} runtime preserves all REST endpoint handlers`, () => {
const runtime = readManagedSurface(
contract,
contract.runtimePath,
"runtime",
);
expectEndpointHandlerContract(runtime);
});
}
test(`${contract.directory} frontend preserves REST transport and shared thread context`, () => {
const frontendPaths = frontendBehaviorPaths(contract);
const provider = readManagedSurface(
contract,
frontendPaths.providerPath,
"frontend provider",
);
const threadSurface = readManagedSurface(
contract,
frontendPaths.threadPath,
"thread surface",
);
expectFrontendThreadContract(provider, threadSurface);
});
if (contract.directory !== "agentcore") {
test(`${contract.directory} uses the no-token managed path with structured entitlements`, () => {
const runtime = readManagedSurface(
contract,
contract.runtimePath,
"runtime",
);
const gate = readManagedSurface(
contract,
contract.gatePath,
"client gate",
);
const readme = readManagedSurface(
contract,
contract.readmePath,
"README",
);
const pins = readManagedSdkPins(contract);
expect(pins.every(pinSupportsManagedEntitlements)).toBe(true);
expectManagedRuntimeContract(runtime);
expect(runtime).not.toMatch(
exactEnvIdentifierPattern(MANAGED_LICENSE_TOKEN),
);
expectManagedGateContract(gate);
for (const contents of [runtime, gate, readme]) {
expect(contents).not.toMatch(
exactEnvIdentifierPattern(OPTIONAL_TELEMETRY_ID),
);
}
});
}
if (contract.directory === "agentcore") {
test(`${contract.directory} runtime uses the managed Intelligence API key`, () => {
const runtime = readManagedSurface(
contract,
contract.runtimePath,
"runtime",
);
expectManagedRuntimeContract(runtime);
});
test(`${contract.directory} env example documents managed Intelligence credentials`, () => {
const envExample = readManagedSurface(
contract,
contract.envPath,
"env example",
);
expectManagedEnvContract(envExample);
});
test(`${contract.directory} README documents managed Intelligence credentials`, () => {
const readme = readManagedSurface(
contract,
contract.readmePath,
"README",
);
expectManagedReadmeContract(readme, false);
});
}
if (contract.directory === "mcp-apps") {
test("mcp-apps runtime preserves its MCP Apps client middleware", () => {
const agent = readManagedSurface(
contract,
"app/agent.ts",
"agent definition",
);
expectMcpAppsRuntimeBehavior(agent);
});
test("mcp-apps preserves its streamable HTTP tools and UI resource server", () => {
const server = readManagedSurface(
contract,
"threejs-server/server.ts",
"MCP server",
);
const transport = readManagedSurface(
contract,
"threejs-server/server-utils.ts",
"MCP transport",
);
expectMcpServerBehavior(server, transport);
});
}
if (contract.directory === "a2a-middleware") {
test("a2a-middleware preserves isolated multi-agent routing", () => {
const agent = readManagedSurface(
contract,
"app/agent.ts",
"agent definition",
);
expectA2ARuntimeBehavior(agent);
});
test("a2a-middleware preserves its configured chat visualization tool", () => {
const chat = readManagedSurface(
contract,
"components/chat.tsx",
"A2A chat",
);
expectA2AVisualizationBehavior(chat);
});
}
if ("supportedPaths" in contract) {
const supportedPaths = contract.supportedPaths;
test(`${contract.directory} runtime preserves AgentCore bridge behavior`, () => {
const runtime = readManagedSurface(
contract,
contract.runtimePath,
"runtime",
);
expectAgentCoreRuntimeBehavior(runtime);
});
test(`${contract.directory} local Compose preserves service networking`, () => {
const compose = readManagedSurface(
contract,
supportedPaths.localComposePath,
"local Compose config",
);
expectAgentCoreNetworkingBehavior(compose);
});
test(`${contract.directory} deploy scripts preserve LangGraph and Strands variants`, () => {
const variants = [
{
path: supportedPaths.deployScriptPaths[0]!,
pattern: "langgraph-single-agent",
suffix: "-lg",
},
{
path: supportedPaths.deployScriptPaths[1]!,
pattern: "strands-single-agent",
suffix: "-st",
},
];
for (const variant of variants) {
const deployScript = readManagedSurface(
contract,
variant.path,
"deploy script",
);
expectAgentCoreVariantBehavior(
deployScript,
variant.pattern,
variant.suffix,
);
expect(
fs.existsSync(
path.join(
integrationsDir,
contract.directory,
"agents",
variant.pattern,
),
),
).toBe(true);
}
});
test(`${contract.directory} local Compose consumes the root managed env`, () => {
const compose = readManagedSurface(
contract,
supportedPaths.localComposePath,
"local Compose config",
);
expectAgentCoreLocalComposeContract(compose);
});
test(`${contract.directory} deployment config stores a managed key secret reference`, () => {
const deploymentConfig = readManagedSurface(
contract,
supportedPaths.deploymentConfigPath,
"deployment config",
);
expectAgentCoreDeploymentConfigContract(deploymentConfig);
});
test(`${contract.directory} deployed Lambda resolves the managed key secret`, () => {
const runtimeDeployment = readManagedSurface(
contract,
supportedPaths.runtimeDeploymentPath,
"runtime deployment config",
);
expectAgentCoreRuntimeDeploymentContract(runtimeDeployment);
});
test(`${contract.directory} excludes self-hosted licenses from managed AWS setup`, () => {
const deploymentConfig = readManagedSurface(
contract,
supportedPaths.deploymentConfigPath,
"deployment config",
);
const runtimeDeployment = readManagedSurface(
contract,
supportedPaths.runtimeDeploymentPath,
"runtime deployment config",
);
const deployScripts = supportedPaths.deployScriptPaths.map(
(deployScriptPath) =>
readManagedSurface(contract, deployScriptPath, "deploy script"),
);
expectAgentCoreNoLicenseTokenContract(
deploymentConfig,
runtimeDeployment,
deployScripts,
);
});
test(`${contract.directory} explicitly excludes managed credentials from Terraform`, () => {
const terraformRuntimeDeployment = readManagedSurface(
contract,
supportedPaths.terraformRuntimeDeploymentPath,
"Terraform runtime deployment",
);
const terraformReadme = readManagedSurface(
contract,
supportedPaths.terraformReadmePath,
"Terraform README",
);
expectAgentCoreTerraformExclusionContract(
terraformRuntimeDeployment,
terraformReadme,
);
});
test(`${contract.directory} deploy scripts materialize the configured managed key secret`, () => {
for (const deployScriptPath of supportedPaths.deployScriptPaths) {
const deployScript = readManagedSurface(
contract,
deployScriptPath,
"deploy script",
);
expectAgentCoreDeployScriptContract(deployScript);
}
});
}
}
/** Assert AgentCore's AWS instructions document optional remote overrides. */
function expectAgentCoreAwsEndpointReadmeContract(contents: string): void {
expect(contents).toMatch(/Managed Intelligence uses its default endpoints/i);
expect(contents).toMatch(/For self-hosted\s+Intelligence/i);
expect(contents).toMatch(/endpoint overrides that AWS can reach/i);
expect(contents).toMatch(
/do not use\s+`localhost`[\s\S]{0,40}`127\.0\.0\.1`/i,
);
for (const scriptName of [
"deploy-langgraph.sh",
"deploy-strands.sh",
] as const) {
expect(contents).toMatch(
new RegExp(
`INTELLIGENCE_API_URL=https://[^\\s]+[\\s\\S]{0,200}` +
`INTELLIGENCE_GATEWAY_WS_URL=wss://[^\\s]+[\\s\\S]{0,200}` +
`\\./${scriptName.replace(".", "\\.")}`,
),
);
}
}
/** Assert one AgentCore deploy script validates remote endpoints before AWS writes. */
function expectAgentCoreAwsEndpointDeployContract(contents: string): void {
const normalized = contents.replace(/\\\r?\n\s*/g, " ");
const lines = normalized.split(/\r?\n/);
const rootEnvLoadIndex = lines.findIndex((line) =>
/(?:^|\s)(?:source|\.)\s+["']?\$\{?SCRIPT_DIR\}?\/\.env["']?(?:\s|$)/.test(
line,
),
);
const apiGuardIndex = lines.findIndex((line) =>
/validate_remote_override\s+INTELLIGENCE_API_URL\b/.test(line),
);
const gatewayGuardIndex = lines.findIndex((line) =>
/validate_remote_override\s+INTELLIGENCE_GATEWAY_WS_URL\b/.test(line),
);
const firstAwsWriteIndex = lines.findIndex((line) =>
/aws\s+secretsmanager\s+(?:create-secret|put-secret-value)\b/.test(line),
);
const cdkDeployIndex = lines.findIndex((line) =>
/npx\s+cdk(?:@\S+)?\s+deploy\b/.test(line),
);
expect(contents).toContain("${INTELLIGENCE_API_URL+x}");
expect(contents).toContain("${INTELLIGENCE_GATEWAY_WS_URL+x}");
expect(contents).toContain("localhost");
expect(contents).toContain("127\\.0\\.0\\.1");
expect(apiGuardIndex).toBeGreaterThan(rootEnvLoadIndex);
expect(gatewayGuardIndex).toBeGreaterThan(rootEnvLoadIndex);
expect(firstAwsWriteIndex).toBeGreaterThan(
Math.max(apiGuardIndex, gatewayGuardIndex),
);
expect(cdkDeployIndex).toBeGreaterThan(
Math.max(apiGuardIndex, gatewayGuardIndex),
);
}
/** Write one executable command stub into an AgentCore deploy harness. */
function writeAgentCoreCommandStub(
directory: string,
command: string,
contents = "#!/usr/bin/env bash\nexit 0\n",
): void {
const commandPath = path.join(directory, command);
fs.writeFileSync(commandPath, contents);
fs.chmodSync(commandPath, 0o755);
}
/** Render one optional endpoint into a shell environment assignment. */
function agentCoreEndpointAssignment(name: string, value?: string): string {
return value === undefined ? "" : `${name}=${value}\n`;
}
/** Read one optional newline-delimited harness capture. */
function readAgentCoreHarnessLines(capturePath: string): string[] {
if (!fs.existsSync(capturePath)) {
return [];
}
return fs
.readFileSync(capturePath, "utf8")
.split("\n")
.filter((line) => line.length > 0);
}
/** Emit a shell probe that records any backend-credential environment leak. */
function agentCoreSecretExposureProbe(command: string): string {
return [
`if [[ -n "\${${MANAGED_API_KEY}-}" ]]; then`,
` printf '%s\\n' '${command}:env' >> "\${SECRET_EXPOSURE_CAPTURE:?}"`,
"fi",
`if [[ "$*" == *'${MANAGED_API_KEY_SENTINEL}'* ]]; then`,
` printf '%s\\n' '${command}:argv' >> "\${SECRET_EXPOSURE_CAPTURE:?}"`,
"fi",
].join("\n");
}
/** Execute one real AgentCore deploy script against non-networking command stubs. */
function runAgentCoreDeployHarness(
options: AgentCoreDeployHarnessOptions,
): AgentCoreDeployHarnessResult {
const harnessDirectory = fs.mkdtempSync(
path.join(os.tmpdir(), "agentcore-deploy-contract-"),
);
try {
const fakeBin = path.join(harnessDirectory, "bin");
const cdkDirectory = path.join(harnessDirectory, "infra-cdk");
const capturePath = path.join(harnessDirectory, "cdk-environment.txt");
const awsCapturePath = path.join(harnessDirectory, "aws-commands.txt");
const npmCapturePath = path.join(harnessDirectory, "npm-commands.txt");
const frontendCapturePath = path.join(
harnessDirectory,
"frontend-environment.txt",
);
const secretExposureCapturePath = path.join(
harnessDirectory,
"secret-exposure.txt",
);
const secretInputCapturePath = path.join(
harnessDirectory,
"secret-input.txt",
);
const scriptPath = path.join(harnessDirectory, options.scriptName);
fs.mkdirSync(fakeBin);
fs.mkdirSync(cdkDirectory);
fs.mkdirSync(path.join(harnessDirectory, "scripts"));
fs.copyFileSync(
path.join(integrationsDir, "agentcore", options.scriptName),
scriptPath,
);
fs.writeFileSync(
path.join(harnessDirectory, ".env"),
[
`${MANAGED_API_KEY}=${MANAGED_API_KEY_SENTINEL}\n`,
`${OPTIONAL_TELEMETRY_ID}=agentcore-test-telemetry\n`,
agentCoreEndpointAssignment(
INTELLIGENCE_API_URL,
options.envFile.apiUrl,
),
agentCoreEndpointAssignment(
INTELLIGENCE_GATEWAY_WS_URL,
options.envFile.gatewayWsUrl,
),
].join(""),
);
fs.writeFileSync(
path.join(harnessDirectory, "config.yaml"),
[
"stack_name_base: agentcore-contract\n",
`${MANAGED_API_KEY_SECRET_CONFIG}: agentcore/contract/key\n`,
"backend:\n",
" pattern: placeholder\n",
].join(""),
);
for (const command of ["docker", "node"]) {
writeAgentCoreCommandStub(fakeBin, command);
}
writeAgentCoreCommandStub(
fakeBin,
"uv",
[
"#!/usr/bin/env bash\n",
"set -eu\n",
'[[ "${1-}" == "run" ]] && shift\n',
'if [[ "${1-}" == "--project" ]]; then shift 2; fi\n',
'if [[ "${1-}" == "python" ]]; then shift; exec python3 "$@"; fi\n',
'if [[ "${1-}" == *.py ]]; then exec python3 "$@"; fi\n',
'exec "$@"\n',
].join(""),
);
writeAgentCoreCommandStub(
fakeBin,
"npm",
[
"#!/usr/bin/env bash\n",
"set -eu\n",
`${agentCoreSecretExposureProbe("npm")}\n`,
'printf \'%s\\n\' "$*" >> "${NPM_COMMAND_CAPTURE:?}"\n',
].join(""),
);
writeAgentCoreCommandStub(
fakeBin,
"aws",
[
"#!/usr/bin/env bash\n",
"set -eu\n",
`${agentCoreSecretExposureProbe("aws")}\n`,
'printf \'%s\\n\' "$*" >> "${AWS_COMMAND_CAPTURE:?}"\n',
'if [[ "$*" == *"secretsmanager put-secret-value"* || "$*" == *"secretsmanager create-secret"* ]]; then\n',
" secret_input=$(cat)\n",
` if [[ "$secret_input" == '${MANAGED_API_KEY_SENTINEL}' ]]; then\n`,
" printf '%s\\n' 'aws:key-stdin-match' >> \"${SECRET_INPUT_CAPTURE:?}\"\n",
` printf '%s\\n' '${MANAGED_API_KEY_SECRET_VERSION_SENTINEL}'\n`,
" else\n",
" printf '%s\\n' 'aws:stdin-missing' >> \"${SECRET_INPUT_CAPTURE:?}\"\n",
" fi\n",
"fi\n",
].join(""),
);
writeAgentCoreCommandStub(
fakeBin,
"npx",
[
"#!/usr/bin/env bash\n",
"set -eu\n",
`${agentCoreSecretExposureProbe("npx")}\n`,
`printf '%s\\n%s\\n%s\\n' "\${${INTELLIGENCE_API_URL}-}" "\${${INTELLIGENCE_GATEWAY_WS_URL}-}" "\${${MANAGED_API_KEY_SECRET_VERSION_ID}-}" > "\${CDK_ENV_CAPTURE:?}"\n`,
].join(""),
);
fs.writeFileSync(
path.join(harnessDirectory, "scripts", "deploy-frontend.py"),
[
"import os\n",
"import pathlib\n",
"import sys\n",
`if os.environ.get('${MANAGED_API_KEY}'):\n`,
' with pathlib.Path(os.environ["SECRET_EXPOSURE_CAPTURE"]).open("a") as capture:\n',
' capture.write("frontend:env\\n")\n',
'pathlib.Path(os.environ["FRONTEND_CAPTURE"]).write_text(\n',
` f"{sys.argv[1]}\\n{os.environ.get('${MANAGED_API_KEY_SECRET_VERSION_ID}', '')}\\n"\n`,
")\n",
].join(""),
);
const environment = { ...process.env };
environment[MANAGED_API_KEY] = MANAGED_API_KEY_SENTINEL;
delete environment[INTELLIGENCE_API_URL];
delete environment[INTELLIGENCE_GATEWAY_WS_URL];
delete environment[MANAGED_API_KEY_SECRET_VERSION_ID];
environment.PATH = `${fakeBin}:${process.env.PATH ?? ""}`;
environment.CDK_ENV_CAPTURE = capturePath;
environment.AWS_COMMAND_CAPTURE = awsCapturePath;
environment.NPM_COMMAND_CAPTURE = npmCapturePath;
environment.FRONTEND_CAPTURE = frontendCapturePath;
environment.SECRET_EXPOSURE_CAPTURE = secretExposureCapturePath;
environment.SECRET_INPUT_CAPTURE = secretInputCapturePath;
if (options.callerEnvironment?.apiUrl !== undefined) {
environment[INTELLIGENCE_API_URL] = options.callerEnvironment.apiUrl;
}
if (options.callerEnvironment?.gatewayWsUrl !== undefined) {
environment[INTELLIGENCE_GATEWAY_WS_URL] =
options.callerEnvironment.gatewayWsUrl;
}
const scriptArguments = [
...(options.xtrace === true ? ["-x"] : []),
scriptPath,
...(options.skipFrontend === false ? [] : ["--skip-frontend"]),
...(options.skipBackend === true ? ["--skip-backend"] : []),
];
const result = spawnSync("/bin/bash", scriptArguments, {
cwd: harnessDirectory,
encoding: "utf8",
env: environment,
});
const output = `${result.stdout}${result.stderr}`;
const capturedEnvironment = fs.existsSync(capturePath)
? fs.readFileSync(capturePath, "utf8")
: null;
const capturedLines = capturedEnvironment?.split("\n") ?? [];
const cdkEnvironment = capturedEnvironment
? `${capturedLines[0] ?? ""}\n${capturedLines[1] ?? ""}\n`
: null;
const secretVersionId = capturedEnvironment
? (capturedLines[2] ?? null)
: null;
const frontendEnvironment = fs.existsSync(frontendCapturePath)
? fs.readFileSync(frontendCapturePath, "utf8").split("\n")
: null;
return {
status: result.status,
output,
cdkEnvironment,
secretVersionId,
awsCommands: readAgentCoreHarnessLines(awsCapturePath),
npmCommands: readAgentCoreHarnessLines(npmCapturePath),
frontendStackName: frontendEnvironment?.[0] ?? null,
frontendSecretVersionId: frontendEnvironment?.[1] ?? null,
secretExposureObservations: readAgentCoreHarnessLines(
secretExposureCapturePath,
),
secretInputObservations: readAgentCoreHarnessLines(
secretInputCapturePath,
),
};
} finally {
fs.rmSync(harnessDirectory, { force: true, recursive: true });
}
}
/**
* Mastra working-memory scope contract.
*
* `@ag-ui/mastra` writes the client's shared state into Mastra working memory
* BEFORE it streams a turn (`syncInputStateToWorkingMemory`). That write is
* unguarded and never creates the thread, because it assumes the resource-scoped
* store, which upserts. Under `scope: "thread"` the same write goes to thread
* metadata instead, and `@mastra/memory` throws `Thread <id> not found` when the
* thread row does not exist yet. On the first turn of a thread it never does, so
* the run aborts before the model is called and the chat never answers.
*
* Managed Intelligence makes that certain rather than likely: the Intelligence
* run handler replaces the client thread id with a platform-canonical one, which
* the Mastra store has never seen.
*
* Resource scope is the correct setting for these starters and keeps working
* memory per conversation, because the bridge derives the resource id from the
* thread id when no explicit resource id is configured.
*/
const MASTRA_MEMORY_GLOB_DIRECTORIES = ["src/mastra"] as const;
/** Returns every `.ts` file under one directory, recursively. */
function typeScriptFilesUnder(directory: string): string[] {
if (!fs.existsSync(directory)) return [];
return fs.readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
const entryPath = path.join(directory, entry.name);
if (entry.isDirectory()) return typeScriptFilesUnder(entryPath);
return entry.isFile() && entryPath.endsWith(".ts") ? [entryPath] : [];
});
}
/** Returns every Mastra source file across the integration starters. */
function mastraMemorySurfaces(): string[] {
return fs
.readdirSync(integrationsDir, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.flatMap((entry) =>
MASTRA_MEMORY_GLOB_DIRECTORIES.flatMap((relative) =>
typeScriptFilesUnder(path.join(integrationsDir, entry.name, relative)),
),
);
}
/**
* Returns whether one source configures thread-scoped Mastra working memory.
*
* @param contents - TypeScript source to inspect.
* @returns True when any `workingMemory` object sets `scope: "thread"`.
*/
function declaresThreadScopedWorkingMemory(contents: string): boolean {
const sourceFile = parseManagedSource(contents);
let found = false;
const visit = (node: ts.Node): void => {
if (found) return;
if (
ts.isPropertyAssignment(node) &&
propertyNameText(node.name) === "workingMemory"
) {
const initializer = unwrapExpression(node.initializer);
if (
ts.isObjectLiteralExpression(initializer) &&
objectPropertyIsString(initializer, "scope", "thread")
) {
found = true;
return;
}
}
ts.forEachChild(node, visit);
};
ts.forEachChild(sourceFile, visit);
return found;
}
test("integration starters never configure thread-scoped Mastra working memory", () => {
const surfaces = mastraMemorySurfaces();
// Guards against a vacuous pass: the mastra starter must be in scope.
expect(
surfaces.some((surface) =>
surface.includes(path.join("mastra", "src", "mastra")),
),
"the mastra starter's Mastra sources must be scanned",
).toBe(true);
const offenders = surfaces.filter((surface) =>
declaresThreadScopedWorkingMemory(fs.readFileSync(surface, "utf8")),
);
expect(
offenders.map((surface) => path.relative(integrationsDir, surface)),
"thread-scoped working memory aborts the first turn of every new thread",
).toEqual([]);
});
test.each([
{
configuration: "thread scope",
contents: `
new Memory({
options: { workingMemory: { enabled: true, scope: "thread" } },
});
`,
expected: true,
},
{
configuration: "resource scope",
contents: `
new Memory({
options: { workingMemory: { enabled: true, scope: "resource" } },
});
`,
expected: false,
},
{
configuration: "an omitted scope",
contents: `
new Memory({ options: { workingMemory: { enabled: true } } });
`,
expected: false,
},
{
configuration: "thread scope nested below other options",
contents: `
new Agent({
memory: new Memory({
options: {
workingMemory: { enabled: true, schema: AgentState, scope: "thread" },
},
}),
});
`,
expected: true,
},
{
configuration: "an unrelated thread-scoped option",
contents: `
new Memory({
options: { semanticRecall: { scope: "thread" } },
});
`,
expected: false,
},
])(
"the Mastra working-memory scope helper detects $configuration",
({ contents, expected }) => {
expect(declaresThreadScopedWorkingMemory(contents)).toBe(expected);
},
);