Skip to content

Commit

Permalink
fix(tools): api calling detail modal (#185)
Browse files Browse the repository at this point in the history
Signed-off-by: Petr Kadlec <[email protected]>
  • Loading branch information
kapetr authored Jan 16, 2025
1 parent 5a1b1a0 commit fc3c8f4
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/layout/shell/MainNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function MainNav() {
onMouseEnter={() => prefetchData()}
>
<span className={classes.label}>{label}</span>
{count && <span className={classes.count}>{count}</span>}
<span className={classes.count}>{count}</span>
</Link>
</li>
))}
Expand Down
4 changes: 4 additions & 0 deletions src/modules/assistants/tools/ToolInfoButton.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
display: flex;
flex-direction: column;
gap: $spacing-04;
p {
@include type-style('body-compact-01');
}
a,
.openDetailBtn {
color: $link-inverse;
&:hover {
Expand Down
15 changes: 10 additions & 5 deletions src/modules/assistants/tools/ToolInfoButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
import { ToolReference } from '@/app/api/tools/types';
import { Tooltip } from '@/components/Tooltip/Tooltip';
import classes from './ToolInfoButton.module.scss';
import { ArrowUpRight, Information } from '@carbon/react/icons';
import { ArrowUpRight, Edit, Information } from '@carbon/react/icons';
import { useToolInfo } from '@/modules/tools/hooks/useToolInfo';
import { LinkButton } from '@/components/LinkButton/LinkButton';
import { useModal } from '@/layout/providers/ModalProvider';
import { UserToolModal } from '@/modules/tools/manage/UserToolModal';
import { PublicToolModal } from '@/modules/tools/manage/PublicToolModal';
import { useAppContext } from '@/layout/providers/AppProvider';
import { ToolDescription } from '@/modules/tools/ToolCard';

interface Props {
toolReference: ToolReference;
Expand All @@ -41,21 +42,25 @@ export function ToolInfoButton({ toolReference }: Props) {
? tool.description
: (tool.uiMetadata.description_short ?? tool.user_description);

const isEditable = tool.type === 'user' && !isProjectReadOnly;

return (
<Tooltip
asChild
content={
<div className={classes.tooltip}>
<span>{toolDescription}</span>
<span>
<ToolDescription description={toolDescription ?? ''} />
</span>
<LinkButton
as="span"
className={classes.openDetailBtn}
icon={ArrowUpRight}
icon={isEditable ? Edit : ArrowUpRight}
onClick={() =>
openModal((props) => (
<>
{tool.type === 'user' ? (
isProjectReadOnly ? (
!isEditable ? (
<UserToolModal.View tool={tool} {...props} />
) : (
<UserToolModal {...props} tool={tool} />
Expand All @@ -67,7 +72,7 @@ export function ToolInfoButton({ toolReference }: Props) {
))
}
>
View Details
{isEditable ? 'Edit tool' : 'View Details'}
</LinkButton>
</div>
}
Expand Down
27 changes: 17 additions & 10 deletions src/modules/tools/manage/UserToolModal.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
gap: $spacing-06;
margin-block-end: $spacing-06;
}
dt {
p {
@include type-style('body-compact-01');
}
}
}

@include breakpoint-up(md) {
Expand All @@ -156,15 +161,17 @@
}
}

.apiSchema {
max-block-size: 20rem;
overflow-y: auto;
display: block;
border-radius: $block-radius;
&:focus-within {
outline: 2px solid $focus;
}
textarea:focus {
outline: none;
.apiSchemaField {
> div {
max-block-size: 20rem;
overflow-y: auto;
display: block;
border-radius: $block-radius;
&:focus-within {
outline: 2px solid $focus;
}
textarea:focus {
outline: none;
}
}
}
32 changes: 21 additions & 11 deletions src/modules/tools/manage/UserToolModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import classes from './UserToolModal.module.scss';
import { useModalControl } from '@/layout/providers/ModalControlProvider';
import { useConfirmModalCloseOnDirty } from '@/layout/hooks/useConfirmModalCloseOnDirtyFields';
import { useAppContext } from '@/layout/providers/AppProvider';
import { ToolDescription } from '../ToolCard';

const EXAMPLE_SOURCE_CODE = `# The following code is just an example
Expand All @@ -67,10 +68,11 @@ def ip_info(ip: str) -> dict:
return response.json()`;

const TOOL_TYPES = [
{ key: 'code' as const, label: 'Code' },
{ key: 'api-call' as const, label: 'API calling' },
{ key: 'function' as const, label: 'Python function' },
{ key: 'api' as const, label: 'API calling' },
];
type ToolType = (typeof TOOL_TYPES)[number];
type ToolTypeKey = ToolType['key'];

const API_AUTH_METHODS = [
{ key: 'none' as const, label: 'None' },
Expand Down Expand Up @@ -117,7 +119,7 @@ export function UserToolModal({
defaultValues: {
type:
TOOL_TYPES.find(({ key }) =>
tool?.open_api_schema ? key === 'api-call' : key === 'code',
tool?.open_api_schema ? key === 'api' : key === 'function',
) ?? TOOL_TYPES[0],
name: tool?.name || '',
sourceCode: tool?.source_code || '',
Expand Down Expand Up @@ -248,7 +250,7 @@ export function UserToolModal({
/>
</div>

{(tool || toolType.key === 'code') && (
{(tool || toolType.key === 'function') && (
<div className={classes.group}>
<TextInput
size="lg"
Expand All @@ -268,7 +270,7 @@ export function UserToolModal({
</div>
)}

{toolType.key === 'api-call' ? (
{toolType.key === 'api' ? (
<>
{/* TODO: make available for update too, when the API is ready */}
{!tool && <ApiAuthenticationMethod />}
Expand All @@ -295,7 +297,7 @@ export function UserToolModal({
required
invalid={errors.api?.schema != null}
rows={16}
className={classes.apiSchema}
className={classes.apiSchemaField}
/>
</>
)}
Expand Down Expand Up @@ -451,6 +453,9 @@ UserToolModal.View = function ViewUserToolModal({
tool: Tool;
} & ModalProps) {
const id = useId();

const type: ToolTypeKey = tool.open_api_schema ? 'api' : 'function';

return (
<Modal {...props} className={classes.modal}>
<ModalHeader>
Expand All @@ -462,24 +467,29 @@ UserToolModal.View = function ViewUserToolModal({
<dd>
<FormLabel>Type</FormLabel>
</dd>
<dt>Python function</dt>
<dt>{type === 'api' ? 'API calling' : 'Python function'}</dt>
</div>

<div>
<dd>
<FormLabel>Description</FormLabel>
</dd>
<dt>{tool.description}</dt>
<dt>
<ToolDescription description={tool.description} />
</dt>
</div>
</dl>

<EditableSyntaxHighlighter
id={`${id}:code`}
labelText="Python code"
value={tool.source_code ?? ''}
labelText={type === 'api' ? 'OpenAPI spec' : 'Python code'}
value={
(type === 'api' ? tool.open_api_schema : tool.source_code) ?? ''
}
required
readOnly
rows={16}
className={type === 'api' ? classes.apiSchemaField : undefined}
/>
</ModalBody>
</Modal>
Expand All @@ -490,7 +500,7 @@ function createSaveToolBody(
{ type, name, sourceCode, api }: FormValues,
tool?: Tool,
): ToolsCreateBody {
return type.key === 'code'
return type.key === 'function'
? {
name,
source_code: sourceCode ?? '',
Expand Down

0 comments on commit fc3c8f4

Please sign in to comment.