Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 1 addition & 6 deletions web/packages/common/src/constants/query.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { JobStatus as IJobStatus, PlatformJobStatus } from '@nemo/sdk/generated/platform/schema';
import { PlatformJobStatus } from '@nemo/sdk/generated/platform/schema';

// Customizer uses Platform SDK status
export const CJobCancellableStatuses: PlatformJobStatus[] = [
Expand All @@ -16,11 +16,6 @@ export const CJobTerminalStatuses: PlatformJobStatus[] = [
PlatformJobStatus.error, // was 'failed'
PlatformJobStatus.cancelled,
];
export const IJobTerminalStatuses: IJobStatus[] = [
IJobStatus.completed,
IJobStatus.failed,
IJobStatus.cancelled,
];
export const PlatformJobTerminalStatuses: PlatformJobStatus[] = [
PlatformJobStatus.completed,
PlatformJobStatus.cancelled,
Expand Down
68 changes: 0 additions & 68 deletions web/packages/common/src/utils/chat.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { FlexibleMessage } from '@nemo/sdk/generated/platform/schema';
import {
ChatCompletion,
ChatCompletionChunk,
Expand Down Expand Up @@ -71,70 +70,3 @@ export const maybeInsertSystemMessage = (
...parsedMessages,
];
};

/**
* Safely extracts string content from a FlexibleMessage.
* Returns empty string if content is undefined, null, or not a string.
*/
const getStringContent = (content: unknown): string => {
if (typeof content === 'string') return content;
if (content === null || content === undefined) return '';
// Handle array content (OpenAI multi-part messages) by joining text parts
if (Array.isArray(content)) {
return content
.filter(
(part): part is { type: 'text'; text: string } =>
typeof part === 'object' && part?.type === 'text' && typeof part?.text === 'string'
)
.map((part) => part.text)
.join(' ');
}
return '';
};

/**
* Converts a FlexibleMessage (intake API) to ChatCompletionMessageParam (OpenAI).
* FlexibleMessage is provider-agnostic; this maps it to the OpenAI standard.
*/
export const toOpenAIMessage = (message: FlexibleMessage): ChatCompletionMessageParam => {
const { role, content, name, tool_calls, tool_call_id } = message;
const stringContent = getStringContent(content);

switch (role) {
case 'user':
return {
role: 'user',
content: stringContent,
...(typeof name === 'string' && { name }),
};
case 'assistant':
return {
role: 'assistant',
content: stringContent || null,
...(Array.isArray(tool_calls) && { tool_calls }),
};
case 'system':
return {
role: 'system',
content: stringContent,
...(typeof name === 'string' && { name }),
};
case 'tool':
return {
role: 'tool',
content: stringContent,
tool_call_id: typeof tool_call_id === 'string' ? tool_call_id : '',
};
case 'function':
// Map legacy 'function' role to 'tool' for OpenAI compatibility
return {
role: 'tool',
content: stringContent,
tool_call_id: typeof tool_call_id === 'string' ? tool_call_id : '',
};
case 'developer':
return { role: 'developer', content: stringContent };
default:
return { role: 'user', content: stringContent };
}
};
12 changes: 4 additions & 8 deletions web/packages/common/src/utils/query.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { JobStatus as IJobStatus, PlatformJobStatus } from '@nemo/sdk/generated/platform/schema';
import { PlatformJobStatus } from '@nemo/sdk/generated/platform/schema';

import * as DataView from '../components/DataView/internal';
import { JOB_POLLING_INTERVAL_MS } from '../constants';
import { CJobTerminalStatuses, IJobTerminalStatuses } from '../constants/query';
import { CJobTerminalStatuses } from '../constants/query';

export const getJobRefetchInterval = (status?: PlatformJobStatus | IJobStatus) => {
if (
!status ||
(!CJobTerminalStatuses.includes(status as PlatformJobStatus) &&
!IJobTerminalStatuses.includes(status as IJobStatus))
) {
export const getJobRefetchInterval = (status?: PlatformJobStatus) => {
if (!status || !CJobTerminalStatuses.includes(status)) {
return JOB_POLLING_INTERVAL_MS;
}
return false;
Expand Down
15 changes: 0 additions & 15 deletions web/packages/studio/src/api/intake/constants.ts

This file was deleted.

68 changes: 0 additions & 68 deletions web/packages/studio/src/api/intake/utils.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { MultiselectOption } from '@studio/constants/mutliselect';
import type { MultiselectOption } from '@studio/constants/mutliselect';

export const LOADING_FILES_OPTION: MultiselectOption = {
label: 'Loading files...',
value: 'loading',
isDisabled: true,
};

export enum FeedbackAddToDatasetFileSource {
New = 'Create new',
Existing = 'Add to existing',
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ import {
SelectRoot,
SelectTrigger,
} from '@nvidia/foundations-react-core';
import { FeedbackAddToDatasetFileSource } from '@studio/api/intake/constants';
import { LOADING_FILES_OPTION } from '@studio/components/DatasetFileSelect/constants';
import {
FeedbackAddToDatasetFileSource,
LOADING_FILES_OPTION,
} from '@studio/components/DatasetFileSelect/constants';
import { MultiselectOption } from '@studio/constants/mutliselect';
import { Plus } from 'lucide-react';
import { FC, ReactNode, useMemo } from 'react';
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { IntakeAnnotationsPanel } from '@studio/components/IntakeAnnotationsPanel';
import { resetMockAnnotations } from '@studio/mocks/intake/telemetry';
import { renderRoute, screen, waitFor, within } from '@studio/tests/util/render';
import userEvent from '@testing-library/user-event';

const spanId = 'span-root-001';
const sessionId = 'session-agent-run-001';

describe('IntakeAnnotationsPanel', () => {
beforeEach(() => {
resetMockAnnotations();
});

it('lists and creates span annotations through the generated client', async () => {
const user = userEvent.setup();

renderRoute(
<IntakeAnnotationsPanel workspace="default" spanId={spanId} sessionId={sessionId} />,
{ history: '/workspaces/default/intake/spans/span-root-001' }
);

expect(
await screen.findByText('Good final response, but verify policy citations.')
).toBeInTheDocument();

await user.click(screen.getByRole('button', { name: /Negative/i }));
expect(await screen.findByText('Negative feedback')).toBeInTheDocument();

await user.type(screen.getByPlaceholderText('Add a note about this span.'), 'Needs review.');
await user.click(screen.getByRole('button', { name: /Add Note/i }));

expect(await screen.findByText('Needs review.')).toBeInTheDocument();
});

it('deletes span annotations through the generated client', async () => {
const user = userEvent.setup();

renderRoute(
<IntakeAnnotationsPanel workspace="default" spanId={spanId} sessionId={sessionId} />,
{ history: '/workspaces/default/intake/spans/span-root-001' }
);

const note = await screen.findByRole('article', { name: 'Note annotation' });
await user.click(within(note).getByRole('button', { name: /Delete/i }));

await waitFor(() => {
expect(
screen.queryByText('Good final response, but verify policy citations.')
).not.toBeInTheDocument();
});
});
});
Loading
Loading