@bolt-foundry/gambit 0.5.3-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitkeep +0 -0
- package/CHANGELOG.md +85 -0
- package/LICENSE +201 -0
- package/README.md +236 -0
- package/esm/_dnt.polyfills.d.ts +25 -0
- package/esm/_dnt.polyfills.d.ts.map +1 -0
- package/esm/_dnt.polyfills.js +1 -0
- package/esm/_dnt.shims.d.ts +6 -0
- package/esm/_dnt.shims.d.ts.map +1 -0
- package/esm/_dnt.shims.js +61 -0
- package/esm/deps/jsr.io/@std/internal/1.0.12/_os.d.ts +2 -0
- package/esm/deps/jsr.io/@std/internal/1.0.12/_os.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/internal/1.0.12/_os.js +12 -0
- package/esm/deps/jsr.io/@std/internal/1.0.12/os.d.ts +3 -0
- package/esm/deps/jsr.io/@std/internal/1.0.12/os.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/internal/1.0.12/os.js +5 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/assert_path.d.ts +2 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/assert_path.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/assert_path.js +7 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/basename.d.ts +4 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/basename.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/basename.js +40 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/common.d.ts +2 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/common.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/common.js +23 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/constants.d.ts +40 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/constants.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/constants.js +46 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/dirname.d.ts +2 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/dirname.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/dirname.js +8 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/format.d.ts +4 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/format.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/format.js +19 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/from_file_url.d.ts +2 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/from_file_url.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/from_file_url.js +9 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/glob_to_reg_exp.d.ts +35 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/glob_to_reg_exp.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/glob_to_reg_exp.js +235 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/normalize.d.ts +2 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/normalize.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/normalize.js +8 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/normalize_string.d.ts +2 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/normalize_string.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/normalize_string.js +77 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/relative.d.ts +2 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/relative.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/relative.js +9 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/strip_trailing_separators.d.ts +2 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/strip_trailing_separators.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/strip_trailing_separators.js +19 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/to_file_url.d.ts +2 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/to_file_url.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/_common/to_file_url.js +15 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/basename.d.ts +27 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/basename.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/basename.js +35 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/common.d.ts +28 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/common.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/common.js +33 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/constants.d.ts +15 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/constants.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/constants.js +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/dirname.d.ts +22 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/dirname.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/dirname.js +28 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/extname.d.ts +22 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/extname.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/extname.js +28 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/format.d.ts +22 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/format.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/format.js +27 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/from_file_url.d.ts +22 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/from_file_url.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/from_file_url.js +28 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/glob_to_regexp.d.ts +77 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/glob_to_regexp.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/glob_to_regexp.js +83 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/is_absolute.d.ts +22 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/is_absolute.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/is_absolute.js +28 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/is_glob.d.ts +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/is_glob.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/is_glob.js +42 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/join.d.ts +23 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/join.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/join.js +29 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/join_globs.d.ts +28 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/join_globs.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/join_globs.js +34 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/mod.d.ts +213 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/mod.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/mod.js +216 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/normalize.d.ts +26 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/normalize.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/normalize.js +32 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/normalize_glob.d.ts +29 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/normalize_glob.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/normalize_glob.js +35 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/parse.d.ts +35 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/parse.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/parse.js +39 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/_util.d.ts +2 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/_util.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/_util.js +8 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/basename.d.ts +39 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/basename.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/basename.js +52 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/constants.d.ts +13 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/constants.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/constants.js +14 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/dirname.d.ts +30 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/dirname.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/dirname.js +64 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/extname.d.ts +37 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/extname.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/extname.js +93 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/format.d.ts +24 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/format.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/format.js +28 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/from_file_url.d.ts +16 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/from_file_url.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/from_file_url.js +21 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/glob_to_regexp.d.ts +72 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/glob_to_regexp.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/glob_to_regexp.js +82 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/is_absolute.d.ts +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/is_absolute.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/is_absolute.js +23 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/join.d.ts +31 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/join.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/join.js +45 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/join_globs.d.ts +20 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/join_globs.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/join_globs.js +40 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/normalize.d.ts +37 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/normalize.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/normalize.js +58 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/normalize_glob.d.ts +20 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/normalize_glob.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/normalize_glob.js +32 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/parse.d.ts +25 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/parse.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/parse.js +115 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/relative.d.ts +20 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/relative.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/relative.js +106 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/resolve.d.ts +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/resolve.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/resolve.js +59 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/to_file_url.d.ts +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/to_file_url.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/to_file_url.js +27 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/to_namespaced_path.d.ts +16 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/to_namespaced_path.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/posix/to_namespaced_path.js +20 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/relative.d.ts +24 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/relative.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/relative.js +30 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/resolve.d.ts +22 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/resolve.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/resolve.js +30 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/to_file_url.d.ts +22 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/to_file_url.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/to_file_url.js +28 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/to_namespaced_path.d.ts +21 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/to_namespaced_path.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/to_namespaced_path.js +29 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/types.d.ts +38 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/types.js +3 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/_util.d.ts +4 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/_util.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/_util.js +15 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/basename.d.ts +22 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/basename.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/basename.js +47 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/constants.d.ts +13 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/constants.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/constants.js +14 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/dirname.d.ts +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/dirname.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/dirname.js +113 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/extname.d.ts +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/extname.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/extname.js +82 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/format.d.ts +24 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/format.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/format.js +28 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/from_file_url.d.ts +18 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/from_file_url.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/from_file_url.js +30 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/glob_to_regexp.d.ts +71 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/glob_to_regexp.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/glob_to_regexp.js +82 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/is_absolute.d.ts +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/is_absolute.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/is_absolute.js +38 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/join.d.ts +18 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/join.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/join.js +77 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/join_globs.d.ts +21 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/join_globs.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/join_globs.js +41 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/normalize.d.ts +19 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/normalize.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/normalize.js +135 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/normalize_glob.d.ts +20 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/normalize_glob.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/normalize_glob.js +32 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/parse.d.ts +25 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/parse.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/parse.js +176 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/relative.d.ts +23 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/relative.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/relative.js +131 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/resolve.d.ts +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/resolve.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/resolve.js +154 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/to_file_url.d.ts +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/to_file_url.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/to_file_url.js +34 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/to_namespaced_path.d.ts +17 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/to_namespaced_path.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/path/1.1.4/windows/to_namespaced_path.js +49 -0
- package/esm/gambit/mod.d.ts +10 -0
- package/esm/gambit/mod.d.ts.map +1 -0
- package/esm/gambit/mod.js +9 -0
- package/esm/gambit/src/durable_streams.d.ts +9 -0
- package/esm/gambit/src/durable_streams.d.ts.map +1 -0
- package/esm/gambit/src/durable_streams.js +132 -0
- package/esm/gambit/src/server.d.ts +16 -0
- package/esm/gambit/src/server.d.ts.map +1 -0
- package/esm/gambit/src/server.js +2288 -0
- package/esm/gambit/src/test_bot.d.ts +5 -0
- package/esm/gambit/src/test_bot.d.ts.map +1 -0
- package/esm/gambit/src/test_bot.js +5 -0
- package/esm/gambit/src/trace.d.ts +4 -0
- package/esm/gambit/src/trace.d.ts.map +1 -0
- package/esm/gambit/src/trace.js +86 -0
- package/esm/gambit-core/mod.d.ts +50 -0
- package/esm/gambit-core/mod.d.ts.map +1 -0
- package/esm/gambit-core/mod.js +19 -0
- package/esm/gambit-core/src/definitions.d.ts +11 -0
- package/esm/gambit-core/src/definitions.d.ts.map +1 -0
- package/esm/gambit-core/src/definitions.js +14 -0
- package/esm/gambit-core/src/openai_compat.d.ts +63 -0
- package/esm/gambit-core/src/openai_compat.d.ts.map +1 -0
- package/esm/gambit-core/src/openai_compat.js +272 -0
- package/esm/gambit-core/src/providers/openrouter.d.ts +8 -0
- package/esm/gambit-core/src/providers/openrouter.d.ts.map +1 -0
- package/esm/gambit-core/src/providers/openrouter.js +168 -0
- package/esm/gambit-core/src/render.d.ts +51 -0
- package/esm/gambit-core/src/render.d.ts.map +1 -0
- package/esm/gambit-core/src/render.js +188 -0
- package/esm/gambit-core/src/schema.d.ts +8 -0
- package/esm/gambit-core/src/schema.d.ts.map +1 -0
- package/esm/gambit-core/src/schema.js +45 -0
- package/esm/package.json +3 -0
- package/package.json +33 -0
- package/script/_dnt.polyfills.d.ts +25 -0
- package/script/_dnt.polyfills.d.ts.map +1 -0
- package/script/_dnt.polyfills.js +2 -0
- package/script/_dnt.shims.d.ts +6 -0
- package/script/_dnt.shims.d.ts.map +1 -0
- package/script/_dnt.shims.js +65 -0
- package/script/deps/jsr.io/@std/internal/1.0.12/_os.d.ts +2 -0
- package/script/deps/jsr.io/@std/internal/1.0.12/_os.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/internal/1.0.12/_os.js +38 -0
- package/script/deps/jsr.io/@std/internal/1.0.12/os.d.ts +3 -0
- package/script/deps/jsr.io/@std/internal/1.0.12/os.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/internal/1.0.12/os.js +8 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/assert_path.d.ts +2 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/assert_path.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/assert_path.js +10 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/basename.d.ts +4 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/basename.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/basename.js +45 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/common.d.ts +2 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/common.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/common.js +26 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/constants.d.ts +40 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/constants.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/constants.js +49 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/dirname.d.ts +2 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/dirname.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/dirname.js +11 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/format.d.ts +4 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/format.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/format.js +23 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/from_file_url.d.ts +2 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/from_file_url.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/from_file_url.js +12 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/glob_to_reg_exp.d.ts +35 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/glob_to_reg_exp.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/glob_to_reg_exp.js +238 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/normalize.d.ts +2 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/normalize.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/normalize.js +11 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/normalize_string.d.ts +2 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/normalize_string.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/normalize_string.js +80 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/relative.d.ts +2 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/relative.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/relative.js +12 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/strip_trailing_separators.d.ts +2 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/strip_trailing_separators.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/strip_trailing_separators.js +22 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/to_file_url.d.ts +2 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/to_file_url.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/_common/to_file_url.js +18 -0
- package/script/deps/jsr.io/@std/path/1.1.4/basename.d.ts +27 -0
- package/script/deps/jsr.io/@std/path/1.1.4/basename.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/basename.js +38 -0
- package/script/deps/jsr.io/@std/path/1.1.4/common.d.ts +28 -0
- package/script/deps/jsr.io/@std/path/1.1.4/common.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/common.js +36 -0
- package/script/deps/jsr.io/@std/path/1.1.4/constants.d.ts +15 -0
- package/script/deps/jsr.io/@std/path/1.1.4/constants.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/constants.js +20 -0
- package/script/deps/jsr.io/@std/path/1.1.4/dirname.d.ts +22 -0
- package/script/deps/jsr.io/@std/path/1.1.4/dirname.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/dirname.js +31 -0
- package/script/deps/jsr.io/@std/path/1.1.4/extname.d.ts +22 -0
- package/script/deps/jsr.io/@std/path/1.1.4/extname.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/extname.js +31 -0
- package/script/deps/jsr.io/@std/path/1.1.4/format.d.ts +22 -0
- package/script/deps/jsr.io/@std/path/1.1.4/format.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/format.js +30 -0
- package/script/deps/jsr.io/@std/path/1.1.4/from_file_url.d.ts +22 -0
- package/script/deps/jsr.io/@std/path/1.1.4/from_file_url.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/from_file_url.js +31 -0
- package/script/deps/jsr.io/@std/path/1.1.4/glob_to_regexp.d.ts +77 -0
- package/script/deps/jsr.io/@std/path/1.1.4/glob_to_regexp.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/glob_to_regexp.js +86 -0
- package/script/deps/jsr.io/@std/path/1.1.4/is_absolute.d.ts +22 -0
- package/script/deps/jsr.io/@std/path/1.1.4/is_absolute.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/is_absolute.js +31 -0
- package/script/deps/jsr.io/@std/path/1.1.4/is_glob.d.ts +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/is_glob.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/is_glob.js +45 -0
- package/script/deps/jsr.io/@std/path/1.1.4/join.d.ts +23 -0
- package/script/deps/jsr.io/@std/path/1.1.4/join.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/join.js +32 -0
- package/script/deps/jsr.io/@std/path/1.1.4/join_globs.d.ts +28 -0
- package/script/deps/jsr.io/@std/path/1.1.4/join_globs.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/join_globs.js +37 -0
- package/script/deps/jsr.io/@std/path/1.1.4/mod.d.ts +213 -0
- package/script/deps/jsr.io/@std/path/1.1.4/mod.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/mod.js +232 -0
- package/script/deps/jsr.io/@std/path/1.1.4/normalize.d.ts +26 -0
- package/script/deps/jsr.io/@std/path/1.1.4/normalize.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/normalize.js +35 -0
- package/script/deps/jsr.io/@std/path/1.1.4/normalize_glob.d.ts +29 -0
- package/script/deps/jsr.io/@std/path/1.1.4/normalize_glob.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/normalize_glob.js +38 -0
- package/script/deps/jsr.io/@std/path/1.1.4/parse.d.ts +35 -0
- package/script/deps/jsr.io/@std/path/1.1.4/parse.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/parse.js +42 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/_util.d.ts +2 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/_util.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/_util.js +11 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/basename.d.ts +39 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/basename.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/basename.js +55 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/constants.d.ts +13 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/constants.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/constants.js +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/dirname.d.ts +30 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/dirname.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/dirname.js +67 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/extname.d.ts +37 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/extname.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/extname.js +96 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/format.d.ts +24 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/format.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/format.js +31 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/from_file_url.d.ts +16 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/from_file_url.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/from_file_url.js +24 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/glob_to_regexp.d.ts +72 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/glob_to_regexp.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/glob_to_regexp.js +85 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/is_absolute.d.ts +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/is_absolute.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/is_absolute.js +26 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/join.d.ts +31 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/join.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/join.js +48 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/join_globs.d.ts +20 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/join_globs.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/join_globs.js +43 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/normalize.d.ts +37 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/normalize.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/normalize.js +61 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/normalize_glob.d.ts +20 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/normalize_glob.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/normalize_glob.js +35 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/parse.d.ts +25 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/parse.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/parse.js +118 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/relative.d.ts +20 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/relative.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/relative.js +109 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/resolve.d.ts +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/resolve.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/resolve.js +85 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/to_file_url.d.ts +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/to_file_url.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/to_file_url.js +30 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/to_namespaced_path.d.ts +16 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/to_namespaced_path.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/posix/to_namespaced_path.js +23 -0
- package/script/deps/jsr.io/@std/path/1.1.4/relative.d.ts +24 -0
- package/script/deps/jsr.io/@std/path/1.1.4/relative.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/relative.js +33 -0
- package/script/deps/jsr.io/@std/path/1.1.4/resolve.d.ts +22 -0
- package/script/deps/jsr.io/@std/path/1.1.4/resolve.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/resolve.js +33 -0
- package/script/deps/jsr.io/@std/path/1.1.4/to_file_url.d.ts +22 -0
- package/script/deps/jsr.io/@std/path/1.1.4/to_file_url.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/to_file_url.js +31 -0
- package/script/deps/jsr.io/@std/path/1.1.4/to_namespaced_path.d.ts +21 -0
- package/script/deps/jsr.io/@std/path/1.1.4/to_namespaced_path.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/to_namespaced_path.js +32 -0
- package/script/deps/jsr.io/@std/path/1.1.4/types.d.ts +38 -0
- package/script/deps/jsr.io/@std/path/1.1.4/types.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/types.js +4 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/_util.d.ts +4 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/_util.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/_util.js +20 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/basename.d.ts +22 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/basename.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/basename.js +50 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/constants.d.ts +13 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/constants.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/constants.js +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/dirname.d.ts +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/dirname.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/dirname.js +116 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/extname.d.ts +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/extname.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/extname.js +85 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/format.d.ts +24 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/format.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/format.js +31 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/from_file_url.d.ts +18 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/from_file_url.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/from_file_url.js +33 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/glob_to_regexp.d.ts +71 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/glob_to_regexp.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/glob_to_regexp.js +85 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/is_absolute.d.ts +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/is_absolute.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/is_absolute.js +41 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/join.d.ts +18 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/join.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/join.js +80 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/join_globs.d.ts +21 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/join_globs.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/join_globs.js +44 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/normalize.d.ts +19 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/normalize.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/normalize.js +138 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/normalize_glob.d.ts +20 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/normalize_glob.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/normalize_glob.js +35 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/parse.d.ts +25 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/parse.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/parse.js +179 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/relative.d.ts +23 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/relative.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/relative.js +134 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/resolve.d.ts +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/resolve.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/resolve.js +180 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/to_file_url.d.ts +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/to_file_url.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/to_file_url.js +37 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/to_namespaced_path.d.ts +17 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/to_namespaced_path.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/path/1.1.4/windows/to_namespaced_path.js +52 -0
- package/script/gambit/mod.d.ts +10 -0
- package/script/gambit/mod.d.ts.map +1 -0
- package/script/gambit/mod.js +27 -0
- package/script/gambit/src/durable_streams.d.ts +9 -0
- package/script/gambit/src/durable_streams.d.ts.map +1 -0
- package/script/gambit/src/durable_streams.js +136 -0
- package/script/gambit/src/server.d.ts +16 -0
- package/script/gambit/src/server.d.ts.map +1 -0
- package/script/gambit/src/server.js +2314 -0
- package/script/gambit/src/test_bot.d.ts +5 -0
- package/script/gambit/src/test_bot.d.ts.map +1 -0
- package/script/gambit/src/test_bot.js +8 -0
- package/script/gambit/src/trace.d.ts +4 -0
- package/script/gambit/src/trace.d.ts.map +1 -0
- package/script/gambit/src/trace.js +113 -0
- package/script/gambit-core/mod.d.ts +50 -0
- package/script/gambit-core/mod.d.ts.map +1 -0
- package/script/gambit-core/mod.js +29 -0
- package/script/gambit-core/src/definitions.d.ts +11 -0
- package/script/gambit-core/src/definitions.d.ts.map +1 -0
- package/script/gambit-core/src/definitions.js +20 -0
- package/script/gambit-core/src/openai_compat.d.ts +63 -0
- package/script/gambit-core/src/openai_compat.d.ts.map +1 -0
- package/script/gambit-core/src/openai_compat.js +276 -0
- package/script/gambit-core/src/providers/openrouter.d.ts +8 -0
- package/script/gambit-core/src/providers/openrouter.d.ts.map +1 -0
- package/script/gambit-core/src/providers/openrouter.js +197 -0
- package/script/gambit-core/src/render.d.ts +51 -0
- package/script/gambit-core/src/render.d.ts.map +1 -0
- package/script/gambit-core/src/render.js +192 -0
- package/script/gambit-core/src/schema.d.ts +8 -0
- package/script/gambit-core/src/schema.d.ts.map +1 -0
- package/script/gambit-core/src/schema.js +51 -0
- package/script/package.json +3 -0
- package/simulator-ui/.gitkeep +1 -0
- package/simulator-ui/bundle.js +22824 -0
- package/simulator-ui/bundle.js.map +7 -0
|
@@ -0,0 +1,2314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.startWebSocketSimulator = startWebSocketSimulator;
|
|
27
|
+
const dntShim = __importStar(require("../../_dnt.shims.js"));
|
|
28
|
+
const path = __importStar(require("../../deps/jsr.io/@std/path/1.1.4/mod.js"));
|
|
29
|
+
const runtime_1 = require("@bolt-foundry/gambit-core/internal/runtime");
|
|
30
|
+
const test_bot_js_1 = require("./test_bot.js");
|
|
31
|
+
const trace_js_1 = require("./trace.js");
|
|
32
|
+
const loader_1 = require("@bolt-foundry/gambit-core/internal/loader");
|
|
33
|
+
const durable_streams_js_1 = require("./durable_streams.js");
|
|
34
|
+
const logger = console;
|
|
35
|
+
const moduleLocation = (() => {
|
|
36
|
+
const directoryFromUrl = (url) => {
|
|
37
|
+
if (!url || !url.startsWith("file:"))
|
|
38
|
+
return undefined;
|
|
39
|
+
return path.dirname(path.fromFileUrl(url));
|
|
40
|
+
};
|
|
41
|
+
try {
|
|
42
|
+
const resolved = new URL("./server.ts", require("url").pathToFileURL(__filename).href).href;
|
|
43
|
+
const fromResolved = directoryFromUrl(resolved);
|
|
44
|
+
if (fromResolved)
|
|
45
|
+
return { dir: fromResolved, isLocal: true };
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// ignore resolution failures and try other strategies
|
|
49
|
+
}
|
|
50
|
+
const fromMeta = directoryFromUrl(require("url").pathToFileURL(__filename).href);
|
|
51
|
+
if (fromMeta)
|
|
52
|
+
return { dir: fromMeta, isLocal: true };
|
|
53
|
+
return { dir: dntShim.Deno.cwd(), isLocal: false };
|
|
54
|
+
})();
|
|
55
|
+
const moduleDir = moduleLocation.dir;
|
|
56
|
+
const simulatorBundleUrl = (() => {
|
|
57
|
+
try {
|
|
58
|
+
return new URL("../simulator-ui/dist/bundle.js", require("url").pathToFileURL(__filename).href).href;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
})();
|
|
64
|
+
const simulatorBundleSourceMapUrl = (() => {
|
|
65
|
+
try {
|
|
66
|
+
return new URL("../simulator-ui/dist/bundle.js.map", require("url").pathToFileURL(__filename).href).href;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
})();
|
|
72
|
+
let cachedRemoteBundle = null;
|
|
73
|
+
let cachedRemoteBundleSourceMap = null;
|
|
74
|
+
const simulatorBundlePath = path.resolve(moduleDir, "..", "simulator-ui", "dist", "bundle.js");
|
|
75
|
+
const simulatorUiEntryPath = path.resolve(moduleDir, "..", "simulator-ui", "src", "main.tsx");
|
|
76
|
+
const simulatorBundleSourceMapPath = path.resolve(moduleDir, "..", "simulator-ui", "dist", "bundle.js.map");
|
|
77
|
+
const SIMULATOR_STREAM_ID = "gambit-simulator";
|
|
78
|
+
const TEST_BOT_STREAM_ID = "gambit-test-bot";
|
|
79
|
+
const CALIBRATE_STREAM_ID = "gambit-calibrate";
|
|
80
|
+
let availableTestDecks = [];
|
|
81
|
+
const testDeckByPath = new Map();
|
|
82
|
+
const testDeckById = new Map();
|
|
83
|
+
let availableGraderDecks = [];
|
|
84
|
+
const graderDeckByPath = new Map();
|
|
85
|
+
const graderDeckById = new Map();
|
|
86
|
+
function randomId(prefix) {
|
|
87
|
+
const suffix = crypto.randomUUID().replace(/-/g, "").slice(0, 24);
|
|
88
|
+
return `${prefix}-${suffix}`;
|
|
89
|
+
}
|
|
90
|
+
function resolveDefaultValue(raw) {
|
|
91
|
+
if (typeof raw === "function") {
|
|
92
|
+
try {
|
|
93
|
+
return raw();
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return raw;
|
|
100
|
+
}
|
|
101
|
+
async function describeDeckInputSchemaFromPath(deckPath) {
|
|
102
|
+
try {
|
|
103
|
+
const deck = await (0, loader_1.loadDeck)(deckPath);
|
|
104
|
+
return describeZodSchema(deck.inputSchema);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
108
|
+
logger.warn(`[sim] failed to load deck schema: ${message}`);
|
|
109
|
+
return { error: message };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function describeZodSchema(schema) {
|
|
113
|
+
try {
|
|
114
|
+
const normalized = normalizeSchema(schema);
|
|
115
|
+
const defaults = normalized ? materializeDefaults(normalized) : undefined;
|
|
116
|
+
return { schema: normalized, defaults };
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
120
|
+
return { error: message };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function schemaHasField(schema, field) {
|
|
124
|
+
return schema?.kind === "object" &&
|
|
125
|
+
Boolean(schema.fields && schema.fields[field]);
|
|
126
|
+
}
|
|
127
|
+
function normalizeSchema(schema) {
|
|
128
|
+
if (!schema)
|
|
129
|
+
return undefined;
|
|
130
|
+
const unwrapped = unwrapSchema(schema);
|
|
131
|
+
const core = unwrapped.schema;
|
|
132
|
+
if (!core || typeof core !== "object")
|
|
133
|
+
return undefined;
|
|
134
|
+
const meta = {
|
|
135
|
+
optional: unwrapped.optional,
|
|
136
|
+
description: readDescription(schema) ?? readDescription(core),
|
|
137
|
+
example: readExample(schema) ?? readExample(core),
|
|
138
|
+
defaultValue: unwrapped.defaultValue,
|
|
139
|
+
};
|
|
140
|
+
const typeName = core._def?.typeName;
|
|
141
|
+
switch (typeName) {
|
|
142
|
+
case "ZodString":
|
|
143
|
+
return { kind: "string", ...meta };
|
|
144
|
+
case "ZodNumber":
|
|
145
|
+
return { kind: "number", ...meta };
|
|
146
|
+
case "ZodBoolean":
|
|
147
|
+
return { kind: "boolean", ...meta };
|
|
148
|
+
case "ZodEnum": {
|
|
149
|
+
const values = core._def.values;
|
|
150
|
+
return { kind: "enum", enumValues: [...values], ...meta };
|
|
151
|
+
}
|
|
152
|
+
case "ZodNativeEnum": {
|
|
153
|
+
const values = core._def
|
|
154
|
+
.values;
|
|
155
|
+
return { kind: "enum", enumValues: Object.values(values), ...meta };
|
|
156
|
+
}
|
|
157
|
+
case "ZodLiteral": {
|
|
158
|
+
const value = core._def.value;
|
|
159
|
+
const defaultValue = meta.defaultValue !== undefined
|
|
160
|
+
? meta.defaultValue
|
|
161
|
+
: value;
|
|
162
|
+
const { defaultValue: _m, ...restMeta } = meta;
|
|
163
|
+
return {
|
|
164
|
+
kind: "enum",
|
|
165
|
+
enumValues: [value],
|
|
166
|
+
...restMeta,
|
|
167
|
+
defaultValue,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
case "ZodArray": {
|
|
171
|
+
const items = core._def.type;
|
|
172
|
+
return {
|
|
173
|
+
kind: "array",
|
|
174
|
+
items: normalizeSchema(items),
|
|
175
|
+
...meta,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
case "ZodObject": {
|
|
179
|
+
const fields = {};
|
|
180
|
+
const shape = core
|
|
181
|
+
._def.shape();
|
|
182
|
+
for (const [key, child] of Object.entries(shape)) {
|
|
183
|
+
const normalized = normalizeSchema(child);
|
|
184
|
+
if (normalized)
|
|
185
|
+
fields[key] = normalized;
|
|
186
|
+
}
|
|
187
|
+
return { kind: "object", fields, ...meta };
|
|
188
|
+
}
|
|
189
|
+
default:
|
|
190
|
+
return { kind: "unknown", ...meta };
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function unwrapSchema(schema) {
|
|
194
|
+
let current = schema;
|
|
195
|
+
let optional = false;
|
|
196
|
+
let defaultValue;
|
|
197
|
+
while (current && typeof current === "object") {
|
|
198
|
+
const def = current
|
|
199
|
+
._def;
|
|
200
|
+
const typeName = def?.typeName;
|
|
201
|
+
if (typeName === "ZodOptional" || typeName === "ZodNullable") {
|
|
202
|
+
optional = true;
|
|
203
|
+
current = def.innerType;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (typeName === "ZodDefault") {
|
|
207
|
+
if (defaultValue === undefined) {
|
|
208
|
+
defaultValue = resolveDefaultValue(def.defaultValue);
|
|
209
|
+
}
|
|
210
|
+
current = def.innerType;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (typeName === "ZodEffects") {
|
|
214
|
+
current = def.schema;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (typeName === "ZodCatch") {
|
|
218
|
+
current = def.innerType;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (typeName === "ZodBranded") {
|
|
222
|
+
current = def.type;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
return { schema: current, optional, defaultValue };
|
|
228
|
+
}
|
|
229
|
+
function readDescription(schema) {
|
|
230
|
+
const def = schema && typeof schema === "object"
|
|
231
|
+
? schema._def
|
|
232
|
+
: undefined;
|
|
233
|
+
return typeof def?.description === "string" ? def.description : undefined;
|
|
234
|
+
}
|
|
235
|
+
function readExample(schema) {
|
|
236
|
+
const def = schema && typeof schema === "object"
|
|
237
|
+
? schema._def
|
|
238
|
+
: undefined;
|
|
239
|
+
if (!def)
|
|
240
|
+
return undefined;
|
|
241
|
+
const direct = def.example ?? def.examples;
|
|
242
|
+
if (direct !== undefined)
|
|
243
|
+
return direct;
|
|
244
|
+
const openapi = def.openapi;
|
|
245
|
+
if (openapi?.example !== undefined)
|
|
246
|
+
return openapi.example;
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
function cloneValue(value) {
|
|
250
|
+
try {
|
|
251
|
+
// @ts-ignore structuredClone is available in Deno
|
|
252
|
+
return structuredClone(value);
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
try {
|
|
256
|
+
return JSON.parse(JSON.stringify(value));
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
return value;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function resolveDeckPath(p) {
|
|
264
|
+
const absolutePath = path.isAbsolute(p) ? p : path.resolve(p);
|
|
265
|
+
try {
|
|
266
|
+
const url = new URL(path.toFileUrl(absolutePath).href, require("url").pathToFileURL(__filename).href).href;
|
|
267
|
+
if (url.startsWith("file:"))
|
|
268
|
+
return path.fromFileUrl(url);
|
|
269
|
+
return url;
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
return absolutePath;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function materializeDefaults(schema) {
|
|
276
|
+
if (!schema)
|
|
277
|
+
return undefined;
|
|
278
|
+
if (schema.defaultValue !== undefined)
|
|
279
|
+
return cloneValue(schema.defaultValue);
|
|
280
|
+
if (schema.example !== undefined)
|
|
281
|
+
return cloneValue(schema.example);
|
|
282
|
+
switch (schema.kind) {
|
|
283
|
+
case "object": {
|
|
284
|
+
const out = {};
|
|
285
|
+
for (const [key, child] of Object.entries(schema.fields ?? {})) {
|
|
286
|
+
const value = materializeDefaults(child);
|
|
287
|
+
if (value !== undefined)
|
|
288
|
+
out[key] = value;
|
|
289
|
+
}
|
|
290
|
+
return Object.keys(out).length ? out : undefined;
|
|
291
|
+
}
|
|
292
|
+
case "array": {
|
|
293
|
+
if (schema.items) {
|
|
294
|
+
const item = materializeDefaults(schema.items);
|
|
295
|
+
if (item !== undefined)
|
|
296
|
+
return [item];
|
|
297
|
+
}
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
default:
|
|
301
|
+
return undefined;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function deriveInitialFromSchema(schema) {
|
|
305
|
+
if (!schema)
|
|
306
|
+
return undefined;
|
|
307
|
+
if (schema.defaultValue !== undefined)
|
|
308
|
+
return cloneValue(schema.defaultValue);
|
|
309
|
+
if (schema.example !== undefined)
|
|
310
|
+
return cloneValue(schema.example);
|
|
311
|
+
switch (schema.kind) {
|
|
312
|
+
case "object": {
|
|
313
|
+
const out = {};
|
|
314
|
+
for (const [key, child] of Object.entries(schema.fields ?? {})) {
|
|
315
|
+
const value = deriveInitialFromSchema(child);
|
|
316
|
+
if (value !== undefined)
|
|
317
|
+
out[key] = value;
|
|
318
|
+
}
|
|
319
|
+
return out;
|
|
320
|
+
}
|
|
321
|
+
case "array": {
|
|
322
|
+
if (schema.items) {
|
|
323
|
+
const item = deriveInitialFromSchema(schema.items);
|
|
324
|
+
if (item !== undefined)
|
|
325
|
+
return [item];
|
|
326
|
+
}
|
|
327
|
+
return [];
|
|
328
|
+
}
|
|
329
|
+
case "boolean":
|
|
330
|
+
return false;
|
|
331
|
+
default:
|
|
332
|
+
return undefined;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function startWebSocketSimulator(opts) {
|
|
336
|
+
const port = opts.port ?? 8000;
|
|
337
|
+
const consoleTracer = opts.verbose ? (0, trace_js_1.makeConsoleTracer)() : undefined;
|
|
338
|
+
let resolvedDeckPath = resolveDeckPath(opts.deckPath);
|
|
339
|
+
const sessionsRoot = (() => {
|
|
340
|
+
const base = opts.sessionDir
|
|
341
|
+
? path.resolve(opts.sessionDir)
|
|
342
|
+
: path.resolve(dntShim.Deno.cwd(), ".gambit", "sessions");
|
|
343
|
+
try {
|
|
344
|
+
dntShim.Deno.mkdirSync(base, { recursive: true });
|
|
345
|
+
}
|
|
346
|
+
catch (err) {
|
|
347
|
+
logger.warn(`[sim] unable to ensure sessions directory ${base}: ${err instanceof Error ? err.message : err}`);
|
|
348
|
+
}
|
|
349
|
+
return base;
|
|
350
|
+
})();
|
|
351
|
+
const ensureDir = (dir) => {
|
|
352
|
+
try {
|
|
353
|
+
dntShim.Deno.mkdirSync(dir, { recursive: true });
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
// ignore
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
const deckSlugFromPath = (p) => {
|
|
360
|
+
const baseName = path.basename(p || "deck");
|
|
361
|
+
const withoutExt = baseName.replace(/\.[^.]+$/, "");
|
|
362
|
+
const slug = withoutExt.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
363
|
+
return slug || "session";
|
|
364
|
+
};
|
|
365
|
+
const testBotRuns = new Map();
|
|
366
|
+
const broadcastTestBot = (payload) => {
|
|
367
|
+
(0, durable_streams_js_1.appendDurableStreamEvent)(TEST_BOT_STREAM_ID, payload);
|
|
368
|
+
};
|
|
369
|
+
let deckSlug = deckSlugFromPath(resolvedDeckPath);
|
|
370
|
+
const enrichStateWithSession = (state) => {
|
|
371
|
+
const meta = { ...(state.meta ?? {}) };
|
|
372
|
+
const now = new Date();
|
|
373
|
+
if (typeof meta.sessionId !== "string") {
|
|
374
|
+
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
375
|
+
meta.sessionId = `${deckSlug}-${stamp}`;
|
|
376
|
+
meta.sessionCreatedAt = now.toISOString();
|
|
377
|
+
}
|
|
378
|
+
if (typeof meta.deck !== "string") {
|
|
379
|
+
meta.deck = resolvedDeckPath;
|
|
380
|
+
}
|
|
381
|
+
if (typeof meta.deckSlug !== "string") {
|
|
382
|
+
meta.deckSlug = deckSlug;
|
|
383
|
+
}
|
|
384
|
+
if (typeof meta.sessionDir !== "string") {
|
|
385
|
+
meta.sessionDir = path.join(sessionsRoot, String(meta.sessionId));
|
|
386
|
+
}
|
|
387
|
+
if (typeof meta.sessionStatePath !== "string" &&
|
|
388
|
+
typeof meta.sessionDir === "string") {
|
|
389
|
+
meta.sessionStatePath = path.join(meta.sessionDir, "state.json");
|
|
390
|
+
}
|
|
391
|
+
const dir = typeof meta.sessionDir === "string"
|
|
392
|
+
? meta.sessionDir
|
|
393
|
+
: undefined;
|
|
394
|
+
return { state: { ...state, meta }, dir };
|
|
395
|
+
};
|
|
396
|
+
const persistSessionState = (state) => {
|
|
397
|
+
const { state: enriched, dir } = enrichStateWithSession(state);
|
|
398
|
+
if (dir) {
|
|
399
|
+
try {
|
|
400
|
+
ensureDir(dir);
|
|
401
|
+
const filePath = path.join(dir, "state.json");
|
|
402
|
+
dntShim.Deno.writeTextFileSync(filePath, JSON.stringify(enriched, null, 2));
|
|
403
|
+
}
|
|
404
|
+
catch (err) {
|
|
405
|
+
logger.warn(`[sim] failed to persist session state: ${err instanceof Error ? err.message : err}`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return enriched;
|
|
409
|
+
};
|
|
410
|
+
const readSessionState = (sessionId) => {
|
|
411
|
+
const dir = path.join(sessionsRoot, sessionId);
|
|
412
|
+
const filePath = path.join(dir, "state.json");
|
|
413
|
+
try {
|
|
414
|
+
const text = dntShim.Deno.readTextFileSync(filePath);
|
|
415
|
+
const parsed = JSON.parse(text);
|
|
416
|
+
if (parsed && typeof parsed === "object") {
|
|
417
|
+
return parsed;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
catch {
|
|
421
|
+
// ignore
|
|
422
|
+
}
|
|
423
|
+
return undefined;
|
|
424
|
+
};
|
|
425
|
+
const deleteSessionState = (sessionId) => {
|
|
426
|
+
if (!sessionId ||
|
|
427
|
+
sessionId === "." ||
|
|
428
|
+
sessionId === ".." ||
|
|
429
|
+
sessionId !== path.basename(sessionId) ||
|
|
430
|
+
sessionId.includes("/") ||
|
|
431
|
+
sessionId.includes("\\")) {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
const dir = path.resolve(sessionsRoot, sessionId);
|
|
435
|
+
if (dir === sessionsRoot)
|
|
436
|
+
return false;
|
|
437
|
+
const relative = path.relative(sessionsRoot, dir);
|
|
438
|
+
if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
441
|
+
try {
|
|
442
|
+
dntShim.Deno.removeSync(dir, { recursive: true });
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
const cloneTraces = (traces) => {
|
|
450
|
+
try {
|
|
451
|
+
return structuredClone(traces);
|
|
452
|
+
}
|
|
453
|
+
catch {
|
|
454
|
+
try {
|
|
455
|
+
return JSON.parse(JSON.stringify(traces));
|
|
456
|
+
}
|
|
457
|
+
catch {
|
|
458
|
+
return [...traces];
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
let simulatorRunning = false;
|
|
463
|
+
let simulatorCurrentRunId;
|
|
464
|
+
let simulatorSavedState;
|
|
465
|
+
let simulatorCapturedTraces = [];
|
|
466
|
+
const emitSimulator = (payload) => {
|
|
467
|
+
(0, durable_streams_js_1.appendDurableStreamEvent)(SIMULATOR_STREAM_ID, payload);
|
|
468
|
+
};
|
|
469
|
+
const listSessions = () => {
|
|
470
|
+
try {
|
|
471
|
+
const entries = [];
|
|
472
|
+
for (const entry of dntShim.Deno.readDirSync(sessionsRoot)) {
|
|
473
|
+
if (!entry.isDirectory)
|
|
474
|
+
continue;
|
|
475
|
+
const state = readSessionState(entry.name);
|
|
476
|
+
if (!state)
|
|
477
|
+
continue;
|
|
478
|
+
entries.push(buildSessionMeta(entry.name, state));
|
|
479
|
+
}
|
|
480
|
+
entries.sort((a, b) => {
|
|
481
|
+
const aKey = a.createdAt ?? a.id;
|
|
482
|
+
const bKey = b.createdAt ?? b.id;
|
|
483
|
+
return bKey.localeCompare(aKey);
|
|
484
|
+
});
|
|
485
|
+
return entries;
|
|
486
|
+
}
|
|
487
|
+
catch {
|
|
488
|
+
return [];
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
const buildSessionMeta = (sessionId, state) => {
|
|
492
|
+
const meta = state?.meta ?? {};
|
|
493
|
+
const createdAt = typeof meta.sessionCreatedAt === "string"
|
|
494
|
+
? meta.sessionCreatedAt
|
|
495
|
+
: undefined;
|
|
496
|
+
const deck = typeof meta.deck === "string" ? meta.deck : undefined;
|
|
497
|
+
const deckSlug = typeof meta.deckSlug === "string"
|
|
498
|
+
? meta.deckSlug
|
|
499
|
+
: undefined;
|
|
500
|
+
const testBotName = typeof meta.testBotName ===
|
|
501
|
+
"string"
|
|
502
|
+
? meta.testBotName
|
|
503
|
+
: undefined;
|
|
504
|
+
const gradingRuns = Array.isArray(meta.gradingRuns)
|
|
505
|
+
? meta.gradingRuns.map((run) => ({
|
|
506
|
+
id: typeof run.id === "string" ? run.id : randomId("cal"),
|
|
507
|
+
graderId: run.graderId,
|
|
508
|
+
graderPath: run.graderPath,
|
|
509
|
+
graderLabel: run.graderLabel,
|
|
510
|
+
status: run.status,
|
|
511
|
+
runAt: run.runAt,
|
|
512
|
+
referenceSample: run.referenceSample,
|
|
513
|
+
input: run.input,
|
|
514
|
+
result: run.result,
|
|
515
|
+
error: run.error,
|
|
516
|
+
}))
|
|
517
|
+
: Array.isArray(meta.calibrationRuns)
|
|
518
|
+
? meta.calibrationRuns.map((run) => ({
|
|
519
|
+
id: typeof run.id === "string" ? run.id : randomId("cal"),
|
|
520
|
+
graderId: run.graderId,
|
|
521
|
+
graderPath: run.graderPath,
|
|
522
|
+
graderLabel: run.graderLabel,
|
|
523
|
+
status: run.status,
|
|
524
|
+
runAt: run.runAt,
|
|
525
|
+
referenceSample: run.referenceSample,
|
|
526
|
+
input: run.input,
|
|
527
|
+
result: run.result,
|
|
528
|
+
error: run.error,
|
|
529
|
+
}))
|
|
530
|
+
: undefined;
|
|
531
|
+
const sessionDir = typeof meta.sessionDir === "string"
|
|
532
|
+
? meta.sessionDir
|
|
533
|
+
: path.join(sessionsRoot, sessionId);
|
|
534
|
+
const statePath = typeof meta
|
|
535
|
+
.sessionStatePath === "string"
|
|
536
|
+
? meta.sessionStatePath
|
|
537
|
+
: path.join(sessionDir, "state.json");
|
|
538
|
+
return {
|
|
539
|
+
id: sessionId,
|
|
540
|
+
deck,
|
|
541
|
+
deckSlug,
|
|
542
|
+
createdAt,
|
|
543
|
+
testBotName,
|
|
544
|
+
gradingRuns,
|
|
545
|
+
sessionDir,
|
|
546
|
+
statePath,
|
|
547
|
+
};
|
|
548
|
+
};
|
|
549
|
+
const stringifyContent = (value) => {
|
|
550
|
+
if (value === null || value === undefined)
|
|
551
|
+
return "";
|
|
552
|
+
if (typeof value === "string")
|
|
553
|
+
return value;
|
|
554
|
+
try {
|
|
555
|
+
return JSON.stringify(value);
|
|
556
|
+
}
|
|
557
|
+
catch {
|
|
558
|
+
return String(value);
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
const updateTestDeckRegistry = (list) => {
|
|
562
|
+
testDeckByPath.clear();
|
|
563
|
+
testDeckById.clear();
|
|
564
|
+
for (const entry of list) {
|
|
565
|
+
testDeckByPath.set(entry.path, entry);
|
|
566
|
+
testDeckById.set(entry.id, entry);
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
const updateGraderDeckRegistry = (list) => {
|
|
570
|
+
graderDeckByPath.clear();
|
|
571
|
+
graderDeckById.clear();
|
|
572
|
+
for (const entry of list) {
|
|
573
|
+
graderDeckByPath.set(entry.path, entry);
|
|
574
|
+
graderDeckById.set(entry.id, entry);
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
const resolveTestDeck = (identifier) => {
|
|
578
|
+
if (!identifier)
|
|
579
|
+
return undefined;
|
|
580
|
+
const byId = testDeckById.get(identifier);
|
|
581
|
+
if (byId)
|
|
582
|
+
return byId;
|
|
583
|
+
const byPath = testDeckByPath.get(path.resolve(identifier));
|
|
584
|
+
return byPath;
|
|
585
|
+
};
|
|
586
|
+
const resolveGraderDeck = (identifier) => {
|
|
587
|
+
if (!identifier)
|
|
588
|
+
return undefined;
|
|
589
|
+
const byId = graderDeckById.get(identifier);
|
|
590
|
+
if (byId)
|
|
591
|
+
return byId;
|
|
592
|
+
const byPath = graderDeckByPath.get(path.resolve(identifier));
|
|
593
|
+
return byPath;
|
|
594
|
+
};
|
|
595
|
+
const slugify = (label) => {
|
|
596
|
+
return label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)+/g, "");
|
|
597
|
+
};
|
|
598
|
+
const toDeckLabel = (filePath) => {
|
|
599
|
+
const base = path.basename(filePath);
|
|
600
|
+
return base
|
|
601
|
+
.replace(/\.deck\.(md|ts)$/i, "")
|
|
602
|
+
.replace(/[-_]+/g, " ")
|
|
603
|
+
.trim() || base;
|
|
604
|
+
};
|
|
605
|
+
const buildTestBotSnapshot = (state) => {
|
|
606
|
+
const rawMessages = state.messages ?? [];
|
|
607
|
+
const refs = state.messageRefs ?? [];
|
|
608
|
+
const feedbackByRef = new Map(state.feedback?.map((entry) => [entry.messageRefId, entry]) ?? []);
|
|
609
|
+
const messages = [];
|
|
610
|
+
const fallbackToolInserts = [];
|
|
611
|
+
for (let i = 0; i < rawMessages.length; i++) {
|
|
612
|
+
const msg = rawMessages[i];
|
|
613
|
+
if (msg?.role === "assistant" || msg?.role === "user") {
|
|
614
|
+
const content = stringifyContent(msg.content).trim();
|
|
615
|
+
if (!content)
|
|
616
|
+
continue;
|
|
617
|
+
const refId = refs[i]?.id;
|
|
618
|
+
messages.push({
|
|
619
|
+
role: msg.role,
|
|
620
|
+
content,
|
|
621
|
+
messageRefId: refId,
|
|
622
|
+
feedback: refId ? feedbackByRef.get(refId) : undefined,
|
|
623
|
+
});
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
if (msg?.role === "tool") {
|
|
627
|
+
const actionCallId = typeof msg.tool_call_id === "string"
|
|
628
|
+
? msg.tool_call_id
|
|
629
|
+
: undefined;
|
|
630
|
+
const name = typeof msg.name === "string" ? msg.name : undefined;
|
|
631
|
+
fallbackToolInserts.push({
|
|
632
|
+
actionCallId,
|
|
633
|
+
name,
|
|
634
|
+
index: messages.length,
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
const traceToolInserts = deriveToolInsertsFromTraces(state, messages.length);
|
|
639
|
+
return {
|
|
640
|
+
messages,
|
|
641
|
+
toolInserts: traceToolInserts.length > 0
|
|
642
|
+
? traceToolInserts
|
|
643
|
+
: fallbackToolInserts,
|
|
644
|
+
};
|
|
645
|
+
};
|
|
646
|
+
const deriveToolInsertsFromTraces = (state, messageCount) => {
|
|
647
|
+
const traces = Array.isArray(state.traces) ? state.traces : [];
|
|
648
|
+
if (!traces.length)
|
|
649
|
+
return [];
|
|
650
|
+
const inserts = [];
|
|
651
|
+
let messageIndex = 0;
|
|
652
|
+
for (const trace of traces) {
|
|
653
|
+
if (!trace || typeof trace !== "object")
|
|
654
|
+
continue;
|
|
655
|
+
const traceRecord = trace;
|
|
656
|
+
const type = typeof traceRecord.type === "string" ? traceRecord.type : "";
|
|
657
|
+
if (type === "message.user" || type === "model.result") {
|
|
658
|
+
messageIndex++;
|
|
659
|
+
continue;
|
|
660
|
+
}
|
|
661
|
+
if (type === "tool.call") {
|
|
662
|
+
const actionCallId = typeof traceRecord.actionCallId === "string"
|
|
663
|
+
? traceRecord.actionCallId
|
|
664
|
+
: undefined;
|
|
665
|
+
const parentActionCallId = typeof traceRecord.parentActionCallId === "string"
|
|
666
|
+
? traceRecord.parentActionCallId
|
|
667
|
+
: undefined;
|
|
668
|
+
const name = typeof traceRecord.name === "string"
|
|
669
|
+
? traceRecord.name
|
|
670
|
+
: undefined;
|
|
671
|
+
inserts.push({
|
|
672
|
+
actionCallId,
|
|
673
|
+
parentActionCallId,
|
|
674
|
+
name,
|
|
675
|
+
index: Math.min(messageIndex, messageCount),
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
return inserts;
|
|
680
|
+
};
|
|
681
|
+
const syncTestBotRunFromState = (run, state) => {
|
|
682
|
+
const snapshot = buildTestBotSnapshot(state);
|
|
683
|
+
run.messages = snapshot.messages;
|
|
684
|
+
run.toolInserts = snapshot.toolInserts;
|
|
685
|
+
const sessionId = typeof state.meta?.sessionId === "string"
|
|
686
|
+
? state.meta.sessionId
|
|
687
|
+
: undefined;
|
|
688
|
+
if (sessionId)
|
|
689
|
+
run.sessionId = sessionId;
|
|
690
|
+
run.traces = Array.isArray(state.traces) ? [...state.traces] : undefined;
|
|
691
|
+
};
|
|
692
|
+
const startTestBotRun = (runOpts = {}) => {
|
|
693
|
+
const botDeckPath = typeof runOpts.botDeckPath === "string"
|
|
694
|
+
? runOpts.botDeckPath
|
|
695
|
+
: undefined;
|
|
696
|
+
if (!botDeckPath) {
|
|
697
|
+
throw new Error("Missing test bot deck path");
|
|
698
|
+
}
|
|
699
|
+
const defaultMaxTurns = 12;
|
|
700
|
+
const maxTurns = Math.round((0, test_bot_js_1.sanitizeNumber)(runOpts.maxTurnsOverride ?? defaultMaxTurns, defaultMaxTurns, { min: 1, max: 200 }));
|
|
701
|
+
const deckInput = runOpts.deckInput;
|
|
702
|
+
const hasDeckInput = deckInput !== undefined;
|
|
703
|
+
const botInput = runOpts.botInput;
|
|
704
|
+
const initialUserMessage = typeof runOpts.initialUserMessage === "string"
|
|
705
|
+
? runOpts.initialUserMessage.trim()
|
|
706
|
+
: "";
|
|
707
|
+
const botConfigPath = botDeckPath;
|
|
708
|
+
const testBotName = path.basename(botConfigPath).replace(/\.deck\.(md|ts)$/i, "");
|
|
709
|
+
const runId = randomId("testbot");
|
|
710
|
+
const startedAt = new Date().toISOString();
|
|
711
|
+
const controller = new AbortController();
|
|
712
|
+
const entry = {
|
|
713
|
+
run: {
|
|
714
|
+
id: runId,
|
|
715
|
+
status: "running",
|
|
716
|
+
startedAt,
|
|
717
|
+
maxTurns,
|
|
718
|
+
messages: [],
|
|
719
|
+
traces: [],
|
|
720
|
+
toolInserts: [],
|
|
721
|
+
},
|
|
722
|
+
promise: null,
|
|
723
|
+
abort: controller,
|
|
724
|
+
};
|
|
725
|
+
testBotRuns.set(runId, entry);
|
|
726
|
+
const run = entry.run;
|
|
727
|
+
let savedState = undefined;
|
|
728
|
+
let lastCount = 0;
|
|
729
|
+
const capturedTraces = [];
|
|
730
|
+
const setSessionId = (state) => {
|
|
731
|
+
const sessionId = typeof state?.meta?.sessionId === "string"
|
|
732
|
+
? state.meta.sessionId
|
|
733
|
+
: undefined;
|
|
734
|
+
if (sessionId)
|
|
735
|
+
run.sessionId = sessionId;
|
|
736
|
+
};
|
|
737
|
+
const appendFromState = (state) => {
|
|
738
|
+
const snapshot = buildTestBotSnapshot(state);
|
|
739
|
+
const rawLength = state.messages?.length ?? 0;
|
|
740
|
+
const toolCount = snapshot.toolInserts.length;
|
|
741
|
+
const shouldBroadcast = rawLength !== lastCount ||
|
|
742
|
+
(run.toolInserts?.length ?? 0) !== toolCount;
|
|
743
|
+
run.messages = snapshot.messages;
|
|
744
|
+
run.toolInserts = snapshot.toolInserts;
|
|
745
|
+
lastCount = rawLength;
|
|
746
|
+
setSessionId(state);
|
|
747
|
+
run.traces = Array.isArray(state.traces) ? [...state.traces] : undefined;
|
|
748
|
+
if (shouldBroadcast) {
|
|
749
|
+
broadcastTestBot({ type: "testBotStatus", run });
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
const tracer = (event) => {
|
|
753
|
+
const stamped = event.ts ? event : { ...event, ts: Date.now() };
|
|
754
|
+
capturedTraces.push(stamped);
|
|
755
|
+
consoleTracer?.(stamped);
|
|
756
|
+
};
|
|
757
|
+
let deckBotState = undefined;
|
|
758
|
+
let sessionEnded = false;
|
|
759
|
+
const getLastAssistantMessage = (history) => {
|
|
760
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
761
|
+
const msg = history[i];
|
|
762
|
+
if (msg?.role === "assistant") {
|
|
763
|
+
return stringifyContent(msg.content);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
return undefined;
|
|
767
|
+
};
|
|
768
|
+
const generateDeckBotUserMessage = async (history, streamOpts) => {
|
|
769
|
+
const assistantMessage = getLastAssistantMessage(history);
|
|
770
|
+
if (!assistantMessage)
|
|
771
|
+
return "";
|
|
772
|
+
const result = await runDeckWithFallback({
|
|
773
|
+
path: botDeckPath,
|
|
774
|
+
input: botInput,
|
|
775
|
+
inputProvided: botInput !== undefined,
|
|
776
|
+
modelProvider: opts.modelProvider,
|
|
777
|
+
state: deckBotState,
|
|
778
|
+
allowRootStringInput: true,
|
|
779
|
+
initialUserMessage: assistantMessage,
|
|
780
|
+
onStateUpdate: (state) => {
|
|
781
|
+
deckBotState = state;
|
|
782
|
+
},
|
|
783
|
+
stream: Boolean(streamOpts?.onStreamText),
|
|
784
|
+
onStreamText: streamOpts?.onStreamText,
|
|
785
|
+
});
|
|
786
|
+
if ((0, runtime_1.isGambitEndSignal)(result)) {
|
|
787
|
+
sessionEnded = true;
|
|
788
|
+
return "";
|
|
789
|
+
}
|
|
790
|
+
const text = stringifyOutput(result);
|
|
791
|
+
return text.trim();
|
|
792
|
+
};
|
|
793
|
+
const loop = async () => {
|
|
794
|
+
try {
|
|
795
|
+
if (!controller.signal.aborted) {
|
|
796
|
+
const initialResult = await (0, runtime_1.runDeck)({
|
|
797
|
+
path: resolvedDeckPath,
|
|
798
|
+
input: deckInput,
|
|
799
|
+
inputProvided: hasDeckInput,
|
|
800
|
+
modelProvider: opts.modelProvider,
|
|
801
|
+
defaultModel: opts.model,
|
|
802
|
+
modelOverride: opts.modelForce,
|
|
803
|
+
trace: tracer,
|
|
804
|
+
stream: false,
|
|
805
|
+
state: savedState,
|
|
806
|
+
allowRootStringInput: true,
|
|
807
|
+
initialUserMessage: initialUserMessage || undefined,
|
|
808
|
+
onStateUpdate: (state) => {
|
|
809
|
+
const nextMeta = {
|
|
810
|
+
...(savedState?.meta ?? {}),
|
|
811
|
+
...(state.meta ?? {}),
|
|
812
|
+
testBot: true,
|
|
813
|
+
testBotRunId: runId,
|
|
814
|
+
testBotConfigPath: botConfigPath,
|
|
815
|
+
testBotName,
|
|
816
|
+
};
|
|
817
|
+
const enriched = persistSessionState({
|
|
818
|
+
...state,
|
|
819
|
+
meta: nextMeta,
|
|
820
|
+
traces: capturedTraces,
|
|
821
|
+
});
|
|
822
|
+
savedState = enriched;
|
|
823
|
+
appendFromState(enriched);
|
|
824
|
+
},
|
|
825
|
+
});
|
|
826
|
+
if ((0, runtime_1.isGambitEndSignal)(initialResult)) {
|
|
827
|
+
sessionEnded = true;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
for (let turn = 0; turn < maxTurns; turn++) {
|
|
831
|
+
if (sessionEnded)
|
|
832
|
+
break;
|
|
833
|
+
if (controller.signal.aborted)
|
|
834
|
+
break;
|
|
835
|
+
const history = savedState?.messages ?? [];
|
|
836
|
+
const userMessage = await generateDeckBotUserMessage(history, {
|
|
837
|
+
onStreamText: (chunk) => broadcastTestBot({
|
|
838
|
+
type: "testBotStream",
|
|
839
|
+
runId,
|
|
840
|
+
role: "user",
|
|
841
|
+
chunk,
|
|
842
|
+
turn,
|
|
843
|
+
ts: Date.now(),
|
|
844
|
+
}),
|
|
845
|
+
});
|
|
846
|
+
broadcastTestBot({
|
|
847
|
+
type: "testBotStreamEnd",
|
|
848
|
+
runId,
|
|
849
|
+
role: "user",
|
|
850
|
+
turn,
|
|
851
|
+
ts: Date.now(),
|
|
852
|
+
});
|
|
853
|
+
if (!userMessage)
|
|
854
|
+
break;
|
|
855
|
+
const rootResult = await (0, runtime_1.runDeck)({
|
|
856
|
+
path: resolvedDeckPath,
|
|
857
|
+
input: deckInput,
|
|
858
|
+
inputProvided: hasDeckInput,
|
|
859
|
+
modelProvider: opts.modelProvider,
|
|
860
|
+
defaultModel: opts.model,
|
|
861
|
+
modelOverride: opts.modelForce,
|
|
862
|
+
trace: tracer,
|
|
863
|
+
stream: true,
|
|
864
|
+
state: savedState,
|
|
865
|
+
allowRootStringInput: true,
|
|
866
|
+
initialUserMessage: userMessage,
|
|
867
|
+
onStateUpdate: (state) => {
|
|
868
|
+
const nextMeta = {
|
|
869
|
+
...(savedState?.meta ?? {}),
|
|
870
|
+
...(state.meta ?? {}),
|
|
871
|
+
testBot: true,
|
|
872
|
+
testBotRunId: runId,
|
|
873
|
+
testBotConfigPath: botConfigPath,
|
|
874
|
+
testBotName,
|
|
875
|
+
};
|
|
876
|
+
const enriched = persistSessionState({
|
|
877
|
+
...state,
|
|
878
|
+
meta: nextMeta,
|
|
879
|
+
traces: capturedTraces,
|
|
880
|
+
});
|
|
881
|
+
savedState = enriched;
|
|
882
|
+
appendFromState(enriched);
|
|
883
|
+
},
|
|
884
|
+
onStreamText: (chunk) => broadcastTestBot({
|
|
885
|
+
type: "testBotStream",
|
|
886
|
+
runId,
|
|
887
|
+
role: "assistant",
|
|
888
|
+
chunk,
|
|
889
|
+
turn,
|
|
890
|
+
ts: Date.now(),
|
|
891
|
+
}),
|
|
892
|
+
});
|
|
893
|
+
if ((0, runtime_1.isGambitEndSignal)(rootResult)) {
|
|
894
|
+
sessionEnded = true;
|
|
895
|
+
break;
|
|
896
|
+
}
|
|
897
|
+
broadcastTestBot({
|
|
898
|
+
type: "testBotStreamEnd",
|
|
899
|
+
runId,
|
|
900
|
+
role: "assistant",
|
|
901
|
+
turn,
|
|
902
|
+
ts: Date.now(),
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
run.status = controller.signal.aborted ? "canceled" : "completed";
|
|
906
|
+
broadcastTestBot({ type: "testBotStatus", run });
|
|
907
|
+
}
|
|
908
|
+
catch (err) {
|
|
909
|
+
run.status = "error";
|
|
910
|
+
run.error = err instanceof Error ? err.message : String(err);
|
|
911
|
+
broadcastTestBot({ type: "testBotStatus", run });
|
|
912
|
+
}
|
|
913
|
+
finally {
|
|
914
|
+
if (savedState?.messages) {
|
|
915
|
+
const snapshot = buildTestBotSnapshot(savedState);
|
|
916
|
+
run.messages = snapshot.messages;
|
|
917
|
+
run.toolInserts = snapshot.toolInserts;
|
|
918
|
+
}
|
|
919
|
+
setSessionId(savedState);
|
|
920
|
+
run.traces = Array.isArray(savedState?.traces)
|
|
921
|
+
? [...(savedState?.traces ?? [])]
|
|
922
|
+
: undefined;
|
|
923
|
+
run.finishedAt = new Date().toISOString();
|
|
924
|
+
entry.abort = null;
|
|
925
|
+
entry.promise = null;
|
|
926
|
+
broadcastTestBot({ type: "testBotStatus", run });
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
entry.promise = loop();
|
|
930
|
+
broadcastTestBot({ type: "testBotStatus", run });
|
|
931
|
+
return run;
|
|
932
|
+
};
|
|
933
|
+
const deckLoadPromise = (0, loader_1.loadDeck)(resolvedDeckPath)
|
|
934
|
+
.then((deck) => {
|
|
935
|
+
resolvedDeckPath = deck.path;
|
|
936
|
+
deckSlug = deckSlugFromPath(resolvedDeckPath);
|
|
937
|
+
availableTestDecks = (deck.testDecks ?? []).map((testDeck, index) => {
|
|
938
|
+
const label = testDeck.label && typeof testDeck.label === "string"
|
|
939
|
+
? testDeck.label
|
|
940
|
+
: toDeckLabel(testDeck.path);
|
|
941
|
+
const id = testDeck.id && typeof testDeck.id === "string"
|
|
942
|
+
? testDeck.id
|
|
943
|
+
: slugify(`${label || "test-deck"}-${index}`);
|
|
944
|
+
return {
|
|
945
|
+
id,
|
|
946
|
+
label: label || id,
|
|
947
|
+
description: typeof testDeck.description === "string"
|
|
948
|
+
? testDeck.description
|
|
949
|
+
: undefined,
|
|
950
|
+
path: testDeck.path,
|
|
951
|
+
};
|
|
952
|
+
});
|
|
953
|
+
updateTestDeckRegistry(availableTestDecks);
|
|
954
|
+
availableGraderDecks = (deck.graderDecks ?? []).map((graderDeck, index) => {
|
|
955
|
+
const label = graderDeck.label && typeof graderDeck.label === "string"
|
|
956
|
+
? graderDeck.label
|
|
957
|
+
: toDeckLabel(graderDeck.path);
|
|
958
|
+
const id = graderDeck.id && typeof graderDeck.id === "string"
|
|
959
|
+
? graderDeck.id
|
|
960
|
+
: slugify(`${label || "grader-deck"}-${index}`);
|
|
961
|
+
return {
|
|
962
|
+
id,
|
|
963
|
+
label: label || id,
|
|
964
|
+
description: typeof graderDeck.description === "string"
|
|
965
|
+
? graderDeck.description
|
|
966
|
+
: undefined,
|
|
967
|
+
path: graderDeck.path,
|
|
968
|
+
};
|
|
969
|
+
});
|
|
970
|
+
updateGraderDeckRegistry(availableGraderDecks);
|
|
971
|
+
return deck;
|
|
972
|
+
})
|
|
973
|
+
.catch((err) => {
|
|
974
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
975
|
+
logger.warn(`[sim] failed to load deck: ${message}`);
|
|
976
|
+
availableTestDecks = [];
|
|
977
|
+
updateTestDeckRegistry(availableTestDecks);
|
|
978
|
+
availableGraderDecks = [];
|
|
979
|
+
updateGraderDeckRegistry(availableGraderDecks);
|
|
980
|
+
return null;
|
|
981
|
+
});
|
|
982
|
+
const schemaPromise = deckLoadPromise
|
|
983
|
+
.then((deck) => deck ? describeZodSchema(deck.inputSchema) : {
|
|
984
|
+
error: "Deck failed to load",
|
|
985
|
+
})
|
|
986
|
+
.catch((err) => {
|
|
987
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
988
|
+
logger.warn(`[sim] failed to load deck schema: ${message}`);
|
|
989
|
+
return { error: message };
|
|
990
|
+
});
|
|
991
|
+
const wantsSourceMap = Boolean(opts.sourceMap);
|
|
992
|
+
const bundlePlatform = opts.bundlePlatform ?? "deno";
|
|
993
|
+
const autoBundle = opts.autoBundle ?? true;
|
|
994
|
+
const needsBundle = !hasReactBundle() ||
|
|
995
|
+
(wantsSourceMap && !hasReactBundleSourceMap()) ||
|
|
996
|
+
isReactBundleStale();
|
|
997
|
+
const shouldAutoBundle = autoBundle && moduleLocation.isLocal && needsBundle;
|
|
998
|
+
if (autoBundle && !moduleLocation.isLocal && opts.verbose) {
|
|
999
|
+
logger.log("[sim] auto-bundle disabled for remote package; using packaged bundle.");
|
|
1000
|
+
}
|
|
1001
|
+
if (shouldAutoBundle) {
|
|
1002
|
+
try {
|
|
1003
|
+
const p = new dntShim.Deno.Command("deno", {
|
|
1004
|
+
args: [
|
|
1005
|
+
"bundle",
|
|
1006
|
+
"--platform",
|
|
1007
|
+
bundlePlatform,
|
|
1008
|
+
...(wantsSourceMap ? ["--sourcemap=external"] : []),
|
|
1009
|
+
"--output",
|
|
1010
|
+
"simulator-ui/dist/bundle.js",
|
|
1011
|
+
"simulator-ui/src/main.tsx",
|
|
1012
|
+
],
|
|
1013
|
+
cwd: path.resolve(moduleDir, ".."),
|
|
1014
|
+
stdout: "null",
|
|
1015
|
+
stderr: "null",
|
|
1016
|
+
});
|
|
1017
|
+
p.outputSync();
|
|
1018
|
+
}
|
|
1019
|
+
catch (err) {
|
|
1020
|
+
logger.warn(`[sim] auto-bundle failed: ${err instanceof Error ? err.message : err}`);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
const server = dntShim.Deno.serve({ port, signal: opts.signal, onListen: () => { } }, async (req) => {
|
|
1024
|
+
const url = new URL(req.url);
|
|
1025
|
+
if (url.pathname.startsWith("/api/durable-streams/stream/")) {
|
|
1026
|
+
return (0, durable_streams_js_1.handleDurableStreamRequest)(req);
|
|
1027
|
+
}
|
|
1028
|
+
if (url.pathname === "/api/calibrate") {
|
|
1029
|
+
if (req.method !== "GET") {
|
|
1030
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1031
|
+
}
|
|
1032
|
+
await deckLoadPromise.catch(() => null);
|
|
1033
|
+
const sessions = listSessions();
|
|
1034
|
+
return new Response(JSON.stringify({
|
|
1035
|
+
graderDecks: availableGraderDecks,
|
|
1036
|
+
sessions,
|
|
1037
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1038
|
+
}
|
|
1039
|
+
if (url.pathname === "/api/calibrate/run") {
|
|
1040
|
+
if (req.method !== "POST") {
|
|
1041
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1042
|
+
}
|
|
1043
|
+
try {
|
|
1044
|
+
const body = await req.json();
|
|
1045
|
+
if (!body.sessionId) {
|
|
1046
|
+
throw new Error("Missing sessionId");
|
|
1047
|
+
}
|
|
1048
|
+
const sessionId = body.sessionId;
|
|
1049
|
+
await deckLoadPromise.catch(() => null);
|
|
1050
|
+
const grader = body.graderId
|
|
1051
|
+
? resolveGraderDeck(body.graderId)
|
|
1052
|
+
: availableGraderDecks[0];
|
|
1053
|
+
if (!grader) {
|
|
1054
|
+
throw new Error("Unknown grader deck selection");
|
|
1055
|
+
}
|
|
1056
|
+
const sessionState = readSessionState(sessionId);
|
|
1057
|
+
if (!sessionState) {
|
|
1058
|
+
throw new Error("Session not found");
|
|
1059
|
+
}
|
|
1060
|
+
const graderSchema = await describeDeckInputSchemaFromPath(grader.path);
|
|
1061
|
+
const runMode = schemaHasField(graderSchema.schema, "messageToGrade")
|
|
1062
|
+
? "turns"
|
|
1063
|
+
: "conversation";
|
|
1064
|
+
const metaForGrading = (() => {
|
|
1065
|
+
const rawMeta = sessionState.meta;
|
|
1066
|
+
if (!rawMeta || typeof rawMeta !== "object")
|
|
1067
|
+
return undefined;
|
|
1068
|
+
const next = { ...rawMeta };
|
|
1069
|
+
delete next.calibrationRuns;
|
|
1070
|
+
delete next.gradingRuns;
|
|
1071
|
+
return next;
|
|
1072
|
+
})();
|
|
1073
|
+
const sessionPayload = {
|
|
1074
|
+
messages: Array.isArray(sessionState.messages)
|
|
1075
|
+
? sessionState.messages.map((msg) => ({
|
|
1076
|
+
role: msg.role,
|
|
1077
|
+
content: msg.content,
|
|
1078
|
+
name: msg.name,
|
|
1079
|
+
}))
|
|
1080
|
+
: undefined,
|
|
1081
|
+
meta: metaForGrading,
|
|
1082
|
+
notes: sessionState.notes
|
|
1083
|
+
? { text: sessionState.notes.text }
|
|
1084
|
+
: undefined,
|
|
1085
|
+
};
|
|
1086
|
+
const startedAt = new Date().toISOString();
|
|
1087
|
+
const runId = randomId("cal");
|
|
1088
|
+
let entry;
|
|
1089
|
+
const upsertCalibrationRun = (state, nextEntry) => {
|
|
1090
|
+
const previousRuns = Array.isArray(state.meta?.gradingRuns)
|
|
1091
|
+
? (state.meta
|
|
1092
|
+
.gradingRuns)
|
|
1093
|
+
: Array.isArray(state.meta?.calibrationRuns)
|
|
1094
|
+
? state.meta?.calibrationRuns
|
|
1095
|
+
: [];
|
|
1096
|
+
const index = previousRuns.findIndex((run) => run.id === nextEntry.id);
|
|
1097
|
+
const nextRuns = index >= 0
|
|
1098
|
+
? previousRuns.map((run, i) => (i === index ? nextEntry : run))
|
|
1099
|
+
: [...previousRuns, nextEntry];
|
|
1100
|
+
const nextState = persistSessionState({
|
|
1101
|
+
...state,
|
|
1102
|
+
meta: {
|
|
1103
|
+
...(state.meta ?? {}),
|
|
1104
|
+
gradingRuns: nextRuns,
|
|
1105
|
+
},
|
|
1106
|
+
});
|
|
1107
|
+
const sessionMeta = buildSessionMeta(sessionId, nextState);
|
|
1108
|
+
(0, durable_streams_js_1.appendDurableStreamEvent)(CALIBRATE_STREAM_ID, {
|
|
1109
|
+
type: "calibrateSession",
|
|
1110
|
+
sessionId,
|
|
1111
|
+
run: nextEntry,
|
|
1112
|
+
session: sessionMeta,
|
|
1113
|
+
});
|
|
1114
|
+
return nextState;
|
|
1115
|
+
};
|
|
1116
|
+
let currentState = sessionState;
|
|
1117
|
+
try {
|
|
1118
|
+
const result = await (async () => {
|
|
1119
|
+
if (runMode !== "turns") {
|
|
1120
|
+
return await runDeckWithFallback({
|
|
1121
|
+
path: grader.path,
|
|
1122
|
+
input: { session: sessionPayload },
|
|
1123
|
+
inputProvided: true,
|
|
1124
|
+
modelProvider: opts.modelProvider,
|
|
1125
|
+
allowRootStringInput: false,
|
|
1126
|
+
initialUserMessage: undefined,
|
|
1127
|
+
stream: false,
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
const messages = sessionPayload.messages ?? [];
|
|
1131
|
+
const assistantTurns = messages
|
|
1132
|
+
.map((msg, idx) => ({ msg, idx }))
|
|
1133
|
+
.filter(({ msg }) => msg.role === "assistant" &&
|
|
1134
|
+
typeof msg.content === "string" &&
|
|
1135
|
+
msg.content.trim().length > 0);
|
|
1136
|
+
const turns = [];
|
|
1137
|
+
entry = {
|
|
1138
|
+
id: runId,
|
|
1139
|
+
graderId: grader.id,
|
|
1140
|
+
graderPath: grader.path,
|
|
1141
|
+
graderLabel: grader.label,
|
|
1142
|
+
status: "running",
|
|
1143
|
+
runAt: startedAt,
|
|
1144
|
+
result: { mode: "turns", turns: [] },
|
|
1145
|
+
};
|
|
1146
|
+
currentState = upsertCalibrationRun(currentState, entry);
|
|
1147
|
+
if (assistantTurns.length === 0) {
|
|
1148
|
+
return { mode: "turns", turns: [] };
|
|
1149
|
+
}
|
|
1150
|
+
for (const { msg, idx } of assistantTurns) {
|
|
1151
|
+
const input = {
|
|
1152
|
+
session: {
|
|
1153
|
+
...sessionPayload,
|
|
1154
|
+
messages: messages.slice(0, idx + 1),
|
|
1155
|
+
},
|
|
1156
|
+
messageToGrade: msg,
|
|
1157
|
+
};
|
|
1158
|
+
const turnResult = await runDeckWithFallback({
|
|
1159
|
+
path: grader.path,
|
|
1160
|
+
input,
|
|
1161
|
+
inputProvided: true,
|
|
1162
|
+
modelProvider: opts.modelProvider,
|
|
1163
|
+
allowRootStringInput: false,
|
|
1164
|
+
initialUserMessage: undefined,
|
|
1165
|
+
stream: false,
|
|
1166
|
+
});
|
|
1167
|
+
turns.push({
|
|
1168
|
+
index: idx,
|
|
1169
|
+
message: msg,
|
|
1170
|
+
input,
|
|
1171
|
+
result: turnResult,
|
|
1172
|
+
});
|
|
1173
|
+
entry = {
|
|
1174
|
+
...entry,
|
|
1175
|
+
result: { mode: "turns", turns: [...turns] },
|
|
1176
|
+
};
|
|
1177
|
+
currentState = upsertCalibrationRun(currentState, entry);
|
|
1178
|
+
}
|
|
1179
|
+
return { mode: "turns", turns };
|
|
1180
|
+
})();
|
|
1181
|
+
entry = {
|
|
1182
|
+
id: runId,
|
|
1183
|
+
graderId: grader.id,
|
|
1184
|
+
graderPath: grader.path,
|
|
1185
|
+
graderLabel: grader.label,
|
|
1186
|
+
status: "completed",
|
|
1187
|
+
runAt: startedAt,
|
|
1188
|
+
input: { session: sessionPayload },
|
|
1189
|
+
result,
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
catch (err) {
|
|
1193
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1194
|
+
entry = {
|
|
1195
|
+
id: runId,
|
|
1196
|
+
graderId: grader.id,
|
|
1197
|
+
graderPath: grader.path,
|
|
1198
|
+
graderLabel: grader.label,
|
|
1199
|
+
status: "error",
|
|
1200
|
+
runAt: startedAt,
|
|
1201
|
+
input: { session: sessionPayload },
|
|
1202
|
+
error: message,
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
const nextState = upsertCalibrationRun(currentState, entry);
|
|
1206
|
+
const sessionMeta = buildSessionMeta(body.sessionId, nextState);
|
|
1207
|
+
return new Response(JSON.stringify({
|
|
1208
|
+
sessionId: body.sessionId,
|
|
1209
|
+
run: entry,
|
|
1210
|
+
session: sessionMeta,
|
|
1211
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1212
|
+
}
|
|
1213
|
+
catch (err) {
|
|
1214
|
+
return new Response(JSON.stringify({
|
|
1215
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1216
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
if (url.pathname === "/api/grading/reference") {
|
|
1220
|
+
if (req.method !== "POST") {
|
|
1221
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1222
|
+
}
|
|
1223
|
+
try {
|
|
1224
|
+
const body = await req.json();
|
|
1225
|
+
if (!body.sessionId)
|
|
1226
|
+
throw new Error("Missing sessionId");
|
|
1227
|
+
if (!body.runId)
|
|
1228
|
+
throw new Error("Missing runId");
|
|
1229
|
+
if (!body.referenceSample) {
|
|
1230
|
+
throw new Error("Missing referenceSample");
|
|
1231
|
+
}
|
|
1232
|
+
const score = body.referenceSample.score;
|
|
1233
|
+
if (typeof score !== "number" || Number.isNaN(score)) {
|
|
1234
|
+
throw new Error("Invalid reference score");
|
|
1235
|
+
}
|
|
1236
|
+
const reason = body.referenceSample.reason;
|
|
1237
|
+
if (typeof reason !== "string" || reason.trim().length === 0) {
|
|
1238
|
+
throw new Error("Missing reference reason");
|
|
1239
|
+
}
|
|
1240
|
+
const evidence = Array.isArray(body.referenceSample.evidence)
|
|
1241
|
+
? body.referenceSample.evidence.filter((e) => typeof e === "string" && e.trim().length > 0)
|
|
1242
|
+
: undefined;
|
|
1243
|
+
const state = readSessionState(body.sessionId);
|
|
1244
|
+
if (!state)
|
|
1245
|
+
throw new Error("Session not found");
|
|
1246
|
+
const previousRuns = Array.isArray(state.meta?.gradingRuns)
|
|
1247
|
+
? (state.meta
|
|
1248
|
+
.gradingRuns)
|
|
1249
|
+
: Array.isArray(state.meta?.calibrationRuns)
|
|
1250
|
+
? state.meta?.calibrationRuns
|
|
1251
|
+
: [];
|
|
1252
|
+
const index = previousRuns.findIndex((run) => run.id === body.runId);
|
|
1253
|
+
if (index < 0)
|
|
1254
|
+
throw new Error("Run not found");
|
|
1255
|
+
const run = previousRuns[index];
|
|
1256
|
+
const nextRun = {
|
|
1257
|
+
...run,
|
|
1258
|
+
};
|
|
1259
|
+
if (typeof body.turnIndex === "number") {
|
|
1260
|
+
const result = run.result;
|
|
1261
|
+
const turnIndex = body.turnIndex;
|
|
1262
|
+
if (!result || typeof result !== "object" ||
|
|
1263
|
+
result.mode !== "turns" ||
|
|
1264
|
+
!Array.isArray(result.turns)) {
|
|
1265
|
+
throw new Error("Run does not support turn references");
|
|
1266
|
+
}
|
|
1267
|
+
const turns = result.turns.map((turn) => ({ ...turn }));
|
|
1268
|
+
const targetIndex = turns.findIndex((turn) => turn.index === turnIndex);
|
|
1269
|
+
if (targetIndex < 0) {
|
|
1270
|
+
throw new Error("Turn not found");
|
|
1271
|
+
}
|
|
1272
|
+
turns[targetIndex] = {
|
|
1273
|
+
...turns[targetIndex],
|
|
1274
|
+
referenceSample: { score, reason, evidence },
|
|
1275
|
+
};
|
|
1276
|
+
nextRun.result = { ...result, turns };
|
|
1277
|
+
}
|
|
1278
|
+
else {
|
|
1279
|
+
nextRun.referenceSample = { score, reason, evidence };
|
|
1280
|
+
}
|
|
1281
|
+
const nextRuns = previousRuns.map((entry, i) => i === index ? nextRun : entry);
|
|
1282
|
+
const nextState = persistSessionState({
|
|
1283
|
+
...state,
|
|
1284
|
+
meta: {
|
|
1285
|
+
...(state.meta ?? {}),
|
|
1286
|
+
gradingRuns: nextRuns,
|
|
1287
|
+
},
|
|
1288
|
+
});
|
|
1289
|
+
const sessionMeta = buildSessionMeta(body.sessionId, nextState);
|
|
1290
|
+
(0, durable_streams_js_1.appendDurableStreamEvent)(CALIBRATE_STREAM_ID, {
|
|
1291
|
+
type: "calibrateSession",
|
|
1292
|
+
sessionId: body.sessionId,
|
|
1293
|
+
run: nextRun,
|
|
1294
|
+
session: sessionMeta,
|
|
1295
|
+
});
|
|
1296
|
+
return new Response(JSON.stringify({
|
|
1297
|
+
sessionId: body.sessionId,
|
|
1298
|
+
run: nextRun,
|
|
1299
|
+
session: sessionMeta,
|
|
1300
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1301
|
+
}
|
|
1302
|
+
catch (err) {
|
|
1303
|
+
return new Response(JSON.stringify({
|
|
1304
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1305
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
if (url.pathname === "/api/test-bot") {
|
|
1309
|
+
if (req.method === "GET") {
|
|
1310
|
+
await deckLoadPromise.catch(() => null);
|
|
1311
|
+
const requestedDeck = url.searchParams.get("deckPath");
|
|
1312
|
+
const selection = requestedDeck
|
|
1313
|
+
? resolveTestDeck(requestedDeck)
|
|
1314
|
+
: availableTestDecks[0];
|
|
1315
|
+
if (requestedDeck && !selection) {
|
|
1316
|
+
return new Response(JSON.stringify({
|
|
1317
|
+
error: "Unknown test deck selection",
|
|
1318
|
+
}), {
|
|
1319
|
+
status: 400,
|
|
1320
|
+
headers: { "content-type": "application/json" },
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
if (selection) {
|
|
1324
|
+
const schemaDesc = await describeDeckInputSchemaFromPath(selection.path);
|
|
1325
|
+
return new Response(JSON.stringify({
|
|
1326
|
+
botPath: selection.path,
|
|
1327
|
+
botLabel: selection.label,
|
|
1328
|
+
botDescription: selection.description,
|
|
1329
|
+
selectedDeckId: selection.id,
|
|
1330
|
+
inputSchema: schemaDesc.schema,
|
|
1331
|
+
inputSchemaError: schemaDesc.error,
|
|
1332
|
+
defaults: { input: schemaDesc.defaults },
|
|
1333
|
+
testDecks: availableTestDecks,
|
|
1334
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1335
|
+
}
|
|
1336
|
+
return new Response(JSON.stringify({
|
|
1337
|
+
botPath: null,
|
|
1338
|
+
botLabel: null,
|
|
1339
|
+
botDescription: null,
|
|
1340
|
+
selectedDeckId: null,
|
|
1341
|
+
inputSchema: null,
|
|
1342
|
+
inputSchemaError: null,
|
|
1343
|
+
defaults: {},
|
|
1344
|
+
testDecks: availableTestDecks,
|
|
1345
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1346
|
+
}
|
|
1347
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1348
|
+
}
|
|
1349
|
+
if (url.pathname === "/api/test-bot/run") {
|
|
1350
|
+
if (req.method !== "POST") {
|
|
1351
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1352
|
+
}
|
|
1353
|
+
let maxTurnsOverride = undefined;
|
|
1354
|
+
let deckInput = undefined;
|
|
1355
|
+
let botInput = undefined;
|
|
1356
|
+
let initialUserMessage = undefined;
|
|
1357
|
+
let botDeckSelection;
|
|
1358
|
+
try {
|
|
1359
|
+
const body = await req.json();
|
|
1360
|
+
if (typeof body.maxTurns === "number" && Number.isFinite(body.maxTurns)) {
|
|
1361
|
+
maxTurnsOverride = body.maxTurns;
|
|
1362
|
+
}
|
|
1363
|
+
deckInput = body.init;
|
|
1364
|
+
botInput = body.botInput;
|
|
1365
|
+
await deckLoadPromise.catch(() => null);
|
|
1366
|
+
if (typeof body.botDeckPath === "string") {
|
|
1367
|
+
const resolved = resolveTestDeck(body.botDeckPath);
|
|
1368
|
+
if (!resolved) {
|
|
1369
|
+
return new Response(JSON.stringify({ error: "Unknown test deck selection" }), {
|
|
1370
|
+
status: 400,
|
|
1371
|
+
headers: { "content-type": "application/json" },
|
|
1372
|
+
});
|
|
1373
|
+
}
|
|
1374
|
+
botDeckSelection = resolved;
|
|
1375
|
+
}
|
|
1376
|
+
else if (!body.botDeckPath && availableTestDecks.length > 0) {
|
|
1377
|
+
botDeckSelection = availableTestDecks[0];
|
|
1378
|
+
}
|
|
1379
|
+
if (typeof body.initialUserMessage === "string" &&
|
|
1380
|
+
body.initialUserMessage.trim().length > 0) {
|
|
1381
|
+
initialUserMessage = body.initialUserMessage;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
catch {
|
|
1385
|
+
// ignore parse errors; use defaults
|
|
1386
|
+
}
|
|
1387
|
+
if (deckInput === undefined) {
|
|
1388
|
+
try {
|
|
1389
|
+
const desc = await schemaPromise;
|
|
1390
|
+
deckInput = desc.defaults !== undefined
|
|
1391
|
+
? desc.defaults
|
|
1392
|
+
: deriveInitialFromSchema(desc.schema);
|
|
1393
|
+
}
|
|
1394
|
+
catch {
|
|
1395
|
+
// ignore; keep undefined
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
if (!botDeckSelection) {
|
|
1399
|
+
return new Response(JSON.stringify({ error: "No test decks configured" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
1400
|
+
}
|
|
1401
|
+
const run = startTestBotRun({
|
|
1402
|
+
maxTurnsOverride,
|
|
1403
|
+
deckInput,
|
|
1404
|
+
botInput,
|
|
1405
|
+
initialUserMessage,
|
|
1406
|
+
botDeckPath: botDeckSelection.path,
|
|
1407
|
+
});
|
|
1408
|
+
return new Response(JSON.stringify({ run }), { headers: { "content-type": "application/json" } });
|
|
1409
|
+
}
|
|
1410
|
+
if (url.pathname === "/api/test-bot/status") {
|
|
1411
|
+
const runId = url.searchParams.get("runId") ?? undefined;
|
|
1412
|
+
const sessionId = url.searchParams.get("sessionId") ?? undefined;
|
|
1413
|
+
let entry = runId ? testBotRuns.get(runId) : undefined;
|
|
1414
|
+
if (!entry && sessionId) {
|
|
1415
|
+
for (const candidate of testBotRuns.values()) {
|
|
1416
|
+
if (candidate.run.sessionId === sessionId) {
|
|
1417
|
+
entry = candidate;
|
|
1418
|
+
break;
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
const run = entry?.run ?? {
|
|
1423
|
+
id: runId ?? "",
|
|
1424
|
+
status: "idle",
|
|
1425
|
+
messages: [],
|
|
1426
|
+
traces: [],
|
|
1427
|
+
toolInserts: [],
|
|
1428
|
+
sessionId,
|
|
1429
|
+
};
|
|
1430
|
+
if (!entry && sessionId) {
|
|
1431
|
+
const state = readSessionState(sessionId);
|
|
1432
|
+
if (state) {
|
|
1433
|
+
run.id = typeof state.runId === "string" ? state.runId : run.id;
|
|
1434
|
+
run.status = "completed";
|
|
1435
|
+
syncTestBotRunFromState(run, state);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
if (run.sessionId) {
|
|
1439
|
+
const state = readSessionState(run.sessionId);
|
|
1440
|
+
if (state) {
|
|
1441
|
+
syncTestBotRunFromState(run, state);
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
await deckLoadPromise.catch(() => null);
|
|
1445
|
+
const requestedDeck = url.searchParams.get("deckPath");
|
|
1446
|
+
const selection = requestedDeck
|
|
1447
|
+
? resolveTestDeck(requestedDeck)
|
|
1448
|
+
: availableTestDecks[0];
|
|
1449
|
+
if (requestedDeck && !selection) {
|
|
1450
|
+
return new Response(JSON.stringify({
|
|
1451
|
+
error: "Unknown test deck selection",
|
|
1452
|
+
}), {
|
|
1453
|
+
status: 400,
|
|
1454
|
+
headers: { "content-type": "application/json" },
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
if (selection) {
|
|
1458
|
+
const schemaDesc = await describeDeckInputSchemaFromPath(selection.path);
|
|
1459
|
+
return new Response(JSON.stringify({
|
|
1460
|
+
run,
|
|
1461
|
+
botPath: selection.path,
|
|
1462
|
+
botLabel: selection.label,
|
|
1463
|
+
botDescription: selection.description,
|
|
1464
|
+
selectedDeckId: selection.id,
|
|
1465
|
+
inputSchema: schemaDesc.schema,
|
|
1466
|
+
inputSchemaError: schemaDesc.error,
|
|
1467
|
+
defaults: { input: schemaDesc.defaults },
|
|
1468
|
+
testDecks: availableTestDecks,
|
|
1469
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1470
|
+
}
|
|
1471
|
+
return new Response(JSON.stringify({
|
|
1472
|
+
run,
|
|
1473
|
+
botPath: null,
|
|
1474
|
+
botLabel: null,
|
|
1475
|
+
botDescription: null,
|
|
1476
|
+
selectedDeckId: null,
|
|
1477
|
+
inputSchema: null,
|
|
1478
|
+
inputSchemaError: null,
|
|
1479
|
+
defaults: {},
|
|
1480
|
+
testDecks: availableTestDecks,
|
|
1481
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1482
|
+
}
|
|
1483
|
+
if (url.pathname === "/api/test-bot/stop") {
|
|
1484
|
+
if (req.method !== "POST") {
|
|
1485
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1486
|
+
}
|
|
1487
|
+
let runId = undefined;
|
|
1488
|
+
try {
|
|
1489
|
+
const body = await req.json();
|
|
1490
|
+
if (typeof body.runId === "string")
|
|
1491
|
+
runId = body.runId;
|
|
1492
|
+
}
|
|
1493
|
+
catch {
|
|
1494
|
+
// ignore
|
|
1495
|
+
}
|
|
1496
|
+
const entry = runId ? testBotRuns.get(runId) : undefined;
|
|
1497
|
+
const wasRunning = Boolean(entry?.promise);
|
|
1498
|
+
if (entry?.abort) {
|
|
1499
|
+
entry.abort.abort();
|
|
1500
|
+
}
|
|
1501
|
+
return new Response(JSON.stringify({
|
|
1502
|
+
stopped: wasRunning,
|
|
1503
|
+
run: entry?.run ?? {
|
|
1504
|
+
id: runId ?? "",
|
|
1505
|
+
status: "idle",
|
|
1506
|
+
messages: [],
|
|
1507
|
+
traces: [],
|
|
1508
|
+
toolInserts: [],
|
|
1509
|
+
},
|
|
1510
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1511
|
+
}
|
|
1512
|
+
if (url.pathname === "/api/simulator/run") {
|
|
1513
|
+
if (req.method !== "POST") {
|
|
1514
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1515
|
+
}
|
|
1516
|
+
if (simulatorRunning) {
|
|
1517
|
+
emitSimulator({ type: "error", message: "Run already in progress" });
|
|
1518
|
+
return new Response(JSON.stringify({ error: "Run already in progress" }), { status: 409, headers: { "content-type": "application/json" } });
|
|
1519
|
+
}
|
|
1520
|
+
let payload = {};
|
|
1521
|
+
try {
|
|
1522
|
+
payload = await req.json();
|
|
1523
|
+
}
|
|
1524
|
+
catch {
|
|
1525
|
+
// ignore parse errors
|
|
1526
|
+
}
|
|
1527
|
+
if (payload.resetState) {
|
|
1528
|
+
simulatorSavedState = undefined;
|
|
1529
|
+
simulatorCapturedTraces = [];
|
|
1530
|
+
simulatorCurrentRunId = undefined;
|
|
1531
|
+
}
|
|
1532
|
+
if (payload.sessionId) {
|
|
1533
|
+
const loaded = readSessionState(payload.sessionId);
|
|
1534
|
+
if (loaded) {
|
|
1535
|
+
simulatorSavedState = loaded;
|
|
1536
|
+
simulatorCapturedTraces = Array.isArray(loaded.traces)
|
|
1537
|
+
? cloneTraces(loaded.traces)
|
|
1538
|
+
: [];
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
simulatorCurrentRunId = undefined;
|
|
1542
|
+
const stream = payload.stream ?? true;
|
|
1543
|
+
const forwardTrace = payload.trace ?? true;
|
|
1544
|
+
const tracer = (event) => {
|
|
1545
|
+
const stamped = event.ts ? event : { ...event, ts: Date.now() };
|
|
1546
|
+
if (stamped.type === "run.start") {
|
|
1547
|
+
simulatorCurrentRunId = stamped.runId;
|
|
1548
|
+
}
|
|
1549
|
+
simulatorCapturedTraces.push(stamped);
|
|
1550
|
+
consoleTracer?.(stamped);
|
|
1551
|
+
if (forwardTrace)
|
|
1552
|
+
emitSimulator({ type: "trace", event: stamped });
|
|
1553
|
+
};
|
|
1554
|
+
let initialUserMessage = typeof payload.message === "string"
|
|
1555
|
+
? payload.message
|
|
1556
|
+
: undefined;
|
|
1557
|
+
let input = payload.input;
|
|
1558
|
+
let inputProvided = payload.input !== undefined;
|
|
1559
|
+
const hasSavedMessages = (simulatorSavedState?.messages?.length ?? 0) > 0;
|
|
1560
|
+
if (initialUserMessage === undefined &&
|
|
1561
|
+
input !== undefined &&
|
|
1562
|
+
hasSavedMessages) {
|
|
1563
|
+
initialUserMessage = input;
|
|
1564
|
+
input = undefined;
|
|
1565
|
+
inputProvided = false;
|
|
1566
|
+
}
|
|
1567
|
+
if (opts.verbose) {
|
|
1568
|
+
logger.log(`[sim] starting run runId=${simulatorSavedState?.runId ?? "(new)"} messages=${simulatorSavedState?.messages?.length ?? 0} stream=${stream}`);
|
|
1569
|
+
}
|
|
1570
|
+
simulatorRunning = true;
|
|
1571
|
+
try {
|
|
1572
|
+
const result = await (0, runtime_1.runDeck)({
|
|
1573
|
+
path: resolvedDeckPath,
|
|
1574
|
+
input,
|
|
1575
|
+
inputProvided,
|
|
1576
|
+
modelProvider: opts.modelProvider,
|
|
1577
|
+
isRoot: true,
|
|
1578
|
+
allowRootStringInput: true,
|
|
1579
|
+
defaultModel: payload.model ?? opts.model,
|
|
1580
|
+
modelOverride: payload.modelForce ?? opts.modelForce,
|
|
1581
|
+
trace: tracer,
|
|
1582
|
+
stream,
|
|
1583
|
+
state: simulatorSavedState,
|
|
1584
|
+
onStateUpdate: (state) => {
|
|
1585
|
+
const nextMeta = {
|
|
1586
|
+
...(simulatorSavedState?.meta ?? {}),
|
|
1587
|
+
...(state.meta ?? {}),
|
|
1588
|
+
};
|
|
1589
|
+
const enrichedState = persistSessionState({
|
|
1590
|
+
...state,
|
|
1591
|
+
meta: nextMeta,
|
|
1592
|
+
notes: state.notes ?? simulatorSavedState?.notes,
|
|
1593
|
+
conversationScore: state.conversationScore ??
|
|
1594
|
+
simulatorSavedState?.conversationScore,
|
|
1595
|
+
traces: simulatorCapturedTraces,
|
|
1596
|
+
});
|
|
1597
|
+
simulatorSavedState = enrichedState;
|
|
1598
|
+
emitSimulator({ type: "state", state: enrichedState });
|
|
1599
|
+
},
|
|
1600
|
+
initialUserMessage,
|
|
1601
|
+
onStreamText: (chunk) => emitSimulator({
|
|
1602
|
+
type: "stream",
|
|
1603
|
+
chunk,
|
|
1604
|
+
runId: simulatorCurrentRunId,
|
|
1605
|
+
}),
|
|
1606
|
+
});
|
|
1607
|
+
emitSimulator({
|
|
1608
|
+
type: "result",
|
|
1609
|
+
result,
|
|
1610
|
+
runId: simulatorCurrentRunId,
|
|
1611
|
+
streamed: stream,
|
|
1612
|
+
});
|
|
1613
|
+
return new Response(JSON.stringify({
|
|
1614
|
+
runId: simulatorCurrentRunId,
|
|
1615
|
+
sessionId: simulatorSavedState?.meta?.sessionId,
|
|
1616
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1617
|
+
}
|
|
1618
|
+
catch (err) {
|
|
1619
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1620
|
+
emitSimulator({
|
|
1621
|
+
type: "error",
|
|
1622
|
+
message,
|
|
1623
|
+
runId: simulatorCurrentRunId,
|
|
1624
|
+
});
|
|
1625
|
+
return new Response(JSON.stringify({ error: message }), { status: 400, headers: { "content-type": "application/json" } });
|
|
1626
|
+
}
|
|
1627
|
+
finally {
|
|
1628
|
+
simulatorRunning = false;
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
if (url.pathname === "/api/simulator/feedback") {
|
|
1632
|
+
if (req.method !== "POST") {
|
|
1633
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1634
|
+
}
|
|
1635
|
+
try {
|
|
1636
|
+
const body = await req.json();
|
|
1637
|
+
if (!body.sessionId) {
|
|
1638
|
+
throw new Error("Missing sessionId");
|
|
1639
|
+
}
|
|
1640
|
+
if (!body.messageRefId) {
|
|
1641
|
+
throw new Error("Missing messageRefId");
|
|
1642
|
+
}
|
|
1643
|
+
if (typeof body.score !== "number" || Number.isNaN(body.score)) {
|
|
1644
|
+
throw new Error("Invalid score");
|
|
1645
|
+
}
|
|
1646
|
+
const state = readSessionState(body.sessionId);
|
|
1647
|
+
if (!state)
|
|
1648
|
+
throw new Error("Session not found");
|
|
1649
|
+
simulatorSavedState = state;
|
|
1650
|
+
simulatorCapturedTraces = Array.isArray(state.traces)
|
|
1651
|
+
? cloneTraces(state.traces)
|
|
1652
|
+
: [];
|
|
1653
|
+
const clamped = Math.max(-3, Math.min(3, Math.round(body.score)));
|
|
1654
|
+
const reason = typeof body.reason === "string"
|
|
1655
|
+
? body.reason
|
|
1656
|
+
: undefined;
|
|
1657
|
+
const runId = typeof state.runId === "string" ? state.runId : "run";
|
|
1658
|
+
const existing = state.feedback ?? [];
|
|
1659
|
+
const idx = existing.findIndex((f) => f.messageRefId === body.messageRefId);
|
|
1660
|
+
const now = new Date().toISOString();
|
|
1661
|
+
const entry = idx >= 0
|
|
1662
|
+
? {
|
|
1663
|
+
...existing[idx],
|
|
1664
|
+
score: clamped,
|
|
1665
|
+
reason,
|
|
1666
|
+
runId: existing[idx].runId ?? runId,
|
|
1667
|
+
}
|
|
1668
|
+
: {
|
|
1669
|
+
id: randomId("fb"),
|
|
1670
|
+
runId,
|
|
1671
|
+
messageRefId: body.messageRefId,
|
|
1672
|
+
score: clamped,
|
|
1673
|
+
reason,
|
|
1674
|
+
createdAt: now,
|
|
1675
|
+
};
|
|
1676
|
+
const feedback = idx >= 0
|
|
1677
|
+
? existing.map((f, i) => i === idx ? entry : f)
|
|
1678
|
+
: [...existing, entry];
|
|
1679
|
+
const enriched = persistSessionState({
|
|
1680
|
+
...state,
|
|
1681
|
+
feedback,
|
|
1682
|
+
traces: simulatorCapturedTraces,
|
|
1683
|
+
});
|
|
1684
|
+
simulatorSavedState = enriched;
|
|
1685
|
+
emitSimulator({ type: "state", state: enriched });
|
|
1686
|
+
return new Response(JSON.stringify({ feedback: entry }), { headers: { "content-type": "application/json" } });
|
|
1687
|
+
}
|
|
1688
|
+
catch (err) {
|
|
1689
|
+
return new Response(JSON.stringify({
|
|
1690
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1691
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
if (url.pathname === "/api/simulator/notes") {
|
|
1695
|
+
if (req.method !== "POST") {
|
|
1696
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1697
|
+
}
|
|
1698
|
+
try {
|
|
1699
|
+
const body = await req.json();
|
|
1700
|
+
if (!body.sessionId) {
|
|
1701
|
+
throw new Error("Missing sessionId");
|
|
1702
|
+
}
|
|
1703
|
+
const state = readSessionState(body.sessionId);
|
|
1704
|
+
if (!state)
|
|
1705
|
+
throw new Error("Session not found");
|
|
1706
|
+
simulatorSavedState = state;
|
|
1707
|
+
simulatorCapturedTraces = Array.isArray(state.traces)
|
|
1708
|
+
? cloneTraces(state.traces)
|
|
1709
|
+
: [];
|
|
1710
|
+
const now = new Date().toISOString();
|
|
1711
|
+
const enriched = persistSessionState({
|
|
1712
|
+
...state,
|
|
1713
|
+
notes: { text: body.text ?? "", updatedAt: now },
|
|
1714
|
+
traces: simulatorCapturedTraces,
|
|
1715
|
+
});
|
|
1716
|
+
simulatorSavedState = enriched;
|
|
1717
|
+
emitSimulator({ type: "state", state: enriched });
|
|
1718
|
+
return new Response(JSON.stringify({ notes: enriched.notes, saved: true }), { headers: { "content-type": "application/json" } });
|
|
1719
|
+
}
|
|
1720
|
+
catch (err) {
|
|
1721
|
+
return new Response(JSON.stringify({
|
|
1722
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1723
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
if (url.pathname === "/api/simulator/conversation-score") {
|
|
1727
|
+
if (req.method !== "POST") {
|
|
1728
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1729
|
+
}
|
|
1730
|
+
try {
|
|
1731
|
+
const body = await req.json();
|
|
1732
|
+
if (!body.sessionId) {
|
|
1733
|
+
throw new Error("Missing sessionId");
|
|
1734
|
+
}
|
|
1735
|
+
if (typeof body.score !== "number" || Number.isNaN(body.score)) {
|
|
1736
|
+
throw new Error("Invalid score");
|
|
1737
|
+
}
|
|
1738
|
+
const state = readSessionState(body.sessionId);
|
|
1739
|
+
if (!state)
|
|
1740
|
+
throw new Error("Session not found");
|
|
1741
|
+
simulatorSavedState = state;
|
|
1742
|
+
simulatorCapturedTraces = Array.isArray(state.traces)
|
|
1743
|
+
? cloneTraces(state.traces)
|
|
1744
|
+
: [];
|
|
1745
|
+
const clamped = Math.max(-3, Math.min(3, Math.round(body.score)));
|
|
1746
|
+
const now = new Date().toISOString();
|
|
1747
|
+
const enriched = persistSessionState({
|
|
1748
|
+
...state,
|
|
1749
|
+
conversationScore: { score: clamped, updatedAt: now },
|
|
1750
|
+
traces: simulatorCapturedTraces,
|
|
1751
|
+
});
|
|
1752
|
+
simulatorSavedState = enriched;
|
|
1753
|
+
emitSimulator({ type: "state", state: enriched });
|
|
1754
|
+
return new Response(JSON.stringify({
|
|
1755
|
+
conversationScore: enriched.conversationScore,
|
|
1756
|
+
saved: true,
|
|
1757
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1758
|
+
}
|
|
1759
|
+
catch (err) {
|
|
1760
|
+
return new Response(JSON.stringify({
|
|
1761
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1762
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
if (url.pathname === "/api/simulator/load-session") {
|
|
1766
|
+
if (req.method !== "POST") {
|
|
1767
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1768
|
+
}
|
|
1769
|
+
try {
|
|
1770
|
+
const body = await req.json();
|
|
1771
|
+
if (!body.sessionId) {
|
|
1772
|
+
throw new Error("Missing sessionId");
|
|
1773
|
+
}
|
|
1774
|
+
const state = readSessionState(body.sessionId);
|
|
1775
|
+
if (!state) {
|
|
1776
|
+
throw new Error("Session not found");
|
|
1777
|
+
}
|
|
1778
|
+
simulatorSavedState = state;
|
|
1779
|
+
simulatorCapturedTraces = Array.isArray(state.traces)
|
|
1780
|
+
? cloneTraces(state.traces)
|
|
1781
|
+
: [];
|
|
1782
|
+
emitSimulator({ type: "state", state });
|
|
1783
|
+
return new Response(JSON.stringify({ state }), { headers: { "content-type": "application/json" } });
|
|
1784
|
+
}
|
|
1785
|
+
catch (err) {
|
|
1786
|
+
return new Response(JSON.stringify({
|
|
1787
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1788
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
if (url.pathname === "/api/session") {
|
|
1792
|
+
if (req.method !== "GET") {
|
|
1793
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1794
|
+
}
|
|
1795
|
+
const sessionId = url.searchParams.get("sessionId");
|
|
1796
|
+
if (!sessionId) {
|
|
1797
|
+
return new Response(JSON.stringify({ error: "Missing sessionId" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
1798
|
+
}
|
|
1799
|
+
const state = readSessionState(sessionId);
|
|
1800
|
+
if (!state) {
|
|
1801
|
+
return new Response(JSON.stringify({ error: "Session not found" }), { status: 404, headers: { "content-type": "application/json" } });
|
|
1802
|
+
}
|
|
1803
|
+
return new Response(JSON.stringify({
|
|
1804
|
+
sessionId,
|
|
1805
|
+
messages: state.messages,
|
|
1806
|
+
messageRefs: state.messageRefs,
|
|
1807
|
+
traces: state.traces,
|
|
1808
|
+
notes: state.notes,
|
|
1809
|
+
meta: state.meta,
|
|
1810
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1811
|
+
}
|
|
1812
|
+
if (url.pathname === "/api/session/notes") {
|
|
1813
|
+
if (req.method !== "POST") {
|
|
1814
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1815
|
+
}
|
|
1816
|
+
try {
|
|
1817
|
+
const body = await req.json();
|
|
1818
|
+
if (!body.sessionId) {
|
|
1819
|
+
throw new Error("Missing sessionId");
|
|
1820
|
+
}
|
|
1821
|
+
const state = readSessionState(body.sessionId);
|
|
1822
|
+
if (!state) {
|
|
1823
|
+
throw new Error("Session not found");
|
|
1824
|
+
}
|
|
1825
|
+
const now = new Date().toISOString();
|
|
1826
|
+
const nextState = persistSessionState({
|
|
1827
|
+
...state,
|
|
1828
|
+
notes: { text: body.text ?? "", updatedAt: now },
|
|
1829
|
+
});
|
|
1830
|
+
return new Response(JSON.stringify({
|
|
1831
|
+
sessionId: body.sessionId,
|
|
1832
|
+
notes: nextState.notes,
|
|
1833
|
+
saved: true,
|
|
1834
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1835
|
+
}
|
|
1836
|
+
catch (err) {
|
|
1837
|
+
return new Response(JSON.stringify({
|
|
1838
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1839
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
if (url.pathname === "/api/session/feedback") {
|
|
1843
|
+
if (req.method !== "POST") {
|
|
1844
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1845
|
+
}
|
|
1846
|
+
try {
|
|
1847
|
+
const body = await req.json();
|
|
1848
|
+
if (!body.sessionId) {
|
|
1849
|
+
throw new Error("Missing sessionId");
|
|
1850
|
+
}
|
|
1851
|
+
if (!body.messageRefId) {
|
|
1852
|
+
throw new Error("Missing messageRefId");
|
|
1853
|
+
}
|
|
1854
|
+
if (typeof body.score !== "number" || Number.isNaN(body.score)) {
|
|
1855
|
+
throw new Error("Invalid score");
|
|
1856
|
+
}
|
|
1857
|
+
const state = readSessionState(body.sessionId);
|
|
1858
|
+
if (!state) {
|
|
1859
|
+
throw new Error("Session not found");
|
|
1860
|
+
}
|
|
1861
|
+
const clamped = Math.max(-3, Math.min(3, Math.round(body.score)));
|
|
1862
|
+
const reason = typeof body.reason === "string"
|
|
1863
|
+
? body.reason
|
|
1864
|
+
: undefined;
|
|
1865
|
+
const runId = typeof state.runId === "string"
|
|
1866
|
+
? state.runId
|
|
1867
|
+
: "session";
|
|
1868
|
+
const existing = state.feedback ?? [];
|
|
1869
|
+
const idx = existing.findIndex((entry) => entry.messageRefId === body.messageRefId);
|
|
1870
|
+
const now = new Date().toISOString();
|
|
1871
|
+
const entry = idx >= 0
|
|
1872
|
+
? {
|
|
1873
|
+
...existing[idx],
|
|
1874
|
+
score: clamped,
|
|
1875
|
+
reason,
|
|
1876
|
+
runId: existing[idx].runId ?? runId,
|
|
1877
|
+
}
|
|
1878
|
+
: {
|
|
1879
|
+
id: randomId("fb"),
|
|
1880
|
+
runId,
|
|
1881
|
+
messageRefId: body.messageRefId,
|
|
1882
|
+
score: clamped,
|
|
1883
|
+
reason,
|
|
1884
|
+
createdAt: now,
|
|
1885
|
+
};
|
|
1886
|
+
const feedback = idx >= 0
|
|
1887
|
+
? existing.map((item, i) => i === idx ? entry : item)
|
|
1888
|
+
: [...existing, entry];
|
|
1889
|
+
const nextState = persistSessionState({
|
|
1890
|
+
...state,
|
|
1891
|
+
feedback,
|
|
1892
|
+
});
|
|
1893
|
+
const testBotRunId = typeof nextState.meta?.testBotRunId === "string"
|
|
1894
|
+
? nextState.meta.testBotRunId
|
|
1895
|
+
: undefined;
|
|
1896
|
+
if (testBotRunId) {
|
|
1897
|
+
const testEntry = testBotRuns.get(testBotRunId);
|
|
1898
|
+
if (testEntry) {
|
|
1899
|
+
syncTestBotRunFromState(testEntry.run, nextState);
|
|
1900
|
+
broadcastTestBot({ type: "testBotStatus", run: testEntry.run });
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
return new Response(JSON.stringify({
|
|
1904
|
+
sessionId: body.sessionId,
|
|
1905
|
+
feedback: entry,
|
|
1906
|
+
saved: true,
|
|
1907
|
+
}), { headers: { "content-type": "application/json" } });
|
|
1908
|
+
}
|
|
1909
|
+
catch (err) {
|
|
1910
|
+
return new Response(JSON.stringify({
|
|
1911
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1912
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
if (url.pathname === "/api/session/delete") {
|
|
1916
|
+
if (req.method !== "POST") {
|
|
1917
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1918
|
+
}
|
|
1919
|
+
try {
|
|
1920
|
+
const body = await req.json();
|
|
1921
|
+
if (!body.sessionId) {
|
|
1922
|
+
throw new Error("Missing sessionId");
|
|
1923
|
+
}
|
|
1924
|
+
const removed = deleteSessionState(body.sessionId);
|
|
1925
|
+
if (!removed) {
|
|
1926
|
+
return new Response(JSON.stringify({ error: "Session not found" }), { status: 404, headers: { "content-type": "application/json" } });
|
|
1927
|
+
}
|
|
1928
|
+
return new Response(JSON.stringify({ sessionId: body.sessionId, deleted: true }), { headers: { "content-type": "application/json" } });
|
|
1929
|
+
}
|
|
1930
|
+
catch (err) {
|
|
1931
|
+
return new Response(JSON.stringify({
|
|
1932
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1933
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
if (url.pathname === "/api/feedback") {
|
|
1937
|
+
if (req.method !== "GET") {
|
|
1938
|
+
return new Response("Method not allowed", { status: 405 });
|
|
1939
|
+
}
|
|
1940
|
+
const deckPathParam = url.searchParams.get("deckPath");
|
|
1941
|
+
if (!deckPathParam) {
|
|
1942
|
+
return new Response(JSON.stringify({ error: "Missing deckPath" }), { status: 400, headers: { "content-type": "application/json" } });
|
|
1943
|
+
}
|
|
1944
|
+
const items = [];
|
|
1945
|
+
try {
|
|
1946
|
+
for await (const entry of dntShim.Deno.readDir(sessionsRoot)) {
|
|
1947
|
+
if (!entry.isDirectory)
|
|
1948
|
+
continue;
|
|
1949
|
+
const sessionId = entry.name;
|
|
1950
|
+
const state = readSessionState(sessionId);
|
|
1951
|
+
if (!state)
|
|
1952
|
+
continue;
|
|
1953
|
+
if (state.meta?.deck !== deckPathParam)
|
|
1954
|
+
continue;
|
|
1955
|
+
const feedbackList = Array.isArray(state.feedback)
|
|
1956
|
+
? state.feedback
|
|
1957
|
+
: [];
|
|
1958
|
+
feedbackList.forEach((fb) => {
|
|
1959
|
+
if (!fb || typeof fb !== "object")
|
|
1960
|
+
return;
|
|
1961
|
+
const messageRefId = fb
|
|
1962
|
+
.messageRefId;
|
|
1963
|
+
if (typeof messageRefId !== "string")
|
|
1964
|
+
return;
|
|
1965
|
+
let messageContent = undefined;
|
|
1966
|
+
if (Array.isArray(state.messageRefs) &&
|
|
1967
|
+
Array.isArray(state.messages)) {
|
|
1968
|
+
const idx = state.messageRefs.findIndex((ref) => ref?.id === messageRefId);
|
|
1969
|
+
if (idx >= 0) {
|
|
1970
|
+
messageContent = state.messages[idx]?.content;
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
items.push({
|
|
1974
|
+
sessionId,
|
|
1975
|
+
deck: state.meta?.deck,
|
|
1976
|
+
sessionCreatedAt: state.meta?.sessionCreatedAt,
|
|
1977
|
+
messageRefId,
|
|
1978
|
+
score: fb.score,
|
|
1979
|
+
reason: fb.reason,
|
|
1980
|
+
createdAt: fb.createdAt,
|
|
1981
|
+
archivedAt: fb.archivedAt,
|
|
1982
|
+
messageContent,
|
|
1983
|
+
});
|
|
1984
|
+
});
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
catch (err) {
|
|
1988
|
+
return new Response(JSON.stringify({
|
|
1989
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1990
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
1991
|
+
}
|
|
1992
|
+
items.sort((a, b) => {
|
|
1993
|
+
const aTime = String(a.createdAt ?? "") || "";
|
|
1994
|
+
const bTime = String(b.createdAt ?? "") || "";
|
|
1995
|
+
return bTime.localeCompare(aTime);
|
|
1996
|
+
});
|
|
1997
|
+
return new Response(JSON.stringify({ deckPath: deckPathParam, items }), {
|
|
1998
|
+
headers: { "content-type": "application/json" },
|
|
1999
|
+
});
|
|
2000
|
+
}
|
|
2001
|
+
if (url.pathname === "/api/feedback/archive" && req.method === "POST") {
|
|
2002
|
+
try {
|
|
2003
|
+
const body = await req.json();
|
|
2004
|
+
if (!body.sessionId || !body.messageRefId) {
|
|
2005
|
+
throw new Error("Missing sessionId or messageRefId");
|
|
2006
|
+
}
|
|
2007
|
+
const state = readSessionState(body.sessionId);
|
|
2008
|
+
if (!state || !Array.isArray(state.feedback)) {
|
|
2009
|
+
throw new Error("Session not found");
|
|
2010
|
+
}
|
|
2011
|
+
const idx = state.feedback.findIndex((fb) => fb.messageRefId === body.messageRefId);
|
|
2012
|
+
if (idx === -1)
|
|
2013
|
+
throw new Error("Feedback not found");
|
|
2014
|
+
const next = { ...state.feedback[idx] };
|
|
2015
|
+
if (body.archived === false) {
|
|
2016
|
+
delete next.archivedAt;
|
|
2017
|
+
}
|
|
2018
|
+
else {
|
|
2019
|
+
next.archivedAt = new Date()
|
|
2020
|
+
.toISOString();
|
|
2021
|
+
}
|
|
2022
|
+
const nextFeedback = state.feedback.map((fb, i) => i === idx ? next : fb);
|
|
2023
|
+
const updated = persistSessionState({
|
|
2024
|
+
...state,
|
|
2025
|
+
feedback: nextFeedback,
|
|
2026
|
+
});
|
|
2027
|
+
return new Response(JSON.stringify({
|
|
2028
|
+
sessionId: body.sessionId,
|
|
2029
|
+
messageRefId: body.messageRefId,
|
|
2030
|
+
archivedAt: next.archivedAt,
|
|
2031
|
+
saved: true,
|
|
2032
|
+
feedbackCount: updated.feedback?.length ?? 0,
|
|
2033
|
+
}), { headers: { "content-type": "application/json" } });
|
|
2034
|
+
}
|
|
2035
|
+
catch (err) {
|
|
2036
|
+
return new Response(JSON.stringify({
|
|
2037
|
+
error: err instanceof Error ? err.message : String(err),
|
|
2038
|
+
}), { status: 400, headers: { "content-type": "application/json" } });
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
if (url.pathname === "/" || url.pathname.startsWith("/sessions/") ||
|
|
2042
|
+
url.pathname.startsWith("/simulate") ||
|
|
2043
|
+
url.pathname.startsWith("/debug") ||
|
|
2044
|
+
url.pathname.startsWith("/editor") ||
|
|
2045
|
+
url.pathname.startsWith("/test-bot") ||
|
|
2046
|
+
url.pathname.startsWith("/calibrate")) {
|
|
2047
|
+
const hasBundle = await canServeReactBundle();
|
|
2048
|
+
if (!hasBundle) {
|
|
2049
|
+
return new Response("Simulator UI bundle missing. Run `deno task bundle:sim` (or start with `--bundle`).", { status: 500 });
|
|
2050
|
+
}
|
|
2051
|
+
return new Response(simulatorReactHtml(resolvedDeckPath), {
|
|
2052
|
+
headers: { "content-type": "text/html; charset=utf-8" },
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
if (url.pathname === "/schema") {
|
|
2056
|
+
const desc = await schemaPromise;
|
|
2057
|
+
return new Response(JSON.stringify({
|
|
2058
|
+
deck: resolvedDeckPath,
|
|
2059
|
+
...desc,
|
|
2060
|
+
}), {
|
|
2061
|
+
headers: { "content-type": "application/json; charset=utf-8" },
|
|
2062
|
+
});
|
|
2063
|
+
}
|
|
2064
|
+
if (url.pathname === "/api/deck-source") {
|
|
2065
|
+
if (req.method !== "GET") {
|
|
2066
|
+
return new Response("Method not allowed", { status: 405 });
|
|
2067
|
+
}
|
|
2068
|
+
try {
|
|
2069
|
+
const content = await dntShim.Deno.readTextFile(resolvedDeckPath);
|
|
2070
|
+
return new Response(JSON.stringify({
|
|
2071
|
+
path: resolvedDeckPath,
|
|
2072
|
+
content,
|
|
2073
|
+
}), { headers: { "content-type": "application/json; charset=utf-8" } });
|
|
2074
|
+
}
|
|
2075
|
+
catch (err) {
|
|
2076
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2077
|
+
return new Response(JSON.stringify({
|
|
2078
|
+
path: resolvedDeckPath,
|
|
2079
|
+
error: message,
|
|
2080
|
+
}), {
|
|
2081
|
+
status: 500,
|
|
2082
|
+
headers: { "content-type": "application/json; charset=utf-8" },
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
if (url.pathname === "/ui/bundle.js") {
|
|
2087
|
+
const data = await readReactBundle();
|
|
2088
|
+
if (!data) {
|
|
2089
|
+
return new Response("Bundle missing. Run `deno task bundle:sim` (or start with `--bundle`).", { status: 404 });
|
|
2090
|
+
}
|
|
2091
|
+
try {
|
|
2092
|
+
const headers = new Headers({
|
|
2093
|
+
"content-type": "application/javascript; charset=utf-8",
|
|
2094
|
+
});
|
|
2095
|
+
// Hint the browser about the external source map since Deno's bundle
|
|
2096
|
+
// output does not embed a sourceMappingURL comment.
|
|
2097
|
+
if (shouldAdvertiseSourceMap()) {
|
|
2098
|
+
headers.set("SourceMap", "/ui/bundle.js.map");
|
|
2099
|
+
}
|
|
2100
|
+
return new Response(data, { headers });
|
|
2101
|
+
}
|
|
2102
|
+
catch (err) {
|
|
2103
|
+
return new Response(`Failed to read bundle: ${err instanceof Error ? err.message : String(err)}`, { status: 500 });
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
if (url.pathname === "/ui/bundle.js.map") {
|
|
2107
|
+
const data = await readReactBundleSourceMap();
|
|
2108
|
+
if (!data) {
|
|
2109
|
+
return new Response("Source map missing. Run `deno task bundle:sim:sourcemap` (or start with `--bundle --sourcemap`).", { status: 404 });
|
|
2110
|
+
}
|
|
2111
|
+
try {
|
|
2112
|
+
return new Response(data, {
|
|
2113
|
+
headers: {
|
|
2114
|
+
"content-type": "application/json; charset=utf-8",
|
|
2115
|
+
},
|
|
2116
|
+
});
|
|
2117
|
+
}
|
|
2118
|
+
catch (err) {
|
|
2119
|
+
return new Response(`Failed to read source map: ${err instanceof Error ? err.message : String(err)}`, { status: 500 });
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
if (url.pathname === "/sessions") {
|
|
2123
|
+
const sessions = listSessions();
|
|
2124
|
+
return new Response(JSON.stringify({ sessions }), {
|
|
2125
|
+
headers: { "content-type": "application/json; charset=utf-8" },
|
|
2126
|
+
});
|
|
2127
|
+
}
|
|
2128
|
+
return new Response("Not found", { status: 404 });
|
|
2129
|
+
});
|
|
2130
|
+
const listenPort = server.addr.port;
|
|
2131
|
+
logger.log(`Simulator listening on http://localhost:${listenPort} (deck=${resolvedDeckPath})`);
|
|
2132
|
+
return server;
|
|
2133
|
+
}
|
|
2134
|
+
function hasReactBundle() {
|
|
2135
|
+
try {
|
|
2136
|
+
const stat = dntShim.Deno.statSync(simulatorBundlePath);
|
|
2137
|
+
return stat.isFile;
|
|
2138
|
+
}
|
|
2139
|
+
catch {
|
|
2140
|
+
return false;
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
function hasReactBundleSourceMap() {
|
|
2144
|
+
try {
|
|
2145
|
+
const stat = dntShim.Deno.statSync(simulatorBundleSourceMapPath);
|
|
2146
|
+
return stat.isFile;
|
|
2147
|
+
}
|
|
2148
|
+
catch {
|
|
2149
|
+
return false;
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
function isReactBundleStale() {
|
|
2153
|
+
try {
|
|
2154
|
+
const bundleStat = dntShim.Deno.statSync(simulatorBundlePath);
|
|
2155
|
+
const entryStat = dntShim.Deno.statSync(simulatorUiEntryPath);
|
|
2156
|
+
if (!bundleStat.isFile || !entryStat.isFile)
|
|
2157
|
+
return false;
|
|
2158
|
+
const bundleTime = bundleStat.mtime?.getTime();
|
|
2159
|
+
const entryTime = entryStat.mtime?.getTime();
|
|
2160
|
+
if (typeof bundleTime !== "number" || typeof entryTime !== "number") {
|
|
2161
|
+
return false;
|
|
2162
|
+
}
|
|
2163
|
+
return entryTime > bundleTime;
|
|
2164
|
+
}
|
|
2165
|
+
catch {
|
|
2166
|
+
return false;
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
function shouldAdvertiseSourceMap() {
|
|
2170
|
+
if (hasReactBundleSourceMap())
|
|
2171
|
+
return true;
|
|
2172
|
+
if (!simulatorBundleSourceMapUrl)
|
|
2173
|
+
return false;
|
|
2174
|
+
return !simulatorBundleSourceMapUrl.startsWith("file:");
|
|
2175
|
+
}
|
|
2176
|
+
async function readReactBundle() {
|
|
2177
|
+
try {
|
|
2178
|
+
return await dntShim.Deno.readFile(simulatorBundlePath);
|
|
2179
|
+
}
|
|
2180
|
+
catch {
|
|
2181
|
+
return await readRemoteBundle(simulatorBundleUrl, "bundle");
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
async function readReactBundleSourceMap() {
|
|
2185
|
+
try {
|
|
2186
|
+
return await dntShim.Deno.readFile(simulatorBundleSourceMapPath);
|
|
2187
|
+
}
|
|
2188
|
+
catch {
|
|
2189
|
+
return await readRemoteBundle(simulatorBundleSourceMapUrl, "map");
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
async function canServeReactBundle() {
|
|
2193
|
+
if (hasReactBundle())
|
|
2194
|
+
return true;
|
|
2195
|
+
return (await readRemoteBundle(simulatorBundleUrl, "bundle")) !== null;
|
|
2196
|
+
}
|
|
2197
|
+
async function readRemoteBundle(url, kind) {
|
|
2198
|
+
if (!url || url.startsWith("file:"))
|
|
2199
|
+
return null;
|
|
2200
|
+
const cached = kind === "bundle"
|
|
2201
|
+
? cachedRemoteBundle
|
|
2202
|
+
: cachedRemoteBundleSourceMap;
|
|
2203
|
+
if (cached)
|
|
2204
|
+
return cached;
|
|
2205
|
+
try {
|
|
2206
|
+
const res = await fetch(url);
|
|
2207
|
+
if (!res.ok)
|
|
2208
|
+
return null;
|
|
2209
|
+
const data = new Uint8Array(await res.arrayBuffer());
|
|
2210
|
+
if (kind === "bundle") {
|
|
2211
|
+
cachedRemoteBundle = data;
|
|
2212
|
+
}
|
|
2213
|
+
else {
|
|
2214
|
+
cachedRemoteBundleSourceMap = data;
|
|
2215
|
+
}
|
|
2216
|
+
return data;
|
|
2217
|
+
}
|
|
2218
|
+
catch {
|
|
2219
|
+
return null;
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
function simulatorReactHtml(deckPath) {
|
|
2223
|
+
const deckLabel = deckPath.replaceAll("<", "<").replaceAll(">", ">");
|
|
2224
|
+
const bundleStamp = (() => {
|
|
2225
|
+
try {
|
|
2226
|
+
const stat = dntShim.Deno.statSync(simulatorBundlePath);
|
|
2227
|
+
const mtime = stat.mtime?.getTime();
|
|
2228
|
+
return typeof mtime === "number" ? String(mtime) : "";
|
|
2229
|
+
}
|
|
2230
|
+
catch {
|
|
2231
|
+
return "";
|
|
2232
|
+
}
|
|
2233
|
+
})();
|
|
2234
|
+
const bundleUrl = bundleStamp
|
|
2235
|
+
? `/ui/bundle.js?v=${bundleStamp}`
|
|
2236
|
+
: "/ui/bundle.js";
|
|
2237
|
+
return `<!doctype html>
|
|
2238
|
+
<html lang="en">
|
|
2239
|
+
<head>
|
|
2240
|
+
<meta charset="utf-8" />
|
|
2241
|
+
<title>Gambit Debug</title>
|
|
2242
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
2243
|
+
<style>
|
|
2244
|
+
body { margin: 0; background: #f3f5f9; }
|
|
2245
|
+
#root { min-height: 100vh; }
|
|
2246
|
+
</style>
|
|
2247
|
+
</head>
|
|
2248
|
+
<body>
|
|
2249
|
+
<div id="root"></div>
|
|
2250
|
+
<script>
|
|
2251
|
+
window.__GAMBIT_DECK_PATH__ = ${JSON.stringify(deckLabel)};
|
|
2252
|
+
</script>
|
|
2253
|
+
<script type="module" src="${bundleUrl}"></script>
|
|
2254
|
+
</body>
|
|
2255
|
+
</html>`;
|
|
2256
|
+
}
|
|
2257
|
+
function stringifyOutput(output) {
|
|
2258
|
+
if (output === null || output === undefined)
|
|
2259
|
+
return "";
|
|
2260
|
+
if (output &&
|
|
2261
|
+
typeof output === "object" &&
|
|
2262
|
+
"payload" in output) {
|
|
2263
|
+
return stringifyOutput(output.payload);
|
|
2264
|
+
}
|
|
2265
|
+
if (typeof output === "string")
|
|
2266
|
+
return output;
|
|
2267
|
+
try {
|
|
2268
|
+
return JSON.stringify(output);
|
|
2269
|
+
}
|
|
2270
|
+
catch {
|
|
2271
|
+
return String(output);
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
function shouldRetryWithStringInput(error) {
|
|
2275
|
+
if (!error)
|
|
2276
|
+
return false;
|
|
2277
|
+
if (error instanceof Error) {
|
|
2278
|
+
return error.message.includes("Schema validation failed");
|
|
2279
|
+
}
|
|
2280
|
+
return false;
|
|
2281
|
+
}
|
|
2282
|
+
async function runDeckWithFallback(args) {
|
|
2283
|
+
try {
|
|
2284
|
+
return await (0, runtime_1.runDeck)({
|
|
2285
|
+
path: args.path,
|
|
2286
|
+
input: args.input,
|
|
2287
|
+
inputProvided: args.inputProvided,
|
|
2288
|
+
modelProvider: args.modelProvider,
|
|
2289
|
+
state: args.state,
|
|
2290
|
+
allowRootStringInput: args.allowRootStringInput,
|
|
2291
|
+
initialUserMessage: args.initialUserMessage,
|
|
2292
|
+
onStateUpdate: args.onStateUpdate,
|
|
2293
|
+
stream: args.stream,
|
|
2294
|
+
onStreamText: args.onStreamText,
|
|
2295
|
+
});
|
|
2296
|
+
}
|
|
2297
|
+
catch (error) {
|
|
2298
|
+
if (args.input === undefined && shouldRetryWithStringInput(error)) {
|
|
2299
|
+
return await (0, runtime_1.runDeck)({
|
|
2300
|
+
path: args.path,
|
|
2301
|
+
input: "",
|
|
2302
|
+
inputProvided: true,
|
|
2303
|
+
modelProvider: args.modelProvider,
|
|
2304
|
+
state: args.state,
|
|
2305
|
+
allowRootStringInput: args.allowRootStringInput,
|
|
2306
|
+
initialUserMessage: args.initialUserMessage,
|
|
2307
|
+
onStateUpdate: args.onStateUpdate,
|
|
2308
|
+
stream: args.stream,
|
|
2309
|
+
onStreamText: args.onStreamText,
|
|
2310
|
+
});
|
|
2311
|
+
}
|
|
2312
|
+
throw error;
|
|
2313
|
+
}
|
|
2314
|
+
}
|