Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sound-lime-dingo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@inkeep/agents-core": patch
---

Add scope-aware query helpers and scoping isolation tests for junction tables
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { beforeEach, describe, expect, it } from 'vitest';
import { getDatasetRunConfigAgentRelations } from '../../../data-access/manage/evalConfig';
import type { AgentsManageDatabaseClient } from '../../../db/manage/manage-client';
import {
agents,
dataset,
datasetRunConfig,
datasetRunConfigAgentRelations,
} from '../../../db/manage/manage-schema';
import { createTestProject } from '../../../db/manage/test-manage-client';
import { generateId } from '../../../utils/conversations';
import { testManageDbClient } from '../../setup';

describe('datasetRunConfigAgentRelations scoping isolation', () => {
const tenantId = 'test-tenant';
let db: AgentsManageDatabaseClient;

beforeEach(() => {
db = testManageDbClient;
});

it('should scope agent relations by project when dataset run configs share the same ID', async () => {
const project1Id = generateId();
const project2Id = generateId();
const sharedRunConfigId = 'shared-run-config';
const agent1Id = generateId();
const agent2Id = generateId();
const dataset1Id = generateId();
const dataset2Id = generateId();

await createTestProject(db, tenantId, project1Id);
await createTestProject(db, tenantId, project2Id);

await db.insert(agents).values([
{
tenantId,
projectId: project1Id,
id: agent1Id,
name: 'Agent 1',
description: 'For project 1',
},
{
tenantId,
projectId: project2Id,
id: agent2Id,
name: 'Agent 2',
description: 'For project 2',
},
]);

await db.insert(dataset).values([
{ tenantId, projectId: project1Id, id: dataset1Id, name: 'Dataset 1' },
{ tenantId, projectId: project2Id, id: dataset2Id, name: 'Dataset 2' },
]);

await db.insert(datasetRunConfig).values([
{
tenantId,
projectId: project1Id,
id: sharedRunConfigId,
name: 'Run Config',
description: 'Shared',
datasetId: dataset1Id,
},
{
tenantId,
projectId: project2Id,
id: sharedRunConfigId,
name: 'Run Config',
description: 'Shared',
datasetId: dataset2Id,
},
]);

await db.insert(datasetRunConfigAgentRelations).values([
{
tenantId,
projectId: project1Id,
id: generateId(),
datasetRunConfigId: sharedRunConfigId,
agentId: agent1Id,
},
{
tenantId,
projectId: project2Id,
id: generateId(),
datasetRunConfigId: sharedRunConfigId,
agentId: agent2Id,
},
]);

const result1 = await getDatasetRunConfigAgentRelations(db)({
scopes: { tenantId, projectId: project1Id, datasetRunConfigId: sharedRunConfigId },
});
const result2 = await getDatasetRunConfigAgentRelations(db)({
scopes: { tenantId, projectId: project2Id, datasetRunConfigId: sharedRunConfigId },
});

expect(result1).toHaveLength(1);
expect(result1[0].agentId).toBe(agent1Id);
expect(result2).toHaveLength(1);
expect(result2[0].agentId).toBe(agent2Id);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { beforeEach, describe, expect, it } from 'vitest';
import { getEvaluationJobConfigEvaluatorRelations } from '../../../data-access/manage/evalConfig';
import type { AgentsManageDatabaseClient } from '../../../db/manage/manage-client';
import {
evaluationJobConfig,
evaluationJobConfigEvaluatorRelations,
evaluator,
} from '../../../db/manage/manage-schema';
import { createTestProject } from '../../../db/manage/test-manage-client';
import { generateId } from '../../../utils/conversations';
import { testManageDbClient } from '../../setup';

describe('evaluationJobConfigEvaluatorRelations scoping isolation', () => {
const tenantId = 'test-tenant';
let db: AgentsManageDatabaseClient;

beforeEach(() => {
db = testManageDbClient;
});

it('should scope evaluator relations by project when job configs share the same ID', async () => {
const project1Id = generateId();
const project2Id = generateId();
const sharedJobConfigId = 'shared-job-config';
const evaluator1Id = generateId();
const evaluator2Id = generateId();

await createTestProject(db, tenantId, project1Id);
await createTestProject(db, tenantId, project2Id);

await db.insert(evaluator).values([
{
tenantId,
projectId: project1Id,
id: evaluator1Id,
name: 'Evaluator 1',
description: 'For project 1',
prompt: 'evaluate',
schema: {},
model: { model: 'test-model' },
},
{
tenantId,
projectId: project2Id,
id: evaluator2Id,
name: 'Evaluator 2',
description: 'For project 2',
prompt: 'evaluate',
schema: {},
model: { model: 'test-model' },
},
]);

await db.insert(evaluationJobConfig).values([
{ tenantId, projectId: project1Id, id: sharedJobConfigId },
{ tenantId, projectId: project2Id, id: sharedJobConfigId },
]);

await db.insert(evaluationJobConfigEvaluatorRelations).values([
{
tenantId,
projectId: project1Id,
id: generateId(),
evaluationJobConfigId: sharedJobConfigId,
evaluatorId: evaluator1Id,
},
{
tenantId,
projectId: project2Id,
id: generateId(),
evaluationJobConfigId: sharedJobConfigId,
evaluatorId: evaluator2Id,
},
]);

const result1 = await getEvaluationJobConfigEvaluatorRelations(db)({
scopes: { tenantId, projectId: project1Id, evaluationJobConfigId: sharedJobConfigId },
});
const result2 = await getEvaluationJobConfigEvaluatorRelations(db)({
scopes: { tenantId, projectId: project2Id, evaluationJobConfigId: sharedJobConfigId },
});

expect(result1).toHaveLength(1);
expect(result1[0].evaluatorId).toBe(evaluator1Id);
expect(result2).toHaveLength(1);
expect(result2[0].evaluatorId).toBe(evaluator2Id);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { beforeEach, describe, expect, it } from 'vitest';
import { getEvaluationRunConfigEvaluationSuiteConfigRelations } from '../../../data-access/manage/evalConfig';
import type { AgentsManageDatabaseClient } from '../../../db/manage/manage-client';
import {
evaluationRunConfig,
evaluationRunConfigEvaluationSuiteConfigRelations,
evaluationSuiteConfig,
} from '../../../db/manage/manage-schema';
import { createTestProject } from '../../../db/manage/test-manage-client';
import { generateId } from '../../../utils/conversations';
import { testManageDbClient } from '../../setup';

describe('evaluationRunConfigEvaluationSuiteConfigRelations scoping isolation', () => {
const tenantId = 'test-tenant';
let db: AgentsManageDatabaseClient;

beforeEach(() => {
db = testManageDbClient;
});

it('should scope suite config relations by project when run configs share the same ID', async () => {
const project1Id = generateId();
const project2Id = generateId();
const sharedRunConfigId = 'shared-run-config';
const suiteConfig1Id = generateId();
const suiteConfig2Id = generateId();

await createTestProject(db, tenantId, project1Id);
await createTestProject(db, tenantId, project2Id);

await db.insert(evaluationRunConfig).values([
{
tenantId,
projectId: project1Id,
id: sharedRunConfigId,
name: 'Run Config',
description: 'Shared',
},
{
tenantId,
projectId: project2Id,
id: sharedRunConfigId,
name: 'Run Config',
description: 'Shared',
},
]);

await db.insert(evaluationSuiteConfig).values([
{ tenantId, projectId: project1Id, id: suiteConfig1Id },
{ tenantId, projectId: project2Id, id: suiteConfig2Id },
]);

await db.insert(evaluationRunConfigEvaluationSuiteConfigRelations).values([
{
tenantId,
projectId: project1Id,
id: generateId(),
evaluationRunConfigId: sharedRunConfigId,
evaluationSuiteConfigId: suiteConfig1Id,
},
{
tenantId,
projectId: project2Id,
id: generateId(),
evaluationRunConfigId: sharedRunConfigId,
evaluationSuiteConfigId: suiteConfig2Id,
},
]);

const result1 = await getEvaluationRunConfigEvaluationSuiteConfigRelations(db)({
scopes: { tenantId, projectId: project1Id, evaluationRunConfigId: sharedRunConfigId },
});
const result2 = await getEvaluationRunConfigEvaluationSuiteConfigRelations(db)({
scopes: { tenantId, projectId: project2Id, evaluationRunConfigId: sharedRunConfigId },
});

expect(result1).toHaveLength(1);
expect(result1[0].evaluationSuiteConfigId).toBe(suiteConfig1Id);
expect(result2).toHaveLength(1);
expect(result2[0].evaluationSuiteConfigId).toBe(suiteConfig2Id);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { beforeEach, describe, expect, it } from 'vitest';
import { getEvaluationSuiteConfigEvaluatorRelations } from '../../../data-access/manage/evalConfig';
import type { AgentsManageDatabaseClient } from '../../../db/manage/manage-client';
import {
evaluationSuiteConfig,
evaluationSuiteConfigEvaluatorRelations,
evaluator,
} from '../../../db/manage/manage-schema';
import { createTestProject } from '../../../db/manage/test-manage-client';
import { generateId } from '../../../utils/conversations';
import { testManageDbClient } from '../../setup';

describe('evaluationSuiteConfigEvaluatorRelations scoping isolation', () => {
const tenantId = 'test-tenant';
let db: AgentsManageDatabaseClient;

beforeEach(() => {
db = testManageDbClient;
});

it('should scope evaluator relations by project when suite configs share the same ID', async () => {
const project1Id = generateId();
const project2Id = generateId();
const sharedSuiteConfigId = 'shared-suite-config';
const evaluator1Id = generateId();
const evaluator2Id = generateId();

await createTestProject(db, tenantId, project1Id);
await createTestProject(db, tenantId, project2Id);

await db.insert(evaluator).values([
{
tenantId,
projectId: project1Id,
id: evaluator1Id,
name: 'Evaluator 1',
description: 'For project 1',
prompt: 'evaluate',
schema: {},
model: { model: 'test-model' },
},
{
tenantId,
projectId: project2Id,
id: evaluator2Id,
name: 'Evaluator 2',
description: 'For project 2',
prompt: 'evaluate',
schema: {},
model: { model: 'test-model' },
},
]);

await db.insert(evaluationSuiteConfig).values([
{ tenantId, projectId: project1Id, id: sharedSuiteConfigId },
{ tenantId, projectId: project2Id, id: sharedSuiteConfigId },
]);

await db.insert(evaluationSuiteConfigEvaluatorRelations).values([
{
tenantId,
projectId: project1Id,
id: generateId(),
evaluationSuiteConfigId: sharedSuiteConfigId,
evaluatorId: evaluator1Id,
},
{
tenantId,
projectId: project2Id,
id: generateId(),
evaluationSuiteConfigId: sharedSuiteConfigId,
evaluatorId: evaluator2Id,
},
]);

const result1 = await getEvaluationSuiteConfigEvaluatorRelations(db)({
scopes: { tenantId, projectId: project1Id, evaluationSuiteConfigId: sharedSuiteConfigId },
});
const result2 = await getEvaluationSuiteConfigEvaluatorRelations(db)({
scopes: { tenantId, projectId: project2Id, evaluationSuiteConfigId: sharedSuiteConfigId },
});

expect(result1).toHaveLength(1);
expect(result1[0].evaluatorId).toBe(evaluator1Id);
expect(result2).toHaveLength(1);
expect(result2[0].evaluatorId).toBe(evaluator2Id);
});
});
Loading