bantamkit-mcp 0.26.0
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/LICENSE +21 -0
- package/README.md +398 -0
- package/assets/contracts/default.yaml +90 -0
- package/assets/evals/devteam/manifest.yaml +351 -0
- package/assets/evals/devteam/repo/HISTORY.md +18 -0
- package/assets/evals/devteam/repo/README.md +12 -0
- package/assets/evals/devteam/repo/docs/architecture.md +17 -0
- package/assets/evals/devteam/repo/docs/runbook.md +10 -0
- package/assets/evals/devteam/repo/issues/142-settlement-timeout.md +23 -0
- package/assets/evals/devteam/repo/patches/0009-retry-budget.patch +38 -0
- package/assets/evals/devteam/repo/src/ledger/__init__.py +3 -0
- package/assets/evals/devteam/repo/src/ledger/config.py +35 -0
- package/assets/evals/devteam/repo/src/ledger/errors.py +13 -0
- package/assets/evals/devteam/repo/src/ledger/posting.py +12 -0
- package/assets/evals/devteam/repo/src/ledger/registry.py +7 -0
- package/assets/evals/devteam/repo/src/ledger/report.py +9 -0
- package/assets/evals/devteam/repo/src/ledger/retry.py +17 -0
- package/assets/evals/devteam/repo/src/ledger/settle.py +16 -0
- package/assets/evals/devteam/repo/src/ledger/validate.py +14 -0
- package/assets/evals/devteam/repo/tests/test_posting.py +13 -0
- package/assets/evals/devteam/repo/tests/test_settle.py +9 -0
- package/assets/evals/devteam/tasks/dt-error-contract.yaml +186 -0
- package/assets/evals/devteam/tasks/dt-handler-map.yaml +183 -0
- package/assets/evals/devteam/tasks/dt-patch-before-after.yaml +182 -0
- package/assets/evals/devteam/tasks/dt-retry-attempts.yaml +181 -0
- package/assets/evals/devteam/tasks/dt-settlement-config.yaml +185 -0
- package/assets/evals/devteam/tasks/dt-symbol-home.yaml +181 -0
- package/assets/evals/devteam/tasks/dt-trace-blame.yaml +182 -0
- package/assets/evals/devteam/tasks/dt-unread-key.yaml +180 -0
- package/assets/evals/document/tasks/doc-large-in-137.yaml +38 -0
- package/assets/evals/document/tasks/doc-large-in-359.yaml +44 -0
- package/assets/evals/document/tasks/doc-large-in-372.yaml +38 -0
- package/assets/evals/document/tasks/doc-large-out-11764.yaml +37 -0
- package/assets/evals/document/tasks/doc-large-out-4137.yaml +37 -0
- package/assets/evals/document/tasks/doc-large-out-8022.yaml +37 -0
- package/assets/evals/document/tasks/doc-small-137.yaml +37 -0
- package/assets/evals/document/tasks/doc-small-261.yaml +37 -0
- package/assets/evals/document/tasks/doc-small-388.yaml +37 -0
- package/assets/evals/fixtures/.gitkeep +0 -0
- package/assets/evals/fixtures/catalog.json +6 -0
- package/assets/evals/perturbations/task-completion.yaml +576 -0
- package/assets/evals/tasks/.gitkeep +0 -0
- package/assets/evals/tasks/extract-contact.yaml +14 -0
- package/assets/evals/tasks/extract-invoice.yaml +14 -0
- package/assets/evals/tasks/extract-order.yaml +15 -0
- package/assets/evals/tasks/extract-schedule.yaml +14 -0
- package/assets/evals/tasks/extract-versions.yaml +17 -0
- package/assets/evals/tasks/nav-prod-port.yaml +84 -0
- package/assets/evals/tasks/nav-release-bundle.yaml +87 -0
- package/assets/evals/tasks/recall-audit-retention.yaml +17 -0
- package/assets/evals/tasks/recall-cache-ttl.yaml +13 -0
- package/assets/evals/tasks/recall-db-port.yaml +17 -0
- package/assets/evals/tasks/recall-deploy.yaml +13 -0
- package/assets/evals/tasks/recall-env-endpoint.yaml +18 -0
- package/assets/evals/tasks/recall-oncall-rotation.yaml +21 -0
- package/assets/evals/tasks/recall-oncall.yaml +13 -0
- package/assets/evals/tasks/recall-org-quota.yaml +18 -0
- package/assets/evals/tasks/recall-owner.yaml +13 -0
- package/assets/evals/tasks/shop-basket-total.yaml +10 -0
- package/assets/evals/tasks/shop-cheapest.yaml +9 -0
- package/assets/evals/tasks/shop-compare.yaml +9 -0
- package/assets/evals/tasks/shop-gadget-value.yaml +9 -0
- package/assets/evals/tasks/shop-stock-total.yaml +9 -0
- package/assets/evals/tasks/shop-total.yaml +9 -0
- package/assets/profiles/default.yaml +31 -0
- package/assets/profiles/patient.yaml +31 -0
- package/assets/rubrics/.gitkeep +0 -0
- package/assets/rubrics/code-quality.yaml +20 -0
- package/assets/rubrics/grounded-completion.yaml +37 -0
- package/assets/rubrics/task-completion.yaml +28 -0
- package/assets/schemas/shiftwork-checkpoint.json +188 -0
- package/assets/skills/.gitkeep +0 -0
- package/assets/skills/file-graph.md +7 -0
- package/assets/skills/memory.md +35 -0
- package/assets/tools/.gitkeep +0 -0
- package/assets/tools/bantamkit_read.json +48 -0
- package/assets/tools/bantamkit_status.json +25 -0
- package/assets/tools/build_identity.json +17 -0
- package/assets/tools/document_list.json +12 -0
- package/assets/tools/document_read.json +31 -0
- package/assets/tools/file_graph.json +12 -0
- package/assets/tools/memory_compact.json +31 -0
- package/assets/tools/memory_recall.json +38 -0
- package/assets/tools/memory_save.json +61 -0
- package/assets/tools/shiftwork_clock_in.json +25 -0
- package/assets/tools/shiftwork_clock_out.json +60 -0
- package/assets/tools/shiftwork_status.json +25 -0
- package/assets/tools/skill_audit.json +70 -0
- package/assets/tools/validate_json.json +31 -0
- package/dist/assets.d.ts +48 -0
- package/dist/assets.js +109 -0
- package/dist/charsets.d.ts +17 -0
- package/dist/charsets.js +580 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.js +280 -0
- package/dist/contract.d.ts +145 -0
- package/dist/contract.js +608 -0
- package/dist/docread.d.ts +357 -0
- package/dist/docread.js +3315 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +14 -0
- package/dist/eventlog.d.ts +137 -0
- package/dist/eventlog.js +294 -0
- package/dist/htmlentities.d.ts +2 -0
- package/dist/htmlentities.js +16 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +13 -0
- package/dist/mcp/identity.d.ts +25 -0
- package/dist/mcp/identity.js +275 -0
- package/dist/mcp/pyargs.d.ts +80 -0
- package/dist/mcp/pyargs.js +362 -0
- package/dist/mcp/sdkjson.d.ts +56 -0
- package/dist/mcp/sdkjson.js +91 -0
- package/dist/mcp/server.d.ts +45 -0
- package/dist/mcp/server.js +740 -0
- package/dist/mcp/status.d.ts +210 -0
- package/dist/mcp/status.js +357 -0
- package/dist/mcp/transport.d.ts +68 -0
- package/dist/mcp/transport.js +111 -0
- package/dist/mcpreport.d.ts +214 -0
- package/dist/mcpreport.js +758 -0
- package/dist/memory/cli.d.ts +2 -0
- package/dist/memory/cli.js +396 -0
- package/dist/memory/component.d.ts +256 -0
- package/dist/memory/component.js +497 -0
- package/dist/memory/factfile.d.ts +120 -0
- package/dist/memory/factfile.js +406 -0
- package/dist/memory/layers.d.ts +92 -0
- package/dist/memory/layers.js +410 -0
- package/dist/memory/pyfs.d.ts +521 -0
- package/dist/memory/pyfs.js +1608 -0
- package/dist/memory/pyyaml.d.ts +155 -0
- package/dist/memory/pyyaml.js +868 -0
- package/dist/memory/store.d.ts +478 -0
- package/dist/memory/store.js +1034 -0
- package/dist/pyargparse.d.ts +141 -0
- package/dist/pyargparse.js +813 -0
- package/dist/pyjson.d.ts +110 -0
- package/dist/pyjson.js +524 -0
- package/dist/pyjsonschema.d.ts +50 -0
- package/dist/pyjsonschema.js +951 -0
- package/dist/shiftwork.d.ts +60 -0
- package/dist/shiftwork.js +324 -0
- package/dist/skillaudit.d.ts +172 -0
- package/dist/skillaudit.js +914 -0
- package/dist/statusline.d.ts +106 -0
- package/dist/statusline.js +281 -0
- package/package.json +45 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The HTML5 named character references, GENERATED from CPython's `html.entities.html5`
|
|
3
|
+
* (Python 3.12.13) so that `docread`'s `unescape` and Python's `html.unescape` agree on
|
|
4
|
+
* every name, including the legacy names that need no `;` (`&`, `©`, ...). 2231
|
|
5
|
+
* entries; a name maps to one or two code points. Flat `[name, text, name, text, ...]`.
|
|
6
|
+
* Regenerated by the script in the commit that added this file; hand-edit nothing here.
|
|
7
|
+
*/
|
|
8
|
+
const FLAT = ["AElig", "Æ", "AElig;", "Æ", "AMP", "&", "AMP;", "&", "Aacute", "Á", "Aacute;", "Á", "Abreve;", "Ă", "Acirc", "Â", "Acirc;", "Â", "Acy;", "А", "Afr;", "𝔄", "Agrave", "À", "Agrave;", "À", "Alpha;", "Α", "Amacr;", "Ā", "And;", "⩓", "Aogon;", "Ą", "Aopf;", "𝔸", "ApplyFunction;", "", "Aring", "Å", "Aring;", "Å", "Ascr;", "𝒜", "Assign;", "≔", "Atilde", "Ã", "Atilde;", "Ã", "Auml", "Ä", "Auml;", "Ä", "Backslash;", "∖", "Barv;", "⫧", "Barwed;", "⌆", "Bcy;", "Б", "Because;", "∵", "Bernoullis;", "ℬ", "Beta;", "Β", "Bfr;", "𝔅", "Bopf;", "𝔹", "Breve;", "˘", "Bscr;", "ℬ", "Bumpeq;", "≎", "CHcy;", "Ч", "COPY", "©", "COPY;", "©", "Cacute;", "Ć", "Cap;", "⋒", "CapitalDifferentialD;", "ⅅ", "Cayleys;", "ℭ", "Ccaron;", "Č", "Ccedil", "Ç", "Ccedil;", "Ç", "Ccirc;", "Ĉ", "Cconint;", "∰", "Cdot;", "Ċ", "Cedilla;", "¸", "CenterDot;", "·", "Cfr;", "ℭ", "Chi;", "Χ", "CircleDot;", "⊙", "CircleMinus;", "⊖", "CirclePlus;", "⊕", "CircleTimes;", "⊗", "ClockwiseContourIntegral;", "∲", "CloseCurlyDoubleQuote;", "”", "CloseCurlyQuote;", "’", "Colon;", "∷", "Colone;", "⩴", "Congruent;", "≡", "Conint;", "∯", "ContourIntegral;", "∮", "Copf;", "ℂ", "Coproduct;", "∐", "CounterClockwiseContourIntegral;", "∳", "Cross;", "⨯", "Cscr;", "𝒞", "Cup;", "⋓", "CupCap;", "≍", "DD;", "ⅅ", "DDotrahd;", "⤑", "DJcy;", "Ђ", "DScy;", "Ѕ", "DZcy;", "Џ", "Dagger;", "‡", "Darr;", "↡", "Dashv;", "⫤", "Dcaron;", "Ď", "Dcy;", "Д", "Del;", "∇", "Delta;", "Δ", "Dfr;", "𝔇", "DiacriticalAcute;", "´", "DiacriticalDot;", "˙", "DiacriticalDoubleAcute;", "˝", "DiacriticalGrave;", "`", "DiacriticalTilde;", "˜", "Diamond;", "⋄", "DifferentialD;", "ⅆ", "Dopf;", "𝔻", "Dot;", "¨", "DotDot;", "⃜", "DotEqual;", "≐", "DoubleContourIntegral;", "∯", "DoubleDot;", "¨", "DoubleDownArrow;", "⇓", "DoubleLeftArrow;", "⇐", "DoubleLeftRightArrow;", "⇔", "DoubleLeftTee;", "⫤", "DoubleLongLeftArrow;", "⟸", "DoubleLongLeftRightArrow;", "⟺", "DoubleLongRightArrow;", "⟹", "DoubleRightArrow;", "⇒", "DoubleRightTee;", "⊨", "DoubleUpArrow;", "⇑", "DoubleUpDownArrow;", "⇕", "DoubleVerticalBar;", "∥", "DownArrow;", "↓", "DownArrowBar;", "⤓", "DownArrowUpArrow;", "⇵", "DownBreve;", "̑", "DownLeftRightVector;", "⥐", "DownLeftTeeVector;", "⥞", "DownLeftVector;", "↽", "DownLeftVectorBar;", "⥖", "DownRightTeeVector;", "⥟", "DownRightVector;", "⇁", "DownRightVectorBar;", "⥗", "DownTee;", "⊤", "DownTeeArrow;", "↧", "Downarrow;", "⇓", "Dscr;", "𝒟", "Dstrok;", "Đ", "ENG;", "Ŋ", "ETH", "Ð", "ETH;", "Ð", "Eacute", "É", "Eacute;", "É", "Ecaron;", "Ě", "Ecirc", "Ê", "Ecirc;", "Ê", "Ecy;", "Э", "Edot;", "Ė", "Efr;", "𝔈", "Egrave", "È", "Egrave;", "È", "Element;", "∈", "Emacr;", "Ē", "EmptySmallSquare;", "◻", "EmptyVerySmallSquare;", "▫", "Eogon;", "Ę", "Eopf;", "𝔼", "Epsilon;", "Ε", "Equal;", "⩵", "EqualTilde;", "≂", "Equilibrium;", "⇌", "Escr;", "ℰ", "Esim;", "⩳", "Eta;", "Η", "Euml", "Ë", "Euml;", "Ë", "Exists;", "∃", "ExponentialE;", "ⅇ", "Fcy;", "Ф", "Ffr;", "𝔉", "FilledSmallSquare;", "◼", "FilledVerySmallSquare;", "▪", "Fopf;", "𝔽", "ForAll;", "∀", "Fouriertrf;", "ℱ", "Fscr;", "ℱ", "GJcy;", "Ѓ", "GT", ">", "GT;", ">", "Gamma;", "Γ", "Gammad;", "Ϝ", "Gbreve;", "Ğ", "Gcedil;", "Ģ", "Gcirc;", "Ĝ", "Gcy;", "Г", "Gdot;", "Ġ", "Gfr;", "𝔊", "Gg;", "⋙", "Gopf;", "𝔾", "GreaterEqual;", "≥", "GreaterEqualLess;", "⋛", "GreaterFullEqual;", "≧", "GreaterGreater;", "⪢", "GreaterLess;", "≷", "GreaterSlantEqual;", "⩾", "GreaterTilde;", "≳", "Gscr;", "𝒢", "Gt;", "≫", "HARDcy;", "Ъ", "Hacek;", "ˇ", "Hat;", "^", "Hcirc;", "Ĥ", "Hfr;", "ℌ", "HilbertSpace;", "ℋ", "Hopf;", "ℍ", "HorizontalLine;", "─", "Hscr;", "ℋ", "Hstrok;", "Ħ", "HumpDownHump;", "≎", "HumpEqual;", "≏", "IEcy;", "Е", "IJlig;", "IJ", "IOcy;", "Ё", "Iacute", "Í", "Iacute;", "Í", "Icirc", "Î", "Icirc;", "Î", "Icy;", "И", "Idot;", "İ", "Ifr;", "ℑ", "Igrave", "Ì", "Igrave;", "Ì", "Im;", "ℑ", "Imacr;", "Ī", "ImaginaryI;", "ⅈ", "Implies;", "⇒", "Int;", "∬", "Integral;", "∫", "Intersection;", "⋂", "InvisibleComma;", "", "InvisibleTimes;", "", "Iogon;", "Į", "Iopf;", "𝕀", "Iota;", "Ι", "Iscr;", "ℐ", "Itilde;", "Ĩ", "Iukcy;", "І", "Iuml", "Ï", "Iuml;", "Ï", "Jcirc;", "Ĵ", "Jcy;", "Й", "Jfr;", "𝔍", "Jopf;", "𝕁", "Jscr;", "𝒥", "Jsercy;", "Ј", "Jukcy;", "Є", "KHcy;", "Х", "KJcy;", "Ќ", "Kappa;", "Κ", "Kcedil;", "Ķ", "Kcy;", "К", "Kfr;", "𝔎", "Kopf;", "𝕂", "Kscr;", "𝒦", "LJcy;", "Љ", "LT", "<", "LT;", "<", "Lacute;", "Ĺ", "Lambda;", "Λ", "Lang;", "⟪", "Laplacetrf;", "ℒ", "Larr;", "↞", "Lcaron;", "Ľ", "Lcedil;", "Ļ", "Lcy;", "Л", "LeftAngleBracket;", "⟨", "LeftArrow;", "←", "LeftArrowBar;", "⇤", "LeftArrowRightArrow;", "⇆", "LeftCeiling;", "⌈", "LeftDoubleBracket;", "⟦", "LeftDownTeeVector;", "⥡", "LeftDownVector;", "⇃", "LeftDownVectorBar;", "⥙", "LeftFloor;", "⌊", "LeftRightArrow;", "↔", "LeftRightVector;", "⥎", "LeftTee;", "⊣", "LeftTeeArrow;", "↤", "LeftTeeVector;", "⥚", "LeftTriangle;", "⊲", "LeftTriangleBar;", "⧏", "LeftTriangleEqual;", "⊴", "LeftUpDownVector;", "⥑", "LeftUpTeeVector;", "⥠", "LeftUpVector;", "↿", "LeftUpVectorBar;", "⥘", "LeftVector;", "↼", "LeftVectorBar;", "⥒", "Leftarrow;", "⇐", "Leftrightarrow;", "⇔", "LessEqualGreater;", "⋚", "LessFullEqual;", "≦", "LessGreater;", "≶", "LessLess;", "⪡", "LessSlantEqual;", "⩽", "LessTilde;", "≲", "Lfr;", "𝔏", "Ll;", "⋘", "Lleftarrow;", "⇚", "Lmidot;", "Ŀ", "LongLeftArrow;", "⟵", "LongLeftRightArrow;", "⟷", "LongRightArrow;", "⟶", "Longleftarrow;", "⟸", "Longleftrightarrow;", "⟺", "Longrightarrow;", "⟹", "Lopf;", "𝕃", "LowerLeftArrow;", "↙", "LowerRightArrow;", "↘", "Lscr;", "ℒ", "Lsh;", "↰", "Lstrok;", "Ł", "Lt;", "≪", "Map;", "⤅", "Mcy;", "М", "MediumSpace;", " ", "Mellintrf;", "ℳ", "Mfr;", "𝔐", "MinusPlus;", "∓", "Mopf;", "𝕄", "Mscr;", "ℳ", "Mu;", "Μ", "NJcy;", "Њ", "Nacute;", "Ń", "Ncaron;", "Ň", "Ncedil;", "Ņ", "Ncy;", "Н", "NegativeMediumSpace;", "", "NegativeThickSpace;", "", "NegativeThinSpace;", "", "NegativeVeryThinSpace;", "", "NestedGreaterGreater;", "≫", "NestedLessLess;", "≪", "NewLine;", "\n", "Nfr;", "𝔑", "NoBreak;", "", "NonBreakingSpace;", " ", "Nopf;", "ℕ", "Not;", "⫬", "NotCongruent;", "≢", "NotCupCap;", "≭", "NotDoubleVerticalBar;", "∦", "NotElement;", "∉", "NotEqual;", "≠", "NotEqualTilde;", "≂̸", "NotExists;", "∄", "NotGreater;", "≯", "NotGreaterEqual;", "≱", "NotGreaterFullEqual;", "≧̸", "NotGreaterGreater;", "≫̸", "NotGreaterLess;", "≹", "NotGreaterSlantEqual;", "⩾̸", "NotGreaterTilde;", "≵", "NotHumpDownHump;", "≎̸", "NotHumpEqual;", "≏̸", "NotLeftTriangle;", "⋪", "NotLeftTriangleBar;", "⧏̸", "NotLeftTriangleEqual;", "⋬", "NotLess;", "≮", "NotLessEqual;", "≰", "NotLessGreater;", "≸", "NotLessLess;", "≪̸", "NotLessSlantEqual;", "⩽̸", "NotLessTilde;", "≴", "NotNestedGreaterGreater;", "⪢̸", "NotNestedLessLess;", "⪡̸", "NotPrecedes;", "⊀", "NotPrecedesEqual;", "⪯̸", "NotPrecedesSlantEqual;", "⋠", "NotReverseElement;", "∌", "NotRightTriangle;", "⋫", "NotRightTriangleBar;", "⧐̸", "NotRightTriangleEqual;", "⋭", "NotSquareSubset;", "⊏̸", "NotSquareSubsetEqual;", "⋢", "NotSquareSuperset;", "⊐̸", "NotSquareSupersetEqual;", "⋣", "NotSubset;", "⊂⃒", "NotSubsetEqual;", "⊈", "NotSucceeds;", "⊁", "NotSucceedsEqual;", "⪰̸", "NotSucceedsSlantEqual;", "⋡", "NotSucceedsTilde;", "≿̸", "NotSuperset;", "⊃⃒", "NotSupersetEqual;", "⊉", "NotTilde;", "≁", "NotTildeEqual;", "≄", "NotTildeFullEqual;", "≇", "NotTildeTilde;", "≉", "NotVerticalBar;", "∤", "Nscr;", "𝒩", "Ntilde", "Ñ", "Ntilde;", "Ñ", "Nu;", "Ν", "OElig;", "Œ", "Oacute", "Ó", "Oacute;", "Ó", "Ocirc", "Ô", "Ocirc;", "Ô", "Ocy;", "О", "Odblac;", "Ő", "Ofr;", "𝔒", "Ograve", "Ò", "Ograve;", "Ò", "Omacr;", "Ō", "Omega;", "Ω", "Omicron;", "Ο", "Oopf;", "𝕆", "OpenCurlyDoubleQuote;", "“", "OpenCurlyQuote;", "‘", "Or;", "⩔", "Oscr;", "𝒪", "Oslash", "Ø", "Oslash;", "Ø", "Otilde", "Õ", "Otilde;", "Õ", "Otimes;", "⨷", "Ouml", "Ö", "Ouml;", "Ö", "OverBar;", "‾", "OverBrace;", "⏞", "OverBracket;", "⎴", "OverParenthesis;", "⏜", "PartialD;", "∂", "Pcy;", "П", "Pfr;", "𝔓", "Phi;", "Φ", "Pi;", "Π", "PlusMinus;", "±", "Poincareplane;", "ℌ", "Popf;", "ℙ", "Pr;", "⪻", "Precedes;", "≺", "PrecedesEqual;", "⪯", "PrecedesSlantEqual;", "≼", "PrecedesTilde;", "≾", "Prime;", "″", "Product;", "∏", "Proportion;", "∷", "Proportional;", "∝", "Pscr;", "𝒫", "Psi;", "Ψ", "QUOT", "\"", "QUOT;", "\"", "Qfr;", "𝔔", "Qopf;", "ℚ", "Qscr;", "𝒬", "RBarr;", "⤐", "REG", "®", "REG;", "®", "Racute;", "Ŕ", "Rang;", "⟫", "Rarr;", "↠", "Rarrtl;", "⤖", "Rcaron;", "Ř", "Rcedil;", "Ŗ", "Rcy;", "Р", "Re;", "ℜ", "ReverseElement;", "∋", "ReverseEquilibrium;", "⇋", "ReverseUpEquilibrium;", "⥯", "Rfr;", "ℜ", "Rho;", "Ρ", "RightAngleBracket;", "⟩", "RightArrow;", "→", "RightArrowBar;", "⇥", "RightArrowLeftArrow;", "⇄", "RightCeiling;", "⌉", "RightDoubleBracket;", "⟧", "RightDownTeeVector;", "⥝", "RightDownVector;", "⇂", "RightDownVectorBar;", "⥕", "RightFloor;", "⌋", "RightTee;", "⊢", "RightTeeArrow;", "↦", "RightTeeVector;", "⥛", "RightTriangle;", "⊳", "RightTriangleBar;", "⧐", "RightTriangleEqual;", "⊵", "RightUpDownVector;", "⥏", "RightUpTeeVector;", "⥜", "RightUpVector;", "↾", "RightUpVectorBar;", "⥔", "RightVector;", "⇀", "RightVectorBar;", "⥓", "Rightarrow;", "⇒", "Ropf;", "ℝ", "RoundImplies;", "⥰", "Rrightarrow;", "⇛", "Rscr;", "ℛ", "Rsh;", "↱", "RuleDelayed;", "⧴", "SHCHcy;", "Щ", "SHcy;", "Ш", "SOFTcy;", "Ь", "Sacute;", "Ś", "Sc;", "⪼", "Scaron;", "Š", "Scedil;", "Ş", "Scirc;", "Ŝ", "Scy;", "С", "Sfr;", "𝔖", "ShortDownArrow;", "↓", "ShortLeftArrow;", "←", "ShortRightArrow;", "→", "ShortUpArrow;", "↑", "Sigma;", "Σ", "SmallCircle;", "∘", "Sopf;", "𝕊", "Sqrt;", "√", "Square;", "□", "SquareIntersection;", "⊓", "SquareSubset;", "⊏", "SquareSubsetEqual;", "⊑", "SquareSuperset;", "⊐", "SquareSupersetEqual;", "⊒", "SquareUnion;", "⊔", "Sscr;", "𝒮", "Star;", "⋆", "Sub;", "⋐", "Subset;", "⋐", "SubsetEqual;", "⊆", "Succeeds;", "≻", "SucceedsEqual;", "⪰", "SucceedsSlantEqual;", "≽", "SucceedsTilde;", "≿", "SuchThat;", "∋", "Sum;", "∑", "Sup;", "⋑", "Superset;", "⊃", "SupersetEqual;", "⊇", "Supset;", "⋑", "THORN", "Þ", "THORN;", "Þ", "TRADE;", "™", "TSHcy;", "Ћ", "TScy;", "Ц", "Tab;", "\t", "Tau;", "Τ", "Tcaron;", "Ť", "Tcedil;", "Ţ", "Tcy;", "Т", "Tfr;", "𝔗", "Therefore;", "∴", "Theta;", "Θ", "ThickSpace;", " ", "ThinSpace;", " ", "Tilde;", "∼", "TildeEqual;", "≃", "TildeFullEqual;", "≅", "TildeTilde;", "≈", "Topf;", "𝕋", "TripleDot;", "⃛", "Tscr;", "𝒯", "Tstrok;", "Ŧ", "Uacute", "Ú", "Uacute;", "Ú", "Uarr;", "↟", "Uarrocir;", "⥉", "Ubrcy;", "Ў", "Ubreve;", "Ŭ", "Ucirc", "Û", "Ucirc;", "Û", "Ucy;", "У", "Udblac;", "Ű", "Ufr;", "𝔘", "Ugrave", "Ù", "Ugrave;", "Ù", "Umacr;", "Ū", "UnderBar;", "_", "UnderBrace;", "⏟", "UnderBracket;", "⎵", "UnderParenthesis;", "⏝", "Union;", "⋃", "UnionPlus;", "⊎", "Uogon;", "Ų", "Uopf;", "𝕌", "UpArrow;", "↑", "UpArrowBar;", "⤒", "UpArrowDownArrow;", "⇅", "UpDownArrow;", "↕", "UpEquilibrium;", "⥮", "UpTee;", "⊥", "UpTeeArrow;", "↥", "Uparrow;", "⇑", "Updownarrow;", "⇕", "UpperLeftArrow;", "↖", "UpperRightArrow;", "↗", "Upsi;", "ϒ", "Upsilon;", "Υ", "Uring;", "Ů", "Uscr;", "𝒰", "Utilde;", "Ũ", "Uuml", "Ü", "Uuml;", "Ü", "VDash;", "⊫", "Vbar;", "⫫", "Vcy;", "В", "Vdash;", "⊩", "Vdashl;", "⫦", "Vee;", "⋁", "Verbar;", "‖", "Vert;", "‖", "VerticalBar;", "∣", "VerticalLine;", "|", "VerticalSeparator;", "❘", "VerticalTilde;", "≀", "VeryThinSpace;", " ", "Vfr;", "𝔙", "Vopf;", "𝕍", "Vscr;", "𝒱", "Vvdash;", "⊪", "Wcirc;", "Ŵ", "Wedge;", "⋀", "Wfr;", "𝔚", "Wopf;", "𝕎", "Wscr;", "𝒲", "Xfr;", "𝔛", "Xi;", "Ξ", "Xopf;", "𝕏", "Xscr;", "𝒳", "YAcy;", "Я", "YIcy;", "Ї", "YUcy;", "Ю", "Yacute", "Ý", "Yacute;", "Ý", "Ycirc;", "Ŷ", "Ycy;", "Ы", "Yfr;", "𝔜", "Yopf;", "𝕐", "Yscr;", "𝒴", "Yuml;", "Ÿ", "ZHcy;", "Ж", "Zacute;", "Ź", "Zcaron;", "Ž", "Zcy;", "З", "Zdot;", "Ż", "ZeroWidthSpace;", "", "Zeta;", "Ζ", "Zfr;", "ℨ", "Zopf;", "ℤ", "Zscr;", "𝒵", "aacute", "á", "aacute;", "á", "abreve;", "ă", "ac;", "∾", "acE;", "∾̳", "acd;", "∿", "acirc", "â", "acirc;", "â", "acute", "´", "acute;", "´", "acy;", "а", "aelig", "æ", "aelig;", "æ", "af;", "", "afr;", "𝔞", "agrave", "à", "agrave;", "à", "alefsym;", "ℵ", "aleph;", "ℵ", "alpha;", "α", "amacr;", "ā", "amalg;", "⨿", "amp", "&", "amp;", "&", "and;", "∧", "andand;", "⩕", "andd;", "⩜", "andslope;", "⩘", "andv;", "⩚", "ang;", "∠", "ange;", "⦤", "angle;", "∠", "angmsd;", "∡", "angmsdaa;", "⦨", "angmsdab;", "⦩", "angmsdac;", "⦪", "angmsdad;", "⦫", "angmsdae;", "⦬", "angmsdaf;", "⦭", "angmsdag;", "⦮", "angmsdah;", "⦯", "angrt;", "∟", "angrtvb;", "⊾", "angrtvbd;", "⦝", "angsph;", "∢", "angst;", "Å", "angzarr;", "⍼", "aogon;", "ą", "aopf;", "𝕒", "ap;", "≈", "apE;", "⩰", "apacir;", "⩯", "ape;", "≊", "apid;", "≋", "apos;", "'", "approx;", "≈", "approxeq;", "≊", "aring", "å", "aring;", "å", "ascr;", "𝒶", "ast;", "*", "asymp;", "≈", "asympeq;", "≍", "atilde", "ã", "atilde;", "ã", "auml", "ä", "auml;", "ä", "awconint;", "∳", "awint;", "⨑", "bNot;", "⫭", "backcong;", "≌", "backepsilon;", "϶", "backprime;", "‵", "backsim;", "∽", "backsimeq;", "⋍", "barvee;", "⊽", "barwed;", "⌅", "barwedge;", "⌅", "bbrk;", "⎵", "bbrktbrk;", "⎶", "bcong;", "≌", "bcy;", "б", "bdquo;", "„", "becaus;", "∵", "because;", "∵", "bemptyv;", "⦰", "bepsi;", "϶", "bernou;", "ℬ", "beta;", "β", "beth;", "ℶ", "between;", "≬", "bfr;", "𝔟", "bigcap;", "⋂", "bigcirc;", "◯", "bigcup;", "⋃", "bigodot;", "⨀", "bigoplus;", "⨁", "bigotimes;", "⨂", "bigsqcup;", "⨆", "bigstar;", "★", "bigtriangledown;", "▽", "bigtriangleup;", "△", "biguplus;", "⨄", "bigvee;", "⋁", "bigwedge;", "⋀", "bkarow;", "⤍", "blacklozenge;", "⧫", "blacksquare;", "▪", "blacktriangle;", "▴", "blacktriangledown;", "▾", "blacktriangleleft;", "◂", "blacktriangleright;", "▸", "blank;", "␣", "blk12;", "▒", "blk14;", "░", "blk34;", "▓", "block;", "█", "bne;", "=⃥", "bnequiv;", "≡⃥", "bnot;", "⌐", "bopf;", "𝕓", "bot;", "⊥", "bottom;", "⊥", "bowtie;", "⋈", "boxDL;", "╗", "boxDR;", "╔", "boxDl;", "╖", "boxDr;", "╓", "boxH;", "═", "boxHD;", "╦", "boxHU;", "╩", "boxHd;", "╤", "boxHu;", "╧", "boxUL;", "╝", "boxUR;", "╚", "boxUl;", "╜", "boxUr;", "╙", "boxV;", "║", "boxVH;", "╬", "boxVL;", "╣", "boxVR;", "╠", "boxVh;", "╫", "boxVl;", "╢", "boxVr;", "╟", "boxbox;", "⧉", "boxdL;", "╕", "boxdR;", "╒", "boxdl;", "┐", "boxdr;", "┌", "boxh;", "─", "boxhD;", "╥", "boxhU;", "╨", "boxhd;", "┬", "boxhu;", "┴", "boxminus;", "⊟", "boxplus;", "⊞", "boxtimes;", "⊠", "boxuL;", "╛", "boxuR;", "╘", "boxul;", "┘", "boxur;", "└", "boxv;", "│", "boxvH;", "╪", "boxvL;", "╡", "boxvR;", "╞", "boxvh;", "┼", "boxvl;", "┤", "boxvr;", "├", "bprime;", "‵", "breve;", "˘", "brvbar", "¦", "brvbar;", "¦", "bscr;", "𝒷", "bsemi;", "⁏", "bsim;", "∽", "bsime;", "⋍", "bsol;", "\\", "bsolb;", "⧅", "bsolhsub;", "⟈", "bull;", "•", "bullet;", "•", "bump;", "≎", "bumpE;", "⪮", "bumpe;", "≏", "bumpeq;", "≏", "cacute;", "ć", "cap;", "∩", "capand;", "⩄", "capbrcup;", "⩉", "capcap;", "⩋", "capcup;", "⩇", "capdot;", "⩀", "caps;", "∩︀", "caret;", "⁁", "caron;", "ˇ", "ccaps;", "⩍", "ccaron;", "č", "ccedil", "ç", "ccedil;", "ç", "ccirc;", "ĉ", "ccups;", "⩌", "ccupssm;", "⩐", "cdot;", "ċ", "cedil", "¸", "cedil;", "¸", "cemptyv;", "⦲", "cent", "¢", "cent;", "¢", "centerdot;", "·", "cfr;", "𝔠", "chcy;", "ч", "check;", "✓", "checkmark;", "✓", "chi;", "χ", "cir;", "○", "cirE;", "⧃", "circ;", "ˆ", "circeq;", "≗", "circlearrowleft;", "↺", "circlearrowright;", "↻", "circledR;", "®", "circledS;", "Ⓢ", "circledast;", "⊛", "circledcirc;", "⊚", "circleddash;", "⊝", "cire;", "≗", "cirfnint;", "⨐", "cirmid;", "⫯", "cirscir;", "⧂", "clubs;", "♣", "clubsuit;", "♣", "colon;", ":", "colone;", "≔", "coloneq;", "≔", "comma;", ",", "commat;", "@", "comp;", "∁", "compfn;", "∘", "complement;", "∁", "complexes;", "ℂ", "cong;", "≅", "congdot;", "⩭", "conint;", "∮", "copf;", "𝕔", "coprod;", "∐", "copy", "©", "copy;", "©", "copysr;", "℗", "crarr;", "↵", "cross;", "✗", "cscr;", "𝒸", "csub;", "⫏", "csube;", "⫑", "csup;", "⫐", "csupe;", "⫒", "ctdot;", "⋯", "cudarrl;", "⤸", "cudarrr;", "⤵", "cuepr;", "⋞", "cuesc;", "⋟", "cularr;", "↶", "cularrp;", "⤽", "cup;", "∪", "cupbrcap;", "⩈", "cupcap;", "⩆", "cupcup;", "⩊", "cupdot;", "⊍", "cupor;", "⩅", "cups;", "∪︀", "curarr;", "↷", "curarrm;", "⤼", "curlyeqprec;", "⋞", "curlyeqsucc;", "⋟", "curlyvee;", "⋎", "curlywedge;", "⋏", "curren", "¤", "curren;", "¤", "curvearrowleft;", "↶", "curvearrowright;", "↷", "cuvee;", "⋎", "cuwed;", "⋏", "cwconint;", "∲", "cwint;", "∱", "cylcty;", "⌭", "dArr;", "⇓", "dHar;", "⥥", "dagger;", "†", "daleth;", "ℸ", "darr;", "↓", "dash;", "‐", "dashv;", "⊣", "dbkarow;", "⤏", "dblac;", "˝", "dcaron;", "ď", "dcy;", "д", "dd;", "ⅆ", "ddagger;", "‡", "ddarr;", "⇊", "ddotseq;", "⩷", "deg", "°", "deg;", "°", "delta;", "δ", "demptyv;", "⦱", "dfisht;", "⥿", "dfr;", "𝔡", "dharl;", "⇃", "dharr;", "⇂", "diam;", "⋄", "diamond;", "⋄", "diamondsuit;", "♦", "diams;", "♦", "die;", "¨", "digamma;", "ϝ", "disin;", "⋲", "div;", "÷", "divide", "÷", "divide;", "÷", "divideontimes;", "⋇", "divonx;", "⋇", "djcy;", "ђ", "dlcorn;", "⌞", "dlcrop;", "⌍", "dollar;", "$", "dopf;", "𝕕", "dot;", "˙", "doteq;", "≐", "doteqdot;", "≑", "dotminus;", "∸", "dotplus;", "∔", "dotsquare;", "⊡", "doublebarwedge;", "⌆", "downarrow;", "↓", "downdownarrows;", "⇊", "downharpoonleft;", "⇃", "downharpoonright;", "⇂", "drbkarow;", "⤐", "drcorn;", "⌟", "drcrop;", "⌌", "dscr;", "𝒹", "dscy;", "ѕ", "dsol;", "⧶", "dstrok;", "đ", "dtdot;", "⋱", "dtri;", "▿", "dtrif;", "▾", "duarr;", "⇵", "duhar;", "⥯", "dwangle;", "⦦", "dzcy;", "џ", "dzigrarr;", "⟿", "eDDot;", "⩷", "eDot;", "≑", "eacute", "é", "eacute;", "é", "easter;", "⩮", "ecaron;", "ě", "ecir;", "≖", "ecirc", "ê", "ecirc;", "ê", "ecolon;", "≕", "ecy;", "э", "edot;", "ė", "ee;", "ⅇ", "efDot;", "≒", "efr;", "𝔢", "eg;", "⪚", "egrave", "è", "egrave;", "è", "egs;", "⪖", "egsdot;", "⪘", "el;", "⪙", "elinters;", "⏧", "ell;", "ℓ", "els;", "⪕", "elsdot;", "⪗", "emacr;", "ē", "empty;", "∅", "emptyset;", "∅", "emptyv;", "∅", "emsp13;", " ", "emsp14;", " ", "emsp;", " ", "eng;", "ŋ", "ensp;", " ", "eogon;", "ę", "eopf;", "𝕖", "epar;", "⋕", "eparsl;", "⧣", "eplus;", "⩱", "epsi;", "ε", "epsilon;", "ε", "epsiv;", "ϵ", "eqcirc;", "≖", "eqcolon;", "≕", "eqsim;", "≂", "eqslantgtr;", "⪖", "eqslantless;", "⪕", "equals;", "=", "equest;", "≟", "equiv;", "≡", "equivDD;", "⩸", "eqvparsl;", "⧥", "erDot;", "≓", "erarr;", "⥱", "escr;", "ℯ", "esdot;", "≐", "esim;", "≂", "eta;", "η", "eth", "ð", "eth;", "ð", "euml", "ë", "euml;", "ë", "euro;", "€", "excl;", "!", "exist;", "∃", "expectation;", "ℰ", "exponentiale;", "ⅇ", "fallingdotseq;", "≒", "fcy;", "ф", "female;", "♀", "ffilig;", "ffi", "fflig;", "ff", "ffllig;", "ffl", "ffr;", "𝔣", "filig;", "fi", "fjlig;", "fj", "flat;", "♭", "fllig;", "fl", "fltns;", "▱", "fnof;", "ƒ", "fopf;", "𝕗", "forall;", "∀", "fork;", "⋔", "forkv;", "⫙", "fpartint;", "⨍", "frac12", "½", "frac12;", "½", "frac13;", "⅓", "frac14", "¼", "frac14;", "¼", "frac15;", "⅕", "frac16;", "⅙", "frac18;", "⅛", "frac23;", "⅔", "frac25;", "⅖", "frac34", "¾", "frac34;", "¾", "frac35;", "⅗", "frac38;", "⅜", "frac45;", "⅘", "frac56;", "⅚", "frac58;", "⅝", "frac78;", "⅞", "frasl;", "⁄", "frown;", "⌢", "fscr;", "𝒻", "gE;", "≧", "gEl;", "⪌", "gacute;", "ǵ", "gamma;", "γ", "gammad;", "ϝ", "gap;", "⪆", "gbreve;", "ğ", "gcirc;", "ĝ", "gcy;", "г", "gdot;", "ġ", "ge;", "≥", "gel;", "⋛", "geq;", "≥", "geqq;", "≧", "geqslant;", "⩾", "ges;", "⩾", "gescc;", "⪩", "gesdot;", "⪀", "gesdoto;", "⪂", "gesdotol;", "⪄", "gesl;", "⋛︀", "gesles;", "⪔", "gfr;", "𝔤", "gg;", "≫", "ggg;", "⋙", "gimel;", "ℷ", "gjcy;", "ѓ", "gl;", "≷", "glE;", "⪒", "gla;", "⪥", "glj;", "⪤", "gnE;", "≩", "gnap;", "⪊", "gnapprox;", "⪊", "gne;", "⪈", "gneq;", "⪈", "gneqq;", "≩", "gnsim;", "⋧", "gopf;", "𝕘", "grave;", "`", "gscr;", "ℊ", "gsim;", "≳", "gsime;", "⪎", "gsiml;", "⪐", "gt", ">", "gt;", ">", "gtcc;", "⪧", "gtcir;", "⩺", "gtdot;", "⋗", "gtlPar;", "⦕", "gtquest;", "⩼", "gtrapprox;", "⪆", "gtrarr;", "⥸", "gtrdot;", "⋗", "gtreqless;", "⋛", "gtreqqless;", "⪌", "gtrless;", "≷", "gtrsim;", "≳", "gvertneqq;", "≩︀", "gvnE;", "≩︀", "hArr;", "⇔", "hairsp;", " ", "half;", "½", "hamilt;", "ℋ", "hardcy;", "ъ", "harr;", "↔", "harrcir;", "⥈", "harrw;", "↭", "hbar;", "ℏ", "hcirc;", "ĥ", "hearts;", "♥", "heartsuit;", "♥", "hellip;", "…", "hercon;", "⊹", "hfr;", "𝔥", "hksearow;", "⤥", "hkswarow;", "⤦", "hoarr;", "⇿", "homtht;", "∻", "hookleftarrow;", "↩", "hookrightarrow;", "↪", "hopf;", "𝕙", "horbar;", "―", "hscr;", "𝒽", "hslash;", "ℏ", "hstrok;", "ħ", "hybull;", "⁃", "hyphen;", "‐", "iacute", "í", "iacute;", "í", "ic;", "", "icirc", "î", "icirc;", "î", "icy;", "и", "iecy;", "е", "iexcl", "¡", "iexcl;", "¡", "iff;", "⇔", "ifr;", "𝔦", "igrave", "ì", "igrave;", "ì", "ii;", "ⅈ", "iiiint;", "⨌", "iiint;", "∭", "iinfin;", "⧜", "iiota;", "℩", "ijlig;", "ij", "imacr;", "ī", "image;", "ℑ", "imagline;", "ℐ", "imagpart;", "ℑ", "imath;", "ı", "imof;", "⊷", "imped;", "Ƶ", "in;", "∈", "incare;", "℅", "infin;", "∞", "infintie;", "⧝", "inodot;", "ı", "int;", "∫", "intcal;", "⊺", "integers;", "ℤ", "intercal;", "⊺", "intlarhk;", "⨗", "intprod;", "⨼", "iocy;", "ё", "iogon;", "į", "iopf;", "𝕚", "iota;", "ι", "iprod;", "⨼", "iquest", "¿", "iquest;", "¿", "iscr;", "𝒾", "isin;", "∈", "isinE;", "⋹", "isindot;", "⋵", "isins;", "⋴", "isinsv;", "⋳", "isinv;", "∈", "it;", "", "itilde;", "ĩ", "iukcy;", "і", "iuml", "ï", "iuml;", "ï", "jcirc;", "ĵ", "jcy;", "й", "jfr;", "𝔧", "jmath;", "ȷ", "jopf;", "𝕛", "jscr;", "𝒿", "jsercy;", "ј", "jukcy;", "є", "kappa;", "κ", "kappav;", "ϰ", "kcedil;", "ķ", "kcy;", "к", "kfr;", "𝔨", "kgreen;", "ĸ", "khcy;", "х", "kjcy;", "ќ", "kopf;", "𝕜", "kscr;", "𝓀", "lAarr;", "⇚", "lArr;", "⇐", "lAtail;", "⤛", "lBarr;", "⤎", "lE;", "≦", "lEg;", "⪋", "lHar;", "⥢", "lacute;", "ĺ", "laemptyv;", "⦴", "lagran;", "ℒ", "lambda;", "λ", "lang;", "⟨", "langd;", "⦑", "langle;", "⟨", "lap;", "⪅", "laquo", "«", "laquo;", "«", "larr;", "←", "larrb;", "⇤", "larrbfs;", "⤟", "larrfs;", "⤝", "larrhk;", "↩", "larrlp;", "↫", "larrpl;", "⤹", "larrsim;", "⥳", "larrtl;", "↢", "lat;", "⪫", "latail;", "⤙", "late;", "⪭", "lates;", "⪭︀", "lbarr;", "⤌", "lbbrk;", "❲", "lbrace;", "{", "lbrack;", "[", "lbrke;", "⦋", "lbrksld;", "⦏", "lbrkslu;", "⦍", "lcaron;", "ľ", "lcedil;", "ļ", "lceil;", "⌈", "lcub;", "{", "lcy;", "л", "ldca;", "⤶", "ldquo;", "“", "ldquor;", "„", "ldrdhar;", "⥧", "ldrushar;", "⥋", "ldsh;", "↲", "le;", "≤", "leftarrow;", "←", "leftarrowtail;", "↢", "leftharpoondown;", "↽", "leftharpoonup;", "↼", "leftleftarrows;", "⇇", "leftrightarrow;", "↔", "leftrightarrows;", "⇆", "leftrightharpoons;", "⇋", "leftrightsquigarrow;", "↭", "leftthreetimes;", "⋋", "leg;", "⋚", "leq;", "≤", "leqq;", "≦", "leqslant;", "⩽", "les;", "⩽", "lescc;", "⪨", "lesdot;", "⩿", "lesdoto;", "⪁", "lesdotor;", "⪃", "lesg;", "⋚︀", "lesges;", "⪓", "lessapprox;", "⪅", "lessdot;", "⋖", "lesseqgtr;", "⋚", "lesseqqgtr;", "⪋", "lessgtr;", "≶", "lesssim;", "≲", "lfisht;", "⥼", "lfloor;", "⌊", "lfr;", "𝔩", "lg;", "≶", "lgE;", "⪑", "lhard;", "↽", "lharu;", "↼", "lharul;", "⥪", "lhblk;", "▄", "ljcy;", "љ", "ll;", "≪", "llarr;", "⇇", "llcorner;", "⌞", "llhard;", "⥫", "lltri;", "◺", "lmidot;", "ŀ", "lmoust;", "⎰", "lmoustache;", "⎰", "lnE;", "≨", "lnap;", "⪉", "lnapprox;", "⪉", "lne;", "⪇", "lneq;", "⪇", "lneqq;", "≨", "lnsim;", "⋦", "loang;", "⟬", "loarr;", "⇽", "lobrk;", "⟦", "longleftarrow;", "⟵", "longleftrightarrow;", "⟷", "longmapsto;", "⟼", "longrightarrow;", "⟶", "looparrowleft;", "↫", "looparrowright;", "↬", "lopar;", "⦅", "lopf;", "𝕝", "loplus;", "⨭", "lotimes;", "⨴", "lowast;", "∗", "lowbar;", "_", "loz;", "◊", "lozenge;", "◊", "lozf;", "⧫", "lpar;", "(", "lparlt;", "⦓", "lrarr;", "⇆", "lrcorner;", "⌟", "lrhar;", "⇋", "lrhard;", "⥭", "lrm;", "", "lrtri;", "⊿", "lsaquo;", "‹", "lscr;", "𝓁", "lsh;", "↰", "lsim;", "≲", "lsime;", "⪍", "lsimg;", "⪏", "lsqb;", "[", "lsquo;", "‘", "lsquor;", "‚", "lstrok;", "ł", "lt", "<", "lt;", "<", "ltcc;", "⪦", "ltcir;", "⩹", "ltdot;", "⋖", "lthree;", "⋋", "ltimes;", "⋉", "ltlarr;", "⥶", "ltquest;", "⩻", "ltrPar;", "⦖", "ltri;", "◃", "ltrie;", "⊴", "ltrif;", "◂", "lurdshar;", "⥊", "luruhar;", "⥦", "lvertneqq;", "≨︀", "lvnE;", "≨︀", "mDDot;", "∺", "macr", "¯", "macr;", "¯", "male;", "♂", "malt;", "✠", "maltese;", "✠", "map;", "↦", "mapsto;", "↦", "mapstodown;", "↧", "mapstoleft;", "↤", "mapstoup;", "↥", "marker;", "▮", "mcomma;", "⨩", "mcy;", "м", "mdash;", "—", "measuredangle;", "∡", "mfr;", "𝔪", "mho;", "℧", "micro", "µ", "micro;", "µ", "mid;", "∣", "midast;", "*", "midcir;", "⫰", "middot", "·", "middot;", "·", "minus;", "−", "minusb;", "⊟", "minusd;", "∸", "minusdu;", "⨪", "mlcp;", "⫛", "mldr;", "…", "mnplus;", "∓", "models;", "⊧", "mopf;", "𝕞", "mp;", "∓", "mscr;", "𝓂", "mstpos;", "∾", "mu;", "μ", "multimap;", "⊸", "mumap;", "⊸", "nGg;", "⋙̸", "nGt;", "≫⃒", "nGtv;", "≫̸", "nLeftarrow;", "⇍", "nLeftrightarrow;", "⇎", "nLl;", "⋘̸", "nLt;", "≪⃒", "nLtv;", "≪̸", "nRightarrow;", "⇏", "nVDash;", "⊯", "nVdash;", "⊮", "nabla;", "∇", "nacute;", "ń", "nang;", "∠⃒", "nap;", "≉", "napE;", "⩰̸", "napid;", "≋̸", "napos;", "ʼn", "napprox;", "≉", "natur;", "♮", "natural;", "♮", "naturals;", "ℕ", "nbsp", " ", "nbsp;", " ", "nbump;", "≎̸", "nbumpe;", "≏̸", "ncap;", "⩃", "ncaron;", "ň", "ncedil;", "ņ", "ncong;", "≇", "ncongdot;", "⩭̸", "ncup;", "⩂", "ncy;", "н", "ndash;", "–", "ne;", "≠", "neArr;", "⇗", "nearhk;", "⤤", "nearr;", "↗", "nearrow;", "↗", "nedot;", "≐̸", "nequiv;", "≢", "nesear;", "⤨", "nesim;", "≂̸", "nexist;", "∄", "nexists;", "∄", "nfr;", "𝔫", "ngE;", "≧̸", "nge;", "≱", "ngeq;", "≱", "ngeqq;", "≧̸", "ngeqslant;", "⩾̸", "nges;", "⩾̸", "ngsim;", "≵", "ngt;", "≯", "ngtr;", "≯", "nhArr;", "⇎", "nharr;", "↮", "nhpar;", "⫲", "ni;", "∋", "nis;", "⋼", "nisd;", "⋺", "niv;", "∋", "njcy;", "њ", "nlArr;", "⇍", "nlE;", "≦̸", "nlarr;", "↚", "nldr;", "‥", "nle;", "≰", "nleftarrow;", "↚", "nleftrightarrow;", "↮", "nleq;", "≰", "nleqq;", "≦̸", "nleqslant;", "⩽̸", "nles;", "⩽̸", "nless;", "≮", "nlsim;", "≴", "nlt;", "≮", "nltri;", "⋪", "nltrie;", "⋬", "nmid;", "∤", "nopf;", "𝕟", "not", "¬", "not;", "¬", "notin;", "∉", "notinE;", "⋹̸", "notindot;", "⋵̸", "notinva;", "∉", "notinvb;", "⋷", "notinvc;", "⋶", "notni;", "∌", "notniva;", "∌", "notnivb;", "⋾", "notnivc;", "⋽", "npar;", "∦", "nparallel;", "∦", "nparsl;", "⫽⃥", "npart;", "∂̸", "npolint;", "⨔", "npr;", "⊀", "nprcue;", "⋠", "npre;", "⪯̸", "nprec;", "⊀", "npreceq;", "⪯̸", "nrArr;", "⇏", "nrarr;", "↛", "nrarrc;", "⤳̸", "nrarrw;", "↝̸", "nrightarrow;", "↛", "nrtri;", "⋫", "nrtrie;", "⋭", "nsc;", "⊁", "nsccue;", "⋡", "nsce;", "⪰̸", "nscr;", "𝓃", "nshortmid;", "∤", "nshortparallel;", "∦", "nsim;", "≁", "nsime;", "≄", "nsimeq;", "≄", "nsmid;", "∤", "nspar;", "∦", "nsqsube;", "⋢", "nsqsupe;", "⋣", "nsub;", "⊄", "nsubE;", "⫅̸", "nsube;", "⊈", "nsubset;", "⊂⃒", "nsubseteq;", "⊈", "nsubseteqq;", "⫅̸", "nsucc;", "⊁", "nsucceq;", "⪰̸", "nsup;", "⊅", "nsupE;", "⫆̸", "nsupe;", "⊉", "nsupset;", "⊃⃒", "nsupseteq;", "⊉", "nsupseteqq;", "⫆̸", "ntgl;", "≹", "ntilde", "ñ", "ntilde;", "ñ", "ntlg;", "≸", "ntriangleleft;", "⋪", "ntrianglelefteq;", "⋬", "ntriangleright;", "⋫", "ntrianglerighteq;", "⋭", "nu;", "ν", "num;", "#", "numero;", "№", "numsp;", " ", "nvDash;", "⊭", "nvHarr;", "⤄", "nvap;", "≍⃒", "nvdash;", "⊬", "nvge;", "≥⃒", "nvgt;", ">⃒", "nvinfin;", "⧞", "nvlArr;", "⤂", "nvle;", "≤⃒", "nvlt;", "<⃒", "nvltrie;", "⊴⃒", "nvrArr;", "⤃", "nvrtrie;", "⊵⃒", "nvsim;", "∼⃒", "nwArr;", "⇖", "nwarhk;", "⤣", "nwarr;", "↖", "nwarrow;", "↖", "nwnear;", "⤧", "oS;", "Ⓢ", "oacute", "ó", "oacute;", "ó", "oast;", "⊛", "ocir;", "⊚", "ocirc", "ô", "ocirc;", "ô", "ocy;", "о", "odash;", "⊝", "odblac;", "ő", "odiv;", "⨸", "odot;", "⊙", "odsold;", "⦼", "oelig;", "œ", "ofcir;", "⦿", "ofr;", "𝔬", "ogon;", "˛", "ograve", "ò", "ograve;", "ò", "ogt;", "⧁", "ohbar;", "⦵", "ohm;", "Ω", "oint;", "∮", "olarr;", "↺", "olcir;", "⦾", "olcross;", "⦻", "oline;", "‾", "olt;", "⧀", "omacr;", "ō", "omega;", "ω", "omicron;", "ο", "omid;", "⦶", "ominus;", "⊖", "oopf;", "𝕠", "opar;", "⦷", "operp;", "⦹", "oplus;", "⊕", "or;", "∨", "orarr;", "↻", "ord;", "⩝", "order;", "ℴ", "orderof;", "ℴ", "ordf", "ª", "ordf;", "ª", "ordm", "º", "ordm;", "º", "origof;", "⊶", "oror;", "⩖", "orslope;", "⩗", "orv;", "⩛", "oscr;", "ℴ", "oslash", "ø", "oslash;", "ø", "osol;", "⊘", "otilde", "õ", "otilde;", "õ", "otimes;", "⊗", "otimesas;", "⨶", "ouml", "ö", "ouml;", "ö", "ovbar;", "⌽", "par;", "∥", "para", "¶", "para;", "¶", "parallel;", "∥", "parsim;", "⫳", "parsl;", "⫽", "part;", "∂", "pcy;", "п", "percnt;", "%", "period;", ".", "permil;", "‰", "perp;", "⊥", "pertenk;", "‱", "pfr;", "𝔭", "phi;", "φ", "phiv;", "ϕ", "phmmat;", "ℳ", "phone;", "☎", "pi;", "π", "pitchfork;", "⋔", "piv;", "ϖ", "planck;", "ℏ", "planckh;", "ℎ", "plankv;", "ℏ", "plus;", "+", "plusacir;", "⨣", "plusb;", "⊞", "pluscir;", "⨢", "plusdo;", "∔", "plusdu;", "⨥", "pluse;", "⩲", "plusmn", "±", "plusmn;", "±", "plussim;", "⨦", "plustwo;", "⨧", "pm;", "±", "pointint;", "⨕", "popf;", "𝕡", "pound", "£", "pound;", "£", "pr;", "≺", "prE;", "⪳", "prap;", "⪷", "prcue;", "≼", "pre;", "⪯", "prec;", "≺", "precapprox;", "⪷", "preccurlyeq;", "≼", "preceq;", "⪯", "precnapprox;", "⪹", "precneqq;", "⪵", "precnsim;", "⋨", "precsim;", "≾", "prime;", "′", "primes;", "ℙ", "prnE;", "⪵", "prnap;", "⪹", "prnsim;", "⋨", "prod;", "∏", "profalar;", "⌮", "profline;", "⌒", "profsurf;", "⌓", "prop;", "∝", "propto;", "∝", "prsim;", "≾", "prurel;", "⊰", "pscr;", "𝓅", "psi;", "ψ", "puncsp;", " ", "qfr;", "𝔮", "qint;", "⨌", "qopf;", "𝕢", "qprime;", "⁗", "qscr;", "𝓆", "quaternions;", "ℍ", "quatint;", "⨖", "quest;", "?", "questeq;", "≟", "quot", "\"", "quot;", "\"", "rAarr;", "⇛", "rArr;", "⇒", "rAtail;", "⤜", "rBarr;", "⤏", "rHar;", "⥤", "race;", "∽̱", "racute;", "ŕ", "radic;", "√", "raemptyv;", "⦳", "rang;", "⟩", "rangd;", "⦒", "range;", "⦥", "rangle;", "⟩", "raquo", "»", "raquo;", "»", "rarr;", "→", "rarrap;", "⥵", "rarrb;", "⇥", "rarrbfs;", "⤠", "rarrc;", "⤳", "rarrfs;", "⤞", "rarrhk;", "↪", "rarrlp;", "↬", "rarrpl;", "⥅", "rarrsim;", "⥴", "rarrtl;", "↣", "rarrw;", "↝", "ratail;", "⤚", "ratio;", "∶", "rationals;", "ℚ", "rbarr;", "⤍", "rbbrk;", "❳", "rbrace;", "}", "rbrack;", "]", "rbrke;", "⦌", "rbrksld;", "⦎", "rbrkslu;", "⦐", "rcaron;", "ř", "rcedil;", "ŗ", "rceil;", "⌉", "rcub;", "}", "rcy;", "р", "rdca;", "⤷", "rdldhar;", "⥩", "rdquo;", "”", "rdquor;", "”", "rdsh;", "↳", "real;", "ℜ", "realine;", "ℛ", "realpart;", "ℜ", "reals;", "ℝ", "rect;", "▭", "reg", "®", "reg;", "®", "rfisht;", "⥽", "rfloor;", "⌋", "rfr;", "𝔯", "rhard;", "⇁", "rharu;", "⇀", "rharul;", "⥬", "rho;", "ρ", "rhov;", "ϱ", "rightarrow;", "→", "rightarrowtail;", "↣", "rightharpoondown;", "⇁", "rightharpoonup;", "⇀", "rightleftarrows;", "⇄", "rightleftharpoons;", "⇌", "rightrightarrows;", "⇉", "rightsquigarrow;", "↝", "rightthreetimes;", "⋌", "ring;", "˚", "risingdotseq;", "≓", "rlarr;", "⇄", "rlhar;", "⇌", "rlm;", "", "rmoust;", "⎱", "rmoustache;", "⎱", "rnmid;", "⫮", "roang;", "⟭", "roarr;", "⇾", "robrk;", "⟧", "ropar;", "⦆", "ropf;", "𝕣", "roplus;", "⨮", "rotimes;", "⨵", "rpar;", ")", "rpargt;", "⦔", "rppolint;", "⨒", "rrarr;", "⇉", "rsaquo;", "›", "rscr;", "𝓇", "rsh;", "↱", "rsqb;", "]", "rsquo;", "’", "rsquor;", "’", "rthree;", "⋌", "rtimes;", "⋊", "rtri;", "▹", "rtrie;", "⊵", "rtrif;", "▸", "rtriltri;", "⧎", "ruluhar;", "⥨", "rx;", "℞", "sacute;", "ś", "sbquo;", "‚", "sc;", "≻", "scE;", "⪴", "scap;", "⪸", "scaron;", "š", "sccue;", "≽", "sce;", "⪰", "scedil;", "ş", "scirc;", "ŝ", "scnE;", "⪶", "scnap;", "⪺", "scnsim;", "⋩", "scpolint;", "⨓", "scsim;", "≿", "scy;", "с", "sdot;", "⋅", "sdotb;", "⊡", "sdote;", "⩦", "seArr;", "⇘", "searhk;", "⤥", "searr;", "↘", "searrow;", "↘", "sect", "§", "sect;", "§", "semi;", ";", "seswar;", "⤩", "setminus;", "∖", "setmn;", "∖", "sext;", "✶", "sfr;", "𝔰", "sfrown;", "⌢", "sharp;", "♯", "shchcy;", "щ", "shcy;", "ш", "shortmid;", "∣", "shortparallel;", "∥", "shy", "", "shy;", "", "sigma;", "σ", "sigmaf;", "ς", "sigmav;", "ς", "sim;", "∼", "simdot;", "⩪", "sime;", "≃", "simeq;", "≃", "simg;", "⪞", "simgE;", "⪠", "siml;", "⪝", "simlE;", "⪟", "simne;", "≆", "simplus;", "⨤", "simrarr;", "⥲", "slarr;", "←", "smallsetminus;", "∖", "smashp;", "⨳", "smeparsl;", "⧤", "smid;", "∣", "smile;", "⌣", "smt;", "⪪", "smte;", "⪬", "smtes;", "⪬︀", "softcy;", "ь", "sol;", "/", "solb;", "⧄", "solbar;", "⌿", "sopf;", "𝕤", "spades;", "♠", "spadesuit;", "♠", "spar;", "∥", "sqcap;", "⊓", "sqcaps;", "⊓︀", "sqcup;", "⊔", "sqcups;", "⊔︀", "sqsub;", "⊏", "sqsube;", "⊑", "sqsubset;", "⊏", "sqsubseteq;", "⊑", "sqsup;", "⊐", "sqsupe;", "⊒", "sqsupset;", "⊐", "sqsupseteq;", "⊒", "squ;", "□", "square;", "□", "squarf;", "▪", "squf;", "▪", "srarr;", "→", "sscr;", "𝓈", "ssetmn;", "∖", "ssmile;", "⌣", "sstarf;", "⋆", "star;", "☆", "starf;", "★", "straightepsilon;", "ϵ", "straightphi;", "ϕ", "strns;", "¯", "sub;", "⊂", "subE;", "⫅", "subdot;", "⪽", "sube;", "⊆", "subedot;", "⫃", "submult;", "⫁", "subnE;", "⫋", "subne;", "⊊", "subplus;", "⪿", "subrarr;", "⥹", "subset;", "⊂", "subseteq;", "⊆", "subseteqq;", "⫅", "subsetneq;", "⊊", "subsetneqq;", "⫋", "subsim;", "⫇", "subsub;", "⫕", "subsup;", "⫓", "succ;", "≻", "succapprox;", "⪸", "succcurlyeq;", "≽", "succeq;", "⪰", "succnapprox;", "⪺", "succneqq;", "⪶", "succnsim;", "⋩", "succsim;", "≿", "sum;", "∑", "sung;", "♪", "sup1", "¹", "sup1;", "¹", "sup2", "²", "sup2;", "²", "sup3", "³", "sup3;", "³", "sup;", "⊃", "supE;", "⫆", "supdot;", "⪾", "supdsub;", "⫘", "supe;", "⊇", "supedot;", "⫄", "suphsol;", "⟉", "suphsub;", "⫗", "suplarr;", "⥻", "supmult;", "⫂", "supnE;", "⫌", "supne;", "⊋", "supplus;", "⫀", "supset;", "⊃", "supseteq;", "⊇", "supseteqq;", "⫆", "supsetneq;", "⊋", "supsetneqq;", "⫌", "supsim;", "⫈", "supsub;", "⫔", "supsup;", "⫖", "swArr;", "⇙", "swarhk;", "⤦", "swarr;", "↙", "swarrow;", "↙", "swnwar;", "⤪", "szlig", "ß", "szlig;", "ß", "target;", "⌖", "tau;", "τ", "tbrk;", "⎴", "tcaron;", "ť", "tcedil;", "ţ", "tcy;", "т", "tdot;", "⃛", "telrec;", "⌕", "tfr;", "𝔱", "there4;", "∴", "therefore;", "∴", "theta;", "θ", "thetasym;", "ϑ", "thetav;", "ϑ", "thickapprox;", "≈", "thicksim;", "∼", "thinsp;", " ", "thkap;", "≈", "thksim;", "∼", "thorn", "þ", "thorn;", "þ", "tilde;", "˜", "times", "×", "times;", "×", "timesb;", "⊠", "timesbar;", "⨱", "timesd;", "⨰", "tint;", "∭", "toea;", "⤨", "top;", "⊤", "topbot;", "⌶", "topcir;", "⫱", "topf;", "𝕥", "topfork;", "⫚", "tosa;", "⤩", "tprime;", "‴", "trade;", "™", "triangle;", "▵", "triangledown;", "▿", "triangleleft;", "◃", "trianglelefteq;", "⊴", "triangleq;", "≜", "triangleright;", "▹", "trianglerighteq;", "⊵", "tridot;", "◬", "trie;", "≜", "triminus;", "⨺", "triplus;", "⨹", "trisb;", "⧍", "tritime;", "⨻", "trpezium;", "⏢", "tscr;", "𝓉", "tscy;", "ц", "tshcy;", "ћ", "tstrok;", "ŧ", "twixt;", "≬", "twoheadleftarrow;", "↞", "twoheadrightarrow;", "↠", "uArr;", "⇑", "uHar;", "⥣", "uacute", "ú", "uacute;", "ú", "uarr;", "↑", "ubrcy;", "ў", "ubreve;", "ŭ", "ucirc", "û", "ucirc;", "û", "ucy;", "у", "udarr;", "⇅", "udblac;", "ű", "udhar;", "⥮", "ufisht;", "⥾", "ufr;", "𝔲", "ugrave", "ù", "ugrave;", "ù", "uharl;", "↿", "uharr;", "↾", "uhblk;", "▀", "ulcorn;", "⌜", "ulcorner;", "⌜", "ulcrop;", "⌏", "ultri;", "◸", "umacr;", "ū", "uml", "¨", "uml;", "¨", "uogon;", "ų", "uopf;", "𝕦", "uparrow;", "↑", "updownarrow;", "↕", "upharpoonleft;", "↿", "upharpoonright;", "↾", "uplus;", "⊎", "upsi;", "υ", "upsih;", "ϒ", "upsilon;", "υ", "upuparrows;", "⇈", "urcorn;", "⌝", "urcorner;", "⌝", "urcrop;", "⌎", "uring;", "ů", "urtri;", "◹", "uscr;", "𝓊", "utdot;", "⋰", "utilde;", "ũ", "utri;", "▵", "utrif;", "▴", "uuarr;", "⇈", "uuml", "ü", "uuml;", "ü", "uwangle;", "⦧", "vArr;", "⇕", "vBar;", "⫨", "vBarv;", "⫩", "vDash;", "⊨", "vangrt;", "⦜", "varepsilon;", "ϵ", "varkappa;", "ϰ", "varnothing;", "∅", "varphi;", "ϕ", "varpi;", "ϖ", "varpropto;", "∝", "varr;", "↕", "varrho;", "ϱ", "varsigma;", "ς", "varsubsetneq;", "⊊︀", "varsubsetneqq;", "⫋︀", "varsupsetneq;", "⊋︀", "varsupsetneqq;", "⫌︀", "vartheta;", "ϑ", "vartriangleleft;", "⊲", "vartriangleright;", "⊳", "vcy;", "в", "vdash;", "⊢", "vee;", "∨", "veebar;", "⊻", "veeeq;", "≚", "vellip;", "⋮", "verbar;", "|", "vert;", "|", "vfr;", "𝔳", "vltri;", "⊲", "vnsub;", "⊂⃒", "vnsup;", "⊃⃒", "vopf;", "𝕧", "vprop;", "∝", "vrtri;", "⊳", "vscr;", "𝓋", "vsubnE;", "⫋︀", "vsubne;", "⊊︀", "vsupnE;", "⫌︀", "vsupne;", "⊋︀", "vzigzag;", "⦚", "wcirc;", "ŵ", "wedbar;", "⩟", "wedge;", "∧", "wedgeq;", "≙", "weierp;", "℘", "wfr;", "𝔴", "wopf;", "𝕨", "wp;", "℘", "wr;", "≀", "wreath;", "≀", "wscr;", "𝓌", "xcap;", "⋂", "xcirc;", "◯", "xcup;", "⋃", "xdtri;", "▽", "xfr;", "𝔵", "xhArr;", "⟺", "xharr;", "⟷", "xi;", "ξ", "xlArr;", "⟸", "xlarr;", "⟵", "xmap;", "⟼", "xnis;", "⋻", "xodot;", "⨀", "xopf;", "𝕩", "xoplus;", "⨁", "xotime;", "⨂", "xrArr;", "⟹", "xrarr;", "⟶", "xscr;", "𝓍", "xsqcup;", "⨆", "xuplus;", "⨄", "xutri;", "△", "xvee;", "⋁", "xwedge;", "⋀", "yacute", "ý", "yacute;", "ý", "yacy;", "я", "ycirc;", "ŷ", "ycy;", "ы", "yen", "¥", "yen;", "¥", "yfr;", "𝔶", "yicy;", "ї", "yopf;", "𝕪", "yscr;", "𝓎", "yucy;", "ю", "yuml", "ÿ", "yuml;", "ÿ", "zacute;", "ź", "zcaron;", "ž", "zcy;", "з", "zdot;", "ż", "zeetrf;", "ℨ", "zeta;", "ζ", "zfr;", "𝔷", "zhcy;", "ж", "zigrarr;", "⇝", "zopf;", "𝕫", "zscr;", "𝓏", "zwj;", "", "zwnj;", ""];
|
|
9
|
+
/** name (with its `;` where the standard has one) -> replacement text. */
|
|
10
|
+
export const HTML5_ENTITIES = (() => {
|
|
11
|
+
const map = new Map();
|
|
12
|
+
for (let i = 0; i + 1 < FLAT.length; i += 2) {
|
|
13
|
+
map.set(FLAT[i], FLAT[i + 1]);
|
|
14
|
+
}
|
|
15
|
+
return map;
|
|
16
|
+
})();
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { BantamError } from './errors.js';
|
|
2
|
+
export { ContractParseError, extractJson, loadContract, parseContractDocument, parseErrorMessage, REQUIRED_KEYS, schemaError, schemaRetryFeedback, validationErrorMessage, } from './contract.js';
|
|
3
|
+
export { dumpJson, fromJs, PY_NONE, parseJson, pyFloatRepr, PyJSONDecodeError, PyValueError, rawDecode, reprValue, toJs, } from './pyjson.js';
|
|
4
|
+
export type { DumpOptions, PyValue } from './pyjson.js';
|
|
5
|
+
export { absolutePath, bestMatch, iterErrors, PyJsonSchemaUnsupported, pyEqual, validate, } from './pyjsonschema.js';
|
|
6
|
+
export type { PyValidationError } from './pyjsonschema.js';
|
|
7
|
+
export { AssetNotFound, assetsRoot, loadSchema, loadSkill, loadTool, loadToolAsset } from './assets.js';
|
|
8
|
+
export type { Tool } from './assets.js';
|
|
9
|
+
export { decodeFactBytes, FactParseError, formatFact, parseFactText, parseFrontmatter, pySplit, pyStrip, todayLocal, } from './memory/factfile.js';
|
|
10
|
+
export type { Fact, FactMeta, FactValue } from './memory/factfile.js';
|
|
11
|
+
export { constructPlain, PyScalar, resolveImplicitTag, safeDumpMapping, YamlConstructError, YamlEmitError, } from './memory/pyyaml.js';
|
|
12
|
+
export type { PyOrder, YamlScalar, YamlValue } from './memory/pyyaml.js';
|
|
13
|
+
export { countFacts, discoverProjectStore, loadGrants, MEMORY_DIR_ENV, PROJECT_STORE, resolveProjectStore, } from './memory/layers.js';
|
|
14
|
+
export type { StoreBinding } from './memory/layers.js';
|
|
15
|
+
export { layerLabel, Memory, normalizeName, profileStore } from './memory/component.js';
|
|
16
|
+
export type { CompactOutcome, MemoryOptions, RecallOutcome, SaveOutcome } from './memory/component.js';
|
|
17
|
+
export { CAP_BYTES, DEFAULT_RELATIVE_PATH, defaultPath, encodeRecord, EVENT_LOG_ENV, EventLog, formatTimestamp, resolvePath, SCHEMA_VERSION, } from './eventlog.js';
|
|
18
|
+
export type { DetailValue } from './eventlog.js';
|
|
19
|
+
export { DEFAULT_INDEX_BUDGET, DUPLICATE_JACCARD, jaccard, MemoryBudgetExceeded, MemoryStore, MemoryValidationError, pyCompareLt, pyEqualValue, pyHashKey, pyText, sortScored, tokens, VALID_TYPES, } from './memory/store.js';
|
|
20
|
+
export type { MemoryStoreOptions, SaveResult } from './memory/store.js';
|
|
21
|
+
export { asPyOSError, cmpCodepoint, matchesMd, normcase, pyDecodeUtf8, pyCwd, pyExists, pyExpanduser, pyHome, pyIsAbsolute, pyIsDir, pyIsFile, pyJoin, pyLexists, pyMkdirParents, pyMtimeDate, pyName, PyOSError, pyParent, pyParents, pyReadText, pyReplace, pyRepr, pyResolve, PyRuntimeError, pyScandirNames, PyUnicodeDecodeError, pyAppendText, pyStatIsDir, pySuffix, pyUnlink, pyWithSuffix, pyWriteText, sortedPathNames, sortedPathParts, STRERROR_NAMES, } from './memory/pyfs.js';
|
|
22
|
+
export { clockIn, clockOut, HISTORY_RING_SIZE, SCHEMA_NAME, status, TERMINAL_UNIT_STATUS, timestamp, } from './shiftwork.js';
|
|
23
|
+
export type { ClockOptions } from './shiftwork.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { BantamError } from './errors.js';
|
|
2
|
+
export { ContractParseError, extractJson, loadContract, parseContractDocument, parseErrorMessage, REQUIRED_KEYS, schemaError, schemaRetryFeedback, validationErrorMessage, } from './contract.js';
|
|
3
|
+
export { dumpJson, fromJs, PY_NONE, parseJson, pyFloatRepr, PyJSONDecodeError, PyValueError, rawDecode, reprValue, toJs, } from './pyjson.js';
|
|
4
|
+
export { absolutePath, bestMatch, iterErrors, PyJsonSchemaUnsupported, pyEqual, validate, } from './pyjsonschema.js';
|
|
5
|
+
export { AssetNotFound, assetsRoot, loadSchema, loadSkill, loadTool, loadToolAsset } from './assets.js';
|
|
6
|
+
export { decodeFactBytes, FactParseError, formatFact, parseFactText, parseFrontmatter, pySplit, pyStrip, todayLocal, } from './memory/factfile.js';
|
|
7
|
+
export { constructPlain, PyScalar, resolveImplicitTag, safeDumpMapping, YamlConstructError, YamlEmitError, } from './memory/pyyaml.js';
|
|
8
|
+
export { countFacts, discoverProjectStore, loadGrants, MEMORY_DIR_ENV, PROJECT_STORE, resolveProjectStore, } from './memory/layers.js';
|
|
9
|
+
export { layerLabel, Memory, normalizeName, profileStore } from './memory/component.js';
|
|
10
|
+
export { CAP_BYTES, DEFAULT_RELATIVE_PATH, defaultPath, encodeRecord, EVENT_LOG_ENV, EventLog, formatTimestamp, resolvePath, SCHEMA_VERSION, } from './eventlog.js';
|
|
11
|
+
export { DEFAULT_INDEX_BUDGET, DUPLICATE_JACCARD, jaccard, MemoryBudgetExceeded, MemoryStore, MemoryValidationError, pyCompareLt, pyEqualValue, pyHashKey, pyText, sortScored, tokens, VALID_TYPES, } from './memory/store.js';
|
|
12
|
+
export { asPyOSError, cmpCodepoint, matchesMd, normcase, pyDecodeUtf8, pyCwd, pyExists, pyExpanduser, pyHome, pyIsAbsolute, pyIsDir, pyIsFile, pyJoin, pyLexists, pyMkdirParents, pyMtimeDate, pyName, PyOSError, pyParent, pyParents, pyReadText, pyReplace, pyRepr, pyResolve, PyRuntimeError, pyScandirNames, PyUnicodeDecodeError, pyAppendText, pyStatIsDir, pySuffix, pyUnlink, pyWithSuffix, pyWriteText, sortedPathNames, sortedPathParts, STRERROR_NAMES, } from './memory/pyfs.js';
|
|
13
|
+
export { clockIn, clockOut, HISTORY_RING_SIZE, SCHEMA_NAME, status, TERMINAL_UNIT_STATUS, timestamp, } from './shiftwork.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const SERVER_NAME = "bantamkit";
|
|
2
|
+
/**
|
|
3
|
+
* sha256 over (relative path, size, bytes) of every file, in sorted path order.
|
|
4
|
+
*
|
|
5
|
+
* The feed is `update(relpath.as_posix().utf8)`, `update(b"\0%d\0" % len(payload))`,
|
|
6
|
+
* `update(payload)` — paths folded in so a move is a different build, sizes so a
|
|
7
|
+
* concatenation cannot be re-partitioned into the same stream. `len(payload)` is a BYTE
|
|
8
|
+
* count, which is why the payload is read as a Buffer and never as a string.
|
|
9
|
+
*
|
|
10
|
+
* `as_posix()` is why the parts are joined with `/` here and not with `path.sep`: on Windows
|
|
11
|
+
* the walk yields the same components and the digest must not change with the separator.
|
|
12
|
+
*/
|
|
13
|
+
export declare function treeDigest(root: string): {
|
|
14
|
+
digest: string;
|
|
15
|
+
files: number;
|
|
16
|
+
};
|
|
17
|
+
/** `sha256(json.dumps(inputs, sort_keys=True, separators=(",", ":")))` — the identity. */
|
|
18
|
+
export declare function buildIdFor(inputs: Record<string, string>): string;
|
|
19
|
+
/**
|
|
20
|
+
* The tool body. Key order is the wire order and is deliberate: what this build IS, then
|
|
21
|
+
* where it lives, then what it refuses, then the environment, then the identity.
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildIdentity(version: string, sdkVersion: string | {
|
|
24
|
+
unavailable: string;
|
|
25
|
+
}): Map<string, unknown>;
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `build_identity` — the one function in the port that could not be ported, and why.
|
|
3
|
+
*
|
|
4
|
+
* THE QUESTION THE TOOL EXISTS TO ANSWER is "which code is actually executing?", and
|
|
5
|
+
* `RB-P84` is the case that made it a tool rather than a field on `initialize`: two
|
|
6
|
+
* `bantamkit` endpoints registered under one name on one machine, both spawned, and their
|
|
7
|
+
* advertised surfaces byte-identical over 6864 bytes. `npx` makes that worse rather than
|
|
8
|
+
* better — it resolves `latest` and caches it per machine, so two developers on one config
|
|
9
|
+
* line can be running two different tarballs and nothing in the handshake says so.
|
|
10
|
+
*
|
|
11
|
+
* WHAT COULD NOT BE PORTED. `_code_fingerprint` hashes 24 `.py` files. A Node build has
|
|
12
|
+
* none, so `code_digest` cannot mean what it means over there, and `build_id` — which is
|
|
13
|
+
* sha256 over `{server_name, version, code_digest, assets_digest}` — cannot be made to
|
|
14
|
+
* agree between the runtimes for one release. Reproducing that shape while silently
|
|
15
|
+
* changing what it measures would be the worst outcome available: a caller comparing two
|
|
16
|
+
* `build_id`s would read "different builds" and could not tell whether the difference is a
|
|
17
|
+
* release, an edit, or the language.
|
|
18
|
+
*
|
|
19
|
+
* SO THE SHAPE IS CHANGED ON PURPOSE, IN THREE PLACES, AND EACH IS VISIBLE ON THE WIRE:
|
|
20
|
+
*
|
|
21
|
+
* 1. `runtime` is a NEW field, `"node"`. Its presence is itself the discriminator — the
|
|
22
|
+
* Python endpoint has no such key — so a caller never has to infer the lineage from a
|
|
23
|
+
* digest that happens not to match.
|
|
24
|
+
* 2. `runtime` is folded INTO `build_id`. That is domain separation, not decoration: with
|
|
25
|
+
* it, a Node and a Python `build_id` cannot collide even in the impossible case where
|
|
26
|
+
* their code digests agreed, so `build_id` equality never means "same build" across
|
|
27
|
+
* lineages by accident.
|
|
28
|
+
* 3. `cross_runtime` says all of it in a sentence, in the output, next to the fields it is
|
|
29
|
+
* about — because the caller who needs it is a model holding one tool result, not a
|
|
30
|
+
* person reading this file.
|
|
31
|
+
*
|
|
32
|
+
* WHAT IS UNCHANGED, AND IS THE POINT. `assets_digest` / `assets_files` / `assets_root` are
|
|
33
|
+
* computed exactly as Python computes them, over the same 84 files and 213,773 bytes, in
|
|
34
|
+
* `sorted(Path)` order, with the same per-file feed. The asset pack is language-agnostic and
|
|
35
|
+
* is the one thing the two runtimes genuinely share, so it is the one field that IS
|
|
36
|
+
* comparable across them — and `tools/conformance/suites/wire.mjs` compares the two live
|
|
37
|
+
* servers' `assets_digest` to prove it, rather than asserting it here.
|
|
38
|
+
*
|
|
39
|
+
* `RB-P84`'s ruling stands unchanged: `build_id` DECLINES when an input is underivable. A
|
|
40
|
+
* partial identity would agree with every other build that lost the same input.
|
|
41
|
+
*/
|
|
42
|
+
import { createHash } from 'node:crypto';
|
|
43
|
+
import { lstatSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
44
|
+
import { dirname, join } from 'node:path';
|
|
45
|
+
import { fileURLToPath } from 'node:url';
|
|
46
|
+
import { AssetNotFound, assetsRoot } from '../assets.js';
|
|
47
|
+
import { sortedPathParts } from '../memory/pyfs.js';
|
|
48
|
+
import { PyOSError, asPyOSError } from '../memory/pyfs.js';
|
|
49
|
+
export const SERVER_NAME = 'bantamkit';
|
|
50
|
+
/** A build fact that could not be derived, carrying WHY. Never becomes a value. */
|
|
51
|
+
class Undetermined extends Error {
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The shape an underivable fact takes on the wire — `RB-P51`, unchanged from Python.
|
|
55
|
+
*
|
|
56
|
+
* A sentinel string (`""`, `"unknown"`) sits in a field typed as a path or a digest and a
|
|
57
|
+
* caller comparing fields reads it as one. An object cannot: every derivable field here is a
|
|
58
|
+
* string, an int or a bool, so a caller that got a dict knows it got no answer.
|
|
59
|
+
*/
|
|
60
|
+
const unavailable = (reason) => ({ unavailable: reason });
|
|
61
|
+
/**
|
|
62
|
+
* `sorted(root.rglob("*") if p.is_file())` — the walk, in `Path` order.
|
|
63
|
+
*
|
|
64
|
+
* `rglob` does not descend into a symlinked DIRECTORY (CPython 3.12), and `is_file()` DOES
|
|
65
|
+
* follow a symlink to a file. Both are mirrored: a symlinked directory is listed and not
|
|
66
|
+
* entered, a symlinked file is included and read through. The asset pack contains neither
|
|
67
|
+
* today; the behaviour is matched anyway, because a pack that grew one would otherwise
|
|
68
|
+
* fingerprint differently under the two runtimes and nothing would say so.
|
|
69
|
+
*/
|
|
70
|
+
function walkFiles(root) {
|
|
71
|
+
const found = [];
|
|
72
|
+
const descend = (parts) => {
|
|
73
|
+
const here = parts.length === 0 ? root : join(root, ...parts);
|
|
74
|
+
for (const entry of readdirSync(here, { withFileTypes: true })) {
|
|
75
|
+
const next = [...parts, entry.name];
|
|
76
|
+
if (entry.isDirectory()) {
|
|
77
|
+
descend(next);
|
|
78
|
+
}
|
|
79
|
+
else if (entry.isFile()) {
|
|
80
|
+
found.push(next);
|
|
81
|
+
}
|
|
82
|
+
else if (entry.isSymbolicLink()) {
|
|
83
|
+
// `is_file()` resolves; a dangling link is neither a file nor a directory and
|
|
84
|
+
// `rglob` yields it while the `is_file()` filter drops it.
|
|
85
|
+
let resolved;
|
|
86
|
+
try {
|
|
87
|
+
resolved = statSync(join(here, entry.name));
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (resolved.isFile())
|
|
93
|
+
found.push(next);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
descend([]);
|
|
98
|
+
return sortedPathParts(found);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* sha256 over (relative path, size, bytes) of every file, in sorted path order.
|
|
102
|
+
*
|
|
103
|
+
* The feed is `update(relpath.as_posix().utf8)`, `update(b"\0%d\0" % len(payload))`,
|
|
104
|
+
* `update(payload)` — paths folded in so a move is a different build, sizes so a
|
|
105
|
+
* concatenation cannot be re-partitioned into the same stream. `len(payload)` is a BYTE
|
|
106
|
+
* count, which is why the payload is read as a Buffer and never as a string.
|
|
107
|
+
*
|
|
108
|
+
* `as_posix()` is why the parts are joined with `/` here and not with `path.sep`: on Windows
|
|
109
|
+
* the walk yields the same components and the digest must not change with the separator.
|
|
110
|
+
*/
|
|
111
|
+
export function treeDigest(root) {
|
|
112
|
+
const files = walkFiles(root);
|
|
113
|
+
const running = createHash('sha256');
|
|
114
|
+
for (const parts of files) {
|
|
115
|
+
const payload = readFileSync(join(root, ...parts));
|
|
116
|
+
running.update(Buffer.from(parts.join('/'), 'utf8'));
|
|
117
|
+
running.update(Buffer.from(`\0${payload.length}\0`, 'utf8'));
|
|
118
|
+
running.update(payload);
|
|
119
|
+
}
|
|
120
|
+
return { digest: `sha256:${running.digest('hex')}`, files: files.length };
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Fingerprint the code that is actually executing — `dist/**\/*.js`.
|
|
124
|
+
*
|
|
125
|
+
* The Node analogue of `bantamkit.__file__` is this module's own URL: it is the resolution
|
|
126
|
+
* the loader already performed, so it names the tree serving the call and not a checkout
|
|
127
|
+
* that happens to be nearby (`RB-P55`, inside a worktree). Compiled to `dist/mcp/identity.js`,
|
|
128
|
+
* one level up is `dist/`, which is the code root in a checkout AND in an installed tarball.
|
|
129
|
+
*
|
|
130
|
+
* `*.js` and nothing else, mirroring Python's `*.py`. The `.d.ts` files ship but never
|
|
131
|
+
* execute, and folding them in would make a build that changed only a type annotation report
|
|
132
|
+
* as different code. `assets/` is excluded for the reason Python excludes it — in a tarball
|
|
133
|
+
* the pack is a SIBLING of `dist/` so the exclusion is inert today, and it stays because the
|
|
134
|
+
* pack carries eleven `.py`-shaped fixture files whose Node equivalents would otherwise be
|
|
135
|
+
* counted twice: once here and once under `assets_digest`, where they belong.
|
|
136
|
+
*/
|
|
137
|
+
function codeFingerprint() {
|
|
138
|
+
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
139
|
+
const jsOnly = (parts) => parts.filter((p) => p[p.length - 1].endsWith('.js') && p[0] !== 'assets');
|
|
140
|
+
const files = jsOnly(walkFiles(root));
|
|
141
|
+
if (files.length === 0) {
|
|
142
|
+
// A digest over nothing is a constant, and two servers that both computed one would
|
|
143
|
+
// agree — the vacuity this whole surface exists to prevent.
|
|
144
|
+
throw new Undetermined(`no .js source found under ${root}`);
|
|
145
|
+
}
|
|
146
|
+
const running = createHash('sha256');
|
|
147
|
+
try {
|
|
148
|
+
for (const parts of files) {
|
|
149
|
+
const payload = readFileSync(join(root, ...parts));
|
|
150
|
+
running.update(Buffer.from(parts.join('/'), 'utf8'));
|
|
151
|
+
running.update(Buffer.from(`\0${payload.length}\0`, 'utf8'));
|
|
152
|
+
running.update(payload);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
const error = e instanceof PyOSError ? e : asPyOSError(e, root);
|
|
157
|
+
throw new Undetermined(`unreadable source under ${root}: ${error.message}`);
|
|
158
|
+
}
|
|
159
|
+
return { digest: `sha256:${running.digest('hex')}`, files: files.length, root };
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Fingerprint the asset pack this build would load — every file, not just the loaded ones.
|
|
163
|
+
*
|
|
164
|
+
* `contracts/default.yaml` is the reason: `RB-P84` measured it as the one asset that differed
|
|
165
|
+
* between two live builds while no resource template exposed it, so it was invisible on every
|
|
166
|
+
* probed surface. It is also why N1 ships all 84 files rather than the 20 that are read.
|
|
167
|
+
*/
|
|
168
|
+
function assetsFingerprint() {
|
|
169
|
+
let root;
|
|
170
|
+
try {
|
|
171
|
+
root = assetsRoot();
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
if (e instanceof AssetNotFound)
|
|
175
|
+
throw new Undetermined(`assets_root() could not resolve a pack: ${e.message}`);
|
|
176
|
+
throw e;
|
|
177
|
+
}
|
|
178
|
+
let walked;
|
|
179
|
+
try {
|
|
180
|
+
walked = treeDigest(root);
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
const error = e instanceof PyOSError ? e : asPyOSError(e, root);
|
|
184
|
+
// A root that does not exist at all is the `BANTAMKIT_ASSETS` typo, and Python reaches
|
|
185
|
+
// the same place: `rglob` over a missing directory yields nothing, so "contains no files".
|
|
186
|
+
if (error.code === 'ENOENT' || error.code === 'ENOTDIR') {
|
|
187
|
+
throw new Undetermined(`asset pack at ${root} contains no files`);
|
|
188
|
+
}
|
|
189
|
+
throw new Undetermined(`unreadable asset under ${root}: ${error.message}`);
|
|
190
|
+
}
|
|
191
|
+
if (walked.files === 0)
|
|
192
|
+
throw new Undetermined(`asset pack at ${root} contains no files`);
|
|
193
|
+
return { digest: walked.digest, files: walked.files, root };
|
|
194
|
+
}
|
|
195
|
+
/** `sha256(json.dumps(inputs, sort_keys=True, separators=(",", ":")))` — the identity. */
|
|
196
|
+
export function buildIdFor(inputs) {
|
|
197
|
+
const canonical = `{${Object.keys(inputs)
|
|
198
|
+
.sort()
|
|
199
|
+
.map((k) => `${JSON.stringify(k)}:${JSON.stringify(inputs[k])}`)
|
|
200
|
+
.join(',')}}`;
|
|
201
|
+
return `sha256:${createHash('sha256').update(Buffer.from(canonical, 'utf8')).digest('hex')}`;
|
|
202
|
+
}
|
|
203
|
+
const GIT_COMMIT_REFUSAL = 'refused, not missing. An installed npm tarball carries no repository at all, and ' +
|
|
204
|
+
"reading a checkout's HEAD would describe the TREE rather than the bytes that " +
|
|
205
|
+
'were imported — an edited working copy serves different code under an unchanged ' +
|
|
206
|
+
'sha, which is precisely the confusion RB-P84 filed. A commit reported that way ' +
|
|
207
|
+
'would be a value that is sometimes a lie; `code_digest` is derived from the ' +
|
|
208
|
+
'bytes themselves and cannot be.';
|
|
209
|
+
const CROSS_RUNTIME = 'assets_digest is comparable across runtimes: the asset pack is language-agnostic and ' +
|
|
210
|
+
'both endpoints digest the same files, in sorted(Path) order, with the same per-file ' +
|
|
211
|
+
'feed. code_digest and build_id are NOT comparable across runtimes. This endpoint ' +
|
|
212
|
+
'digests dist/**/*.js and folds runtime="node" into build_id; the Python endpoint ' +
|
|
213
|
+
'digests **/*.py and folds no runtime at all, so the two build_id values are domain-' +
|
|
214
|
+
'separated by construction and cannot agree for any release. Compare build_id only ' +
|
|
215
|
+
'between endpoints whose `runtime` agrees; across runtimes compare `version` and ' +
|
|
216
|
+
'`assets_digest`.';
|
|
217
|
+
/**
|
|
218
|
+
* The tool body. Key order is the wire order and is deliberate: what this build IS, then
|
|
219
|
+
* where it lives, then what it refuses, then the environment, then the identity.
|
|
220
|
+
*/
|
|
221
|
+
export function buildIdentity(version, sdkVersion) {
|
|
222
|
+
const identity = new Map();
|
|
223
|
+
identity.set('runtime', 'node');
|
|
224
|
+
identity.set('server_name', SERVER_NAME);
|
|
225
|
+
identity.set('version', version);
|
|
226
|
+
try {
|
|
227
|
+
const code = codeFingerprint();
|
|
228
|
+
identity.set('code_digest', code.digest);
|
|
229
|
+
identity.set('code_files', code.files);
|
|
230
|
+
identity.set('package_path', code.root);
|
|
231
|
+
}
|
|
232
|
+
catch (e) {
|
|
233
|
+
if (!(e instanceof Undetermined))
|
|
234
|
+
throw e;
|
|
235
|
+
for (const field of ['code_digest', 'code_files', 'package_path'])
|
|
236
|
+
identity.set(field, unavailable(e.message));
|
|
237
|
+
}
|
|
238
|
+
try {
|
|
239
|
+
const pack = assetsFingerprint();
|
|
240
|
+
identity.set('assets_digest', pack.digest);
|
|
241
|
+
identity.set('assets_files', pack.files);
|
|
242
|
+
identity.set('assets_root', pack.root);
|
|
243
|
+
}
|
|
244
|
+
catch (e) {
|
|
245
|
+
if (!(e instanceof Undetermined))
|
|
246
|
+
throw e;
|
|
247
|
+
for (const field of ['assets_digest', 'assets_files', 'assets_root'])
|
|
248
|
+
identity.set(field, unavailable(e.message));
|
|
249
|
+
}
|
|
250
|
+
// Location, never identity: `BANTAMKIT_ASSETS` redirects the pack, so whether the root was
|
|
251
|
+
// chosen by the operator or resolved by the package is a fact a caller comparing two
|
|
252
|
+
// endpoints needs. A bool, so it is never confusable with a missing one.
|
|
253
|
+
identity.set('assets_root_from_env', Boolean(process.env.BANTAMKIT_ASSETS));
|
|
254
|
+
identity.set('git_commit', unavailable(GIT_COMMIT_REFUSAL));
|
|
255
|
+
identity.set('interpreter', process.execPath || unavailable('process.execPath is empty; this process cannot name its own binary'));
|
|
256
|
+
identity.set('node_version', process.versions.node);
|
|
257
|
+
identity.set('v8_version', process.versions.v8);
|
|
258
|
+
identity.set('mcp_sdk_version', sdkVersion);
|
|
259
|
+
const inputNames = ['runtime', 'server_name', 'version', 'code_digest', 'assets_digest'];
|
|
260
|
+
const missing = inputNames.filter((key) => typeof identity.get(key) !== 'string').sort();
|
|
261
|
+
if (missing.length > 0) {
|
|
262
|
+
identity.set('build_id', unavailable('computed from runtime, server_name, version, code_digest and assets_digest; could ' +
|
|
263
|
+
`not derive ${missing.join(', ')}. A build_id short of an input would agree ` +
|
|
264
|
+
'with every other build that lost the same input, so none is reported.'));
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
const inputs = {};
|
|
268
|
+
for (const key of inputNames)
|
|
269
|
+
inputs[key] = identity.get(key);
|
|
270
|
+
identity.set('build_id', buildIdFor(inputs));
|
|
271
|
+
}
|
|
272
|
+
identity.set('cross_runtime', CROSS_RUNTIME);
|
|
273
|
+
identity.set('unavailable', [...identity].filter(([, v]) => typeof v === 'object' && v !== null && 'unavailable' in v).map(([k]) => k).sort());
|
|
274
|
+
return identity;
|
|
275
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Argument validation, in the reference runtime's own words.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS IS REPRODUCED RATHER THAN RULED. The text below is not a diagnostic in a log —
|
|
5
|
+
* it is the `content[0].text` of a tool result, which means the MODEL reads it and decides
|
|
6
|
+
* what to do next. `zod`'s wording is entirely different, so a port that let zod speak would
|
|
7
|
+
* ship a server whose recovery behaviour differs from the reference's on every mistyped
|
|
8
|
+
* argument, and that is a product difference, not a cosmetic one.
|
|
9
|
+
*
|
|
10
|
+
* WHAT THE URL IS. `https://errors.pydantic.dev/2.13/v/<type>` names an entry in pydantic's
|
|
11
|
+
* public error catalogue. This runtime has no pydantic; the URL is part of the sentence the
|
|
12
|
+
* reference emits, reproduced because the sentence is the contract. `2.13` is therefore a
|
|
13
|
+
* PIN on the reference, not a claim about this process — and it is compared against the
|
|
14
|
+
* live server by `tools/conformance/suites/wire.mjs`, so the day the Python side bumps to
|
|
15
|
+
* 2.14 the suite goes red here instead of the two runtimes drifting apart quietly.
|
|
16
|
+
*
|
|
17
|
+
* EVERY RULE BELOW WAS MEASURED, not read off pydantic's documentation. The probes are in
|
|
18
|
+
* `scratchpad/job38-n7/probe{4,7,8,9}.py` and each drove the real stdio server:
|
|
19
|
+
*
|
|
20
|
+
* * errors come in MODEL FIELD order, not in the order the arguments arrived (probe7 id 80
|
|
21
|
+
* sends `body, name, description, type` and gets `type` before `name`);
|
|
22
|
+
* * `int` is LAX — `True`, `'2'`, `' 3 '`, `'2_0'`, `'+2'` and `3.0` all validate, while
|
|
23
|
+
* `'2.5'`, `'1e3'`, `'0x10'` and `''` are `int_parsing` and `2.5` is `int_from_float`;
|
|
24
|
+
* * a float too large for an i64 is `int_parsing_size`, with a DIFFERENT message shape
|
|
25
|
+
* (no "Input should be a valid integer," prefix);
|
|
26
|
+
* * `input_value` is truncated on the UTF-8 BYTE length of `repr(value)`: over 50 bytes it
|
|
27
|
+
* becomes head-25-bytes + `...` + tail-24-bytes, each end floored to a character
|
|
28
|
+
* boundary. Thirty Thai characters are 34 repr CHARACTERS and are still truncated.
|
|
29
|
+
*/
|
|
30
|
+
import { type PyValue } from '../pyjson.js';
|
|
31
|
+
/** What a parameter accepts. `optional` is `| None = None` in the signature. */
|
|
32
|
+
export interface FieldSpec {
|
|
33
|
+
readonly name: string;
|
|
34
|
+
readonly kind: 'str' | 'int' | 'dict' | 'dictInt' | 'dictStr' | 'listStr';
|
|
35
|
+
readonly optional: boolean;
|
|
36
|
+
/** `Field(le=...)`: an inclusive ceiling, checked AFTER the lax int parse succeeds. */
|
|
37
|
+
readonly le?: bigint;
|
|
38
|
+
}
|
|
39
|
+
export interface ArgModel {
|
|
40
|
+
/** The pydantic model name, which is the FUNCTION name plus `Arguments`. */
|
|
41
|
+
readonly model: string;
|
|
42
|
+
readonly fields: readonly FieldSpec[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* One model per handler, mirroring `build_server`'s closures signature for signature.
|
|
46
|
+
*
|
|
47
|
+
* `build_identity`'s model is `build_identity_toolArguments` and not `build_identityArguments`
|
|
48
|
+
* — pydantic names it after the PYTHON FUNCTION, and the function is the closure
|
|
49
|
+
* `build_identity_tool`. The same leak is already in the shipped manifest
|
|
50
|
+
* (`output_schema.title` is `build_identity_toolDictOutput`), so the name is not an accident
|
|
51
|
+
* this port gets to tidy: it is on the wire today, and a client that pinned it would break.
|
|
52
|
+
*
|
|
53
|
+
* MEASURED SURVIVOR, AND IT STAYS. A mutation changing this one string to
|
|
54
|
+
* `build_identityArguments` survives both gates, because `build_identity` has no parameters
|
|
55
|
+
* and a model with no fields can never fail — the name is unreachable from the wire. It is
|
|
56
|
+
* still spelled correctly: the day the tool grows an argument, the sweep's kill comes for
|
|
57
|
+
* free, and a name that was wrong until then would be a defect nobody planted. The leak that
|
|
58
|
+
* IS observable is the manifest's `output_schema.title`, and that one is compared byte for
|
|
59
|
+
* byte by the conformance suite's `advertisement: id 2` case.
|
|
60
|
+
*/
|
|
61
|
+
export declare const ARG_MODELS: Readonly<Record<string, ArgModel>>;
|
|
62
|
+
/**
|
|
63
|
+
* The pydantic `ValidationError` text, WITHOUT the `Error executing tool <name>: ` prefix.
|
|
64
|
+
*
|
|
65
|
+
* The prefix is the SDK's, added by `Tool.run`'s `except Exception` for every failure a tool
|
|
66
|
+
* can have — not just an argument one — so it belongs at the one place that catches them all.
|
|
67
|
+
*/
|
|
68
|
+
export declare class PyValidationFailure extends Error {
|
|
69
|
+
readonly detail: string;
|
|
70
|
+
constructor(detail: string);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* `model.model_validate(arguments)` for one tool, or the exact `ValidationError` text.
|
|
74
|
+
*
|
|
75
|
+
* Unknown keys are IGNORED, because pydantic's default `model_config` ignores them and the
|
|
76
|
+
* measured server accepts `{"query": "a", "extra": 1}` without complaint. The absent-key case
|
|
77
|
+
* and the explicit-`null` case are different: `{}` is `missing`, `{"handoff_patch": null}` is
|
|
78
|
+
* `dict_type`, and only an OPTIONAL field treats `null` as its default.
|
|
79
|
+
*/
|
|
80
|
+
export declare function validateArguments(model: ArgModel, args: PyValue): Map<string, PyValue>;
|