@steerable/runtime-darwin-arm64 0.0.0-stage → 0.9.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/bin/steerable-egress-proxy +0 -0
- package/package.json +25 -4
- package/python-runtime/manifest.json +8 -0
- package/python-runtime/python/bin/2to3 +7 -0
- package/python-runtime/python/bin/2to3-3.12 +7 -0
- package/python-runtime/python/bin/cffi-gen-src +6 -0
- package/python-runtime/python/bin/dotenv +6 -0
- package/python-runtime/python/bin/httpx +6 -0
- package/python-runtime/python/bin/idle3 +7 -0
- package/python-runtime/python/bin/idle3.12 +7 -0
- package/python-runtime/python/bin/idna +6 -0
- package/python-runtime/python/bin/jsonschema +6 -0
- package/python-runtime/python/bin/mcp +6 -0
- package/python-runtime/python/bin/pydoc3 +7 -0
- package/python-runtime/python/bin/pydoc3.12 +7 -0
- package/python-runtime/python/bin/python +0 -0
- package/python-runtime/python/bin/python3 +0 -0
- package/python-runtime/python/bin/python3-config +76 -0
- package/python-runtime/python/bin/python3.12 +0 -0
- package/python-runtime/python/bin/python3.12-config +76 -0
- package/python-runtime/python/bin/steerable-sidecar +6 -0
- package/python-runtime/python/bin/steerable-sidecar-acp +6 -0
- package/python-runtime/python/bin/steerable-sidecar-headless +6 -0
- package/python-runtime/python/bin/uvicorn +6 -0
- package/python-runtime/python/include/python3.12/Python.h +109 -0
- package/python-runtime/python/include/python3.12/abstract.h +899 -0
- package/python-runtime/python/include/python3.12/bltinmodule.h +14 -0
- package/python-runtime/python/include/python3.12/boolobject.h +42 -0
- package/python-runtime/python/include/python3.12/bytearrayobject.h +44 -0
- package/python-runtime/python/include/python3.12/bytesobject.h +69 -0
- package/python-runtime/python/include/python3.12/ceval.h +168 -0
- package/python-runtime/python/include/python3.12/codecs.h +248 -0
- package/python-runtime/python/include/python3.12/compile.h +22 -0
- package/python-runtime/python/include/python3.12/complexobject.h +30 -0
- package/python-runtime/python/include/python3.12/cpython/abstract.h +206 -0
- package/python-runtime/python/include/python3.12/cpython/bytearrayobject.h +34 -0
- package/python-runtime/python/include/python3.12/cpython/bytesobject.h +133 -0
- package/python-runtime/python/include/python3.12/cpython/cellobject.h +44 -0
- package/python-runtime/python/include/python3.12/cpython/ceval.h +35 -0
- package/python-runtime/python/include/python3.12/cpython/classobject.h +71 -0
- package/python-runtime/python/include/python3.12/cpython/code.h +389 -0
- package/python-runtime/python/include/python3.12/cpython/compile.h +69 -0
- package/python-runtime/python/include/python3.12/cpython/complexobject.h +44 -0
- package/python-runtime/python/include/python3.12/cpython/context.h +78 -0
- package/python-runtime/python/include/python3.12/cpython/descrobject.h +64 -0
- package/python-runtime/python/include/python3.12/cpython/dictobject.h +118 -0
- package/python-runtime/python/include/python3.12/cpython/fileobject.h +19 -0
- package/python-runtime/python/include/python3.12/cpython/fileutils.h +8 -0
- package/python-runtime/python/include/python3.12/cpython/floatobject.h +27 -0
- package/python-runtime/python/include/python3.12/cpython/frameobject.h +29 -0
- package/python-runtime/python/include/python3.12/cpython/funcobject.h +190 -0
- package/python-runtime/python/include/python3.12/cpython/genobject.h +89 -0
- package/python-runtime/python/include/python3.12/cpython/import.h +46 -0
- package/python-runtime/python/include/python3.12/cpython/initconfig.h +256 -0
- package/python-runtime/python/include/python3.12/cpython/interpreteridobject.h +11 -0
- package/python-runtime/python/include/python3.12/cpython/listobject.h +47 -0
- package/python-runtime/python/include/python3.12/cpython/longintrepr.h +133 -0
- package/python-runtime/python/include/python3.12/cpython/longobject.h +100 -0
- package/python-runtime/python/include/python3.12/cpython/memoryobject.h +52 -0
- package/python-runtime/python/include/python3.12/cpython/methodobject.h +66 -0
- package/python-runtime/python/include/python3.12/cpython/modsupport.h +109 -0
- package/python-runtime/python/include/python3.12/cpython/object.h +575 -0
- package/python-runtime/python/include/python3.12/cpython/objimpl.h +95 -0
- package/python-runtime/python/include/python3.12/cpython/odictobject.h +43 -0
- package/python-runtime/python/include/python3.12/cpython/picklebufobject.h +31 -0
- package/python-runtime/python/include/python3.12/cpython/pthread_stubs.h +88 -0
- package/python-runtime/python/include/python3.12/cpython/pyctype.h +39 -0
- package/python-runtime/python/include/python3.12/cpython/pydebug.h +38 -0
- package/python-runtime/python/include/python3.12/cpython/pyerrors.h +178 -0
- package/python-runtime/python/include/python3.12/cpython/pyfpe.h +15 -0
- package/python-runtime/python/include/python3.12/cpython/pyframe.h +35 -0
- package/python-runtime/python/include/python3.12/cpython/pylifecycle.h +111 -0
- package/python-runtime/python/include/python3.12/cpython/pymem.h +98 -0
- package/python-runtime/python/include/python3.12/cpython/pystate.h +456 -0
- package/python-runtime/python/include/python3.12/cpython/pythonrun.h +121 -0
- package/python-runtime/python/include/python3.12/cpython/pythread.h +42 -0
- package/python-runtime/python/include/python3.12/cpython/pytime.h +331 -0
- package/python-runtime/python/include/python3.12/cpython/setobject.h +72 -0
- package/python-runtime/python/include/python3.12/cpython/sysmodule.h +16 -0
- package/python-runtime/python/include/python3.12/cpython/traceback.h +16 -0
- package/python-runtime/python/include/python3.12/cpython/tupleobject.h +39 -0
- package/python-runtime/python/include/python3.12/cpython/unicodeobject.h +976 -0
- package/python-runtime/python/include/python3.12/cpython/warnings.h +20 -0
- package/python-runtime/python/include/python3.12/cpython/weakrefobject.h +56 -0
- package/python-runtime/python/include/python3.12/datetime.h +267 -0
- package/python-runtime/python/include/python3.12/descrobject.h +100 -0
- package/python-runtime/python/include/python3.12/dictobject.h +97 -0
- package/python-runtime/python/include/python3.12/dynamic_annotations.h +499 -0
- package/python-runtime/python/include/python3.12/enumobject.h +17 -0
- package/python-runtime/python/include/python3.12/errcode.h +38 -0
- package/python-runtime/python/include/python3.12/exports.h +36 -0
- package/python-runtime/python/include/python3.12/fileobject.h +49 -0
- package/python-runtime/python/include/python3.12/fileutils.h +26 -0
- package/python-runtime/python/include/python3.12/floatobject.h +54 -0
- package/python-runtime/python/include/python3.12/frameobject.h +20 -0
- package/python-runtime/python/include/python3.12/genericaliasobject.h +14 -0
- package/python-runtime/python/include/python3.12/import.h +98 -0
- package/python-runtime/python/include/python3.12/internal/pycore_abstract.h +25 -0
- package/python-runtime/python/include/python3.12/internal/pycore_asdl.h +112 -0
- package/python-runtime/python/include/python3.12/internal/pycore_ast.h +922 -0
- package/python-runtime/python/include/python3.12/internal/pycore_ast_state.h +265 -0
- package/python-runtime/python/include/python3.12/internal/pycore_atexit.h +57 -0
- package/python-runtime/python/include/python3.12/internal/pycore_atomic.h +557 -0
- package/python-runtime/python/include/python3.12/internal/pycore_atomic_funcs.h +94 -0
- package/python-runtime/python/include/python3.12/internal/pycore_bitutils.h +186 -0
- package/python-runtime/python/include/python3.12/internal/pycore_blocks_output_buffer.h +317 -0
- package/python-runtime/python/include/python3.12/internal/pycore_bytes_methods.h +73 -0
- package/python-runtime/python/include/python3.12/internal/pycore_bytesobject.h +47 -0
- package/python-runtime/python/include/python3.12/internal/pycore_call.h +133 -0
- package/python-runtime/python/include/python3.12/internal/pycore_ceval.h +164 -0
- package/python-runtime/python/include/python3.12/internal/pycore_ceval_state.h +103 -0
- package/python-runtime/python/include/python3.12/internal/pycore_code.h +496 -0
- package/python-runtime/python/include/python3.12/internal/pycore_compile.h +118 -0
- package/python-runtime/python/include/python3.12/internal/pycore_condvar.h +99 -0
- package/python-runtime/python/include/python3.12/internal/pycore_context.h +71 -0
- package/python-runtime/python/include/python3.12/internal/pycore_descrobject.h +26 -0
- package/python-runtime/python/include/python3.12/internal/pycore_dict.h +199 -0
- package/python-runtime/python/include/python3.12/internal/pycore_dict_state.h +50 -0
- package/python-runtime/python/include/python3.12/internal/pycore_dtoa.h +69 -0
- package/python-runtime/python/include/python3.12/internal/pycore_emscripten_signal.h +25 -0
- package/python-runtime/python/include/python3.12/internal/pycore_exceptions.h +37 -0
- package/python-runtime/python/include/python3.12/internal/pycore_faulthandler.h +99 -0
- package/python-runtime/python/include/python3.12/internal/pycore_fileutils.h +292 -0
- package/python-runtime/python/include/python3.12/internal/pycore_fileutils_windows.h +98 -0
- package/python-runtime/python/include/python3.12/internal/pycore_floatobject.h +71 -0
- package/python-runtime/python/include/python3.12/internal/pycore_flowgraph.h +120 -0
- package/python-runtime/python/include/python3.12/internal/pycore_format.h +27 -0
- package/python-runtime/python/include/python3.12/internal/pycore_frame.h +283 -0
- package/python-runtime/python/include/python3.12/internal/pycore_function.h +26 -0
- package/python-runtime/python/include/python3.12/internal/pycore_gc.h +211 -0
- package/python-runtime/python/include/python3.12/internal/pycore_genobject.h +49 -0
- package/python-runtime/python/include/python3.12/internal/pycore_getopt.h +22 -0
- package/python-runtime/python/include/python3.12/internal/pycore_gil.h +50 -0
- package/python-runtime/python/include/python3.12/internal/pycore_global_objects.h +105 -0
- package/python-runtime/python/include/python3.12/internal/pycore_global_objects_fini_generated.h +1517 -0
- package/python-runtime/python/include/python3.12/internal/pycore_global_strings.h +777 -0
- package/python-runtime/python/include/python3.12/internal/pycore_hamt.h +134 -0
- package/python-runtime/python/include/python3.12/internal/pycore_hashtable.h +149 -0
- package/python-runtime/python/include/python3.12/internal/pycore_import.h +183 -0
- package/python-runtime/python/include/python3.12/internal/pycore_initconfig.h +179 -0
- package/python-runtime/python/include/python3.12/internal/pycore_instruments.h +106 -0
- package/python-runtime/python/include/python3.12/internal/pycore_interp.h +275 -0
- package/python-runtime/python/include/python3.12/internal/pycore_intrinsics.h +32 -0
- package/python-runtime/python/include/python3.12/internal/pycore_list.h +83 -0
- package/python-runtime/python/include/python3.12/internal/pycore_long.h +258 -0
- package/python-runtime/python/include/python3.12/internal/pycore_memoryobject.h +18 -0
- package/python-runtime/python/include/python3.12/internal/pycore_moduleobject.h +45 -0
- package/python-runtime/python/include/python3.12/internal/pycore_namespace.h +20 -0
- package/python-runtime/python/include/python3.12/internal/pycore_object.h +455 -0
- package/python-runtime/python/include/python3.12/internal/pycore_object_state.h +42 -0
- package/python-runtime/python/include/python3.12/internal/pycore_obmalloc.h +700 -0
- package/python-runtime/python/include/python3.12/internal/pycore_obmalloc_init.h +73 -0
- package/python-runtime/python/include/python3.12/internal/pycore_opcode.h +587 -0
- package/python-runtime/python/include/python3.12/internal/pycore_opcode_utils.h +92 -0
- package/python-runtime/python/include/python3.12/internal/pycore_parser.h +66 -0
- package/python-runtime/python/include/python3.12/internal/pycore_pathconfig.h +24 -0
- package/python-runtime/python/include/python3.12/internal/pycore_pyarena.h +64 -0
- package/python-runtime/python/include/python3.12/internal/pycore_pyerrors.h +129 -0
- package/python-runtime/python/include/python3.12/internal/pycore_pyhash.h +40 -0
- package/python-runtime/python/include/python3.12/internal/pycore_pylifecycle.h +99 -0
- package/python-runtime/python/include/python3.12/internal/pycore_pymath.h +205 -0
- package/python-runtime/python/include/python3.12/internal/pycore_pymem.h +98 -0
- package/python-runtime/python/include/python3.12/internal/pycore_pymem_init.h +85 -0
- package/python-runtime/python/include/python3.12/internal/pycore_pystate.h +180 -0
- package/python-runtime/python/include/python3.12/internal/pycore_pythread.h +81 -0
- package/python-runtime/python/include/python3.12/internal/pycore_range.h +21 -0
- package/python-runtime/python/include/python3.12/internal/pycore_runtime.h +235 -0
- package/python-runtime/python/include/python3.12/internal/pycore_runtime_init.h +188 -0
- package/python-runtime/python/include/python3.12/internal/pycore_runtime_init_generated.h +1511 -0
- package/python-runtime/python/include/python3.12/internal/pycore_signal.h +98 -0
- package/python-runtime/python/include/python3.12/internal/pycore_sliceobject.h +22 -0
- package/python-runtime/python/include/python3.12/internal/pycore_strhex.h +36 -0
- package/python-runtime/python/include/python3.12/internal/pycore_structseq.h +39 -0
- package/python-runtime/python/include/python3.12/internal/pycore_symtable.h +160 -0
- package/python-runtime/python/include/python3.12/internal/pycore_sysmodule.h +34 -0
- package/python-runtime/python/include/python3.12/internal/pycore_time.h +25 -0
- package/python-runtime/python/include/python3.12/internal/pycore_token.h +108 -0
- package/python-runtime/python/include/python3.12/internal/pycore_traceback.h +101 -0
- package/python-runtime/python/include/python3.12/internal/pycore_tracemalloc.h +123 -0
- package/python-runtime/python/include/python3.12/internal/pycore_tuple.h +79 -0
- package/python-runtime/python/include/python3.12/internal/pycore_typeobject.h +151 -0
- package/python-runtime/python/include/python3.12/internal/pycore_typevarobject.h +24 -0
- package/python-runtime/python/include/python3.12/internal/pycore_ucnhash.h +34 -0
- package/python-runtime/python/include/python3.12/internal/pycore_unicodeobject.h +86 -0
- package/python-runtime/python/include/python3.12/internal/pycore_unicodeobject_generated.h +2832 -0
- package/python-runtime/python/include/python3.12/internal/pycore_unionobject.h +23 -0
- package/python-runtime/python/include/python3.12/internal/pycore_warnings.h +29 -0
- package/python-runtime/python/include/python3.12/interpreteridobject.h +17 -0
- package/python-runtime/python/include/python3.12/intrcheck.h +30 -0
- package/python-runtime/python/include/python3.12/iterobject.h +27 -0
- package/python-runtime/python/include/python3.12/listobject.h +52 -0
- package/python-runtime/python/include/python3.12/longobject.h +108 -0
- package/python-runtime/python/include/python3.12/marshal.h +31 -0
- package/python-runtime/python/include/python3.12/memoryobject.h +34 -0
- package/python-runtime/python/include/python3.12/methodobject.h +132 -0
- package/python-runtime/python/include/python3.12/modsupport.h +168 -0
- package/python-runtime/python/include/python3.12/moduleobject.h +119 -0
- package/python-runtime/python/include/python3.12/object.h +993 -0
- package/python-runtime/python/include/python3.12/objimpl.h +234 -0
- package/python-runtime/python/include/python3.12/opcode.h +271 -0
- package/python-runtime/python/include/python3.12/osdefs.h +51 -0
- package/python-runtime/python/include/python3.12/osmodule.h +17 -0
- package/python-runtime/python/include/python3.12/patchlevel.h +35 -0
- package/python-runtime/python/include/python3.12/py_curses.h +99 -0
- package/python-runtime/python/include/python3.12/pybuffer.h +145 -0
- package/python-runtime/python/include/python3.12/pycapsule.h +59 -0
- package/python-runtime/python/include/python3.12/pyconfig.h +1943 -0
- package/python-runtime/python/include/python3.12/pydtrace.h +59 -0
- package/python-runtime/python/include/python3.12/pyerrors.h +337 -0
- package/python-runtime/python/include/python3.12/pyexpat.h +62 -0
- package/python-runtime/python/include/python3.12/pyframe.h +26 -0
- package/python-runtime/python/include/python3.12/pyhash.h +144 -0
- package/python-runtime/python/include/python3.12/pylifecycle.h +78 -0
- package/python-runtime/python/include/python3.12/pymacconfig.h +99 -0
- package/python-runtime/python/include/python3.12/pymacro.h +172 -0
- package/python-runtime/python/include/python3.12/pymath.h +62 -0
- package/python-runtime/python/include/python3.12/pymem.h +104 -0
- package/python-runtime/python/include/python3.12/pyport.h +782 -0
- package/python-runtime/python/include/python3.12/pystate.h +132 -0
- package/python-runtime/python/include/python3.12/pystats.h +110 -0
- package/python-runtime/python/include/python3.12/pystrcmp.h +23 -0
- package/python-runtime/python/include/python3.12/pystrtod.h +46 -0
- package/python-runtime/python/include/python3.12/pythonrun.h +49 -0
- package/python-runtime/python/include/python3.12/pythread.h +135 -0
- package/python-runtime/python/include/python3.12/pytypedefs.h +30 -0
- package/python-runtime/python/include/python3.12/rangeobject.h +27 -0
- package/python-runtime/python/include/python3.12/setobject.h +49 -0
- package/python-runtime/python/include/python3.12/sliceobject.h +65 -0
- package/python-runtime/python/include/python3.12/structmember.h +56 -0
- package/python-runtime/python/include/python3.12/structseq.h +49 -0
- package/python-runtime/python/include/python3.12/sysmodule.h +54 -0
- package/python-runtime/python/include/python3.12/traceback.h +26 -0
- package/python-runtime/python/include/python3.12/tracemalloc.h +77 -0
- package/python-runtime/python/include/python3.12/tupleobject.h +46 -0
- package/python-runtime/python/include/python3.12/typeslots.h +88 -0
- package/python-runtime/python/include/python3.12/unicodeobject.h +1020 -0
- package/python-runtime/python/include/python3.12/warnings.h +45 -0
- package/python-runtime/python/include/python3.12/weakrefobject.h +42 -0
- package/python-runtime/python/lib/itcl4.3.5/itcl.tcl +151 -0
- package/python-runtime/python/lib/itcl4.3.5/itclConfig.sh +67 -0
- package/python-runtime/python/lib/itcl4.3.5/itclHullCmds.tcl +562 -0
- package/python-runtime/python/lib/itcl4.3.5/itclWidget.tcl +447 -0
- package/python-runtime/python/lib/itcl4.3.5/libitcl4.3.5.dylib +0 -0
- package/python-runtime/python/lib/itcl4.3.5/libitclstub.a +0 -0
- package/python-runtime/python/lib/itcl4.3.5/libitclstub4.3.5.a +0 -0
- package/python-runtime/python/lib/itcl4.3.5/libtcl9itcl4.3.5.dylib +0 -0
- package/python-runtime/python/lib/itcl4.3.5/pkgIndex.tcl +14 -0
- package/python-runtime/python/lib/libpython3.12.dylib +0 -0
- package/python-runtime/python/lib/libtcl9.0.dylib +0 -0
- package/python-runtime/python/lib/libtcl9tk9.0.dylib +0 -0
- package/python-runtime/python/lib/pkgconfig/python-3.12-embed.pc +13 -0
- package/python-runtime/python/lib/pkgconfig/python-3.12.pc +13 -0
- package/python-runtime/python/lib/pkgconfig/python3-embed.pc +13 -0
- package/python-runtime/python/lib/pkgconfig/python3.pc +13 -0
- package/python-runtime/python/lib/python3.12/LICENSE.txt +279 -0
- package/python-runtime/python/lib/python3.12/__future__.py +147 -0
- package/python-runtime/python/lib/python3.12/__hello__.py +16 -0
- package/python-runtime/python/lib/python3.12/__phello__/__init__.py +7 -0
- package/python-runtime/python/lib/python3.12/__phello__/spam.py +7 -0
- package/python-runtime/python/lib/python3.12/_aix_support.py +108 -0
- package/python-runtime/python/lib/python3.12/_collections_abc.py +1173 -0
- package/python-runtime/python/lib/python3.12/_compat_pickle.py +252 -0
- package/python-runtime/python/lib/python3.12/_compression.py +162 -0
- package/python-runtime/python/lib/python3.12/_markupbase.py +396 -0
- package/python-runtime/python/lib/python3.12/_osx_support.py +579 -0
- package/python-runtime/python/lib/python3.12/_py_abc.py +147 -0
- package/python-runtime/python/lib/python3.12/_pydatetime.py +2643 -0
- package/python-runtime/python/lib/python3.12/_pydecimal.py +6339 -0
- package/python-runtime/python/lib/python3.12/_pyio.py +2698 -0
- package/python-runtime/python/lib/python3.12/_pylong.py +329 -0
- package/python-runtime/python/lib/python3.12/_sitebuiltins.py +103 -0
- package/python-runtime/python/lib/python3.12/_strptime.py +664 -0
- package/python-runtime/python/lib/python3.12/_sysconfigdata__darwin_darwin.py +984 -0
- package/python-runtime/python/lib/python3.12/_threading_local.py +242 -0
- package/python-runtime/python/lib/python3.12/_weakrefset.py +205 -0
- package/python-runtime/python/lib/python3.12/abc.py +188 -0
- package/python-runtime/python/lib/python3.12/aifc.py +984 -0
- package/python-runtime/python/lib/python3.12/antigravity.py +17 -0
- package/python-runtime/python/lib/python3.12/argparse.py +2650 -0
- package/python-runtime/python/lib/python3.12/ast.py +1840 -0
- package/python-runtime/python/lib/python3.12/asyncio/__init__.py +47 -0
- package/python-runtime/python/lib/python3.12/asyncio/__main__.py +128 -0
- package/python-runtime/python/lib/python3.12/asyncio/base_events.py +2024 -0
- package/python-runtime/python/lib/python3.12/asyncio/base_futures.py +67 -0
- package/python-runtime/python/lib/python3.12/asyncio/base_subprocess.py +285 -0
- package/python-runtime/python/lib/python3.12/asyncio/base_tasks.py +94 -0
- package/python-runtime/python/lib/python3.12/asyncio/constants.py +41 -0
- package/python-runtime/python/lib/python3.12/asyncio/coroutines.py +109 -0
- package/python-runtime/python/lib/python3.12/asyncio/events.py +868 -0
- package/python-runtime/python/lib/python3.12/asyncio/exceptions.py +62 -0
- package/python-runtime/python/lib/python3.12/asyncio/format_helpers.py +76 -0
- package/python-runtime/python/lib/python3.12/asyncio/futures.py +430 -0
- package/python-runtime/python/lib/python3.12/asyncio/locks.py +586 -0
- package/python-runtime/python/lib/python3.12/asyncio/log.py +7 -0
- package/python-runtime/python/lib/python3.12/asyncio/mixins.py +21 -0
- package/python-runtime/python/lib/python3.12/asyncio/proactor_events.py +897 -0
- package/python-runtime/python/lib/python3.12/asyncio/protocols.py +216 -0
- package/python-runtime/python/lib/python3.12/asyncio/queues.py +244 -0
- package/python-runtime/python/lib/python3.12/asyncio/runners.py +216 -0
- package/python-runtime/python/lib/python3.12/asyncio/selector_events.py +1324 -0
- package/python-runtime/python/lib/python3.12/asyncio/sslproto.py +929 -0
- package/python-runtime/python/lib/python3.12/asyncio/staggered.py +174 -0
- package/python-runtime/python/lib/python3.12/asyncio/streams.py +770 -0
- package/python-runtime/python/lib/python3.12/asyncio/subprocess.py +229 -0
- package/python-runtime/python/lib/python3.12/asyncio/taskgroups.py +268 -0
- package/python-runtime/python/lib/python3.12/asyncio/tasks.py +1065 -0
- package/python-runtime/python/lib/python3.12/asyncio/threads.py +25 -0
- package/python-runtime/python/lib/python3.12/asyncio/timeouts.py +168 -0
- package/python-runtime/python/lib/python3.12/asyncio/transports.py +335 -0
- package/python-runtime/python/lib/python3.12/asyncio/trsock.py +98 -0
- package/python-runtime/python/lib/python3.12/asyncio/unix_events.py +1500 -0
- package/python-runtime/python/lib/python3.12/asyncio/windows_events.py +901 -0
- package/python-runtime/python/lib/python3.12/asyncio/windows_utils.py +173 -0
- package/python-runtime/python/lib/python3.12/base64.py +586 -0
- package/python-runtime/python/lib/python3.12/bdb.py +920 -0
- package/python-runtime/python/lib/python3.12/bisect.py +118 -0
- package/python-runtime/python/lib/python3.12/bz2.py +344 -0
- package/python-runtime/python/lib/python3.12/cProfile.py +195 -0
- package/python-runtime/python/lib/python3.12/calendar.py +808 -0
- package/python-runtime/python/lib/python3.12/cgi.py +1014 -0
- package/python-runtime/python/lib/python3.12/cgitb.py +332 -0
- package/python-runtime/python/lib/python3.12/chunk.py +173 -0
- package/python-runtime/python/lib/python3.12/cmd.py +401 -0
- package/python-runtime/python/lib/python3.12/code.py +324 -0
- package/python-runtime/python/lib/python3.12/codecs.py +1129 -0
- package/python-runtime/python/lib/python3.12/codeop.py +161 -0
- package/python-runtime/python/lib/python3.12/collections/__init__.py +1592 -0
- package/python-runtime/python/lib/python3.12/collections/abc.py +3 -0
- package/python-runtime/python/lib/python3.12/colorsys.py +166 -0
- package/python-runtime/python/lib/python3.12/compileall.py +469 -0
- package/python-runtime/python/lib/python3.12/concurrent/__init__.py +1 -0
- package/python-runtime/python/lib/python3.12/concurrent/futures/__init__.py +54 -0
- package/python-runtime/python/lib/python3.12/concurrent/futures/_base.py +654 -0
- package/python-runtime/python/lib/python3.12/concurrent/futures/process.py +876 -0
- package/python-runtime/python/lib/python3.12/concurrent/futures/thread.py +240 -0
- package/python-runtime/python/lib/python3.12/configparser.py +1333 -0
- package/python-runtime/python/lib/python3.12/contextlib.py +800 -0
- package/python-runtime/python/lib/python3.12/contextvars.py +4 -0
- package/python-runtime/python/lib/python3.12/copy.py +292 -0
- package/python-runtime/python/lib/python3.12/copyreg.py +217 -0
- package/python-runtime/python/lib/python3.12/crypt.py +124 -0
- package/python-runtime/python/lib/python3.12/csv.py +451 -0
- package/python-runtime/python/lib/python3.12/ctypes/__init__.py +582 -0
- package/python-runtime/python/lib/python3.12/ctypes/_aix.py +327 -0
- package/python-runtime/python/lib/python3.12/ctypes/_endian.py +78 -0
- package/python-runtime/python/lib/python3.12/ctypes/macholib/README.ctypes +7 -0
- package/python-runtime/python/lib/python3.12/ctypes/macholib/__init__.py +9 -0
- package/python-runtime/python/lib/python3.12/ctypes/macholib/dyld.py +165 -0
- package/python-runtime/python/lib/python3.12/ctypes/macholib/dylib.py +42 -0
- package/python-runtime/python/lib/python3.12/ctypes/macholib/fetch_macholib +2 -0
- package/python-runtime/python/lib/python3.12/ctypes/macholib/fetch_macholib.bat +1 -0
- package/python-runtime/python/lib/python3.12/ctypes/macholib/framework.py +42 -0
- package/python-runtime/python/lib/python3.12/ctypes/util.py +379 -0
- package/python-runtime/python/lib/python3.12/ctypes/wintypes.py +202 -0
- package/python-runtime/python/lib/python3.12/curses/__init__.py +101 -0
- package/python-runtime/python/lib/python3.12/curses/ascii.py +99 -0
- package/python-runtime/python/lib/python3.12/curses/has_key.py +192 -0
- package/python-runtime/python/lib/python3.12/curses/panel.py +6 -0
- package/python-runtime/python/lib/python3.12/curses/textpad.py +204 -0
- package/python-runtime/python/lib/python3.12/dataclasses.py +1588 -0
- package/python-runtime/python/lib/python3.12/datetime.py +9 -0
- package/python-runtime/python/lib/python3.12/dbm/__init__.py +190 -0
- package/python-runtime/python/lib/python3.12/dbm/dumb.py +317 -0
- package/python-runtime/python/lib/python3.12/dbm/gnu.py +3 -0
- package/python-runtime/python/lib/python3.12/dbm/ndbm.py +3 -0
- package/python-runtime/python/lib/python3.12/decimal.py +108 -0
- package/python-runtime/python/lib/python3.12/difflib.py +2056 -0
- package/python-runtime/python/lib/python3.12/dis.py +805 -0
- package/python-runtime/python/lib/python3.12/doctest.py +2845 -0
- package/python-runtime/python/lib/python3.12/email/__init__.py +61 -0
- package/python-runtime/python/lib/python3.12/email/_encoded_words.py +233 -0
- package/python-runtime/python/lib/python3.12/email/_header_value_parser.py +3108 -0
- package/python-runtime/python/lib/python3.12/email/_parseaddr.py +557 -0
- package/python-runtime/python/lib/python3.12/email/_policybase.py +382 -0
- package/python-runtime/python/lib/python3.12/email/architecture.rst +216 -0
- package/python-runtime/python/lib/python3.12/email/base64mime.py +115 -0
- package/python-runtime/python/lib/python3.12/email/charset.py +398 -0
- package/python-runtime/python/lib/python3.12/email/contentmanager.py +251 -0
- package/python-runtime/python/lib/python3.12/email/encoders.py +65 -0
- package/python-runtime/python/lib/python3.12/email/errors.py +117 -0
- package/python-runtime/python/lib/python3.12/email/feedparser.py +534 -0
- package/python-runtime/python/lib/python3.12/email/generator.py +530 -0
- package/python-runtime/python/lib/python3.12/email/header.py +573 -0
- package/python-runtime/python/lib/python3.12/email/headerregistry.py +604 -0
- package/python-runtime/python/lib/python3.12/email/iterators.py +68 -0
- package/python-runtime/python/lib/python3.12/email/message.py +1215 -0
- package/python-runtime/python/lib/python3.12/email/mime/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/email/mime/application.py +37 -0
- package/python-runtime/python/lib/python3.12/email/mime/audio.py +100 -0
- package/python-runtime/python/lib/python3.12/email/mime/base.py +29 -0
- package/python-runtime/python/lib/python3.12/email/mime/image.py +152 -0
- package/python-runtime/python/lib/python3.12/email/mime/message.py +33 -0
- package/python-runtime/python/lib/python3.12/email/mime/multipart.py +47 -0
- package/python-runtime/python/lib/python3.12/email/mime/nonmultipart.py +21 -0
- package/python-runtime/python/lib/python3.12/email/mime/text.py +40 -0
- package/python-runtime/python/lib/python3.12/email/parser.py +127 -0
- package/python-runtime/python/lib/python3.12/email/policy.py +232 -0
- package/python-runtime/python/lib/python3.12/email/quoprimime.py +300 -0
- package/python-runtime/python/lib/python3.12/email/utils.py +486 -0
- package/python-runtime/python/lib/python3.12/encodings/__init__.py +174 -0
- package/python-runtime/python/lib/python3.12/encodings/aliases.py +551 -0
- package/python-runtime/python/lib/python3.12/encodings/ascii.py +50 -0
- package/python-runtime/python/lib/python3.12/encodings/base64_codec.py +55 -0
- package/python-runtime/python/lib/python3.12/encodings/big5.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/big5hkscs.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/bz2_codec.py +78 -0
- package/python-runtime/python/lib/python3.12/encodings/charmap.py +69 -0
- package/python-runtime/python/lib/python3.12/encodings/cp037.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1006.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1026.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1125.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1140.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1250.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1251.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1252.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1253.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1254.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1255.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1256.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1257.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp1258.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp273.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp424.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp437.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp500.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp720.py +309 -0
- package/python-runtime/python/lib/python3.12/encodings/cp737.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp775.py +697 -0
- package/python-runtime/python/lib/python3.12/encodings/cp850.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp852.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp855.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp856.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp857.py +694 -0
- package/python-runtime/python/lib/python3.12/encodings/cp858.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp860.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp861.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp862.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp863.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp864.py +690 -0
- package/python-runtime/python/lib/python3.12/encodings/cp865.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp866.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/cp869.py +689 -0
- package/python-runtime/python/lib/python3.12/encodings/cp874.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp875.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/cp932.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/cp949.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/cp950.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/euc_jis_2004.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/euc_jisx0213.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/euc_jp.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/euc_kr.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/gb18030.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/gb2312.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/gbk.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/hex_codec.py +55 -0
- package/python-runtime/python/lib/python3.12/encodings/hp_roman8.py +314 -0
- package/python-runtime/python/lib/python3.12/encodings/hz.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/idna.py +317 -0
- package/python-runtime/python/lib/python3.12/encodings/iso2022_jp.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/iso2022_jp_1.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/iso2022_jp_2.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/iso2022_jp_2004.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/iso2022_jp_3.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/iso2022_jp_ext.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/iso2022_kr.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_1.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_10.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_11.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_13.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_14.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_15.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_16.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_2.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_3.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_4.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_5.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_6.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_7.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_8.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/iso8859_9.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/johab.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/koi8_r.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/koi8_t.py +308 -0
- package/python-runtime/python/lib/python3.12/encodings/koi8_u.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/kz1048.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/latin_1.py +50 -0
- package/python-runtime/python/lib/python3.12/encodings/mac_arabic.py +698 -0
- package/python-runtime/python/lib/python3.12/encodings/mac_croatian.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/mac_cyrillic.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/mac_farsi.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/mac_greek.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/mac_iceland.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/mac_latin2.py +312 -0
- package/python-runtime/python/lib/python3.12/encodings/mac_roman.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/mac_romanian.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/mac_turkish.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/mbcs.py +47 -0
- package/python-runtime/python/lib/python3.12/encodings/oem.py +41 -0
- package/python-runtime/python/lib/python3.12/encodings/palmos.py +308 -0
- package/python-runtime/python/lib/python3.12/encodings/ptcp154.py +312 -0
- package/python-runtime/python/lib/python3.12/encodings/punycode.py +237 -0
- package/python-runtime/python/lib/python3.12/encodings/quopri_codec.py +56 -0
- package/python-runtime/python/lib/python3.12/encodings/raw_unicode_escape.py +46 -0
- package/python-runtime/python/lib/python3.12/encodings/rot_13.py +113 -0
- package/python-runtime/python/lib/python3.12/encodings/shift_jis.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/shift_jis_2004.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/shift_jisx0213.py +39 -0
- package/python-runtime/python/lib/python3.12/encodings/tis_620.py +307 -0
- package/python-runtime/python/lib/python3.12/encodings/undefined.py +49 -0
- package/python-runtime/python/lib/python3.12/encodings/unicode_escape.py +46 -0
- package/python-runtime/python/lib/python3.12/encodings/utf_16.py +155 -0
- package/python-runtime/python/lib/python3.12/encodings/utf_16_be.py +42 -0
- package/python-runtime/python/lib/python3.12/encodings/utf_16_le.py +42 -0
- package/python-runtime/python/lib/python3.12/encodings/utf_32.py +150 -0
- package/python-runtime/python/lib/python3.12/encodings/utf_32_be.py +37 -0
- package/python-runtime/python/lib/python3.12/encodings/utf_32_le.py +37 -0
- package/python-runtime/python/lib/python3.12/encodings/utf_7.py +38 -0
- package/python-runtime/python/lib/python3.12/encodings/utf_8.py +42 -0
- package/python-runtime/python/lib/python3.12/encodings/utf_8_sig.py +130 -0
- package/python-runtime/python/lib/python3.12/encodings/uu_codec.py +103 -0
- package/python-runtime/python/lib/python3.12/encodings/zlib_codec.py +77 -0
- package/python-runtime/python/lib/python3.12/enum.py +2108 -0
- package/python-runtime/python/lib/python3.12/filecmp.py +315 -0
- package/python-runtime/python/lib/python3.12/fileinput.py +442 -0
- package/python-runtime/python/lib/python3.12/fnmatch.py +185 -0
- package/python-runtime/python/lib/python3.12/fractions.py +990 -0
- package/python-runtime/python/lib/python3.12/ftplib.py +966 -0
- package/python-runtime/python/lib/python3.12/functools.py +1009 -0
- package/python-runtime/python/lib/python3.12/genericpath.py +176 -0
- package/python-runtime/python/lib/python3.12/getopt.py +215 -0
- package/python-runtime/python/lib/python3.12/getpass.py +185 -0
- package/python-runtime/python/lib/python3.12/gettext.py +646 -0
- package/python-runtime/python/lib/python3.12/glob.py +252 -0
- package/python-runtime/python/lib/python3.12/graphlib.py +250 -0
- package/python-runtime/python/lib/python3.12/gzip.py +711 -0
- package/python-runtime/python/lib/python3.12/hashlib.py +253 -0
- package/python-runtime/python/lib/python3.12/heapq.py +603 -0
- package/python-runtime/python/lib/python3.12/hmac.py +219 -0
- package/python-runtime/python/lib/python3.12/html/__init__.py +132 -0
- package/python-runtime/python/lib/python3.12/html/entities.py +2513 -0
- package/python-runtime/python/lib/python3.12/html/parser.py +535 -0
- package/python-runtime/python/lib/python3.12/http/__init__.py +200 -0
- package/python-runtime/python/lib/python3.12/http/client.py +1570 -0
- package/python-runtime/python/lib/python3.12/http/cookiejar.py +2121 -0
- package/python-runtime/python/lib/python3.12/http/cookies.py +615 -0
- package/python-runtime/python/lib/python3.12/http/server.py +1335 -0
- package/python-runtime/python/lib/python3.12/imaplib.py +1641 -0
- package/python-runtime/python/lib/python3.12/imghdr.py +180 -0
- package/python-runtime/python/lib/python3.12/importlib/__init__.py +138 -0
- package/python-runtime/python/lib/python3.12/importlib/_abc.py +39 -0
- package/python-runtime/python/lib/python3.12/importlib/_bootstrap.py +1551 -0
- package/python-runtime/python/lib/python3.12/importlib/_bootstrap_external.py +1749 -0
- package/python-runtime/python/lib/python3.12/importlib/abc.py +239 -0
- package/python-runtime/python/lib/python3.12/importlib/machinery.py +20 -0
- package/python-runtime/python/lib/python3.12/importlib/metadata/__init__.py +966 -0
- package/python-runtime/python/lib/python3.12/importlib/metadata/_adapters.py +89 -0
- package/python-runtime/python/lib/python3.12/importlib/metadata/_collections.py +30 -0
- package/python-runtime/python/lib/python3.12/importlib/metadata/_functools.py +104 -0
- package/python-runtime/python/lib/python3.12/importlib/metadata/_itertools.py +73 -0
- package/python-runtime/python/lib/python3.12/importlib/metadata/_meta.py +63 -0
- package/python-runtime/python/lib/python3.12/importlib/metadata/_text.py +99 -0
- package/python-runtime/python/lib/python3.12/importlib/readers.py +12 -0
- package/python-runtime/python/lib/python3.12/importlib/resources/__init__.py +38 -0
- package/python-runtime/python/lib/python3.12/importlib/resources/_adapters.py +168 -0
- package/python-runtime/python/lib/python3.12/importlib/resources/_common.py +208 -0
- package/python-runtime/python/lib/python3.12/importlib/resources/_itertools.py +38 -0
- package/python-runtime/python/lib/python3.12/importlib/resources/_legacy.py +98 -0
- package/python-runtime/python/lib/python3.12/importlib/resources/abc.py +173 -0
- package/python-runtime/python/lib/python3.12/importlib/resources/readers.py +146 -0
- package/python-runtime/python/lib/python3.12/importlib/resources/simple.py +106 -0
- package/python-runtime/python/lib/python3.12/importlib/simple.py +14 -0
- package/python-runtime/python/lib/python3.12/importlib/util.py +270 -0
- package/python-runtime/python/lib/python3.12/inspect.py +3433 -0
- package/python-runtime/python/lib/python3.12/io.py +99 -0
- package/python-runtime/python/lib/python3.12/ipaddress.py +2430 -0
- package/python-runtime/python/lib/python3.12/json/__init__.py +359 -0
- package/python-runtime/python/lib/python3.12/json/decoder.py +357 -0
- package/python-runtime/python/lib/python3.12/json/encoder.py +443 -0
- package/python-runtime/python/lib/python3.12/json/scanner.py +73 -0
- package/python-runtime/python/lib/python3.12/json/tool.py +85 -0
- package/python-runtime/python/lib/python3.12/keyword.py +64 -0
- package/python-runtime/python/lib/python3.12/lib-dynload/_crypt.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/lib-dynload/_dbm.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/lib-dynload/_tkinter.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/linecache.py +185 -0
- package/python-runtime/python/lib/python3.12/locale.py +1779 -0
- package/python-runtime/python/lib/python3.12/logging/__init__.py +2345 -0
- package/python-runtime/python/lib/python3.12/logging/config.py +1078 -0
- package/python-runtime/python/lib/python3.12/logging/handlers.py +1624 -0
- package/python-runtime/python/lib/python3.12/lzma.py +356 -0
- package/python-runtime/python/lib/python3.12/mailbox.py +2153 -0
- package/python-runtime/python/lib/python3.12/mailcap.py +302 -0
- package/python-runtime/python/lib/python3.12/mimetypes.py +656 -0
- package/python-runtime/python/lib/python3.12/modulefinder.py +666 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/__init__.py +37 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/connection.py +1178 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/context.py +377 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/dummy/__init__.py +126 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/dummy/connection.py +75 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/forkserver.py +350 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/heap.py +337 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/managers.py +1387 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/pool.py +957 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/popen_fork.py +83 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/popen_forkserver.py +74 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/popen_spawn_posix.py +72 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/popen_spawn_win32.py +145 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/process.py +439 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/queues.py +401 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/reduction.py +281 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/resource_sharer.py +154 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/resource_tracker.py +294 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/shared_memory.py +534 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/sharedctypes.py +240 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/spawn.py +307 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/synchronize.py +404 -0
- package/python-runtime/python/lib/python3.12/multiprocessing/util.py +494 -0
- package/python-runtime/python/lib/python3.12/netrc.py +192 -0
- package/python-runtime/python/lib/python3.12/nntplib.py +1093 -0
- package/python-runtime/python/lib/python3.12/ntpath.py +869 -0
- package/python-runtime/python/lib/python3.12/nturl2path.py +69 -0
- package/python-runtime/python/lib/python3.12/numbers.py +418 -0
- package/python-runtime/python/lib/python3.12/opcode.py +493 -0
- package/python-runtime/python/lib/python3.12/operator.py +467 -0
- package/python-runtime/python/lib/python3.12/optparse.py +1681 -0
- package/python-runtime/python/lib/python3.12/os.py +1159 -0
- package/python-runtime/python/lib/python3.12/pathlib.py +1435 -0
- package/python-runtime/python/lib/python3.12/pdb.py +1987 -0
- package/python-runtime/python/lib/python3.12/pickle.py +1866 -0
- package/python-runtime/python/lib/python3.12/pickletools.py +2904 -0
- package/python-runtime/python/lib/python3.12/pipes.py +250 -0
- package/python-runtime/python/lib/python3.12/pkgutil.py +529 -0
- package/python-runtime/python/lib/python3.12/platform.py +1359 -0
- package/python-runtime/python/lib/python3.12/plistlib.py +920 -0
- package/python-runtime/python/lib/python3.12/poplib.py +478 -0
- package/python-runtime/python/lib/python3.12/posixpath.py +577 -0
- package/python-runtime/python/lib/python3.12/pprint.py +658 -0
- package/python-runtime/python/lib/python3.12/profile.py +615 -0
- package/python-runtime/python/lib/python3.12/pstats.py +778 -0
- package/python-runtime/python/lib/python3.12/pty.py +211 -0
- package/python-runtime/python/lib/python3.12/py_compile.py +212 -0
- package/python-runtime/python/lib/python3.12/pyclbr.py +314 -0
- package/python-runtime/python/lib/python3.12/pydoc.py +2950 -0
- package/python-runtime/python/lib/python3.12/queue.py +326 -0
- package/python-runtime/python/lib/python3.12/quopri.py +237 -0
- package/python-runtime/python/lib/python3.12/random.py +996 -0
- package/python-runtime/python/lib/python3.12/re/__init__.py +385 -0
- package/python-runtime/python/lib/python3.12/re/_casefix.py +106 -0
- package/python-runtime/python/lib/python3.12/re/_compiler.py +770 -0
- package/python-runtime/python/lib/python3.12/re/_constants.py +220 -0
- package/python-runtime/python/lib/python3.12/re/_parser.py +1080 -0
- package/python-runtime/python/lib/python3.12/reprlib.py +214 -0
- package/python-runtime/python/lib/python3.12/rlcompleter.py +219 -0
- package/python-runtime/python/lib/python3.12/runpy.py +319 -0
- package/python-runtime/python/lib/python3.12/sched.py +167 -0
- package/python-runtime/python/lib/python3.12/secrets.py +71 -0
- package/python-runtime/python/lib/python3.12/selectors.py +623 -0
- package/python-runtime/python/lib/python3.12/shelve.py +243 -0
- package/python-runtime/python/lib/python3.12/shlex.py +345 -0
- package/python-runtime/python/lib/python3.12/shutil.py +1566 -0
- package/python-runtime/python/lib/python3.12/signal.py +94 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/AvifImagePlugin.py +299 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/BdfFontFile.py +122 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/BlpImagePlugin.py +503 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/BmpImagePlugin.py +526 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/BufrStubImagePlugin.py +70 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ContainerIO.py +177 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/CurImagePlugin.py +105 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/DcxImagePlugin.py +88 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/DdsImagePlugin.py +637 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/EpsImagePlugin.py +494 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ExifTags.py +383 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/FitsImagePlugin.py +171 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/FliImagePlugin.py +188 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/FontFile.py +163 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/FpxImagePlugin.py +264 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/FtexImagePlugin.py +119 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/GbrImagePlugin.py +101 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/GdImageFile.py +109 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/GifImagePlugin.py +1152 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/GimpGradientFile.py +156 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/GimpPaletteFile.py +77 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/GribStubImagePlugin.py +70 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/Hdf5StubImagePlugin.py +70 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/IcnsImagePlugin.py +406 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/IcoImagePlugin.py +418 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImImagePlugin.py +401 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/Image.py +4390 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageChops.py +278 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageCms.py +1069 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageColor.py +321 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageDraw.py +1003 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageDraw2.py +250 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageEnhance.py +112 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageFile.py +944 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageFilter.py +596 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageFont.py +1335 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageGrab.py +229 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageMath.py +314 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageMode.py +85 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageMorph.py +317 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageOps.py +803 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImagePalette.py +314 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImagePath.py +20 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageQt.py +229 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageSequence.py +89 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageShow.py +372 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageStat.py +169 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageText.py +512 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageTk.py +269 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageTransform.py +138 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImageWin.py +247 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/ImtImagePlugin.py +103 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/IptcImagePlugin.py +228 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/Jpeg2KImagePlugin.py +472 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/JpegImagePlugin.py +913 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/JpegPresets.py +240 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/McIdasImagePlugin.py +80 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/MicImagePlugin.py +105 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/MpegImagePlugin.py +89 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/MpoImagePlugin.py +211 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/MspImagePlugin.py +206 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PSDraw.py +249 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PaletteFile.py +58 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PalmImagePlugin.py +220 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PcdImagePlugin.py +68 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PcfFontFile.py +258 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PcxImagePlugin.py +237 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PdfImagePlugin.py +313 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PdfParser.py +1129 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PixarImagePlugin.py +74 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PngImagePlugin.py +1616 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PpmImagePlugin.py +380 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/PsdImagePlugin.py +340 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/QoiImagePlugin.py +248 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/SgiImagePlugin.py +236 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/SpiderImagePlugin.py +329 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/SunImagePlugin.py +147 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/TarIO.py +68 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/TgaImagePlugin.py +295 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/TiffImagePlugin.py +2410 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/TiffTags.py +571 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/WalImageFile.py +134 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/WebPImagePlugin.py +352 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/WmfImagePlugin.py +189 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/XVThumbImagePlugin.py +83 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/XbmImagePlugin.py +128 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/XpmImagePlugin.py +175 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/__init__.py +87 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/__main__.py +7 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_avif.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_avif.pyi +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_binary.py +115 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_deprecate.py +74 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imaging.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imaging.pyi +31 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imagingcms.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imagingcms.pyi +143 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imagingft.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imagingft.pyi +70 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imagingmath.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imagingmath.pyi +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imagingmorph.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imagingmorph.pyi +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imagingtk.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_imagingtk.pyi +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_tkinter_finder.py +20 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_typing.py +46 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_util.py +29 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_version.py +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_webp.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/_webp.pyi +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/features.py +347 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/PIL/report.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/README.txt +2 -0
- package/python-runtime/python/lib/python3.12/site-packages/_cffi_backend.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/__init__.py +247 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/_cookies.py +53 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/_deserialize.py +62 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/_jsonrpc.py +28 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/_protocol_adapters.py +72 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/_schema_base.py +79 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/_sse.py +98 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/_transport.py +145 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/agent/__init__.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/agent/connection.py +367 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/agent/router.py +10 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/client/__init__.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/client/connection.py +626 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/client/router.py +10 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/connection.py +344 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/contrib/__init__.py +27 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/contrib/permissions.py +105 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/contrib/session_state.py +274 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/contrib/tool_calls.py +290 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/core.py +111 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/exceptions.py +50 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/__init__.py +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/negotiation.py +214 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/__init__.py +18 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/_connection.py +24 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/_initialization.py +67 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/_methods.py +58 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/_params.py +65 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/_router.py +74 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/_schema_base.py +60 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/agent.py +287 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/client.py +463 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/interfaces.py +314 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/meta.py +41 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/experimental/v2/schema.py +6018 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/http/__init__.py +30 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/http/asgi.py +97 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/http/client.py +266 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/http/protocol.py +115 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/http/server.py +374 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/interfaces.py +468 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/meta.py +50 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/py.typed +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/router.py +239 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/schema.py +5846 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/stdio.py +208 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/task/__init__.py +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/task/sender.py +63 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/task/supervisor.py +80 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/telemetry.py +41 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/transports.py +112 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/utils.py +265 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/ws/__init__.py +23 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/ws/client.py +124 -0
- package/python-runtime/python/lib/python3.12/site-packages/acp/ws/server.py +75 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/_generated/__init__.py +9 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/_generated/models.py +2825 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/_generated/version.py +12 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/core/__init__.py +242 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/core/capabilities.py +64 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/core/deprecated.py +46 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/core/events.py +131 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/core/token_usage.py +210 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/core/types.py +162 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/core/version.py +38 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/encoder/__init__.py +7 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/encoder/encoder.py +36 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui_protocol-1.0.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui_protocol-1.0.0.dist-info/METADATA +114 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui_protocol-1.0.0.dist-info/RECORD +32 -0
- package/python-runtime/python/lib/python3.12/site-packages/ag_ui_protocol-1.0.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/agent_client_protocol-1.0.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/agent_client_protocol-1.0.0.dist-info/METADATA +106 -0
- package/python-runtime/python/lib/python3.12/site-packages/agent_client_protocol-1.0.0.dist-info/RECORD +115 -0
- package/python-runtime/python/lib/python3.12/site-packages/agent_client_protocol-1.0.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/agent_client_protocol-1.0.0.dist-info/entry_points.txt +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/annotated_types/__init__.py +416 -0
- package/python-runtime/python/lib/python3.12/site-packages/annotated_types/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/annotated_types/test_cases.py +146 -0
- package/python-runtime/python/lib/python3.12/site-packages/annotated_types-0.8.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/annotated_types-0.8.0.dist-info/METADATA +295 -0
- package/python-runtime/python/lib/python3.12/site-packages/annotated_types-0.8.0.dist-info/RECORD +10 -0
- package/python-runtime/python/lib/python3.12/site-packages/annotated_types-0.8.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/__init__.py +154 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_backends/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_backends/_asyncio.py +3300 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_backends/_trio.py +1489 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_asyncio_selector_thread.py +167 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_concurrency_utils.py +156 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_contextmanagers.py +200 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_eventloop.py +244 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_exceptions.py +205 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_fileio.py +1047 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_futures.py +191 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_resources.py +18 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_signals.py +29 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_sockets.py +1032 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_streams.py +52 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_subprocesses.py +196 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_synchronization.py +780 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_tasks.py +464 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_tempfile.py +623 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_testing.py +82 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_core/_typedattr.py +90 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/_lazyimport.py +176 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/abc/__init__.py +63 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/abc/_eventloop.py +443 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/abc/_resources.py +39 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/abc/_sockets.py +401 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/abc/_streams.py +237 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/abc/_subprocesses.py +82 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/abc/_tasks.py +223 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/abc/_testing.py +79 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/from_thread.py +689 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/functools.py +400 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/itertools.py +632 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/lowlevel.py +228 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/pytest_plugin.py +408 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/streams/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/streams/buffered.py +212 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/streams/file.py +162 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/streams/memory.py +365 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/streams/stapled.py +160 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/streams/text.py +189 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/streams/tls.py +450 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/to_interpreter.py +246 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/to_process.py +269 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio/to_thread.py +80 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio-4.16.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio-4.16.0.dist-info/METADATA +108 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio-4.16.0.dist-info/RECORD +100 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio-4.16.0.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/anyio-4.16.0.dist-info/entry_points.txt +2 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/__init__.py +104 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/__init__.pyi +389 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/_cmp.py +160 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/_cmp.pyi +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/_compat.py +99 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/_config.py +31 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/_funcs.py +497 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/_make.py +3406 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/_next_gen.py +674 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/_typing_compat.pyi +15 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/_version_info.py +89 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/_version_info.pyi +9 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/converters.py +162 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/converters.pyi +19 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/exceptions.py +95 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/exceptions.pyi +17 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/filters.py +72 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/filters.pyi +6 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/setters.py +79 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/setters.pyi +20 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/validators.py +750 -0
- package/python-runtime/python/lib/python3.12/site-packages/attr/validators.pyi +140 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs/__init__.py +72 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs/__init__.pyi +314 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs/converters.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs/exceptions.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs/filters.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs/setters.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs/validators.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs-26.1.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs-26.1.0.dist-info/METADATA +199 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs-26.1.0.dist-info/RECORD +55 -0
- package/python-runtime/python/lib/python3.12/site-packages/attrs-26.1.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/certifi/__init__.py +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/certifi/__main__.py +12 -0
- package/python-runtime/python/lib/python3.12/site-packages/certifi/cacert.pem +3885 -0
- package/python-runtime/python/lib/python3.12/site-packages/certifi/core.py +83 -0
- package/python-runtime/python/lib/python3.12/site-packages/certifi/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/certifi-2026.10.23.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/certifi-2026.10.23.dist-info/METADATA +79 -0
- package/python-runtime/python/lib/python3.12/site-packages/certifi-2026.10.23.dist-info/RECORD +18 -0
- package/python-runtime/python/lib/python3.12/site-packages/certifi-2026.10.23.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/__init__.py +14 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/_cffi_errors.h +135 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/_cffi_gen_src.py +216 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/_cffi_include.h +397 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/_embedding.h +512 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/_imp_emulation.py +83 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/_shimmed_dist_utils.py +45 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/api.py +960 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/backend_ctypes.py +1120 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/cffi_opcode.py +187 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/commontypes.py +82 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/cparser.py +1014 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/error.py +31 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/ffiplatform.py +113 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/gen_src.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/lock.py +30 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/model.py +617 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/parse_c_type.h +181 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/pkgconfig.py +121 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/recompiler.py +1586 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/setuptools_ext.py +231 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/vengine_cpy.py +1058 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/vengine_gen.py +679 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi/verifier.py +306 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi-2.1.1.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi-2.1.1.dist-info/METADATA +67 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi-2.1.1.dist-info/RECORD +53 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi-2.1.1.dist-info/WHEEL +6 -0
- package/python-runtime/python/lib/python3.12/site-packages/cffi-2.1.1.dist-info/entry_points.txt +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/__init__.py +144 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/_compat.py +590 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/_termui_impl.py +970 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/_textwrap.py +188 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/_utils.py +45 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/_winconsole.py +292 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/core.py +3825 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/decorators.py +625 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/exceptions.py +378 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/formatting.py +320 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/globals.py +67 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/parser.py +533 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/shell_completion.py +796 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/termui.py +1024 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/testing.py +796 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/types.py +1437 -0
- package/python-runtime/python/lib/python3.12/site-packages/click/utils.py +676 -0
- package/python-runtime/python/lib/python3.12/site-packages/click-8.5.1.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/click-8.5.1.dist-info/METADATA +83 -0
- package/python-runtime/python/lib/python3.12/site-packages/click-8.5.1.dist-info/RECORD +40 -0
- package/python-runtime/python/lib/python3.12/site-packages/click-8.5.1.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/__about__.py +17 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/__init__.py +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/cobblestone.py +21 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/exceptions.py +52 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/fernet.py +240 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/__init__.py +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/_oid.py +373 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/asn1/__init__.py +47 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/asn1/asn1.py +533 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/backends/__init__.py +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/backends/openssl/__init__.py +9 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/backends/openssl/backend.py +309 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi +67 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/_openssl.pyi +8 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi +7 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/cobblestone.pyi +33 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/declarative_asn1.pyi +133 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/exceptions.pyi +17 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi +117 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi +82 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/aead.pyi +189 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/ciphers.pyi +38 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/cmac.pyi +18 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi +51 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi +41 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/ec.pyi +52 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi +30 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi +22 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/hpke.pyi +109 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi +205 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/keys.pyi +34 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/keywrap.pyi +28 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/mldsa.pyi +35 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/mlkem.pyi +18 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi +15 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/rsa.pyi +55 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/pkcs12.pyi +52 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi +50 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/test_support.pyi +23 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust/x509.pyi +313 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust.abi3.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/openssl/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/openssl/_conditional.py +199 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/bindings/openssl/binding.py +107 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/decrepit/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/decrepit/ciphers/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/decrepit/ciphers/algorithms.py +145 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/decrepit/ciphers/modes.py +53 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/_asymmetric.py +19 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py +60 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/_modes.py +105 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/_serialization.py +136 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/dh.py +253 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py +179 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/ec.py +369 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py +116 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py +143 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/mldsa.py +505 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/mlkem.py +278 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/padding.py +141 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py +295 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/types.py +94 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/utils.py +28 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py +134 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/asymmetric/x448.py +137 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/ciphers/__init__.py +27 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/ciphers/aead.py +23 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py +138 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/ciphers/base.py +146 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/ciphers/modes.py +192 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/cmac.py +10 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/constant_time.py +14 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/hashes.py +357 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/hmac.py +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/hpke.py +27 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/kdf/__init__.py +32 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/kdf/argon2.py +17 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py +16 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/kdf/hkdf.py +16 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py +26 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/kdf/scrypt.py +19 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/keywrap.py +25 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/padding.py +69 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/poly1305.py +11 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/serialization/__init__.py +85 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/serialization/base.py +16 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py +176 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py +412 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/serialization/ssh.py +1615 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/twofactor/__init__.py +9 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/twofactor/hotp.py +101 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/hazmat/primitives/twofactor/totp.py +56 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/utils.py +136 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/x509/__init__.py +270 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/x509/base.py +834 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/x509/certificate_transparency.py +35 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/x509/extensions.py +2533 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/x509/general_name.py +281 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/x509/name.py +489 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/x509/ocsp.py +379 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/x509/oid.py +37 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography/x509/verification.py +34 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography-50.0.2.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography-50.0.2.dist-info/METADATA +111 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography-50.0.2.dist-info/RECORD +199 -0
- package/python-runtime/python/lib/python3.12/site-packages/cryptography-50.0.2.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/dotenv/__init__.py +51 -0
- package/python-runtime/python/lib/python3.12/site-packages/dotenv/__main__.py +6 -0
- package/python-runtime/python/lib/python3.12/site-packages/dotenv/cli.py +246 -0
- package/python-runtime/python/lib/python3.12/site-packages/dotenv/ipython.py +50 -0
- package/python-runtime/python/lib/python3.12/site-packages/dotenv/main.py +487 -0
- package/python-runtime/python/lib/python3.12/site-packages/dotenv/parser.py +191 -0
- package/python-runtime/python/lib/python3.12/site-packages/dotenv/py.typed +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/dotenv/variables.py +86 -0
- package/python-runtime/python/lib/python3.12/site-packages/dotenv/version.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/__init__.py +62 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/_abnf.py +132 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/_connection.py +659 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/_events.py +369 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/_headers.py +282 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/_readers.py +250 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/_receivebuffer.py +153 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/_state.py +365 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/_util.py +135 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/_version.py +16 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/_writers.py +145 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11/py.typed +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11-0.16.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11-0.16.0.dist-info/METADATA +202 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11-0.16.0.dist-info/RECORD +29 -0
- package/python-runtime/python/lib/python3.12/site-packages/h11-0.16.0.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/__init__.py +141 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_api.py +94 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_async/__init__.py +39 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_async/connection.py +222 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_async/connection_pool.py +420 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_async/http11.py +379 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_async/http2.py +592 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_async/http_proxy.py +367 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_async/interfaces.py +137 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_async/socks_proxy.py +341 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_backends/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_backends/anyio.py +146 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_backends/auto.py +52 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_backends/base.py +101 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_backends/mock.py +143 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_backends/sync.py +241 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_backends/trio.py +159 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_exceptions.py +81 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_models.py +516 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_ssl.py +9 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_sync/__init__.py +39 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_sync/connection.py +222 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_sync/connection_pool.py +420 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_sync/http11.py +379 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_sync/http2.py +592 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_sync/http_proxy.py +367 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_sync/interfaces.py +137 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_sync/socks_proxy.py +341 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_synchronization.py +318 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_trace.py +107 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/_utils.py +37 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/METADATA +625 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/RECORD +68 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/__init__.py +105 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/__version__.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_api.py +438 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_auth.py +348 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_client.py +2019 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_config.py +248 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_content.py +240 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_decoders.py +393 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_exceptions.py +379 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_main.py +506 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_models.py +1277 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_multipart.py +300 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_status_codes.py +162 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_transports/__init__.py +15 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_transports/asgi.py +187 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_transports/base.py +86 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_transports/default.py +406 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_transports/mock.py +43 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_transports/wsgi.py +149 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_types.py +114 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_urlparse.py +527 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_urls.py +641 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/_utils.py +242 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx-0.28.1.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx-0.28.1.dist-info/METADATA +203 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx-0.28.1.dist-info/RECORD +54 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx-0.28.1.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx-0.28.1.dist-info/entry_points.txt +2 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx_sse/__init__.py +14 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx_sse/_api.py +93 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx_sse/_decoders.py +139 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx_sse/_exceptions.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx_sse/_models.py +54 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx_sse/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx_sse-0.4.3.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx_sse-0.4.3.dist-info/METADATA +351 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx_sse-0.4.3.dist-info/RECORD +17 -0
- package/python-runtime/python/lib/python3.12/site-packages/httpx_sse-0.4.3.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/__init__.py +47 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/__main__.py +6 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/cli.py +132 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/codec.py +225 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/compat.py +43 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/core.py +863 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/idnadata.py +1933 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/intranges.py +55 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/package_data.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna/uts46data.py +17117 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna-3.20.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna-3.20.dist-info/METADATA +176 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna-3.20.dist-info/RECORD +28 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna-3.20.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/idna-3.20.dist-info/entry_points.txt +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/__init__.py +120 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/__main__.py +6 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/_format.py +546 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/_keywords.py +449 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/_legacy_keywords.py +449 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/_types.py +204 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/_typing.py +29 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/_utils.py +355 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/const_vs_enum.py +30 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/contains.py +28 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/import_benchmark.py +31 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/issue232/issue.json +2653 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/issue232.py +25 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/json_schema_test_suite.py +12 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/nested_schemas.py +56 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/subcomponents.py +42 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/unused_registry.py +35 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/useless_applicator_schemas.py +106 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/useless_keywords.py +32 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/benchmarks/validator_creation.py +14 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/cli.py +292 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/exceptions.py +490 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/protocols.py +230 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema/validators.py +1410 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema-4.26.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema-4.26.0.dist-info/METADATA +170 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema-4.26.0.dist-info/RECORD +82 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema-4.26.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema-4.26.0.dist-info/entry_points.txt +2 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/__init__.py +12 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/_core.py +38 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft201909/metaschema.json +42 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/applicator +56 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/content +17 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/core +57 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/format +14 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/meta-data +37 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/validation +98 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft202012/metaschema.json +58 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/applicator +48 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/content +17 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/core +51 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/format-annotation +14 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/format-assertion +14 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/meta-data +37 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/unevaluated +15 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/validation +98 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft3/metaschema.json +172 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft4/metaschema.json +149 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft6/metaschema.json +153 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications/schemas/draft7/metaschema.json +166 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications-2025.9.1.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications-2025.9.1.dist-info/METADATA +54 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications-2025.9.1.dist-info/RECORD +33 -0
- package/python-runtime/python/lib/python3.12/site-packages/jsonschema_specifications-2025.9.1.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/__init__.py +78 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/algorithms.py +1121 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/api_jwk.py +196 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/api_jws.py +485 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/api_jwt.py +595 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/exceptions.py +113 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/help.py +66 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/jwk_set_cache.py +47 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/jwks_client.py +333 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/types.py +69 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/utils.py +146 -0
- package/python-runtime/python/lib/python3.12/site-packages/jwt/warnings.py +11 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/__init__.py +135 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/cli/__init__.py +6 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/cli/claude.py +148 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/cli/cli.py +488 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/__main__.py +85 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/auth/__init__.py +21 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/auth/exceptions.py +10 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/auth/extensions/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/auth/extensions/client_credentials.py +567 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/auth/oauth2.py +682 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/auth/utils.py +395 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/experimental/__init__.py +9 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/experimental/task_handlers.py +290 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/experimental/tasks.py +224 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/session.py +640 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/session_group.py +447 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/sse.py +177 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/stdio/__init__.py +278 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/streamable_http.py +747 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/client/websocket.py +94 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/os/__init__.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/os/posix/__init__.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/os/posix/utilities.py +60 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/os/win32/__init__.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/os/win32/utilities.py +338 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/__main__.py +50 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/__init__.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/errors.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/handlers/__init__.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/handlers/authorize.py +224 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/handlers/metadata.py +29 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/handlers/register.py +136 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/handlers/revoke.py +91 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/handlers/token.py +241 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/json_response.py +10 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/middleware/__init__.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/middleware/auth_context.py +48 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/middleware/bearer_auth.py +173 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/middleware/client_auth.py +115 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/provider.py +314 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/routes.py +254 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/auth/settings.py +56 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/elicitation.py +190 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/experimental/__init__.py +12 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/experimental/request_context.py +285 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/experimental/session_features.py +226 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/experimental/task_context.py +614 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/experimental/task_result_handler.py +243 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/experimental/task_scope.py +75 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/experimental/task_support.py +128 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/__init__.py +11 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/exceptions.py +21 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/prompts/__init__.py +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/prompts/base.py +183 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/prompts/manager.py +60 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/resources/__init__.py +23 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/resources/base.py +50 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/resources/resource_manager.py +115 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/resources/templates.py +122 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/resources/types.py +203 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/server.py +1390 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/tools/__init__.py +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/tools/base.py +126 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/tools/tool_manager.py +93 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/utilities/__init__.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/utilities/context_injection.py +68 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/utilities/func_metadata.py +560 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/utilities/logging.py +43 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/fastmcp/utilities/types.py +101 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/lowlevel/__init__.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/lowlevel/experimental.py +342 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/lowlevel/func_inspection.py +54 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/lowlevel/helper_types.py +11 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/lowlevel/server.py +830 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/models.py +20 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/session.py +701 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/sse.py +299 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/stdio.py +88 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/streamable_http.py +1131 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/streamable_http_manager.py +425 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/transport_security.py +194 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/validation.py +104 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/server/websocket.py +89 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/_httpx_utils.py +219 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/auth.py +180 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/auth_utils.py +80 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/context.py +32 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/exceptions.py +71 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/experimental/__init__.py +7 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/experimental/tasks/__init__.py +12 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/experimental/tasks/capabilities.py +115 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/experimental/tasks/context.py +101 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/experimental/tasks/helpers.py +181 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/experimental/tasks/in_memory_task_store.py +219 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/experimental/tasks/message_queue.py +241 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/experimental/tasks/polling.py +45 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/experimental/tasks/resolver.py +60 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/experimental/tasks/store.py +156 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/memory.py +98 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/message.py +50 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/metadata_utils.py +45 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/progress.py +58 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/response_router.py +63 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/session.py +552 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/tool_name_validation.py +129 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/shared/version.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp/types.py +1999 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp-1.30.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp-1.30.0.dist-info/METADATA +239 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp-1.30.0.dist-info/RECORD +228 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp-1.30.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/mcp-1.30.0.dist-info/entry_points.txt +2 -0
- package/python-runtime/python/lib/python3.12/site-packages/multipart/__init__.py +38 -0
- package/python-runtime/python/lib/python3.12/site-packages/multipart/decoders.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/multipart/exceptions.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/multipart/multipart.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/pillow-13.0.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/pillow-13.0.0.dist-info/METADATA +182 -0
- package/python-runtime/python/lib/python3.12/site-packages/pillow-13.0.0.dist-info/RECORD +236 -0
- package/python-runtime/python/lib/python3.12/site-packages/pillow-13.0.0.dist-info/WHEEL +6 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser/__init__.py +98 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser/_ast_gen.py +385 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser/_c_ast.cfg +268 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser/ast_transforms.py +201 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser/c_ast.py +1670 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser/c_generator.py +866 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser/c_lexer.py +861 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser/c_parser.py +2759 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser-3.12.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser-3.12.dist-info/METADATA +286 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser-3.12.dist-info/RECORD +21 -0
- package/python-runtime/python/lib/python3.12/site-packages/pycparser-3.12.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/__init__.py +461 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_config.py +408 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_contextlib.py +84 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_core_metadata.py +97 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_core_utils.py +156 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_dataclasses.py +327 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_decorators.py +906 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_decorators_v1.py +174 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_discriminated_union.py +510 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_docs_extraction.py +128 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_fields.py +910 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_forward_ref.py +23 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py +3053 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_generics.py +556 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_git.py +27 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_import_utils.py +20 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_known_annotated_metadata.py +412 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_mock_val_ser.py +241 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_model_construction.py +833 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_namespace_utils.py +300 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_repr.py +122 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_schema_gather.py +49 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_schema_generation_shared.py +126 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_serializers.py +59 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_signature.py +193 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_type_refs.py +128 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_typing_extra.py +506 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_utils.py +433 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_validate_call.py +141 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_internal/_validators.py +541 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/_migration.py +317 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/alias_generators.py +62 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/aliases.py +136 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/annotated_handlers.py +123 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/class_validators.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/color.py +605 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/config.py +1295 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/dataclasses.py +385 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/datetime_parse.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/decorator.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/deprecated/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/deprecated/class_validators.py +257 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/deprecated/config.py +72 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/deprecated/copy_internals.py +224 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/deprecated/decorator.py +286 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/deprecated/json.py +142 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/deprecated/parse.py +81 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/deprecated/tools.py +104 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/env_settings.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/error_wrappers.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/errors.py +185 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/experimental/__init__.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/experimental/arguments_schema.py +44 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/experimental/missing_sentinel.py +29 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/experimental/pipeline.py +684 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/fields.py +2065 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/functional_serializers.py +461 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/functional_validators.py +920 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/generics.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/json.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/json_schema.py +3281 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/main.py +1947 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/mypy.py +1469 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/networks.py +1417 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/parse.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/plugin/__init__.py +190 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/plugin/_loader.py +56 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/plugin/_schema_validator.py +152 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/root_model.py +189 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/schema.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/tools.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/type_adapter.py +780 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/types.py +3405 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/typing.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/utils.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/__init__.py +131 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/_hypothesis_plugin.py +391 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/annotated_types.py +72 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/class_validators.py +361 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/color.py +494 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/config.py +191 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/dataclasses.py +503 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/datetime_parse.py +248 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/decorator.py +264 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/env_settings.py +350 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/error_wrappers.py +161 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/errors.py +646 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/fields.py +1253 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/generics.py +400 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/json.py +112 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/main.py +1130 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/mypy.py +950 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/networks.py +747 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/parse.py +66 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/schema.py +1163 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/tools.py +92 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/types.py +1213 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/typing.py +627 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/utils.py +807 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/validators.py +768 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/v1/version.py +38 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/validate_call_decorator.py +121 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/validators.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/version.py +113 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic/warnings.py +130 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic-2.14.3.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic-2.14.3.dist-info/METADATA +1646 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic-2.14.3.dist-info/RECORD +219 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic-2.14.3.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_core/__init__.py +194 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_core/_pydantic_core/__init__.pyi +1114 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_core/_pydantic_core/_schema_gather.pyi +34 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_core/_pydantic_core.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_core/core_schema.py +5093 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_core/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_core-2.50.4.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_core-2.50.4.dist-info/METADATA +172 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_core-2.50.4.dist-info/RECORD +14 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_core-2.50.4.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/__init__.py +74 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/exceptions.py +10 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/main.py +1133 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/__init__.py +91 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/base.py +767 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/__init__.py +48 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/aws.py +158 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/azure.py +246 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/cli.py +1942 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/dotenv.py +226 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/env.py +423 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/gcp.py +365 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/json.py +61 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/nested_secrets.py +220 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/pyproject.py +64 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/secrets.py +146 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/toml.py +72 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/providers/yaml.py +147 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/types.py +109 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/sources/utils.py +515 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/utils.py +46 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings/version.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings-2.16.2.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings-2.16.2.dist-info/METADATA +72 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings-2.16.2.dist-info/RECORD +50 -0
- package/python-runtime/python/lib/python3.12/site-packages/pydantic_settings-2.16.2.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/pyjwt-2.15.1.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/pyjwt-2.15.1.dist-info/METADATA +94 -0
- package/python-runtime/python/lib/python3.12/site-packages/pyjwt-2.15.1.dist-info/RECORD +32 -0
- package/python-runtime/python/lib/python3.12/site-packages/pyjwt-2.15.1.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_dotenv-1.2.4.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_dotenv-1.2.4.dist-info/METADATA +835 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_dotenv-1.2.4.dist-info/RECORD +25 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_dotenv-1.2.4.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_dotenv-1.2.4.dist-info/entry_points.txt +2 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_multipart/__init__.py +35 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_multipart/decoders.py +185 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_multipart/exceptions.py +34 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_multipart/multipart.py +2005 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_multipart/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_multipart-0.0.33.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_multipart-0.0.33.dist-info/METADATA +179 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_multipart-0.0.33.dist-info/RECORD +22 -0
- package/python-runtime/python/lib/python3.12/site-packages/python_multipart-0.0.33.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing/__init__.py +7 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing/_attrs.py +31 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing/_attrs.pyi +21 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing/_core.py +739 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing/exceptions.py +165 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing/jsonschema.py +642 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing/retrieval.py +94 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing/typing.py +61 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing-0.37.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing-0.37.0.dist-info/METADATA +64 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing-0.37.0.dist-info/RECORD +33 -0
- package/python-runtime/python/lib/python3.12/site-packages/referencing-0.37.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/rpds/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/rpds/__init__.pyi +79 -0
- package/python-runtime/python/lib/python3.12/site-packages/rpds/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/rpds/rpds.cpython-312-darwin.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/rpds_py-2026.9.1.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/rpds_py-2026.9.1.dist-info/METADATA +99 -0
- package/python-runtime/python/lib/python3.12/site-packages/rpds_py-2026.9.1.dist-info/RECORD +11 -0
- package/python-runtime/python/lib/python3.12/site-packages/rpds_py-2026.9.1.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio/__init__.py +46 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio/_types.py +3 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio/compat.py +86 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio/exceptions.py +6 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio/socks4.py +253 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio/socks5.py +399 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio/utils.py +95 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio-1.0.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio-1.0.0.dist-info/METADATA +182 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio-1.0.0.dist-info/RECORD +20 -0
- package/python-runtime/python/lib/python3.12/site-packages/socksio-1.0.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/sse_starlette/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/sse_starlette/_utils.py +36 -0
- package/python-runtime/python/lib/python3.12/site-packages/sse_starlette/event.py +96 -0
- package/python-runtime/python/lib/python3.12/site-packages/sse_starlette/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/sse_starlette/sse.py +602 -0
- package/python-runtime/python/lib/python3.12/site-packages/sse_starlette-3.7.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/sse_starlette-3.7.0.dist-info/METADATA +493 -0
- package/python-runtime/python/lib/python3.12/site-packages/sse_starlette-3.7.0.dist-info/RECORD +16 -0
- package/python-runtime/python/lib/python3.12/site-packages/sse_starlette-3.7.0.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/__init__.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/_exception_handler.py +67 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/_utils.py +152 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/applications.py +124 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/authentication.py +157 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/background.py +36 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/concurrency.py +59 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/config.py +142 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/convertors.py +89 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/datastructures.py +717 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/endpoints.py +128 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/exceptions.py +43 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/formparsers.py +289 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/__init__.py +37 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/authentication.py +52 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/base.py +254 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/body_limit.py +132 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/cors.py +177 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/errors.py +259 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/exceptions.py +73 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/gzip.py +230 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/httpsredirect.py +22 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/opentelemetry.py +126 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/sessions.py +139 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/trustedhost.py +66 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/middleware/wsgi.py +157 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/requests.py +357 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/responses.py +616 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/routing.py +772 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/schemas.py +152 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/staticfiles.py +231 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/status.py +211 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/templating.py +156 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/testclient.py +624 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/types.py +26 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette/websockets.py +202 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette-1.10.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette-1.10.0.dist-info/METADATA +181 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette-1.10.0.dist-info/RECORD +78 -0
- package/python-runtime/python/lib/python3.12/site-packages/starlette-1.10.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness/__init__.py +49 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness/budget.py +70 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness/completion.py +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness/generated.py +250 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness/policy.py +35 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness/retry.py +21 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness/safety.py +170 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness/tracing.py +138 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness-0.9.1.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness-0.9.1.dist-info/METADATA +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness-0.9.1.dist-info/RECORD +23 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_harness-0.9.1.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_protocol/__init__.py +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_protocol/generated.py +250 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_protocol-0.9.1.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_protocol-0.9.1.dist-info/METADATA +12 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_protocol-0.9.1.dist-info/RECORD +11 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_protocol-0.9.1.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/__init__.py +529 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/antihallucination.py +644 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/approval.py +730 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/approval_policy.py +243 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/ask_user.py +324 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/branch.py +419 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/cache_control.py +254 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/calibration.py +318 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/compaction.py +737 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/compaction_policy.py +97 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/config.py +225 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/default.harness.json +32 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/default.harness.yaml +38 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/delegation_gate.py +100 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/errors.py +58 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/gateway_catalog.py +397 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/handoff.py +147 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/harness.py +922 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/harness_spec.py +339 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/history.py +962 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/hooks.py +541 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/llm/__init__.py +204 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/llm/anthropic_native.py +392 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/llm/compat.py +316 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/llm/errors.py +207 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/llm/google_genai.py +454 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/llm/openai_compat.py +769 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/llm/openai_responses.py +554 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/llm/parts.py +69 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/llm/presets.py +259 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/llm/system_proxy.py +309 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/loop.py +1040 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/maintenance.py +238 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/mcp.py +673 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/mcp_server.py +319 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/model_catalog.py +7742 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/model_info.py +472 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/model_resolve.py +271 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/native_bridge.py +1034 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/observation_aging.py +196 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/orchestration.py +462 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/otel.py +384 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/plugins.py +487 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/pool.py +438 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/pricing.py +88 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/pseudo.py +713 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/recording.py +454 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/reminders.py +339 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/replay.py +222 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/resume.py +343 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/retry.py +163 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/sandboxed.py +201 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/skills.py +730 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/spill.py +127 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/storage/__init__.py +138 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/storage/in_memory.py +215 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/storage/sqlalchemy_store.py +472 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/storage/sqlite_store.py +497 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/storage/write_lease.py +173 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/subagent.py +564 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/todo.py +348 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/tokens.py +162 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/tool_presentation.py +132 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/tool_schema.py +124 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/tool_search.py +177 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/tools.py +457 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/tracing.py +285 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/transport/__init__.py +39 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/transport/fastapi_sse.py +116 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/transport/stdio_jsonrpc.py +431 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime/world_state.py +345 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime-0.9.1.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime-0.9.1.dist-info/METADATA +72 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime-0.9.1.dist-info/RECORD +147 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime-0.9.1.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime_native/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime_native/steerable_agent_runtime_native.abi3.so +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime_native-1.0.7.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime_native-1.0.7.dist-info/METADATA +7 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime_native-1.0.7.dist-info/RECORD +9 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_agent_runtime_native-1.0.7.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/__init__.py +28 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/__main__.py +119 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/_version.py +14 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/acp_adapter.py +890 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/acp_fs.py +64 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/acp_terminal.py +147 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/ag_ui.py +223 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/delivery.py +2933 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/display.py +308 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/egress_ask.py +183 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/file_edit.py +251 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/headless.py +760 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/host_spawn.py +137 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/host_tools.py +255 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/jpeg_ascii.py +314 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/landlock.py +353 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/landlock_run.py +35 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/loop_limits.py +85 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/multi_file_edit.py +109 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/png_ascii.py +294 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/ptc_js.py +986 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/ptc_js_worker.cjs +579 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/run_code.py +634 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/run_code_driver.py +229 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/sandbox.py +771 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/search_tools.py +173 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/shell_session.py +301 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/sidecar.py +3785 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/stream_chunks.py +115 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/todo_tools.py +49 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/tool_contract.json +352 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/tool_contract.py +62 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/web_tools.py +1375 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/workspace_fs.py +71 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar/workspace_tools.py +1472 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar-0.9.1.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar-0.9.1.dist-info/METADATA +58 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar-0.9.1.dist-info/RECORD +79 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar-0.9.1.dist-info/WHEEL +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/steerable_sidecar-0.9.1.dist-info/entry_points.txt +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_extensions-4.16.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_extensions-4.16.0.dist-info/METADATA +73 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_extensions-4.16.0.dist-info/RECORD +7 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_extensions-4.16.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_extensions.py +4422 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_inspection/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_inspection/introspection.py +604 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_inspection/py.typed +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_inspection/typing_objects.py +620 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_inspection/typing_objects.pyi +421 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_inspection-0.4.5.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_inspection-0.4.5.dist-info/METADATA +49 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_inspection-0.4.5.dist-info/RECORD +13 -0
- package/python-runtime/python/lib/python3.12/site-packages/typing_inspection-0.4.5.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/__init__.py +5 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/__main__.py +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/_ansi.py +29 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/_compat.py +91 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/_subprocess.py +84 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/_types.py +280 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/config.py +618 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/importer.py +34 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/lifespan/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/lifespan/off.py +17 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/lifespan/on.py +137 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/logging.py +117 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/loops/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/loops/asyncio.py +11 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/loops/auto.py +17 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/loops/uvloop.py +10 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/loops/zuvloop.py +10 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/main.py +656 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/middleware/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/middleware/asgi2.py +15 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/middleware/message_logger.py +87 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py +187 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/middleware/wsgi.py +199 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/http/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/http/auto.py +15 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/http/auto_zttp_impl.py +89 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/http/flow_control.py +54 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/http/h11_impl.py +540 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py +581 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/http/zttp_h2_impl.py +559 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/http/zttp_impl.py +537 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/utils.py +62 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/websockets/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/websockets/auto.py +21 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/websockets/websockets_impl.py +390 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/websockets/websockets_sansio_impl.py +556 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/protocols/websockets/wsproto_impl.py +500 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/py.typed +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/server.py +356 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/supervisors/__init__.py +16 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/supervisors/basereload.py +124 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/supervisors/multiprocess.py +282 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/supervisors/statreload.py +52 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/supervisors/watchfilesreload.py +86 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn/workers.py +111 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn-0.54.0.dist-info/INSTALLER +1 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn-0.54.0.dist-info/METADATA +189 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn-0.54.0.dist-info/RECORD +98 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn-0.54.0.dist-info/WHEEL +4 -0
- package/python-runtime/python/lib/python3.12/site-packages/uvicorn-0.54.0.dist-info/entry_points.txt +2 -0
- package/python-runtime/python/lib/python3.12/site.py +693 -0
- package/python-runtime/python/lib/python3.12/smtplib.py +1109 -0
- package/python-runtime/python/lib/python3.12/sndhdr.py +271 -0
- package/python-runtime/python/lib/python3.12/socket.py +983 -0
- package/python-runtime/python/lib/python3.12/socketserver.py +863 -0
- package/python-runtime/python/lib/python3.12/sqlite3/__init__.py +70 -0
- package/python-runtime/python/lib/python3.12/sqlite3/__main__.py +127 -0
- package/python-runtime/python/lib/python3.12/sqlite3/dbapi2.py +108 -0
- package/python-runtime/python/lib/python3.12/sqlite3/dump.py +89 -0
- package/python-runtime/python/lib/python3.12/sre_compile.py +7 -0
- package/python-runtime/python/lib/python3.12/sre_constants.py +7 -0
- package/python-runtime/python/lib/python3.12/sre_parse.py +7 -0
- package/python-runtime/python/lib/python3.12/ssl.py +1488 -0
- package/python-runtime/python/lib/python3.12/stat.py +195 -0
- package/python-runtime/python/lib/python3.12/statistics.py +1454 -0
- package/python-runtime/python/lib/python3.12/string.py +309 -0
- package/python-runtime/python/lib/python3.12/stringprep.py +272 -0
- package/python-runtime/python/lib/python3.12/struct.py +15 -0
- package/python-runtime/python/lib/python3.12/subprocess.py +2216 -0
- package/python-runtime/python/lib/python3.12/sunau.py +533 -0
- package/python-runtime/python/lib/python3.12/symtable.py +362 -0
- package/python-runtime/python/lib/python3.12/sysconfig.py +894 -0
- package/python-runtime/python/lib/python3.12/tabnanny.py +340 -0
- package/python-runtime/python/lib/python3.12/tarfile.py +3031 -0
- package/python-runtime/python/lib/python3.12/telnetlib.py +680 -0
- package/python-runtime/python/lib/python3.12/tempfile.py +956 -0
- package/python-runtime/python/lib/python3.12/textwrap.py +491 -0
- package/python-runtime/python/lib/python3.12/this.py +28 -0
- package/python-runtime/python/lib/python3.12/threading.py +1708 -0
- package/python-runtime/python/lib/python3.12/timeit.py +381 -0
- package/python-runtime/python/lib/python3.12/token.py +143 -0
- package/python-runtime/python/lib/python3.12/tokenize.py +594 -0
- package/python-runtime/python/lib/python3.12/tomllib/__init__.py +10 -0
- package/python-runtime/python/lib/python3.12/tomllib/_parser.py +691 -0
- package/python-runtime/python/lib/python3.12/tomllib/_re.py +107 -0
- package/python-runtime/python/lib/python3.12/tomllib/_types.py +10 -0
- package/python-runtime/python/lib/python3.12/trace.py +748 -0
- package/python-runtime/python/lib/python3.12/traceback.py +1187 -0
- package/python-runtime/python/lib/python3.12/tracemalloc.py +560 -0
- package/python-runtime/python/lib/python3.12/tty.py +73 -0
- package/python-runtime/python/lib/python3.12/turtle.py +4207 -0
- package/python-runtime/python/lib/python3.12/types.py +333 -0
- package/python-runtime/python/lib/python3.12/typing.py +3494 -0
- package/python-runtime/python/lib/python3.12/unittest/__init__.py +85 -0
- package/python-runtime/python/lib/python3.12/unittest/__main__.py +18 -0
- package/python-runtime/python/lib/python3.12/unittest/_log.py +86 -0
- package/python-runtime/python/lib/python3.12/unittest/async_case.py +143 -0
- package/python-runtime/python/lib/python3.12/unittest/case.py +1456 -0
- package/python-runtime/python/lib/python3.12/unittest/loader.py +497 -0
- package/python-runtime/python/lib/python3.12/unittest/main.py +291 -0
- package/python-runtime/python/lib/python3.12/unittest/mock.py +3054 -0
- package/python-runtime/python/lib/python3.12/unittest/result.py +256 -0
- package/python-runtime/python/lib/python3.12/unittest/runner.py +292 -0
- package/python-runtime/python/lib/python3.12/unittest/signals.py +71 -0
- package/python-runtime/python/lib/python3.12/unittest/suite.py +379 -0
- package/python-runtime/python/lib/python3.12/unittest/util.py +170 -0
- package/python-runtime/python/lib/python3.12/urllib/__init__.py +0 -0
- package/python-runtime/python/lib/python3.12/urllib/error.py +74 -0
- package/python-runtime/python/lib/python3.12/urllib/parse.py +1262 -0
- package/python-runtime/python/lib/python3.12/urllib/request.py +2816 -0
- package/python-runtime/python/lib/python3.12/urllib/response.py +84 -0
- package/python-runtime/python/lib/python3.12/urllib/robotparser.py +275 -0
- package/python-runtime/python/lib/python3.12/uu.py +216 -0
- package/python-runtime/python/lib/python3.12/uuid.py +793 -0
- package/python-runtime/python/lib/python3.12/warnings.py +598 -0
- package/python-runtime/python/lib/python3.12/wave.py +653 -0
- package/python-runtime/python/lib/python3.12/weakref.py +674 -0
- package/python-runtime/python/lib/python3.12/webbrowser.py +689 -0
- package/python-runtime/python/lib/python3.12/xdrlib.py +242 -0
- package/python-runtime/python/lib/python3.12/xml/__init__.py +20 -0
- package/python-runtime/python/lib/python3.12/xml/dom/NodeFilter.py +27 -0
- package/python-runtime/python/lib/python3.12/xml/dom/__init__.py +140 -0
- package/python-runtime/python/lib/python3.12/xml/dom/domreg.py +99 -0
- package/python-runtime/python/lib/python3.12/xml/dom/expatbuilder.py +962 -0
- package/python-runtime/python/lib/python3.12/xml/dom/minicompat.py +109 -0
- package/python-runtime/python/lib/python3.12/xml/dom/minidom.py +2008 -0
- package/python-runtime/python/lib/python3.12/xml/dom/pulldom.py +336 -0
- package/python-runtime/python/lib/python3.12/xml/dom/xmlbuilder.py +389 -0
- package/python-runtime/python/lib/python3.12/xml/etree/ElementInclude.py +186 -0
- package/python-runtime/python/lib/python3.12/xml/etree/ElementPath.py +423 -0
- package/python-runtime/python/lib/python3.12/xml/etree/ElementTree.py +2085 -0
- package/python-runtime/python/lib/python3.12/xml/etree/__init__.py +33 -0
- package/python-runtime/python/lib/python3.12/xml/etree/cElementTree.py +3 -0
- package/python-runtime/python/lib/python3.12/xml/parsers/__init__.py +8 -0
- package/python-runtime/python/lib/python3.12/xml/parsers/expat.py +8 -0
- package/python-runtime/python/lib/python3.12/xml/sax/__init__.py +94 -0
- package/python-runtime/python/lib/python3.12/xml/sax/_exceptions.py +127 -0
- package/python-runtime/python/lib/python3.12/xml/sax/expatreader.py +454 -0
- package/python-runtime/python/lib/python3.12/xml/sax/handler.py +387 -0
- package/python-runtime/python/lib/python3.12/xml/sax/saxutils.py +369 -0
- package/python-runtime/python/lib/python3.12/xml/sax/xmlreader.py +378 -0
- package/python-runtime/python/lib/python3.12/zipapp.py +206 -0
- package/python-runtime/python/lib/python3.12/zipfile/__init__.py +2340 -0
- package/python-runtime/python/lib/python3.12/zipfile/__main__.py +4 -0
- package/python-runtime/python/lib/python3.12/zipfile/_path/__init__.py +412 -0
- package/python-runtime/python/lib/python3.12/zipfile/_path/glob.py +53 -0
- package/python-runtime/python/lib/python3.12/zipimport.py +712 -0
- package/python-runtime/python/lib/python3.12/zoneinfo/__init__.py +31 -0
- package/python-runtime/python/lib/python3.12/zoneinfo/_common.py +164 -0
- package/python-runtime/python/lib/python3.12/zoneinfo/_tzpath.py +181 -0
- package/python-runtime/python/lib/python3.12/zoneinfo/_zoneinfo.py +772 -0
- package/python-runtime/python/lib/tcl9/9.0/http-2.10.1.tm +5475 -0
- package/python-runtime/python/lib/tcl9/9.0/msgcat-1.7.1.tm +1349 -0
- package/python-runtime/python/lib/tcl9/9.0/platform/shell-1.1.4.tm +241 -0
- package/python-runtime/python/lib/tcl9/9.0/platform-1.1.0.tm +443 -0
- package/python-runtime/python/lib/tcl9/9.0/tcltest-2.5.10.tm +3588 -0
- package/python-runtime/python/lib/tcl9.0/auto.tcl +711 -0
- package/python-runtime/python/lib/tcl9.0/clock.tcl +2110 -0
- package/python-runtime/python/lib/tcl9.0/cookiejar0.2/cookiejar.tcl +746 -0
- package/python-runtime/python/lib/tcl9.0/cookiejar0.2/idna.tcl +292 -0
- package/python-runtime/python/lib/tcl9.0/cookiejar0.2/pkgIndex.tcl +3 -0
- package/python-runtime/python/lib/tcl9.0/cookiejar0.2/public_suffix_list.dat.gz +0 -0
- package/python-runtime/python/lib/tcl9.0/encoding/ascii.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/big5.enc +1516 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cns11643.enc +1584 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp1250.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp1251.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp1252.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp1253.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp1254.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp1255.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp1256.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp1257.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp1258.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp165.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp437.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp737.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp775.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp850.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp852.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp855.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp857.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp860.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp861.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp862.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp863.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp864.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp865.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp866.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp869.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp874.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp932.enc +801 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp936.enc +2162 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp949.enc +2128 -0
- package/python-runtime/python/lib/tcl9.0/encoding/cp950.enc +1499 -0
- package/python-runtime/python/lib/tcl9.0/encoding/dingbats.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/ebcdic.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/euc-cn.enc +1397 -0
- package/python-runtime/python/lib/tcl9.0/encoding/euc-jp.enc +1353 -0
- package/python-runtime/python/lib/tcl9.0/encoding/euc-kr.enc +1533 -0
- package/python-runtime/python/lib/tcl9.0/encoding/gb12345.enc +1414 -0
- package/python-runtime/python/lib/tcl9.0/encoding/gb1988.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/gb2312-raw.enc +1380 -0
- package/python-runtime/python/lib/tcl9.0/encoding/gb2312.enc +1397 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso2022-jp.enc +12 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso2022-kr.enc +7 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso2022.enc +14 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-1.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-10.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-11.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-13.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-14.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-15.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-16.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-2.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-3.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-4.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-5.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-6.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-7.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-8.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/iso8859-9.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/jis0201.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/jis0208.enc +1319 -0
- package/python-runtime/python/lib/tcl9.0/encoding/jis0212.enc +1159 -0
- package/python-runtime/python/lib/tcl9.0/encoding/koi8-r.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/koi8-ru.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/koi8-t.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/koi8-u.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/ksc5601.enc +1516 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macCentEuro.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macCroatian.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macCyrillic.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macDingbats.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macGreek.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macIceland.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macJapan.enc +785 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macRoman.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macRomania.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macThai.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macTurkish.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/macUkraine.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/shiftjis.enc +690 -0
- package/python-runtime/python/lib/tcl9.0/encoding/symbol.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/encoding/tis-620.enc +20 -0
- package/python-runtime/python/lib/tcl9.0/foreachline.tcl +25 -0
- package/python-runtime/python/lib/tcl9.0/history.tcl +335 -0
- package/python-runtime/python/lib/tcl9.0/icu.tcl +145 -0
- package/python-runtime/python/lib/tcl9.0/init.tcl +773 -0
- package/python-runtime/python/lib/tcl9.0/install.tcl +275 -0
- package/python-runtime/python/lib/tcl9.0/opt0.4/optparse.tcl +1069 -0
- package/python-runtime/python/lib/tcl9.0/opt0.4/pkgIndex.tcl +12 -0
- package/python-runtime/python/lib/tcl9.0/package.tcl +767 -0
- package/python-runtime/python/lib/tcl9.0/parray.tcl +28 -0
- package/python-runtime/python/lib/tcl9.0/readfile.tcl +23 -0
- package/python-runtime/python/lib/tcl9.0/safe.tcl +1461 -0
- package/python-runtime/python/lib/tcl9.0/tclAppInit.c +183 -0
- package/python-runtime/python/lib/tcl9.0/tclIndex +112 -0
- package/python-runtime/python/lib/tcl9.0/tm.tcl +378 -0
- package/python-runtime/python/lib/tcl9.0/word.tcl +155 -0
- package/python-runtime/python/lib/tcl9.0/writefile.tcl +37 -0
- package/python-runtime/python/lib/thread3.0.4/libtcl9thread3.0.4.dylib +0 -0
- package/python-runtime/python/lib/thread3.0.4/libthread3.0.4.dylib +0 -0
- package/python-runtime/python/lib/thread3.0.4/pkgIndex.tcl +52 -0
- package/python-runtime/python/lib/thread3.0.4/ttrace.tcl +943 -0
- package/python-runtime/python/lib/tk9.0/bgerror.tcl +282 -0
- package/python-runtime/python/lib/tk9.0/button.tcl +782 -0
- package/python-runtime/python/lib/tk9.0/choosedir.tcl +310 -0
- package/python-runtime/python/lib/tk9.0/clrpick.tcl +696 -0
- package/python-runtime/python/lib/tk9.0/comdlg.tcl +322 -0
- package/python-runtime/python/lib/tk9.0/console.tcl +1148 -0
- package/python-runtime/python/lib/tk9.0/dialog.tcl +175 -0
- package/python-runtime/python/lib/tk9.0/entry.tcl +720 -0
- package/python-runtime/python/lib/tk9.0/focus.tcl +178 -0
- package/python-runtime/python/lib/tk9.0/fontchooser.tcl +512 -0
- package/python-runtime/python/lib/tk9.0/iconbadges.tcl +253 -0
- package/python-runtime/python/lib/tk9.0/iconlist.tcl +705 -0
- package/python-runtime/python/lib/tk9.0/icons.tcl +54 -0
- package/python-runtime/python/lib/tk9.0/images/README +7 -0
- package/python-runtime/python/lib/tk9.0/images/logo.eps +2091 -0
- package/python-runtime/python/lib/tk9.0/images/logo100.gif +0 -0
- package/python-runtime/python/lib/tk9.0/images/logo64.gif +0 -0
- package/python-runtime/python/lib/tk9.0/images/logoLarge.gif +0 -0
- package/python-runtime/python/lib/tk9.0/images/logoMed.gif +0 -0
- package/python-runtime/python/lib/tk9.0/images/pwrdLogo.eps +1897 -0
- package/python-runtime/python/lib/tk9.0/images/pwrdLogo100.gif +0 -0
- package/python-runtime/python/lib/tk9.0/images/pwrdLogo150.gif +0 -0
- package/python-runtime/python/lib/tk9.0/images/pwrdLogo175.gif +0 -0
- package/python-runtime/python/lib/tk9.0/images/pwrdLogo200.gif +0 -0
- package/python-runtime/python/lib/tk9.0/images/pwrdLogo75.gif +0 -0
- package/python-runtime/python/lib/tk9.0/images/tai-ku.gif +0 -0
- package/python-runtime/python/lib/tk9.0/listbox.tcl +522 -0
- package/python-runtime/python/lib/tk9.0/megawidget.tcl +297 -0
- package/python-runtime/python/lib/tk9.0/menu.tcl +1376 -0
- package/python-runtime/python/lib/tk9.0/mkpsenc.tcl +1488 -0
- package/python-runtime/python/lib/tk9.0/msgbox.tcl +454 -0
- package/python-runtime/python/lib/tk9.0/optMenu.tcl +43 -0
- package/python-runtime/python/lib/tk9.0/palette.tcl +283 -0
- package/python-runtime/python/lib/tk9.0/panedwindow.tcl +194 -0
- package/python-runtime/python/lib/tk9.0/pkgIndex.tcl +3 -0
- package/python-runtime/python/lib/tk9.0/print.tcl +1460 -0
- package/python-runtime/python/lib/tk9.0/safetk.tcl +262 -0
- package/python-runtime/python/lib/tk9.0/scale.tcl +299 -0
- package/python-runtime/python/lib/tk9.0/scaling.tcl +232 -0
- package/python-runtime/python/lib/tk9.0/scrlbar.tcl +500 -0
- package/python-runtime/python/lib/tk9.0/spinbox.tcl +580 -0
- package/python-runtime/python/lib/tk9.0/systray.tcl +483 -0
- package/python-runtime/python/lib/tk9.0/tclIndex +252 -0
- package/python-runtime/python/lib/tk9.0/tearoff.tcl +155 -0
- package/python-runtime/python/lib/tk9.0/text.tcl +1295 -0
- package/python-runtime/python/lib/tk9.0/tk.tcl +853 -0
- package/python-runtime/python/lib/tk9.0/tkAppInit.c +200 -0
- package/python-runtime/python/lib/tk9.0/tkfbox.tcl +1251 -0
- package/python-runtime/python/lib/tk9.0/ttk/altTheme.tcl +153 -0
- package/python-runtime/python/lib/tk9.0/ttk/aquaTheme.tcl +178 -0
- package/python-runtime/python/lib/tk9.0/ttk/button.tcl +83 -0
- package/python-runtime/python/lib/tk9.0/ttk/clamTheme.tcl +196 -0
- package/python-runtime/python/lib/tk9.0/ttk/classicTheme.tcl +145 -0
- package/python-runtime/python/lib/tk9.0/ttk/combobox.tcl +555 -0
- package/python-runtime/python/lib/tk9.0/ttk/cursors.tcl +205 -0
- package/python-runtime/python/lib/tk9.0/ttk/defaults.tcl +231 -0
- package/python-runtime/python/lib/tk9.0/ttk/entry.tcl +678 -0
- package/python-runtime/python/lib/tk9.0/ttk/fonts.tcl +152 -0
- package/python-runtime/python/lib/tk9.0/ttk/menubutton.tcl +237 -0
- package/python-runtime/python/lib/tk9.0/ttk/notebook.tcl +255 -0
- package/python-runtime/python/lib/tk9.0/ttk/panedwindow.tcl +89 -0
- package/python-runtime/python/lib/tk9.0/ttk/progress.tcl +55 -0
- package/python-runtime/python/lib/tk9.0/ttk/scale.tcl +94 -0
- package/python-runtime/python/lib/tk9.0/ttk/scrollbar.tcl +119 -0
- package/python-runtime/python/lib/tk9.0/ttk/sizegrip.tcl +102 -0
- package/python-runtime/python/lib/tk9.0/ttk/spinbox.tcl +204 -0
- package/python-runtime/python/lib/tk9.0/ttk/treeview.tcl +464 -0
- package/python-runtime/python/lib/tk9.0/ttk/ttk.tcl +223 -0
- package/python-runtime/python/lib/tk9.0/ttk/utils.tcl +317 -0
- package/python-runtime/python/lib/tk9.0/ttk/vistaTheme.tcl +259 -0
- package/python-runtime/python/lib/tk9.0/ttk/winTheme.tcl +119 -0
- package/python-runtime/python/lib/tk9.0/ttk/xpTheme.tcl +95 -0
- package/python-runtime/python/lib/tk9.0/xmfbox.tcl +982 -0
- package/python-runtime/python/share/man/man1/python3.1 +630 -0
- package/python-runtime/python/share/man/man1/python3.12.1 +630 -0
- package/runtime.json +8768 -0
- package/README.md +0 -3
|
@@ -0,0 +1,3785 @@
|
|
|
1
|
+
"""Sidecar core: wires the runtime adapters into a JSON-RPC server.
|
|
2
|
+
|
|
3
|
+
Methods (see spec/sidecar/README.md for the full catalog):
|
|
4
|
+
|
|
5
|
+
system.ping -> SidecarHealth
|
|
6
|
+
system.shutdown -> null
|
|
7
|
+
system.shutdown_now -> null
|
|
8
|
+
agent.session.create -> AgentSession
|
|
9
|
+
agent.session.resume -> AgentSession
|
|
10
|
+
agent.session.list -> AgentSession[]
|
|
11
|
+
agent.session.fork -> BranchPoint (fork a record, no turn run)
|
|
12
|
+
agent.session.branches -> { lineage, children } (branch-family view)
|
|
13
|
+
agent.session.tree -> { recordId, tree, nodeCount, truncated }
|
|
14
|
+
(full branch family from the root)
|
|
15
|
+
agent.chat.stream -> { streamId } (chunks pushed via `stream.chunk`,
|
|
16
|
+
terminator via `stream.done`)
|
|
17
|
+
agent.chat.cancel -> null (best-effort cancel of an in-flight stream)
|
|
18
|
+
tool.list -> ToolDescriptor[]
|
|
19
|
+
tool.invoke -> ToolResult
|
|
20
|
+
workspace.apply_edits -> { content, diff, applied, matches } (pure edit
|
|
21
|
+
algorithm on supplied content; the host owns
|
|
22
|
+
all file I/O — W6-1 single source of truth)
|
|
23
|
+
skills.list -> { skills } (parse + select SKILL.md from host
|
|
24
|
+
roots; single parse source so the desktop no
|
|
25
|
+
longer re-parses — eager/catalog both returned)
|
|
26
|
+
trace.fetch -> { trace, spans, events }
|
|
27
|
+
trace.export -> { status, traceId, privacyMode } (OTLP/HTTP push, W6-6)
|
|
28
|
+
config.get / config.set
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
import asyncio
|
|
34
|
+
import importlib.util
|
|
35
|
+
import json
|
|
36
|
+
import logging
|
|
37
|
+
import math
|
|
38
|
+
import os
|
|
39
|
+
import platform
|
|
40
|
+
import sys
|
|
41
|
+
import threading
|
|
42
|
+
import time
|
|
43
|
+
import uuid
|
|
44
|
+
from collections import OrderedDict
|
|
45
|
+
from dataclasses import dataclass, field
|
|
46
|
+
from functools import lru_cache
|
|
47
|
+
from pathlib import Path
|
|
48
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
49
|
+
|
|
50
|
+
if TYPE_CHECKING:
|
|
51
|
+
from steerable_agent_runtime.llm import ProviderPreset
|
|
52
|
+
|
|
53
|
+
from steerable_agent_harness import DEFAULT_CACHED_TOKEN_WEIGHT, BudgetLimit
|
|
54
|
+
from steerable_agent_protocol.generated import (
|
|
55
|
+
AgentSession,
|
|
56
|
+
SidecarHealth,
|
|
57
|
+
ToolCall,
|
|
58
|
+
)
|
|
59
|
+
from steerable_agent_runtime import (
|
|
60
|
+
DEFAULT_SHELL_TOOLS,
|
|
61
|
+
AntiHallucinationConfig,
|
|
62
|
+
AntiHallucinationHooks,
|
|
63
|
+
ApprovalExecutor,
|
|
64
|
+
AutoApprover,
|
|
65
|
+
BudgetExhaustedError,
|
|
66
|
+
ChainHooks,
|
|
67
|
+
CoreLoop,
|
|
68
|
+
FamilyTreeNode,
|
|
69
|
+
FilesystemSkillProvider,
|
|
70
|
+
HistorySeed,
|
|
71
|
+
JsonApprovalStore,
|
|
72
|
+
LoopConfig,
|
|
73
|
+
LoopHooks,
|
|
74
|
+
McpClient,
|
|
75
|
+
McpError,
|
|
76
|
+
OrchestrationConfig,
|
|
77
|
+
OrchestrationExecutor,
|
|
78
|
+
PluginLoadError,
|
|
79
|
+
PluginStateError,
|
|
80
|
+
PolicyDeniedError,
|
|
81
|
+
RequiredDelegationGate,
|
|
82
|
+
RouterToolExecutor,
|
|
83
|
+
SandboxedToolExecutor,
|
|
84
|
+
SessionApprovalCache,
|
|
85
|
+
SkillDefinition,
|
|
86
|
+
SkillExecutor,
|
|
87
|
+
SkillHooks,
|
|
88
|
+
StaticWorldStateSection,
|
|
89
|
+
StorageError,
|
|
90
|
+
SubagentConfig,
|
|
91
|
+
SubagentExecutor,
|
|
92
|
+
SubagentRegistry,
|
|
93
|
+
ToolDispatchError,
|
|
94
|
+
ToolRouter,
|
|
95
|
+
TodoCompletionGate,
|
|
96
|
+
create_mcp_client,
|
|
97
|
+
TodoPlanningNudge,
|
|
98
|
+
TraceRecorder,
|
|
99
|
+
WorldStateHooks,
|
|
100
|
+
branch_label,
|
|
101
|
+
close_dangling_tool_calls,
|
|
102
|
+
entry_from_dict,
|
|
103
|
+
estimate_cost_usd,
|
|
104
|
+
export_metrics,
|
|
105
|
+
export_trace,
|
|
106
|
+
resolve_compaction_policy,
|
|
107
|
+
is_large_window,
|
|
108
|
+
family_tree,
|
|
109
|
+
fork_record,
|
|
110
|
+
lineage,
|
|
111
|
+
load_history_transcript,
|
|
112
|
+
orchestration_tool_descriptors,
|
|
113
|
+
resolve_fork_seq,
|
|
114
|
+
select_catalog,
|
|
115
|
+
select_pinned_loadable,
|
|
116
|
+
select_skills,
|
|
117
|
+
skill_to_dict,
|
|
118
|
+
skill_tool_descriptor,
|
|
119
|
+
subagent_tool_descriptor,
|
|
120
|
+
mcp_invoker,
|
|
121
|
+
register_mcp_catalog,
|
|
122
|
+
)
|
|
123
|
+
from steerable_agent_runtime.llm import (
|
|
124
|
+
ContentPart,
|
|
125
|
+
ImagePart,
|
|
126
|
+
LLMMessage,
|
|
127
|
+
LLMProvider,
|
|
128
|
+
TextPart,
|
|
129
|
+
)
|
|
130
|
+
from steerable_agent_runtime.resume import project_transcript
|
|
131
|
+
from steerable_agent_runtime.storage import InMemoryStorage, StorageAdapter
|
|
132
|
+
from steerable_agent_runtime.transport.stdio_jsonrpc import (
|
|
133
|
+
JsonRpcError,
|
|
134
|
+
JsonRpcServer,
|
|
135
|
+
StdioJsonRpcTransport,
|
|
136
|
+
encode_frame,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
from ._version import __version__ as SIDECAR_VERSION
|
|
140
|
+
from .file_edit import EditError, EditOp, apply_edits
|
|
141
|
+
from .host_tools import HostApprover, HostAskUserHandler, HostToolExecutor
|
|
142
|
+
from .loop_limits import UNLIMITED_LOOP_LIMIT, resolve_loop_limits
|
|
143
|
+
from .sandbox import select_exec_backend
|
|
144
|
+
from .stream_chunks import RawChunkBridgeHooks
|
|
145
|
+
|
|
146
|
+
logger = logging.getLogger("steerable_sidecar")
|
|
147
|
+
|
|
148
|
+
_AUTO_APPROVED_HOST_CONTROL_TOOLS = (
|
|
149
|
+
"get_goal",
|
|
150
|
+
"create_goal",
|
|
151
|
+
"update_goal",
|
|
152
|
+
"loop_create",
|
|
153
|
+
"loop_list",
|
|
154
|
+
"loop_stop",
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
PROTOCOL_VERSION = "0.1.0"
|
|
158
|
+
|
|
159
|
+
# asyncio's default 64 KiB StreamReader limit kills the read loop with
|
|
160
|
+
# LimitOverrunError the moment a single JSON-RPC frame exceeds it — a large
|
|
161
|
+
# reverse-channel tool result (e.g. a file read) or a long conversation's
|
|
162
|
+
# chat.stream request crosses it easily, and the turn then dies silently
|
|
163
|
+
# (host sees a hang, no trace). 16 MiB stays bounded while covering
|
|
164
|
+
# realistic frames.
|
|
165
|
+
STDIO_STREAM_LIMIT = 16 * 1024 * 1024
|
|
166
|
+
READY_PREFIX = "__SIDECAR_READY__:"
|
|
167
|
+
|
|
168
|
+
#: Bound on per-chat session approval caches held by one sidecar. Eviction
|
|
169
|
+
#: only re-asks a cached *_for_session decision once; decisions are cheap.
|
|
170
|
+
_APPROVAL_SESSION_CACHE_CAP = 64
|
|
171
|
+
|
|
172
|
+
#: Grace window between a cooperative cancel (loop.cancel()) and the
|
|
173
|
+
#: hard-cancel backstop. The loop normally winds down within one await
|
|
174
|
+
#: point; 5s covers a slow final history flush without masking a wedge.
|
|
175
|
+
_CANCEL_GRACE_S = 5.0
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class _TurnExecControl:
|
|
179
|
+
"""Live command-sandbox switch for one running turn.
|
|
180
|
+
|
|
181
|
+
The composer can change workspace / full access after the stream has
|
|
182
|
+
started. Steer applies that choice here so the next shell call follows
|
|
183
|
+
it. The sandbox wrapper and the workspace auto-approver are optional:
|
|
184
|
+
a turn that never installed a wrapper cannot grow one mid-flight.
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
def __init__(self) -> None:
|
|
188
|
+
self.sandbox: Any = None
|
|
189
|
+
self.approver: Any = None
|
|
190
|
+
|
|
191
|
+
def apply(self, policy: str) -> None:
|
|
192
|
+
active = policy != "full"
|
|
193
|
+
sandbox = self.sandbox
|
|
194
|
+
if sandbox is not None:
|
|
195
|
+
sandbox.set_active(active)
|
|
196
|
+
approver = self.approver
|
|
197
|
+
if approver is not None:
|
|
198
|
+
approver.set_sandbox_enforced(active)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@dataclass
|
|
202
|
+
class SidecarConfig:
|
|
203
|
+
"""Sidecar runtime configuration."""
|
|
204
|
+
|
|
205
|
+
log_level: str = "INFO"
|
|
206
|
+
quiet_stderr: bool = False
|
|
207
|
+
grace_period_seconds: float = 5.0
|
|
208
|
+
install_signal_handlers: bool = True
|
|
209
|
+
initial_tools: list[Any] = field(default_factory=list)
|
|
210
|
+
#: W2.6.1: when set, sessions/traces/history persist to a zero-dependency
|
|
211
|
+
#: SqliteStorage database at this path instead of vanishing with the
|
|
212
|
+
#: process (the InMemoryStorage default).
|
|
213
|
+
storage_path: str | None = None
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class Sidecar:
|
|
217
|
+
"""In-process sidecar harness.
|
|
218
|
+
|
|
219
|
+
The main entrypoint composes a `JsonRpcServer`, a default `ToolRouter`, an
|
|
220
|
+
`InMemoryStorage`, and a `StdioJsonRpcTransport`. Embedders can swap any of
|
|
221
|
+
these by setting the corresponding attribute before calling ``serve()``.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
def __init__(
|
|
225
|
+
self,
|
|
226
|
+
*,
|
|
227
|
+
config: SidecarConfig | None = None,
|
|
228
|
+
storage: StorageAdapter | None = None,
|
|
229
|
+
tools: ToolRouter | None = None,
|
|
230
|
+
llm_provider_factory: Any | None = None,
|
|
231
|
+
loop_hooks_factory: Any | None = None,
|
|
232
|
+
) -> None:
|
|
233
|
+
self.config = config or SidecarConfig()
|
|
234
|
+
if storage is not None:
|
|
235
|
+
self.storage: StorageAdapter = storage
|
|
236
|
+
elif self.config.storage_path:
|
|
237
|
+
from steerable_agent_runtime.storage import SqliteStorage
|
|
238
|
+
|
|
239
|
+
self.storage = SqliteStorage(self.config.storage_path)
|
|
240
|
+
else:
|
|
241
|
+
self.storage = InMemoryStorage()
|
|
242
|
+
self.tools: ToolRouter = tools or ToolRouter()
|
|
243
|
+
self.server = JsonRpcServer()
|
|
244
|
+
self._llm_provider_factory = (
|
|
245
|
+
llm_provider_factory or default_llm_provider_factory
|
|
246
|
+
)
|
|
247
|
+
# Optional embedder hook for the CoreLoop chat path — receives the
|
|
248
|
+
# request params, returns a LoopHooks (e.g. ChainHooks of retry +
|
|
249
|
+
# compaction + spill). Defaults to RetryHooks alone.
|
|
250
|
+
self._loop_hooks_factory = loop_hooks_factory
|
|
251
|
+
self._streams: dict[str, asyncio.Task[Any]] = {}
|
|
252
|
+
#: Active CoreLoop instances by stream id — the steer RPC targets
|
|
253
|
+
#: these to inject user messages into a running turn.
|
|
254
|
+
self._coreloops: dict[str, CoreLoop] = {}
|
|
255
|
+
#: Per-stream command sandbox, toggled by agent.chat.steer execPolicy.
|
|
256
|
+
self._exec_controls: dict[str, _TurnExecControl] = {}
|
|
257
|
+
#: Hard-cancel watchdogs armed by agent.chat.cancel on CoreLoop
|
|
258
|
+
#: streams; tracked so the tasks are not garbage-collected early.
|
|
259
|
+
self._cancel_watchdogs: set[asyncio.Task[None]] = set()
|
|
260
|
+
#: Session-scope approval caches per chat (Wave 3 approval algebra).
|
|
261
|
+
#: LRU-bounded so a long-lived sidecar hosting many chats doesn't
|
|
262
|
+
#: grow without limit; eviction only means a cached *_for_session
|
|
263
|
+
#: decision is re-asked once.
|
|
264
|
+
self._approval_sessions: OrderedDict[str, SessionApprovalCache] = OrderedDict()
|
|
265
|
+
self._transport: StdioJsonRpcTransport | None = None
|
|
266
|
+
self._started_ms = int(time.monotonic() * 1000)
|
|
267
|
+
self._wall_started_ms = int(time.time() * 1000)
|
|
268
|
+
self._shutdown_requested = asyncio.Event()
|
|
269
|
+
self._serving = False
|
|
270
|
+
#: Injected by the entrypoint after plugin loading so the plugin.*
|
|
271
|
+
#: RPCs can drive the lifecycle. None means the plugin subsystem is
|
|
272
|
+
#: not wired (unit tests constructing a bare Sidecar).
|
|
273
|
+
self.plugin_registry: Any = None
|
|
274
|
+
|
|
275
|
+
self._register_default_methods()
|
|
276
|
+
for tool in self.config.initial_tools:
|
|
277
|
+
self.tools.register(tool)
|
|
278
|
+
|
|
279
|
+
def _approval_session(self, chat_id: Any) -> SessionApprovalCache:
|
|
280
|
+
"""Session-scope approval cache for one chat (LRU-bounded)."""
|
|
281
|
+
key = str(chat_id) if chat_id else ""
|
|
282
|
+
cache = self._approval_sessions.get(key)
|
|
283
|
+
if cache is None:
|
|
284
|
+
cache = SessionApprovalCache()
|
|
285
|
+
self._approval_sessions[key] = cache
|
|
286
|
+
while len(self._approval_sessions) > _APPROVAL_SESSION_CACHE_CAP:
|
|
287
|
+
self._approval_sessions.popitem(last=False)
|
|
288
|
+
else:
|
|
289
|
+
self._approval_sessions.move_to_end(key)
|
|
290
|
+
return cache
|
|
291
|
+
|
|
292
|
+
# ------------------------------------------------------------------
|
|
293
|
+
# Method registration
|
|
294
|
+
# ------------------------------------------------------------------
|
|
295
|
+
|
|
296
|
+
def _register_default_methods(self) -> None:
|
|
297
|
+
register = self.server.register
|
|
298
|
+
register("system.ping", self._handle_ping)
|
|
299
|
+
register("system.shutdown", self._handle_shutdown)
|
|
300
|
+
register("system.shutdown_now", self._handle_shutdown_now)
|
|
301
|
+
register("agent.session.create", self._handle_session_create)
|
|
302
|
+
register("agent.session.resume", self._handle_session_resume)
|
|
303
|
+
register("agent.session.list", self._handle_session_list)
|
|
304
|
+
register("tool.list", self._handle_tool_list)
|
|
305
|
+
register("tool.invoke", self._handle_tool_invoke)
|
|
306
|
+
register("workspace.apply_edits", self._handle_workspace_apply_edits)
|
|
307
|
+
register("skills.list", self._handle_skills_list)
|
|
308
|
+
register("trace.fetch", self._handle_trace_fetch)
|
|
309
|
+
register("trace.export", self._handle_trace_export)
|
|
310
|
+
register("metrics.export", self._handle_metrics_export)
|
|
311
|
+
register("config.get", self._handle_config_get)
|
|
312
|
+
register("config.set", self._handle_config_set)
|
|
313
|
+
register("compat.describe", self._handle_compat_describe)
|
|
314
|
+
register("sandbox.describe", self._handle_sandbox_describe)
|
|
315
|
+
register("plugin.list", self._handle_plugin_list)
|
|
316
|
+
register("plugin.enable", self._handle_plugin_enable)
|
|
317
|
+
register("plugin.disable", self._handle_plugin_disable)
|
|
318
|
+
register("plugin.reload", self._handle_plugin_reload)
|
|
319
|
+
register("plugin.tools.describe", self._handle_plugin_tools_describe)
|
|
320
|
+
register("presets.describe", self._handle_presets_describe)
|
|
321
|
+
register("presets.resolve", self._handle_presets_resolve)
|
|
322
|
+
register("catalog.describe", self._handle_catalog_describe)
|
|
323
|
+
register("models.list", self._handle_models_list)
|
|
324
|
+
register("harness.describe", self._handle_harness_describe)
|
|
325
|
+
register("agent.chat.stream", self._handle_chat_stream)
|
|
326
|
+
register("agent.chat.cancel", self._handle_chat_cancel)
|
|
327
|
+
register("agent.chat.steer", self._handle_chat_steer)
|
|
328
|
+
register("agent.chat.compact", self._handle_chat_compact)
|
|
329
|
+
register("agent.chat.fork", self._handle_chat_fork)
|
|
330
|
+
register("agent.session.fork", self._handle_session_fork)
|
|
331
|
+
register("agent.session.branches", self._handle_session_branches)
|
|
332
|
+
register("agent.session.tree", self._handle_session_tree)
|
|
333
|
+
register("agent.session.messages", self._handle_session_messages)
|
|
334
|
+
|
|
335
|
+
# ------------------------------------------------------------------
|
|
336
|
+
# Entrypoint
|
|
337
|
+
# ------------------------------------------------------------------
|
|
338
|
+
|
|
339
|
+
async def serve(self) -> None:
|
|
340
|
+
"""Run the sidecar until shutdown is requested."""
|
|
341
|
+
|
|
342
|
+
self._configure_logging()
|
|
343
|
+
if self.config.install_signal_handlers:
|
|
344
|
+
self._install_signal_handlers()
|
|
345
|
+
|
|
346
|
+
ready = await self.snapshot_health()
|
|
347
|
+
self._emit_ready_marker(ready)
|
|
348
|
+
|
|
349
|
+
reader, writer = await self._connect_stdio()
|
|
350
|
+
transport = StdioJsonRpcTransport(writer)
|
|
351
|
+
self._transport = transport
|
|
352
|
+
self.server.attach_writer(writer)
|
|
353
|
+
await transport.emit_notification(
|
|
354
|
+
"lifecycle.ready",
|
|
355
|
+
{
|
|
356
|
+
"version": SIDECAR_VERSION,
|
|
357
|
+
"protocolVersion": PROTOCOL_VERSION,
|
|
358
|
+
"pid": os.getpid(),
|
|
359
|
+
"listenInfo": {"transport": "stdio"},
|
|
360
|
+
},
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
self._serving = True
|
|
364
|
+
in_flight: set[asyncio.Task[None]] = set()
|
|
365
|
+
try:
|
|
366
|
+
while not self._shutdown_requested.is_set():
|
|
367
|
+
line_task = asyncio.ensure_future(reader.readline())
|
|
368
|
+
shutdown_task = asyncio.ensure_future(self._shutdown_requested.wait())
|
|
369
|
+
done, pending = await asyncio.wait(
|
|
370
|
+
{line_task, shutdown_task},
|
|
371
|
+
return_when=asyncio.FIRST_COMPLETED,
|
|
372
|
+
)
|
|
373
|
+
for task in pending:
|
|
374
|
+
task.cancel()
|
|
375
|
+
if shutdown_task in done:
|
|
376
|
+
break
|
|
377
|
+
line = line_task.result()
|
|
378
|
+
if not line:
|
|
379
|
+
break
|
|
380
|
+
# Dispatch each frame on its own task so the read loop keeps
|
|
381
|
+
# serving while a handler awaits a reverse (sidecar -> host)
|
|
382
|
+
# call — otherwise the two peers deadlock.
|
|
383
|
+
task = asyncio.ensure_future(self._process_line(line, writer))
|
|
384
|
+
in_flight.add(task)
|
|
385
|
+
task.add_done_callback(in_flight.discard)
|
|
386
|
+
finally:
|
|
387
|
+
if in_flight:
|
|
388
|
+
await asyncio.gather(*in_flight, return_exceptions=True)
|
|
389
|
+
await transport.emit_notification(
|
|
390
|
+
"lifecycle.shutdown",
|
|
391
|
+
{"reason": "normal" if self._shutdown_requested.is_set() else "eof"},
|
|
392
|
+
)
|
|
393
|
+
await transport.aclose()
|
|
394
|
+
close = getattr(writer, "close", None)
|
|
395
|
+
if close is not None:
|
|
396
|
+
close()
|
|
397
|
+
self._serving = False
|
|
398
|
+
close_storage = getattr(self.storage, "close", None)
|
|
399
|
+
if close_storage is not None:
|
|
400
|
+
close_storage()
|
|
401
|
+
|
|
402
|
+
async def _process_line(self, line: bytes, writer: Any) -> None:
|
|
403
|
+
response = await self.server.handle_frame(line.decode("utf-8"))
|
|
404
|
+
if response is None:
|
|
405
|
+
return
|
|
406
|
+
writer.write(encode_frame(response))
|
|
407
|
+
await self._maybe_drain(writer)
|
|
408
|
+
|
|
409
|
+
async def request_shutdown(self) -> None:
|
|
410
|
+
self._shutdown_requested.set()
|
|
411
|
+
|
|
412
|
+
async def snapshot_health(self) -> SidecarHealth:
|
|
413
|
+
uptime = int(time.monotonic() * 1000) - self._started_ms
|
|
414
|
+
return SidecarHealth(
|
|
415
|
+
status="ok" if self._serving or self._started_ms else "starting",
|
|
416
|
+
version=SIDECAR_VERSION,
|
|
417
|
+
protocolVersion=PROTOCOL_VERSION,
|
|
418
|
+
uptimeMs=max(0, uptime),
|
|
419
|
+
pid=os.getpid(),
|
|
420
|
+
pythonVersion=platform.python_version(),
|
|
421
|
+
platform=f"{sys.platform}-{platform.machine()}",
|
|
422
|
+
loadedTools=len(self.tools.list_tools()),
|
|
423
|
+
activeTraces=0,
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
# ------------------------------------------------------------------
|
|
427
|
+
# Method handlers
|
|
428
|
+
# ------------------------------------------------------------------
|
|
429
|
+
|
|
430
|
+
async def _handle_ping(self, _params: dict[str, Any] | None) -> dict[str, Any]:
|
|
431
|
+
health = await self.snapshot_health()
|
|
432
|
+
return health.model_dump(exclude_none=True)
|
|
433
|
+
|
|
434
|
+
async def _handle_shutdown(self, _params: dict[str, Any] | None) -> None:
|
|
435
|
+
_flush_shared_calibration()
|
|
436
|
+
# Schedule the actual stop so the response can be drained first.
|
|
437
|
+
loop = asyncio.get_running_loop()
|
|
438
|
+
loop.call_later(0.1, lambda: self._shutdown_requested.set())
|
|
439
|
+
|
|
440
|
+
async def _handle_shutdown_now(self, _params: dict[str, Any] | None) -> None:
|
|
441
|
+
_flush_shared_calibration()
|
|
442
|
+
self._shutdown_requested.set()
|
|
443
|
+
|
|
444
|
+
async def _handle_session_create(
|
|
445
|
+
self, params: dict[str, Any] | None
|
|
446
|
+
) -> dict[str, Any]:
|
|
447
|
+
params = _require_params(params)
|
|
448
|
+
session = AgentSession(
|
|
449
|
+
sessionId=params.get("sessionId") or _new_session_id(),
|
|
450
|
+
userId=params.get("userId") or "local",
|
|
451
|
+
chatId=params["chatId"],
|
|
452
|
+
currentStage=params.get("currentStage", "plan"),
|
|
453
|
+
isActive=True,
|
|
454
|
+
createdAt=_iso_now(),
|
|
455
|
+
updatedAt=_iso_now(),
|
|
456
|
+
scenario=params.get("scenario", "agent-entry"),
|
|
457
|
+
stageData=params.get("stageData"),
|
|
458
|
+
projectId=params.get("projectId"),
|
|
459
|
+
)
|
|
460
|
+
try:
|
|
461
|
+
stored = await self.storage.upsert_session(session)
|
|
462
|
+
except StorageError as exc:
|
|
463
|
+
raise JsonRpcError(str(exc), code=-32011, kind="internal") from exc
|
|
464
|
+
return stored.model_dump(exclude_none=True)
|
|
465
|
+
|
|
466
|
+
async def _handle_session_resume(
|
|
467
|
+
self, params: dict[str, Any] | None
|
|
468
|
+
) -> dict[str, Any]:
|
|
469
|
+
params = _require_params(params)
|
|
470
|
+
session_id = params.get("sessionId")
|
|
471
|
+
if not session_id:
|
|
472
|
+
raise JsonRpcError("sessionId required", code=-32602, kind="invalid_params")
|
|
473
|
+
session = await self.storage.get_session(session_id)
|
|
474
|
+
if session is None:
|
|
475
|
+
raise JsonRpcError(
|
|
476
|
+
f"session not found: {session_id}", code=-32004, kind="invalid_request"
|
|
477
|
+
)
|
|
478
|
+
return session.model_dump(exclude_none=True)
|
|
479
|
+
|
|
480
|
+
async def _seed_host_read_state(self, record_id: str) -> None:
|
|
481
|
+
"""Push the record's read-before-write evidence to the host.
|
|
482
|
+
|
|
483
|
+
Best-effort: a failed scan or push leaves the host's readFileState
|
|
484
|
+
empty, which only means fewer automatic CAS checks (or, with the
|
|
485
|
+
hard gate armed, a required re-read) — never a wrong write.
|
|
486
|
+
"""
|
|
487
|
+
from steerable_agent_runtime.history import (
|
|
488
|
+
HistoryItem,
|
|
489
|
+
HistorySeed,
|
|
490
|
+
entry_from_dict,
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
from .workspace_tools import read_file_state_from_messages
|
|
494
|
+
|
|
495
|
+
try:
|
|
496
|
+
raw_entries = await self.storage.list_history(record_id)
|
|
497
|
+
except Exception as exc: # noqa: BLE001 — seeding is best-effort
|
|
498
|
+
logger.warning("read_state seed scan failed for %s: %s", record_id, exc)
|
|
499
|
+
return
|
|
500
|
+
messages: list[LLMMessage] = []
|
|
501
|
+
for raw in raw_entries:
|
|
502
|
+
try:
|
|
503
|
+
entry = entry_from_dict(raw)
|
|
504
|
+
except Exception as exc: # noqa: BLE001 — skip entries this build cannot read
|
|
505
|
+
logger.debug("skipping unreadable history entry: %s", exc)
|
|
506
|
+
continue
|
|
507
|
+
if isinstance(entry, HistoryItem):
|
|
508
|
+
messages.append(entry.message)
|
|
509
|
+
elif isinstance(entry, HistorySeed):
|
|
510
|
+
messages.extend(entry.messages)
|
|
511
|
+
state = read_file_state_from_messages(messages)
|
|
512
|
+
if not state:
|
|
513
|
+
return
|
|
514
|
+
try:
|
|
515
|
+
await self.server.call("read_state.seed", {"state": state}, timeout=10)
|
|
516
|
+
except Exception as exc: # noqa: BLE001 — best-effort; see docstring
|
|
517
|
+
logger.warning("read_state.seed push failed for %s: %s", record_id, exc)
|
|
518
|
+
|
|
519
|
+
async def _handle_session_list(
|
|
520
|
+
self, params: dict[str, Any] | None
|
|
521
|
+
) -> list[dict[str, Any]]:
|
|
522
|
+
params = params or {}
|
|
523
|
+
sessions = await self.storage.list_sessions(
|
|
524
|
+
user_id=params.get("userId"),
|
|
525
|
+
chat_id=params.get("chatId"),
|
|
526
|
+
active_only=bool(params.get("activeOnly", False)),
|
|
527
|
+
)
|
|
528
|
+
return [s.model_dump(exclude_none=True) for s in sessions]
|
|
529
|
+
|
|
530
|
+
async def _handle_tool_list(
|
|
531
|
+
self, _params: dict[str, Any] | None
|
|
532
|
+
) -> list[dict[str, Any]]:
|
|
533
|
+
return self.tools.describe()
|
|
534
|
+
|
|
535
|
+
async def _handle_tool_invoke(
|
|
536
|
+
self, params: dict[str, Any] | None
|
|
537
|
+
) -> dict[str, Any]:
|
|
538
|
+
params = _require_params(params)
|
|
539
|
+
try:
|
|
540
|
+
call = ToolCall(
|
|
541
|
+
id=params.get("id") or _new_call_id(),
|
|
542
|
+
name=params["name"],
|
|
543
|
+
arguments=params.get("arguments") or {},
|
|
544
|
+
)
|
|
545
|
+
except KeyError as exc:
|
|
546
|
+
raise JsonRpcError(
|
|
547
|
+
f"missing argument: {exc.args[0]}", code=-32602, kind="invalid_params"
|
|
548
|
+
) from exc
|
|
549
|
+
try:
|
|
550
|
+
result = await self.tools.dispatch(
|
|
551
|
+
call,
|
|
552
|
+
consent_granted=bool(params.get("consentGranted", False)),
|
|
553
|
+
context=params.get("context"),
|
|
554
|
+
)
|
|
555
|
+
except PolicyDeniedError as exc:
|
|
556
|
+
raise JsonRpcError(
|
|
557
|
+
exc.message, code=-32020, kind="policy_denied", data=exc.data
|
|
558
|
+
) from exc
|
|
559
|
+
except BudgetExhaustedError as exc:
|
|
560
|
+
raise JsonRpcError(
|
|
561
|
+
exc.message, code=-32021, kind="budget_exhausted", data=exc.data
|
|
562
|
+
) from exc
|
|
563
|
+
except ToolDispatchError as exc:
|
|
564
|
+
raise JsonRpcError(
|
|
565
|
+
exc.message, code=-32030, kind="tool_failed", data=exc.data
|
|
566
|
+
) from exc
|
|
567
|
+
return result.model_dump(exclude_none=True)
|
|
568
|
+
|
|
569
|
+
async def _handle_workspace_apply_edits(
|
|
570
|
+
self, params: dict[str, Any] | None
|
|
571
|
+
) -> dict[str, Any]:
|
|
572
|
+
"""Pure structured-edit algorithm on caller-supplied content.
|
|
573
|
+
|
|
574
|
+
The host (desktop) owns file read / version check / atomic write; this
|
|
575
|
+
is only the locate-and-replace surgery so the algorithm has a single
|
|
576
|
+
Python source of truth shared with the headless / ACP workspace tools.
|
|
577
|
+
"""
|
|
578
|
+
params = _require_params(params)
|
|
579
|
+
content = params.get("content")
|
|
580
|
+
if not isinstance(content, str):
|
|
581
|
+
raise JsonRpcError(
|
|
582
|
+
"workspace.apply_edits: `content` (string) is required",
|
|
583
|
+
code=-32602,
|
|
584
|
+
kind="invalid_params",
|
|
585
|
+
)
|
|
586
|
+
raw_edits = params.get("edits")
|
|
587
|
+
if not isinstance(raw_edits, list):
|
|
588
|
+
raise JsonRpcError(
|
|
589
|
+
"workspace.apply_edits: `edits` (array) is required",
|
|
590
|
+
code=-32602,
|
|
591
|
+
kind="invalid_params",
|
|
592
|
+
)
|
|
593
|
+
ops = [
|
|
594
|
+
EditOp(
|
|
595
|
+
old_text=str(e.get("oldText", "")), new_text=str(e.get("newText", ""))
|
|
596
|
+
)
|
|
597
|
+
for e in raw_edits
|
|
598
|
+
if isinstance(e, dict)
|
|
599
|
+
]
|
|
600
|
+
file_path = str(params.get("filePath") or "file")
|
|
601
|
+
try:
|
|
602
|
+
result = apply_edits(content, ops, file_path=file_path)
|
|
603
|
+
except EditError as exc:
|
|
604
|
+
raise JsonRpcError(
|
|
605
|
+
str(exc), code=-32030, kind="edit_failed", data={"code": exc.code}
|
|
606
|
+
) from exc
|
|
607
|
+
return {
|
|
608
|
+
"content": result.content,
|
|
609
|
+
"diff": result.diff,
|
|
610
|
+
"applied": len(result.matches),
|
|
611
|
+
"matches": [
|
|
612
|
+
{
|
|
613
|
+
"level": m.level,
|
|
614
|
+
"startLine": m.start_line,
|
|
615
|
+
"oldLineCount": m.old_line_count,
|
|
616
|
+
}
|
|
617
|
+
for m in result.matches
|
|
618
|
+
],
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
async def _handle_skills_list(
|
|
622
|
+
self, params: dict[str, Any] | None
|
|
623
|
+
) -> dict[str, Any]:
|
|
624
|
+
"""Parse + select skills from host-supplied roots (single source of
|
|
625
|
+
truth for SKILL.md parsing, so the desktop no longer re-parses).
|
|
626
|
+
|
|
627
|
+
Roots are host-local paths — the sidecar shares the filesystem with
|
|
628
|
+
the desktop host. Returns both layers (eager + catalog) with bodies;
|
|
629
|
+
the host applies its own layer filter / budget / name lookup."""
|
|
630
|
+
params = _require_params(params)
|
|
631
|
+
roots_raw = params.get("roots")
|
|
632
|
+
if not isinstance(roots_raw, list):
|
|
633
|
+
raise JsonRpcError(
|
|
634
|
+
"skills.list: `roots` (array of paths) is required",
|
|
635
|
+
code=-32602,
|
|
636
|
+
kind="invalid_params",
|
|
637
|
+
)
|
|
638
|
+
roots = [str(r) for r in roots_raw]
|
|
639
|
+
conditions = set(params.get("conditions") or [])
|
|
640
|
+
exclude = list(params.get("exclude") or [])
|
|
641
|
+
ignore_conditions = bool(params.get("ignoreConditions"))
|
|
642
|
+
provider = FilesystemSkillProvider(roots)
|
|
643
|
+
definitions = [d for d in provider.list() if isinstance(d, SkillDefinition)]
|
|
644
|
+
selected = select_skills(definitions, conditions, exclude, ignore_conditions)
|
|
645
|
+
return {"skills": [skill_to_dict(d) for d in selected]}
|
|
646
|
+
|
|
647
|
+
async def _handle_trace_fetch(
|
|
648
|
+
self, params: dict[str, Any] | None
|
|
649
|
+
) -> dict[str, Any]:
|
|
650
|
+
params = _require_params(params)
|
|
651
|
+
trace_id = params.get("traceId")
|
|
652
|
+
if not trace_id:
|
|
653
|
+
raise JsonRpcError("traceId required", code=-32602, kind="invalid_params")
|
|
654
|
+
trace = await self.storage.get_trace(trace_id)
|
|
655
|
+
if trace is None:
|
|
656
|
+
raise JsonRpcError(
|
|
657
|
+
f"trace not found: {trace_id}", code=-32004, kind="invalid_request"
|
|
658
|
+
)
|
|
659
|
+
spans = await self.storage.list_spans(trace_id)
|
|
660
|
+
events = await self.storage.list_events(trace_id)
|
|
661
|
+
# Bound the payload. A long agentic turn logs events at roughly
|
|
662
|
+
# 200-800/round; the 259-round incident produced 161k events ≈ 39 MB of
|
|
663
|
+
# JSON, which the host's single-RPC fetch (5 s) could never pull — the
|
|
664
|
+
# trace was silently dropped, and the biggest runs are exactly the ones
|
|
665
|
+
# worth inspecting. Head + tail keeps the setup and (more importantly)
|
|
666
|
+
# *how the run ended*; the dropped middle is the thrash. The markers
|
|
667
|
+
# below tell the host — and the trace viewer — that the slice is
|
|
668
|
+
# partial, so a truncated trace is never mistaken for a whole one.
|
|
669
|
+
total_events = len(events)
|
|
670
|
+
max_events = _trace_fetch_max_events(params)
|
|
671
|
+
truncated = max_events is not None and total_events > max_events
|
|
672
|
+
if truncated and max_events is not None:
|
|
673
|
+
head = max(0, max_events // 4)
|
|
674
|
+
events = [*events[:head], *events[-(max_events - head) :]]
|
|
675
|
+
payload: dict[str, Any] = {
|
|
676
|
+
"trace": trace.model_dump(exclude_none=True),
|
|
677
|
+
"spans": [s.model_dump(exclude_none=True) for s in spans],
|
|
678
|
+
"events": [e.model_dump(exclude_none=True) for e in events],
|
|
679
|
+
}
|
|
680
|
+
if truncated:
|
|
681
|
+
payload["eventsTotal"] = total_events
|
|
682
|
+
payload["eventsTruncated"] = True
|
|
683
|
+
return payload
|
|
684
|
+
|
|
685
|
+
async def _handle_trace_export(
|
|
686
|
+
self, params: dict[str, Any] | None
|
|
687
|
+
) -> dict[str, Any]:
|
|
688
|
+
"""Export a stored trace to an OTLP/HTTP collector (W6-6).
|
|
689
|
+
|
|
690
|
+
Params: ``traceId`` (required), ``endpoint`` (required, the collector's
|
|
691
|
+
``/v1/traces`` URL), ``privacyMode`` (``"full"`` | ``"metadata"``,
|
|
692
|
+
default ``"metadata"``), ``serviceName`` (optional). The payload is
|
|
693
|
+
secret-redacted regardless of mode; ``metadata`` additionally strips
|
|
694
|
+
event payload bodies and free-form span attributes.
|
|
695
|
+
"""
|
|
696
|
+
params = _require_params(params)
|
|
697
|
+
trace_id = params.get("traceId")
|
|
698
|
+
endpoint = params.get("endpoint")
|
|
699
|
+
if not trace_id:
|
|
700
|
+
raise JsonRpcError("traceId required", code=-32602, kind="invalid_params")
|
|
701
|
+
if not endpoint:
|
|
702
|
+
raise JsonRpcError("endpoint required", code=-32602, kind="invalid_params")
|
|
703
|
+
privacy_mode = params.get("privacyMode", "metadata")
|
|
704
|
+
if privacy_mode not in ("full", "metadata"):
|
|
705
|
+
raise JsonRpcError(
|
|
706
|
+
f"invalid privacyMode: {privacy_mode}",
|
|
707
|
+
code=-32602,
|
|
708
|
+
kind="invalid_params",
|
|
709
|
+
)
|
|
710
|
+
trace = await self.storage.get_trace(trace_id)
|
|
711
|
+
if trace is None:
|
|
712
|
+
raise JsonRpcError(
|
|
713
|
+
f"trace not found: {trace_id}", code=-32004, kind="invalid_request"
|
|
714
|
+
)
|
|
715
|
+
spans = await self.storage.list_spans(trace_id)
|
|
716
|
+
events = await self.storage.list_events(trace_id)
|
|
717
|
+
try:
|
|
718
|
+
status = export_trace(
|
|
719
|
+
trace,
|
|
720
|
+
spans,
|
|
721
|
+
events,
|
|
722
|
+
str(endpoint),
|
|
723
|
+
privacy_mode=privacy_mode,
|
|
724
|
+
service_name=str(params.get("serviceName") or "steerable-agent"),
|
|
725
|
+
)
|
|
726
|
+
except Exception as exc: # collector unreachable / non-2xx
|
|
727
|
+
raise JsonRpcError(
|
|
728
|
+
f"trace export failed: {exc}", code=-32603, kind="internal"
|
|
729
|
+
) from exc
|
|
730
|
+
return {"status": status, "traceId": trace_id, "privacyMode": privacy_mode}
|
|
731
|
+
|
|
732
|
+
async def _handle_metrics_export(
|
|
733
|
+
self, params: dict[str, Any] | None
|
|
734
|
+
) -> dict[str, Any]:
|
|
735
|
+
"""POST turn-outcome counters to a collector's ``/v1/metrics`` (R4).
|
|
736
|
+
|
|
737
|
+
Params: ``samples`` (required) — one dict per finished turn with
|
|
738
|
+
``outcome`` / ``failureKind`` / ``attempts`` / ``usedDirect`` —,
|
|
739
|
+
``endpoint`` (required, the collector's ``/v1/metrics`` URL),
|
|
740
|
+
``serviceName`` (optional).
|
|
741
|
+
|
|
742
|
+
Separate from ``trace.export`` because a collector may accept traces
|
|
743
|
+
and not metrics, or the reverse; the host calls this only when it has
|
|
744
|
+
turn outcomes to report. The payload carries no conversation content,
|
|
745
|
+
so there is nothing for the privacy mode to filter.
|
|
746
|
+
"""
|
|
747
|
+
params = _require_params(params)
|
|
748
|
+
samples = params.get("samples")
|
|
749
|
+
endpoint = params.get("endpoint")
|
|
750
|
+
if not isinstance(samples, list) or not samples:
|
|
751
|
+
raise JsonRpcError("samples required", code=-32602, kind="invalid_params")
|
|
752
|
+
if not endpoint:
|
|
753
|
+
raise JsonRpcError("endpoint required", code=-32602, kind="invalid_params")
|
|
754
|
+
cleaned: list[dict[str, Any]] = []
|
|
755
|
+
for sample in samples:
|
|
756
|
+
if not isinstance(sample, dict):
|
|
757
|
+
raise JsonRpcError(
|
|
758
|
+
"each sample must be an object", code=-32602, kind="invalid_params"
|
|
759
|
+
)
|
|
760
|
+
cleaned.append(sample)
|
|
761
|
+
try:
|
|
762
|
+
status = export_metrics(
|
|
763
|
+
cleaned,
|
|
764
|
+
str(endpoint),
|
|
765
|
+
service_name=str(params.get("serviceName") or "steerable-agent"),
|
|
766
|
+
)
|
|
767
|
+
except Exception as exc: # collector unreachable / non-2xx
|
|
768
|
+
raise JsonRpcError(
|
|
769
|
+
f"metrics export failed: {exc}", code=-32603, kind="internal"
|
|
770
|
+
) from exc
|
|
771
|
+
return {"status": status, "metrics": len(cleaned)}
|
|
772
|
+
|
|
773
|
+
async def _handle_config_get(
|
|
774
|
+
self, params: dict[str, Any] | None
|
|
775
|
+
) -> dict[str, Any]:
|
|
776
|
+
base = {
|
|
777
|
+
"logLevel": self.config.log_level,
|
|
778
|
+
"gracePeriodSeconds": self.config.grace_period_seconds,
|
|
779
|
+
"version": SIDECAR_VERSION,
|
|
780
|
+
"protocolVersion": PROTOCOL_VERSION,
|
|
781
|
+
}
|
|
782
|
+
# ``{"merged": true}`` previews the layered user config (default →
|
|
783
|
+
# ~/.steerable/config.json → STEERABLE_* env), reporting each key's
|
|
784
|
+
# value and where it came from — the ``--dump-config`` counterpart.
|
|
785
|
+
# A malformed user file fails loud instead of serving stale defaults.
|
|
786
|
+
if isinstance(params, dict) and params.get("merged"):
|
|
787
|
+
from steerable_agent_runtime import resolve_config
|
|
788
|
+
|
|
789
|
+
resolved = resolve_config(
|
|
790
|
+
{
|
|
791
|
+
"log_level": self.config.log_level,
|
|
792
|
+
"grace_period_seconds": self.config.grace_period_seconds,
|
|
793
|
+
"storage_path": self.config.storage_path,
|
|
794
|
+
}
|
|
795
|
+
)
|
|
796
|
+
base["merged"] = resolved.describe()
|
|
797
|
+
return base
|
|
798
|
+
|
|
799
|
+
async def _handle_config_set(self, params: dict[str, Any] | None) -> None:
|
|
800
|
+
params = _require_params(params)
|
|
801
|
+
log_level = params.get("logLevel")
|
|
802
|
+
if log_level is not None:
|
|
803
|
+
self.config.log_level = str(log_level)
|
|
804
|
+
logging.getLogger().setLevel(self.config.log_level)
|
|
805
|
+
|
|
806
|
+
async def _handle_compat_describe(
|
|
807
|
+
self, _params: dict[str, Any] | None
|
|
808
|
+
) -> dict[str, Any]:
|
|
809
|
+
"""Serve the compat-flag wire vocabulary to host settings UIs.
|
|
810
|
+
|
|
811
|
+
The framework owns the flag definitions (`describe_compat_flags`);
|
|
812
|
+
hosts render their compat section from this payload so a new flag
|
|
813
|
+
needs no host-side constant to stay in sync (ALIGN 2.3.3).
|
|
814
|
+
"""
|
|
815
|
+
from steerable_agent_runtime.llm import describe_compat_flags
|
|
816
|
+
|
|
817
|
+
return {"flags": describe_compat_flags()}
|
|
818
|
+
|
|
819
|
+
async def _handle_sandbox_describe(
|
|
820
|
+
self, params: dict[str, Any] | None
|
|
821
|
+
) -> dict[str, Any]:
|
|
822
|
+
"""Report the per-exec enforcement this host can actually reach.
|
|
823
|
+
|
|
824
|
+
``execSandbox.requireFull`` refuses every command whose backend
|
|
825
|
+
reports short of ``full``, and with egress open only Seatbelt can
|
|
826
|
+
reach ``full`` (it pins per host); bwrap and Landlock have no
|
|
827
|
+
per-host pinning.
|
|
828
|
+
anchor: packages/sidecar/py/src/steerable_sidecar/sandbox.py :: Windows\w*(ExecBackend|Rewriter)
|
|
829
|
+
Windows has no rewriter backend at all. A host
|
|
830
|
+
that decides ``requireFull`` from its own platform guess therefore
|
|
831
|
+
denies every shell call on the platforms it guessed wrong about.
|
|
832
|
+
Probing with the ``network`` / ``allowedHosts`` the turn will send
|
|
833
|
+
returns the enforcement that turn would get, so the host can pick a
|
|
834
|
+
posture it can satisfy and disclose the real one.
|
|
835
|
+
|
|
836
|
+
``writableRoots`` is deliberately not consulted: every backend
|
|
837
|
+
derives ``enforcement`` from egress alone, so the answer is exact
|
|
838
|
+
rather than an approximation, and probing cannot fail on a root that
|
|
839
|
+
does not exist yet.
|
|
840
|
+
"""
|
|
841
|
+
params = params or {}
|
|
842
|
+
backend = select_exec_backend(
|
|
843
|
+
network=bool(params.get("network")),
|
|
844
|
+
allowed_hosts=params.get("allowedHosts") or None,
|
|
845
|
+
shell=str(params.get("shell") or "/bin/sh"),
|
|
846
|
+
)
|
|
847
|
+
if backend is None:
|
|
848
|
+
return {"backend": "none", "enforcement": "none"}
|
|
849
|
+
return {"backend": backend.name, "enforcement": backend.enforcement}
|
|
850
|
+
|
|
851
|
+
def _require_plugin_registry(self) -> Any:
|
|
852
|
+
"""The plugin registry, or an RPC error when the subsystem is unwired."""
|
|
853
|
+
if self.plugin_registry is None:
|
|
854
|
+
raise JsonRpcError(
|
|
855
|
+
"plugin subsystem is not wired on this sidecar",
|
|
856
|
+
code=-32602,
|
|
857
|
+
kind="invalid_params",
|
|
858
|
+
)
|
|
859
|
+
return self.plugin_registry
|
|
860
|
+
|
|
861
|
+
@staticmethod
|
|
862
|
+
def _plugin_record_dict(record: Any) -> dict[str, Any]:
|
|
863
|
+
return {
|
|
864
|
+
"name": record.name,
|
|
865
|
+
"origin": record.origin,
|
|
866
|
+
"tools": list(record.tools),
|
|
867
|
+
"enabled": record.enabled,
|
|
868
|
+
"reloadable": record.reloadable,
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
async def _handle_plugin_list(
|
|
872
|
+
self, _params: dict[str, Any] | None
|
|
873
|
+
) -> dict[str, Any]:
|
|
874
|
+
registry = self._require_plugin_registry()
|
|
875
|
+
return {
|
|
876
|
+
"plugins": [
|
|
877
|
+
self._plugin_record_dict(record) for record in registry.plugins()
|
|
878
|
+
]
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
async def _handle_plugin_enable(
|
|
882
|
+
self, params: dict[str, Any] | None
|
|
883
|
+
) -> dict[str, Any]:
|
|
884
|
+
registry = self._require_plugin_registry()
|
|
885
|
+
name = str(_require_params(params).get("name") or "")
|
|
886
|
+
try:
|
|
887
|
+
registry.enable(name)
|
|
888
|
+
except PluginStateError as exc:
|
|
889
|
+
raise JsonRpcError(str(exc), code=-32602, kind="invalid_params") from exc
|
|
890
|
+
return {"plugin": self._plugin_record_dict(registry.get(name))}
|
|
891
|
+
|
|
892
|
+
async def _handle_plugin_disable(
|
|
893
|
+
self, params: dict[str, Any] | None
|
|
894
|
+
) -> dict[str, Any]:
|
|
895
|
+
registry = self._require_plugin_registry()
|
|
896
|
+
name = str(_require_params(params).get("name") or "")
|
|
897
|
+
try:
|
|
898
|
+
registry.disable(name)
|
|
899
|
+
except PluginStateError as exc:
|
|
900
|
+
raise JsonRpcError(str(exc), code=-32602, kind="invalid_params") from exc
|
|
901
|
+
return {"plugin": self._plugin_record_dict(registry.get(name))}
|
|
902
|
+
|
|
903
|
+
async def _handle_plugin_reload(
|
|
904
|
+
self, params: dict[str, Any] | None
|
|
905
|
+
) -> dict[str, Any]:
|
|
906
|
+
registry = self._require_plugin_registry()
|
|
907
|
+
name = str(_require_params(params).get("name") or "")
|
|
908
|
+
try:
|
|
909
|
+
registry.reload(name)
|
|
910
|
+
except (PluginStateError, PluginLoadError) as exc:
|
|
911
|
+
raise JsonRpcError(str(exc), code=-32602, kind="invalid_params") from exc
|
|
912
|
+
return {"plugin": self._plugin_record_dict(registry.get(name))}
|
|
913
|
+
|
|
914
|
+
async def _handle_plugin_tools_describe(
|
|
915
|
+
self, _params: dict[str, Any] | None
|
|
916
|
+
) -> dict[str, Any]:
|
|
917
|
+
"""Descriptors for every tool an enabled plugin has on the router.
|
|
918
|
+
|
|
919
|
+
Hosts that own the model-visible tool list (``toolsViaHost``) use
|
|
920
|
+
this to advertise plugin tools and forward calls back over
|
|
921
|
+
``tool.invoke``; ``tool.list`` carries no mode or plugin owner.
|
|
922
|
+
Disabled plugins have no tools on the router, so they contribute none.
|
|
923
|
+
"""
|
|
924
|
+
registry = self._require_plugin_registry()
|
|
925
|
+
tools: list[dict[str, Any]] = []
|
|
926
|
+
for record in registry.plugins():
|
|
927
|
+
if not record.enabled:
|
|
928
|
+
continue
|
|
929
|
+
for name in record.tools:
|
|
930
|
+
tool = self.tools.get(name)
|
|
931
|
+
if tool is None:
|
|
932
|
+
continue
|
|
933
|
+
tools.append(
|
|
934
|
+
{
|
|
935
|
+
"name": tool.name,
|
|
936
|
+
"description": tool.description,
|
|
937
|
+
"schema": tool.schema,
|
|
938
|
+
"mode": tool.mode,
|
|
939
|
+
"exposure": tool.exposure,
|
|
940
|
+
"requireConsent": tool.require_consent,
|
|
941
|
+
"concurrencySafe": tool.concurrency_safe,
|
|
942
|
+
"plugin": record.name,
|
|
943
|
+
}
|
|
944
|
+
)
|
|
945
|
+
return {"tools": tools}
|
|
946
|
+
|
|
947
|
+
async def _handle_presets_describe(
|
|
948
|
+
self, _params: dict[str, Any] | None
|
|
949
|
+
) -> dict[str, Any]:
|
|
950
|
+
"""Serve the provider-preset table to host settings UIs.
|
|
951
|
+
|
|
952
|
+
Same service pattern as ``compat.describe``: the framework owns the
|
|
953
|
+
preset data (`describe_provider_presets`), hosts render their preset
|
|
954
|
+
picker from this payload so a new table entry needs no host change.
|
|
955
|
+
"""
|
|
956
|
+
from steerable_agent_runtime.llm import describe_provider_presets
|
|
957
|
+
|
|
958
|
+
return {"presets": describe_provider_presets()}
|
|
959
|
+
|
|
960
|
+
async def _handle_presets_resolve(
|
|
961
|
+
self, params: dict[str, Any] | None
|
|
962
|
+
) -> dict[str, Any]:
|
|
963
|
+
"""Resolve the preset a given (baseUrl, model) pair would auto-match.
|
|
964
|
+
|
|
965
|
+
Powers the settings UI's "what applies" preview without the host
|
|
966
|
+
reimplementing the matching rules. ``preset`` is the camelCase wire
|
|
967
|
+
form, or ``None`` when no entry matches (or the layer is disabled
|
|
968
|
+
via ``STEERABLE_PROVIDER_PRESETS=0``).
|
|
969
|
+
"""
|
|
970
|
+
from steerable_agent_runtime.llm import preset_for
|
|
971
|
+
|
|
972
|
+
params = params or {}
|
|
973
|
+
preset = preset_for(params.get("baseUrl"), params.get("model"))
|
|
974
|
+
return {"preset": preset.to_dict() if preset is not None else None}
|
|
975
|
+
|
|
976
|
+
async def _handle_catalog_describe(
|
|
977
|
+
self, _params: dict[str, Any] | None
|
|
978
|
+
) -> dict[str, Any]:
|
|
979
|
+
"""Serve the bundled serving-provider catalog to host settings UIs.
|
|
980
|
+
|
|
981
|
+
Same service pattern as ``compat.describe`` / ``presets.describe``:
|
|
982
|
+
the framework owns default URLs, wire kinds, and chat-capable model
|
|
983
|
+
ids. Hosts render the vendor picker from this payload so a catalog
|
|
984
|
+
refresh needs no host-side constant.
|
|
985
|
+
"""
|
|
986
|
+
from steerable_agent_runtime.model_resolve import describe_catalog_providers
|
|
987
|
+
|
|
988
|
+
return {"providers": describe_catalog_providers()}
|
|
989
|
+
|
|
990
|
+
async def _handle_models_list(
|
|
991
|
+
self, params: dict[str, Any] | None
|
|
992
|
+
) -> dict[str, Any]:
|
|
993
|
+
"""Serve the gateway's live model catalog to host model pickers.
|
|
994
|
+
|
|
995
|
+
The gateway's own ``GET /models`` names the ids the endpoint
|
|
996
|
+
actually accepts — discovery, not a routing whitelist (a host may
|
|
997
|
+
still send an unlisted id). Each id is joined with catalog
|
|
998
|
+
capabilities via the same leaf join the request path uses, so the
|
|
999
|
+
picker and ``clamp_reasoning_effort`` never disagree about a model's
|
|
1000
|
+
knob. A successful fetch is installed into the runtime's resolution
|
|
1001
|
+
path (``register_gateway_models``) so window budgeting sees the
|
|
1002
|
+
gateway-advertised windows.
|
|
1003
|
+
|
|
1004
|
+
``catalogStatus``: ``live`` (just fetched), ``stale`` (refresh
|
|
1005
|
+
failed, previous listing served), ``offline`` (no listing at all —
|
|
1006
|
+
the picker falls back to free-form entry). Offline is a 200, not an
|
|
1007
|
+
RPC error: an unreachable gateway must not break the host's
|
|
1008
|
+
settings screen.
|
|
1009
|
+
"""
|
|
1010
|
+
from steerable_agent_runtime import (
|
|
1011
|
+
REASONING_EFFORT_ORDER,
|
|
1012
|
+
register_gateway_models,
|
|
1013
|
+
)
|
|
1014
|
+
from steerable_agent_runtime.gateway_catalog import (
|
|
1015
|
+
GatewayCatalogError,
|
|
1016
|
+
fetch_gateway_models,
|
|
1017
|
+
merge_with_catalog,
|
|
1018
|
+
)
|
|
1019
|
+
|
|
1020
|
+
params = params or {}
|
|
1021
|
+
base_url = params.get("baseUrl") or os.environ.get("STEERABLE_BASE_URL", "")
|
|
1022
|
+
api_key = params.get("apiKey") or os.environ.get("STEERABLE_API_KEY", "")
|
|
1023
|
+
provider = params.get("provider")
|
|
1024
|
+
if not base_url:
|
|
1025
|
+
raise JsonRpcError(
|
|
1026
|
+
"models.list requires baseUrl (or STEERABLE_BASE_URL)",
|
|
1027
|
+
code=-32602,
|
|
1028
|
+
kind="invalid_params",
|
|
1029
|
+
)
|
|
1030
|
+
try:
|
|
1031
|
+
refresh = bool(params.get("refresh"))
|
|
1032
|
+
listing = await fetch_gateway_models(
|
|
1033
|
+
str(base_url),
|
|
1034
|
+
str(api_key) or None,
|
|
1035
|
+
provider=str(provider) if provider else None,
|
|
1036
|
+
**({"ttl_sec": 0} if refresh else {}),
|
|
1037
|
+
)
|
|
1038
|
+
except GatewayCatalogError as exc:
|
|
1039
|
+
return {"models": [], "catalogStatus": "offline", "error": str(exc)}
|
|
1040
|
+
rows = merge_with_catalog(listing.entries, base_url=str(base_url))
|
|
1041
|
+
register_gateway_models(row.info for row in rows)
|
|
1042
|
+
return {
|
|
1043
|
+
"models": [
|
|
1044
|
+
{
|
|
1045
|
+
"id": row.id,
|
|
1046
|
+
"name": row.name,
|
|
1047
|
+
"window": row.info.context_window,
|
|
1048
|
+
"modalities": sorted(row.info.modalities),
|
|
1049
|
+
"reasoningLevels": [
|
|
1050
|
+
level
|
|
1051
|
+
for level in REASONING_EFFORT_ORDER
|
|
1052
|
+
if level in row.info.reasoning_levels
|
|
1053
|
+
],
|
|
1054
|
+
"pricing": (
|
|
1055
|
+
{
|
|
1056
|
+
"promptPerMtok": row.prompt_price_per_mtok,
|
|
1057
|
+
"completionPerMtok": row.completion_price_per_mtok,
|
|
1058
|
+
}
|
|
1059
|
+
if row.prompt_price_per_mtok is not None
|
|
1060
|
+
or row.completion_price_per_mtok is not None
|
|
1061
|
+
else None
|
|
1062
|
+
),
|
|
1063
|
+
"joinedFrom": row.joined_from,
|
|
1064
|
+
"capabilities": (
|
|
1065
|
+
"known" if row.joined_from is not None else "unknown"
|
|
1066
|
+
),
|
|
1067
|
+
}
|
|
1068
|
+
for row in rows
|
|
1069
|
+
],
|
|
1070
|
+
"catalogStatus": "stale" if listing.stale else "live",
|
|
1071
|
+
"fetchedAt": listing.fetched_at,
|
|
1072
|
+
"current": {
|
|
1073
|
+
"model": os.environ.get("STEERABLE_MODEL") or None,
|
|
1074
|
+
"reasoningEffort": os.environ.get("STEERABLE_REASONING_EFFORT")
|
|
1075
|
+
or None,
|
|
1076
|
+
},
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
async def _handle_harness_describe(
|
|
1080
|
+
self, _params: dict[str, Any] | None
|
|
1081
|
+
) -> dict[str, Any]:
|
|
1082
|
+
"""Serve the harness vocabulary + the active default selection.
|
|
1083
|
+
|
|
1084
|
+
Same precedent as ``compat.describe`` (W1.2.2): the framework owns
|
|
1085
|
+
the dimension/implementation catalog; hosts render harness pickers
|
|
1086
|
+
from this payload so a new strategy needs no host-side constant.
|
|
1087
|
+
"""
|
|
1088
|
+
from steerable_agent_runtime.harness_spec import (
|
|
1089
|
+
describe_harness_registry,
|
|
1090
|
+
load_harness_spec,
|
|
1091
|
+
)
|
|
1092
|
+
|
|
1093
|
+
default_spec = load_harness_spec(_DEFAULT_HARNESS_SPEC_PATH)
|
|
1094
|
+
return {
|
|
1095
|
+
"default": default_spec.describe(),
|
|
1096
|
+
"available": describe_harness_registry(),
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
async def _handle_chat_stream(
|
|
1100
|
+
self, params: dict[str, Any] | None
|
|
1101
|
+
) -> dict[str, Any]:
|
|
1102
|
+
"""Start a streaming chat-completion run.
|
|
1103
|
+
|
|
1104
|
+
Params shape (all optional unless noted)::
|
|
1105
|
+
|
|
1106
|
+
{
|
|
1107
|
+
"provider": "openai_compat" | "anthropic" # required
|
|
1108
|
+
| "openai-responses" | "google" | <custom>,
|
|
1109
|
+
"model": "gpt-4o-mini", # required
|
|
1110
|
+
"messages": [{"role": "...", "content": "..."}], # required
|
|
1111
|
+
"baseUrl": "https://api.example.com/v1",
|
|
1112
|
+
"apiKey": "sk-...",
|
|
1113
|
+
"temperature": 0.2,
|
|
1114
|
+
"maxTokens": 1024,
|
|
1115
|
+
"reasoningEffort": "high", # per-request picker value; wins over
|
|
1116
|
+
# STEERABLE_REASONING_EFFORT and the
|
|
1117
|
+
# preset default. Strict: an effort the
|
|
1118
|
+
# model cannot honor is an RPC error.
|
|
1119
|
+
"tools": [...], # OpenAI tool descriptors
|
|
1120
|
+
"streamId": "str_xyz", # auto-generated if omitted
|
|
1121
|
+
"providerOptions": {...}, # passthrough
|
|
1122
|
+
"resume": True, # W7-1: continue the record's
|
|
1123
|
+
# interrupted turn; messages must be
|
|
1124
|
+
# empty, recordId (or chatId) required
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
Returns ``{"streamId": "..."}`` immediately. Chunks arrive as
|
|
1128
|
+
``stream.chunk`` notifications with ``{"streamId", "delta"}``;
|
|
1129
|
+
completion is signalled by ``stream.done`` with ``{"streamId",
|
|
1130
|
+
"finishReason", "usage"}``. Errors mid-stream are emitted as
|
|
1131
|
+
``stream.error``.
|
|
1132
|
+
"""
|
|
1133
|
+
|
|
1134
|
+
params = _require_params(params)
|
|
1135
|
+
if self._transport is None:
|
|
1136
|
+
raise JsonRpcError("transport not ready", code=-32099, kind="internal")
|
|
1137
|
+
try:
|
|
1138
|
+
provider = self._llm_provider_factory(params)
|
|
1139
|
+
except Exception as exc: # surface as RPC error before scheduling task
|
|
1140
|
+
raise JsonRpcError(
|
|
1141
|
+
f"failed to construct LLM provider: {exc}",
|
|
1142
|
+
code=-32602,
|
|
1143
|
+
kind="invalid_params",
|
|
1144
|
+
) from exc
|
|
1145
|
+
|
|
1146
|
+
stream_id = params.get("streamId") or _new_stream_id()
|
|
1147
|
+
messages = _coerce_messages(params.get("messages") or [])
|
|
1148
|
+
# W7-1: resume=true continues the durable record's interrupted turn
|
|
1149
|
+
# instead of opening a new one. The record's projected transcript
|
|
1150
|
+
# becomes the loop seed verbatim — the host neither re-sends the last
|
|
1151
|
+
# user message nor fabricates a synthetic continuation prompt, and
|
|
1152
|
+
# the loop's seed reconciliation sees an exact extension of the
|
|
1153
|
+
# record, so no compaction.boundary is declared and the record
|
|
1154
|
+
# continues linearly. `messages` must be empty: the record is
|
|
1155
|
+
# authoritative and merging a second history would silently fork.
|
|
1156
|
+
if params.get("resume"):
|
|
1157
|
+
if not _use_coreloop(params):
|
|
1158
|
+
raise JsonRpcError(
|
|
1159
|
+
"resume requires useCoreLoop",
|
|
1160
|
+
code=-32602,
|
|
1161
|
+
kind="invalid_params",
|
|
1162
|
+
)
|
|
1163
|
+
if messages:
|
|
1164
|
+
raise JsonRpcError(
|
|
1165
|
+
"resume replays the durable record; messages must be empty",
|
|
1166
|
+
code=-32602,
|
|
1167
|
+
kind="invalid_params",
|
|
1168
|
+
)
|
|
1169
|
+
record_id = params.get("recordId") or params.get("chatId")
|
|
1170
|
+
if not record_id:
|
|
1171
|
+
raise JsonRpcError(
|
|
1172
|
+
"resume requires recordId (or chatId)",
|
|
1173
|
+
code=-32602,
|
|
1174
|
+
kind="invalid_params",
|
|
1175
|
+
)
|
|
1176
|
+
resumed = await load_history_transcript(self.storage, str(record_id))
|
|
1177
|
+
if not resumed:
|
|
1178
|
+
raise JsonRpcError(
|
|
1179
|
+
f"record {record_id} has no history to resume",
|
|
1180
|
+
code=-32602,
|
|
1181
|
+
kind="invalid_params",
|
|
1182
|
+
)
|
|
1183
|
+
# Defensive close: the loop's flush discipline keeps its own
|
|
1184
|
+
# records free of dangling tool_calls, but the record is a
|
|
1185
|
+
# durable artifact other writers/versions may have produced.
|
|
1186
|
+
messages = close_dangling_tool_calls(resumed)
|
|
1187
|
+
# seed_read_state (CC parity): under toolsViaHost the desktop's
|
|
1188
|
+
# file tools own the write gate, but their readFileState is
|
|
1189
|
+
# process-resident and empty after an app restart. Re-seed it
|
|
1190
|
+
# from the record so the resumed session keeps its
|
|
1191
|
+
# read-before-write evidence.
|
|
1192
|
+
if params.get("toolsViaHost"):
|
|
1193
|
+
await self._seed_host_read_state(str(record_id))
|
|
1194
|
+
# The host re-sends its freshly assembled systemPrompt on every
|
|
1195
|
+
# turn; the record's leading system message (written by the
|
|
1196
|
+
# interrupted turn) must yield to it or the mutual-exclusion
|
|
1197
|
+
# check below fires. Splicing it out keeps the seed an exact
|
|
1198
|
+
# extension of the record when the prompt is unchanged.
|
|
1199
|
+
if (
|
|
1200
|
+
params.get("systemPrompt") is not None
|
|
1201
|
+
and messages
|
|
1202
|
+
and messages[0].role == "system"
|
|
1203
|
+
):
|
|
1204
|
+
messages = messages[1:]
|
|
1205
|
+
# W2.8.2: the host's assembled system prompt arrives as a typed
|
|
1206
|
+
# fragment (token cap enforced at this boundary), not an opaque seed
|
|
1207
|
+
# message. Supplying both seeds is a host bug — fail loud.
|
|
1208
|
+
#
|
|
1209
|
+
# Only the *leading* message counts as a competing seed. Later system
|
|
1210
|
+
# messages are ordinary transcript content this sidecar itself injected
|
|
1211
|
+
# — the skills catalog, `<world-state>`, reminders — and a resumed
|
|
1212
|
+
# record replays them verbatim. Rejecting those would make resume
|
|
1213
|
+
# impossible for every turn that carried a skill or world-state
|
|
1214
|
+
# fragment.
|
|
1215
|
+
system_prompt = params.get("systemPrompt")
|
|
1216
|
+
if system_prompt is not None:
|
|
1217
|
+
if messages and messages[0].role == "system":
|
|
1218
|
+
raise JsonRpcError(
|
|
1219
|
+
"systemPrompt param and a system message in messages are "
|
|
1220
|
+
"mutually exclusive",
|
|
1221
|
+
code=-32602,
|
|
1222
|
+
kind="invalid_params",
|
|
1223
|
+
)
|
|
1224
|
+
from steerable_agent_runtime import (
|
|
1225
|
+
SystemPromptFragment,
|
|
1226
|
+
render_fragment_capped,
|
|
1227
|
+
)
|
|
1228
|
+
|
|
1229
|
+
messages.insert(
|
|
1230
|
+
0, render_fragment_capped(SystemPromptFragment(str(system_prompt)))
|
|
1231
|
+
)
|
|
1232
|
+
|
|
1233
|
+
transport = self._transport
|
|
1234
|
+
use_coreloop = _use_coreloop(params)
|
|
1235
|
+
content_mode = params.get("contentMode", "all")
|
|
1236
|
+
if content_mode not in ("all", "final"):
|
|
1237
|
+
raise JsonRpcError(
|
|
1238
|
+
"contentMode must be 'all' or 'final'",
|
|
1239
|
+
code=-32602,
|
|
1240
|
+
kind="invalid_params",
|
|
1241
|
+
)
|
|
1242
|
+
if content_mode == "final" and not use_coreloop:
|
|
1243
|
+
raise JsonRpcError(
|
|
1244
|
+
"contentMode 'final' requires useCoreLoop",
|
|
1245
|
+
code=-32602,
|
|
1246
|
+
kind="invalid_params",
|
|
1247
|
+
)
|
|
1248
|
+
# Validate the mcp param up front (foreground, so a malformed entry
|
|
1249
|
+
# fails the request with a clean invalid_params rather than surfacing
|
|
1250
|
+
# as an unretrieved exception inside the background stream task).
|
|
1251
|
+
# Spawning/registration happens in _run_chat_stream_coreloop.
|
|
1252
|
+
mcp_param = params.get("mcp")
|
|
1253
|
+
if (
|
|
1254
|
+
isinstance(mcp_param, list)
|
|
1255
|
+
and not params.get("toolsViaHost")
|
|
1256
|
+
and self._loop_hooks_factory is None
|
|
1257
|
+
):
|
|
1258
|
+
for index, server in enumerate(mcp_param):
|
|
1259
|
+
if not isinstance(server, dict):
|
|
1260
|
+
raise JsonRpcError(
|
|
1261
|
+
f"mcp[{index}] must be an object",
|
|
1262
|
+
code=-32602,
|
|
1263
|
+
kind="invalid_params",
|
|
1264
|
+
)
|
|
1265
|
+
try:
|
|
1266
|
+
create_mcp_client(server)
|
|
1267
|
+
except McpError as exc:
|
|
1268
|
+
raise JsonRpcError(
|
|
1269
|
+
f"mcp[{index}]: {exc}",
|
|
1270
|
+
code=-32602,
|
|
1271
|
+
kind="invalid_params",
|
|
1272
|
+
) from exc
|
|
1273
|
+
if use_coreloop:
|
|
1274
|
+
task = asyncio.create_task(
|
|
1275
|
+
self._run_chat_stream_coreloop_guarded(
|
|
1276
|
+
provider, messages, params, stream_id, transport
|
|
1277
|
+
)
|
|
1278
|
+
)
|
|
1279
|
+
else:
|
|
1280
|
+
kwargs = _build_provider_kwargs(params)
|
|
1281
|
+
task = asyncio.create_task(
|
|
1282
|
+
self._run_chat_stream(provider, messages, kwargs, stream_id, transport)
|
|
1283
|
+
)
|
|
1284
|
+
self._streams[stream_id] = task
|
|
1285
|
+
return {"streamId": stream_id}
|
|
1286
|
+
|
|
1287
|
+
async def _handle_chat_cancel(self, params: dict[str, Any] | None) -> None:
|
|
1288
|
+
params = _require_params(params)
|
|
1289
|
+
stream_id = params.get("streamId")
|
|
1290
|
+
if not stream_id:
|
|
1291
|
+
raise JsonRpcError("streamId required", code=-32602, kind="invalid_params")
|
|
1292
|
+
# CoreLoop streams cancel cooperatively: the loop winds down at the
|
|
1293
|
+
# next safe point, records the partial turn (no dangling tool_calls),
|
|
1294
|
+
# and its terminal completion surfaces as stream.done with
|
|
1295
|
+
# status="cancelled". A watchdog hard-cancels the task if the wind-
|
|
1296
|
+
# down wedges (e.g. a provider stream that never yields).
|
|
1297
|
+
loop = self._coreloops.get(stream_id)
|
|
1298
|
+
if loop is not None:
|
|
1299
|
+
loop.cancel()
|
|
1300
|
+
task = self._streams.get(stream_id)
|
|
1301
|
+
if task is not None and not task.done():
|
|
1302
|
+
watchdog = asyncio.ensure_future(
|
|
1303
|
+
self._hard_cancel_after(task, stream_id)
|
|
1304
|
+
)
|
|
1305
|
+
self._cancel_watchdogs.add(watchdog)
|
|
1306
|
+
watchdog.add_done_callback(self._cancel_watchdogs.discard)
|
|
1307
|
+
return
|
|
1308
|
+
task = self._streams.pop(stream_id, None)
|
|
1309
|
+
if task is not None and not task.done():
|
|
1310
|
+
task.cancel()
|
|
1311
|
+
|
|
1312
|
+
async def _hard_cancel_after(
|
|
1313
|
+
self, task: asyncio.Task[None], stream_id: str
|
|
1314
|
+
) -> None:
|
|
1315
|
+
"""Backstop for cooperative cancel: if the loop has not finished
|
|
1316
|
+
within the grace window, cancel the task outright."""
|
|
1317
|
+
await asyncio.sleep(_CANCEL_GRACE_S)
|
|
1318
|
+
if not task.done():
|
|
1319
|
+
logger.warning(
|
|
1320
|
+
"stream %s did not wind down within %.0fs of cancel; hard-cancelling",
|
|
1321
|
+
stream_id,
|
|
1322
|
+
_CANCEL_GRACE_S,
|
|
1323
|
+
)
|
|
1324
|
+
task.cancel()
|
|
1325
|
+
|
|
1326
|
+
async def _handle_chat_fork(self, params: dict[str, Any] | None) -> dict[str, Any]:
|
|
1327
|
+
"""Start a new CoreLoop stream seeded from a recorded trace — the
|
|
1328
|
+
variant/regenerate primitive for trace-sourced sessions.
|
|
1329
|
+
|
|
1330
|
+
Params: everything ``agent.chat.stream`` takes (provider/model are
|
|
1331
|
+
required), plus ONE fork source::
|
|
1332
|
+
|
|
1333
|
+
{
|
|
1334
|
+
"recordId": "chat_...", # Wave 1: fork the durable record
|
|
1335
|
+
"untilSeq": 41, # optional inclusive record-seq bound
|
|
1336
|
+
# (see resume.load_history_transcript)
|
|
1337
|
+
# — or, legacy trace source —
|
|
1338
|
+
"traceId": "tr_...", # the trace to fork from
|
|
1339
|
+
"untilSequence": 41, # optional inclusive event-sequence
|
|
1340
|
+
# bound (see resume.project_transcript)
|
|
1341
|
+
"messages": [...], # optional messages appended after
|
|
1342
|
+
# the projected seed (e.g. the
|
|
1343
|
+
# re-asked user turn)
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
A record fork runs under a fresh ``<recordId>:fork:<streamId>``
|
|
1347
|
+
record seeded by one provenance-carrying ``history.seed`` entry, so
|
|
1348
|
+
the variant never pollutes the source chat's log.
|
|
1349
|
+
|
|
1350
|
+
Returns ``{"streamId", "seedMessages"}``. The fork always runs the
|
|
1351
|
+
CoreLoop path (projection is a CoreLoop concept) and records its own
|
|
1352
|
+
trace, so each variant is independently auditable. Hosts that keep
|
|
1353
|
+
their own message store (the desktop) don't need this RPC — they
|
|
1354
|
+
truncate their store and call ``agent.chat.stream`` with the rebuilt
|
|
1355
|
+
history.
|
|
1356
|
+
"""
|
|
1357
|
+
params = _require_params(params)
|
|
1358
|
+
if self._transport is None:
|
|
1359
|
+
raise JsonRpcError("transport not ready", code=-32099, kind="internal")
|
|
1360
|
+
stream_id = params.get("streamId") or _new_stream_id()
|
|
1361
|
+
source_record = params.get("recordId")
|
|
1362
|
+
if source_record is not None:
|
|
1363
|
+
# Wave 1 record fork (Wave 5: via branch.fork_record): seed from
|
|
1364
|
+
# the durable record (optionally truncated at a record seq) into
|
|
1365
|
+
# a FRESH record id, so the variant never pollutes the source
|
|
1366
|
+
# chat's log. The seed entry is persisted up front with
|
|
1367
|
+
# provenance and per-message kinds (the loop's host-view
|
|
1368
|
+
# reconciliation needs them to keep forked records continuous);
|
|
1369
|
+
# the run's own continuous-log seeding then recognises the
|
|
1370
|
+
# prefix and only appends genuinely new items.
|
|
1371
|
+
until_seq = params.get("untilSeq")
|
|
1372
|
+
try:
|
|
1373
|
+
fork = await fork_record(
|
|
1374
|
+
self.storage,
|
|
1375
|
+
str(source_record),
|
|
1376
|
+
until_seq=int(until_seq) if until_seq is not None else None,
|
|
1377
|
+
new_record_id=f"{source_record}:fork:{stream_id}",
|
|
1378
|
+
)
|
|
1379
|
+
except KeyError:
|
|
1380
|
+
raise JsonRpcError(
|
|
1381
|
+
f"record not found: {source_record}",
|
|
1382
|
+
code=-32004,
|
|
1383
|
+
kind="invalid_request",
|
|
1384
|
+
) from None
|
|
1385
|
+
seed = list(fork.messages)
|
|
1386
|
+
params = {**params, "recordId": fork.point.record_id}
|
|
1387
|
+
else:
|
|
1388
|
+
trace_id = params.get("traceId")
|
|
1389
|
+
if not trace_id:
|
|
1390
|
+
raise JsonRpcError(
|
|
1391
|
+
"traceId or recordId required", code=-32602, kind="invalid_params"
|
|
1392
|
+
)
|
|
1393
|
+
events = await self.storage.list_events(str(trace_id))
|
|
1394
|
+
if not events:
|
|
1395
|
+
raise JsonRpcError(
|
|
1396
|
+
f"trace not found: {trace_id}", code=-32004, kind="invalid_request"
|
|
1397
|
+
)
|
|
1398
|
+
events.sort(key=lambda e: getattr(e, "sequence", 0))
|
|
1399
|
+
until = params.get("untilSequence")
|
|
1400
|
+
seed = project_transcript(
|
|
1401
|
+
events, until_sequence=int(until) if until is not None else None
|
|
1402
|
+
)
|
|
1403
|
+
seed.extend(_coerce_messages(params.get("messages") or []))
|
|
1404
|
+
|
|
1405
|
+
try:
|
|
1406
|
+
provider = self._llm_provider_factory(params)
|
|
1407
|
+
except Exception as exc:
|
|
1408
|
+
raise JsonRpcError(
|
|
1409
|
+
f"failed to construct LLM provider: {exc}",
|
|
1410
|
+
code=-32602,
|
|
1411
|
+
kind="invalid_params",
|
|
1412
|
+
) from exc
|
|
1413
|
+
|
|
1414
|
+
transport = self._transport
|
|
1415
|
+
task = asyncio.create_task(
|
|
1416
|
+
self._run_chat_stream_coreloop_guarded(
|
|
1417
|
+
provider, seed, params, stream_id, transport
|
|
1418
|
+
)
|
|
1419
|
+
)
|
|
1420
|
+
self._streams[stream_id] = task
|
|
1421
|
+
return {"streamId": stream_id, "seedMessages": len(seed)}
|
|
1422
|
+
|
|
1423
|
+
async def _handle_session_fork(
|
|
1424
|
+
self, params: dict[str, Any] | None
|
|
1425
|
+
) -> dict[str, Any]:
|
|
1426
|
+
"""Fork a durable record WITHOUT running a turn (Wave 5).
|
|
1427
|
+
|
|
1428
|
+
Params::
|
|
1429
|
+
|
|
1430
|
+
{
|
|
1431
|
+
"recordId": "chat_...", # the source record (required)
|
|
1432
|
+
"untilSeq": 41, # exact inclusive fork point, or
|
|
1433
|
+
"beforeLastUser": true, # regen addressing: fork at the
|
|
1434
|
+
# newest user item (the prompting
|
|
1435
|
+
# turn stays, the reply is dropped)
|
|
1436
|
+
"beforeUserIndex": 2, # regen addressing by user-message
|
|
1437
|
+
# ordinal (mid-history regen)
|
|
1438
|
+
"newRecordId": "chat_...:r2", # optional explicit branch id
|
|
1439
|
+
"label": "...", # optional host-supplied summary
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
Returns the BranchPoint (``recordId``, ``sourceRecordId``,
|
|
1443
|
+
``sourceUntilSeq``, ``label``) plus ``seedMessages`` (count). The
|
|
1444
|
+
host then runs turns on the branch by passing the returned
|
|
1445
|
+
``recordId`` to ``agent.chat.stream``. The source record is never
|
|
1446
|
+
mutated — this is the non-destructive regenerate primitive: the old
|
|
1447
|
+
tail stays intact and discoverable via ``agent.session.branches``.
|
|
1448
|
+
"""
|
|
1449
|
+
params = _require_params(params)
|
|
1450
|
+
source_record = params.get("recordId")
|
|
1451
|
+
if not source_record:
|
|
1452
|
+
raise JsonRpcError("recordId required", code=-32602, kind="invalid_params")
|
|
1453
|
+
until_seq = params.get("untilSeq")
|
|
1454
|
+
user_index = params.get("beforeUserIndex")
|
|
1455
|
+
if until_seq is None and user_index is not None:
|
|
1456
|
+
until_seq = await resolve_fork_seq(
|
|
1457
|
+
self.storage, str(source_record), user_index=int(user_index)
|
|
1458
|
+
)
|
|
1459
|
+
if until_seq is None:
|
|
1460
|
+
raise JsonRpcError(
|
|
1461
|
+
f"user message index {user_index} not addressable in "
|
|
1462
|
+
f"record: {source_record}",
|
|
1463
|
+
code=-32004,
|
|
1464
|
+
kind="invalid_request",
|
|
1465
|
+
)
|
|
1466
|
+
if until_seq is None and params.get("beforeLastUser"):
|
|
1467
|
+
until_seq = await resolve_fork_seq(
|
|
1468
|
+
self.storage, str(source_record), before_last_user=True
|
|
1469
|
+
)
|
|
1470
|
+
if until_seq is None:
|
|
1471
|
+
raise JsonRpcError(
|
|
1472
|
+
f"no user message to fork before: {source_record}",
|
|
1473
|
+
code=-32004,
|
|
1474
|
+
kind="invalid_request",
|
|
1475
|
+
)
|
|
1476
|
+
try:
|
|
1477
|
+
fork = await fork_record(
|
|
1478
|
+
self.storage,
|
|
1479
|
+
str(source_record),
|
|
1480
|
+
until_seq=int(until_seq) if until_seq is not None else None,
|
|
1481
|
+
new_record_id=(
|
|
1482
|
+
str(params["newRecordId"]) if params.get("newRecordId") else None
|
|
1483
|
+
),
|
|
1484
|
+
label=str(params["label"]) if params.get("label") else None,
|
|
1485
|
+
)
|
|
1486
|
+
except KeyError:
|
|
1487
|
+
raise JsonRpcError(
|
|
1488
|
+
f"record not found: {source_record}",
|
|
1489
|
+
code=-32004,
|
|
1490
|
+
kind="invalid_request",
|
|
1491
|
+
) from None
|
|
1492
|
+
point = fork.point
|
|
1493
|
+
return {
|
|
1494
|
+
"recordId": point.record_id,
|
|
1495
|
+
"sourceRecordId": point.source_record_id,
|
|
1496
|
+
"sourceUntilSeq": point.source_until_seq,
|
|
1497
|
+
"label": point.label,
|
|
1498
|
+
"seedMessages": len(fork.messages),
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
async def _handle_session_branches(
|
|
1502
|
+
self, params: dict[str, Any] | None
|
|
1503
|
+
) -> dict[str, Any]:
|
|
1504
|
+
"""Branch-family view of a record (Wave 5).
|
|
1505
|
+
|
|
1506
|
+
Returns ``{"lineage": [...root-first BranchPoints...], "children":
|
|
1507
|
+
[...]}``. Lineage walks seed provenance upwards and always works;
|
|
1508
|
+
children discovery needs record enumeration — stores implementing
|
|
1509
|
+
Children discovery enumerates the record space
|
|
1510
|
+
(``list_history_records``, first-class since W3.1.2) and keeps
|
|
1511
|
+
records whose seed names this one as source.
|
|
1512
|
+
"""
|
|
1513
|
+
params = _require_params(params)
|
|
1514
|
+
record_id = params.get("recordId")
|
|
1515
|
+
if not record_id:
|
|
1516
|
+
raise JsonRpcError("recordId required", code=-32602, kind="invalid_params")
|
|
1517
|
+
chain = await lineage(self.storage, str(record_id))
|
|
1518
|
+
children: list[dict[str, Any]] = []
|
|
1519
|
+
for candidate in await self.storage.list_history_records():
|
|
1520
|
+
if candidate == record_id:
|
|
1521
|
+
continue
|
|
1522
|
+
first = await self.storage.list_history(candidate, limit=1)
|
|
1523
|
+
if not first:
|
|
1524
|
+
continue
|
|
1525
|
+
entry = entry_from_dict(first[0])
|
|
1526
|
+
if (
|
|
1527
|
+
isinstance(entry, HistorySeed)
|
|
1528
|
+
and entry.source_record_id == record_id
|
|
1529
|
+
):
|
|
1530
|
+
children.append(
|
|
1531
|
+
{
|
|
1532
|
+
"recordId": candidate,
|
|
1533
|
+
"sourceRecordId": record_id,
|
|
1534
|
+
"sourceUntilSeq": entry.source_until_seq,
|
|
1535
|
+
"label": branch_label(list(entry.messages)),
|
|
1536
|
+
}
|
|
1537
|
+
)
|
|
1538
|
+
return {
|
|
1539
|
+
"lineage": [
|
|
1540
|
+
{
|
|
1541
|
+
"recordId": point.record_id,
|
|
1542
|
+
"sourceRecordId": point.source_record_id,
|
|
1543
|
+
"sourceUntilSeq": point.source_until_seq,
|
|
1544
|
+
"label": point.label,
|
|
1545
|
+
"depth": point.depth,
|
|
1546
|
+
}
|
|
1547
|
+
for point in chain
|
|
1548
|
+
],
|
|
1549
|
+
"children": children,
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
async def _handle_session_tree(
|
|
1553
|
+
self, params: dict[str, Any] | None
|
|
1554
|
+
) -> dict[str, Any]:
|
|
1555
|
+
"""Full branch family containing a record (session-tree view).
|
|
1556
|
+
|
|
1557
|
+
Params: ``{"recordId": "chat_..."}``. Returns ``{"recordId",
|
|
1558
|
+
"tree", "nodeCount", "truncated"}`` where ``tree`` is the family
|
|
1559
|
+
root as a recursive node::
|
|
1560
|
+
|
|
1561
|
+
{
|
|
1562
|
+
"recordId", "sourceRecordId", "sourceUntilSeq",
|
|
1563
|
+
"label", "depth", # depth 0 on the root
|
|
1564
|
+
"children": [...] # same shape, recursively
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
This is the single-call tree a host needs to render a pi-style
|
|
1568
|
+
full-tree branch view and to validate switching to ANY family
|
|
1569
|
+
member (cousins included) — ``agent.session.branches`` only sees
|
|
1570
|
+
the lineage plus direct children. Expansion is bounded (depth ≤
|
|
1571
|
+
32, nodes ≤ 500 — see ``branch.family_tree``); a cut family comes
|
|
1572
|
+
back with ``truncated: true``. Unknown record → invalid_request;
|
|
1573
|
+
lineage corruption (cycle) → invalid_request, both fail loud.
|
|
1574
|
+
"""
|
|
1575
|
+
params = _require_params(params)
|
|
1576
|
+
record_id = params.get("recordId")
|
|
1577
|
+
if not record_id:
|
|
1578
|
+
raise JsonRpcError("recordId required", code=-32602, kind="invalid_params")
|
|
1579
|
+
try:
|
|
1580
|
+
family = await family_tree(self.storage, str(record_id))
|
|
1581
|
+
except KeyError:
|
|
1582
|
+
raise JsonRpcError(
|
|
1583
|
+
f"record not found: {record_id}",
|
|
1584
|
+
code=-32004,
|
|
1585
|
+
kind="invalid_request",
|
|
1586
|
+
) from None
|
|
1587
|
+
except ValueError as exc:
|
|
1588
|
+
raise JsonRpcError(
|
|
1589
|
+
str(exc), code=-32004, kind="invalid_request"
|
|
1590
|
+
) from None
|
|
1591
|
+
|
|
1592
|
+
def node_to_dict(node: FamilyTreeNode) -> dict[str, Any]:
|
|
1593
|
+
return {
|
|
1594
|
+
"recordId": node.record_id,
|
|
1595
|
+
"sourceRecordId": node.source_record_id,
|
|
1596
|
+
"sourceUntilSeq": node.source_until_seq,
|
|
1597
|
+
"label": node.label,
|
|
1598
|
+
"depth": node.depth,
|
|
1599
|
+
"children": [node_to_dict(child) for child in node.children],
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
return {
|
|
1603
|
+
"recordId": str(record_id),
|
|
1604
|
+
"tree": node_to_dict(family.root),
|
|
1605
|
+
"nodeCount": family.node_count,
|
|
1606
|
+
"truncated": family.truncated,
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
async def _handle_session_messages(
|
|
1610
|
+
self, params: dict[str, Any] | None
|
|
1611
|
+
) -> dict[str, Any]:
|
|
1612
|
+
"""Projected transcript of a history record (W1.2.1).
|
|
1613
|
+
|
|
1614
|
+
``{"recordId", "messages": [{seq, role, content}...]}`` — the
|
|
1615
|
+
post-boundary visible span, i.e. what the model would see on resume.
|
|
1616
|
+
This is the read path a host needs to render/switch branches: the
|
|
1617
|
+
branch's messages live in the framework record, not the host's UI
|
|
1618
|
+
store. Unknown record → invalid_request (fail loud, not an empty
|
|
1619
|
+
list that looks like an empty branch).
|
|
1620
|
+
"""
|
|
1621
|
+
from steerable_agent_runtime.resume import load_history_items
|
|
1622
|
+
|
|
1623
|
+
params = _require_params(params)
|
|
1624
|
+
record_id = params.get("recordId")
|
|
1625
|
+
if not record_id:
|
|
1626
|
+
raise JsonRpcError("recordId required", code=-32602, kind="invalid_params")
|
|
1627
|
+
items = await load_history_items(self.storage, str(record_id))
|
|
1628
|
+
if items is None:
|
|
1629
|
+
raise JsonRpcError(
|
|
1630
|
+
f"record not found: {record_id}", code=-32004, kind="invalid_request"
|
|
1631
|
+
)
|
|
1632
|
+
messages = []
|
|
1633
|
+
for item in items:
|
|
1634
|
+
content = "".join(
|
|
1635
|
+
getattr(part, "text", "")
|
|
1636
|
+
for part in item.message.content
|
|
1637
|
+
if getattr(part, "type", None) == "text"
|
|
1638
|
+
) if isinstance(item.message.content, list) else str(item.message.content)
|
|
1639
|
+
messages.append(
|
|
1640
|
+
{"seq": item.seq, "role": item.message.role, "content": content}
|
|
1641
|
+
)
|
|
1642
|
+
return {"recordId": str(record_id), "messages": messages}
|
|
1643
|
+
|
|
1644
|
+
async def _handle_chat_steer(self, params: dict[str, Any] | None) -> dict[str, Any]:
|
|
1645
|
+
"""Inject a user message into a running CoreLoop turn.
|
|
1646
|
+
|
|
1647
|
+
Soft-fail with ``{"ok": False}`` when the stream is unknown or not
|
|
1648
|
+
CoreLoop-backed — between the user hitting send and this RPC landing,
|
|
1649
|
+
the turn may legitimately have completed.
|
|
1650
|
+
"""
|
|
1651
|
+
params = _require_params(params)
|
|
1652
|
+
stream_id = params.get("streamId")
|
|
1653
|
+
content = params.get("content")
|
|
1654
|
+
if not stream_id or not isinstance(content, str) or not content.strip():
|
|
1655
|
+
raise JsonRpcError(
|
|
1656
|
+
"streamId and non-empty content required",
|
|
1657
|
+
code=-32602,
|
|
1658
|
+
kind="invalid_params",
|
|
1659
|
+
)
|
|
1660
|
+
loop = self._coreloops.get(stream_id)
|
|
1661
|
+
if loop is None:
|
|
1662
|
+
return {"ok": False, "reason": "stream_not_active"}
|
|
1663
|
+
# Composer sandbox (workspace / full) rides with the interjection so
|
|
1664
|
+
# the next shell call in this turn matches the picker. Unknown values
|
|
1665
|
+
# leave the turn's original sandbox alone.
|
|
1666
|
+
policy = params.get("execPolicy")
|
|
1667
|
+
if policy in ("full", "workspace"):
|
|
1668
|
+
control = self._exec_controls.get(stream_id)
|
|
1669
|
+
if control is not None:
|
|
1670
|
+
control.apply(str(policy))
|
|
1671
|
+
loop.steer(content)
|
|
1672
|
+
return {"ok": True}
|
|
1673
|
+
|
|
1674
|
+
async def _handle_chat_compact(self, params: dict[str, Any] | None) -> dict[str, Any]:
|
|
1675
|
+
"""Manually compact a running CoreLoop turn's transcript — the
|
|
1676
|
+
host-command path (CC ``/compact`` parity).
|
|
1677
|
+
|
|
1678
|
+
The loop consumes the request at its next pre_step boundary: the
|
|
1679
|
+
hook chain's ``compact_now`` folds old tool results and summarizes
|
|
1680
|
+
the middle regardless of pressure, landing as a declared rewrite
|
|
1681
|
+
plus a ``hook_action`` event. Soft-fails like steer — between the
|
|
1682
|
+
host command and this RPC landing, the turn may legitimately have
|
|
1683
|
+
completed.
|
|
1684
|
+
"""
|
|
1685
|
+
params = _require_params(params)
|
|
1686
|
+
stream_id = params.get("streamId")
|
|
1687
|
+
if not stream_id:
|
|
1688
|
+
raise JsonRpcError("streamId required", code=-32602, kind="invalid_params")
|
|
1689
|
+
loop = self._coreloops.get(stream_id)
|
|
1690
|
+
if loop is None:
|
|
1691
|
+
return {"ok": False, "reason": "stream_not_active"}
|
|
1692
|
+
loop.request_compact()
|
|
1693
|
+
return {"ok": True}
|
|
1694
|
+
|
|
1695
|
+
async def _run_chat_stream(
|
|
1696
|
+
self,
|
|
1697
|
+
provider: LLMProvider,
|
|
1698
|
+
messages: list[LLMMessage],
|
|
1699
|
+
kwargs: dict[str, Any],
|
|
1700
|
+
stream_id: str,
|
|
1701
|
+
transport: StdioJsonRpcTransport,
|
|
1702
|
+
) -> None:
|
|
1703
|
+
try:
|
|
1704
|
+
iterator = provider.stream(messages, **kwargs)
|
|
1705
|
+
async for chunk in iterator:
|
|
1706
|
+
payload: dict[str, Any] = {"streamId": stream_id}
|
|
1707
|
+
if chunk.content_delta is not None:
|
|
1708
|
+
payload["delta"] = chunk.content_delta
|
|
1709
|
+
if chunk.reasoning_delta is not None:
|
|
1710
|
+
payload["reasoningDelta"] = chunk.reasoning_delta
|
|
1711
|
+
if chunk.tool_call_delta is not None:
|
|
1712
|
+
payload["toolCall"] = chunk.tool_call_delta.model_dump(
|
|
1713
|
+
exclude_none=True
|
|
1714
|
+
)
|
|
1715
|
+
if chunk.finish_reason is not None:
|
|
1716
|
+
payload["finishReason"] = chunk.finish_reason
|
|
1717
|
+
if chunk.usage is not None:
|
|
1718
|
+
payload["usage"] = {
|
|
1719
|
+
"promptTokens": chunk.usage.prompt_tokens,
|
|
1720
|
+
"completionTokens": chunk.usage.completion_tokens,
|
|
1721
|
+
"totalTokens": chunk.usage.total_tokens,
|
|
1722
|
+
}
|
|
1723
|
+
await transport.emit_notification("stream.chunk", payload)
|
|
1724
|
+
await transport.emit_notification(
|
|
1725
|
+
"stream.done", {"streamId": stream_id, "ok": True}
|
|
1726
|
+
)
|
|
1727
|
+
except asyncio.CancelledError:
|
|
1728
|
+
await transport.emit_notification(
|
|
1729
|
+
"stream.done", {"streamId": stream_id, "ok": False, "cancelled": True}
|
|
1730
|
+
)
|
|
1731
|
+
except Exception as exc:
|
|
1732
|
+
logger.exception("chat stream %s failed", stream_id)
|
|
1733
|
+
await transport.emit_notification(
|
|
1734
|
+
"stream.error",
|
|
1735
|
+
{
|
|
1736
|
+
"streamId": stream_id,
|
|
1737
|
+
"kind": exc.__class__.__name__,
|
|
1738
|
+
"message": str(exc),
|
|
1739
|
+
},
|
|
1740
|
+
)
|
|
1741
|
+
finally:
|
|
1742
|
+
self._streams.pop(stream_id, None)
|
|
1743
|
+
|
|
1744
|
+
async def _run_chat_stream_coreloop_guarded(
|
|
1745
|
+
self,
|
|
1746
|
+
provider: LLMProvider,
|
|
1747
|
+
messages: list[LLMMessage],
|
|
1748
|
+
params: dict[str, Any],
|
|
1749
|
+
stream_id: str,
|
|
1750
|
+
transport: StdioJsonRpcTransport,
|
|
1751
|
+
) -> None:
|
|
1752
|
+
"""Catch setup-phase failures the inner catch-all cannot reach.
|
|
1753
|
+
|
|
1754
|
+
``_run_chat_stream_coreloop`` only starts converting exceptions into
|
|
1755
|
+
``stream.error`` once its ``try`` begins — a failure in the setup
|
|
1756
|
+
region before it (tool registration, MCP client spawn, executor
|
|
1757
|
+
wiring) would otherwise escape as an unretrieved task exception and
|
|
1758
|
+
strand the host waiting for a terminal event that never comes.
|
|
1759
|
+
"""
|
|
1760
|
+
try:
|
|
1761
|
+
await self._run_chat_stream_coreloop(
|
|
1762
|
+
provider, messages, params, stream_id, transport
|
|
1763
|
+
)
|
|
1764
|
+
except asyncio.CancelledError:
|
|
1765
|
+
raise
|
|
1766
|
+
except Exception as exc: # last line before a stranded host
|
|
1767
|
+
logger.exception("coreloop chat stream %s failed during setup", stream_id)
|
|
1768
|
+
try:
|
|
1769
|
+
await transport.emit_notification(
|
|
1770
|
+
"stream.error",
|
|
1771
|
+
{
|
|
1772
|
+
"streamId": stream_id,
|
|
1773
|
+
"kind": exc.__class__.__name__,
|
|
1774
|
+
"message": str(exc),
|
|
1775
|
+
},
|
|
1776
|
+
)
|
|
1777
|
+
except Exception: # noqa: BLE001 — transport already broken
|
|
1778
|
+
logger.warning("stream.error emit failed for %s", stream_id)
|
|
1779
|
+
|
|
1780
|
+
async def _run_chat_stream_coreloop(
|
|
1781
|
+
self,
|
|
1782
|
+
provider: LLMProvider,
|
|
1783
|
+
messages: list[LLMMessage],
|
|
1784
|
+
params: dict[str, Any],
|
|
1785
|
+
stream_id: str,
|
|
1786
|
+
transport: StdioJsonRpcTransport,
|
|
1787
|
+
) -> None:
|
|
1788
|
+
"""CoreLoop-backed chat stream (flag-gated — see ``_use_coreloop``).
|
|
1789
|
+
|
|
1790
|
+
Maps LoopEvents onto the existing wire surface so hosts don't need a
|
|
1791
|
+
new protocol to opt in: content/reasoning deltas and tool progress
|
|
1792
|
+
arrive as ``stream.chunk``; the terminal completion arrives as
|
|
1793
|
+
``stream.done`` with the loop's status/reason attached.
|
|
1794
|
+
|
|
1795
|
+
``contentMode: "final"`` buffers each provider call's display text
|
|
1796
|
+
until its outcome is known. A new request replaces a rejected retry
|
|
1797
|
+
draft, and a tool call discards that request's narration. Only the
|
|
1798
|
+
terminal tool-free response reaches the host; the durable record and
|
|
1799
|
+
trace still retain every intermediate assistant turn.
|
|
1800
|
+
|
|
1801
|
+
``mcp`` mounts per-turn MCP servers on the sidecar-local path.
|
|
1802
|
+
Stdio entries use ``command`` and Streamable HTTP entries use
|
|
1803
|
+
``url``; each client registers its catalog under the
|
|
1804
|
+
``mcp__<name>__<tool>`` prefix on this turn's router, and closes the
|
|
1805
|
+
clients when the stream ends (completion, error, or cancel). It is
|
|
1806
|
+
the sidecar-local counterpart of the ACP adapter's ``mcpServers``
|
|
1807
|
+
wiring (``acp_adapter``); over ``toolsViaHost`` the host owns tool
|
|
1808
|
+
execution, so MCP mounting is a desktop concern instead.
|
|
1809
|
+
"""
|
|
1810
|
+
|
|
1811
|
+
# mcp: per-turn MCP servers on the sidecar-local path. Each entry
|
|
1812
|
+
# creates one transport client; its catalog is registered on this
|
|
1813
|
+
# turn's router under the ``mcp__<name>__<tool>`` prefix. Clients close
|
|
1814
|
+
# in this method's ``finally`` so a completion, error, or cancel never
|
|
1815
|
+
# leaks a transport. Skipped under toolsViaHost (the host owns
|
|
1816
|
+
# execution there) and when an embedder replaces the whole harness
|
|
1817
|
+
# (the hooks factory owns the tool surface).
|
|
1818
|
+
mcp_clients: list[McpClient] = []
|
|
1819
|
+
mcp_param = params.get("mcp")
|
|
1820
|
+
if (
|
|
1821
|
+
isinstance(mcp_param, list)
|
|
1822
|
+
and mcp_param
|
|
1823
|
+
and not params.get("toolsViaHost")
|
|
1824
|
+
and self._loop_hooks_factory is None
|
|
1825
|
+
):
|
|
1826
|
+
# Entries were shape-validated in _handle_chat_stream.
|
|
1827
|
+
for index, server in enumerate(mcp_param):
|
|
1828
|
+
name = str(server.get("name") or f"mcp{index}")
|
|
1829
|
+
client = create_mcp_client(server)
|
|
1830
|
+
await client.start()
|
|
1831
|
+
mcp_clients.append(client)
|
|
1832
|
+
catalog = await client.list_tools()
|
|
1833
|
+
register_mcp_catalog(
|
|
1834
|
+
self.tools,
|
|
1835
|
+
server=name,
|
|
1836
|
+
tools=catalog,
|
|
1837
|
+
invoker=mcp_invoker(client),
|
|
1838
|
+
)
|
|
1839
|
+
|
|
1840
|
+
if self._loop_hooks_factory is not None:
|
|
1841
|
+
# An embedder-supplied hooks factory replaces the whole default
|
|
1842
|
+
# assembly, tools dimension included — no selection is applied.
|
|
1843
|
+
hooks: LoopHooks = self._loop_hooks_factory(params)
|
|
1844
|
+
tool_selection: Any = None
|
|
1845
|
+
else:
|
|
1846
|
+
default_harness = _assemble_default_harness(
|
|
1847
|
+
params, summarizer=_summarizer_for(provider)
|
|
1848
|
+
)
|
|
1849
|
+
hooks = default_harness.hooks
|
|
1850
|
+
tool_selection = default_harness.tool_selection
|
|
1851
|
+
# todo completion gate: a turn that ends `completed` while the
|
|
1852
|
+
# chat's todo list still has unfinished items is retried with a
|
|
1853
|
+
# reminder instead of stalling for user input (long-task stall fix).
|
|
1854
|
+
# The gate keys the store by the run's LoopContext.chat_id — the same
|
|
1855
|
+
# id todo_write dispatches with — so it reads the list the model wrote.
|
|
1856
|
+
from .todo_tools import todo_store
|
|
1857
|
+
|
|
1858
|
+
hooks = ChainHooks(hooks, TodoCompletionGate(todo_store()))
|
|
1859
|
+
# Planning nudge: one reminder per turn when a long run never wrote
|
|
1860
|
+
# a task list. Per-run instance — it counts this turn's tool calls.
|
|
1861
|
+
if self.tools.get("todo_write") is not None:
|
|
1862
|
+
hooks = ChainHooks(hooks, TodoPlanningNudge(todo_store()))
|
|
1863
|
+
# The bundled spec's tools dimension governs the host-supplied tool
|
|
1864
|
+
# surface; the sidecar's own additions below (subagent / skills /
|
|
1865
|
+
# orchestration) are orthogonal dimensions advertised past
|
|
1866
|
+
# selection, mirroring the headless assembly. The bundled `full`
|
|
1867
|
+
# strategy is a pass-through. A router-backed strategy
|
|
1868
|
+
# (progressive) cannot run on this path — host tools dispatch over
|
|
1869
|
+
# the reverse channel, so there is no in-process ToolRouter to bind
|
|
1870
|
+
# — and must fail loud rather than offer a dead descriptor.
|
|
1871
|
+
tools = params.get("tools")
|
|
1872
|
+
from steerable_agent_runtime.approval import declared_resolver as _declared_resolver
|
|
1873
|
+
|
|
1874
|
+
approval_resolve = _declared_resolver(tools if isinstance(tools, list) else None)
|
|
1875
|
+
if isinstance(tools, list):
|
|
1876
|
+
tools = [_model_tool(tool) for tool in tools]
|
|
1877
|
+
if tools is not None and tool_selection is not None:
|
|
1878
|
+
try:
|
|
1879
|
+
tools = tool_selection.select(list(tools))
|
|
1880
|
+
except ValueError as exc:
|
|
1881
|
+
logger.error("chat stream %s rejected: %s", stream_id, exc)
|
|
1882
|
+
await transport.emit_notification(
|
|
1883
|
+
"stream.error",
|
|
1884
|
+
{
|
|
1885
|
+
"streamId": stream_id,
|
|
1886
|
+
"kind": exc.__class__.__name__,
|
|
1887
|
+
"message": str(exc),
|
|
1888
|
+
},
|
|
1889
|
+
)
|
|
1890
|
+
self._streams.pop(stream_id, None)
|
|
1891
|
+
return
|
|
1892
|
+
# antiHallucination: sink the desktop loop's four guards (data-need
|
|
1893
|
+
# routing, deferred/claimed retry, grounding judge, narration) into
|
|
1894
|
+
# the CoreLoop via hooks. Off unless the host opts in.
|
|
1895
|
+
ah = params.get("antiHallucination")
|
|
1896
|
+
if ah:
|
|
1897
|
+
ah_opts = ah if isinstance(ah, dict) else {}
|
|
1898
|
+
tool_context = params.get("toolContext") or {}
|
|
1899
|
+
hooks = ChainHooks(
|
|
1900
|
+
AntiHallucinationHooks(
|
|
1901
|
+
provider,
|
|
1902
|
+
AntiHallucinationConfig(
|
|
1903
|
+
mode=tool_context.get("mode"),
|
|
1904
|
+
user_question=_last_message_content(messages, "user"),
|
|
1905
|
+
last_assistant_tail=_last_message_content(
|
|
1906
|
+
messages, "assistant", tail=400
|
|
1907
|
+
),
|
|
1908
|
+
max_retries=int(ah_opts.get("maxRetries") or 2),
|
|
1909
|
+
tools_available=bool(params.get("tools")),
|
|
1910
|
+
),
|
|
1911
|
+
),
|
|
1912
|
+
hooks,
|
|
1913
|
+
)
|
|
1914
|
+
# toolsViaHost: every tool call is forwarded to the host over the
|
|
1915
|
+
# reverse channel (desktop deployment — tools live in Electron).
|
|
1916
|
+
# Otherwise the sidecar-local registry executes them.
|
|
1917
|
+
executor = (
|
|
1918
|
+
HostToolExecutor(
|
|
1919
|
+
self.server, tool_context=params.get("toolContext") or None
|
|
1920
|
+
)
|
|
1921
|
+
if params.get("toolsViaHost")
|
|
1922
|
+
else RouterToolExecutor(self.tools)
|
|
1923
|
+
)
|
|
1924
|
+
# execSandbox: opt-in per-exec confinement for shell/subprocess
|
|
1925
|
+
# calls (Wave 3). The command is rewritten to run under the
|
|
1926
|
+
# platform's backend (Seatbelt on macOS, bwrap on Linux) and then
|
|
1927
|
+
# delegated — over toolsViaHost the confined command is spawned by
|
|
1928
|
+
# the host's shell, giving the desktop per-exec confinement without
|
|
1929
|
+
# the host learning sandbox mechanics. Wrapped inside the approval
|
|
1930
|
+
# layer so the approver reviews the ORIGINAL command, not the
|
|
1931
|
+
# sandboxed invocation. Absent → commands run unconfined (legacy
|
|
1932
|
+
# behavior); enabled with no available backend → enforcement "none"
|
|
1933
|
+
# (requireFull refuses anything short of full; requireBackend
|
|
1934
|
+
# refuses only enforcement "none" — the desktop uses the latter so
|
|
1935
|
+
# honest-partial Seatbelt/bwrap still runs).
|
|
1936
|
+
# Kept on the turn so a later steer can switch workspace / full
|
|
1937
|
+
# access without rebuilding the executor chain.
|
|
1938
|
+
exec_control = _TurnExecControl()
|
|
1939
|
+
exec_sandbox = params.get("execSandbox")
|
|
1940
|
+
if isinstance(exec_sandbox, dict) and exec_sandbox.get("enabled"):
|
|
1941
|
+
backend = select_exec_backend(
|
|
1942
|
+
writable_roots=[
|
|
1943
|
+
str(r) for r in exec_sandbox.get("writableRoots") or []
|
|
1944
|
+
],
|
|
1945
|
+
network=bool(exec_sandbox.get("network")),
|
|
1946
|
+
allowed_hosts=exec_sandbox.get("allowedHosts") or None,
|
|
1947
|
+
shell=str(exec_sandbox.get("shell") or "/bin/sh"),
|
|
1948
|
+
)
|
|
1949
|
+
if backend is None and exec_sandbox.get("hostSpawn"):
|
|
1950
|
+
# W2.2.1: no local rewriter backend (Windows) — delegate
|
|
1951
|
+
# confined spawn to the host over the reverse channel
|
|
1952
|
+
# instead of rewriting the command. The host owns the real
|
|
1953
|
+
# confinement (restricted token + JobObject) and reports the
|
|
1954
|
+
# enforcement it applied; absent capability fails closed.
|
|
1955
|
+
from .host_spawn import HostSpawnExecutor
|
|
1956
|
+
|
|
1957
|
+
executor = HostSpawnExecutor(
|
|
1958
|
+
executor,
|
|
1959
|
+
self.server,
|
|
1960
|
+
policy={
|
|
1961
|
+
"writableRoots": [
|
|
1962
|
+
str(r) for r in exec_sandbox.get("writableRoots") or []
|
|
1963
|
+
],
|
|
1964
|
+
"network": bool(exec_sandbox.get("network")),
|
|
1965
|
+
"allowedHosts": exec_sandbox.get("allowedHosts") or [],
|
|
1966
|
+
},
|
|
1967
|
+
shell_tools=(
|
|
1968
|
+
exec_sandbox["tools"]
|
|
1969
|
+
if exec_sandbox.get("tools") is not None
|
|
1970
|
+
else DEFAULT_SHELL_TOOLS
|
|
1971
|
+
),
|
|
1972
|
+
command_arg=str(exec_sandbox.get("commandArg") or "command"),
|
|
1973
|
+
)
|
|
1974
|
+
exec_control.sandbox = executor
|
|
1975
|
+
else:
|
|
1976
|
+
executor = SandboxedToolExecutor(
|
|
1977
|
+
executor,
|
|
1978
|
+
backend,
|
|
1979
|
+
shell_tools=(
|
|
1980
|
+
exec_sandbox["tools"]
|
|
1981
|
+
if exec_sandbox.get("tools") is not None
|
|
1982
|
+
else DEFAULT_SHELL_TOOLS
|
|
1983
|
+
),
|
|
1984
|
+
command_arg=str(exec_sandbox.get("commandArg") or "command"),
|
|
1985
|
+
require_full=bool(exec_sandbox.get("requireFull")),
|
|
1986
|
+
require_backend=bool(exec_sandbox.get("requireBackend")),
|
|
1987
|
+
)
|
|
1988
|
+
exec_control.sandbox = executor
|
|
1989
|
+
# approval: opt-in approval algebra (Wave 3). ``{"mode": "auto"}`` is
|
|
1990
|
+
# the headless policy (safe modes auto-approve, the rest auto-deny —
|
|
1991
|
+
# a run never hangs on a prompt nobody answers); ``{"mode": "host"}``
|
|
1992
|
+
# asks the host UI over the reverse channel. Absent → no approval
|
|
1993
|
+
# layer, the router's require_consent gate alone (legacy behavior).
|
|
1994
|
+
# Wrapped innermost so a subagent's child-loop calls are gated too.
|
|
1995
|
+
approval = params.get("approval")
|
|
1996
|
+
if isinstance(approval, dict) and approval.get("mode") in ("auto", "host"):
|
|
1997
|
+
timeout_ms = approval.get("timeoutMs")
|
|
1998
|
+
store_path = approval.get("storePath")
|
|
1999
|
+
# W2.4: pattern rules (codex execpolicy's counterpart). Loaded
|
|
2000
|
+
# from ``policyPath`` and consulted after the lattice's own
|
|
2001
|
+
# caches, before the interactive/headless approver; host replies
|
|
2002
|
+
# may amend it (``amendment`` payload → durable rule). The sink
|
|
2003
|
+
# updates the live in-memory policy too, so an amendment takes
|
|
2004
|
+
# effect within the same run, not just on the next one.
|
|
2005
|
+
approver: Any
|
|
2006
|
+
approval_chat_id = _approval_prompt_chat_id(params)
|
|
2007
|
+
policy_path = approval.get("policyPath")
|
|
2008
|
+
# In-project file targets do not ask. Roots come from the host's
|
|
2009
|
+
# project fence (still sent when 「完整权限」 turns the OS sandbox
|
|
2010
|
+
# off). The exec sandbox list is the fallback for callers that
|
|
2011
|
+
# only set that. Shell calls skip the prompt only while that
|
|
2012
|
+
# sandbox is actually on and the cwd stays in the roots; with
|
|
2013
|
+
# the sandbox off, or a cwd outside the roots, the prompt stays.
|
|
2014
|
+
# allow_once is not cached, so the next call is judged on its
|
|
2015
|
+
# own paths. Sits under policy rules so an explicit deny still wins.
|
|
2016
|
+
raw_roots = approval.get("writableRoots")
|
|
2017
|
+
if (
|
|
2018
|
+
not raw_roots
|
|
2019
|
+
and isinstance(exec_sandbox, dict)
|
|
2020
|
+
and exec_sandbox.get("enabled")
|
|
2021
|
+
):
|
|
2022
|
+
raw_roots = exec_sandbox.get("writableRoots")
|
|
2023
|
+
writable_roots = (
|
|
2024
|
+
[str(root) for root in (raw_roots or []) if root]
|
|
2025
|
+
if approval["mode"] == "host"
|
|
2026
|
+
else []
|
|
2027
|
+
)
|
|
2028
|
+
raw_base = approval.get("pathBase")
|
|
2029
|
+
path_base = str(raw_base) if isinstance(raw_base, str) and raw_base.strip() else None
|
|
2030
|
+
|
|
2031
|
+
def _sandbox_enforced() -> bool:
|
|
2032
|
+
# The wrapper is installed before the first approve call, and
|
|
2033
|
+
# steer updates this flag for the next shell call.
|
|
2034
|
+
approver = exec_control.approver
|
|
2035
|
+
return bool(getattr(approver, "_sandbox_enforced", False))
|
|
2036
|
+
|
|
2037
|
+
def _host_approver(amendment_sink: Any | None = None) -> Any:
|
|
2038
|
+
host = HostApprover(
|
|
2039
|
+
self.server,
|
|
2040
|
+
amendment_sink=amendment_sink,
|
|
2041
|
+
chat_id=approval_chat_id,
|
|
2042
|
+
sandbox_enforced=_sandbox_enforced,
|
|
2043
|
+
)
|
|
2044
|
+
from steerable_agent_runtime.approval import WorkspaceAutoApprover
|
|
2045
|
+
|
|
2046
|
+
approver = WorkspaceAutoApprover(
|
|
2047
|
+
host,
|
|
2048
|
+
writable_roots,
|
|
2049
|
+
sandbox_enforced=bool(
|
|
2050
|
+
isinstance(exec_sandbox, dict) and exec_sandbox.get("enabled")
|
|
2051
|
+
),
|
|
2052
|
+
auto_allow_tools=_AUTO_APPROVED_HOST_CONTROL_TOOLS,
|
|
2053
|
+
path_base=path_base,
|
|
2054
|
+
)
|
|
2055
|
+
exec_control.approver = approver
|
|
2056
|
+
return approver
|
|
2057
|
+
|
|
2058
|
+
if policy_path:
|
|
2059
|
+
from steerable_agent_runtime import (
|
|
2060
|
+
JsonApprovalPolicyStore,
|
|
2061
|
+
PolicyApprover,
|
|
2062
|
+
)
|
|
2063
|
+
|
|
2064
|
+
policy_store = JsonApprovalPolicyStore(str(policy_path))
|
|
2065
|
+
live_policy = policy_store.load()
|
|
2066
|
+
|
|
2067
|
+
def _amendment_sink(rule: Any) -> None:
|
|
2068
|
+
live_policy.add(rule)
|
|
2069
|
+
policy_store.add_rule(rule)
|
|
2070
|
+
|
|
2071
|
+
base = (
|
|
2072
|
+
AutoApprover()
|
|
2073
|
+
if approval["mode"] == "auto"
|
|
2074
|
+
else _host_approver(_amendment_sink)
|
|
2075
|
+
)
|
|
2076
|
+
approver = PolicyApprover(base, live_policy)
|
|
2077
|
+
elif approval["mode"] == "auto":
|
|
2078
|
+
approver = AutoApprover()
|
|
2079
|
+
else:
|
|
2080
|
+
approver = _host_approver()
|
|
2081
|
+
executor = ApprovalExecutor(
|
|
2082
|
+
executor,
|
|
2083
|
+
approver,
|
|
2084
|
+
session=self._approval_session(approval_chat_id or params.get("chatId")),
|
|
2085
|
+
store=JsonApprovalStore(store_path) if store_path else None,
|
|
2086
|
+
timeout_s=(float(timeout_ms) / 1000.0) if timeout_ms else None,
|
|
2087
|
+
resolve=approval_resolve,
|
|
2088
|
+
)
|
|
2089
|
+
# Child-safe sidecar-local tools must be visible and dispatchable
|
|
2090
|
+
# before SubagentExecutor snapshots its tool domain. User interaction
|
|
2091
|
+
# is deliberately absent: children report questions through
|
|
2092
|
+
# request_parent_input and the parent owns ask_user.
|
|
2093
|
+
child_local_names: list[str] = []
|
|
2094
|
+
if self.tools.get("todo_write") is not None:
|
|
2095
|
+
from steerable_agent_runtime import todo_write_tool_descriptor
|
|
2096
|
+
from .run_code import RunCodeBoundExecutor
|
|
2097
|
+
|
|
2098
|
+
child_local_names.append("todo_write")
|
|
2099
|
+
tools = [*(tools or []), todo_write_tool_descriptor()]
|
|
2100
|
+
executor = RunCodeBoundExecutor(
|
|
2101
|
+
executor,
|
|
2102
|
+
router=self.tools,
|
|
2103
|
+
local_names=child_local_names,
|
|
2104
|
+
)
|
|
2105
|
+
# subagent: the delegation seam is ON BY DEFAULT (delegate-on-pool
|
|
2106
|
+
# unification) — delegate_subagent is the model's single multi-agent
|
|
2107
|
+
# surface; the six-tool orchestration family below is the opt-in
|
|
2108
|
+
# advanced mode. ``params.subagent: false`` turns delegation off;
|
|
2109
|
+
# a dict configures it. ``{"toolFilter": ["read_a", "read_b"]}``
|
|
2110
|
+
# narrows the child's tool domain (W4-5): filtered-out calls fail
|
|
2111
|
+
# closed with tool_not_delegated, so a read-only research sub-agent
|
|
2112
|
+
# cannot reach the parent's write/shell tools by construction.
|
|
2113
|
+
# Children run as pooled AgentPool runs: lifecycle lands on the
|
|
2114
|
+
# agent.child notification stream, and a concurrent profile's
|
|
2115
|
+
# same-round delegations execute in parallel under the pool budget.
|
|
2116
|
+
loop_config = _build_loop_config(params)
|
|
2117
|
+
subagent_param = params.get("subagent", True)
|
|
2118
|
+
subagent_executor: SubagentExecutor | None = None
|
|
2119
|
+
if subagent_param:
|
|
2120
|
+
subagent_opts = subagent_param if isinstance(subagent_param, dict) else {}
|
|
2121
|
+
tool_filter = (
|
|
2122
|
+
frozenset(str(t) for t in subagent_opts.get("toolFilter"))
|
|
2123
|
+
if isinstance(subagent_opts.get("toolFilter"), list)
|
|
2124
|
+
else None
|
|
2125
|
+
)
|
|
2126
|
+
# Named profiles (CC ``subagent_type`` parity): the host passes
|
|
2127
|
+
# ``{"profiles": {"researcher": {"toolFilter": [...], "model":
|
|
2128
|
+
# "...", "maxRounds": N, "concurrent": bool}}}`` and the tool
|
|
2129
|
+
# schema advertises the names as a ``subagent_type`` enum. An
|
|
2130
|
+
# unknown name fails closed listing the registered ones.
|
|
2131
|
+
# Round / tool-error walls inherit the parent loop unless a
|
|
2132
|
+
# profile pins its own. The parent default is no cap, so an
|
|
2133
|
+
# unpinned child is not stopped at SubagentConfig's 8 / 3.
|
|
2134
|
+
registry = None
|
|
2135
|
+
profiles = subagent_opts.get("profiles")
|
|
2136
|
+
if isinstance(profiles, dict) and profiles:
|
|
2137
|
+
registry = SubagentRegistry()
|
|
2138
|
+
for name, profile_opts in profiles.items():
|
|
2139
|
+
p = profile_opts if isinstance(profile_opts, dict) else {}
|
|
2140
|
+
p_filter = (
|
|
2141
|
+
frozenset(str(t) for t in p.get("toolFilter"))
|
|
2142
|
+
if isinstance(p.get("toolFilter"), list)
|
|
2143
|
+
else None
|
|
2144
|
+
)
|
|
2145
|
+
registry.register(
|
|
2146
|
+
str(name),
|
|
2147
|
+
SubagentConfig(
|
|
2148
|
+
max_rounds=int(
|
|
2149
|
+
p.get("maxRounds", loop_config.max_rounds)
|
|
2150
|
+
),
|
|
2151
|
+
max_tool_errors=int(
|
|
2152
|
+
p.get(
|
|
2153
|
+
"maxToolErrors", loop_config.max_tool_errors
|
|
2154
|
+
)
|
|
2155
|
+
),
|
|
2156
|
+
tool_filter=p_filter,
|
|
2157
|
+
model=(
|
|
2158
|
+
str(p["model"]) if p.get("model") is not None else None
|
|
2159
|
+
),
|
|
2160
|
+
concurrent=bool(p.get("concurrent", False)),
|
|
2161
|
+
system_prompt=(
|
|
2162
|
+
str(p["systemPrompt"])
|
|
2163
|
+
if p.get("systemPrompt") is not None
|
|
2164
|
+
else None
|
|
2165
|
+
),
|
|
2166
|
+
description=(
|
|
2167
|
+
str(p["description"])
|
|
2168
|
+
if p.get("description") is not None
|
|
2169
|
+
else SubagentConfig().description
|
|
2170
|
+
),
|
|
2171
|
+
),
|
|
2172
|
+
)
|
|
2173
|
+
|
|
2174
|
+
# Per-profile models resolve through a provider factory that
|
|
2175
|
+
# re-enters the host's own factory with the model overridden —
|
|
2176
|
+
# a profile naming a model the host cannot serve fails closed
|
|
2177
|
+
# rather than silently running the parent's model.
|
|
2178
|
+
def _subagent_provider_factory(model: str) -> LLMProvider:
|
|
2179
|
+
overridden = {**params, "model": model}
|
|
2180
|
+
return self._llm_provider_factory(overridden)
|
|
2181
|
+
|
|
2182
|
+
subagent_executor = SubagentExecutor(
|
|
2183
|
+
executor,
|
|
2184
|
+
provider,
|
|
2185
|
+
SubagentConfig(
|
|
2186
|
+
tool_filter=tool_filter,
|
|
2187
|
+
max_parallel=int(subagent_opts.get("maxParallel", 4)),
|
|
2188
|
+
max_rounds=int(
|
|
2189
|
+
subagent_opts.get("maxRounds", loop_config.max_rounds)
|
|
2190
|
+
),
|
|
2191
|
+
max_tool_errors=int(
|
|
2192
|
+
subagent_opts.get(
|
|
2193
|
+
"maxToolErrors", loop_config.max_tool_errors
|
|
2194
|
+
)
|
|
2195
|
+
),
|
|
2196
|
+
),
|
|
2197
|
+
registry=registry,
|
|
2198
|
+
provider_factory=_subagent_provider_factory,
|
|
2199
|
+
# Each child writes its own durable record
|
|
2200
|
+
# (``<parent>:child:<lineage id>``) so the host can render
|
|
2201
|
+
# the delegation's process; the id rides child_spawned.
|
|
2202
|
+
history_store=self.storage,
|
|
2203
|
+
record_id_prefix=(
|
|
2204
|
+
params.get("recordId") or params.get("chatId") or None
|
|
2205
|
+
),
|
|
2206
|
+
# Children advertise the host tool surface (minus the
|
|
2207
|
+
# delegation tool itself), narrowed per profile; the
|
|
2208
|
+
# descriptor appended below is deliberately not in the
|
|
2209
|
+
# snapshot — a child never re-delegates (depth-1).
|
|
2210
|
+
tools=list(tools or []),
|
|
2211
|
+
event_sink=lambda kind, data: self._emit_child_event(
|
|
2212
|
+
transport, stream_id, kind, data
|
|
2213
|
+
),
|
|
2214
|
+
)
|
|
2215
|
+
executor = subagent_executor
|
|
2216
|
+
tools = [
|
|
2217
|
+
*(tools or []),
|
|
2218
|
+
subagent_tool_descriptor(registry=registry),
|
|
2219
|
+
]
|
|
2220
|
+
# requiredProfiles: the host named these sub-agents for the turn
|
|
2221
|
+
# (desktop ``@`` mentions), so finishing without delegating to
|
|
2222
|
+
# one is a skipped instruction, not a choice. The prompt alone
|
|
2223
|
+
# cannot enforce that — a turn that ran other tools and narrated
|
|
2224
|
+
# the hand-off passes every other discipline guard.
|
|
2225
|
+
required_profiles = [
|
|
2226
|
+
str(name) for name in subagent_opts.get("requiredProfiles") or []
|
|
2227
|
+
]
|
|
2228
|
+
if required_profiles:
|
|
2229
|
+
hooks = ChainHooks(
|
|
2230
|
+
RequiredDelegationGate(
|
|
2231
|
+
required_profiles,
|
|
2232
|
+
tool_name=SubagentConfig().tool_name,
|
|
2233
|
+
),
|
|
2234
|
+
hooks,
|
|
2235
|
+
)
|
|
2236
|
+
# worldState: slow-changing host context (time, workspace, git
|
|
2237
|
+
# branch, …) as plain per-section data. The loop injects it once as
|
|
2238
|
+
# a <world-state> fragment; later turns diff against the snapshot
|
|
2239
|
+
# embedded in the last fragment — unchanged state costs zero tokens,
|
|
2240
|
+
# a change costs one small RFC 7386 tail patch. Hosts adopting this
|
|
2241
|
+
# stop rebuilding the system prompt per turn, keeping the cached
|
|
2242
|
+
# prefix byte-stable.
|
|
2243
|
+
world_state = params.get("worldState")
|
|
2244
|
+
if isinstance(world_state, dict) and world_state:
|
|
2245
|
+
hooks = ChainHooks(
|
|
2246
|
+
WorldStateHooks(
|
|
2247
|
+
[
|
|
2248
|
+
StaticWorldStateSection(str(key), value)
|
|
2249
|
+
for key, value in world_state.items()
|
|
2250
|
+
]
|
|
2251
|
+
),
|
|
2252
|
+
hooks,
|
|
2253
|
+
)
|
|
2254
|
+
# skills: layered disclosure. The host injects the eager layer into
|
|
2255
|
+
# the system prompt itself; the sidecar lists the catalog layer
|
|
2256
|
+
# (first-round pre_step injection, recorded as a hook_action event)
|
|
2257
|
+
# and answers `skill` tool calls with the full body. ``mode:
|
|
2258
|
+
# "eager"`` keeps everything host-side (compat for hosts that have
|
|
2259
|
+
# not adopted layered disclosure). Roots are host-local paths — the
|
|
2260
|
+
# sidecar shares the filesystem with the desktop host.
|
|
2261
|
+
skills_param = params.get("skills")
|
|
2262
|
+
if (
|
|
2263
|
+
isinstance(skills_param, dict)
|
|
2264
|
+
and skills_param.get("mode", "layered") != "eager"
|
|
2265
|
+
):
|
|
2266
|
+
roots = [str(r) for r in skills_param.get("roots") or []]
|
|
2267
|
+
conditions = set(skills_param.get("conditions") or [])
|
|
2268
|
+
exclude = list(skills_param.get("exclude") or [])
|
|
2269
|
+
pinned = list(skills_param.get("pinned") or [])
|
|
2270
|
+
ignore_conditions = bool(skills_param.get("ignoreConditions"))
|
|
2271
|
+
if roots:
|
|
2272
|
+
skill_provider = FilesystemSkillProvider(roots)
|
|
2273
|
+
# `pinned` only suppresses the catalog entry: the host has
|
|
2274
|
+
# already injected these bodies eagerly, but the model may
|
|
2275
|
+
# still call `skill` (and must get the full body if eager
|
|
2276
|
+
# injection was truncated). The readiness probe therefore
|
|
2277
|
+
# also counts pinned skills that survive hard exclusion, so
|
|
2278
|
+
# even a turn whose only visible skill is pinned still
|
|
2279
|
+
# advertises the skill tool.
|
|
2280
|
+
visible_catalog = select_catalog(
|
|
2281
|
+
skill_provider.list(), conditions, exclude, ignore_conditions
|
|
2282
|
+
)
|
|
2283
|
+
pinned_loadable = select_pinned_loadable(
|
|
2284
|
+
skill_provider.list(), pinned, exclude
|
|
2285
|
+
)
|
|
2286
|
+
catalog = select_catalog(
|
|
2287
|
+
skill_provider.list(),
|
|
2288
|
+
conditions,
|
|
2289
|
+
exclude,
|
|
2290
|
+
ignore_conditions,
|
|
2291
|
+
pinned,
|
|
2292
|
+
)
|
|
2293
|
+
if visible_catalog or pinned_loadable:
|
|
2294
|
+
if catalog:
|
|
2295
|
+
hooks = ChainHooks(
|
|
2296
|
+
SkillHooks(
|
|
2297
|
+
skill_provider,
|
|
2298
|
+
conditions=conditions,
|
|
2299
|
+
exclude=exclude,
|
|
2300
|
+
ignore_conditions=ignore_conditions,
|
|
2301
|
+
pinned=pinned,
|
|
2302
|
+
),
|
|
2303
|
+
hooks,
|
|
2304
|
+
)
|
|
2305
|
+
executor = SkillExecutor(
|
|
2306
|
+
executor,
|
|
2307
|
+
skill_provider,
|
|
2308
|
+
conditions=conditions,
|
|
2309
|
+
exclude=exclude,
|
|
2310
|
+
ignore_conditions=ignore_conditions,
|
|
2311
|
+
pinned=pinned,
|
|
2312
|
+
)
|
|
2313
|
+
tools = [*(tools or []), skill_tool_descriptor()]
|
|
2314
|
+
# orchestration: opt-in advanced multi-agent seam (P3.1) — the
|
|
2315
|
+
# parent model drives parallel child CoreLoops through
|
|
2316
|
+
# agent_spawn/send/wait/close/list/interrupt. OFF BY DEFAULT since
|
|
2317
|
+
# the delegate-on-pool unification: delegate_subagent (above) is the
|
|
2318
|
+
# single model-facing surface; the six tools ship only when the host
|
|
2319
|
+
# passes ``orchestration: {"enabled": true, ...}``. Wrapped outermost
|
|
2320
|
+
# so children inherit every gate below (approval, skills, subagent).
|
|
2321
|
+
# Budgets fail closed (maxDepth/maxParallel); depth is structural —
|
|
2322
|
+
# a child only has orchestration tools when its own pool is nested
|
|
2323
|
+
# inside. When both surfaces are on the delegation seam ADOPTS this
|
|
2324
|
+
# pool (attach_pool): one max_parallel budget, one lineage space,
|
|
2325
|
+
# and delegate children appear in agent_list.
|
|
2326
|
+
orchestration_param = params.get("orchestration")
|
|
2327
|
+
orchestration: OrchestrationExecutor | None = None
|
|
2328
|
+
if (
|
|
2329
|
+
isinstance(orchestration_param, dict)
|
|
2330
|
+
and orchestration_param
|
|
2331
|
+
and not orchestration_param.get("enabled")
|
|
2332
|
+
):
|
|
2333
|
+
# Pre-unification hosts passed a bare config dict (e.g.
|
|
2334
|
+
# {"maxDepth": 1}) to enable the six tools. That no longer
|
|
2335
|
+
# enables them — say so loudly instead of silently dropping.
|
|
2336
|
+
logger.warning(
|
|
2337
|
+
"orchestration config passed without enabled:true; the six "
|
|
2338
|
+
"orchestration tools stay off (delegate_subagent is the "
|
|
2339
|
+
"default multi-agent surface). Set orchestration.enabled=true "
|
|
2340
|
+
"to opt into agent_spawn/send/wait/close/list/interrupt."
|
|
2341
|
+
)
|
|
2342
|
+
if isinstance(orchestration_param, dict) and orchestration_param.get("enabled"):
|
|
2343
|
+
# Child round / tool-error walls inherit the parent loop unless the
|
|
2344
|
+
# host pins them, matching the delegation profiles above.
|
|
2345
|
+
orch_config = OrchestrationConfig(
|
|
2346
|
+
max_depth=int(orchestration_param.get("maxDepth", 1)),
|
|
2347
|
+
max_parallel=int(orchestration_param.get("maxParallel", 4)),
|
|
2348
|
+
child_max_rounds=int(
|
|
2349
|
+
orchestration_param.get("childMaxRounds", loop_config.max_rounds)
|
|
2350
|
+
),
|
|
2351
|
+
child_max_tool_errors=int(
|
|
2352
|
+
orchestration_param.get(
|
|
2353
|
+
"childMaxToolErrors", loop_config.max_tool_errors
|
|
2354
|
+
)
|
|
2355
|
+
),
|
|
2356
|
+
)
|
|
2357
|
+
orchestration = OrchestrationExecutor(
|
|
2358
|
+
executor,
|
|
2359
|
+
provider,
|
|
2360
|
+
orch_config,
|
|
2361
|
+
tools=list(tools or []),
|
|
2362
|
+
event_sink=lambda kind, data: self._emit_child_event(
|
|
2363
|
+
transport, stream_id, kind, data
|
|
2364
|
+
),
|
|
2365
|
+
)
|
|
2366
|
+
if subagent_executor is not None:
|
|
2367
|
+
subagent_executor.attach_pool(orchestration.pool)
|
|
2368
|
+
executor = orchestration
|
|
2369
|
+
tools = [
|
|
2370
|
+
*(tools or []),
|
|
2371
|
+
*orchestration_tool_descriptors(orch_config),
|
|
2372
|
+
]
|
|
2373
|
+
# Router-answered tools (run_code, ask_user): registered on the
|
|
2374
|
+
# sidecar's router but unknown to the host — under toolsViaHost the
|
|
2375
|
+
# inner executor forwards every call to the host, so they must be
|
|
2376
|
+
# intercepted here and dispatched locally regardless of which subset
|
|
2377
|
+
# is enabled.
|
|
2378
|
+
local_names: list[str] = []
|
|
2379
|
+
if self.tools.get("run_code") is not None:
|
|
2380
|
+
from .run_code import run_code_tool_descriptor
|
|
2381
|
+
|
|
2382
|
+
local_names.append("run_code")
|
|
2383
|
+
# Advertise the tool to the model: registration on the router only
|
|
2384
|
+
# enables dispatch; the descriptor must also reach the tools array
|
|
2385
|
+
# (mirrors subagent/skills above) or the model never sees run_code.
|
|
2386
|
+
tools = [*(tools or []), run_code_tool_descriptor()]
|
|
2387
|
+
# todo_write: session task list (CC TodoWrite parity). Registered
|
|
2388
|
+
# unconditionally at boot and advertised above before the subagent
|
|
2389
|
+
# snapshots its domain. Keep it in this outer dispatcher too so
|
|
2390
|
+
# parent run_code calls capture the complete executor chain.
|
|
2391
|
+
if self.tools.get("todo_write") is not None:
|
|
2392
|
+
local_names.append("todo_write")
|
|
2393
|
+
# run_js/wait_js: conversational JS PTC (the codex CodeModeHost
|
|
2394
|
+
# counterpart). Same router-answered local dispatch as run_code; the
|
|
2395
|
+
# session binds to this run's chatId inside the tool.
|
|
2396
|
+
if self.tools.get("run_js") is not None:
|
|
2397
|
+
from .ptc_js import run_js_tool_descriptor, wait_js_tool_descriptor
|
|
2398
|
+
|
|
2399
|
+
local_names.extend(["run_js", "wait_js"])
|
|
2400
|
+
tools = [
|
|
2401
|
+
*(tools or []),
|
|
2402
|
+
run_js_tool_descriptor(),
|
|
2403
|
+
wait_js_tool_descriptor(),
|
|
2404
|
+
]
|
|
2405
|
+
# askUser: opt-in structured user questions (W8). The host renders the
|
|
2406
|
+
# question card and answers over the reverse channel
|
|
2407
|
+
# (``ask_user.request``); the tool blocks until the reply. Registered
|
|
2408
|
+
# on the router so dispatch works on both the host path (toolsViaHost)
|
|
2409
|
+
# and the sidecar-local path — the handler is host-routed either way.
|
|
2410
|
+
if params.get("askUser"):
|
|
2411
|
+
from steerable_agent_runtime import make_ask_user_tool
|
|
2412
|
+
|
|
2413
|
+
ask_fn = make_ask_user_tool(HostAskUserHandler(self.server))
|
|
2414
|
+
meta = ask_fn.__steerable_tool_meta__
|
|
2415
|
+
# Registration is process-global while this block runs per
|
|
2416
|
+
# request: the router rejects duplicates, so only the first
|
|
2417
|
+
# askUser turn registers (the handler binds self.server, which
|
|
2418
|
+
# is request-independent — re-registering would be identical).
|
|
2419
|
+
if self.tools.get(meta["name"]) is None:
|
|
2420
|
+
self.tools.register(
|
|
2421
|
+
ask_fn,
|
|
2422
|
+
name=meta["name"],
|
|
2423
|
+
mode=meta["mode"],
|
|
2424
|
+
description=meta["description"],
|
|
2425
|
+
schema=meta["schema"],
|
|
2426
|
+
require_consent=meta["require_consent"],
|
|
2427
|
+
concurrency_safe=meta["concurrency_safe"],
|
|
2428
|
+
exposure=meta["exposure"],
|
|
2429
|
+
)
|
|
2430
|
+
local_names.append(meta["name"])
|
|
2431
|
+
tools = [
|
|
2432
|
+
*(tools or []),
|
|
2433
|
+
{
|
|
2434
|
+
"type": "function",
|
|
2435
|
+
"function": {
|
|
2436
|
+
"name": meta["name"],
|
|
2437
|
+
"description": meta["description"],
|
|
2438
|
+
"parameters": meta["schema"],
|
|
2439
|
+
},
|
|
2440
|
+
},
|
|
2441
|
+
]
|
|
2442
|
+
if local_names:
|
|
2443
|
+
from .run_code import RunCodeBoundExecutor
|
|
2444
|
+
|
|
2445
|
+
executor = RunCodeBoundExecutor(
|
|
2446
|
+
executor, router=self.tools, local_names=local_names
|
|
2447
|
+
)
|
|
2448
|
+
# streamRawChunks: opt-in pre-digestion chunk forwarding. The loop's
|
|
2449
|
+
# on_stream_chunk hook sees every raw LLMStreamChunk before UI-tag
|
|
2450
|
+
# stripping and surrogate splitting turn it into display text — hosts
|
|
2451
|
+
# running incremental renderers (streaming UI-tag parsers) need that
|
|
2452
|
+
# stream; it rides stream.chunk under `rawChunk`, distinct from the
|
|
2453
|
+
# digested delta/reasoningDelta. Default off: it costs one
|
|
2454
|
+
# notification per chunk. (OpenAI-compat buffers tool arguments, so
|
|
2455
|
+
# toolCallDelta arrives whole — no incremental argument fragments.)
|
|
2456
|
+
if params.get("streamRawChunks"):
|
|
2457
|
+
hooks = ChainHooks(hooks, RawChunkBridgeHooks(transport, stream_id))
|
|
2458
|
+
loop = CoreLoop(
|
|
2459
|
+
provider,
|
|
2460
|
+
executor,
|
|
2461
|
+
loop_config,
|
|
2462
|
+
hooks=hooks,
|
|
2463
|
+
# Wave 1 durable record: the continuous per-chat log. An
|
|
2464
|
+
# explicit recordId (the fork path's fresh log) wins over the
|
|
2465
|
+
# default chat_id-derived one.
|
|
2466
|
+
history_store=self.storage,
|
|
2467
|
+
record_id=params.get("recordId") or params.get("chatId"),
|
|
2468
|
+
)
|
|
2469
|
+
# Persist the run as it streams so the host can inspect it afterwards
|
|
2470
|
+
# via trace.fetch (and so a future resume projection has the events).
|
|
2471
|
+
recorder = TraceRecorder(self.storage, chat_id=params.get("chatId"))
|
|
2472
|
+
self._coreloops[stream_id] = loop
|
|
2473
|
+
self._exec_controls[stream_id] = exec_control
|
|
2474
|
+
final_content_only = params.get("contentMode") == "final"
|
|
2475
|
+
pending_content: list[str] = []
|
|
2476
|
+
from .egress_ask import bind_turn_chat_id, reset_turn_chat_id
|
|
2477
|
+
|
|
2478
|
+
raw_chat_id = params.get("chatId")
|
|
2479
|
+
chat_token = bind_turn_chat_id(raw_chat_id if isinstance(raw_chat_id, str) else None)
|
|
2480
|
+
try:
|
|
2481
|
+
async for event in recorder.tee(
|
|
2482
|
+
loop.run(
|
|
2483
|
+
messages,
|
|
2484
|
+
tools=tools,
|
|
2485
|
+
chat_id=params.get("chatId"),
|
|
2486
|
+
)
|
|
2487
|
+
):
|
|
2488
|
+
if final_content_only:
|
|
2489
|
+
if event.kind == "llm_request":
|
|
2490
|
+
pending_content.clear()
|
|
2491
|
+
elif event.kind == "content_delta":
|
|
2492
|
+
pending_content.append(str(event.data.get("delta") or ""))
|
|
2493
|
+
continue
|
|
2494
|
+
elif event.kind == "tool_call_start":
|
|
2495
|
+
pending_content.clear()
|
|
2496
|
+
elif event.kind == "error":
|
|
2497
|
+
pending_content.clear()
|
|
2498
|
+
elif event.kind == "completion":
|
|
2499
|
+
if event.data.get("status") == "executing":
|
|
2500
|
+
pending_content.clear()
|
|
2501
|
+
elif pending_content:
|
|
2502
|
+
await transport.emit_notification(
|
|
2503
|
+
"stream.chunk",
|
|
2504
|
+
{
|
|
2505
|
+
"streamId": stream_id,
|
|
2506
|
+
"delta": "".join(pending_content),
|
|
2507
|
+
},
|
|
2508
|
+
)
|
|
2509
|
+
pending_content.clear()
|
|
2510
|
+
await self._emit_loop_event(
|
|
2511
|
+
transport,
|
|
2512
|
+
stream_id,
|
|
2513
|
+
event,
|
|
2514
|
+
recorder.trace_id,
|
|
2515
|
+
model=params.get("model"),
|
|
2516
|
+
hooks=hooks,
|
|
2517
|
+
)
|
|
2518
|
+
except asyncio.CancelledError:
|
|
2519
|
+
await transport.emit_notification(
|
|
2520
|
+
"stream.done",
|
|
2521
|
+
{
|
|
2522
|
+
"streamId": stream_id,
|
|
2523
|
+
"ok": False,
|
|
2524
|
+
"cancelled": True,
|
|
2525
|
+
"traceId": recorder.trace_id,
|
|
2526
|
+
},
|
|
2527
|
+
)
|
|
2528
|
+
except Exception as exc:
|
|
2529
|
+
logger.exception("coreloop chat stream %s failed", stream_id)
|
|
2530
|
+
await transport.emit_notification(
|
|
2531
|
+
"stream.error",
|
|
2532
|
+
{
|
|
2533
|
+
"streamId": stream_id,
|
|
2534
|
+
"kind": exc.__class__.__name__,
|
|
2535
|
+
"message": str(exc),
|
|
2536
|
+
# Failed turns are exactly the traces worth keeping — let
|
|
2537
|
+
# the host persist them via trace.fetch.
|
|
2538
|
+
"traceId": recorder.trace_id,
|
|
2539
|
+
},
|
|
2540
|
+
)
|
|
2541
|
+
finally:
|
|
2542
|
+
reset_turn_chat_id(chat_token)
|
|
2543
|
+
self._coreloops.pop(stream_id, None)
|
|
2544
|
+
self._exec_controls.pop(stream_id, None)
|
|
2545
|
+
for client in mcp_clients:
|
|
2546
|
+
# Close every per-turn MCP client (completion, error, or
|
|
2547
|
+
# cancel) so no transport outlives its stream.
|
|
2548
|
+
await client.aclose()
|
|
2549
|
+
if orchestration is not None:
|
|
2550
|
+
# Wind down any children still running when the parent ends
|
|
2551
|
+
# (completion, error, or cancel) — cooperative first. The
|
|
2552
|
+
# delegation seam shares this pool when both are on, so this
|
|
2553
|
+
# covers delegate children too.
|
|
2554
|
+
await orchestration.shutdown()
|
|
2555
|
+
elif subagent_executor is not None:
|
|
2556
|
+
# Delegation-only turn: wind down the delegate pool.
|
|
2557
|
+
await subagent_executor.shutdown()
|
|
2558
|
+
await recorder.finalize()
|
|
2559
|
+
self._streams.pop(stream_id, None)
|
|
2560
|
+
|
|
2561
|
+
def _emit_child_event(
|
|
2562
|
+
self,
|
|
2563
|
+
transport: StdioJsonRpcTransport,
|
|
2564
|
+
stream_id: str,
|
|
2565
|
+
kind: str,
|
|
2566
|
+
data: dict[str, Any],
|
|
2567
|
+
) -> None:
|
|
2568
|
+
"""Forward a child-lifecycle event from the agent pool.
|
|
2569
|
+
|
|
2570
|
+
Fired by orchestration children and by delegate_subagent
|
|
2571
|
+
delegations (both run on the pool). The pool's sink is synchronous
|
|
2572
|
+
(it fires inside tool execution), so the notification is scheduled
|
|
2573
|
+
fire-and-forget; ordering against the surrounding stream events is
|
|
2574
|
+
not guaranteed, lineage ids are.
|
|
2575
|
+
"""
|
|
2576
|
+
task = asyncio.ensure_future(
|
|
2577
|
+
transport.emit_notification(
|
|
2578
|
+
"agent.child", {"streamId": stream_id, "kind": kind, **data}
|
|
2579
|
+
)
|
|
2580
|
+
)
|
|
2581
|
+
task.add_done_callback(
|
|
2582
|
+
lambda t: (
|
|
2583
|
+
t.exception()
|
|
2584
|
+
and logger.warning("child event emit failed: %s", t.exception())
|
|
2585
|
+
)
|
|
2586
|
+
)
|
|
2587
|
+
|
|
2588
|
+
@staticmethod
|
|
2589
|
+
async def _emit_loop_event(
|
|
2590
|
+
transport: StdioJsonRpcTransport,
|
|
2591
|
+
stream_id: str,
|
|
2592
|
+
event: Any,
|
|
2593
|
+
trace_id: str | None = None,
|
|
2594
|
+
model: str | None = None,
|
|
2595
|
+
hooks: Any | None = None,
|
|
2596
|
+
) -> None:
|
|
2597
|
+
kind = event.kind
|
|
2598
|
+
data = event.data
|
|
2599
|
+
if kind == "content_delta":
|
|
2600
|
+
await transport.emit_notification(
|
|
2601
|
+
"stream.chunk", {"streamId": stream_id, "delta": data["delta"]}
|
|
2602
|
+
)
|
|
2603
|
+
elif kind == "reasoning_delta":
|
|
2604
|
+
await transport.emit_notification(
|
|
2605
|
+
"stream.chunk", {"streamId": stream_id, "reasoningDelta": data["delta"]}
|
|
2606
|
+
)
|
|
2607
|
+
elif kind == "stream_restart":
|
|
2608
|
+
# The engine is re-issuing the request it was streaming, so what
|
|
2609
|
+
# the host already appended belongs to a discarded attempt. The
|
|
2610
|
+
# host drops it instead of appending the retry's text after it.
|
|
2611
|
+
await transport.emit_notification(
|
|
2612
|
+
"stream.chunk",
|
|
2613
|
+
{
|
|
2614
|
+
"streamId": stream_id,
|
|
2615
|
+
"restart": {
|
|
2616
|
+
"reason": data.get("reason") or "retry",
|
|
2617
|
+
"round": data.get("round"),
|
|
2618
|
+
"attempt": data.get("attempt"),
|
|
2619
|
+
},
|
|
2620
|
+
},
|
|
2621
|
+
)
|
|
2622
|
+
elif kind == "tool_call_start":
|
|
2623
|
+
await transport.emit_notification(
|
|
2624
|
+
"stream.chunk",
|
|
2625
|
+
{
|
|
2626
|
+
"streamId": stream_id,
|
|
2627
|
+
"toolCall": {
|
|
2628
|
+
"id": data["id"],
|
|
2629
|
+
"name": data["name"],
|
|
2630
|
+
"arguments": data.get("arguments") or {},
|
|
2631
|
+
},
|
|
2632
|
+
},
|
|
2633
|
+
)
|
|
2634
|
+
elif kind in ("tool_call_result", "tool_error"):
|
|
2635
|
+
payload: dict[str, Any] = {
|
|
2636
|
+
"id": data["id"],
|
|
2637
|
+
"name": data["name"],
|
|
2638
|
+
"success": data.get("success", False),
|
|
2639
|
+
}
|
|
2640
|
+
if "durationMs" in data:
|
|
2641
|
+
payload["durationMs"] = data["durationMs"]
|
|
2642
|
+
if "error" in data:
|
|
2643
|
+
payload["error"] = data["error"]
|
|
2644
|
+
if "resultPreview" in data:
|
|
2645
|
+
payload["resultPreview"] = data["resultPreview"]
|
|
2646
|
+
if "sandbox" in data:
|
|
2647
|
+
# W4-2: per-exec sandbox marker for the host's tool card.
|
|
2648
|
+
payload["sandbox"] = data["sandbox"]
|
|
2649
|
+
if "approval" in data:
|
|
2650
|
+
payload["approval"] = data["approval"]
|
|
2651
|
+
# Older engines omit the top-level fields when a sibling already
|
|
2652
|
+
# finished before a terminal tool. The preview still carries them.
|
|
2653
|
+
if "sandbox" not in payload or "approval" not in payload:
|
|
2654
|
+
lifted_sandbox, lifted_approval = _markers_from_result_preview(
|
|
2655
|
+
data.get("resultPreview")
|
|
2656
|
+
)
|
|
2657
|
+
if "sandbox" not in payload and lifted_sandbox is not None:
|
|
2658
|
+
payload["sandbox"] = lifted_sandbox
|
|
2659
|
+
if "approval" not in payload and lifted_approval is not None:
|
|
2660
|
+
payload["approval"] = lifted_approval
|
|
2661
|
+
await transport.emit_notification(
|
|
2662
|
+
"stream.chunk", {"streamId": stream_id, "toolResult": payload}
|
|
2663
|
+
)
|
|
2664
|
+
elif kind in ("soft_timeout", "budget_exhausted"):
|
|
2665
|
+
await transport.emit_notification(
|
|
2666
|
+
"stream.chunk",
|
|
2667
|
+
{"streamId": stream_id, "notice": {"kind": kind, **data}},
|
|
2668
|
+
)
|
|
2669
|
+
elif kind == "hook_action":
|
|
2670
|
+
# Hook-driven control flow (compaction / retry / narration /
|
|
2671
|
+
# tool_choice). TraceRecorder already persists it; forward as a
|
|
2672
|
+
# notice so hosts can surface it live too.
|
|
2673
|
+
await transport.emit_notification(
|
|
2674
|
+
"stream.chunk",
|
|
2675
|
+
{"streamId": stream_id, "notice": {"kind": "hook_action", **data}},
|
|
2676
|
+
)
|
|
2677
|
+
elif kind == "steer":
|
|
2678
|
+
# The host already rendered the user's message; this confirms the
|
|
2679
|
+
# loop consumed it into the transcript (vs. still queued).
|
|
2680
|
+
await transport.emit_notification(
|
|
2681
|
+
"stream.chunk",
|
|
2682
|
+
{
|
|
2683
|
+
"streamId": stream_id,
|
|
2684
|
+
"notice": {"kind": "steer", "content": data.get("content", "")},
|
|
2685
|
+
},
|
|
2686
|
+
)
|
|
2687
|
+
elif kind == "error":
|
|
2688
|
+
await transport.emit_notification(
|
|
2689
|
+
"stream.error",
|
|
2690
|
+
{
|
|
2691
|
+
"streamId": stream_id,
|
|
2692
|
+
"kind": "LoopError",
|
|
2693
|
+
"message": data["message"],
|
|
2694
|
+
**({"traceId": trace_id} if trace_id else {}),
|
|
2695
|
+
# The envelope `kind` stays "LoopError" for compatibility;
|
|
2696
|
+
# the engine's own classification travels separately so the
|
|
2697
|
+
# host can pick user-facing copy by category instead of
|
|
2698
|
+
# matching on message text.
|
|
2699
|
+
**(
|
|
2700
|
+
{"errorKind": data.get("kind")}
|
|
2701
|
+
if data.get("kind")
|
|
2702
|
+
else {}
|
|
2703
|
+
),
|
|
2704
|
+
**{
|
|
2705
|
+
field: data[field]
|
|
2706
|
+
for field in ("proxy", "attempts", "statusCode")
|
|
2707
|
+
if data.get(field) is not None
|
|
2708
|
+
},
|
|
2709
|
+
},
|
|
2710
|
+
)
|
|
2711
|
+
elif kind == "completion" and data.get("status") == "executing":
|
|
2712
|
+
# Per-round bookkeeping (think → act → observe). Hosts seal the
|
|
2713
|
+
# live thinking segment here so the next LLM burst starts a new
|
|
2714
|
+
# block instead of concatenating every round into one wall.
|
|
2715
|
+
await transport.emit_notification(
|
|
2716
|
+
"stream.chunk",
|
|
2717
|
+
{
|
|
2718
|
+
"streamId": stream_id,
|
|
2719
|
+
"notice": {
|
|
2720
|
+
"kind": "round_end",
|
|
2721
|
+
"status": "executing",
|
|
2722
|
+
"round": data.get("round"),
|
|
2723
|
+
},
|
|
2724
|
+
},
|
|
2725
|
+
)
|
|
2726
|
+
elif kind == "completion" and data.get("status") != "executing":
|
|
2727
|
+
# W6-9: forward the run's accumulated billable usage, plus a cost
|
|
2728
|
+
# estimate when the model is priced (None → key omitted, never a
|
|
2729
|
+
# fabricated $0.00 for unpriced/local models).
|
|
2730
|
+
#
|
|
2731
|
+
# Wrap-up laundering: when a narration round was granted after the
|
|
2732
|
+
# turn already hit a wall, this round's natural-language summary
|
|
2733
|
+
# makes the loop report `completed` — but the task did not finish.
|
|
2734
|
+
# Reporting the wall keeps the host honest: it surfaces failed
|
|
2735
|
+
# turns to the user and lets auto-continue resume a
|
|
2736
|
+
# `budget_exhausted` pass instead of silently stopping.
|
|
2737
|
+
status = data["status"]
|
|
2738
|
+
reason = data["reason"]
|
|
2739
|
+
wall_status = _hook_wall_status(hooks)
|
|
2740
|
+
if status == "completed" and wall_status is not None:
|
|
2741
|
+
status = wall_status
|
|
2742
|
+
reason = (
|
|
2743
|
+
f"{reason or 'wrapped up'} [wall={wall_status}; "
|
|
2744
|
+
"narration round answered, task not finished]"
|
|
2745
|
+
)
|
|
2746
|
+
done: dict[str, Any] = {
|
|
2747
|
+
"streamId": stream_id,
|
|
2748
|
+
"ok": status == "completed",
|
|
2749
|
+
"status": status,
|
|
2750
|
+
"reason": reason,
|
|
2751
|
+
**({"traceId": trace_id} if trace_id else {}),
|
|
2752
|
+
}
|
|
2753
|
+
if status == "cancelled":
|
|
2754
|
+
# Same terminal signal the hard-cancel path emits, so hosts
|
|
2755
|
+
# handle cooperative and forced cancellation uniformly.
|
|
2756
|
+
done["cancelled"] = True
|
|
2757
|
+
usage = data.get("usage")
|
|
2758
|
+
if isinstance(usage, dict):
|
|
2759
|
+
done["usage"] = usage
|
|
2760
|
+
cost = estimate_cost_usd(
|
|
2761
|
+
model,
|
|
2762
|
+
int(usage.get("promptTokens") or 0),
|
|
2763
|
+
int(usage.get("completionTokens") or 0),
|
|
2764
|
+
)
|
|
2765
|
+
if cost is not None:
|
|
2766
|
+
done["usage"] = {**usage, "costUsd": cost}
|
|
2767
|
+
await transport.emit_notification("stream.done", done)
|
|
2768
|
+
|
|
2769
|
+
# ------------------------------------------------------------------
|
|
2770
|
+
# Plumbing
|
|
2771
|
+
# ------------------------------------------------------------------
|
|
2772
|
+
|
|
2773
|
+
def _emit_ready_marker(self, health: SidecarHealth) -> None:
|
|
2774
|
+
if self.config.quiet_stderr:
|
|
2775
|
+
return
|
|
2776
|
+
payload = json.dumps(
|
|
2777
|
+
health.model_dump(exclude_none=True), separators=(",", ":")
|
|
2778
|
+
)
|
|
2779
|
+
sys.stderr.write(f"{READY_PREFIX}{payload}\n")
|
|
2780
|
+
sys.stderr.flush()
|
|
2781
|
+
|
|
2782
|
+
def _configure_logging(self) -> None:
|
|
2783
|
+
logging.basicConfig(
|
|
2784
|
+
level=self.config.log_level,
|
|
2785
|
+
format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
|
|
2786
|
+
stream=sys.stderr,
|
|
2787
|
+
)
|
|
2788
|
+
|
|
2789
|
+
def _install_signal_handlers(self) -> None:
|
|
2790
|
+
loop = asyncio.get_running_loop()
|
|
2791
|
+
try:
|
|
2792
|
+
import signal
|
|
2793
|
+
|
|
2794
|
+
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
2795
|
+
loop.add_signal_handler(sig, lambda: self._shutdown_requested.set())
|
|
2796
|
+
except (NotImplementedError, RuntimeError):
|
|
2797
|
+
# Windows event-loop policies that lack add_signal_handler.
|
|
2798
|
+
pass
|
|
2799
|
+
|
|
2800
|
+
@staticmethod
|
|
2801
|
+
async def _connect_stdio() -> tuple[asyncio.StreamReader, Any]:
|
|
2802
|
+
if sys.platform == "win32":
|
|
2803
|
+
# ProactorEventLoop 的 connect_read/write_pipe 要求 IOCP 可关联
|
|
2804
|
+
# 句柄;被 Node/Electron spawn 的子进程继承的是普通匿名管道句柄
|
|
2805
|
+
# (控制台句柄亦然),注册即 OSError [WinError 6],且读侧可能在
|
|
2806
|
+
# connect 成功后才在回调里异步崩。SelectorEventLoop 在 Windows 上
|
|
2807
|
+
# 根本不支持管道,因此走线程泵兜底(见 _connect_stdio_threaded)。
|
|
2808
|
+
return _connect_stdio_threaded()
|
|
2809
|
+
loop = asyncio.get_running_loop()
|
|
2810
|
+
reader = asyncio.StreamReader(limit=STDIO_STREAM_LIMIT)
|
|
2811
|
+
protocol = asyncio.StreamReaderProtocol(reader)
|
|
2812
|
+
await loop.connect_read_pipe(lambda: protocol, sys.stdin)
|
|
2813
|
+
transport, _ = await loop.connect_write_pipe(
|
|
2814
|
+
asyncio.streams.FlowControlMixin, sys.stdout
|
|
2815
|
+
)
|
|
2816
|
+
writer = asyncio.StreamWriter(transport, protocol, reader, loop)
|
|
2817
|
+
return reader, writer
|
|
2818
|
+
|
|
2819
|
+
@staticmethod
|
|
2820
|
+
async def _maybe_drain(writer: Any) -> None:
|
|
2821
|
+
drain = getattr(writer, "drain", None)
|
|
2822
|
+
if drain is None:
|
|
2823
|
+
return
|
|
2824
|
+
result = drain()
|
|
2825
|
+
if asyncio.iscoroutine(result):
|
|
2826
|
+
await result
|
|
2827
|
+
|
|
2828
|
+
|
|
2829
|
+
# ---------------------------------------------------------------------------
|
|
2830
|
+
# Helpers
|
|
2831
|
+
# ---------------------------------------------------------------------------
|
|
2832
|
+
|
|
2833
|
+
|
|
2834
|
+
class _ThreadedStdoutWriter:
|
|
2835
|
+
"""Duck-typed stdout writer for the Windows stdio fallback.
|
|
2836
|
+
|
|
2837
|
+
Matches the surface the JSON-RPC server/transport actually use:
|
|
2838
|
+
synchronous ``write(bytes)`` plus optional ``drain()`` / ``close()`` /
|
|
2839
|
+
``is_closing()``. A lock keeps frames ordered when the event loop and a
|
|
2840
|
+
reverse-call path write concurrently; every frame is flushed immediately
|
|
2841
|
+
(line-delimited JSON-RPC). A blocking write backpressures the event loop
|
|
2842
|
+
directly — acceptable here because the host always drains stdout.
|
|
2843
|
+
"""
|
|
2844
|
+
|
|
2845
|
+
def __init__(self) -> None:
|
|
2846
|
+
self._lock = threading.Lock()
|
|
2847
|
+
self._closing = False
|
|
2848
|
+
|
|
2849
|
+
def write(self, data: bytes) -> int:
|
|
2850
|
+
with self._lock:
|
|
2851
|
+
if self._closing:
|
|
2852
|
+
raise RuntimeError("stdio writer is closed")
|
|
2853
|
+
out = sys.stdout.buffer
|
|
2854
|
+
written = out.write(data)
|
|
2855
|
+
out.flush()
|
|
2856
|
+
return written if written is not None else len(data)
|
|
2857
|
+
|
|
2858
|
+
async def drain(self) -> None:
|
|
2859
|
+
return None
|
|
2860
|
+
|
|
2861
|
+
def close(self) -> None:
|
|
2862
|
+
with self._lock:
|
|
2863
|
+
self._closing = True
|
|
2864
|
+
try:
|
|
2865
|
+
sys.stdout.buffer.flush()
|
|
2866
|
+
except Exception:
|
|
2867
|
+
pass
|
|
2868
|
+
|
|
2869
|
+
def is_closing(self) -> bool:
|
|
2870
|
+
return self._closing
|
|
2871
|
+
|
|
2872
|
+
|
|
2873
|
+
def _connect_stdio_threaded() -> tuple[asyncio.StreamReader, Any]:
|
|
2874
|
+
"""Windows stdio transport: blocking stdin reader thread + sync writer.
|
|
2875
|
+
|
|
2876
|
+
A daemon thread runs blocking ``readline()`` on stdin and feeds a
|
|
2877
|
+
``StreamReader`` via ``call_soon_threadsafe``; EOF (parent closed the
|
|
2878
|
+
pipe) surfaces as ``feed_eof`` so the serve loop shuts down normally.
|
|
2879
|
+
No flow control on the read side — the host sends one request frame at a
|
|
2880
|
+
time, so the buffer cannot grow unboundedly in practice.
|
|
2881
|
+
"""
|
|
2882
|
+
loop = asyncio.get_running_loop()
|
|
2883
|
+
reader: asyncio.StreamReader = asyncio.StreamReader(limit=STDIO_STREAM_LIMIT)
|
|
2884
|
+
|
|
2885
|
+
def _pump_stdin() -> None:
|
|
2886
|
+
# 用裸 fd 读而非 sys.stdin.buffer:解释器退出时会关闭带锁的
|
|
2887
|
+
# BufferedReader,守护线程若正阻塞在它的锁上,finalization 会抛
|
|
2888
|
+
# "_enter_buffered_busy" fatal error。os.read 不持有该锁;fd 被
|
|
2889
|
+
# 关闭后 read 返回错误,按 EOF 处理即可。StreamReader 自行重组行。
|
|
2890
|
+
try:
|
|
2891
|
+
while True:
|
|
2892
|
+
chunk = os.read(0, 65536)
|
|
2893
|
+
if not chunk:
|
|
2894
|
+
loop.call_soon_threadsafe(reader.feed_eof)
|
|
2895
|
+
return
|
|
2896
|
+
loop.call_soon_threadsafe(reader.feed_data, chunk)
|
|
2897
|
+
except Exception:
|
|
2898
|
+
# stdin broken/closed: surface as EOF so the serve loop exits.
|
|
2899
|
+
try:
|
|
2900
|
+
loop.call_soon_threadsafe(reader.feed_eof)
|
|
2901
|
+
except RuntimeError:
|
|
2902
|
+
pass # event loop already closed
|
|
2903
|
+
|
|
2904
|
+
threading.Thread(
|
|
2905
|
+
target=_pump_stdin, name="sidecar-stdin-pump", daemon=True
|
|
2906
|
+
).start()
|
|
2907
|
+
return reader, _ThreadedStdoutWriter()
|
|
2908
|
+
|
|
2909
|
+
|
|
2910
|
+
def _markers_from_result_preview(preview: Any) -> tuple[dict[str, Any] | None, dict[str, Any] | None]:
|
|
2911
|
+
"""Sandbox and approval objects embedded in a tool-result preview.
|
|
2912
|
+
|
|
2913
|
+
The loop event usually lifts these itself. When it does not, they remain
|
|
2914
|
+
under ``data._sandbox`` and ``data._approval`` in the preview JSON. A
|
|
2915
|
+
published loop also cuts that preview at 300 characters, so a marker
|
|
2916
|
+
past the cut is gone; one that still fits is read without parsing the
|
|
2917
|
+
rest of the truncated JSON.
|
|
2918
|
+
"""
|
|
2919
|
+
if not isinstance(preview, str) or not preview.startswith("{"):
|
|
2920
|
+
return None, None
|
|
2921
|
+
try:
|
|
2922
|
+
parsed = json.loads(preview)
|
|
2923
|
+
except json.JSONDecodeError:
|
|
2924
|
+
return (
|
|
2925
|
+
_object_after_key(preview, "_sandbox"),
|
|
2926
|
+
_object_after_key(preview, "_approval"),
|
|
2927
|
+
)
|
|
2928
|
+
if not isinstance(parsed, dict):
|
|
2929
|
+
return None, None
|
|
2930
|
+
body = parsed.get("data")
|
|
2931
|
+
if not isinstance(body, dict):
|
|
2932
|
+
return None, None
|
|
2933
|
+
sandbox = body.get("_sandbox")
|
|
2934
|
+
approval = body.get("_approval")
|
|
2935
|
+
return (
|
|
2936
|
+
sandbox if isinstance(sandbox, dict) else None,
|
|
2937
|
+
approval if isinstance(approval, dict) else None,
|
|
2938
|
+
)
|
|
2939
|
+
|
|
2940
|
+
|
|
2941
|
+
def _object_after_key(text: str, key: str) -> dict[str, Any] | None:
|
|
2942
|
+
needle = f'"{key}"'
|
|
2943
|
+
decoder = json.JSONDecoder()
|
|
2944
|
+
start = 0
|
|
2945
|
+
while True:
|
|
2946
|
+
found = text.find(needle, start)
|
|
2947
|
+
if found < 0:
|
|
2948
|
+
return None
|
|
2949
|
+
colon = text.find(":", found + len(needle))
|
|
2950
|
+
if colon < 0:
|
|
2951
|
+
return None
|
|
2952
|
+
index = colon + 1
|
|
2953
|
+
while index < len(text) and text[index] in " \t\r\n":
|
|
2954
|
+
index += 1
|
|
2955
|
+
try:
|
|
2956
|
+
value, _end = decoder.raw_decode(text, index)
|
|
2957
|
+
except json.JSONDecodeError:
|
|
2958
|
+
start = found + len(needle)
|
|
2959
|
+
continue
|
|
2960
|
+
if isinstance(value, dict):
|
|
2961
|
+
return value
|
|
2962
|
+
start = found + len(needle)
|
|
2963
|
+
|
|
2964
|
+
|
|
2965
|
+
def _approval_prompt_chat_id(params: dict[str, Any]) -> str | None:
|
|
2966
|
+
"""Chat the approval card belongs to.
|
|
2967
|
+
|
|
2968
|
+
A background task streams under ``task:<id>`` while the user stays in
|
|
2969
|
+
the parent conversation (``toolContext.chatId``). Otherwise the stream
|
|
2970
|
+
``chatId`` is that conversation.
|
|
2971
|
+
"""
|
|
2972
|
+
tool_context = params.get("toolContext")
|
|
2973
|
+
if isinstance(tool_context, dict):
|
|
2974
|
+
raw = tool_context.get("chatId")
|
|
2975
|
+
if isinstance(raw, str) and raw:
|
|
2976
|
+
return raw
|
|
2977
|
+
raw = params.get("chatId")
|
|
2978
|
+
if isinstance(raw, str) and raw:
|
|
2979
|
+
return raw
|
|
2980
|
+
return None
|
|
2981
|
+
|
|
2982
|
+
|
|
2983
|
+
def _require_params(params: Any) -> dict[str, Any]:
|
|
2984
|
+
if not isinstance(params, dict):
|
|
2985
|
+
raise JsonRpcError(
|
|
2986
|
+
"params must be an object", code=-32602, kind="invalid_params"
|
|
2987
|
+
)
|
|
2988
|
+
return params
|
|
2989
|
+
|
|
2990
|
+
|
|
2991
|
+
def _iso_now() -> str:
|
|
2992
|
+
from datetime import datetime, timezone
|
|
2993
|
+
|
|
2994
|
+
return datetime.now(timezone.utc).isoformat()
|
|
2995
|
+
|
|
2996
|
+
|
|
2997
|
+
def _new_session_id() -> str:
|
|
2998
|
+
return f"sess_{uuid.uuid4().hex}"
|
|
2999
|
+
|
|
3000
|
+
|
|
3001
|
+
def _new_call_id() -> str:
|
|
3002
|
+
return f"call_{uuid.uuid4().hex}"
|
|
3003
|
+
|
|
3004
|
+
|
|
3005
|
+
def _new_stream_id() -> str:
|
|
3006
|
+
return f"str_{uuid.uuid4().hex}"
|
|
3007
|
+
|
|
3008
|
+
|
|
3009
|
+
def _coerce_part(item: Any) -> ContentPart:
|
|
3010
|
+
"""Coerce one wire ``ContentPart`` (spec/chat/ContentPart.schema.json).
|
|
3011
|
+
|
|
3012
|
+
The wire part is authoritative when ``parts`` is present on a
|
|
3013
|
+
ChatMessage; ``content`` is then just its text projection.
|
|
3014
|
+
"""
|
|
3015
|
+
if not isinstance(item, dict):
|
|
3016
|
+
raise JsonRpcError(
|
|
3017
|
+
"each part must be an object", code=-32602, kind="invalid_params"
|
|
3018
|
+
)
|
|
3019
|
+
kind = item.get("type")
|
|
3020
|
+
if kind == "text":
|
|
3021
|
+
return TextPart(str(item.get("text") or ""))
|
|
3022
|
+
if kind == "image":
|
|
3023
|
+
url = item.get("url")
|
|
3024
|
+
if url:
|
|
3025
|
+
return ImagePart.from_url(
|
|
3026
|
+
str(url), media_type=str(item.get("mediaType") or "image/png")
|
|
3027
|
+
)
|
|
3028
|
+
data = item.get("data")
|
|
3029
|
+
if data:
|
|
3030
|
+
return ImagePart.from_base64(
|
|
3031
|
+
str(data), media_type=str(item.get("mediaType") or "image/png")
|
|
3032
|
+
)
|
|
3033
|
+
raise JsonRpcError(
|
|
3034
|
+
"image part needs url or data", code=-32602, kind="invalid_params"
|
|
3035
|
+
)
|
|
3036
|
+
raise JsonRpcError(
|
|
3037
|
+
f"invalid part type: {kind!r}", code=-32602, kind="invalid_params"
|
|
3038
|
+
)
|
|
3039
|
+
|
|
3040
|
+
|
|
3041
|
+
def _coerce_messages(items: Any) -> list[LLMMessage]:
|
|
3042
|
+
if not isinstance(items, list):
|
|
3043
|
+
raise JsonRpcError(
|
|
3044
|
+
"messages must be a list", code=-32602, kind="invalid_params"
|
|
3045
|
+
)
|
|
3046
|
+
out: list[LLMMessage] = []
|
|
3047
|
+
for entry in items:
|
|
3048
|
+
if not isinstance(entry, dict):
|
|
3049
|
+
raise JsonRpcError(
|
|
3050
|
+
"each message must be an object", code=-32602, kind="invalid_params"
|
|
3051
|
+
)
|
|
3052
|
+
role = entry.get("role")
|
|
3053
|
+
if role not in {"system", "user", "assistant", "tool"}:
|
|
3054
|
+
raise JsonRpcError(
|
|
3055
|
+
f"invalid role: {role!r}", code=-32602, kind="invalid_params"
|
|
3056
|
+
)
|
|
3057
|
+
# Assistant 轮的工具调用/推理回传:host 历史里的 assistant 消息必须
|
|
3058
|
+
# 把 toolCalls 一起带回来,否则下一轮 role:'tool' 被 OpenAI 严格协
|
|
3059
|
+
# 议判为孤儿(400);thinking 模型(DeepSeek)还要求 reasoning 回传
|
|
3060
|
+
# (字段名由 provider compat 的 reasoningEchoField 决定)。
|
|
3061
|
+
tool_calls = _coerce_tool_calls(entry.get("toolCalls"))
|
|
3062
|
+
reasoning = entry.get("reasoning")
|
|
3063
|
+
if reasoning is None:
|
|
3064
|
+
reasoning = entry.get("reasoningContent")
|
|
3065
|
+
if reasoning is not None and not isinstance(reasoning, str):
|
|
3066
|
+
raise JsonRpcError(
|
|
3067
|
+
"reasoning must be a string", code=-32602, kind="invalid_params"
|
|
3068
|
+
)
|
|
3069
|
+
reasoning_details = entry.get("reasoningDetails")
|
|
3070
|
+
if reasoning_details is not None and not isinstance(reasoning_details, list):
|
|
3071
|
+
raise JsonRpcError(
|
|
3072
|
+
"reasoningDetails must be a list", code=-32602, kind="invalid_params"
|
|
3073
|
+
)
|
|
3074
|
+
wire_parts = entry.get("parts")
|
|
3075
|
+
if wire_parts is not None:
|
|
3076
|
+
if not isinstance(wire_parts, list):
|
|
3077
|
+
raise JsonRpcError(
|
|
3078
|
+
"parts must be a list", code=-32602, kind="invalid_params"
|
|
3079
|
+
)
|
|
3080
|
+
out.append(
|
|
3081
|
+
LLMMessage(
|
|
3082
|
+
role=role, # type: ignore[arg-type]
|
|
3083
|
+
content=[_coerce_part(p) for p in wire_parts],
|
|
3084
|
+
name=entry.get("name"),
|
|
3085
|
+
tool_call_id=entry.get("toolCallId"),
|
|
3086
|
+
tool_calls=tool_calls,
|
|
3087
|
+
reasoning=reasoning,
|
|
3088
|
+
reasoning_details=reasoning_details,
|
|
3089
|
+
)
|
|
3090
|
+
)
|
|
3091
|
+
continue
|
|
3092
|
+
out.append(
|
|
3093
|
+
LLMMessage.text_of(
|
|
3094
|
+
role, # type: ignore[arg-type]
|
|
3095
|
+
str(entry.get("content", "")),
|
|
3096
|
+
name=entry.get("name"),
|
|
3097
|
+
tool_call_id=entry.get("toolCallId"),
|
|
3098
|
+
tool_calls=tool_calls,
|
|
3099
|
+
reasoning=reasoning,
|
|
3100
|
+
reasoning_details=reasoning_details,
|
|
3101
|
+
)
|
|
3102
|
+
)
|
|
3103
|
+
return out
|
|
3104
|
+
|
|
3105
|
+
|
|
3106
|
+
def _coerce_tool_calls(items: Any) -> list[ToolCall] | None:
|
|
3107
|
+
"""Validate the host-echoed assistant ``toolCalls`` array."""
|
|
3108
|
+
if items is None:
|
|
3109
|
+
return None
|
|
3110
|
+
if not isinstance(items, list):
|
|
3111
|
+
raise JsonRpcError(
|
|
3112
|
+
"toolCalls must be a list", code=-32602, kind="invalid_params"
|
|
3113
|
+
)
|
|
3114
|
+
out: list[ToolCall] = []
|
|
3115
|
+
for item in items:
|
|
3116
|
+
if not isinstance(item, dict):
|
|
3117
|
+
raise JsonRpcError(
|
|
3118
|
+
"each toolCalls entry must be an object",
|
|
3119
|
+
code=-32602,
|
|
3120
|
+
kind="invalid_params",
|
|
3121
|
+
)
|
|
3122
|
+
arguments = item.get("arguments")
|
|
3123
|
+
if not isinstance(arguments, dict):
|
|
3124
|
+
arguments = {}
|
|
3125
|
+
out.append(
|
|
3126
|
+
ToolCall(
|
|
3127
|
+
id=str(item.get("id") or ""),
|
|
3128
|
+
name=str(item.get("name") or ""),
|
|
3129
|
+
arguments=arguments,
|
|
3130
|
+
)
|
|
3131
|
+
)
|
|
3132
|
+
return out or None
|
|
3133
|
+
|
|
3134
|
+
|
|
3135
|
+
def _model_tool(tool: Any) -> Any:
|
|
3136
|
+
"""Drop approval metadata before the provider sees the tool list.
|
|
3137
|
+
|
|
3138
|
+
``mode`` and ``approvalCategory`` are host-to-sidecar fields. Provider
|
|
3139
|
+
APIs reject unknown tool keys.
|
|
3140
|
+
"""
|
|
3141
|
+
if not isinstance(tool, dict):
|
|
3142
|
+
return tool
|
|
3143
|
+
cleaned = {
|
|
3144
|
+
key: value
|
|
3145
|
+
for key, value in tool.items()
|
|
3146
|
+
if key not in ("mode", "approvalCategory")
|
|
3147
|
+
}
|
|
3148
|
+
function = cleaned.get("function")
|
|
3149
|
+
if isinstance(function, dict):
|
|
3150
|
+
cleaned["function"] = {
|
|
3151
|
+
key: value
|
|
3152
|
+
for key, value in function.items()
|
|
3153
|
+
if key not in ("mode", "approvalCategory")
|
|
3154
|
+
}
|
|
3155
|
+
return cleaned
|
|
3156
|
+
|
|
3157
|
+
|
|
3158
|
+
def _build_provider_kwargs(params: dict[str, Any]) -> dict[str, Any]:
|
|
3159
|
+
kwargs: dict[str, Any] = {}
|
|
3160
|
+
if (tools := params.get("tools")) is not None:
|
|
3161
|
+
kwargs["tools"] = (
|
|
3162
|
+
[_model_tool(tool) for tool in tools] if isinstance(tools, list) else tools
|
|
3163
|
+
)
|
|
3164
|
+
if (temp := params.get("temperature")) is not None:
|
|
3165
|
+
kwargs["temperature"] = float(temp)
|
|
3166
|
+
if (max_tokens := params.get("maxTokens")) is not None:
|
|
3167
|
+
kwargs["max_tokens"] = int(max_tokens)
|
|
3168
|
+
extra = params.get("providerOptions") or {}
|
|
3169
|
+
if isinstance(extra, dict):
|
|
3170
|
+
kwargs.update(extra)
|
|
3171
|
+
return kwargs
|
|
3172
|
+
|
|
3173
|
+
|
|
3174
|
+
def _use_coreloop(params: dict[str, Any]) -> bool:
|
|
3175
|
+
"""Flag resolution for the CoreLoop chat path: per-request
|
|
3176
|
+
``useCoreLoop`` wins; otherwise the ``STEERABLE_SIDECAR_CORELOOP`` env
|
|
3177
|
+
var; default off (legacy direct-stream path)."""
|
|
3178
|
+
|
|
3179
|
+
flag = params.get("useCoreLoop")
|
|
3180
|
+
if flag is not None:
|
|
3181
|
+
return bool(flag)
|
|
3182
|
+
return os.environ.get("STEERABLE_SIDECAR_CORELOOP", "").strip().lower() in {
|
|
3183
|
+
"1",
|
|
3184
|
+
"true",
|
|
3185
|
+
"yes",
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
|
|
3189
|
+
def _last_message_content(
|
|
3190
|
+
messages: list[LLMMessage], role: str, *, tail: int | None = None
|
|
3191
|
+
) -> str:
|
|
3192
|
+
"""Content of the last message with ``role`` (for anti-hallucination
|
|
3193
|
+
routing/judging context). ``tail`` truncates to the trailing N chars."""
|
|
3194
|
+
|
|
3195
|
+
for message in reversed(messages):
|
|
3196
|
+
if message.role == role and message.content_text:
|
|
3197
|
+
content = message.content_text
|
|
3198
|
+
return content[-tail:] if tail else content
|
|
3199
|
+
return ""
|
|
3200
|
+
|
|
3201
|
+
|
|
3202
|
+
def _hook_wall_status(hooks: Any | None) -> str | None:
|
|
3203
|
+
"""Pre-wrap-up terminal status a ``before_completion`` hook swallowed.
|
|
3204
|
+
|
|
3205
|
+
Optional capability, probed with ``getattr`` so any hooks assembly —
|
|
3206
|
+
a bare ``NoopHooks``, a product chain, an embedder factory — answers
|
|
3207
|
+
None without implementing it. See ``LoopHooks.wall_status``.
|
|
3208
|
+
"""
|
|
3209
|
+
|
|
3210
|
+
probe = getattr(hooks, "wall_status", None)
|
|
3211
|
+
if not callable(probe):
|
|
3212
|
+
return None
|
|
3213
|
+
try:
|
|
3214
|
+
status = probe()
|
|
3215
|
+
except Exception: # noqa: BLE001 — reporting must never break the stream
|
|
3216
|
+
logger.exception("hook_wall_status_failed")
|
|
3217
|
+
return None
|
|
3218
|
+
return status if isinstance(status, str) and status else None
|
|
3219
|
+
|
|
3220
|
+
|
|
3221
|
+
#: ``trace.fetch`` event cap. ~50k events ≈ 12 MB of JSON — comfortably inside
|
|
3222
|
+
#: the host's fetch deadline and MySQL's default ``max_allowed_packet`` (64 MB),
|
|
3223
|
+
#: while still covering all but the longest runs whole. Override per call with
|
|
3224
|
+
#: ``maxEvents`` or globally with ``STEERABLE_TRACE_FETCH_MAX_EVENTS`` (``0``
|
|
3225
|
+
#: disables the cap and restores the old unbounded fetch).
|
|
3226
|
+
_DEFAULT_TRACE_FETCH_MAX_EVENTS = 50_000
|
|
3227
|
+
|
|
3228
|
+
|
|
3229
|
+
def _trace_fetch_max_events(params: dict[str, Any]) -> int | None:
|
|
3230
|
+
"""Resolve the ``trace.fetch`` event cap; None means unbounded."""
|
|
3231
|
+
|
|
3232
|
+
raw: Any = params.get("maxEvents")
|
|
3233
|
+
if raw is None:
|
|
3234
|
+
raw = os.environ.get("STEERABLE_TRACE_FETCH_MAX_EVENTS")
|
|
3235
|
+
if raw is None:
|
|
3236
|
+
return _DEFAULT_TRACE_FETCH_MAX_EVENTS
|
|
3237
|
+
try:
|
|
3238
|
+
value = int(raw)
|
|
3239
|
+
except (TypeError, ValueError):
|
|
3240
|
+
return _DEFAULT_TRACE_FETCH_MAX_EVENTS
|
|
3241
|
+
return None if value <= 0 else value
|
|
3242
|
+
|
|
3243
|
+
|
|
3244
|
+
def _summarizer_for(provider: Any) -> Any | None:
|
|
3245
|
+
"""Wire the turn's provider as the compaction summarizer.
|
|
3246
|
+
|
|
3247
|
+
The desktop rolling summary made a genuine model call; the deterministic
|
|
3248
|
+
excerpt fallback would be a quality regression now that the framework is
|
|
3249
|
+
the sole owner of cross-turn compaction. Reusing the turn provider for the
|
|
3250
|
+
one-off ``complete`` mirrors how AntiHallucinationHooks already reuses it
|
|
3251
|
+
for the grounding judge. Opt out with ``STEERABLE_SIDECAR_SUMMARIZER=0``
|
|
3252
|
+
(cost-sensitive deployments keep the deterministic excerpts).
|
|
3253
|
+
"""
|
|
3254
|
+
flag = os.environ.get("STEERABLE_SIDECAR_SUMMARIZER", "1").strip().lower()
|
|
3255
|
+
if flag in {"0", "false", "no", "off"}:
|
|
3256
|
+
return None
|
|
3257
|
+
return provider
|
|
3258
|
+
|
|
3259
|
+
|
|
3260
|
+
def _assemble_default_harness(
|
|
3261
|
+
params: dict[str, Any], summarizer: Any | None = None
|
|
3262
|
+
) -> Any:
|
|
3263
|
+
"""Assemble the bundled ``default.harness.yaml`` into the loop's seams
|
|
3264
|
+
(W1.2.4: the declarative spec is the single source of truth for the
|
|
3265
|
+
default harness — this function only resolves the sidecar's runtime
|
|
3266
|
+
parameters and deployment env knobs).
|
|
3267
|
+
|
|
3268
|
+
Returns the full ``AssembledHarness``: callers take ``.hooks`` for the
|
|
3269
|
+
hook chain and drive the tools dimension against their tool surface —
|
|
3270
|
+
``wire_tools(router)`` where an in-process router exists (headless,
|
|
3271
|
+
ACP), ``select_tools`` everywhere. Router-backed tools strategies
|
|
3272
|
+
(progressive) raise on selection without wiring, so a path with no
|
|
3273
|
+
router must not select them.
|
|
3274
|
+
"""
|
|
3275
|
+
from dataclasses import replace
|
|
3276
|
+
|
|
3277
|
+
from steerable_agent_runtime.harness_spec import assemble_harness
|
|
3278
|
+
from steerable_agent_runtime.tokens import resolve_context_window
|
|
3279
|
+
|
|
3280
|
+
# Explicit maxContextTokens wins; otherwise the model's known context
|
|
3281
|
+
# window (a fixed 60k against a 131k model compacted far earlier than the
|
|
3282
|
+
# provider required — the dogfood 22-compacts/5-traces pathology).
|
|
3283
|
+
max_ctx = resolve_context_window(
|
|
3284
|
+
params.get("model"),
|
|
3285
|
+
explicit=int(params.get("maxContextTokens") or 0) or None,
|
|
3286
|
+
provider=params.get("provider"),
|
|
3287
|
+
base_url=params.get("baseUrl"),
|
|
3288
|
+
)
|
|
3289
|
+
spec = _default_harness_spec()
|
|
3290
|
+
# STEERABLE_SIDECAR_SPILL=0 is deployment policy, not harness strategy:
|
|
3291
|
+
# it drops the spill dimension before assembly rather than wrapping hooks.
|
|
3292
|
+
flag = os.environ.get("STEERABLE_SIDECAR_SPILL", "1").strip().lower()
|
|
3293
|
+
if flag in {"0", "false", "no", "off"}:
|
|
3294
|
+
spec = replace(spec, context=[c for c in spec.context if c.impl != "spill"])
|
|
3295
|
+
# STEERABLE_RETRY_* is the same kind of knob: the desktop cadence
|
|
3296
|
+
# (3×200ms) dies instantly on Harbor's OpenRouter 429s, so eval jobs
|
|
3297
|
+
# retune the spec's simple retry without editing the bundled YAML.
|
|
3298
|
+
retry_params = _retry_params_from_env()
|
|
3299
|
+
if retry_params:
|
|
3300
|
+
spec = replace(
|
|
3301
|
+
spec,
|
|
3302
|
+
retry=[
|
|
3303
|
+
replace(c, params={**c.params, **retry_params})
|
|
3304
|
+
if c.impl == "simple"
|
|
3305
|
+
else c
|
|
3306
|
+
for c in spec.retry
|
|
3307
|
+
],
|
|
3308
|
+
)
|
|
3309
|
+
model = params.get("model")
|
|
3310
|
+
# P3: the knob set is resolved explicitly per model/window — no hidden
|
|
3311
|
+
# if/else at the assembly site. (Desktop 60k–131k keeps 2 tool results;
|
|
3312
|
+
# GLM 1M Harbor traces need 16 or compile/train tails fold away.)
|
|
3313
|
+
policy = resolve_compaction_policy(model=model, max_context_tokens=max_ctx)
|
|
3314
|
+
# Spill budgets branch on the same window size class as the compaction
|
|
3315
|
+
# policy; the threshold lives in compaction_policy, not here.
|
|
3316
|
+
large = is_large_window(max_ctx)
|
|
3317
|
+
return assemble_harness(
|
|
3318
|
+
spec,
|
|
3319
|
+
provider=summarizer,
|
|
3320
|
+
runtime_params={
|
|
3321
|
+
"pressure_compaction": {
|
|
3322
|
+
"max_context_tokens": max_ctx,
|
|
3323
|
+
"model": model,
|
|
3324
|
+
**policy.as_params(),
|
|
3325
|
+
},
|
|
3326
|
+
"informed_backtrack": {"max_context_tokens": max_ctx, "model": model},
|
|
3327
|
+
# Desktop 16k inline. GLM 1M Harbor keeps full 100k bash clips
|
|
3328
|
+
# until compaction; 2k previews hid compile/train endings.
|
|
3329
|
+
"spill": {
|
|
3330
|
+
"directory": _spill_directory(),
|
|
3331
|
+
"max_inline_bytes": 100_000 if large else 16_000,
|
|
3332
|
+
"preview_bytes": 8_000 if large else 2_000,
|
|
3333
|
+
},
|
|
3334
|
+
},
|
|
3335
|
+
)
|
|
3336
|
+
|
|
3337
|
+
|
|
3338
|
+
def _default_loop_hooks(
|
|
3339
|
+
params: dict[str, Any], summarizer: Any | None = None
|
|
3340
|
+
) -> LoopHooks:
|
|
3341
|
+
"""The default harness's hook chain (assembly: `_assemble_default_harness`).
|
|
3342
|
+
|
|
3343
|
+
Slice order is the spec's: pressure compaction's ``pre_step`` first,
|
|
3344
|
+
spill's ``post_tool_result``, then overflow backtrack ahead of
|
|
3345
|
+
taxonomy-routed backoff on ``on_request_error``.
|
|
3346
|
+
"""
|
|
3347
|
+
return _assemble_default_harness(params, summarizer).hooks
|
|
3348
|
+
|
|
3349
|
+
|
|
3350
|
+
def _retry_params_from_env() -> dict[str, int]:
|
|
3351
|
+
"""STEERABLE_RETRY_* deployment overrides for the spec's simple retry.
|
|
3352
|
+
|
|
3353
|
+
Desktop default is 3×200ms. Harbor OpenRouter 429s need minutes.
|
|
3354
|
+
|
|
3355
|
+
The ``TRANSPORT_`` prefixed names configure the connection-failure policy
|
|
3356
|
+
(5 attempts, 1s base, 8s cap, 60s deadline) separately from the shared
|
|
3357
|
+
one, because a proxy or a flaky link needs waits an API error does not.
|
|
3358
|
+
"""
|
|
3359
|
+
params: dict[str, int] = {}
|
|
3360
|
+
for env_name, param in (
|
|
3361
|
+
("STEERABLE_RETRY_MAX_ATTEMPTS", "max_attempts"),
|
|
3362
|
+
("STEERABLE_RETRY_BASE_DELAY_MS", "base_delay_ms"),
|
|
3363
|
+
("STEERABLE_RETRY_MAX_DELAY_MS", "max_delay_ms"),
|
|
3364
|
+
("STEERABLE_RETRY_TRANSPORT_ATTEMPTS", "transport_max_attempts"),
|
|
3365
|
+
("STEERABLE_RETRY_TRANSPORT_BASE_DELAY_MS", "transport_base_delay_ms"),
|
|
3366
|
+
("STEERABLE_RETRY_TRANSPORT_MAX_DELAY_MS", "transport_max_delay_ms"),
|
|
3367
|
+
("STEERABLE_RETRY_TRANSPORT_DEADLINE_MS", "transport_deadline_ms"),
|
|
3368
|
+
):
|
|
3369
|
+
raw = os.environ.get(env_name, "").strip()
|
|
3370
|
+
if not raw:
|
|
3371
|
+
continue
|
|
3372
|
+
try:
|
|
3373
|
+
value = int(raw)
|
|
3374
|
+
except ValueError:
|
|
3375
|
+
continue
|
|
3376
|
+
if value > 0:
|
|
3377
|
+
params[param] = value
|
|
3378
|
+
return params
|
|
3379
|
+
|
|
3380
|
+
|
|
3381
|
+
@lru_cache(maxsize=1)
|
|
3382
|
+
def _default_harness_spec():
|
|
3383
|
+
"""Load the bundled default spec once per process (every chat turn reads
|
|
3384
|
+
it for loop limits and tool selection; the parse is not free).
|
|
3385
|
+
|
|
3386
|
+
The cache lives on this function, not on a per-call inner closure — a
|
|
3387
|
+
closure redefined each call carries a fresh empty cache and re-parses.
|
|
3388
|
+
"""
|
|
3389
|
+
from steerable_agent_runtime.harness_spec import load_harness_spec
|
|
3390
|
+
|
|
3391
|
+
return load_harness_spec(_DEFAULT_HARNESS_SPEC_PATH)
|
|
3392
|
+
|
|
3393
|
+
|
|
3394
|
+
def _spill_directory() -> str:
|
|
3395
|
+
"""Stable per-host spill dir (findable across a session), overridable
|
|
3396
|
+
with STEERABLE_SPILL_DIR."""
|
|
3397
|
+
import tempfile
|
|
3398
|
+
|
|
3399
|
+
override = os.environ.get("STEERABLE_SPILL_DIR")
|
|
3400
|
+
if override:
|
|
3401
|
+
return override
|
|
3402
|
+
try:
|
|
3403
|
+
base = tempfile.gettempdir()
|
|
3404
|
+
except FileNotFoundError:
|
|
3405
|
+
# 受限沙箱(如 Windows restricted-token 只放行声明过的 writable
|
|
3406
|
+
# root)下系统临时目录不可写,gettempdir() 探测失败。回落到
|
|
3407
|
+
# ~/.steerable——宿主沙箱策略始终放行的根。
|
|
3408
|
+
base = os.path.join(Path.home(), ".steerable")
|
|
3409
|
+
return os.path.join(base, "steerable-spill")
|
|
3410
|
+
|
|
3411
|
+
|
|
3412
|
+
def _build_loop_config(params: dict[str, Any]) -> LoopConfig:
|
|
3413
|
+
# Loop-limit precedence (W3.4.2.4): explicit request param > the bundled
|
|
3414
|
+
# default spec's `loop:` section > the baseline. `resolve_loop_limits` is
|
|
3415
|
+
# that one rule, shared with headless and ACP.
|
|
3416
|
+
resolved = resolve_loop_limits(
|
|
3417
|
+
_default_harness_spec().loop,
|
|
3418
|
+
max_rounds=(
|
|
3419
|
+
int(params["maxRounds"]) if params.get("maxRounds") is not None else None
|
|
3420
|
+
),
|
|
3421
|
+
max_tool_errors=(
|
|
3422
|
+
int(params["maxToolErrors"])
|
|
3423
|
+
if params.get("maxToolErrors") is not None
|
|
3424
|
+
else None
|
|
3425
|
+
),
|
|
3426
|
+
)
|
|
3427
|
+
max_rounds = resolved.max_rounds
|
|
3428
|
+
max_tool_errors = resolved.max_tool_errors
|
|
3429
|
+
budget = None
|
|
3430
|
+
if (budget_tokens := params.get("budgetTokens")) is not None:
|
|
3431
|
+
budget = BudgetLimit(
|
|
3432
|
+
max_tokens=int(budget_tokens),
|
|
3433
|
+
max_steps=max_rounds,
|
|
3434
|
+
max_tool_calls=int(params.get("budgetMaxToolCalls", 10_000)),
|
|
3435
|
+
)
|
|
3436
|
+
else:
|
|
3437
|
+
# Only the token axis of BudgetLimit is consumed by the loop
|
|
3438
|
+
# (steps/tool_calls stay inert). The token axis is cumulative over
|
|
3439
|
+
# the run while a context window is
|
|
3440
|
+
# a per-request size, so a flat multiple of the window caps the round
|
|
3441
|
+
# count instead of the spend: an agentic turn re-sends its prompt
|
|
3442
|
+
# every round, and even a fully cache-hit window still bills
|
|
3443
|
+
# ``cached_token_weight × window``. Scaling with an explicit round
|
|
3444
|
+
# cap keeps that cap primary and leaves the token axis a backstop.
|
|
3445
|
+
# The default cap is unlimited — a derived token budget would just
|
|
3446
|
+
# re-introduce the wall — so an uncapped run has no token budget
|
|
3447
|
+
# unless the caller passed ``budgetTokens``.
|
|
3448
|
+
from steerable_agent_runtime.tokens import resolve_context_window
|
|
3449
|
+
|
|
3450
|
+
if max_rounds >= UNLIMITED_LOOP_LIMIT:
|
|
3451
|
+
budget = None
|
|
3452
|
+
else:
|
|
3453
|
+
window = resolve_context_window(
|
|
3454
|
+
params.get("model"),
|
|
3455
|
+
explicit=int(params.get("maxContextTokens") or 0) or None,
|
|
3456
|
+
provider=params.get("provider"),
|
|
3457
|
+
base_url=params.get("baseUrl"),
|
|
3458
|
+
)
|
|
3459
|
+
budget = BudgetLimit(
|
|
3460
|
+
max_tokens=max(
|
|
3461
|
+
2 * window,
|
|
3462
|
+
math.floor(max_rounds * window * DEFAULT_CACHED_TOKEN_WEIGHT),
|
|
3463
|
+
),
|
|
3464
|
+
max_steps=max_rounds,
|
|
3465
|
+
max_tool_calls=10_000,
|
|
3466
|
+
)
|
|
3467
|
+
return LoopConfig(
|
|
3468
|
+
max_rounds=max_rounds,
|
|
3469
|
+
max_tool_errors=max_tool_errors,
|
|
3470
|
+
budget=budget,
|
|
3471
|
+
tool_dedup=resolved.tool_dedup,
|
|
3472
|
+
temperature=(
|
|
3473
|
+
float(params["temperature"])
|
|
3474
|
+
if params.get("temperature") is not None
|
|
3475
|
+
else None
|
|
3476
|
+
),
|
|
3477
|
+
max_tokens=int(params["maxTokens"])
|
|
3478
|
+
if params.get("maxTokens") is not None
|
|
3479
|
+
else None,
|
|
3480
|
+
soft_timeout_ms=(
|
|
3481
|
+
int(params["softTimeoutMs"])
|
|
3482
|
+
if params.get("softTimeoutMs") is not None
|
|
3483
|
+
else None
|
|
3484
|
+
),
|
|
3485
|
+
# Per-tool backstop against hung executors (in-process or remote).
|
|
3486
|
+
# LoopConfig carries the default; the param only overrides.
|
|
3487
|
+
**(
|
|
3488
|
+
{"tool_timeout_ms": int(params["toolTimeoutMs"])}
|
|
3489
|
+
if params.get("toolTimeoutMs") is not None
|
|
3490
|
+
else {}
|
|
3491
|
+
),
|
|
3492
|
+
# W2.8.1: mid-turn steer policy — "boundary" (default) drains at the
|
|
3493
|
+
# next round boundary; "interrupt" cancels the in-flight tool phase
|
|
3494
|
+
# so the steer reaches the model at the very next request.
|
|
3495
|
+
**(
|
|
3496
|
+
{"steer_mode": params["steerMode"]}
|
|
3497
|
+
if params.get("steerMode") in ("boundary", "interrupt")
|
|
3498
|
+
else {}
|
|
3499
|
+
),
|
|
3500
|
+
)
|
|
3501
|
+
|
|
3502
|
+
|
|
3503
|
+
_shared_calibration: Any | None = None
|
|
3504
|
+
_shared_calibration_path: str | None = None
|
|
3505
|
+
|
|
3506
|
+
|
|
3507
|
+
def _get_shared_calibration() -> Any:
|
|
3508
|
+
"""Process-level UsageCalibration singleton.
|
|
3509
|
+
|
|
3510
|
+
The provider factory runs per chat-stream request; a per-request
|
|
3511
|
+
calibration would accumulate samples only within one turn and rarely
|
|
3512
|
+
reach the persist threshold. A process-shared singleton accumulates
|
|
3513
|
+
across turns and is flushed periodically (persist_every) and on
|
|
3514
|
+
shutdown.
|
|
3515
|
+
"""
|
|
3516
|
+
global _shared_calibration, _shared_calibration_path
|
|
3517
|
+
if _shared_calibration is None:
|
|
3518
|
+
from steerable_agent_runtime import UsageCalibration
|
|
3519
|
+
|
|
3520
|
+
path = os.environ.get("STEERABLE_TOKEN_CALIBRATION_PATH") or os.path.join(
|
|
3521
|
+
os.path.expanduser("~"), ".steerable", "token-calibration.json"
|
|
3522
|
+
)
|
|
3523
|
+
_shared_calibration = UsageCalibration.load(path)
|
|
3524
|
+
_shared_calibration.register_factors()
|
|
3525
|
+
_shared_calibration_path = path
|
|
3526
|
+
return _shared_calibration
|
|
3527
|
+
|
|
3528
|
+
|
|
3529
|
+
def _flush_shared_calibration() -> None:
|
|
3530
|
+
if _shared_calibration is not None and _shared_calibration_path is not None:
|
|
3531
|
+
try:
|
|
3532
|
+
_shared_calibration.save(_shared_calibration_path)
|
|
3533
|
+
except OSError:
|
|
3534
|
+
pass # shutdown flush is best-effort; periodic flushes already ran
|
|
3535
|
+
|
|
3536
|
+
|
|
3537
|
+
def _wrap_with_calibration(provider: LLMProvider) -> LLMProvider:
|
|
3538
|
+
"""Wrap the provider so every request records estimated-vs-observed usage.
|
|
3539
|
+
|
|
3540
|
+
Default-on: dogfooding should accumulate calibration samples with zero
|
|
3541
|
+
setup. Disable with ``STEERABLE_TOKEN_CALIBRATION=0``; override the
|
|
3542
|
+
aggregates file with ``STEERABLE_TOKEN_CALIBRATION_PATH`` (default
|
|
3543
|
+
``~/.steerable/token-calibration.json``). Previously accumulated factors
|
|
3544
|
+
are registered into MODEL_TOKEN_FACTORS on load, so a restarted sidecar
|
|
3545
|
+
resumes with its measured corrections.
|
|
3546
|
+
"""
|
|
3547
|
+
flag = os.environ.get("STEERABLE_TOKEN_CALIBRATION", "1").strip().lower()
|
|
3548
|
+
if flag in {"0", "false", "no", "off"}:
|
|
3549
|
+
return provider
|
|
3550
|
+
from steerable_agent_runtime import CalibratingProvider
|
|
3551
|
+
|
|
3552
|
+
return CalibratingProvider(
|
|
3553
|
+
provider,
|
|
3554
|
+
_get_shared_calibration(),
|
|
3555
|
+
persist_path=_shared_calibration_path,
|
|
3556
|
+
)
|
|
3557
|
+
|
|
3558
|
+
|
|
3559
|
+
def _wrap_with_recording(provider: LLMProvider) -> LLMProvider:
|
|
3560
|
+
"""Wrap the provider so every outbound request lands in a JSONL record.
|
|
3561
|
+
|
|
3562
|
+
Opt-in via ``STEERABLE_REQUEST_RECORD_PATH=<file.jsonl>`` — the E2E
|
|
3563
|
+
harness and dogfood runs set it to assert the prompt invariants
|
|
3564
|
+
(``assert_stable_prefix`` / ``assert_bounded_items``) on real traffic.
|
|
3565
|
+
Off by default: the record carries full prompt contents.
|
|
3566
|
+
"""
|
|
3567
|
+
|
|
3568
|
+
path = os.environ.get("STEERABLE_REQUEST_RECORD_PATH", "").strip()
|
|
3569
|
+
if not path:
|
|
3570
|
+
return provider
|
|
3571
|
+
from steerable_agent_runtime import JsonlRequestSink, RecordingProvider
|
|
3572
|
+
|
|
3573
|
+
return RecordingProvider(provider, JsonlRequestSink(path))
|
|
3574
|
+
|
|
3575
|
+
|
|
3576
|
+
def _catalog_base_url(provider_kind: str) -> str | None:
|
|
3577
|
+
"""The catalog's api base URL for a first-party provider kind."""
|
|
3578
|
+
from steerable_agent_runtime.model_resolve import provider_endpoint
|
|
3579
|
+
|
|
3580
|
+
endpoint = provider_endpoint(provider_kind)
|
|
3581
|
+
return endpoint.api_base_url if endpoint else None
|
|
3582
|
+
|
|
3583
|
+
|
|
3584
|
+
#: The bundled default harness spec (W1.2.4): the built-in chain as data.
|
|
3585
|
+
#: The JSON copy is the runtime-loaded one — PyYAML is deliberately not a
|
|
3586
|
+
#: runtime dependency, and JSON is a YAML subset the loader parses with
|
|
3587
|
+
#: stdlib json. Resolved inside the installed steerable_agent_runtime
|
|
3588
|
+
#: package (shipped as package data) so pip-installed venvs — Harbor trial
|
|
3589
|
+
#: containers — find it; the repo layout lands on the same file through
|
|
3590
|
+
#: the editable install. default.harness.yaml stays the commented source;
|
|
3591
|
+
#: test_harness_spec pins the two in sync.
|
|
3592
|
+
_DEFAULT_HARNESS_SPEC_PATH = (
|
|
3593
|
+
Path(importlib.util.find_spec("steerable_agent_runtime").origin).resolve().parent
|
|
3594
|
+
/ "default.harness.json"
|
|
3595
|
+
)
|
|
3596
|
+
|
|
3597
|
+
|
|
3598
|
+
def _resolve_preset_param(
|
|
3599
|
+
params: dict[str, Any],
|
|
3600
|
+
) -> ProviderPreset | Literal["auto", "off"]:
|
|
3601
|
+
"""Map the host's ``presets`` chat param onto the provider's ``preset`` field.
|
|
3602
|
+
|
|
3603
|
+
Absent or ``{"enabled": true}`` → ``"auto"`` (registry match on
|
|
3604
|
+
base-URL+model); ``{"enabled": false}`` → ``"off"``; ``{"override": {...}}``
|
|
3605
|
+
pins an explicit preset (parsed fail-loud by ``ProviderPreset.from_dict``).
|
|
3606
|
+
A malformed payload raises ``ValueError`` rather than silently falling
|
|
3607
|
+
back to auto — the host made a choice, it must apply or fail.
|
|
3608
|
+
"""
|
|
3609
|
+
from steerable_agent_runtime.llm import ProviderPreset
|
|
3610
|
+
|
|
3611
|
+
raw = params.get("presets")
|
|
3612
|
+
if raw is None:
|
|
3613
|
+
return "auto"
|
|
3614
|
+
if not isinstance(raw, dict):
|
|
3615
|
+
raise TypeError("presets param must be an object")
|
|
3616
|
+
override = raw.get("override")
|
|
3617
|
+
if override is not None:
|
|
3618
|
+
if not isinstance(override, dict):
|
|
3619
|
+
raise TypeError("presets.override must be an object")
|
|
3620
|
+
return ProviderPreset.from_dict(override)
|
|
3621
|
+
return "auto" if raw.get("enabled", True) else "off"
|
|
3622
|
+
|
|
3623
|
+
|
|
3624
|
+
def default_llm_provider_factory(params: dict[str, Any]) -> LLMProvider:
|
|
3625
|
+
"""Construct an LLMProvider from a chat-stream request payload.
|
|
3626
|
+
|
|
3627
|
+
Embedders can override this by passing ``llm_provider_factory=`` to
|
|
3628
|
+
``Sidecar(...)`` — useful for tests or for sites that want to enforce a
|
|
3629
|
+
single configured provider.
|
|
3630
|
+
"""
|
|
3631
|
+
|
|
3632
|
+
provider_kind = (params.get("provider") or "").strip().lower()
|
|
3633
|
+
model = params.get("model")
|
|
3634
|
+
if not model:
|
|
3635
|
+
raise ValueError("model is required")
|
|
3636
|
+
base_url = params.get("baseUrl") or params.get("base_url")
|
|
3637
|
+
api_key = params.get("apiKey") or params.get("api_key") or ""
|
|
3638
|
+
|
|
3639
|
+
# The host model picker's per-request reasoning effort. Parsed once for
|
|
3640
|
+
# every provider family and validated at construction so an
|
|
3641
|
+
# unsupportable level is an RPC error here, not a mid-stream failure
|
|
3642
|
+
# (EVALS 2.5.22 fail-loud). The wire path re-validates with the
|
|
3643
|
+
# branch-resolved base_url.
|
|
3644
|
+
reasoning_effort = params.get("reasoningEffort") or params.get(
|
|
3645
|
+
"reasoning_effort"
|
|
3646
|
+
)
|
|
3647
|
+
if reasoning_effort:
|
|
3648
|
+
from steerable_agent_runtime import clamp_reasoning_effort
|
|
3649
|
+
|
|
3650
|
+
clamp_reasoning_effort(
|
|
3651
|
+
str(model),
|
|
3652
|
+
str(reasoning_effort),
|
|
3653
|
+
provider=provider_kind or None,
|
|
3654
|
+
base_url=base_url,
|
|
3655
|
+
strict=True,
|
|
3656
|
+
)
|
|
3657
|
+
|
|
3658
|
+
# The host asked this one endpoint to skip the proxy (see
|
|
3659
|
+
# `ProviderConfig.force_direct`). Per request, not per process: a product
|
|
3660
|
+
# may send one model service direct and leave the rest proxied.
|
|
3661
|
+
direct_connection = bool(params.get("directConnection"))
|
|
3662
|
+
|
|
3663
|
+
if provider_kind in {"openai", "openai_compat", "openai-compatible", "ollama"}:
|
|
3664
|
+
from steerable_agent_runtime.llm import (
|
|
3665
|
+
OpenAICompatFlags,
|
|
3666
|
+
OpenAICompatProvider,
|
|
3667
|
+
compat_for_base_url,
|
|
3668
|
+
)
|
|
3669
|
+
|
|
3670
|
+
if provider_kind == "ollama":
|
|
3671
|
+
# Ollama's OpenAI-compatible API lives under /v1. Callers that
|
|
3672
|
+
# configure the native daemon root (e.g. the desktop app stores
|
|
3673
|
+
# http://127.0.0.1:11434 for its native /api/chat client) would
|
|
3674
|
+
# otherwise 404 on /chat/completions.
|
|
3675
|
+
base_url = (base_url or "http://127.0.0.1:11434").rstrip("/")
|
|
3676
|
+
if not base_url.endswith("/v1"):
|
|
3677
|
+
base_url = f"{base_url}/v1"
|
|
3678
|
+
|
|
3679
|
+
# W5.3.1: a catalogued provider name supplies its own endpoint —
|
|
3680
|
+
# ``provider: deepseek`` needs no hand-written base_url. Unknown
|
|
3681
|
+
# kinds (openai_compat shims, ollama) keep the OpenAI default.
|
|
3682
|
+
resolved_base_url = (
|
|
3683
|
+
base_url or _catalog_base_url(provider_kind) or "https://api.openai.com/v1"
|
|
3684
|
+
)
|
|
3685
|
+
# Vendor divergences arrive as data: an explicit ``compat`` payload
|
|
3686
|
+
# wins; otherwise auto-detect from the base-URL host (pi-style).
|
|
3687
|
+
compat_param = params.get("compat")
|
|
3688
|
+
compat = (
|
|
3689
|
+
OpenAICompatFlags.from_dict(compat_param)
|
|
3690
|
+
if isinstance(compat_param, dict)
|
|
3691
|
+
else compat_for_base_url(resolved_base_url)
|
|
3692
|
+
)
|
|
3693
|
+
return _wrap_with_recording(
|
|
3694
|
+
_wrap_with_calibration(
|
|
3695
|
+
OpenAICompatProvider(
|
|
3696
|
+
name=provider_kind or "openai_compat",
|
|
3697
|
+
base_url=resolved_base_url,
|
|
3698
|
+
api_key=api_key,
|
|
3699
|
+
model=str(model),
|
|
3700
|
+
compat=compat,
|
|
3701
|
+
preset=_resolve_preset_param(params),
|
|
3702
|
+
reasoning_effort=(
|
|
3703
|
+
str(reasoning_effort) if reasoning_effort else None
|
|
3704
|
+
),
|
|
3705
|
+
force_direct=direct_connection,
|
|
3706
|
+
)
|
|
3707
|
+
)
|
|
3708
|
+
)
|
|
3709
|
+
if provider_kind in {"anthropic", "claude"}:
|
|
3710
|
+
from steerable_agent_runtime.llm import AnthropicProvider
|
|
3711
|
+
|
|
3712
|
+
return _wrap_with_recording(
|
|
3713
|
+
_wrap_with_calibration(
|
|
3714
|
+
_wrap_with_cache_control(
|
|
3715
|
+
AnthropicProvider(
|
|
3716
|
+
name=provider_kind or "anthropic",
|
|
3717
|
+
api_key=api_key,
|
|
3718
|
+
model=str(model),
|
|
3719
|
+
base_url=base_url,
|
|
3720
|
+
)
|
|
3721
|
+
)
|
|
3722
|
+
)
|
|
3723
|
+
)
|
|
3724
|
+
if provider_kind in {"openai-responses", "openai_responses", "responses", "xai"}:
|
|
3725
|
+
from steerable_agent_runtime.llm import OpenAIResponsesProvider
|
|
3726
|
+
|
|
3727
|
+
resolved_base_url = (
|
|
3728
|
+
base_url
|
|
3729
|
+
or ("https://api.x.ai/v1" if provider_kind == "xai" else None)
|
|
3730
|
+
or "https://api.openai.com/v1"
|
|
3731
|
+
)
|
|
3732
|
+
return _wrap_with_recording(
|
|
3733
|
+
_wrap_with_calibration(
|
|
3734
|
+
OpenAIResponsesProvider(
|
|
3735
|
+
name=provider_kind or "openai-responses",
|
|
3736
|
+
base_url=resolved_base_url,
|
|
3737
|
+
api_key=api_key,
|
|
3738
|
+
model=str(model),
|
|
3739
|
+
preset=_resolve_preset_param(params),
|
|
3740
|
+
reasoning_effort=(
|
|
3741
|
+
str(reasoning_effort) if reasoning_effort else None
|
|
3742
|
+
),
|
|
3743
|
+
force_direct=direct_connection,
|
|
3744
|
+
)
|
|
3745
|
+
)
|
|
3746
|
+
)
|
|
3747
|
+
if provider_kind in {"google", "gemini", "google-genai", "google_genai"}:
|
|
3748
|
+
from steerable_agent_runtime.llm import GoogleGenAIProvider
|
|
3749
|
+
|
|
3750
|
+
return _wrap_with_recording(
|
|
3751
|
+
_wrap_with_calibration(
|
|
3752
|
+
GoogleGenAIProvider(
|
|
3753
|
+
name=provider_kind or "google",
|
|
3754
|
+
base_url=base_url or "https://generativelanguage.googleapis.com",
|
|
3755
|
+
api_key=api_key,
|
|
3756
|
+
model=str(model),
|
|
3757
|
+
preset=_resolve_preset_param(params),
|
|
3758
|
+
force_direct=direct_connection,
|
|
3759
|
+
)
|
|
3760
|
+
)
|
|
3761
|
+
)
|
|
3762
|
+
|
|
3763
|
+
raise ValueError(f"unknown provider: {provider_kind!r}")
|
|
3764
|
+
|
|
3765
|
+
|
|
3766
|
+
def _wrap_with_cache_control(provider: LLMProvider) -> LLMProvider:
|
|
3767
|
+
"""Emit prompt-cache breakpoints (Wave 4, W4-4) — default-on.
|
|
3768
|
+
|
|
3769
|
+
Anthropic is the only provider with an explicit breakpoint API; for the
|
|
3770
|
+
implicit prefix caches (OpenAI-compatible, Ollama) the wrapper is a
|
|
3771
|
+
pass-through. ``STEERABLE_CACHE_CONTROL=0`` disables it (a debugging
|
|
3772
|
+
escape hatch, e.g. diffing wire bytes against a recorded fixture).
|
|
3773
|
+
``STEERABLE_PROMPT_CACHE_TTL=1h`` opts the breakpoints into Anthropic's
|
|
3774
|
+
1-hour TTL (CC ``CLAUDE_CODE_PROMPT_CACHE_TTL`` parity); anything else
|
|
3775
|
+
keeps the 5-minute default.
|
|
3776
|
+
"""
|
|
3777
|
+
|
|
3778
|
+
flag = os.environ.get("STEERABLE_CACHE_CONTROL", "1").strip().lower()
|
|
3779
|
+
if flag in {"0", "false", "no", "off"}:
|
|
3780
|
+
return provider
|
|
3781
|
+
from steerable_agent_runtime import CacheControlProvider
|
|
3782
|
+
|
|
3783
|
+
ttl = os.environ.get("STEERABLE_PROMPT_CACHE_TTL", "").strip().lower()
|
|
3784
|
+
retention = "long" if ttl in {"1h", "3600", "3600s", "long"} else "short"
|
|
3785
|
+
return CacheControlProvider(provider, retention=retention)
|