diff --git a/frontend/src/components/editor/output/JsonOutput.tsx b/frontend/src/components/editor/output/JsonOutput.tsx index 8368bbff56a..7eb5d624183 100644 --- a/frontend/src/components/editor/output/JsonOutput.tsx +++ b/frontend/src/components/editor/output/JsonOutput.tsx @@ -194,6 +194,7 @@ const LEAF_RENDERERS = { "video/": (value: string) => , "text/html:": (value: string) => , "text/plain+float:": (value: string) => {value}, + "text/plain+bigint:": (value: string) => {value}, "text/plain+set:": (value: string) => set{value}, "text/plain+tuple:": (value: string) => {value}, "text/plain:": (value: string) => , @@ -351,6 +352,9 @@ function pythonJsonReplacer(_key: string, value: unknown): unknown { if (typeof value === "object") { return value; } + if (typeof value === "bigint") { + return `${REPLACE_PREFIX}${value}${REPLACE_SUFFIX}`; + } if (Array.isArray(value)) { return value; } @@ -359,6 +363,11 @@ function pythonJsonReplacer(_key: string, value: unknown): unknown { if (value.startsWith("text/plain+float:")) { return `${REPLACE_PREFIX}${leafData(value)}${REPLACE_SUFFIX}`; } + if (value.startsWith("text/plain+bigint:")) { + // Use BigInt to avoid precision loss + const number = BigInt(leafData(value)); + return `${REPLACE_PREFIX}${number}${REPLACE_SUFFIX}`; + } if (value.startsWith("text/plain+tuple:")) { // replace first and last characters [] with () return `${REPLACE_PREFIX}(${leafData(value).slice(1, -1)})${REPLACE_SUFFIX}`; diff --git a/frontend/src/components/editor/output/__tests__/json-output.test.ts b/frontend/src/components/editor/output/__tests__/json-output.test.ts index 2ff76ba4943..d76a6e2afd8 100644 --- a/frontend/src/components/editor/output/__tests__/json-output.test.ts +++ b/frontend/src/components/editor/output/__tests__/json-output.test.ts @@ -218,6 +218,49 @@ describe("getCopyValue", () => { `, ); }); + + it("should handle bigint", () => { + const bigint = String(BigInt(2 ** 64)); + const value = `text/plain+bigint:${bigint}`; + const result = getCopyValue(value); + expect(result).toMatchInlineSnapshot(`"18446744073709551616"`); + + const nestedBigInt = { + key1: bigint, // this will be just a string + key2: `text/plain+bigint:${bigint}`, // this will convert to number + key3: true, + }; + const nestedResult = getCopyValue(nestedBigInt); + expect(nestedResult).toMatchInlineSnapshot( + ` + "{ + "key1": "18446744073709551616", + "key2": 18446744073709551616, + "key3": True + }" + `, + ); + + const bigintRaw = BigInt(2 ** 64); + const bigintRawResult = getCopyValue(bigintRaw); + expect(bigintRawResult).toMatchInlineSnapshot(`"18446744073709551616"`); + + const nestedBigIntRaw = { + key1: bigintRaw, // raw number + key2: `text/plain+bigint:${bigintRaw}`, + key3: true, + }; + const nestedBigIntRawResult = getCopyValue(nestedBigIntRaw); + expect(nestedBigIntRawResult).toMatchInlineSnapshot( + ` + "{ + "key1": 18446744073709551616, + "key2": 18446744073709551616, + "key3": True + }" + `, + ); + }); }); describe("determineMaxDisplayLength", () => { diff --git a/frontend/src/components/editor/package-alert.tsx b/frontend/src/components/editor/package-alert.tsx index bf681563dc7..1a904df1b91 100644 --- a/frontend/src/components/editor/package-alert.tsx +++ b/frontend/src/components/editor/package-alert.tsx @@ -463,6 +463,7 @@ const ExtrasSelector: React.FC = ({ @@ -523,6 +524,7 @@ const ExtrasSelector: React.FC = ({ !canSelectExtras && "opacity-50 cursor-not-allowed", )} title={canSelectExtras ? "Add extras" : "Loading extras..."} + type="button" > @@ -619,6 +621,7 @@ const StreamingLogsViewer: React.FC = ({