From 07577fc94b129dbc1935fd77df369bc1cdafb8c4 Mon Sep 17 00:00:00 2001
From: kshern
Date: Mon, 24 Feb 2025 02:36:52 +0800
Subject: [PATCH 1/3] feat:toolsbar add array support
---
client/src/components/DynamicJsonForm.tsx | 55 ++++++++++++++++-------
client/src/components/ToolsTab.tsx | 14 +++---
2 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/client/src/components/DynamicJsonForm.tsx b/client/src/components/DynamicJsonForm.tsx
index ff26118..e760a13 100644
--- a/client/src/components/DynamicJsonForm.tsx
+++ b/client/src/components/DynamicJsonForm.tsx
@@ -215,23 +215,48 @@ const DynamicJsonForm = ({
return;
}
- const newValue = {
- ...(typeof value === "object" && value !== null && !Array.isArray(value)
- ? value
- : {}),
- } as JsonObject;
- let current: JsonObject = newValue;
-
- for (let i = 0; i < path.length - 1; i++) {
- const key = path[i];
- if (!(key in current)) {
- current[key] = {};
+ const updateArray = (array: JsonValue[], path: string[], value: JsonValue): JsonValue[] => {
+ const [index, ...restPath] = path;
+ const arrayIndex = Number(index);
+ const newArray = [...array];
+
+ if (restPath.length === 0) {
+ newArray[arrayIndex] = value;
+ } else {
+ newArray[arrayIndex] = updateValue(newArray[arrayIndex], restPath, value);
}
- current = current[key] as JsonObject;
- }
+ return newArray;
+ };
- current[path[path.length - 1]] = fieldValue;
- onChange(newValue);
+ const updateObject = (obj: JsonObject, path: string[], value: JsonValue): JsonObject => {
+ const [key, ...restPath] = path;
+ const newObj = { ...obj };
+
+ if (restPath.length === 0) {
+ newObj[key] = value;
+ } else {
+ newObj[key] = updateValue(newObj[key], restPath, value);
+ }
+ return newObj;
+ };
+
+ const updateValue = (current: JsonValue, path: string[], value: JsonValue): JsonValue => {
+ if (path.length === 0) return value;
+
+ if (!current) {
+ current = !isNaN(Number(path[0])) ? [] : {};
+ }
+
+ if (Array.isArray(current)) {
+ return updateArray(current, path, value);
+ } else if (typeof current === 'object' && current !== null) {
+ return updateObject(current, path, value);
+ }
+
+ return current;
+ };
+
+ onChange(updateValue(value, path, fieldValue));
};
return (
diff --git a/client/src/components/ToolsTab.tsx b/client/src/components/ToolsTab.tsx
index 418e58e..23be41a 100644
--- a/client/src/components/ToolsTab.tsx
+++ b/client/src/components/ToolsTab.tsx
@@ -17,11 +17,6 @@ import ListPane from "./ListPane";
import { CompatibilityCallToolResult } from "@modelcontextprotocol/sdk/types.js";
-type SchemaProperty = {
- type: string;
- description?: string;
- properties?: Record;
-};
const ToolsTab = ({
tools,
@@ -168,7 +163,7 @@ const ToolsTab = ({
{Object.entries(selectedTool.inputSchema.properties ?? []).map(
([key, value]) => {
- const prop = value as SchemaProperty;
+ const prop = value as JsonSchemaType;
return (
- ) : prop.type === "object" ? (
+ ) : prop.type === "object"|| prop.type === "array" ? (
{
From 18438dbdd0219d225d04337535094093d3f30d7c Mon Sep 17 00:00:00 2001
From: kshern
Date: Mon, 24 Feb 2025 02:52:17 +0800
Subject: [PATCH 2/3] feat: add error handling
---
client/src/components/DynamicJsonForm.tsx | 65 +++++++++++++++++++----
1 file changed, 55 insertions(+), 10 deletions(-)
diff --git a/client/src/components/DynamicJsonForm.tsx b/client/src/components/DynamicJsonForm.tsx
index e760a13..75bdc6a 100644
--- a/client/src/components/DynamicJsonForm.tsx
+++ b/client/src/components/DynamicJsonForm.tsx
@@ -218,11 +218,30 @@ const DynamicJsonForm = ({
const updateArray = (array: JsonValue[], path: string[], value: JsonValue): JsonValue[] => {
const [index, ...restPath] = path;
const arrayIndex = Number(index);
+
+ // Validate array index
+ if (isNaN(arrayIndex)) {
+ console.error(`Invalid array index: ${index}`);
+ return array;
+ }
+
+ // Check array bounds
+ if (arrayIndex < 0) {
+ console.error(`Array index out of bounds: ${arrayIndex} < 0`);
+ return array;
+ }
+
const newArray = [...array];
if (restPath.length === 0) {
newArray[arrayIndex] = value;
} else {
+ // Ensure index position exists
+ if (arrayIndex >= array.length) {
+ console.warn(`Extending array to index ${arrayIndex}`);
+ newArray.length = arrayIndex + 1;
+ newArray.fill(null, array.length, arrayIndex);
+ }
newArray[arrayIndex] = updateValue(newArray[arrayIndex], restPath, value);
}
return newArray;
@@ -230,11 +249,23 @@ const DynamicJsonForm = ({
const updateObject = (obj: JsonObject, path: string[], value: JsonValue): JsonObject => {
const [key, ...restPath] = path;
+
+ // Validate object key
+ if (typeof key !== 'string') {
+ console.error(`Invalid object key: ${key}`);
+ return obj;
+ }
+
const newObj = { ...obj };
if (restPath.length === 0) {
newObj[key] = value;
} else {
+ // Ensure key exists
+ if (!(key in newObj)) {
+ console.warn(`Creating new key in object: ${key}`);
+ newObj[key] = {};
+ }
newObj[key] = updateValue(newObj[key], restPath, value);
}
return newObj;
@@ -243,20 +274,34 @@ const DynamicJsonForm = ({
const updateValue = (current: JsonValue, path: string[], value: JsonValue): JsonValue => {
if (path.length === 0) return value;
- if (!current) {
- current = !isNaN(Number(path[0])) ? [] : {};
- }
+ try {
+ if (!current) {
+ current = !isNaN(Number(path[0])) ? [] : {};
+ }
- if (Array.isArray(current)) {
- return updateArray(current, path, value);
- } else if (typeof current === 'object' && current !== null) {
- return updateObject(current, path, value);
+ // Type checking
+ if (Array.isArray(current)) {
+ return updateArray(current, path, value);
+ } else if (typeof current === 'object' && current !== null) {
+ return updateObject(current, path, value);
+ } else {
+ console.error(`Cannot update path ${path.join('.')} in non-object/array value:`, current);
+ return current;
+ }
+ } catch (error) {
+ console.error(`Error updating value at path ${path.join('.')}:`, error);
+ return current;
}
-
- return current;
};
- onChange(updateValue(value, path, fieldValue));
+ try {
+ const newValue = updateValue(value, path, fieldValue);
+ onChange(newValue);
+ } catch (error) {
+ console.error('Failed to update form value:', error);
+ // Keep the original value unchanged
+ onChange(value);
+ }
};
return (
From 8267e514ce2b22cc4f2202631300abfd495ba74c Mon Sep 17 00:00:00 2001
From: kshern
Date: Tue, 25 Feb 2025 00:09:04 +0800
Subject: [PATCH 3/3] fix: prettier write
---
client/src/components/DynamicJsonForm.tsx | 43 ++++++++++++++++-------
client/src/components/ToolsTab.tsx | 17 ++++-----
2 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/client/src/components/DynamicJsonForm.tsx b/client/src/components/DynamicJsonForm.tsx
index 75bdc6a..a15b57e 100644
--- a/client/src/components/DynamicJsonForm.tsx
+++ b/client/src/components/DynamicJsonForm.tsx
@@ -215,7 +215,11 @@ const DynamicJsonForm = ({
return;
}
- const updateArray = (array: JsonValue[], path: string[], value: JsonValue): JsonValue[] => {
+ const updateArray = (
+ array: JsonValue[],
+ path: string[],
+ value: JsonValue,
+ ): JsonValue[] => {
const [index, ...restPath] = path;
const arrayIndex = Number(index);
@@ -232,7 +236,7 @@ const DynamicJsonForm = ({
}
const newArray = [...array];
-
+
if (restPath.length === 0) {
newArray[arrayIndex] = value;
} else {
@@ -242,22 +246,30 @@ const DynamicJsonForm = ({
newArray.length = arrayIndex + 1;
newArray.fill(null, array.length, arrayIndex);
}
- newArray[arrayIndex] = updateValue(newArray[arrayIndex], restPath, value);
+ newArray[arrayIndex] = updateValue(
+ newArray[arrayIndex],
+ restPath,
+ value,
+ );
}
return newArray;
};
- const updateObject = (obj: JsonObject, path: string[], value: JsonValue): JsonObject => {
+ const updateObject = (
+ obj: JsonObject,
+ path: string[],
+ value: JsonValue,
+ ): JsonObject => {
const [key, ...restPath] = path;
-
+
// Validate object key
- if (typeof key !== 'string') {
+ if (typeof key !== "string") {
console.error(`Invalid object key: ${key}`);
return obj;
}
const newObj = { ...obj };
-
+
if (restPath.length === 0) {
newObj[key] = value;
} else {
@@ -271,7 +283,11 @@ const DynamicJsonForm = ({
return newObj;
};
- const updateValue = (current: JsonValue, path: string[], value: JsonValue): JsonValue => {
+ const updateValue = (
+ current: JsonValue,
+ path: string[],
+ value: JsonValue,
+ ): JsonValue => {
if (path.length === 0) return value;
try {
@@ -282,14 +298,17 @@ const DynamicJsonForm = ({
// Type checking
if (Array.isArray(current)) {
return updateArray(current, path, value);
- } else if (typeof current === 'object' && current !== null) {
+ } else if (typeof current === "object" && current !== null) {
return updateObject(current, path, value);
} else {
- console.error(`Cannot update path ${path.join('.')} in non-object/array value:`, current);
+ console.error(
+ `Cannot update path ${path.join(".")} in non-object/array value:`,
+ current,
+ );
return current;
}
} catch (error) {
- console.error(`Error updating value at path ${path.join('.')}:`, error);
+ console.error(`Error updating value at path ${path.join(".")}:`, error);
return current;
}
};
@@ -298,7 +317,7 @@ const DynamicJsonForm = ({
const newValue = updateValue(value, path, fieldValue);
onChange(newValue);
} catch (error) {
- console.error('Failed to update form value:', error);
+ console.error("Failed to update form value:", error);
// Keep the original value unchanged
onChange(value);
}
diff --git a/client/src/components/ToolsTab.tsx b/client/src/components/ToolsTab.tsx
index 23be41a..777db80 100644
--- a/client/src/components/ToolsTab.tsx
+++ b/client/src/components/ToolsTab.tsx
@@ -17,7 +17,6 @@ import ListPane from "./ListPane";
import { CompatibilityCallToolResult } from "@modelcontextprotocol/sdk/types.js";
-
const ToolsTab = ({
tools,
listTools,
@@ -206,17 +205,15 @@ const ToolsTab = ({
}
className="mt-1"
/>
- ) : prop.type === "object"|| prop.type === "array" ? (
+ ) : prop.type === "object" || prop.type === "array" ? (
{
setParams({