diff --git a/CHANGELOG.md b/CHANGELOG.md index dd28b2162..8c71de290 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - fix: omit parallel_tool_calls in Go OpenAI SDK if it is set to true [#849](https://github.com/hypermodeinc/modus/pull/849) - feat: use embedded postgres on Windows [#851](https://github.com/hypermodeinc/modus/pull/851) +- feat: add functions for parsing chat messages [#853](https://github.com/hypermodeinc/modus/pull/853) ## 2025-05-19 - Go SDK 0.18.0-alpha.2 diff --git a/sdk/assemblyscript/examples/agents/package-lock.json b/sdk/assemblyscript/examples/agents/package-lock.json index d6b0781eb..23677ae91 100644 --- a/sdk/assemblyscript/examples/agents/package-lock.json +++ b/sdk/assemblyscript/examples/agents/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/agents/package.json b/sdk/assemblyscript/examples/agents/package.json index 9b6795fe5..5d373e0f2 100644 --- a/sdk/assemblyscript/examples/agents/package.json +++ b/sdk/assemblyscript/examples/agents/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/anthropic-functions/package-lock.json b/sdk/assemblyscript/examples/anthropic-functions/package-lock.json index 485d03628..7666d77b1 100644 --- a/sdk/assemblyscript/examples/anthropic-functions/package-lock.json +++ b/sdk/assemblyscript/examples/anthropic-functions/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/anthropic-functions/package.json b/sdk/assemblyscript/examples/anthropic-functions/package.json index 2444a344b..0e457d6d6 100644 --- a/sdk/assemblyscript/examples/anthropic-functions/package.json +++ b/sdk/assemblyscript/examples/anthropic-functions/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/auth/package-lock.json b/sdk/assemblyscript/examples/auth/package-lock.json index 62a7b71ad..1a04dab83 100644 --- a/sdk/assemblyscript/examples/auth/package-lock.json +++ b/sdk/assemblyscript/examples/auth/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/auth/package.json b/sdk/assemblyscript/examples/auth/package.json index 1413df5a2..fb4fb8d1e 100644 --- a/sdk/assemblyscript/examples/auth/package.json +++ b/sdk/assemblyscript/examples/auth/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/classification/package-lock.json b/sdk/assemblyscript/examples/classification/package-lock.json index a6c89582d..4537b7f4b 100644 --- a/sdk/assemblyscript/examples/classification/package-lock.json +++ b/sdk/assemblyscript/examples/classification/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/classification/package.json b/sdk/assemblyscript/examples/classification/package.json index 8fc4c87b6..aff4d1465 100644 --- a/sdk/assemblyscript/examples/classification/package.json +++ b/sdk/assemblyscript/examples/classification/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/collections/package-lock.json b/sdk/assemblyscript/examples/collections/package-lock.json index 2701267ea..7d281e034 100644 --- a/sdk/assemblyscript/examples/collections/package-lock.json +++ b/sdk/assemblyscript/examples/collections/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/collections/package.json b/sdk/assemblyscript/examples/collections/package.json index b6375d42b..41d0dd970 100644 --- a/sdk/assemblyscript/examples/collections/package.json +++ b/sdk/assemblyscript/examples/collections/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/dgraph/package-lock.json b/sdk/assemblyscript/examples/dgraph/package-lock.json index 10d28da11..282c6d862 100644 --- a/sdk/assemblyscript/examples/dgraph/package-lock.json +++ b/sdk/assemblyscript/examples/dgraph/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/dgraph/package.json b/sdk/assemblyscript/examples/dgraph/package.json index 5d64f151a..d6cad11cb 100644 --- a/sdk/assemblyscript/examples/dgraph/package.json +++ b/sdk/assemblyscript/examples/dgraph/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/embedding/package-lock.json b/sdk/assemblyscript/examples/embedding/package-lock.json index 2c96102b4..efd63ee88 100644 --- a/sdk/assemblyscript/examples/embedding/package-lock.json +++ b/sdk/assemblyscript/examples/embedding/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/embedding/package.json b/sdk/assemblyscript/examples/embedding/package.json index 4f072e1bb..4b645b5ab 100644 --- a/sdk/assemblyscript/examples/embedding/package.json +++ b/sdk/assemblyscript/examples/embedding/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/graphql/package-lock.json b/sdk/assemblyscript/examples/graphql/package-lock.json index 7f49fe1ed..feeb21c6b 100644 --- a/sdk/assemblyscript/examples/graphql/package-lock.json +++ b/sdk/assemblyscript/examples/graphql/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/graphql/package.json b/sdk/assemblyscript/examples/graphql/package.json index 3056405b3..746441386 100644 --- a/sdk/assemblyscript/examples/graphql/package.json +++ b/sdk/assemblyscript/examples/graphql/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/http/package-lock.json b/sdk/assemblyscript/examples/http/package-lock.json index 23ed314d3..7be9ad653 100644 --- a/sdk/assemblyscript/examples/http/package-lock.json +++ b/sdk/assemblyscript/examples/http/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/http/package.json b/sdk/assemblyscript/examples/http/package.json index 02800a7a3..c9181e017 100644 --- a/sdk/assemblyscript/examples/http/package.json +++ b/sdk/assemblyscript/examples/http/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/mysql/package-lock.json b/sdk/assemblyscript/examples/mysql/package-lock.json index 638c876b1..95b51713b 100644 --- a/sdk/assemblyscript/examples/mysql/package-lock.json +++ b/sdk/assemblyscript/examples/mysql/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/mysql/package.json b/sdk/assemblyscript/examples/mysql/package.json index d0696265e..d66cc02d4 100644 --- a/sdk/assemblyscript/examples/mysql/package.json +++ b/sdk/assemblyscript/examples/mysql/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/neo4j/package-lock.json b/sdk/assemblyscript/examples/neo4j/package-lock.json index 5967c2cee..1bf0ec240 100644 --- a/sdk/assemblyscript/examples/neo4j/package-lock.json +++ b/sdk/assemblyscript/examples/neo4j/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/neo4j/package.json b/sdk/assemblyscript/examples/neo4j/package.json index d48374f47..afbb65b32 100644 --- a/sdk/assemblyscript/examples/neo4j/package.json +++ b/sdk/assemblyscript/examples/neo4j/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/postgresql/package-lock.json b/sdk/assemblyscript/examples/postgresql/package-lock.json index 31e5bf307..65a7d22f1 100644 --- a/sdk/assemblyscript/examples/postgresql/package-lock.json +++ b/sdk/assemblyscript/examples/postgresql/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/postgresql/package.json b/sdk/assemblyscript/examples/postgresql/package.json index 03c569504..8b7cea5b4 100644 --- a/sdk/assemblyscript/examples/postgresql/package.json +++ b/sdk/assemblyscript/examples/postgresql/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/simple/package-lock.json b/sdk/assemblyscript/examples/simple/package-lock.json index 134d3641f..3a6b7e14f 100644 --- a/sdk/assemblyscript/examples/simple/package-lock.json +++ b/sdk/assemblyscript/examples/simple/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/simple/package.json b/sdk/assemblyscript/examples/simple/package.json index ec7b558fb..5874a41a4 100644 --- a/sdk/assemblyscript/examples/simple/package.json +++ b/sdk/assemblyscript/examples/simple/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/textgeneration/package-lock.json b/sdk/assemblyscript/examples/textgeneration/package-lock.json index 49d814e22..60d0fa563 100644 --- a/sdk/assemblyscript/examples/textgeneration/package-lock.json +++ b/sdk/assemblyscript/examples/textgeneration/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/textgeneration/package.json b/sdk/assemblyscript/examples/textgeneration/package.json index 28379d805..172db180d 100644 --- a/sdk/assemblyscript/examples/textgeneration/package.json +++ b/sdk/assemblyscript/examples/textgeneration/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/time/package-lock.json b/sdk/assemblyscript/examples/time/package-lock.json index 132e1df61..273bc94c2 100644 --- a/sdk/assemblyscript/examples/time/package-lock.json +++ b/sdk/assemblyscript/examples/time/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/time/package.json b/sdk/assemblyscript/examples/time/package.json index 809102771..447ed3d78 100644 --- a/sdk/assemblyscript/examples/time/package.json +++ b/sdk/assemblyscript/examples/time/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/examples/vectors/package-lock.json b/sdk/assemblyscript/examples/vectors/package-lock.json index aa6bcdc44..8bd850099 100644 --- a/sdk/assemblyscript/examples/vectors/package-lock.json +++ b/sdk/assemblyscript/examples/vectors/package-lock.json @@ -8,7 +8,7 @@ "license": "Apache-2.0", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -27,7 +27,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -36,7 +36,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1190,9 +1190,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/examples/vectors/package.json b/sdk/assemblyscript/examples/vectors/package.json index 36dbdf21e..75cf4faf8 100644 --- a/sdk/assemblyscript/examples/vectors/package.json +++ b/sdk/assemblyscript/examples/vectors/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/assemblyscript/src/assembly/__tests__/openai.spec.ts b/sdk/assemblyscript/src/assembly/__tests__/openai.spec.ts new file mode 100644 index 000000000..fc21aae7e --- /dev/null +++ b/sdk/assemblyscript/src/assembly/__tests__/openai.spec.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2025 Hypermode Inc. + * Licensed under the terms of the Apache License, Version 2.0 + * See the LICENSE file that accompanied this code for further details. + * + * SPDX-FileCopyrightText: 2025 Hypermode Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { expect, it, run } from "as-test"; +import { JSON } from "json-as"; + +import { + SystemMessage, + UserMessage, + AssistantMessage, + RequestMessage, + parseMessages, +} from "../../models/openai/chat"; + +it("should round-trip chat messages", () => { + const msgs: RequestMessage[] = [ + new SystemMessage("You are a helpful assistant."), + new UserMessage("What is the capital of France?"), + new AssistantMessage("The capital of France is Paris."), + ]; + + const data = JSON.stringify(msgs); + const parsedMsgs = parseMessages(data); + + expect(parsedMsgs.length).toBe(msgs.length); + for (let i = 0; i < msgs.length; i++) { + expect(msgs[i].role).toBe(parsedMsgs[i].role); + } + + const roundTrip = JSON.stringify(parsedMsgs); + expect(roundTrip).toBe(data); +}); + +run(); diff --git a/sdk/assemblyscript/src/models/openai/chat.ts b/sdk/assemblyscript/src/models/openai/chat.ts index 6ae1ec6bc..a6882577b 100644 --- a/sdk/assemblyscript/src/models/openai/chat.ts +++ b/sdk/assemblyscript/src/models/openai/chat.ts @@ -262,6 +262,7 @@ export class OpenAIChatInput { /** * An object specifying which tool the model should call. */ +@json export class ToolChoice { /** * Constructs a new tool choice object. @@ -1352,6 +1353,7 @@ export class AssistantMessage extends RequestMessage { /** * Data about a previous audio response from the model. */ + @omitnull() audio: AudioRef | null = null; /** @@ -1538,3 +1540,59 @@ export class AudioOutput { */ transcript!: string; } + +/** + * Represents a a raw message object, which is used when reconstructing messages from JSON. + * A raw message will round-trip all the JSON data, but does not expose the fields directly. + * (note, this type is not exported) + */ +@json +class RawMessage extends RequestMessage { + constructor(data: string) { + const obj = JSON.parse(data); + if (!obj.has("role")) { + throw new Error("Missing role field in message JSON."); + } + + const role = obj.get("role")!.get(); + super(role); + + this._data = data; + } + + private _data: string; + + // HACK: this is a workaround for https://github.com/JairusSW/json-as/issues/132 + // TODO: unwind hack when issue is resolved + // eslint-disable-next-line @typescript-eslint/no-unused-vars + __SERIALIZE(ptr: usize): void { + const data = this.serialize(this); + const dataSize = data.length << 1; + // @ts-expect-error: bs is defined during the json-as-transform + memory.copy(bs.offset, changetype(data), dataSize); + // @ts-expect-error: bs is defined during the json-as-transform + bs.offset += dataSize; + } + + // @serializer + serialize(self: RawMessage): string { + return self._data; + } + + + @deserializer + deserialize(data: string): RawMessage { + return new RawMessage(data); + } +} + +/** + * Parses a JSON-encoded request message into a list of RequestMessage objects. + * The resulting message objects are suitable for restoring a previous chat conversation. + * However, the original message types are not preserved. + */ +export function parseMessages(data: string): RequestMessage[] { + return JSON.parse(data).map( + (msg) => new RawMessage(msg.toString()), + ); +} diff --git a/sdk/assemblyscript/src/package-lock.json b/sdk/assemblyscript/src/package-lock.json index 363bd6f7b..dd76ac8d3 100644 --- a/sdk/assemblyscript/src/package-lock.json +++ b/sdk/assemblyscript/src/package-lock.json @@ -10,7 +10,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -19,7 +19,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -320,9 +320,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.15.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.18.tgz", - "integrity": "sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg==", + "version": "22.15.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", + "integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1425,9 +1425,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/src/package.json b/sdk/assemblyscript/src/package.json index 2d439681f..33da7f926 100644 --- a/sdk/assemblyscript/src/package.json +++ b/sdk/assemblyscript/src/package.json @@ -23,13 +23,13 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", diff --git a/sdk/assemblyscript/src/tests/openai.run.ts b/sdk/assemblyscript/src/tests/openai.run.ts new file mode 100644 index 000000000..2acc450e4 --- /dev/null +++ b/sdk/assemblyscript/src/tests/openai.run.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2025 Hypermode Inc. + * Licensed under the terms of the Apache License, Version 2.0 + * See the LICENSE file that accompanied this code for further details. + * + * SPDX-FileCopyrightText: 2025 Hypermode Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { readFileSync } from "fs"; +import { instantiate } from "../build/openai.spec.js"; +const binary = readFileSync("./build/openai.spec.wasm"); +const module = new WebAssembly.Module(binary); +instantiate(module, { + env: {}, + modus_models: {}, +}); diff --git a/sdk/assemblyscript/templates/default/package-lock.json b/sdk/assemblyscript/templates/default/package-lock.json index b8a894b4c..572192fe7 100644 --- a/sdk/assemblyscript/templates/default/package-lock.json +++ b/sdk/assemblyscript/templates/default/package-lock.json @@ -7,7 +7,7 @@ "name": "my-modus-app", "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", @@ -26,7 +26,7 @@ "@assemblyscript/wasi-shim": "^0.1.0", "as-base64": "^0.2.0", "chalk": "^5.4.1", - "json-as": "^1.0.7", + "json-as": "^1.0.8", "semver": "^7.7.2", "xid-ts": "^1.1.4" }, @@ -35,7 +35,7 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", - "@types/node": "^22.15.18", + "@types/node": "^22.15.21", "as-test": "^0.4.1", "assemblyscript": "^0.27.36", "assemblyscript-prettier": "^3.0.1", @@ -1189,9 +1189,9 @@ } }, "node_modules/json-as": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.7.tgz", - "integrity": "sha512-+SOoMPj+HOB7RR7KO8gDKOPFlUyp4ltOHcJRrSLHLZmvhhw9330kSrTEycIppCX+tHhbqDu8slX32c4T4mq6Ng==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-1.0.8.tgz", + "integrity": "sha512-x4lTtNArVM9zP2csa+Rhjae33cnosr1HJpn4UTudtGTBzvvbxsXoi2Kwy50eC5kEQD+bCrgt/Bbl1BzLxUHO7A==", "license": "MIT" }, "node_modules/json-buffer": { diff --git a/sdk/assemblyscript/templates/default/package.json b/sdk/assemblyscript/templates/default/package.json index c1a992314..b28dec519 100644 --- a/sdk/assemblyscript/templates/default/package.json +++ b/sdk/assemblyscript/templates/default/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@hypermode/modus-sdk-as": "../../src", - "json-as": "^1.0.7" + "json-as": "^1.0.8" }, "devDependencies": { "@eslint/js": "^9.27.0", diff --git a/sdk/go/pkg/models/openai/chat.go b/sdk/go/pkg/models/openai/chat.go index f4de8c9d4..6289fa618 100644 --- a/sdk/go/pkg/models/openai/chat.go +++ b/sdk/go/pkg/models/openai/chat.go @@ -1234,3 +1234,49 @@ func (mi *ChatModelInput) MarshalJSON() ([]byte, error) { return b, nil } + +// Represents a a raw message object, which is used when reconstructing messages from JSON. +// A raw message will round-trip all the JSON data, but does not expose the fields directly. +// (note, this type is not exported) +type rawMessage struct { + role string + data json.RawMessage +} + +func (m *rawMessage) Role() string { + return m.role +} + +func (m *rawMessage) MarshalJSON() ([]byte, error) { + if len(m.data) == 0 { + return nil, fmt.Errorf("missing data in message") + } + return m.data, nil +} + +func (m *rawMessage) UnmarshalJSON(data []byte) error { + r := gjson.GetBytes(data, "role") + if !r.Exists() { + return fmt.Errorf("missing role field in message JSON") + } + m.role = r.String() + m.data = data + return nil +} + +// Parses a JSON-encoded request message into a list of RequestMessage objects. +// The resulting message objects are suitable for restoring a previous chat conversation. +// However, the original message types are not preserved. +func ParseMessages(data []byte) ([]RequestMessage, error) { + var messages []rawMessage + if err := json.Unmarshal([]byte(data), &messages); err != nil { + return nil, err + } + + results := make([]RequestMessage, len(messages)) + for i := range messages { + results[i] = &messages[i] + } + + return results, nil +} diff --git a/sdk/go/pkg/models/openai/chat_test.go b/sdk/go/pkg/models/openai/chat_test.go new file mode 100644 index 000000000..66b0cd792 --- /dev/null +++ b/sdk/go/pkg/models/openai/chat_test.go @@ -0,0 +1,53 @@ +/* + * Copyright 2025 Hypermode Inc. + * Licensed under the terms of the Apache License, Version 2.0 + * See the LICENSE file that accompanied this code for further details. + * + * SPDX-FileCopyrightText: 2025 Hypermode Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +package openai_test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/hypermodeinc/modus/sdk/go/pkg/models/openai" +) + +func TestMessagesRoundTrip(t *testing.T) { + msgs := []openai.RequestMessage{ + openai.NewSystemMessage("You are a helpful assistant."), + openai.NewUserMessage("What is the capital of France?"), + openai.NewAssistantMessage("The capital of France is Paris."), + } + + data, err := json.Marshal(msgs) + if err != nil { + t.Fatalf("Failed to marshal messages: %v", err) + } + + parsedMsgs, err := openai.ParseMessages(data) + if err != nil { + t.Fatalf("Failed to parse messages: %v", err) + } + if len(parsedMsgs) != len(msgs) { + t.Fatalf("Expected %d messages, but got %d", len(msgs), len(parsedMsgs)) + } + + for i, msg := range msgs { + if msg.Role() != parsedMsgs[i].Role() { + t.Errorf("Expected role %s for message %d, but got %s", msg.Role(), i, parsedMsgs[i].Role()) + } + } + + roundTrip, err := json.Marshal(parsedMsgs) + if err != nil { + t.Fatalf("Failed to marshal parsed messages: %v", err) + } + if !bytes.Equal(data, roundTrip) { + t.Fatalf("Expected original and parsed messages to have the same JSON representation, but they differ") + } +}