Add inline python extension (#3107)
Co-authored-by: Douwe Osinga <douwe@squareup.com> Co-authored-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
@@ -217,6 +217,28 @@ export type ExtensionConfig = {
|
||||
*/
|
||||
tools: Array<Tool>;
|
||||
type: 'frontend';
|
||||
} | {
|
||||
/**
|
||||
* The Python code to execute
|
||||
*/
|
||||
code: string;
|
||||
/**
|
||||
* Python package dependencies required by this extension
|
||||
*/
|
||||
dependencies?: Array<string> | null;
|
||||
/**
|
||||
* Description of what the extension does
|
||||
*/
|
||||
description?: string | null;
|
||||
/**
|
||||
* The name used to identify this extension
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Timeout in seconds
|
||||
*/
|
||||
timeout?: number | null;
|
||||
type: 'inline_python';
|
||||
};
|
||||
|
||||
export type ExtensionEntry = ExtensionConfig & {
|
||||
|
||||
@@ -55,8 +55,8 @@ export default function ExtensionsSection({
|
||||
if (a.type !== 'builtin' && b.type === 'builtin') return 1;
|
||||
|
||||
// Then sort by bundled (handle null/undefined cases)
|
||||
const aBundled = a.bundled === true;
|
||||
const bBundled = b.bundled === true;
|
||||
const aBundled = 'bundled' in a && a.bundled === true;
|
||||
const bBundled = 'bundled' in b && b.bundled === true;
|
||||
if (aBundled && !bBundled) return -1;
|
||||
if (!aBundled && bBundled) return 1;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ export async function syncBundledExtensions(
|
||||
const existingExt = existingExtensions.find((ext) => nameToKey(ext.name) === bundledExt.id);
|
||||
|
||||
// Skip if extension exists and is already marked as bundled
|
||||
if (existingExt?.bundled) continue;
|
||||
if (existingExt && 'bundled' in existingExt && existingExt.bundled) continue;
|
||||
|
||||
// Create the config for this extension
|
||||
let extConfig: ExtensionConfig;
|
||||
|
||||
@@ -68,7 +68,8 @@ export default function ExtensionItem({
|
||||
// Over time we can take the first part of the conditional away as people have bundled: true in their config.yaml entries
|
||||
|
||||
// allow configuration editing if extension is not a builtin/bundled extension AND isStatic = false
|
||||
const editable = !(extension.type === 'builtin' || extension.bundled) && !isStatic;
|
||||
const editable =
|
||||
!(extension.type === 'builtin' || ('bundled' in extension && extension.bundled)) && !isStatic;
|
||||
|
||||
return (
|
||||
<Card
|
||||
|
||||
@@ -45,7 +45,12 @@ export function getFriendlyTitle(extension: FixedExtensionEntry): string {
|
||||
let name = '';
|
||||
|
||||
// if it's a builtin, check if there's a display_name (old configs didn't have this field)
|
||||
if (extension.bundled === true && 'display_name' in extension && extension.display_name) {
|
||||
if (
|
||||
'bundled' in extension &&
|
||||
extension.bundled === true &&
|
||||
'display_name' in extension &&
|
||||
extension.display_name
|
||||
) {
|
||||
// If we have a display_name for a builtin, use it directly
|
||||
return extension.display_name;
|
||||
} else {
|
||||
|
||||
@@ -100,7 +100,10 @@ export function extensionToFormData(extension: FixedExtensionEntry): ExtensionFo
|
||||
extension.type === 'stdio' || extension.type === 'sse' || extension.type === 'streamable_http'
|
||||
? extension.description || ''
|
||||
: '',
|
||||
type: extension.type === 'frontend' ? 'stdio' : extension.type,
|
||||
type:
|
||||
extension.type === 'frontend' || extension.type === 'inline_python'
|
||||
? 'stdio'
|
||||
: extension.type,
|
||||
cmd: extension.type === 'stdio' ? combineCmdAndArgs(extension.cmd, extension.args) : undefined,
|
||||
endpoint:
|
||||
extension.type === 'sse' || extension.type === 'streamable_http' ? extension.uri : undefined,
|
||||
|
||||
@@ -66,8 +66,8 @@ export default function PermissionRulesModal({ isOpen, onClose }: PermissionRule
|
||||
if (a.type !== 'builtin' && b.type === 'builtin') return 1;
|
||||
|
||||
// Then sort by bundled (handle null/undefined cases)
|
||||
const aBundled = a.bundled === true;
|
||||
const bBundled = b.bundled === true;
|
||||
const aBundled = 'bundled' in a && a.bundled === true;
|
||||
const bBundled = 'bundled' in b && b.bundled === true;
|
||||
if (aBundled && !bBundled) return -1;
|
||||
if (!aBundled && bBundled) return 1;
|
||||
|
||||
|
||||
@@ -62,8 +62,8 @@ export default function PermissionSettingsView({ onClose }: { onClose: () => voi
|
||||
if (a.type !== 'builtin' && b.type === 'builtin') return 1;
|
||||
|
||||
// Then sort by bundled (handle null/undefined cases)
|
||||
const aBundled = a.bundled === true;
|
||||
const bBundled = b.bundled === true;
|
||||
const aBundled = 'bundled' in a && a.bundled === true;
|
||||
const bBundled = 'bundled' in b && b.bundled === true;
|
||||
if (aBundled && !bBundled) return -1;
|
||||
if (!aBundled && bBundled) return 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user