axon-code 2.4.0 → 2.6.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/dist/auth/snapshot.d.ts +24 -0
- package/dist/auth/snapshot.d.ts.map +1 -0
- package/dist/auth/snapshot.js +144 -0
- package/dist/auth/snapshot.js.map +1 -0
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/dist/config/axon-md-parser.d.ts.map +1 -1
- package/dist/config/axon-md-parser.js +21 -4
- package/dist/config/axon-md-parser.js.map +1 -1
- package/dist/config/index.d.ts +39 -21
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +14 -2
- package/dist/config/index.js.map +1 -1
- package/dist/context/enhanced.d.ts.map +1 -1
- package/dist/context/enhanced.js +5 -0
- package/dist/context/enhanced.js.map +1 -1
- package/dist/core/client.d.ts +7 -2
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +50 -18
- package/dist/core/client.js.map +1 -1
- package/dist/core/loop.d.ts +47 -8
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +333 -149
- package/dist/core/loop.js.map +1 -1
- package/dist/core/max-tokens.d.ts +24 -0
- package/dist/core/max-tokens.d.ts.map +1 -0
- package/dist/core/max-tokens.js +69 -0
- package/dist/core/max-tokens.js.map +1 -0
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +7 -14
- package/dist/core/session.js.map +1 -1
- package/dist/daemon/config.d.ts +6 -6
- package/dist/daemon/executor.d.ts.map +1 -1
- package/dist/daemon/executor.js +24 -30
- package/dist/daemon/executor.js.map +1 -1
- package/dist/goals/goal-store.d.ts +1 -1
- package/dist/goals/goal-store.d.ts.map +1 -1
- package/dist/goals/goal-store.js.map +1 -1
- package/dist/hooks/auto-verify.d.ts +86 -0
- package/dist/hooks/auto-verify.d.ts.map +1 -0
- package/dist/hooks/auto-verify.js +297 -0
- package/dist/hooks/auto-verify.js.map +1 -0
- package/dist/mcp/config.d.ts +16 -16
- package/dist/media/index.d.ts +2 -1
- package/dist/media/index.d.ts.map +1 -1
- package/dist/media/index.js +5 -3
- package/dist/media/index.js.map +1 -1
- package/dist/media/office-visual.d.ts +66 -0
- package/dist/media/office-visual.d.ts.map +1 -0
- package/dist/media/office-visual.js +409 -0
- package/dist/media/office-visual.js.map +1 -0
- package/dist/media/office.d.ts +17 -0
- package/dist/media/office.d.ts.map +1 -1
- package/dist/media/office.js +227 -2
- package/dist/media/office.js.map +1 -1
- package/dist/memory/long-term-store.d.ts +6 -0
- package/dist/memory/long-term-store.d.ts.map +1 -1
- package/dist/memory/long-term-store.js +66 -48
- package/dist/memory/long-term-store.js.map +1 -1
- package/dist/memory/memory-search.d.ts +9 -3
- package/dist/memory/memory-search.d.ts.map +1 -1
- package/dist/memory/memory-search.js +58 -12
- package/dist/memory/memory-search.js.map +1 -1
- package/dist/memory/memory-sync.d.ts +7 -0
- package/dist/memory/memory-sync.d.ts.map +1 -1
- package/dist/memory/memory-sync.js +92 -0
- package/dist/memory/memory-sync.js.map +1 -1
- package/dist/memory/notebook.d.ts +7 -0
- package/dist/memory/notebook.d.ts.map +1 -1
- package/dist/memory/notebook.js +624 -24
- package/dist/memory/notebook.js.map +1 -1
- package/dist/models/config.d.ts.map +1 -1
- package/dist/models/config.js +7 -4
- package/dist/models/config.js.map +1 -1
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +1 -0
- package/dist/models/index.js.map +1 -1
- package/dist/models/model-limits.d.ts +13 -0
- package/dist/models/model-limits.d.ts.map +1 -0
- package/dist/models/model-limits.js +79 -0
- package/dist/models/model-limits.js.map +1 -0
- package/dist/network/discovery.d.ts +2 -0
- package/dist/network/discovery.d.ts.map +1 -1
- package/dist/network/discovery.js +10 -5
- package/dist/network/discovery.js.map +1 -1
- package/dist/network/global-proxy.d.ts +7 -0
- package/dist/network/global-proxy.d.ts.map +1 -1
- package/dist/network/global-proxy.js +67 -0
- package/dist/network/global-proxy.js.map +1 -1
- package/dist/network/index.d.ts +6 -1
- package/dist/network/index.d.ts.map +1 -1
- package/dist/network/index.js +16 -11
- package/dist/network/index.js.map +1 -1
- package/dist/network/transport.d.ts +41 -4
- package/dist/network/transport.d.ts.map +1 -1
- package/dist/network/transport.js +234 -61
- package/dist/network/transport.js.map +1 -1
- package/dist/network/types.d.ts +19 -1
- package/dist/network/types.d.ts.map +1 -1
- package/dist/network/types.js.map +1 -1
- package/dist/notifications/cmux.d.ts +115 -0
- package/dist/notifications/cmux.d.ts.map +1 -0
- package/dist/notifications/cmux.js +436 -0
- package/dist/notifications/cmux.js.map +1 -0
- package/dist/prompt/attachments.d.ts +8 -0
- package/dist/prompt/attachments.d.ts.map +1 -1
- package/dist/prompt/attachments.js +74 -2
- package/dist/prompt/attachments.js.map +1 -1
- package/dist/prompt/builder.js +1 -1
- package/dist/prompt/builder.js.map +1 -1
- package/dist/prompt/cache.d.ts +1 -6
- package/dist/prompt/cache.d.ts.map +1 -1
- package/dist/prompt/cache.js +37 -7
- package/dist/prompt/cache.js.map +1 -1
- package/dist/prompt/templates.d.ts +1 -1
- package/dist/prompt/templates.d.ts.map +1 -1
- package/dist/prompt/templates.js +4 -3
- package/dist/prompt/templates.js.map +1 -1
- package/dist/prompt/types.d.ts +3 -1
- package/dist/prompt/types.d.ts.map +1 -1
- package/dist/prompt/types.js.map +1 -1
- package/dist/proxy/server.d.ts.map +1 -1
- package/dist/proxy/server.js +32 -11
- package/dist/proxy/server.js.map +1 -1
- package/dist/search/ripgrep.d.ts.map +1 -1
- package/dist/search/ripgrep.js +11 -0
- package/dist/search/ripgrep.js.map +1 -1
- package/dist/session/index.d.ts +3 -0
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +1 -0
- package/dist/session/index.js.map +1 -1
- package/dist/skills/builtin/algorithmic-art/LICENSE.txt +202 -0
- package/dist/skills/builtin/algorithmic-art/SKILL.md +405 -0
- package/dist/skills/builtin/algorithmic-art/templates/generator_template.js +223 -0
- package/dist/skills/builtin/algorithmic-art/templates/viewer.html +599 -0
- package/dist/skills/builtin/analyze-logs/SKILL.md +75 -0
- package/dist/skills/builtin/audit-official/SKILL.md +81 -0
- package/dist/skills/builtin/brand-guidelines/LICENSE.txt +202 -0
- package/dist/skills/builtin/brand-guidelines/SKILL.md +73 -0
- package/dist/skills/builtin/build-portable/SKILL.md +53 -0
- package/dist/skills/builtin/canvas-design/SKILL.md +130 -0
- package/dist/skills/builtin/changelog/SKILL.md +65 -0
- package/dist/skills/builtin/code-review/SKILL.md +75 -0
- package/dist/skills/builtin/doc-coauthoring/SKILL.md +375 -0
- package/dist/skills/builtin/doctor/SKILL.md +166 -0
- package/dist/skills/builtin/docx/LICENSE.txt +30 -0
- package/dist/skills/builtin/docx/SKILL.md +590 -0
- package/dist/skills/builtin/docx/scripts/__init__.py +1 -0
- package/dist/skills/builtin/docx/scripts/accept_changes.py +135 -0
- package/dist/skills/builtin/docx/scripts/comment.py +318 -0
- package/dist/skills/builtin/docx/scripts/office/helpers/__init__.py +0 -0
- package/dist/skills/builtin/docx/scripts/office/helpers/merge_runs.py +199 -0
- package/dist/skills/builtin/docx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/dist/skills/builtin/docx/scripts/office/pack.py +159 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/dist/skills/builtin/docx/scripts/office/soffice.py +183 -0
- package/dist/skills/builtin/docx/scripts/office/unpack.py +132 -0
- package/dist/skills/builtin/docx/scripts/office/validate.py +111 -0
- package/dist/skills/builtin/docx/scripts/office/validators/__init__.py +15 -0
- package/dist/skills/builtin/docx/scripts/office/validators/base.py +847 -0
- package/dist/skills/builtin/docx/scripts/office/validators/docx.py +446 -0
- package/dist/skills/builtin/docx/scripts/office/validators/pptx.py +275 -0
- package/dist/skills/builtin/docx/scripts/office/validators/redlining.py +247 -0
- package/dist/skills/builtin/docx/scripts/templates/comments.xml +3 -0
- package/dist/skills/builtin/docx/scripts/templates/commentsExtended.xml +3 -0
- package/dist/skills/builtin/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/dist/skills/builtin/docx/scripts/templates/commentsIds.xml +3 -0
- package/dist/skills/builtin/docx/scripts/templates/people.xml +3 -0
- package/dist/skills/builtin/frontend-design/LICENSE.txt +177 -0
- package/dist/skills/builtin/frontend-design/SKILL.md +42 -0
- package/dist/skills/builtin/i18n-check/SKILL.md +56 -0
- package/dist/skills/builtin/internal-comms/LICENSE.txt +202 -0
- package/dist/skills/builtin/internal-comms/SKILL.md +32 -0
- package/dist/skills/builtin/internal-comms/examples/3p-updates.md +47 -0
- package/dist/skills/builtin/internal-comms/examples/company-newsletter.md +65 -0
- package/dist/skills/builtin/internal-comms/examples/faq-answers.md +30 -0
- package/dist/skills/builtin/internal-comms/examples/general-comms.md +16 -0
- package/dist/skills/builtin/mcp-builder/LICENSE.txt +202 -0
- package/dist/skills/builtin/mcp-builder/SKILL.md +236 -0
- package/dist/skills/builtin/mcp-builder/reference/evaluation.md +602 -0
- package/dist/skills/builtin/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/dist/skills/builtin/mcp-builder/reference/node_mcp_server.md +970 -0
- package/dist/skills/builtin/mcp-builder/reference/python_mcp_server.md +719 -0
- package/dist/skills/builtin/mcp-builder/scripts/connections.py +151 -0
- package/dist/skills/builtin/mcp-builder/scripts/evaluation.py +373 -0
- package/dist/skills/builtin/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/dist/skills/builtin/mcp-builder/scripts/requirements.txt +2 -0
- package/dist/skills/builtin/pdf/LICENSE.txt +30 -0
- package/dist/skills/builtin/pdf/SKILL.md +314 -0
- package/dist/skills/builtin/pdf/forms.md +294 -0
- package/dist/skills/builtin/pdf/reference.md +612 -0
- package/dist/skills/builtin/pdf/scripts/check_bounding_boxes.py +65 -0
- package/dist/skills/builtin/pdf/scripts/check_fillable_fields.py +11 -0
- package/dist/skills/builtin/pdf/scripts/convert_pdf_to_images.py +33 -0
- package/dist/skills/builtin/pdf/scripts/create_validation_image.py +37 -0
- package/dist/skills/builtin/pdf/scripts/extract_form_field_info.py +122 -0
- package/dist/skills/builtin/pdf/scripts/extract_form_structure.py +115 -0
- package/dist/skills/builtin/pdf/scripts/fill_fillable_fields.py +98 -0
- package/dist/skills/builtin/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/dist/skills/builtin/pptx/LICENSE.txt +30 -0
- package/dist/skills/builtin/pptx/SKILL.md +232 -0
- package/dist/skills/builtin/pptx/editing.md +205 -0
- package/dist/skills/builtin/pptx/pptxgenjs.md +420 -0
- package/dist/skills/builtin/pptx/scripts/__init__.py +0 -0
- package/dist/skills/builtin/pptx/scripts/add_slide.py +195 -0
- package/dist/skills/builtin/pptx/scripts/clean.py +286 -0
- package/dist/skills/builtin/pptx/scripts/office/helpers/__init__.py +0 -0
- package/dist/skills/builtin/pptx/scripts/office/helpers/merge_runs.py +199 -0
- package/dist/skills/builtin/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/dist/skills/builtin/pptx/scripts/office/pack.py +159 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/dist/skills/builtin/pptx/scripts/office/soffice.py +183 -0
- package/dist/skills/builtin/pptx/scripts/office/unpack.py +132 -0
- package/dist/skills/builtin/pptx/scripts/office/validate.py +111 -0
- package/dist/skills/builtin/pptx/scripts/office/validators/__init__.py +15 -0
- package/dist/skills/builtin/pptx/scripts/office/validators/base.py +847 -0
- package/dist/skills/builtin/pptx/scripts/office/validators/docx.py +446 -0
- package/dist/skills/builtin/pptx/scripts/office/validators/pptx.py +275 -0
- package/dist/skills/builtin/pptx/scripts/office/validators/redlining.py +247 -0
- package/dist/skills/builtin/pptx/scripts/thumbnail.py +289 -0
- package/dist/skills/builtin/promo-video/SKILL.md +124 -0
- package/dist/skills/builtin/promote/SKILL.md +77 -0
- package/dist/skills/builtin/skill-creator/LICENSE.txt +202 -0
- package/dist/skills/builtin/skill-creator/SKILL.md +598 -0
- package/dist/skills/builtin/skill-creator/agents/analyzer.md +274 -0
- package/dist/skills/builtin/skill-creator/agents/comparator.md +202 -0
- package/dist/skills/builtin/skill-creator/agents/grader.md +223 -0
- package/dist/skills/builtin/skill-creator/assets/eval_review.html +146 -0
- package/dist/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -0
- package/dist/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -0
- package/dist/skills/builtin/skill-creator/references/schemas.md +430 -0
- package/dist/skills/builtin/skill-creator/scripts/__init__.py +0 -0
- package/dist/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/dist/skills/builtin/skill-creator/scripts/generate_report.py +326 -0
- package/dist/skills/builtin/skill-creator/scripts/improve_description.py +248 -0
- package/dist/skills/builtin/skill-creator/scripts/package_skill.py +136 -0
- package/dist/skills/builtin/skill-creator/scripts/quick_validate.py +103 -0
- package/dist/skills/builtin/skill-creator/scripts/run_eval.py +310 -0
- package/dist/skills/builtin/skill-creator/scripts/run_loop.py +332 -0
- package/dist/skills/builtin/skill-creator/scripts/utils.py +47 -0
- package/dist/skills/builtin/slack-gif-creator/LICENSE.txt +202 -0
- package/dist/skills/builtin/slack-gif-creator/SKILL.md +254 -0
- package/dist/skills/builtin/slack-gif-creator/core/easing.py +234 -0
- package/dist/skills/builtin/slack-gif-creator/core/frame_composer.py +176 -0
- package/dist/skills/builtin/slack-gif-creator/core/gif_builder.py +269 -0
- package/dist/skills/builtin/slack-gif-creator/core/validators.py +136 -0
- package/dist/skills/builtin/slack-gif-creator/requirements.txt +4 -0
- package/dist/skills/builtin/sync-version/SKILL.md +39 -0
- package/dist/skills/builtin/theme-factory/LICENSE.txt +202 -0
- package/dist/skills/builtin/theme-factory/SKILL.md +59 -0
- package/dist/skills/builtin/theme-factory/theme-showcase.pdf +0 -0
- package/dist/skills/builtin/theme-factory/themes/arctic-frost.md +19 -0
- package/dist/skills/builtin/theme-factory/themes/botanical-garden.md +19 -0
- package/dist/skills/builtin/theme-factory/themes/desert-rose.md +19 -0
- package/dist/skills/builtin/theme-factory/themes/forest-canopy.md +19 -0
- package/dist/skills/builtin/theme-factory/themes/golden-hour.md +19 -0
- package/dist/skills/builtin/theme-factory/themes/midnight-galaxy.md +19 -0
- package/dist/skills/builtin/theme-factory/themes/modern-minimalist.md +19 -0
- package/dist/skills/builtin/theme-factory/themes/ocean-depths.md +19 -0
- package/dist/skills/builtin/theme-factory/themes/sunset-boulevard.md +19 -0
- package/dist/skills/builtin/theme-factory/themes/tech-innovation.md +19 -0
- package/dist/skills/builtin/web-artifacts-builder/LICENSE.txt +202 -0
- package/dist/skills/builtin/web-artifacts-builder/SKILL.md +74 -0
- package/dist/skills/builtin/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/dist/skills/builtin/web-artifacts-builder/scripts/init-artifact.sh +322 -0
- package/dist/skills/builtin/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/dist/skills/builtin/webapp-testing/LICENSE.txt +202 -0
- package/dist/skills/builtin/webapp-testing/SKILL.md +96 -0
- package/dist/skills/builtin/webapp-testing/examples/console_logging.py +35 -0
- package/dist/skills/builtin/webapp-testing/examples/element_discovery.py +40 -0
- package/dist/skills/builtin/webapp-testing/examples/static_html_automation.py +33 -0
- package/dist/skills/builtin/webapp-testing/scripts/with_server.py +106 -0
- package/dist/skills/builtin/xlsx/LICENSE.txt +30 -0
- package/dist/skills/builtin/xlsx/SKILL.md +292 -0
- package/dist/skills/builtin/xlsx/scripts/office/helpers/__init__.py +0 -0
- package/dist/skills/builtin/xlsx/scripts/office/helpers/merge_runs.py +199 -0
- package/dist/skills/builtin/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/dist/skills/builtin/xlsx/scripts/office/pack.py +159 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/dist/skills/builtin/xlsx/scripts/office/soffice.py +183 -0
- package/dist/skills/builtin/xlsx/scripts/office/unpack.py +132 -0
- package/dist/skills/builtin/xlsx/scripts/office/validate.py +111 -0
- package/dist/skills/builtin/xlsx/scripts/office/validators/__init__.py +15 -0
- package/dist/skills/builtin/xlsx/scripts/office/validators/base.py +847 -0
- package/dist/skills/builtin/xlsx/scripts/office/validators/docx.py +446 -0
- package/dist/skills/builtin/xlsx/scripts/office/validators/pptx.py +275 -0
- package/dist/skills/builtin/xlsx/scripts/office/validators/redlining.py +247 -0
- package/dist/skills/builtin/xlsx/scripts/recalc.py +184 -0
- package/dist/tools/agent.d.ts +8 -0
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/agent.js +66 -2
- package/dist/tools/agent.js.map +1 -1
- package/dist/tools/base.d.ts +16 -0
- package/dist/tools/base.d.ts.map +1 -1
- package/dist/tools/base.js +32 -0
- package/dist/tools/base.js.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +8 -0
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/file.d.ts +3 -1
- package/dist/tools/file.d.ts.map +1 -1
- package/dist/tools/file.js +176 -117
- package/dist/tools/file.js.map +1 -1
- package/dist/tools/generate-design.d.ts +5 -1
- package/dist/tools/generate-design.d.ts.map +1 -1
- package/dist/tools/generate-design.js +25 -3
- package/dist/tools/generate-design.js.map +1 -1
- package/dist/tools/goal.d.ts +1 -1
- package/dist/tools/goal.d.ts.map +1 -1
- package/dist/tools/goal.js +18 -9
- package/dist/tools/goal.js.map +1 -1
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +74 -5
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools/mcp.js +5 -0
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/memory-search.d.ts +1 -1
- package/dist/tools/memory-search.d.ts.map +1 -1
- package/dist/tools/memory-search.js +1 -1
- package/dist/tools/memory-search.js.map +1 -1
- package/dist/tools/network-agent.js +2 -1
- package/dist/tools/network-agent.js.map +1 -1
- package/dist/tools/notebook-write.d.ts.map +1 -1
- package/dist/tools/notebook-write.js +3 -1
- package/dist/tools/notebook-write.js.map +1 -1
- package/dist/tools/schedule.d.ts.map +1 -1
- package/dist/tools/schedule.js +2 -26
- package/dist/tools/schedule.js.map +1 -1
- package/dist/tools/skill.d.ts +1 -7
- package/dist/tools/skill.d.ts.map +1 -1
- package/dist/tools/skill.js +225 -61
- package/dist/tools/skill.js.map +1 -1
- package/dist/types/messages.d.ts +1 -5
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/web/server/api-manager.d.ts +9 -4
- package/dist/web/server/api-manager.d.ts.map +1 -1
- package/dist/web/server/api-manager.js +173 -63
- package/dist/web/server/api-manager.js.map +1 -1
- package/dist/web/server/app-manager.d.ts +71 -0
- package/dist/web/server/app-manager.d.ts.map +1 -0
- package/dist/web/server/app-manager.js +364 -0
- package/dist/web/server/app-manager.js.map +1 -0
- package/dist/web/server/channels/bridge.d.ts.map +1 -1
- package/dist/web/server/channels/bridge.js +2 -1
- package/dist/web/server/channels/bridge.js.map +1 -1
- package/dist/web/server/codex-auth-manager.d.ts +43 -0
- package/dist/web/server/codex-auth-manager.d.ts.map +1 -0
- package/dist/web/server/codex-auth-manager.js +429 -0
- package/dist/web/server/codex-auth-manager.js.map +1 -0
- package/dist/web/server/conversation.d.ts +34 -5
- package/dist/web/server/conversation.d.ts.map +1 -1
- package/dist/web/server/conversation.js +435 -142
- package/dist/web/server/conversation.js.map +1 -1
- package/dist/web/server/image-attachments.d.ts +23 -0
- package/dist/web/server/image-attachments.d.ts.map +1 -0
- package/dist/web/server/image-attachments.js +93 -0
- package/dist/web/server/image-attachments.js.map +1 -0
- package/dist/web/server/index.d.ts.map +1 -1
- package/dist/web/server/index.js +28 -0
- package/dist/web/server/index.js.map +1 -1
- package/dist/web/server/routes/__tests__/app-api.test.d.ts +5 -0
- package/dist/web/server/routes/__tests__/app-api.test.d.ts.map +1 -0
- package/dist/web/server/routes/__tests__/app-api.test.js +48 -0
- package/dist/web/server/routes/__tests__/app-api.test.js.map +1 -0
- package/dist/web/server/routes/__tests__/tunnel-api.test.d.ts +2 -0
- package/dist/web/server/routes/__tests__/tunnel-api.test.d.ts.map +1 -0
- package/dist/web/server/routes/__tests__/tunnel-api.test.js +96 -0
- package/dist/web/server/routes/__tests__/tunnel-api.test.js.map +1 -0
- package/dist/web/server/routes/ai-editor.d.ts.map +1 -1
- package/dist/web/server/routes/ai-editor.js +9 -45
- package/dist/web/server/routes/ai-editor.js.map +1 -1
- package/dist/web/server/routes/ai-hover.d.ts.map +1 -1
- package/dist/web/server/routes/ai-hover.js +6 -23
- package/dist/web/server/routes/ai-hover.js.map +1 -1
- package/dist/web/server/routes/api.d.ts.map +1 -1
- package/dist/web/server/routes/api.js +27 -23
- package/dist/web/server/routes/api.js.map +1 -1
- package/dist/web/server/routes/app-api.d.ts +8 -0
- package/dist/web/server/routes/app-api.d.ts.map +1 -0
- package/dist/web/server/routes/app-api.js +191 -0
- package/dist/web/server/routes/app-api.js.map +1 -0
- package/dist/web/server/routes/auth.d.ts.map +1 -1
- package/dist/web/server/routes/auth.js +306 -5
- package/dist/web/server/routes/auth.js.map +1 -1
- package/dist/web/server/routes/autocomplete-api.d.ts.map +1 -1
- package/dist/web/server/routes/autocomplete-api.js +5 -43
- package/dist/web/server/routes/autocomplete-api.js.map +1 -1
- package/dist/web/server/routes/axon-cloud.d.ts.map +1 -1
- package/dist/web/server/routes/axon-cloud.js +352 -1
- package/dist/web/server/routes/axon-cloud.js.map +1 -1
- package/dist/web/server/routes/config-api.d.ts.map +1 -1
- package/dist/web/server/routes/config-api.js +12 -20
- package/dist/web/server/routes/config-api.js.map +1 -1
- package/dist/web/server/routes/download-proxy.d.ts.map +1 -1
- package/dist/web/server/routes/download-proxy.js +234 -12
- package/dist/web/server/routes/download-proxy.js.map +1 -1
- package/dist/web/server/routes/network-api.d.ts +1 -0
- package/dist/web/server/routes/network-api.d.ts.map +1 -1
- package/dist/web/server/routes/network-api.js +36 -11
- package/dist/web/server/routes/network-api.js.map +1 -1
- package/dist/web/server/routes/port-forward.d.ts.map +1 -1
- package/dist/web/server/routes/port-forward.js +3 -2
- package/dist/web/server/routes/port-forward.js.map +1 -1
- package/dist/web/server/routes/schedule-api.d.ts.map +1 -1
- package/dist/web/server/routes/schedule-api.js +5 -1
- package/dist/web/server/routes/schedule-api.js.map +1 -1
- package/dist/web/server/routes/tunnel-api.d.ts +14 -0
- package/dist/web/server/routes/tunnel-api.d.ts.map +1 -0
- package/dist/web/server/routes/tunnel-api.js +52 -0
- package/dist/web/server/routes/tunnel-api.js.map +1 -0
- package/dist/web/server/runtime/api-connection-test.d.ts +18 -0
- package/dist/web/server/runtime/api-connection-test.d.ts.map +1 -0
- package/dist/web/server/runtime/api-connection-test.js +62 -0
- package/dist/web/server/runtime/api-connection-test.js.map +1 -0
- package/dist/web/server/runtime/codex-client.d.ts +35 -0
- package/dist/web/server/runtime/codex-client.d.ts.map +1 -0
- package/dist/web/server/runtime/codex-client.js +1202 -0
- package/dist/web/server/runtime/codex-client.js.map +1 -0
- package/dist/web/server/runtime/factory.d.ts +3 -0
- package/dist/web/server/runtime/factory.d.ts.map +1 -0
- package/dist/web/server/runtime/factory.js +16 -0
- package/dist/web/server/runtime/factory.js.map +1 -0
- package/dist/web/server/runtime/runtime-model-catalog.d.ts +10 -0
- package/dist/web/server/runtime/runtime-model-catalog.d.ts.map +1 -0
- package/dist/web/server/runtime/runtime-model-catalog.js +85 -0
- package/dist/web/server/runtime/runtime-model-catalog.js.map +1 -0
- package/dist/web/server/runtime/runtime-model-list.d.ts +24 -0
- package/dist/web/server/runtime/runtime-model-list.d.ts.map +1 -0
- package/dist/web/server/runtime/runtime-model-list.js +43 -0
- package/dist/web/server/runtime/runtime-model-list.js.map +1 -0
- package/dist/web/server/runtime/runtime-selection.d.ts +17 -0
- package/dist/web/server/runtime/runtime-selection.d.ts.map +1 -0
- package/dist/web/server/runtime/runtime-selection.js +35 -0
- package/dist/web/server/runtime/runtime-selection.js.map +1 -0
- package/dist/web/server/runtime/tool-input-normalizer.d.ts +3 -0
- package/dist/web/server/runtime/tool-input-normalizer.d.ts.map +1 -0
- package/dist/web/server/runtime/tool-input-normalizer.js +52 -0
- package/dist/web/server/runtime/tool-input-normalizer.js.map +1 -0
- package/dist/web/server/runtime/types.d.ts +102 -0
- package/dist/web/server/runtime/types.d.ts.map +1 -0
- package/dist/web/server/runtime/types.js +2 -0
- package/dist/web/server/runtime/types.js.map +1 -0
- package/dist/web/server/runtime/utility-client.d.ts +5 -0
- package/dist/web/server/runtime/utility-client.d.ts.map +1 -0
- package/dist/web/server/runtime/utility-client.js +68 -0
- package/dist/web/server/runtime/utility-client.js.map +1 -0
- package/dist/web/server/services/axon-cloud-service.d.ts +24 -0
- package/dist/web/server/services/axon-cloud-service.d.ts.map +1 -1
- package/dist/web/server/services/axon-cloud-service.js +93 -0
- package/dist/web/server/services/axon-cloud-service.js.map +1 -1
- package/dist/web/server/services/config-service.d.ts +8 -2
- package/dist/web/server/services/config-service.d.ts.map +1 -1
- package/dist/web/server/services/config-service.js +51 -0
- package/dist/web/server/services/config-service.js.map +1 -1
- package/dist/web/server/services/gemini-image-service.d.ts +20 -1
- package/dist/web/server/services/gemini-image-service.d.ts.map +1 -1
- package/dist/web/server/services/gemini-image-service.js +121 -13
- package/dist/web/server/services/gemini-image-service.js.map +1 -1
- package/dist/web/server/session-manager.d.ts +10 -0
- package/dist/web/server/session-manager.d.ts.map +1 -1
- package/dist/web/server/session-manager.js +39 -0
- package/dist/web/server/session-manager.js.map +1 -1
- package/dist/web/server/slash-commands.d.ts.map +1 -1
- package/dist/web/server/slash-commands.js +127 -25
- package/dist/web/server/slash-commands.js.map +1 -1
- package/dist/web/server/task-manager.d.ts +4 -15
- package/dist/web/server/task-manager.d.ts.map +1 -1
- package/dist/web/server/task-manager.js +11 -4
- package/dist/web/server/task-manager.js.map +1 -1
- package/dist/web/server/tunnel.d.ts +47 -0
- package/dist/web/server/tunnel.d.ts.map +1 -0
- package/dist/web/server/tunnel.js +165 -0
- package/dist/web/server/tunnel.js.map +1 -0
- package/dist/web/server/user-interaction.d.ts +10 -0
- package/dist/web/server/user-interaction.d.ts.map +1 -1
- package/dist/web/server/user-interaction.js +28 -0
- package/dist/web/server/user-interaction.js.map +1 -1
- package/dist/web/server/web-auth.d.ts +35 -3
- package/dist/web/server/web-auth.d.ts.map +1 -1
- package/dist/web/server/web-auth.js +302 -29
- package/dist/web/server/web-auth.js.map +1 -1
- package/dist/web/server/web-scheduler.d.ts.map +1 -1
- package/dist/web/server/web-scheduler.js +9 -0
- package/dist/web/server/web-scheduler.js.map +1 -1
- package/dist/web/server/websocket-git-handlers.d.ts.map +1 -1
- package/dist/web/server/websocket-git-handlers.js +5 -29
- package/dist/web/server/websocket-git-handlers.js.map +1 -1
- package/dist/web/server/websocket.d.ts.map +1 -1
- package/dist/web/server/websocket.js +246 -70
- package/dist/web/server/websocket.js.map +1 -1
- package/dist/web/shared/auth-summary.d.ts +28 -0
- package/dist/web/shared/auth-summary.d.ts.map +1 -0
- package/dist/web/shared/auth-summary.js +56 -0
- package/dist/web/shared/auth-summary.js.map +1 -0
- package/dist/web/shared/model-catalog.d.ts +31 -0
- package/dist/web/shared/model-catalog.d.ts.map +1 -0
- package/dist/web/shared/model-catalog.js +365 -0
- package/dist/web/shared/model-catalog.js.map +1 -0
- package/dist/web/shared/model-preferences.d.ts +5 -0
- package/dist/web/shared/model-preferences.d.ts.map +1 -0
- package/dist/web/shared/model-preferences.js +13 -0
- package/dist/web/shared/model-preferences.js.map +1 -0
- package/dist/web/shared/runtime-capabilities.d.ts +37 -0
- package/dist/web/shared/runtime-capabilities.d.ts.map +1 -0
- package/dist/web/shared/runtime-capabilities.js +101 -0
- package/dist/web/shared/runtime-capabilities.js.map +1 -0
- package/dist/web/shared/setup-runtime.d.ts +50 -0
- package/dist/web/shared/setup-runtime.d.ts.map +1 -0
- package/dist/web/shared/setup-runtime.js +214 -0
- package/dist/web/shared/setup-runtime.js.map +1 -0
- package/dist/web/shared/thinking-config.d.ts +20 -0
- package/dist/web/shared/thinking-config.d.ts.map +1 -0
- package/dist/web/shared/thinking-config.js +104 -0
- package/dist/web/shared/thinking-config.js.map +1 -0
- package/dist/web/shared/types.d.ts +30 -2
- package/dist/web/shared/types.d.ts.map +1 -1
- package/dist/web/shared/types.js.map +1 -1
- package/electron/main.cjs +15 -3
- package/package.json +6 -2
- package/src/web/client/dist/assets/index-B2M5Nr-5.js +736 -0
- package/src/web/client/dist/assets/index-COEqamS-.css +32 -0
- package/src/web/client/dist/icons/icon-192.png +0 -0
- package/src/web/client/dist/icons/icon-512.png +0 -0
- package/src/web/client/dist/index.html +31 -0
- package/src/web/client/dist/logo.png +0 -0
- package/src/web/client/dist/manifest.webmanifest +25 -0
- package/src/web/client/dist/sw.js +78 -0
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* 对话管理器
|
|
3
3
|
* 封装核心对话逻辑,提供 WebUI 专用接口
|
|
4
4
|
*/
|
|
5
|
-
import { ClaudeClient } from '../../core/client.js';
|
|
6
5
|
import { Session } from '../../core/session.js';
|
|
7
6
|
import { runWithCwd } from '../../core/cwd-context.js';
|
|
8
7
|
import { runWithSessionId } from '../../core/session-context.js';
|
|
@@ -15,6 +14,7 @@ import { createOAuthApiKey } from '../../auth/index.js';
|
|
|
15
14
|
import { UserInteractionHandler } from './user-interaction.js';
|
|
16
15
|
import { PermissionHandler } from './permission-handler.js';
|
|
17
16
|
import { runPreToolUseHooks, runPostToolUseHooks, runPostToolUseFailureHooks } from '../../hooks/index.js';
|
|
17
|
+
import { getChangeTracker } from '../../hooks/auto-verify.js';
|
|
18
18
|
import { WebSessionManager } from './session-manager.js';
|
|
19
19
|
import { walAppend, walCheckpoint } from '../../session/index.js';
|
|
20
20
|
import { TaskManager } from './task-manager.js';
|
|
@@ -45,6 +45,13 @@ import { appendRunLog } from '../../daemon/run-log.js';
|
|
|
45
45
|
import { promptSnippetsManager } from './prompt-snippets.js';
|
|
46
46
|
import { isEvolveRestartRequested, triggerGracefulShutdown } from './evolve-state.js';
|
|
47
47
|
import { loadActiveGoals } from '../../goals/index.js';
|
|
48
|
+
import { getAppManager } from './app-manager.js';
|
|
49
|
+
import { createConversationClient } from './runtime/factory.js';
|
|
50
|
+
import { resolveRuntimeSelection } from './runtime/runtime-selection.js';
|
|
51
|
+
import { normalizeToolInputForWebRuntime } from './runtime/tool-input-normalizer.js';
|
|
52
|
+
import { resolveImageGenSource, } from './image-attachments.js';
|
|
53
|
+
import { getProviderForRuntimeBackend, } from '../shared/model-catalog.js';
|
|
54
|
+
import { mapThinkingConfigToRuntimeOptions, } from '../shared/thinking-config.js';
|
|
48
55
|
import * as fs from 'fs';
|
|
49
56
|
import * as path from 'path';
|
|
50
57
|
import * as os from 'os';
|
|
@@ -360,7 +367,7 @@ export class ConversationManager {
|
|
|
360
367
|
temporarilyEnabledMcpServers = new Set();
|
|
361
368
|
constructor(cwd, defaultModel = 'opus', options) {
|
|
362
369
|
this.cwd = cwd;
|
|
363
|
-
this.defaultModel = defaultModel;
|
|
370
|
+
this.defaultModel = this.normalizeRuntimeModel(defaultModel);
|
|
364
371
|
this.options = options;
|
|
365
372
|
this.sessionManager = new WebSessionManager(cwd);
|
|
366
373
|
this.mcpConfigManager = new McpConfigManager({
|
|
@@ -384,6 +391,13 @@ export class ConversationManager {
|
|
|
384
391
|
});
|
|
385
392
|
// 注册蓝图工具(仅 Web 模式需要,CLI 模式不加载)
|
|
386
393
|
registerBlueprintTools();
|
|
394
|
+
// 初始化插件工具同步 — 将插件注册的工具桥接到 toolRegistry
|
|
395
|
+
// 这样 ConversationLoop 通过 toolRegistry.getDefinitions() 能拿到插件工具,模型 API 可以调用
|
|
396
|
+
const { initPluginToolSync } = await import('../../tools/index.js');
|
|
397
|
+
initPluginToolSync();
|
|
398
|
+
// 发现并加载已安装的插件,触发工具注册事件
|
|
399
|
+
await pluginManager.discover();
|
|
400
|
+
console.log(`[ConversationManager] Plugin discover completed, ${pluginManager.getTools().length} plugin tools synced`);
|
|
387
401
|
// v12.0: 注入 StartLeadAgent 自包含执行上下文(支持 TaskPlan + 结构化错误)
|
|
388
402
|
StartLeadAgentTool.setContext({
|
|
389
403
|
getBlueprint: (id) => blueprintStore.get(id),
|
|
@@ -734,36 +748,79 @@ export class ConversationManager {
|
|
|
734
748
|
/**
|
|
735
749
|
* 计算凭据指纹,用于检测认证变更
|
|
736
750
|
*/
|
|
737
|
-
getCredentialsFingerprint() {
|
|
738
|
-
const creds = webAuth.getCredentials();
|
|
751
|
+
getCredentialsFingerprint(runtimeBackend = this.getRuntimeBackend()) {
|
|
752
|
+
const creds = webAuth.getCredentials(runtimeBackend);
|
|
739
753
|
// 用凭据的关键字段拼接成指纹,任何变更都会导致指纹不同
|
|
740
|
-
return `${creds.apiKey || ''}\0${creds.authToken || ''}\0${creds.baseUrl || ''}`;
|
|
754
|
+
return `${this.getRuntimeProvider(runtimeBackend)}\0${creds.apiKey || ''}\0${creds.authToken || ''}\0${creds.baseUrl || ''}\0${creds.accountId || ''}`;
|
|
741
755
|
}
|
|
742
756
|
/**
|
|
743
757
|
* 检查凭据是否变更,如果变更则重建客户端
|
|
744
758
|
* 处理场景:用户在 WebUI 重新登录/切换 API Key 后,已有会话自动使用新凭据
|
|
745
759
|
*/
|
|
746
760
|
ensureClientCredentialsFresh(state) {
|
|
747
|
-
const currentFingerprint = this.getCredentialsFingerprint();
|
|
761
|
+
const currentFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
|
|
748
762
|
if (state.credentialsFingerprint && state.credentialsFingerprint !== currentFingerprint) {
|
|
749
763
|
console.log('[ConversationManager] Detected auth credentials change, rebuilding client');
|
|
750
|
-
const newConfig = this.buildClientConfig(state.model);
|
|
751
|
-
state.client =
|
|
764
|
+
const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
|
|
765
|
+
state.client = createConversationClient(newConfig);
|
|
752
766
|
state.credentialsFingerprint = currentFingerprint;
|
|
753
767
|
}
|
|
754
768
|
}
|
|
769
|
+
getRuntimeBackend() {
|
|
770
|
+
return webAuth.getRuntimeBackend();
|
|
771
|
+
}
|
|
772
|
+
getRuntimeSelection(model, runtimeBackend = this.getRuntimeBackend()) {
|
|
773
|
+
return resolveRuntimeSelection({
|
|
774
|
+
runtimeBackend,
|
|
775
|
+
model,
|
|
776
|
+
defaultModelByBackend: webAuth.getDefaultModelByBackend(),
|
|
777
|
+
customModelCatalogByBackend: webAuth.getCustomModelCatalogByBackend(),
|
|
778
|
+
codexModelName: webAuth.getCodexModelName(),
|
|
779
|
+
customModelName: webAuth.getCustomModelName(),
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
getRuntimeProvider(runtimeBackend = this.getRuntimeBackend()) {
|
|
783
|
+
return this.getRuntimeSelection(undefined, runtimeBackend).provider;
|
|
784
|
+
}
|
|
785
|
+
getRuntimeCustomModelName(runtimeBackend = this.getRuntimeBackend()) {
|
|
786
|
+
return this.getRuntimeSelection(undefined, runtimeBackend).customModelName;
|
|
787
|
+
}
|
|
788
|
+
normalizeRuntimeModel(model, runtimeBackend = this.getRuntimeBackend()) {
|
|
789
|
+
return this.getRuntimeSelection(model, runtimeBackend).normalizedModel;
|
|
790
|
+
}
|
|
791
|
+
ensureStateModelMatchesRuntime(state) {
|
|
792
|
+
const normalizedModel = this.normalizeRuntimeModel(state.model, state.runtimeBackend);
|
|
793
|
+
if (normalizedModel === state.model) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
state.model = normalizedModel;
|
|
797
|
+
state.client = createConversationClient(this.buildClientConfig(normalizedModel, state.runtimeBackend));
|
|
798
|
+
}
|
|
755
799
|
/**
|
|
756
800
|
* 构建 ClaudeClient 配置
|
|
757
801
|
* 认证全部委托给 webAuth(唯一认证入口)
|
|
758
802
|
*/
|
|
759
|
-
buildClientConfig(model) {
|
|
760
|
-
const creds = webAuth.getCredentials();
|
|
761
|
-
const
|
|
803
|
+
buildClientConfig(model, runtimeBackend = this.getRuntimeBackend()) {
|
|
804
|
+
const creds = webAuth.getCredentials(runtimeBackend);
|
|
805
|
+
const selection = this.getRuntimeSelection(model, runtimeBackend);
|
|
806
|
+
const normalizedModel = selection.normalizedModel;
|
|
807
|
+
const provider = selection.provider;
|
|
808
|
+
const customModel = selection.customModelName;
|
|
809
|
+
const authStatus = webAuth.getStatus();
|
|
810
|
+
const identityVariant = provider === 'anthropic'
|
|
811
|
+
&& runtimeBackend === 'claude-compatible-api'
|
|
812
|
+
&& authStatus.type === 'oauth'
|
|
813
|
+
? 'agent'
|
|
814
|
+
: undefined;
|
|
762
815
|
return {
|
|
763
|
-
|
|
816
|
+
provider,
|
|
817
|
+
model: provider === 'codex' ? normalizedModel : this.getModelId(normalizedModel),
|
|
764
818
|
apiKey: creds.apiKey,
|
|
765
819
|
authToken: creds.authToken,
|
|
766
820
|
baseUrl: creds.baseUrl,
|
|
821
|
+
accountId: creds.accountId,
|
|
822
|
+
customModelName: customModel,
|
|
823
|
+
identityVariant,
|
|
767
824
|
timeout: 300000,
|
|
768
825
|
};
|
|
769
826
|
}
|
|
@@ -777,6 +834,7 @@ export class ConversationManager {
|
|
|
777
834
|
apiKey: config.apiKey,
|
|
778
835
|
authToken: config.authToken,
|
|
779
836
|
baseUrl: config.baseUrl,
|
|
837
|
+
accountId: config.accountId,
|
|
780
838
|
};
|
|
781
839
|
}
|
|
782
840
|
/**
|
|
@@ -784,6 +842,26 @@ export class ConversationManager {
|
|
|
784
842
|
* 这个方法在每次调用 API 之前被调用,检查 token 是否过期,如果过期则自动刷新
|
|
785
843
|
*/
|
|
786
844
|
async ensureValidOAuthToken(state) {
|
|
845
|
+
const runtimeProvider = getProviderForRuntimeBackend(state.runtimeBackend, state.model);
|
|
846
|
+
const authStatus = webAuth.getStatus();
|
|
847
|
+
if (runtimeProvider !== 'anthropic') {
|
|
848
|
+
const tokenBefore = webAuth.getCredentials(state.runtimeBackend).authToken;
|
|
849
|
+
const refreshOk = await webAuth.ensureValidToken(state.runtimeBackend);
|
|
850
|
+
if (!refreshOk) {
|
|
851
|
+
throw new Error('OAuth token expired, refresh failed. Please log in again.');
|
|
852
|
+
}
|
|
853
|
+
const tokenAfter = webAuth.getCredentials(state.runtimeBackend).authToken;
|
|
854
|
+
if (tokenBefore !== tokenAfter) {
|
|
855
|
+
const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
|
|
856
|
+
state.client = createConversationClient(newConfig);
|
|
857
|
+
state.credentialsFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
|
|
858
|
+
console.log('[ConversationManager] Client now using refreshed OAuth credentials');
|
|
859
|
+
}
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
if (authStatus.type !== 'oauth') {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
787
865
|
// 只在使用 OAuth 时处理
|
|
788
866
|
const oauthConfig = oauthManager.getOAuthConfig();
|
|
789
867
|
if (!oauthConfig) {
|
|
@@ -799,9 +877,9 @@ export class ConversationManager {
|
|
|
799
877
|
if (apiKey) {
|
|
800
878
|
await oauthManager.saveOAuthConfig({ oauthApiKey: apiKey });
|
|
801
879
|
console.log('[ConversationManager] OAuth API Key auto-created, rebuilding client');
|
|
802
|
-
const newConfig = this.buildClientConfig(state.model);
|
|
803
|
-
state.client =
|
|
804
|
-
state.credentialsFingerprint = this.getCredentialsFingerprint();
|
|
880
|
+
const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
|
|
881
|
+
state.client = createConversationClient(newConfig);
|
|
882
|
+
state.credentialsFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
|
|
805
883
|
}
|
|
806
884
|
else {
|
|
807
885
|
console.warn('[ConversationManager] createOAuthApiKey returned null, inference may fail');
|
|
@@ -814,16 +892,16 @@ export class ConversationManager {
|
|
|
814
892
|
// 记住刷新前的 token,用于判断是否需要重建客户端
|
|
815
893
|
const tokenBefore = oauthManager.getOAuthConfig()?.accessToken;
|
|
816
894
|
// 统一的 token 有效性检查(对齐官方 NM() 语义)
|
|
817
|
-
const refreshOk = await webAuth.ensureValidToken();
|
|
895
|
+
const refreshOk = await webAuth.ensureValidToken(state.runtimeBackend);
|
|
818
896
|
if (!refreshOk) {
|
|
819
897
|
throw new Error('OAuth token expired, refresh failed. Please log in again.');
|
|
820
898
|
}
|
|
821
899
|
// 只有 token 真正变更了才重建客户端
|
|
822
900
|
const tokenAfter = oauthManager.getOAuthConfig()?.accessToken;
|
|
823
901
|
if (tokenBefore !== tokenAfter) {
|
|
824
|
-
const newConfig = this.buildClientConfig(state.model);
|
|
825
|
-
state.client =
|
|
826
|
-
state.credentialsFingerprint = this.getCredentialsFingerprint();
|
|
902
|
+
const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
|
|
903
|
+
state.client = createConversationClient(newConfig);
|
|
904
|
+
state.credentialsFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
|
|
827
905
|
console.log('[ConversationManager] Client now using refreshed OAuth credentials');
|
|
828
906
|
}
|
|
829
907
|
}
|
|
@@ -834,6 +912,8 @@ export class ConversationManager {
|
|
|
834
912
|
async getOrCreateSession(sessionId, model, projectPath, permissionMode) {
|
|
835
913
|
let state = this.sessions.get(sessionId);
|
|
836
914
|
if (state) {
|
|
915
|
+
state.runtimeBackend = state.runtimeBackend || this.getRuntimeBackend();
|
|
916
|
+
this.ensureStateModelMatchesRuntime(state);
|
|
837
917
|
// 会话已存在,检查是否需要更新工作目录
|
|
838
918
|
if (projectPath && state.session.cwd !== projectPath) {
|
|
839
919
|
console.log(`[ConversationManager] Updated session ${sessionId} working directory: ${state.session.cwd} -> ${projectPath}`);
|
|
@@ -848,15 +928,14 @@ export class ConversationManager {
|
|
|
848
928
|
}
|
|
849
929
|
// 创建新会话
|
|
850
930
|
const workingDir = projectPath || this.cwd;
|
|
931
|
+
const runtimeBackend = this.getRuntimeBackend();
|
|
932
|
+
const resolvedModel = this.normalizeRuntimeModel(model || this.defaultModel, runtimeBackend);
|
|
851
933
|
console.log(`[ConversationManager] Creating new session ${sessionId}, workingDir: ${workingDir}, permissionMode: ${permissionMode || 'default'}`);
|
|
852
934
|
const session = new Session(workingDir, sessionId);
|
|
853
935
|
await session.initializeGitInfo();
|
|
854
936
|
// 使用与核心 loop.ts 一致的认证逻辑
|
|
855
|
-
const clientConfig = this.buildClientConfig(
|
|
856
|
-
const client =
|
|
857
|
-
...clientConfig,
|
|
858
|
-
timeout: clientConfig.timeout,
|
|
859
|
-
});
|
|
937
|
+
const clientConfig = this.buildClientConfig(resolvedModel, runtimeBackend);
|
|
938
|
+
const client = createConversationClient(clientConfig);
|
|
860
939
|
// 创建用户交互处理器
|
|
861
940
|
const userInteractionHandler = new UserInteractionHandler();
|
|
862
941
|
userInteractionHandler.setSessionId(sessionId);
|
|
@@ -870,7 +949,8 @@ export class ConversationManager {
|
|
|
870
949
|
session,
|
|
871
950
|
client,
|
|
872
951
|
messages: [],
|
|
873
|
-
model:
|
|
952
|
+
model: resolvedModel,
|
|
953
|
+
runtimeBackend,
|
|
874
954
|
cancelled: false,
|
|
875
955
|
chatHistory: [],
|
|
876
956
|
userInteractionHandler,
|
|
@@ -887,8 +967,9 @@ export class ConversationManager {
|
|
|
887
967
|
processingGeneration: 0,
|
|
888
968
|
lastActualInputTokens: 0,
|
|
889
969
|
messagesLenAtLastApiCall: 0,
|
|
970
|
+
latestImageAttachments: [],
|
|
890
971
|
lastPersistedMessageCount: 0,
|
|
891
|
-
credentialsFingerprint: this.getCredentialsFingerprint(),
|
|
972
|
+
credentialsFingerprint: this.getCredentialsFingerprint(runtimeBackend),
|
|
892
973
|
};
|
|
893
974
|
this.sessions.set(sessionId, state);
|
|
894
975
|
// 初始化 session memory(官方 session-memory 功能)
|
|
@@ -925,15 +1006,28 @@ export class ConversationManager {
|
|
|
925
1006
|
setModel(sessionId, model) {
|
|
926
1007
|
const state = this.sessions.get(sessionId);
|
|
927
1008
|
if (state) {
|
|
928
|
-
|
|
1009
|
+
const normalizedModel = this.normalizeRuntimeModel(model, state.runtimeBackend);
|
|
1010
|
+
state.model = normalizedModel;
|
|
929
1011
|
// 使用与核心 loop.ts 一致的认证逻辑
|
|
930
|
-
const clientConfig = this.buildClientConfig(
|
|
931
|
-
state.client =
|
|
932
|
-
...clientConfig,
|
|
933
|
-
timeout: clientConfig.timeout,
|
|
934
|
-
});
|
|
1012
|
+
const clientConfig = this.buildClientConfig(normalizedModel, state.runtimeBackend);
|
|
1013
|
+
state.client = createConversationClient(clientConfig);
|
|
935
1014
|
}
|
|
936
1015
|
}
|
|
1016
|
+
getSessionModel(sessionId) {
|
|
1017
|
+
const state = this.sessions.get(sessionId);
|
|
1018
|
+
if (!state) {
|
|
1019
|
+
return null;
|
|
1020
|
+
}
|
|
1021
|
+
this.ensureStateModelMatchesRuntime(state);
|
|
1022
|
+
return state.model;
|
|
1023
|
+
}
|
|
1024
|
+
getSessionRuntimeBackend(sessionId) {
|
|
1025
|
+
const state = this.sessions.get(sessionId);
|
|
1026
|
+
if (!state) {
|
|
1027
|
+
return null;
|
|
1028
|
+
}
|
|
1029
|
+
return state.runtimeBackend;
|
|
1030
|
+
}
|
|
937
1031
|
/**
|
|
938
1032
|
* 获取历史记录
|
|
939
1033
|
*/
|
|
@@ -961,7 +1055,7 @@ export class ConversationManager {
|
|
|
961
1055
|
const hasCompactBoundary = state.chatHistory.some(m => m.isCompactBoundary);
|
|
962
1056
|
if (!hasCompactBoundary) {
|
|
963
1057
|
// 未压缩:messages 是完整的,可以安全重建
|
|
964
|
-
return this.convertMessagesToChatHistory(state.messages);
|
|
1058
|
+
return this.convertMessagesToChatHistory(state.messages, state.runtimeBackend);
|
|
965
1059
|
}
|
|
966
1060
|
// 已压缩:以 chatHistory 为基础,找出 messages 中还没同步的增量部分
|
|
967
1061
|
// chatHistory 中最后一条记录的 _messagesLen 表示已经同步到 messages 的哪个位置
|
|
@@ -975,7 +1069,7 @@ export class ConversationManager {
|
|
|
975
1069
|
if (incrementalMessages.length === 0) {
|
|
976
1070
|
return state.chatHistory;
|
|
977
1071
|
}
|
|
978
|
-
const incrementalHistory = this.convertMessagesToChatHistory(incrementalMessages);
|
|
1072
|
+
const incrementalHistory = this.convertMessagesToChatHistory(incrementalMessages, state.runtimeBackend);
|
|
979
1073
|
return [...state.chatHistory, ...incrementalHistory];
|
|
980
1074
|
}
|
|
981
1075
|
/**
|
|
@@ -1134,13 +1228,28 @@ export class ConversationManager {
|
|
|
1134
1228
|
const state = this.sessions.get(sessionId);
|
|
1135
1229
|
return state?.userInteractionHandler.getPendingPayloads() ?? [];
|
|
1136
1230
|
}
|
|
1231
|
+
/**
|
|
1232
|
+
* 获取当前 ws 还未收到的待处理用户问题。
|
|
1233
|
+
* 用于恢复会话时补发,避免重复弹窗。
|
|
1234
|
+
*/
|
|
1235
|
+
getUndeliveredPendingUserQuestions(sessionId) {
|
|
1236
|
+
const state = this.sessions.get(sessionId);
|
|
1237
|
+
return state?.userInteractionHandler.getUndeliveredPayloadsForCurrentWebSocket() ?? [];
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* 标记问题已经送达当前 ws,防止同一连接被重复补发。
|
|
1241
|
+
*/
|
|
1242
|
+
markPendingUserQuestionDelivered(sessionId, requestId) {
|
|
1243
|
+
const state = this.sessions.get(sessionId);
|
|
1244
|
+
state?.userInteractionHandler.markDeliveredToCurrentWebSocket(requestId);
|
|
1245
|
+
}
|
|
1137
1246
|
/**
|
|
1138
1247
|
* 媒体附件信息(图片或 PDF)
|
|
1139
1248
|
*/
|
|
1140
1249
|
/**
|
|
1141
1250
|
* 发送聊天消息
|
|
1142
1251
|
*/
|
|
1143
|
-
async chat(sessionId, content, mediaAttachments, model, callbacks, projectPath, ws, permissionMode, messageId) {
|
|
1252
|
+
async chat(sessionId, content, mediaAttachments, model, callbacks, projectPath, ws, permissionMode, messageId, thinkingConfig) {
|
|
1144
1253
|
const state = await this.getOrCreateSession(sessionId, model, projectPath, permissionMode);
|
|
1145
1254
|
// 插话模式:如果会话正在处理中,取消当前操作并等待其完成
|
|
1146
1255
|
if (state.isProcessing) {
|
|
@@ -1184,6 +1293,9 @@ export class ConversationManager {
|
|
|
1184
1293
|
catch {
|
|
1185
1294
|
// 增强失败不影响主流程
|
|
1186
1295
|
}
|
|
1296
|
+
if (mediaAttachments && mediaAttachments.length > 0) {
|
|
1297
|
+
state.latestImageAttachments = mediaAttachments.map(attachment => ({ ...attachment }));
|
|
1298
|
+
}
|
|
1187
1299
|
// 构建用户消息
|
|
1188
1300
|
const userMessage = {
|
|
1189
1301
|
role: 'user',
|
|
@@ -1217,6 +1329,7 @@ export class ConversationManager {
|
|
|
1217
1329
|
media_type: attachment.mimeType,
|
|
1218
1330
|
data: attachment.data,
|
|
1219
1331
|
},
|
|
1332
|
+
fileName: attachment.name,
|
|
1220
1333
|
});
|
|
1221
1334
|
}
|
|
1222
1335
|
}
|
|
@@ -1226,6 +1339,7 @@ export class ConversationManager {
|
|
|
1226
1339
|
role: 'user',
|
|
1227
1340
|
timestamp: Date.now(),
|
|
1228
1341
|
content: chatContentItems,
|
|
1342
|
+
runtimeBackend: state.runtimeBackend,
|
|
1229
1343
|
_messagesLen: state.messages.length,
|
|
1230
1344
|
};
|
|
1231
1345
|
state.chatHistory.push(chatEntry);
|
|
@@ -1237,7 +1351,7 @@ export class ConversationManager {
|
|
|
1237
1351
|
// 使用工作目录上下文包裹对话循环(与 CLI loop.ts 保持一致)
|
|
1238
1352
|
// 确保所有工具执行都在正确的工作目录上下文中
|
|
1239
1353
|
await runWithCwd(state.session.cwd, async () => {
|
|
1240
|
-
await this.conversationLoop(state, callbacks, sessionId);
|
|
1354
|
+
await this.conversationLoop(state, callbacks, sessionId, thinkingConfig);
|
|
1241
1355
|
});
|
|
1242
1356
|
}
|
|
1243
1357
|
catch (error) {
|
|
@@ -1272,7 +1386,7 @@ export class ConversationManager {
|
|
|
1272
1386
|
/**
|
|
1273
1387
|
* 对话循环
|
|
1274
1388
|
*/
|
|
1275
|
-
async conversationLoop(state, callbacks, sessionId) {
|
|
1389
|
+
async conversationLoop(state, callbacks, sessionId, thinkingConfig) {
|
|
1276
1390
|
let continueLoop = true;
|
|
1277
1391
|
let totalInputTokens = 0;
|
|
1278
1392
|
let totalOutputTokens = 0;
|
|
@@ -1289,12 +1403,23 @@ export class ConversationManager {
|
|
|
1289
1403
|
let messageConsistencyHealed = false;
|
|
1290
1404
|
// 创建 AbortController,用于在取消时中断正在执行的工具
|
|
1291
1405
|
state.currentAbortController = new AbortController();
|
|
1406
|
+
// Auto-verify: 设置全局 sessionId 供工具层追踪文件变更
|
|
1407
|
+
if (sessionId) {
|
|
1408
|
+
globalThis.__currentSessionId = sessionId;
|
|
1409
|
+
}
|
|
1292
1410
|
while (continueLoop && !state.cancelled) {
|
|
1293
1411
|
// 标记本次迭代是否已有内容流式输出到前端
|
|
1294
1412
|
// 如果有内容已输出,则不进行自动重试(避免前端内容重复)
|
|
1295
1413
|
let hasStreamedContent = false;
|
|
1296
1414
|
// 初始化流式中间内容追踪(用于浏览器刷新后恢复)
|
|
1297
1415
|
state.streamingContent = { thinkingText: '', textContent: '' };
|
|
1416
|
+
// Auto-verify: 每轮迭代重置注入标记
|
|
1417
|
+
if (sessionId) {
|
|
1418
|
+
try {
|
|
1419
|
+
getChangeTracker(sessionId).resetTurnFlag();
|
|
1420
|
+
}
|
|
1421
|
+
catch { /* ignore */ }
|
|
1422
|
+
}
|
|
1298
1423
|
// 凭据变更检测(处理用户在 WebUI 重新登录后已有会话自动使用新凭据)
|
|
1299
1424
|
this.ensureClientCredentialsFresh(state);
|
|
1300
1425
|
// OAuth Token 自动刷新检查(在调用 API 之前)
|
|
@@ -1507,10 +1632,18 @@ export class ConversationManager {
|
|
|
1507
1632
|
}
|
|
1508
1633
|
// 将流式状态变量提升到 try 外,以便 catch 中断流自愈时可以访问
|
|
1509
1634
|
const assistantContent = [];
|
|
1635
|
+
let currentThinkingContent = '';
|
|
1510
1636
|
let currentTextContent = '';
|
|
1511
1637
|
let currentToolUse = null;
|
|
1512
1638
|
let stopReason = null;
|
|
1513
1639
|
let thinkingStarted = false;
|
|
1640
|
+
const flushThinkingContent = () => {
|
|
1641
|
+
if (!currentThinkingContent) {
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1644
|
+
assistantContent.push({ type: 'thinking', thinking: currentThinkingContent });
|
|
1645
|
+
currentThinkingContent = '';
|
|
1646
|
+
};
|
|
1514
1647
|
// 对齐官方 v2.1.70:检查是否有 ToolSearch 工具(Mcp),决定是否启用 deferred tools
|
|
1515
1648
|
const hasToolSearch = tools.some(t => t.name === 'Mcp');
|
|
1516
1649
|
// 对齐官方 v2.1.70:注入 <available-deferred-tools> 列表到消息中
|
|
@@ -1542,11 +1675,13 @@ export class ConversationManager {
|
|
|
1542
1675
|
}
|
|
1543
1676
|
}
|
|
1544
1677
|
try {
|
|
1545
|
-
|
|
1678
|
+
const thinkingOptions = mapThinkingConfigToRuntimeOptions(state.runtimeBackend, state.model, thinkingConfig);
|
|
1679
|
+
// 调用运行时 API(思考能力由前端 per-message 配置映射到真实 runtime 选项)
|
|
1546
1680
|
// 传递 abort signal,取消时可直接中止 HTTP 流(对齐官方 CLI)
|
|
1547
1681
|
const stream = state.client.createMessageStream(cleanedMessages, tools, systemPrompt.content, {
|
|
1548
|
-
enableThinking:
|
|
1549
|
-
thinkingBudget:
|
|
1682
|
+
enableThinking: thinkingOptions.enableThinking,
|
|
1683
|
+
thinkingBudget: thinkingOptions.thinkingBudget,
|
|
1684
|
+
reasoningEffort: thinkingOptions.reasoningEffort,
|
|
1550
1685
|
signal: state.currentAbortController?.signal,
|
|
1551
1686
|
promptBlocks: systemPrompt.blocks,
|
|
1552
1687
|
toolSearchEnabled: hasToolSearch,
|
|
@@ -1561,6 +1696,7 @@ export class ConversationManager {
|
|
|
1561
1696
|
thinkingStarted = true;
|
|
1562
1697
|
}
|
|
1563
1698
|
if (event.thinking) {
|
|
1699
|
+
currentThinkingContent += event.thinking;
|
|
1564
1700
|
// 追踪 thinking 内容(用于浏览器刷新恢复)
|
|
1565
1701
|
if (state.streamingContent) {
|
|
1566
1702
|
state.streamingContent.thinkingText += event.thinking;
|
|
@@ -1573,6 +1709,7 @@ export class ConversationManager {
|
|
|
1573
1709
|
callbacks.onThinkingComplete?.();
|
|
1574
1710
|
thinkingStarted = false;
|
|
1575
1711
|
}
|
|
1712
|
+
flushThinkingContent();
|
|
1576
1713
|
if (event.text) {
|
|
1577
1714
|
hasStreamedContent = true;
|
|
1578
1715
|
currentTextContent += event.text;
|
|
@@ -1584,6 +1721,11 @@ export class ConversationManager {
|
|
|
1584
1721
|
}
|
|
1585
1722
|
break;
|
|
1586
1723
|
case 'tool_use_start':
|
|
1724
|
+
if (thinkingStarted) {
|
|
1725
|
+
callbacks.onThinkingComplete?.();
|
|
1726
|
+
thinkingStarted = false;
|
|
1727
|
+
}
|
|
1728
|
+
flushThinkingContent();
|
|
1587
1729
|
hasStreamedContent = true;
|
|
1588
1730
|
// 保存之前的文本内容
|
|
1589
1731
|
if (currentTextContent) {
|
|
@@ -1592,25 +1734,38 @@ export class ConversationManager {
|
|
|
1592
1734
|
}
|
|
1593
1735
|
// 如果有未完成的工具调用(多工具响应时 content_block_stop 不产生事件),先完成它
|
|
1594
1736
|
if (currentToolUse) {
|
|
1737
|
+
// 优先使用 SDK 注入的 parsedInput
|
|
1738
|
+
const sdkPrev = currentToolUse.parsedInput;
|
|
1595
1739
|
let prevInput = {};
|
|
1596
|
-
|
|
1597
|
-
prevInput =
|
|
1740
|
+
if (sdkPrev && typeof sdkPrev === 'object' && Object.keys(sdkPrev).length > 0) {
|
|
1741
|
+
prevInput = sdkPrev;
|
|
1598
1742
|
}
|
|
1599
|
-
|
|
1743
|
+
else {
|
|
1744
|
+
try {
|
|
1745
|
+
prevInput = JSON.parse(currentToolUse.inputJson || '{}');
|
|
1746
|
+
}
|
|
1747
|
+
catch {
|
|
1748
|
+
console.warn(`[StreamDebug] Failed to parse tool input JSON for ${currentToolUse.name} (length=${currentToolUse.inputJson.length}), raw start: ${currentToolUse.inputJson.slice(0, 100)}`);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
console.log(`[StreamDebug] tool_use_start: completing previous tool ${currentToolUse.name}(${currentToolUse.id}), keys=[${Object.keys(prevInput)}]`);
|
|
1600
1752
|
assistantContent.push({
|
|
1601
1753
|
type: 'tool_use',
|
|
1602
1754
|
id: currentToolUse.id,
|
|
1603
1755
|
name: currentToolUse.name,
|
|
1604
1756
|
input: prevInput,
|
|
1605
1757
|
});
|
|
1606
|
-
|
|
1758
|
+
// 通知前端完整 input(参数流完毕)
|
|
1759
|
+
callbacks.onToolUseInputReady?.(currentToolUse.id, prevInput);
|
|
1607
1760
|
}
|
|
1608
|
-
//
|
|
1761
|
+
// 开始新的工具调用 — 立即通知前端(参数尚在流式传输)
|
|
1609
1762
|
currentToolUse = {
|
|
1610
1763
|
id: event.id || '',
|
|
1611
1764
|
name: event.name || '',
|
|
1612
1765
|
inputJson: '',
|
|
1613
1766
|
};
|
|
1767
|
+
console.log(`[StreamDebug] tool_use_start: new tool ${currentToolUse.name}(${currentToolUse.id}), sending _streaming=true to frontend`);
|
|
1768
|
+
callbacks.onToolUseStart?.(currentToolUse.id, currentToolUse.name, { _streaming: true });
|
|
1614
1769
|
break;
|
|
1615
1770
|
case 'tool_use_delta':
|
|
1616
1771
|
if (currentToolUse && event.input) {
|
|
@@ -1618,7 +1773,37 @@ export class ConversationManager {
|
|
|
1618
1773
|
callbacks.onToolUseDelta?.(currentToolUse.id, event.input);
|
|
1619
1774
|
}
|
|
1620
1775
|
break;
|
|
1776
|
+
case 'tool_use_complete': {
|
|
1777
|
+
// 来自 SDK finalMessage 的完整 tool_use(input 已由 SDK parse 好)
|
|
1778
|
+
// 覆盖手动拼接的 inputJson,确保 input 的正确性
|
|
1779
|
+
const completeId = event.id;
|
|
1780
|
+
const completeInput = event.input;
|
|
1781
|
+
console.log(`[StreamDebug] tool_use_complete: id=${completeId}, inputKeys=${completeInput ? Object.keys(completeInput) : 'null'}`);
|
|
1782
|
+
// 如果当前有正在流式接收的工具且 id 匹配,直接注入解析好的 input
|
|
1783
|
+
if (currentToolUse && currentToolUse.id === completeId) {
|
|
1784
|
+
// 把 SDK 解析好的 input 保存到 currentToolUse(stop 事件会用)
|
|
1785
|
+
currentToolUse.parsedInput = completeInput;
|
|
1786
|
+
}
|
|
1787
|
+
else {
|
|
1788
|
+
// 可能是之前已经 push 到 assistantContent 的工具(多工具场景)
|
|
1789
|
+
// 用 SDK 的 input 覆盖手动 parse 的结果
|
|
1790
|
+
for (const block of assistantContent) {
|
|
1791
|
+
if (block.type === 'tool_use' && block.id === completeId) {
|
|
1792
|
+
block.input = completeInput || {};
|
|
1793
|
+
// 同时通知前端更新
|
|
1794
|
+
callbacks.onToolUseInputReady?.(completeId, completeInput || {});
|
|
1795
|
+
break;
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
break;
|
|
1800
|
+
}
|
|
1621
1801
|
case 'stop':
|
|
1802
|
+
if (thinkingStarted) {
|
|
1803
|
+
callbacks.onThinkingComplete?.();
|
|
1804
|
+
thinkingStarted = false;
|
|
1805
|
+
}
|
|
1806
|
+
flushThinkingContent();
|
|
1622
1807
|
// 完成当前文本块
|
|
1623
1808
|
if (currentTextContent) {
|
|
1624
1809
|
assistantContent.push({ type: 'text', text: currentTextContent });
|
|
@@ -1626,12 +1811,22 @@ export class ConversationManager {
|
|
|
1626
1811
|
}
|
|
1627
1812
|
// 完成当前工具调用
|
|
1628
1813
|
if (currentToolUse) {
|
|
1814
|
+
// 优先使用 SDK finalMessage 中的 input(由 tool_use_complete 事件注入)
|
|
1815
|
+
// 回退到手动拼接 inputJson + JSON.parse(兼容非标准 API)
|
|
1629
1816
|
let parsedInput = {};
|
|
1630
|
-
|
|
1631
|
-
|
|
1817
|
+
const sdkInput = currentToolUse.parsedInput;
|
|
1818
|
+
if (sdkInput && typeof sdkInput === 'object' && Object.keys(sdkInput).length > 0) {
|
|
1819
|
+
parsedInput = sdkInput;
|
|
1820
|
+
console.log(`[StreamDebug] stop: using SDK input for ${currentToolUse.name}(${currentToolUse.id}), keys=[${Object.keys(parsedInput)}]`);
|
|
1632
1821
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1822
|
+
else {
|
|
1823
|
+
try {
|
|
1824
|
+
parsedInput = JSON.parse(currentToolUse.inputJson || '{}');
|
|
1825
|
+
console.log(`[StreamDebug] stop: using manual JSON.parse for ${currentToolUse.name}(${currentToolUse.id}), inputJson.length=${currentToolUse.inputJson.length}, keys=[${Object.keys(parsedInput)}]`);
|
|
1826
|
+
}
|
|
1827
|
+
catch (e) {
|
|
1828
|
+
console.warn(`[StreamDebug] stop: JSON.parse FAILED for ${currentToolUse.name} (length=${currentToolUse.inputJson.length}, stopReason=${event.stopReason}), raw start: ${currentToolUse.inputJson.slice(0, 200)}`);
|
|
1829
|
+
}
|
|
1635
1830
|
}
|
|
1636
1831
|
assistantContent.push({
|
|
1637
1832
|
type: 'tool_use',
|
|
@@ -1639,8 +1834,8 @@ export class ConversationManager {
|
|
|
1639
1834
|
name: currentToolUse.name,
|
|
1640
1835
|
input: parsedInput,
|
|
1641
1836
|
});
|
|
1642
|
-
//
|
|
1643
|
-
callbacks.
|
|
1837
|
+
// 通知前端完整 input(onToolUseStart 已在 tool_use_start 事件时发送)
|
|
1838
|
+
callbacks.onToolUseInputReady?.(currentToolUse.id, parsedInput);
|
|
1644
1839
|
currentToolUse = null;
|
|
1645
1840
|
}
|
|
1646
1841
|
stopReason = event.stopReason || null;
|
|
@@ -1706,6 +1901,7 @@ export class ConversationManager {
|
|
|
1706
1901
|
networkRetryCount = 0;
|
|
1707
1902
|
justForceCompacted = false;
|
|
1708
1903
|
// 中断或正常结束时,保存未完成的文本内容
|
|
1904
|
+
flushThinkingContent();
|
|
1709
1905
|
if (currentTextContent) {
|
|
1710
1906
|
assistantContent.push({ type: 'text', text: currentTextContent });
|
|
1711
1907
|
currentTextContent = '';
|
|
@@ -1794,6 +1990,28 @@ export class ConversationManager {
|
|
|
1794
1990
|
allNewMessages.push(...result.newMessages);
|
|
1795
1991
|
}
|
|
1796
1992
|
}
|
|
1993
|
+
// Auto-verify: 注入验证提示到最后一个工具结果
|
|
1994
|
+
if (sessionId && toolResults.length > 0) {
|
|
1995
|
+
try {
|
|
1996
|
+
const tracker = getChangeTracker(sessionId);
|
|
1997
|
+
const cwd = state.session.cwd || process.cwd();
|
|
1998
|
+
const hint = tracker.generateHint(cwd);
|
|
1999
|
+
if (hint) {
|
|
2000
|
+
// 找到最后一个 text 类型的工具结果并追加提示
|
|
2001
|
+
const lastResult = toolResults[toolResults.length - 1];
|
|
2002
|
+
if (typeof lastResult.content === 'string') {
|
|
2003
|
+
lastResult.content += `\n\n<auto-verify>${hint}</auto-verify>`;
|
|
2004
|
+
}
|
|
2005
|
+
else if (Array.isArray(lastResult.content)) {
|
|
2006
|
+
const textBlocks = lastResult.content.filter((b) => b.type === 'text');
|
|
2007
|
+
if (textBlocks.length > 0) {
|
|
2008
|
+
textBlocks[textBlocks.length - 1].text += `\n\n<auto-verify>${hint}</auto-verify>`;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
catch { /* auto-verify 失败不影响主流程 */ }
|
|
2014
|
+
}
|
|
1797
2015
|
// 添加工具结果到消息
|
|
1798
2016
|
if (toolResults.length > 0) {
|
|
1799
2017
|
const toolResultMsg = {
|
|
@@ -1834,6 +2052,13 @@ export class ConversationManager {
|
|
|
1834
2052
|
else {
|
|
1835
2053
|
// 对话结束
|
|
1836
2054
|
continueLoop = false;
|
|
2055
|
+
// 对齐官方:max_tokens 截断时,流式输出错误消息告知用户
|
|
2056
|
+
if (stopReason === 'max_tokens') {
|
|
2057
|
+
const currentMax = getMaxOutputTokens(resolvedModel);
|
|
2058
|
+
const errorMsg = `\n\nClaude's response exceeded the ${currentMax} output token maximum. ` +
|
|
2059
|
+
`Set CLAUDE_CODE_MAX_OUTPUT_TOKENS environment variable to a higher value to configure.`;
|
|
2060
|
+
callbacks.onTextDelta?.(errorMsg);
|
|
2061
|
+
}
|
|
1837
2062
|
// 添加到聊天历史
|
|
1838
2063
|
const chatContent = assistantContent.map(block => {
|
|
1839
2064
|
if (block.type === 'text') {
|
|
@@ -1857,6 +2082,7 @@ export class ConversationManager {
|
|
|
1857
2082
|
timestamp: Date.now(),
|
|
1858
2083
|
content: chatContent,
|
|
1859
2084
|
model: state.model,
|
|
2085
|
+
runtimeBackend: state.runtimeBackend,
|
|
1860
2086
|
usage: {
|
|
1861
2087
|
inputTokens: totalInputTokens,
|
|
1862
2088
|
outputTokens: totalOutputTokens,
|
|
@@ -2083,6 +2309,7 @@ export class ConversationManager {
|
|
|
2083
2309
|
sessionData.messages = state.messages;
|
|
2084
2310
|
sessionData.chatHistory = state.chatHistory;
|
|
2085
2311
|
sessionData.currentModel = state.model;
|
|
2312
|
+
sessionData.metadata.runtimeBackend = state.runtimeBackend;
|
|
2086
2313
|
sessionData.toolFilterConfig = state.toolFilterConfig;
|
|
2087
2314
|
sessionData.systemPromptConfig = state.systemPromptConfig;
|
|
2088
2315
|
sessionData.metadata.messageCount = state.messages.length;
|
|
@@ -2124,7 +2351,7 @@ export class ConversationManager {
|
|
|
2124
2351
|
// 如果 messages 中的 assistant 消息比 chatHistory 多,说明有消息没有同步
|
|
2125
2352
|
if (assistantMsgCount > assistantChatCount) {
|
|
2126
2353
|
// 从 messages 重建 chatHistory
|
|
2127
|
-
state.chatHistory = this.convertMessagesToChatHistory(state.messages);
|
|
2354
|
+
state.chatHistory = this.convertMessagesToChatHistory(state.messages, state.runtimeBackend);
|
|
2128
2355
|
console.log(`[ConversationManager] Syncing chatHistory: messages=${assistantMsgCount}, chatHistory=${state.chatHistory.filter(m => m.role === 'assistant').length}`);
|
|
2129
2356
|
}
|
|
2130
2357
|
}
|
|
@@ -2246,17 +2473,13 @@ export class ConversationManager {
|
|
|
2246
2473
|
// --- 阶段 2: 执行子 agent ---
|
|
2247
2474
|
sendCountdown('executing', 0);
|
|
2248
2475
|
console.log(`[ScheduleTask] Countdown finished, starting execution: ${taskName}`);
|
|
2249
|
-
const mainClientConfig = this.buildClientConfig(input.model || state.model);
|
|
2476
|
+
const mainClientConfig = this.buildClientConfig(input.model || state.model, state.runtimeBackend);
|
|
2250
2477
|
const startedAt = Date.now();
|
|
2251
2478
|
try {
|
|
2252
2479
|
const result = await state.taskManager.executeScheduleTaskInline(taskName, task.prompt, {
|
|
2253
2480
|
model: task.model || 'sonnet',
|
|
2254
2481
|
workingDirectory: task.workingDir,
|
|
2255
|
-
clientConfig:
|
|
2256
|
-
apiKey: mainClientConfig.apiKey,
|
|
2257
|
-
authToken: mainClientConfig.authToken,
|
|
2258
|
-
baseUrl: mainClientConfig.baseUrl,
|
|
2259
|
-
},
|
|
2482
|
+
clientConfig: mainClientConfig,
|
|
2260
2483
|
});
|
|
2261
2484
|
const endedAt = Date.now();
|
|
2262
2485
|
// --- 阶段 3: 更新任务状态 + 返回精简结果 ---
|
|
@@ -2370,20 +2593,24 @@ export class ConversationManager {
|
|
|
2370
2593
|
callbacks.onToolResult?.(toolUse.id, false, undefined, error);
|
|
2371
2594
|
return { success: false, error };
|
|
2372
2595
|
}
|
|
2596
|
+
const normalizedToolInput = normalizeToolInputForWebRuntime(toolUse.input, tool?.getInputSchema());
|
|
2597
|
+
const normalizedToolUse = normalizedToolInput === toolUse.input
|
|
2598
|
+
? toolUse
|
|
2599
|
+
: { ...toolUse, input: normalizedToolInput };
|
|
2373
2600
|
// 检查工具是否被过滤
|
|
2374
|
-
if (!this.isToolEnabled(
|
|
2375
|
-
const error = `Tool ${
|
|
2376
|
-
callbacks.onToolResult?.(
|
|
2601
|
+
if (!this.isToolEnabled(normalizedToolUse.name, state.toolFilterConfig)) {
|
|
2602
|
+
const error = `Tool ${normalizedToolUse.name} is disabled`;
|
|
2603
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2377
2604
|
return { success: false, error };
|
|
2378
2605
|
}
|
|
2379
2606
|
// ========================================================================
|
|
2380
2607
|
// 权限检查(对齐 CLI loop.ts 的 handlePermissionRequest 逻辑)
|
|
2381
2608
|
// ========================================================================
|
|
2382
2609
|
try {
|
|
2383
|
-
const permissionResult = await this.checkToolPermission(
|
|
2610
|
+
const permissionResult = await this.checkToolPermission(normalizedToolUse, state, callbacks);
|
|
2384
2611
|
if (permissionResult === 'denied') {
|
|
2385
|
-
const error = `User denied execution permission for ${
|
|
2386
|
-
callbacks.onToolResult?.(
|
|
2612
|
+
const error = `User denied execution permission for ${normalizedToolUse.name}`;
|
|
2613
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2387
2614
|
return { success: false, error };
|
|
2388
2615
|
}
|
|
2389
2616
|
// permissionResult === 'allowed' 或 'skipped'(无需权限),继续执行
|
|
@@ -2391,7 +2618,7 @@ export class ConversationManager {
|
|
|
2391
2618
|
catch (permError) {
|
|
2392
2619
|
// 权限请求超时或被取消
|
|
2393
2620
|
const error = permError instanceof Error ? permError.message : 'Permission request failed';
|
|
2394
|
-
callbacks.onToolResult?.(
|
|
2621
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2395
2622
|
return { success: false, error };
|
|
2396
2623
|
}
|
|
2397
2624
|
// ========================================================================
|
|
@@ -2399,10 +2626,10 @@ export class ConversationManager {
|
|
|
2399
2626
|
// ========================================================================
|
|
2400
2627
|
const hookSessionId = state.session.sessionId || '';
|
|
2401
2628
|
try {
|
|
2402
|
-
const hookResult = await runPreToolUseHooks(
|
|
2629
|
+
const hookResult = await runPreToolUseHooks(normalizedToolUse.name, normalizedToolUse.input, hookSessionId);
|
|
2403
2630
|
if (!hookResult.allowed) {
|
|
2404
|
-
const error = hookResult.message || `PreToolUse hook blocked execution of ${
|
|
2405
|
-
callbacks.onToolResult?.(
|
|
2631
|
+
const error = hookResult.message || `PreToolUse hook blocked execution of ${normalizedToolUse.name}`;
|
|
2632
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2406
2633
|
return { success: false, error };
|
|
2407
2634
|
}
|
|
2408
2635
|
}
|
|
@@ -2411,34 +2638,30 @@ export class ConversationManager {
|
|
|
2411
2638
|
console.warn(`[Hook] PreToolUse hook execution failed:`, hookError);
|
|
2412
2639
|
}
|
|
2413
2640
|
try {
|
|
2414
|
-
console.log(`[Tool] Executing ${
|
|
2641
|
+
console.log(`[Tool] Executing ${normalizedToolUse.name}:`, JSON.stringify(normalizedToolUse.input).slice(0, 200));
|
|
2415
2642
|
// 拦截 Task 工具 - WebUI 模式下使用同步执行 + WebSocket 实时推送
|
|
2416
2643
|
// 不再默认后台执行,避免 TaskOutput 多次轮询的性能浪费
|
|
2417
|
-
if (
|
|
2418
|
-
const input =
|
|
2644
|
+
if (normalizedToolUse.name === 'Task') {
|
|
2645
|
+
const input = normalizedToolUse.input;
|
|
2419
2646
|
const description = input.description || 'Background task';
|
|
2420
2647
|
const prompt = input.prompt || '';
|
|
2421
2648
|
const agentType = input.subagent_type || 'general-purpose';
|
|
2422
2649
|
// 验证必需参数
|
|
2423
2650
|
if (!prompt) {
|
|
2424
2651
|
const error = 'Task prompt is required';
|
|
2425
|
-
callbacks.onToolResult?.(
|
|
2652
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2426
2653
|
return { success: false, error };
|
|
2427
2654
|
}
|
|
2428
2655
|
try {
|
|
2429
2656
|
// 获取主 agent 的认证信息,传递给子 agent 复用(避免子 agent initAuth 拿到不同凭证导致 403)
|
|
2430
|
-
const mainClientConfig = this.buildClientConfig(input.model || state.model);
|
|
2657
|
+
const mainClientConfig = this.buildClientConfig(input.model || state.model, state.runtimeBackend);
|
|
2431
2658
|
// WebUI 始终使用同步执行:await 拿结果,中间过程由 TaskManager 通过 WebSocket 实时推送
|
|
2432
2659
|
const result = await state.taskManager.executeTaskSync(description, prompt, agentType, {
|
|
2433
2660
|
model: input.model || state.model,
|
|
2434
2661
|
parentMessages: state.messages,
|
|
2435
2662
|
workingDirectory: state.session.cwd,
|
|
2436
|
-
clientConfig:
|
|
2437
|
-
|
|
2438
|
-
authToken: mainClientConfig.authToken,
|
|
2439
|
-
baseUrl: mainClientConfig.baseUrl,
|
|
2440
|
-
},
|
|
2441
|
-
toolUseId: toolUse.id,
|
|
2663
|
+
clientConfig: mainClientConfig,
|
|
2664
|
+
toolUseId: normalizedToolUse.id,
|
|
2442
2665
|
maxTurns: input.max_turns,
|
|
2443
2666
|
});
|
|
2444
2667
|
let output;
|
|
@@ -2460,7 +2683,7 @@ export class ConversationManager {
|
|
|
2460
2683
|
}
|
|
2461
2684
|
output = parts.join('');
|
|
2462
2685
|
}
|
|
2463
|
-
callbacks.onToolResult?.(
|
|
2686
|
+
callbacks.onToolResult?.(normalizedToolUse.id, result.success, output, result.success ? undefined : result.error, {
|
|
2464
2687
|
tool: 'Task',
|
|
2465
2688
|
agentType,
|
|
2466
2689
|
description,
|
|
@@ -2472,13 +2695,13 @@ export class ConversationManager {
|
|
|
2472
2695
|
catch (error) {
|
|
2473
2696
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2474
2697
|
console.error(`[Tool] Task execution failed:`, errorMessage);
|
|
2475
|
-
callbacks.onToolResult?.(
|
|
2698
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2476
2699
|
return { success: false, error: errorMessage };
|
|
2477
2700
|
}
|
|
2478
2701
|
}
|
|
2479
2702
|
// 拦截 ScheduleTask 工具 - inline 执行时提供倒计时 + 子 agent 渲染
|
|
2480
|
-
if (
|
|
2481
|
-
const input =
|
|
2703
|
+
if (normalizedToolUse.name === 'ScheduleTask') {
|
|
2704
|
+
const input = normalizedToolUse.input;
|
|
2482
2705
|
// 只拦截 create + once + 10分钟内的情况(即 inline 执行路径)
|
|
2483
2706
|
if (input.action === 'create' && input.type === 'once' && input.triggerAt) {
|
|
2484
2707
|
try {
|
|
@@ -2506,15 +2729,15 @@ export class ConversationManager {
|
|
|
2506
2729
|
const scheduleTool = toolRegistry.get('ScheduleTask');
|
|
2507
2730
|
if (!scheduleTool) {
|
|
2508
2731
|
const error = 'ScheduleTask tool not found in registry';
|
|
2509
|
-
callbacks.onToolResult?.(
|
|
2732
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2510
2733
|
return { success: false, error };
|
|
2511
2734
|
}
|
|
2512
|
-
const rawResult = await scheduleTool.execute(
|
|
2735
|
+
const rawResult = await scheduleTool.execute(normalizedToolUse.input);
|
|
2513
2736
|
const result = typeof rawResult === 'object' && rawResult !== null
|
|
2514
2737
|
? rawResult
|
|
2515
2738
|
: { success: true, output: String(rawResult) };
|
|
2516
2739
|
// 通知前端工具结果
|
|
2517
|
-
callbacks.onToolResult?.(
|
|
2740
|
+
callbacks.onToolResult?.(normalizedToolUse.id, result.success, result.output, result.error);
|
|
2518
2741
|
// 用差集精确找到新创建的任务
|
|
2519
2742
|
if (result.success && existingIds) {
|
|
2520
2743
|
try {
|
|
@@ -2533,15 +2756,15 @@ export class ConversationManager {
|
|
|
2533
2756
|
// list/cancel/watch 走正常工具执行路径
|
|
2534
2757
|
}
|
|
2535
2758
|
// 拦截 TaskOutput 工具 - 从 TaskManager 获取任务输出
|
|
2536
|
-
if (
|
|
2537
|
-
const input =
|
|
2759
|
+
if (normalizedToolUse.name === 'TaskOutput') {
|
|
2760
|
+
const input = normalizedToolUse.input;
|
|
2538
2761
|
const taskId = input.task_id;
|
|
2539
2762
|
const block = input.block !== false;
|
|
2540
2763
|
const timeout = input.timeout || 300000; // 默认5分钟超时
|
|
2541
2764
|
const showHistory = input.show_history || false;
|
|
2542
2765
|
if (!taskId) {
|
|
2543
2766
|
const error = 'task_id is required';
|
|
2544
|
-
callbacks.onToolResult?.(
|
|
2767
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2545
2768
|
return { success: false, error };
|
|
2546
2769
|
}
|
|
2547
2770
|
try {
|
|
@@ -2560,11 +2783,11 @@ export class ConversationManager {
|
|
|
2560
2783
|
const fallbackSuccess = typeof fallbackResult === 'string'
|
|
2561
2784
|
? true
|
|
2562
2785
|
: fallbackResult?.success ?? false;
|
|
2563
|
-
callbacks.onToolResult?.(
|
|
2786
|
+
callbacks.onToolResult?.(normalizedToolUse.id, fallbackSuccess, fallbackOutput, fallbackSuccess ? undefined : fallbackOutput);
|
|
2564
2787
|
return { success: fallbackSuccess, output: fallbackOutput, error: fallbackSuccess ? undefined : fallbackOutput };
|
|
2565
2788
|
}
|
|
2566
2789
|
const error = `Task ${taskId} not found`;
|
|
2567
|
-
callbacks.onToolResult?.(
|
|
2790
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2568
2791
|
return { success: false, error };
|
|
2569
2792
|
}
|
|
2570
2793
|
// 如果需要阻塞等待完成
|
|
@@ -2575,7 +2798,7 @@ export class ConversationManager {
|
|
|
2575
2798
|
}
|
|
2576
2799
|
if (task.status === 'running') {
|
|
2577
2800
|
const output = `Task ${taskId} is still running (timeout reached).\n\nStatus: ${task.status}\nDescription: ${task.description}`;
|
|
2578
|
-
callbacks.onToolResult?.(
|
|
2801
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2579
2802
|
return { success: true, output };
|
|
2580
2803
|
}
|
|
2581
2804
|
}
|
|
@@ -2608,23 +2831,23 @@ export class ConversationManager {
|
|
|
2608
2831
|
else if (task.error) {
|
|
2609
2832
|
output += `\nError: ${task.error}`;
|
|
2610
2833
|
}
|
|
2611
|
-
callbacks.onToolResult?.(
|
|
2834
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2612
2835
|
return { success: true, output };
|
|
2613
2836
|
}
|
|
2614
2837
|
catch (error) {
|
|
2615
2838
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2616
2839
|
console.error(`[Tool] TaskOutput execution failed:`, errorMessage);
|
|
2617
|
-
callbacks.onToolResult?.(
|
|
2840
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2618
2841
|
return { success: false, error: errorMessage };
|
|
2619
2842
|
}
|
|
2620
2843
|
}
|
|
2621
2844
|
// 拦截 AskUserQuestion 工具 - 通过 WebSocket 向前端发送问题
|
|
2622
|
-
if (
|
|
2623
|
-
const input =
|
|
2845
|
+
if (normalizedToolUse.name === 'AskUserQuestion') {
|
|
2846
|
+
const input = normalizedToolUse.input;
|
|
2624
2847
|
const questions = input.questions || [];
|
|
2625
2848
|
if (questions.length === 0) {
|
|
2626
2849
|
const error = 'No questions provided';
|
|
2627
|
-
callbacks.onToolResult?.(
|
|
2850
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2628
2851
|
return { success: false, error };
|
|
2629
2852
|
}
|
|
2630
2853
|
const answers = {};
|
|
@@ -2645,19 +2868,19 @@ export class ConversationManager {
|
|
|
2645
2868
|
.map(([header, answer]) => `"${header}"="${answer}"`)
|
|
2646
2869
|
.join(', ');
|
|
2647
2870
|
const output = `User has answered your questions: ${formattedAnswers}. You can now continue with the user's answers in mind.`;
|
|
2648
|
-
callbacks.onToolResult?.(
|
|
2871
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2649
2872
|
return { success: true, output };
|
|
2650
2873
|
}
|
|
2651
2874
|
catch (error) {
|
|
2652
2875
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2653
2876
|
console.error(`[Tool] AskUserQuestion failed:`, errorMessage);
|
|
2654
|
-
callbacks.onToolResult?.(
|
|
2877
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2655
2878
|
return { success: false, error: errorMessage };
|
|
2656
2879
|
}
|
|
2657
2880
|
}
|
|
2658
2881
|
// 拦截 GenerateBlueprint 工具 - 将对话需求结构化为蓝图
|
|
2659
|
-
if (
|
|
2660
|
-
const input =
|
|
2882
|
+
if (normalizedToolUse.name === 'GenerateBlueprint') {
|
|
2883
|
+
const input = normalizedToolUse.input;
|
|
2661
2884
|
try {
|
|
2662
2885
|
const blueprintId = `bp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
2663
2886
|
const hasModules = Array.isArray(input.modules) && input.modules.length > 0;
|
|
@@ -2735,19 +2958,19 @@ export class ConversationManager {
|
|
|
2735
2958
|
? `Modules: ${moduleCount}, Processes: ${processCount}, NFR: ${nfrCount}`
|
|
2736
2959
|
: `Requirements: ${reqCount}`;
|
|
2737
2960
|
const output = `Blueprint generated and saved.\nBlueprint ID: ${blueprint.id}\nProject: ${blueprint.name}\nType: ${isCodebase ? 'Panoramic Blueprint' : 'Requirements Blueprint'}\n${stats}\n\nYou can now call StartLeadAgent to start execution.`;
|
|
2738
|
-
callbacks.onToolResult?.(
|
|
2961
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2739
2962
|
return { success: true, output };
|
|
2740
2963
|
}
|
|
2741
2964
|
catch (error) {
|
|
2742
2965
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2743
2966
|
console.error(`[Tool] GenerateBlueprint execution failed:`, errorMessage);
|
|
2744
|
-
callbacks.onToolResult?.(
|
|
2967
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2745
2968
|
return { success: false, error: errorMessage };
|
|
2746
2969
|
}
|
|
2747
2970
|
}
|
|
2748
2971
|
// v11.0: StartLeadAgent 不再拦截,走正常 tool.execute() 路径
|
|
2749
2972
|
// 执行前动态绑定当前会话的 WebSocket 和工作目录,确保蜂群在正确的项目路径下执行
|
|
2750
|
-
if (
|
|
2973
|
+
if (normalizedToolUse.name === 'StartLeadAgent') {
|
|
2751
2974
|
const currentCtx = StartLeadAgentTool.getContext();
|
|
2752
2975
|
if (currentCtx) {
|
|
2753
2976
|
StartLeadAgentTool.setContext({
|
|
@@ -2766,15 +2989,30 @@ export class ConversationManager {
|
|
|
2766
2989
|
}
|
|
2767
2990
|
}
|
|
2768
2991
|
// 拦截 ImageGen 工具 - 文生图 / 图生图
|
|
2769
|
-
if (
|
|
2770
|
-
const input =
|
|
2992
|
+
if (normalizedToolUse.name === 'ImageGen') {
|
|
2993
|
+
const input = normalizedToolUse.input;
|
|
2771
2994
|
try {
|
|
2772
|
-
const { prompt, style, image_path } = input;
|
|
2773
|
-
console.log(`[Tool] ImageGen: ${image_path ? 'image-to-image' : 'text-to-image'} - ${prompt.substring(0, 50)}...`);
|
|
2774
|
-
const
|
|
2995
|
+
const { prompt, style, size, edit_strength, image_path, image_base64, image_mime_type, output_path } = input;
|
|
2996
|
+
console.log(`[Tool] ImageGen: ${image_path || image_base64 ? 'image-to-image' : 'text-to-image'} - ${prompt.substring(0, 50)}...`);
|
|
2997
|
+
const resolvedImageSource = resolveImageGenSource({
|
|
2998
|
+
image_path,
|
|
2999
|
+
image_base64,
|
|
3000
|
+
image_mime_type,
|
|
3001
|
+
}, state.latestImageAttachments);
|
|
3002
|
+
if (image_path && resolvedImageSource.imagePath && resolvedImageSource.imagePath !== image_path) {
|
|
3003
|
+
console.log(`[Tool] ImageGen: remapped uploaded image_path "${image_path}" -> "${resolvedImageSource.imagePath}"`);
|
|
3004
|
+
}
|
|
3005
|
+
else if (image_path && resolvedImageSource.imageBase64) {
|
|
3006
|
+
console.log(`[Tool] ImageGen: fell back to uploaded image base64 for "${image_path}"`);
|
|
3007
|
+
}
|
|
3008
|
+
const result = await geminiImageService.generateImage(prompt, style, {
|
|
3009
|
+
imagePath: resolvedImageSource.imagePath,
|
|
3010
|
+
imageBase64: resolvedImageSource.imageBase64,
|
|
3011
|
+
imageMimeType: resolvedImageSource.imageMimeType,
|
|
3012
|
+
}, output_path, size, edit_strength);
|
|
2775
3013
|
if (!result.success) {
|
|
2776
3014
|
const error = result.error || 'Image generation failed';
|
|
2777
|
-
callbacks.onToolResult?.(
|
|
3015
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2778
3016
|
return { success: false, error };
|
|
2779
3017
|
}
|
|
2780
3018
|
// 通过 WebSocket 发送图片给前端显示
|
|
@@ -2789,21 +3027,28 @@ export class ConversationManager {
|
|
|
2789
3027
|
},
|
|
2790
3028
|
}));
|
|
2791
3029
|
}
|
|
2792
|
-
const
|
|
2793
|
-
|
|
3030
|
+
const parts = ['Image generated and sent to user for preview.'];
|
|
3031
|
+
if (result.savedPath) {
|
|
3032
|
+
parts.push(`\nSaved to: ${result.savedPath}`);
|
|
3033
|
+
}
|
|
3034
|
+
if (result.generatedText) {
|
|
3035
|
+
parts.push(`\nDescription: ${result.generatedText}`);
|
|
3036
|
+
}
|
|
3037
|
+
const output = parts.join('');
|
|
3038
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2794
3039
|
return { success: true, output };
|
|
2795
3040
|
}
|
|
2796
3041
|
catch (error) {
|
|
2797
3042
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2798
3043
|
console.error(`[Tool] ImageGen execution failed:`, errorMessage);
|
|
2799
|
-
callbacks.onToolResult?.(
|
|
3044
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2800
3045
|
return { success: false, error: errorMessage };
|
|
2801
3046
|
}
|
|
2802
3047
|
}
|
|
2803
3048
|
// 拦截 Mcp 工具的 server management actions (action=list/enable/disable)
|
|
2804
3049
|
// 这些 action 需要访问 ConversationManager 的 toggleMcpServer/listMcpServers
|
|
2805
|
-
if (
|
|
2806
|
-
const input =
|
|
3050
|
+
if (normalizedToolUse.name === 'Mcp') {
|
|
3051
|
+
const input = normalizedToolUse.input;
|
|
2807
3052
|
if (input.action) {
|
|
2808
3053
|
try {
|
|
2809
3054
|
if (input.action === 'list') {
|
|
@@ -2812,13 +3057,13 @@ export class ConversationManager {
|
|
|
2812
3057
|
const output = servers.length > 0
|
|
2813
3058
|
? `MCP Servers (${servers.length}):\n${lines.join('\n')}`
|
|
2814
3059
|
: 'No MCP servers configured.';
|
|
2815
|
-
callbacks.onToolResult?.(
|
|
3060
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2816
3061
|
return { success: true, output };
|
|
2817
3062
|
}
|
|
2818
3063
|
if (input.action === 'enable' || input.action === 'disable') {
|
|
2819
3064
|
if (!input.name) {
|
|
2820
3065
|
const error = `"name" parameter is required for ${input.action} action.`;
|
|
2821
|
-
callbacks.onToolResult?.(
|
|
3066
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2822
3067
|
return { success: false, error };
|
|
2823
3068
|
}
|
|
2824
3069
|
const enabled = input.action === 'enable';
|
|
@@ -2832,23 +3077,23 @@ export class ConversationManager {
|
|
|
2832
3077
|
this.temporarilyEnabledMcpServers.delete(input.name);
|
|
2833
3078
|
}
|
|
2834
3079
|
const output = `MCP server "${input.name}" has been ${result.enabled ? 'enabled' : 'disabled'}.`;
|
|
2835
|
-
callbacks.onToolResult?.(
|
|
3080
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2836
3081
|
return { success: true, output };
|
|
2837
3082
|
}
|
|
2838
3083
|
else {
|
|
2839
3084
|
const error = `Failed to ${input.action} MCP server "${input.name}". The server may not exist in the configuration. Use action="list" to see available servers.`;
|
|
2840
|
-
callbacks.onToolResult?.(
|
|
3085
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2841
3086
|
return { success: false, error };
|
|
2842
3087
|
}
|
|
2843
3088
|
}
|
|
2844
3089
|
const error = `Unknown Mcp action: ${input.action}. Use "list", "enable", or "disable".`;
|
|
2845
|
-
callbacks.onToolResult?.(
|
|
3090
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2846
3091
|
return { success: false, error };
|
|
2847
3092
|
}
|
|
2848
3093
|
catch (error) {
|
|
2849
3094
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2850
3095
|
console.error(`[Tool] Mcp server management failed:`, errorMessage);
|
|
2851
|
-
callbacks.onToolResult?.(
|
|
3096
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2852
3097
|
return { success: false, error: errorMessage };
|
|
2853
3098
|
}
|
|
2854
3099
|
}
|
|
@@ -2856,34 +3101,34 @@ export class ConversationManager {
|
|
|
2856
3101
|
}
|
|
2857
3102
|
// MCP 工具执行:解析 mcp__{serverName}__{toolName} 格式,调用 callMcpTool()
|
|
2858
3103
|
if (isMcpTool) {
|
|
2859
|
-
const parts =
|
|
3104
|
+
const parts = normalizedToolUse.name.split('__');
|
|
2860
3105
|
// 格式: mcp__{serverName}__{toolName}
|
|
2861
3106
|
const mcpServerName = parts[1];
|
|
2862
3107
|
const mcpToolName = parts.slice(2).join('__');
|
|
2863
3108
|
if (!mcpServerName || !mcpToolName) {
|
|
2864
|
-
const error = `Invalid MCP tool name format: ${
|
|
2865
|
-
callbacks.onToolResult?.(
|
|
3109
|
+
const error = `Invalid MCP tool name format: ${normalizedToolUse.name}`;
|
|
3110
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2866
3111
|
return { success: false, error };
|
|
2867
3112
|
}
|
|
2868
|
-
const mcpResult = await callMcpTool(mcpServerName, mcpToolName,
|
|
3113
|
+
const mcpResult = await callMcpTool(mcpServerName, mcpToolName, normalizedToolUse.input);
|
|
2869
3114
|
const mcpOutput = mcpResult.output || mcpResult.error || JSON.stringify(mcpResult);
|
|
2870
3115
|
const truncatedMcpOutput = mcpOutput.length > 50000
|
|
2871
3116
|
? mcpOutput.slice(0, 50000) + '\n... (output truncated)'
|
|
2872
3117
|
: mcpOutput;
|
|
2873
3118
|
// PostToolUse Hook
|
|
2874
3119
|
try {
|
|
2875
|
-
await runPostToolUseHooks(
|
|
3120
|
+
await runPostToolUseHooks(normalizedToolUse.name, normalizedToolUse.input, truncatedMcpOutput, hookSessionId);
|
|
2876
3121
|
}
|
|
2877
3122
|
catch (hookError) {
|
|
2878
3123
|
console.warn(`[Hook] PostToolUse hook execution failed:`, hookError);
|
|
2879
3124
|
}
|
|
2880
|
-
callbacks.onToolResult?.(
|
|
3125
|
+
callbacks.onToolResult?.(normalizedToolUse.id, mcpResult.success, truncatedMcpOutput, mcpResult.error ? mcpResult.error : undefined);
|
|
2881
3126
|
return { success: mcpResult.success, output: truncatedMcpOutput, error: mcpResult.error };
|
|
2882
3127
|
}
|
|
2883
3128
|
// 执行其他工具(内置 registry 工具)
|
|
2884
|
-
const result = await tool.execute(
|
|
3129
|
+
const result = await tool.execute(normalizedToolUse.input);
|
|
2885
3130
|
// 构建结构化数据
|
|
2886
|
-
const data = this.buildToolResultData(
|
|
3131
|
+
const data = this.buildToolResultData(normalizedToolUse.name, normalizedToolUse.input, result);
|
|
2887
3132
|
// 格式化输出
|
|
2888
3133
|
let output;
|
|
2889
3134
|
if (typeof result === 'string') {
|
|
@@ -2918,7 +3163,7 @@ export class ConversationManager {
|
|
|
2918
3163
|
: undefined;
|
|
2919
3164
|
// PostToolUse Hook
|
|
2920
3165
|
try {
|
|
2921
|
-
await runPostToolUseHooks(
|
|
3166
|
+
await runPostToolUseHooks(normalizedToolUse.name, normalizedToolUse.input, output, hookSessionId);
|
|
2922
3167
|
}
|
|
2923
3168
|
catch (hookError) {
|
|
2924
3169
|
console.warn(`[Hook] PostToolUse hook execution failed:`, hookError);
|
|
@@ -3467,6 +3712,10 @@ Respond ONLY with valid JSON, no other text.`;
|
|
|
3467
3712
|
}
|
|
3468
3713
|
// 构建提示上下文(与 CLI loop.ts 保持一致)
|
|
3469
3714
|
// 注意:不注入 contextUsage,保持 system prompt 稳定可缓存
|
|
3715
|
+
const runtimeBackend = state.runtimeBackend || this.getRuntimeBackend();
|
|
3716
|
+
const authStatus = webAuth.getStatus();
|
|
3717
|
+
const isAnthropicOauth = authStatus.type === 'oauth'
|
|
3718
|
+
&& getProviderForRuntimeBackend(runtimeBackend, state.model) === 'anthropic';
|
|
3470
3719
|
const promptContext = {
|
|
3471
3720
|
workingDir: state.session.cwd,
|
|
3472
3721
|
model: this.getModelId(state.model),
|
|
@@ -3480,8 +3729,12 @@ Respond ONLY with valid JSON, no other text.`;
|
|
|
3480
3729
|
debug: false,
|
|
3481
3730
|
// v2.1.0+: 语言配置 - 与 CLI 保持一致
|
|
3482
3731
|
language: configManager.get('language'),
|
|
3483
|
-
//
|
|
3484
|
-
isOfficialAuth:
|
|
3732
|
+
// 只有 Claude 官方订阅 OAuth 才使用官方 CLI 身份前缀
|
|
3733
|
+
isOfficialAuth: isAnthropicOauth && runtimeBackend === 'claude-subscription',
|
|
3734
|
+
// Console OAuth + oauthApiKey 必须使用 Agent SDK 身份前缀
|
|
3735
|
+
coreIdentityVariant: isAnthropicOauth && runtimeBackend === 'claude-compatible-api'
|
|
3736
|
+
? 'agent'
|
|
3737
|
+
: undefined,
|
|
3485
3738
|
// Agent 笔记本内容
|
|
3486
3739
|
notebookSummary,
|
|
3487
3740
|
// MCP 服务器信息(用于系统提示中的 MCP 指令)
|
|
@@ -3638,6 +3891,29 @@ You are running in web server mode accessible by multiple users. HIGHEST PRIORIT
|
|
|
3638
3891
|
// 端口转发功能提示 — 精简版
|
|
3639
3892
|
sections.push(`# Port Forwarding
|
|
3640
3893
|
When starting a web server for the user, they access it via \`/proxy/:port/\` (e.g. \`/proxy/9090/\`). After starting a server, tell the user: "Preview it here: [Open Preview](/proxy/9090/)". Supports HTTP and WebSocket, ports 1024-65535, localhost only.`);
|
|
3894
|
+
// 已注册应用感知
|
|
3895
|
+
try {
|
|
3896
|
+
const apps = getAppManager().list();
|
|
3897
|
+
if (apps.length > 0) {
|
|
3898
|
+
const appLines = apps.map(a => {
|
|
3899
|
+
const status = a.status === 'running' ? `running (pid ${a.pid}, port ${a.port || '?'})` : a.status;
|
|
3900
|
+
return `- **${a.name}** [${status}]: ${a.description || 'no description'} (dir: \`${a.directory}\`, cmd: \`${a.startCommand}\`)`;
|
|
3901
|
+
}).join('\n');
|
|
3902
|
+
sections.push(`# Managed Apps
|
|
3903
|
+
You have ${apps.length} registered app(s) in the Apps page. You can start/stop/manage them via \`GET/POST /api/apps\`.
|
|
3904
|
+
${appLines}`);
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3907
|
+
catch {
|
|
3908
|
+
// AppManager 未初始化时忽略
|
|
3909
|
+
}
|
|
3910
|
+
// ImageGen 使用约束
|
|
3911
|
+
sections.push(`## ImageGen tool usage
|
|
3912
|
+
- When the user provides an image attachment and asks to edit or transform that image, prefer calling ImageGen instead of only describing edits in text.
|
|
3913
|
+
- If the conversation context includes image attachment edit preferences, copy that preference into the ImageGen tool call as \`edit_strength\` ('low' | 'medium' | 'high').
|
|
3914
|
+
- For conservative/local edits, prefer \`edit_strength: 'low'\`.
|
|
3915
|
+
- For broader but still recognizable edits, prefer \`edit_strength: 'medium'\` or \`edit_strength: 'high'\` as appropriate.
|
|
3916
|
+
- When editing an uploaded image, pass the image through \`image_base64\` (or \`image_path\` if you truly have a file path) and keep the tool prompt focused on the requested change.`);
|
|
3641
3917
|
if (sections.length === 0) {
|
|
3642
3918
|
return null;
|
|
3643
3919
|
}
|
|
@@ -3894,6 +4170,9 @@ Guidelines:
|
|
|
3894
4170
|
broadcast({ type: 'tool_use_start', payload: { messageId, toolUseId, toolName, input, sessionId: targetSessionId } });
|
|
3895
4171
|
broadcast({ type: 'status', payload: { status: 'tool_executing', message: `Executing ${toolName}...`, sessionId: targetSessionId } });
|
|
3896
4172
|
},
|
|
4173
|
+
onToolUseInputReady: (toolUseId, input) => {
|
|
4174
|
+
broadcast({ type: 'tool_use_input_ready', payload: { toolUseId, input, sessionId: targetSessionId } });
|
|
4175
|
+
},
|
|
3897
4176
|
onToolUseDelta: (toolUseId, partialJson) => broadcast({ type: 'tool_use_delta', payload: { toolUseId, partialJson, sessionId: targetSessionId } }),
|
|
3898
4177
|
onToolResult: (toolUseId, success, output, error, data) => {
|
|
3899
4178
|
broadcast({ type: 'tool_result', payload: { toolUseId, success, output, error, data: data, defaultCollapsed: true, sessionId: targetSessionId } });
|
|
@@ -3934,6 +4213,13 @@ Guidelines:
|
|
|
3934
4213
|
}
|
|
3935
4214
|
return state.session.cwd;
|
|
3936
4215
|
}
|
|
4216
|
+
/**
|
|
4217
|
+
* 获取会话名称(从 sessionManager 的持久化数据中读取)
|
|
4218
|
+
*/
|
|
4219
|
+
getSessionName(sessionId) {
|
|
4220
|
+
const sessionData = this.sessionManager.loadSessionById(sessionId);
|
|
4221
|
+
return sessionData?.metadata?.name;
|
|
4222
|
+
}
|
|
3937
4223
|
/**
|
|
3938
4224
|
* 持久化会话
|
|
3939
4225
|
*/
|
|
@@ -3963,6 +4249,7 @@ Guidelines:
|
|
|
3963
4249
|
sessionData.messages = state.messages;
|
|
3964
4250
|
sessionData.chatHistory = state.chatHistory;
|
|
3965
4251
|
sessionData.currentModel = state.model;
|
|
4252
|
+
sessionData.metadata.runtimeBackend = state.runtimeBackend;
|
|
3966
4253
|
sessionData.toolFilterConfig = state.toolFilterConfig;
|
|
3967
4254
|
sessionData.systemPromptConfig = state.systemPromptConfig;
|
|
3968
4255
|
// 关键:更新 messageCount(官方规范:统计消息数)
|
|
@@ -4019,9 +4306,10 @@ Guidelines:
|
|
|
4019
4306
|
try {
|
|
4020
4307
|
// 如果会话已经在内存中,直接返回成功(避免重复创建)
|
|
4021
4308
|
if (this.sessions.has(sessionId)) {
|
|
4309
|
+
const state = this.sessions.get(sessionId);
|
|
4310
|
+
this.ensureStateModelMatchesRuntime(state);
|
|
4022
4311
|
// 同步权限模式(修复切换会话后 YOLO 模式丢失的问题)
|
|
4023
4312
|
if (permissionMode) {
|
|
4024
|
-
const state = this.sessions.get(sessionId);
|
|
4025
4313
|
state.permissionHandler.updateConfig({ mode: permissionMode });
|
|
4026
4314
|
}
|
|
4027
4315
|
return true;
|
|
@@ -4035,15 +4323,14 @@ Guidelines:
|
|
|
4035
4323
|
const session = new Session(sessionData.metadata.workingDirectory || this.cwd);
|
|
4036
4324
|
// 在后台异步获取 Git 信息,不阻塞会话切换(Git 信息主要用于 system prompt,在用户发送消息时才需要)
|
|
4037
4325
|
session.initializeGitInfo().catch(() => { });
|
|
4038
|
-
const
|
|
4039
|
-
const
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
});
|
|
4326
|
+
const runtimeBackend = sessionData.metadata.runtimeBackend || this.getRuntimeBackend();
|
|
4327
|
+
const resolvedModel = this.normalizeRuntimeModel(sessionData.currentModel || sessionData.metadata.model || this.defaultModel, runtimeBackend);
|
|
4328
|
+
const clientConfig = this.buildClientConfig(resolvedModel, runtimeBackend);
|
|
4329
|
+
const client = createConversationClient(clientConfig);
|
|
4043
4330
|
// 如果 chatHistory 为空但 messages 不为空,从 messages 构建 chatHistory
|
|
4044
4331
|
let chatHistory = sessionData.chatHistory || [];
|
|
4045
4332
|
if (chatHistory.length === 0 && sessionData.messages && sessionData.messages.length > 0) {
|
|
4046
|
-
chatHistory = this.convertMessagesToChatHistory(sessionData.messages);
|
|
4333
|
+
chatHistory = this.convertMessagesToChatHistory(sessionData.messages, runtimeBackend);
|
|
4047
4334
|
}
|
|
4048
4335
|
const resumeUserInteractionHandler = new UserInteractionHandler();
|
|
4049
4336
|
resumeUserInteractionHandler.setSessionId(sessionId);
|
|
@@ -4051,7 +4338,8 @@ Guidelines:
|
|
|
4051
4338
|
session,
|
|
4052
4339
|
client,
|
|
4053
4340
|
messages: sessionData.messages,
|
|
4054
|
-
model:
|
|
4341
|
+
model: resolvedModel,
|
|
4342
|
+
runtimeBackend,
|
|
4055
4343
|
cancelled: false,
|
|
4056
4344
|
chatHistory,
|
|
4057
4345
|
userInteractionHandler: resumeUserInteractionHandler,
|
|
@@ -4068,8 +4356,9 @@ Guidelines:
|
|
|
4068
4356
|
processingGeneration: 0,
|
|
4069
4357
|
lastActualInputTokens: 0,
|
|
4070
4358
|
messagesLenAtLastApiCall: 0,
|
|
4359
|
+
latestImageAttachments: [],
|
|
4071
4360
|
lastPersistedMessageCount: sessionData.messages.length, // 从磁盘加载时,初始化为当前消息数
|
|
4072
|
-
credentialsFingerprint: this.getCredentialsFingerprint(),
|
|
4361
|
+
credentialsFingerprint: this.getCredentialsFingerprint(runtimeBackend),
|
|
4073
4362
|
};
|
|
4074
4363
|
this.sessions.set(sessionId, state);
|
|
4075
4364
|
// 初始化 NotebookManager(SelfEvolve 重启后 resumeSession 不经过 getOrCreateSession,需要在这里初始化)
|
|
@@ -4141,7 +4430,7 @@ Guidelines:
|
|
|
4141
4430
|
/**
|
|
4142
4431
|
* 将 API 消息格式转换为 ChatHistory 格式
|
|
4143
4432
|
*/
|
|
4144
|
-
convertMessagesToChatHistory(messages) {
|
|
4433
|
+
convertMessagesToChatHistory(messages, runtimeBackend = this.getRuntimeBackend()) {
|
|
4145
4434
|
const chatHistory = [];
|
|
4146
4435
|
// 预构建 tool_use_id → tool_result 映射,用于将工具结果关联回工具调用
|
|
4147
4436
|
const toolResultMap = new Map();
|
|
@@ -4192,6 +4481,7 @@ Guidelines:
|
|
|
4192
4481
|
role: msg.role,
|
|
4193
4482
|
timestamp: Date.now(),
|
|
4194
4483
|
content: [],
|
|
4484
|
+
runtimeBackend,
|
|
4195
4485
|
// 记录此 chatEntry 对应的 messages 位置(i+1 表示包含当前消息)
|
|
4196
4486
|
_messagesLen: i + 1,
|
|
4197
4487
|
};
|
|
@@ -4204,6 +4494,9 @@ Guidelines:
|
|
|
4204
4494
|
if (block.type === 'text') {
|
|
4205
4495
|
chatMsg.content.push({ type: 'text', text: block.text });
|
|
4206
4496
|
}
|
|
4497
|
+
else if (block.type === 'thinking') {
|
|
4498
|
+
chatMsg.content.push({ type: 'thinking', text: block.thinking });
|
|
4499
|
+
}
|
|
4207
4500
|
else if (block.type === 'image') {
|
|
4208
4501
|
// 保留图片内容以便刷新后回显
|
|
4209
4502
|
const imgBlock = block;
|