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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions web/packages/sdk/generateAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,12 @@ const computeInputHash = (): string => {
hash.update(`orval:${readOrvalVersion()}\n`);

const generatorSources = [
path.join(__dirname, 'orval.config.ts'),
path.join(ORVAL_DIR, 'generate.ts'),
path.join(ORVAL_DIR, 'constants.ts'),
path.join(ORVAL_DIR, 'format-generated.ts'),
path.join(ORVAL_DIR, 'generateCustomFetcher.ts'),
path.join(ORVAL_DIR, 'operationNameOverride.ts'),
path.join(__dirname, 'generateAll.ts'),
];
for (const file of generatorSources) {
Expand Down
44 changes: 44 additions & 0 deletions web/packages/sdk/orval/operationNameOverride.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ describe('operationNameOverride', () => {
).toBe('dataDesignerCreateJob');
});

it('create data designer job with create path segment', () => {
expect(
operationNameOverride({
operationId: 'create_job_apis_data_designer_v2_workspaces__workspace__jobs_create_post',
})
).toBe('dataDesignerCreateJob');
});

it('list workspaces', () => {
expect(
operationNameOverride({
Expand All @@ -60,6 +68,42 @@ describe('operationNameOverride', () => {
expect(operationNameOverride({ operationId: 'gateway_proxy_get' })).toBe('gatewayProxyGet');
});

// --- Job subtype routes ---

it('create agent analyze job', () => {
expect(
operationNameOverride({
operationId: 'create_job_apis_agents_v2_workspaces__workspace__jobs_analyze_post',
})
).toBe('agentsCreateAnalyzeJob');
});

it('list agent evaluate suite jobs', () => {
expect(
operationNameOverride({
operationId: 'list_jobs_apis_agents_v2_workspaces__workspace__jobs_evaluate_suite_get',
})
).toBe('agentsListEvaluateSuiteJobs');
});

it('get agent optimize job logs', () => {
expect(
operationNameOverride({
operationId:
'get_job_logs_apis_agents_v2_workspaces__workspace__jobs_optimize__name__logs_get',
})
).toBe('agentsGetOptimizeJobLogs');
});

it('list agent optimize skills job results', () => {
expect(
operationNameOverride({
operationId:
'list_job_results_apis_agents_v2_workspaces__workspace__jobs_optimize_skills__name__results_get',
})
).toBe('agentsListOptimizeSkillsJobResults');
});

// --- Flat collection endpoints (should keep original names) ---

it('list metric job results (flat)', () => {
Expand Down
40 changes: 38 additions & 2 deletions web/packages/sdk/orval/operationNameOverride.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
// - list_jobs_apis_customization_v2_workspaces__workspace__jobs_get -> customizationListJobs
// - create_job_apis_data_designer_v2_workspaces__workspace__jobs_post -> dataDesignerCreateJob
// - list_workspaces_apis_entities_v2_workspaces_get -> entitiesListWorkspaces
// - create_job_apis_agents_v2_workspaces__workspace__jobs_analyze_post -> agentsCreateAnalyzeJob
// - list_jobs_apis_agents_v2_workspaces__workspace__jobs_evaluate_suite_get -> agentsListEvaluateSuiteJobs
//
// Non-apis_ routes (unchanged):
// - gateway_proxy_get -> gatewayProxyGet
Expand Down Expand Up @@ -84,6 +86,37 @@ const extractAllPathResources = (pathPart: string): string[] => {
return segments.filter((_, i) => i % 2 === 0);
};

/**
* Qualifies generic job actions using job subtype routes.
*
* e.g., actionResource="job", pathResource="jobs_analyze" -> "analyze_job"
* e.g., actionResource="jobs", pathResource="jobs_evaluate_suite" -> "evaluate_suite_jobs"
* e.g., actionResource="job_logs", pathResource="jobs_optimize" -> "optimize_job_logs"
*/
const qualifyJobSubtypeResource = (
service: string,
actionResource: string,
pathResource: string
): string | undefined => {
if (service !== 'agents') {
return undefined;
}

const actionWords = actionResource.split('_');
const pathWords = pathResource.split('_');

if (pathWords.length < 2 || singularize(pathWords[0]) !== 'job') {
return undefined;
}

if (actionWords.length === 0 || singularize(actionWords[0]) !== 'job') {
return undefined;
}

const subtypeWords = pathWords.slice(1);
return [...subtypeWords, actionWords[0], ...actionWords.slice(1)].join('_');
};

/**
* Qualifies the action resource using path information for disambiguation.
* When the path is more specific than the action, the path qualifier is prepended.
Expand All @@ -93,9 +126,12 @@ const extractAllPathResources = (pathPart: string): string[] => {
* e.g., actionResource="job_result_aggregate_scores", pathResource="benchmark_jobs"
* -> "benchmark_job_result_aggregate_scores"
*/
const qualifyResource = (actionResource: string, pathResource: string): string => {
const qualifyResource = (service: string, actionResource: string, pathResource: string): string => {
if (!actionResource || !pathResource) return actionResource;

const jobSubtypeResource = qualifyJobSubtypeResource(service, actionResource, pathResource);
if (jobSubtypeResource) return jobSubtypeResource;

const actionWords = actionResource.split('_');
const pathWords = pathResource.split('_');

Expand Down Expand Up @@ -177,7 +213,7 @@ export const operationNameOverride = (operation: { operationId?: string }) => {
const pathResource = extractPrimaryResource(pathPart);

// Qualify the action resource using path context
const qualifiedResource = qualifyResource(actionResource, pathResource);
const qualifiedResource = qualifyResource(service, actionResource, pathResource);

// Build: {service}_{verb}_{qualifiedResource}
let name = normalizeOperationName(service, buildOperationName(service, verb, qualifiedResource));
Expand Down
Loading