axon-code 2.4.0 → 2.5.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/index.d.ts +30 -15
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +13 -2
- package/dist/config/index.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 +2 -7
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +16 -38
- 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 +64 -0
- package/dist/core/max-tokens.js.map +1 -0
- 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 +8 -8
- package/dist/media/index.d.ts +1 -0
- package/dist/media/index.d.ts.map +1 -1
- package/dist/media/index.js +2 -0
- 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/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 +5 -2
- package/dist/memory/memory-search.d.ts.map +1 -1
- package/dist/memory/memory-search.js +27 -10
- package/dist/memory/memory-search.js.map +1 -1
- package/dist/memory/memory-sync.d.ts.map +1 -1
- package/dist/memory/memory-sync.js +4 -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 +62 -9
- package/dist/memory/notebook.js.map +1 -1
- 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 +7 -0
- package/dist/prompt/attachments.d.ts.map +1 -1
- package/dist/prompt/attachments.js +57 -0
- 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 +2 -0
- package/dist/prompt/cache.d.ts.map +1 -1
- package/dist/prompt/cache.js +2 -0
- 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 +2 -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/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 +116 -126
- 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 +67 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/network-agent.js +2 -1
- package/dist/tools/network-agent.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 -1
- package/dist/tools/skill.d.ts.map +1 -1
- package/dist/tools/skill.js +18 -31
- package/dist/tools/skill.js.map +1 -1
- package/dist/web/server/api-manager.d.ts +3 -0
- package/dist/web/server/api-manager.d.ts.map +1 -1
- package/dist/web/server/api-manager.js +128 -12
- 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 +408 -132
- 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 -20
- 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 +2 -0
- package/dist/web/server/routes/axon-cloud.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/codex-client.d.ts +30 -0
- package/dist/web/server/runtime/codex-client.d.ts.map +1 -0
- package/dist/web/server/runtime/codex-client.js +1002 -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-selection.d.ts +16 -0
- package/dist/web/server/runtime/runtime-selection.d.ts.map +1 -0
- package/dist/web/server/runtime/runtime-selection.js +33 -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 +97 -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 +65 -0
- package/dist/web/server/runtime/utility-client.js.map +1 -0
- package/dist/web/server/services/config-service.d.ts +7 -2
- package/dist/web/server/services/config-service.d.ts.map +1 -1
- package/dist/web/server/services/config-service.js +41 -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 +1 -0
- package/dist/web/server/session-manager.d.ts.map +1 -1
- package/dist/web/server/session-manager.js +1 -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 +59 -17
- package/dist/web/server/slash-commands.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 +298 -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 +193 -44
- 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 +53 -0
- package/dist/web/shared/auth-summary.js.map +1 -0
- package/dist/web/shared/model-catalog.d.ts +30 -0
- package/dist/web/shared/model-catalog.d.ts.map +1 -0
- package/dist/web/shared/model-catalog.js +373 -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/setup-runtime.d.ts +27 -0
- package/dist/web/shared/setup-runtime.d.ts.map +1 -0
- package/dist/web/shared/setup-runtime.js +114 -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 +99 -0
- package/dist/web/shared/thinking-config.js.map +1 -0
- package/dist/web/shared/types.d.ts +22 -2
- package/dist/web/shared/types.d.ts.map +1 -1
- package/dist/web/shared/types.js.map +1 -1
- package/electron/main.cjs +7 -2
- package/package.json +4 -2
- package/src/web/client/dist/assets/index-B0gwq5PJ.js +727 -0
- package/src/web/client/dist/assets/index-CwhuMLtk.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,78 @@ 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
|
+
codexModelName: webAuth.getCodexModelName(),
|
|
778
|
+
customModelName: webAuth.getCustomModelName(),
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
getRuntimeProvider(runtimeBackend = this.getRuntimeBackend()) {
|
|
782
|
+
return this.getRuntimeSelection(undefined, runtimeBackend).provider;
|
|
783
|
+
}
|
|
784
|
+
getRuntimeCustomModelName(runtimeBackend = this.getRuntimeBackend()) {
|
|
785
|
+
return this.getRuntimeSelection(undefined, runtimeBackend).customModelName;
|
|
786
|
+
}
|
|
787
|
+
normalizeRuntimeModel(model, runtimeBackend = this.getRuntimeBackend()) {
|
|
788
|
+
return this.getRuntimeSelection(model, runtimeBackend).normalizedModel;
|
|
789
|
+
}
|
|
790
|
+
ensureStateModelMatchesRuntime(state) {
|
|
791
|
+
const normalizedModel = this.normalizeRuntimeModel(state.model, state.runtimeBackend);
|
|
792
|
+
if (normalizedModel === state.model) {
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
state.model = normalizedModel;
|
|
796
|
+
state.client = createConversationClient(this.buildClientConfig(normalizedModel, state.runtimeBackend));
|
|
797
|
+
}
|
|
755
798
|
/**
|
|
756
799
|
* 构建 ClaudeClient 配置
|
|
757
800
|
* 认证全部委托给 webAuth(唯一认证入口)
|
|
758
801
|
*/
|
|
759
|
-
buildClientConfig(model) {
|
|
760
|
-
const creds = webAuth.getCredentials();
|
|
761
|
-
const
|
|
802
|
+
buildClientConfig(model, runtimeBackend = this.getRuntimeBackend()) {
|
|
803
|
+
const creds = webAuth.getCredentials(runtimeBackend);
|
|
804
|
+
const selection = this.getRuntimeSelection(model, runtimeBackend);
|
|
805
|
+
const normalizedModel = selection.normalizedModel;
|
|
806
|
+
const provider = selection.provider;
|
|
807
|
+
const customModel = selection.customModelName;
|
|
808
|
+
const authStatus = webAuth.getStatus();
|
|
809
|
+
const identityVariant = provider === 'anthropic'
|
|
810
|
+
&& runtimeBackend === 'claude-compatible-api'
|
|
811
|
+
&& authStatus.type === 'oauth'
|
|
812
|
+
? 'agent'
|
|
813
|
+
: undefined;
|
|
762
814
|
return {
|
|
763
|
-
|
|
815
|
+
provider,
|
|
816
|
+
model: provider === 'codex' ? normalizedModel : this.getModelId(normalizedModel),
|
|
764
817
|
apiKey: creds.apiKey,
|
|
765
818
|
authToken: creds.authToken,
|
|
766
819
|
baseUrl: creds.baseUrl,
|
|
820
|
+
accountId: creds.accountId,
|
|
821
|
+
customModelName: customModel,
|
|
822
|
+
identityVariant,
|
|
767
823
|
timeout: 300000,
|
|
768
824
|
};
|
|
769
825
|
}
|
|
@@ -777,6 +833,7 @@ export class ConversationManager {
|
|
|
777
833
|
apiKey: config.apiKey,
|
|
778
834
|
authToken: config.authToken,
|
|
779
835
|
baseUrl: config.baseUrl,
|
|
836
|
+
accountId: config.accountId,
|
|
780
837
|
};
|
|
781
838
|
}
|
|
782
839
|
/**
|
|
@@ -784,6 +841,26 @@ export class ConversationManager {
|
|
|
784
841
|
* 这个方法在每次调用 API 之前被调用,检查 token 是否过期,如果过期则自动刷新
|
|
785
842
|
*/
|
|
786
843
|
async ensureValidOAuthToken(state) {
|
|
844
|
+
const runtimeProvider = getProviderForRuntimeBackend(state.runtimeBackend, state.model);
|
|
845
|
+
const authStatus = webAuth.getStatus();
|
|
846
|
+
if (runtimeProvider !== 'anthropic') {
|
|
847
|
+
const tokenBefore = webAuth.getCredentials(state.runtimeBackend).authToken;
|
|
848
|
+
const refreshOk = await webAuth.ensureValidToken(state.runtimeBackend);
|
|
849
|
+
if (!refreshOk) {
|
|
850
|
+
throw new Error('OAuth token expired, refresh failed. Please log in again.');
|
|
851
|
+
}
|
|
852
|
+
const tokenAfter = webAuth.getCredentials(state.runtimeBackend).authToken;
|
|
853
|
+
if (tokenBefore !== tokenAfter) {
|
|
854
|
+
const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
|
|
855
|
+
state.client = createConversationClient(newConfig);
|
|
856
|
+
state.credentialsFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
|
|
857
|
+
console.log('[ConversationManager] Client now using refreshed OAuth credentials');
|
|
858
|
+
}
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
if (authStatus.type !== 'oauth') {
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
787
864
|
// 只在使用 OAuth 时处理
|
|
788
865
|
const oauthConfig = oauthManager.getOAuthConfig();
|
|
789
866
|
if (!oauthConfig) {
|
|
@@ -799,9 +876,9 @@ export class ConversationManager {
|
|
|
799
876
|
if (apiKey) {
|
|
800
877
|
await oauthManager.saveOAuthConfig({ oauthApiKey: apiKey });
|
|
801
878
|
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();
|
|
879
|
+
const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
|
|
880
|
+
state.client = createConversationClient(newConfig);
|
|
881
|
+
state.credentialsFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
|
|
805
882
|
}
|
|
806
883
|
else {
|
|
807
884
|
console.warn('[ConversationManager] createOAuthApiKey returned null, inference may fail');
|
|
@@ -814,16 +891,16 @@ export class ConversationManager {
|
|
|
814
891
|
// 记住刷新前的 token,用于判断是否需要重建客户端
|
|
815
892
|
const tokenBefore = oauthManager.getOAuthConfig()?.accessToken;
|
|
816
893
|
// 统一的 token 有效性检查(对齐官方 NM() 语义)
|
|
817
|
-
const refreshOk = await webAuth.ensureValidToken();
|
|
894
|
+
const refreshOk = await webAuth.ensureValidToken(state.runtimeBackend);
|
|
818
895
|
if (!refreshOk) {
|
|
819
896
|
throw new Error('OAuth token expired, refresh failed. Please log in again.');
|
|
820
897
|
}
|
|
821
898
|
// 只有 token 真正变更了才重建客户端
|
|
822
899
|
const tokenAfter = oauthManager.getOAuthConfig()?.accessToken;
|
|
823
900
|
if (tokenBefore !== tokenAfter) {
|
|
824
|
-
const newConfig = this.buildClientConfig(state.model);
|
|
825
|
-
state.client =
|
|
826
|
-
state.credentialsFingerprint = this.getCredentialsFingerprint();
|
|
901
|
+
const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
|
|
902
|
+
state.client = createConversationClient(newConfig);
|
|
903
|
+
state.credentialsFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
|
|
827
904
|
console.log('[ConversationManager] Client now using refreshed OAuth credentials');
|
|
828
905
|
}
|
|
829
906
|
}
|
|
@@ -834,6 +911,8 @@ export class ConversationManager {
|
|
|
834
911
|
async getOrCreateSession(sessionId, model, projectPath, permissionMode) {
|
|
835
912
|
let state = this.sessions.get(sessionId);
|
|
836
913
|
if (state) {
|
|
914
|
+
state.runtimeBackend = state.runtimeBackend || this.getRuntimeBackend();
|
|
915
|
+
this.ensureStateModelMatchesRuntime(state);
|
|
837
916
|
// 会话已存在,检查是否需要更新工作目录
|
|
838
917
|
if (projectPath && state.session.cwd !== projectPath) {
|
|
839
918
|
console.log(`[ConversationManager] Updated session ${sessionId} working directory: ${state.session.cwd} -> ${projectPath}`);
|
|
@@ -848,15 +927,14 @@ export class ConversationManager {
|
|
|
848
927
|
}
|
|
849
928
|
// 创建新会话
|
|
850
929
|
const workingDir = projectPath || this.cwd;
|
|
930
|
+
const runtimeBackend = this.getRuntimeBackend();
|
|
931
|
+
const resolvedModel = this.normalizeRuntimeModel(model || this.defaultModel, runtimeBackend);
|
|
851
932
|
console.log(`[ConversationManager] Creating new session ${sessionId}, workingDir: ${workingDir}, permissionMode: ${permissionMode || 'default'}`);
|
|
852
933
|
const session = new Session(workingDir, sessionId);
|
|
853
934
|
await session.initializeGitInfo();
|
|
854
935
|
// 使用与核心 loop.ts 一致的认证逻辑
|
|
855
|
-
const clientConfig = this.buildClientConfig(
|
|
856
|
-
const client =
|
|
857
|
-
...clientConfig,
|
|
858
|
-
timeout: clientConfig.timeout,
|
|
859
|
-
});
|
|
936
|
+
const clientConfig = this.buildClientConfig(resolvedModel, runtimeBackend);
|
|
937
|
+
const client = createConversationClient(clientConfig);
|
|
860
938
|
// 创建用户交互处理器
|
|
861
939
|
const userInteractionHandler = new UserInteractionHandler();
|
|
862
940
|
userInteractionHandler.setSessionId(sessionId);
|
|
@@ -870,7 +948,8 @@ export class ConversationManager {
|
|
|
870
948
|
session,
|
|
871
949
|
client,
|
|
872
950
|
messages: [],
|
|
873
|
-
model:
|
|
951
|
+
model: resolvedModel,
|
|
952
|
+
runtimeBackend,
|
|
874
953
|
cancelled: false,
|
|
875
954
|
chatHistory: [],
|
|
876
955
|
userInteractionHandler,
|
|
@@ -887,8 +966,9 @@ export class ConversationManager {
|
|
|
887
966
|
processingGeneration: 0,
|
|
888
967
|
lastActualInputTokens: 0,
|
|
889
968
|
messagesLenAtLastApiCall: 0,
|
|
969
|
+
latestImageAttachments: [],
|
|
890
970
|
lastPersistedMessageCount: 0,
|
|
891
|
-
credentialsFingerprint: this.getCredentialsFingerprint(),
|
|
971
|
+
credentialsFingerprint: this.getCredentialsFingerprint(runtimeBackend),
|
|
892
972
|
};
|
|
893
973
|
this.sessions.set(sessionId, state);
|
|
894
974
|
// 初始化 session memory(官方 session-memory 功能)
|
|
@@ -925,14 +1005,27 @@ export class ConversationManager {
|
|
|
925
1005
|
setModel(sessionId, model) {
|
|
926
1006
|
const state = this.sessions.get(sessionId);
|
|
927
1007
|
if (state) {
|
|
928
|
-
|
|
1008
|
+
const normalizedModel = this.normalizeRuntimeModel(model, state.runtimeBackend);
|
|
1009
|
+
state.model = normalizedModel;
|
|
929
1010
|
// 使用与核心 loop.ts 一致的认证逻辑
|
|
930
|
-
const clientConfig = this.buildClientConfig(
|
|
931
|
-
state.client =
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
1011
|
+
const clientConfig = this.buildClientConfig(normalizedModel, state.runtimeBackend);
|
|
1012
|
+
state.client = createConversationClient(clientConfig);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
getSessionModel(sessionId) {
|
|
1016
|
+
const state = this.sessions.get(sessionId);
|
|
1017
|
+
if (!state) {
|
|
1018
|
+
return null;
|
|
935
1019
|
}
|
|
1020
|
+
this.ensureStateModelMatchesRuntime(state);
|
|
1021
|
+
return state.model;
|
|
1022
|
+
}
|
|
1023
|
+
getSessionRuntimeBackend(sessionId) {
|
|
1024
|
+
const state = this.sessions.get(sessionId);
|
|
1025
|
+
if (!state) {
|
|
1026
|
+
return null;
|
|
1027
|
+
}
|
|
1028
|
+
return state.runtimeBackend;
|
|
936
1029
|
}
|
|
937
1030
|
/**
|
|
938
1031
|
* 获取历史记录
|
|
@@ -961,7 +1054,7 @@ export class ConversationManager {
|
|
|
961
1054
|
const hasCompactBoundary = state.chatHistory.some(m => m.isCompactBoundary);
|
|
962
1055
|
if (!hasCompactBoundary) {
|
|
963
1056
|
// 未压缩:messages 是完整的,可以安全重建
|
|
964
|
-
return this.convertMessagesToChatHistory(state.messages);
|
|
1057
|
+
return this.convertMessagesToChatHistory(state.messages, state.runtimeBackend);
|
|
965
1058
|
}
|
|
966
1059
|
// 已压缩:以 chatHistory 为基础,找出 messages 中还没同步的增量部分
|
|
967
1060
|
// chatHistory 中最后一条记录的 _messagesLen 表示已经同步到 messages 的哪个位置
|
|
@@ -975,7 +1068,7 @@ export class ConversationManager {
|
|
|
975
1068
|
if (incrementalMessages.length === 0) {
|
|
976
1069
|
return state.chatHistory;
|
|
977
1070
|
}
|
|
978
|
-
const incrementalHistory = this.convertMessagesToChatHistory(incrementalMessages);
|
|
1071
|
+
const incrementalHistory = this.convertMessagesToChatHistory(incrementalMessages, state.runtimeBackend);
|
|
979
1072
|
return [...state.chatHistory, ...incrementalHistory];
|
|
980
1073
|
}
|
|
981
1074
|
/**
|
|
@@ -1134,13 +1227,28 @@ export class ConversationManager {
|
|
|
1134
1227
|
const state = this.sessions.get(sessionId);
|
|
1135
1228
|
return state?.userInteractionHandler.getPendingPayloads() ?? [];
|
|
1136
1229
|
}
|
|
1230
|
+
/**
|
|
1231
|
+
* 获取当前 ws 还未收到的待处理用户问题。
|
|
1232
|
+
* 用于恢复会话时补发,避免重复弹窗。
|
|
1233
|
+
*/
|
|
1234
|
+
getUndeliveredPendingUserQuestions(sessionId) {
|
|
1235
|
+
const state = this.sessions.get(sessionId);
|
|
1236
|
+
return state?.userInteractionHandler.getUndeliveredPayloadsForCurrentWebSocket() ?? [];
|
|
1237
|
+
}
|
|
1238
|
+
/**
|
|
1239
|
+
* 标记问题已经送达当前 ws,防止同一连接被重复补发。
|
|
1240
|
+
*/
|
|
1241
|
+
markPendingUserQuestionDelivered(sessionId, requestId) {
|
|
1242
|
+
const state = this.sessions.get(sessionId);
|
|
1243
|
+
state?.userInteractionHandler.markDeliveredToCurrentWebSocket(requestId);
|
|
1244
|
+
}
|
|
1137
1245
|
/**
|
|
1138
1246
|
* 媒体附件信息(图片或 PDF)
|
|
1139
1247
|
*/
|
|
1140
1248
|
/**
|
|
1141
1249
|
* 发送聊天消息
|
|
1142
1250
|
*/
|
|
1143
|
-
async chat(sessionId, content, mediaAttachments, model, callbacks, projectPath, ws, permissionMode, messageId) {
|
|
1251
|
+
async chat(sessionId, content, mediaAttachments, model, callbacks, projectPath, ws, permissionMode, messageId, thinkingConfig) {
|
|
1144
1252
|
const state = await this.getOrCreateSession(sessionId, model, projectPath, permissionMode);
|
|
1145
1253
|
// 插话模式:如果会话正在处理中,取消当前操作并等待其完成
|
|
1146
1254
|
if (state.isProcessing) {
|
|
@@ -1184,6 +1292,9 @@ export class ConversationManager {
|
|
|
1184
1292
|
catch {
|
|
1185
1293
|
// 增强失败不影响主流程
|
|
1186
1294
|
}
|
|
1295
|
+
if (mediaAttachments && mediaAttachments.length > 0) {
|
|
1296
|
+
state.latestImageAttachments = mediaAttachments.map(attachment => ({ ...attachment }));
|
|
1297
|
+
}
|
|
1187
1298
|
// 构建用户消息
|
|
1188
1299
|
const userMessage = {
|
|
1189
1300
|
role: 'user',
|
|
@@ -1217,6 +1328,7 @@ export class ConversationManager {
|
|
|
1217
1328
|
media_type: attachment.mimeType,
|
|
1218
1329
|
data: attachment.data,
|
|
1219
1330
|
},
|
|
1331
|
+
fileName: attachment.name,
|
|
1220
1332
|
});
|
|
1221
1333
|
}
|
|
1222
1334
|
}
|
|
@@ -1226,6 +1338,7 @@ export class ConversationManager {
|
|
|
1226
1338
|
role: 'user',
|
|
1227
1339
|
timestamp: Date.now(),
|
|
1228
1340
|
content: chatContentItems,
|
|
1341
|
+
runtimeBackend: state.runtimeBackend,
|
|
1229
1342
|
_messagesLen: state.messages.length,
|
|
1230
1343
|
};
|
|
1231
1344
|
state.chatHistory.push(chatEntry);
|
|
@@ -1237,7 +1350,7 @@ export class ConversationManager {
|
|
|
1237
1350
|
// 使用工作目录上下文包裹对话循环(与 CLI loop.ts 保持一致)
|
|
1238
1351
|
// 确保所有工具执行都在正确的工作目录上下文中
|
|
1239
1352
|
await runWithCwd(state.session.cwd, async () => {
|
|
1240
|
-
await this.conversationLoop(state, callbacks, sessionId);
|
|
1353
|
+
await this.conversationLoop(state, callbacks, sessionId, thinkingConfig);
|
|
1241
1354
|
});
|
|
1242
1355
|
}
|
|
1243
1356
|
catch (error) {
|
|
@@ -1272,7 +1385,7 @@ export class ConversationManager {
|
|
|
1272
1385
|
/**
|
|
1273
1386
|
* 对话循环
|
|
1274
1387
|
*/
|
|
1275
|
-
async conversationLoop(state, callbacks, sessionId) {
|
|
1388
|
+
async conversationLoop(state, callbacks, sessionId, thinkingConfig) {
|
|
1276
1389
|
let continueLoop = true;
|
|
1277
1390
|
let totalInputTokens = 0;
|
|
1278
1391
|
let totalOutputTokens = 0;
|
|
@@ -1289,12 +1402,23 @@ export class ConversationManager {
|
|
|
1289
1402
|
let messageConsistencyHealed = false;
|
|
1290
1403
|
// 创建 AbortController,用于在取消时中断正在执行的工具
|
|
1291
1404
|
state.currentAbortController = new AbortController();
|
|
1405
|
+
// Auto-verify: 设置全局 sessionId 供工具层追踪文件变更
|
|
1406
|
+
if (sessionId) {
|
|
1407
|
+
globalThis.__currentSessionId = sessionId;
|
|
1408
|
+
}
|
|
1292
1409
|
while (continueLoop && !state.cancelled) {
|
|
1293
1410
|
// 标记本次迭代是否已有内容流式输出到前端
|
|
1294
1411
|
// 如果有内容已输出,则不进行自动重试(避免前端内容重复)
|
|
1295
1412
|
let hasStreamedContent = false;
|
|
1296
1413
|
// 初始化流式中间内容追踪(用于浏览器刷新后恢复)
|
|
1297
1414
|
state.streamingContent = { thinkingText: '', textContent: '' };
|
|
1415
|
+
// Auto-verify: 每轮迭代重置注入标记
|
|
1416
|
+
if (sessionId) {
|
|
1417
|
+
try {
|
|
1418
|
+
getChangeTracker(sessionId).resetTurnFlag();
|
|
1419
|
+
}
|
|
1420
|
+
catch { /* ignore */ }
|
|
1421
|
+
}
|
|
1298
1422
|
// 凭据变更检测(处理用户在 WebUI 重新登录后已有会话自动使用新凭据)
|
|
1299
1423
|
this.ensureClientCredentialsFresh(state);
|
|
1300
1424
|
// OAuth Token 自动刷新检查(在调用 API 之前)
|
|
@@ -1542,11 +1666,13 @@ export class ConversationManager {
|
|
|
1542
1666
|
}
|
|
1543
1667
|
}
|
|
1544
1668
|
try {
|
|
1545
|
-
|
|
1669
|
+
const thinkingOptions = mapThinkingConfigToRuntimeOptions(state.runtimeBackend, state.model, thinkingConfig);
|
|
1670
|
+
// 调用运行时 API(思考能力由前端 per-message 配置映射到真实 runtime 选项)
|
|
1546
1671
|
// 传递 abort signal,取消时可直接中止 HTTP 流(对齐官方 CLI)
|
|
1547
1672
|
const stream = state.client.createMessageStream(cleanedMessages, tools, systemPrompt.content, {
|
|
1548
|
-
enableThinking:
|
|
1549
|
-
thinkingBudget:
|
|
1673
|
+
enableThinking: thinkingOptions.enableThinking,
|
|
1674
|
+
thinkingBudget: thinkingOptions.thinkingBudget,
|
|
1675
|
+
reasoningEffort: thinkingOptions.reasoningEffort,
|
|
1550
1676
|
signal: state.currentAbortController?.signal,
|
|
1551
1677
|
promptBlocks: systemPrompt.blocks,
|
|
1552
1678
|
toolSearchEnabled: hasToolSearch,
|
|
@@ -1592,25 +1718,38 @@ export class ConversationManager {
|
|
|
1592
1718
|
}
|
|
1593
1719
|
// 如果有未完成的工具调用(多工具响应时 content_block_stop 不产生事件),先完成它
|
|
1594
1720
|
if (currentToolUse) {
|
|
1721
|
+
// 优先使用 SDK 注入的 parsedInput
|
|
1722
|
+
const sdkPrev = currentToolUse.parsedInput;
|
|
1595
1723
|
let prevInput = {};
|
|
1596
|
-
|
|
1597
|
-
prevInput =
|
|
1724
|
+
if (sdkPrev && typeof sdkPrev === 'object' && Object.keys(sdkPrev).length > 0) {
|
|
1725
|
+
prevInput = sdkPrev;
|
|
1598
1726
|
}
|
|
1599
|
-
|
|
1727
|
+
else {
|
|
1728
|
+
try {
|
|
1729
|
+
prevInput = JSON.parse(currentToolUse.inputJson || '{}');
|
|
1730
|
+
}
|
|
1731
|
+
catch {
|
|
1732
|
+
console.warn(`[StreamDebug] Failed to parse tool input JSON for ${currentToolUse.name} (length=${currentToolUse.inputJson.length}), raw start: ${currentToolUse.inputJson.slice(0, 100)}`);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
console.log(`[StreamDebug] tool_use_start: completing previous tool ${currentToolUse.name}(${currentToolUse.id}), keys=[${Object.keys(prevInput)}]`);
|
|
1600
1736
|
assistantContent.push({
|
|
1601
1737
|
type: 'tool_use',
|
|
1602
1738
|
id: currentToolUse.id,
|
|
1603
1739
|
name: currentToolUse.name,
|
|
1604
1740
|
input: prevInput,
|
|
1605
1741
|
});
|
|
1606
|
-
|
|
1742
|
+
// 通知前端完整 input(参数流完毕)
|
|
1743
|
+
callbacks.onToolUseInputReady?.(currentToolUse.id, prevInput);
|
|
1607
1744
|
}
|
|
1608
|
-
//
|
|
1745
|
+
// 开始新的工具调用 — 立即通知前端(参数尚在流式传输)
|
|
1609
1746
|
currentToolUse = {
|
|
1610
1747
|
id: event.id || '',
|
|
1611
1748
|
name: event.name || '',
|
|
1612
1749
|
inputJson: '',
|
|
1613
1750
|
};
|
|
1751
|
+
console.log(`[StreamDebug] tool_use_start: new tool ${currentToolUse.name}(${currentToolUse.id}), sending _streaming=true to frontend`);
|
|
1752
|
+
callbacks.onToolUseStart?.(currentToolUse.id, currentToolUse.name, { _streaming: true });
|
|
1614
1753
|
break;
|
|
1615
1754
|
case 'tool_use_delta':
|
|
1616
1755
|
if (currentToolUse && event.input) {
|
|
@@ -1618,6 +1757,31 @@ export class ConversationManager {
|
|
|
1618
1757
|
callbacks.onToolUseDelta?.(currentToolUse.id, event.input);
|
|
1619
1758
|
}
|
|
1620
1759
|
break;
|
|
1760
|
+
case 'tool_use_complete': {
|
|
1761
|
+
// 来自 SDK finalMessage 的完整 tool_use(input 已由 SDK parse 好)
|
|
1762
|
+
// 覆盖手动拼接的 inputJson,确保 input 的正确性
|
|
1763
|
+
const completeId = event.id;
|
|
1764
|
+
const completeInput = event.input;
|
|
1765
|
+
console.log(`[StreamDebug] tool_use_complete: id=${completeId}, inputKeys=${completeInput ? Object.keys(completeInput) : 'null'}`);
|
|
1766
|
+
// 如果当前有正在流式接收的工具且 id 匹配,直接注入解析好的 input
|
|
1767
|
+
if (currentToolUse && currentToolUse.id === completeId) {
|
|
1768
|
+
// 把 SDK 解析好的 input 保存到 currentToolUse(stop 事件会用)
|
|
1769
|
+
currentToolUse.parsedInput = completeInput;
|
|
1770
|
+
}
|
|
1771
|
+
else {
|
|
1772
|
+
// 可能是之前已经 push 到 assistantContent 的工具(多工具场景)
|
|
1773
|
+
// 用 SDK 的 input 覆盖手动 parse 的结果
|
|
1774
|
+
for (const block of assistantContent) {
|
|
1775
|
+
if (block.type === 'tool_use' && block.id === completeId) {
|
|
1776
|
+
block.input = completeInput || {};
|
|
1777
|
+
// 同时通知前端更新
|
|
1778
|
+
callbacks.onToolUseInputReady?.(completeId, completeInput || {});
|
|
1779
|
+
break;
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
break;
|
|
1784
|
+
}
|
|
1621
1785
|
case 'stop':
|
|
1622
1786
|
// 完成当前文本块
|
|
1623
1787
|
if (currentTextContent) {
|
|
@@ -1626,12 +1790,22 @@ export class ConversationManager {
|
|
|
1626
1790
|
}
|
|
1627
1791
|
// 完成当前工具调用
|
|
1628
1792
|
if (currentToolUse) {
|
|
1793
|
+
// 优先使用 SDK finalMessage 中的 input(由 tool_use_complete 事件注入)
|
|
1794
|
+
// 回退到手动拼接 inputJson + JSON.parse(兼容非标准 API)
|
|
1629
1795
|
let parsedInput = {};
|
|
1630
|
-
|
|
1631
|
-
|
|
1796
|
+
const sdkInput = currentToolUse.parsedInput;
|
|
1797
|
+
if (sdkInput && typeof sdkInput === 'object' && Object.keys(sdkInput).length > 0) {
|
|
1798
|
+
parsedInput = sdkInput;
|
|
1799
|
+
console.log(`[StreamDebug] stop: using SDK input for ${currentToolUse.name}(${currentToolUse.id}), keys=[${Object.keys(parsedInput)}]`);
|
|
1632
1800
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1801
|
+
else {
|
|
1802
|
+
try {
|
|
1803
|
+
parsedInput = JSON.parse(currentToolUse.inputJson || '{}');
|
|
1804
|
+
console.log(`[StreamDebug] stop: using manual JSON.parse for ${currentToolUse.name}(${currentToolUse.id}), inputJson.length=${currentToolUse.inputJson.length}, keys=[${Object.keys(parsedInput)}]`);
|
|
1805
|
+
}
|
|
1806
|
+
catch (e) {
|
|
1807
|
+
console.warn(`[StreamDebug] stop: JSON.parse FAILED for ${currentToolUse.name} (length=${currentToolUse.inputJson.length}, stopReason=${event.stopReason}), raw start: ${currentToolUse.inputJson.slice(0, 200)}`);
|
|
1808
|
+
}
|
|
1635
1809
|
}
|
|
1636
1810
|
assistantContent.push({
|
|
1637
1811
|
type: 'tool_use',
|
|
@@ -1639,8 +1813,8 @@ export class ConversationManager {
|
|
|
1639
1813
|
name: currentToolUse.name,
|
|
1640
1814
|
input: parsedInput,
|
|
1641
1815
|
});
|
|
1642
|
-
//
|
|
1643
|
-
callbacks.
|
|
1816
|
+
// 通知前端完整 input(onToolUseStart 已在 tool_use_start 事件时发送)
|
|
1817
|
+
callbacks.onToolUseInputReady?.(currentToolUse.id, parsedInput);
|
|
1644
1818
|
currentToolUse = null;
|
|
1645
1819
|
}
|
|
1646
1820
|
stopReason = event.stopReason || null;
|
|
@@ -1794,6 +1968,28 @@ export class ConversationManager {
|
|
|
1794
1968
|
allNewMessages.push(...result.newMessages);
|
|
1795
1969
|
}
|
|
1796
1970
|
}
|
|
1971
|
+
// Auto-verify: 注入验证提示到最后一个工具结果
|
|
1972
|
+
if (sessionId && toolResults.length > 0) {
|
|
1973
|
+
try {
|
|
1974
|
+
const tracker = getChangeTracker(sessionId);
|
|
1975
|
+
const cwd = state.session.cwd || process.cwd();
|
|
1976
|
+
const hint = tracker.generateHint(cwd);
|
|
1977
|
+
if (hint) {
|
|
1978
|
+
// 找到最后一个 text 类型的工具结果并追加提示
|
|
1979
|
+
const lastResult = toolResults[toolResults.length - 1];
|
|
1980
|
+
if (typeof lastResult.content === 'string') {
|
|
1981
|
+
lastResult.content += `\n\n<auto-verify>${hint}</auto-verify>`;
|
|
1982
|
+
}
|
|
1983
|
+
else if (Array.isArray(lastResult.content)) {
|
|
1984
|
+
const textBlocks = lastResult.content.filter((b) => b.type === 'text');
|
|
1985
|
+
if (textBlocks.length > 0) {
|
|
1986
|
+
textBlocks[textBlocks.length - 1].text += `\n\n<auto-verify>${hint}</auto-verify>`;
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
catch { /* auto-verify 失败不影响主流程 */ }
|
|
1992
|
+
}
|
|
1797
1993
|
// 添加工具结果到消息
|
|
1798
1994
|
if (toolResults.length > 0) {
|
|
1799
1995
|
const toolResultMsg = {
|
|
@@ -1834,6 +2030,13 @@ export class ConversationManager {
|
|
|
1834
2030
|
else {
|
|
1835
2031
|
// 对话结束
|
|
1836
2032
|
continueLoop = false;
|
|
2033
|
+
// 对齐官方:max_tokens 截断时,流式输出错误消息告知用户
|
|
2034
|
+
if (stopReason === 'max_tokens') {
|
|
2035
|
+
const currentMax = getMaxOutputTokens(resolvedModel);
|
|
2036
|
+
const errorMsg = `\n\nClaude's response exceeded the ${currentMax} output token maximum. ` +
|
|
2037
|
+
`Set CLAUDE_CODE_MAX_OUTPUT_TOKENS environment variable to a higher value to configure.`;
|
|
2038
|
+
callbacks.onTextDelta?.(errorMsg);
|
|
2039
|
+
}
|
|
1837
2040
|
// 添加到聊天历史
|
|
1838
2041
|
const chatContent = assistantContent.map(block => {
|
|
1839
2042
|
if (block.type === 'text') {
|
|
@@ -1857,6 +2060,7 @@ export class ConversationManager {
|
|
|
1857
2060
|
timestamp: Date.now(),
|
|
1858
2061
|
content: chatContent,
|
|
1859
2062
|
model: state.model,
|
|
2063
|
+
runtimeBackend: state.runtimeBackend,
|
|
1860
2064
|
usage: {
|
|
1861
2065
|
inputTokens: totalInputTokens,
|
|
1862
2066
|
outputTokens: totalOutputTokens,
|
|
@@ -2083,6 +2287,7 @@ export class ConversationManager {
|
|
|
2083
2287
|
sessionData.messages = state.messages;
|
|
2084
2288
|
sessionData.chatHistory = state.chatHistory;
|
|
2085
2289
|
sessionData.currentModel = state.model;
|
|
2290
|
+
sessionData.metadata.runtimeBackend = state.runtimeBackend;
|
|
2086
2291
|
sessionData.toolFilterConfig = state.toolFilterConfig;
|
|
2087
2292
|
sessionData.systemPromptConfig = state.systemPromptConfig;
|
|
2088
2293
|
sessionData.metadata.messageCount = state.messages.length;
|
|
@@ -2124,7 +2329,7 @@ export class ConversationManager {
|
|
|
2124
2329
|
// 如果 messages 中的 assistant 消息比 chatHistory 多,说明有消息没有同步
|
|
2125
2330
|
if (assistantMsgCount > assistantChatCount) {
|
|
2126
2331
|
// 从 messages 重建 chatHistory
|
|
2127
|
-
state.chatHistory = this.convertMessagesToChatHistory(state.messages);
|
|
2332
|
+
state.chatHistory = this.convertMessagesToChatHistory(state.messages, state.runtimeBackend);
|
|
2128
2333
|
console.log(`[ConversationManager] Syncing chatHistory: messages=${assistantMsgCount}, chatHistory=${state.chatHistory.filter(m => m.role === 'assistant').length}`);
|
|
2129
2334
|
}
|
|
2130
2335
|
}
|
|
@@ -2246,7 +2451,7 @@ export class ConversationManager {
|
|
|
2246
2451
|
// --- 阶段 2: 执行子 agent ---
|
|
2247
2452
|
sendCountdown('executing', 0);
|
|
2248
2453
|
console.log(`[ScheduleTask] Countdown finished, starting execution: ${taskName}`);
|
|
2249
|
-
const mainClientConfig = this.buildClientConfig(input.model || state.model);
|
|
2454
|
+
const mainClientConfig = this.buildClientConfig(input.model || state.model, state.runtimeBackend);
|
|
2250
2455
|
const startedAt = Date.now();
|
|
2251
2456
|
try {
|
|
2252
2457
|
const result = await state.taskManager.executeScheduleTaskInline(taskName, task.prompt, {
|
|
@@ -2370,20 +2575,24 @@ export class ConversationManager {
|
|
|
2370
2575
|
callbacks.onToolResult?.(toolUse.id, false, undefined, error);
|
|
2371
2576
|
return { success: false, error };
|
|
2372
2577
|
}
|
|
2578
|
+
const normalizedToolInput = normalizeToolInputForWebRuntime(toolUse.input, tool?.getInputSchema());
|
|
2579
|
+
const normalizedToolUse = normalizedToolInput === toolUse.input
|
|
2580
|
+
? toolUse
|
|
2581
|
+
: { ...toolUse, input: normalizedToolInput };
|
|
2373
2582
|
// 检查工具是否被过滤
|
|
2374
|
-
if (!this.isToolEnabled(
|
|
2375
|
-
const error = `Tool ${
|
|
2376
|
-
callbacks.onToolResult?.(
|
|
2583
|
+
if (!this.isToolEnabled(normalizedToolUse.name, state.toolFilterConfig)) {
|
|
2584
|
+
const error = `Tool ${normalizedToolUse.name} is disabled`;
|
|
2585
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2377
2586
|
return { success: false, error };
|
|
2378
2587
|
}
|
|
2379
2588
|
// ========================================================================
|
|
2380
2589
|
// 权限检查(对齐 CLI loop.ts 的 handlePermissionRequest 逻辑)
|
|
2381
2590
|
// ========================================================================
|
|
2382
2591
|
try {
|
|
2383
|
-
const permissionResult = await this.checkToolPermission(
|
|
2592
|
+
const permissionResult = await this.checkToolPermission(normalizedToolUse, state, callbacks);
|
|
2384
2593
|
if (permissionResult === 'denied') {
|
|
2385
|
-
const error = `User denied execution permission for ${
|
|
2386
|
-
callbacks.onToolResult?.(
|
|
2594
|
+
const error = `User denied execution permission for ${normalizedToolUse.name}`;
|
|
2595
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2387
2596
|
return { success: false, error };
|
|
2388
2597
|
}
|
|
2389
2598
|
// permissionResult === 'allowed' 或 'skipped'(无需权限),继续执行
|
|
@@ -2391,7 +2600,7 @@ export class ConversationManager {
|
|
|
2391
2600
|
catch (permError) {
|
|
2392
2601
|
// 权限请求超时或被取消
|
|
2393
2602
|
const error = permError instanceof Error ? permError.message : 'Permission request failed';
|
|
2394
|
-
callbacks.onToolResult?.(
|
|
2603
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2395
2604
|
return { success: false, error };
|
|
2396
2605
|
}
|
|
2397
2606
|
// ========================================================================
|
|
@@ -2399,10 +2608,10 @@ export class ConversationManager {
|
|
|
2399
2608
|
// ========================================================================
|
|
2400
2609
|
const hookSessionId = state.session.sessionId || '';
|
|
2401
2610
|
try {
|
|
2402
|
-
const hookResult = await runPreToolUseHooks(
|
|
2611
|
+
const hookResult = await runPreToolUseHooks(normalizedToolUse.name, normalizedToolUse.input, hookSessionId);
|
|
2403
2612
|
if (!hookResult.allowed) {
|
|
2404
|
-
const error = hookResult.message || `PreToolUse hook blocked execution of ${
|
|
2405
|
-
callbacks.onToolResult?.(
|
|
2613
|
+
const error = hookResult.message || `PreToolUse hook blocked execution of ${normalizedToolUse.name}`;
|
|
2614
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2406
2615
|
return { success: false, error };
|
|
2407
2616
|
}
|
|
2408
2617
|
}
|
|
@@ -2411,23 +2620,23 @@ export class ConversationManager {
|
|
|
2411
2620
|
console.warn(`[Hook] PreToolUse hook execution failed:`, hookError);
|
|
2412
2621
|
}
|
|
2413
2622
|
try {
|
|
2414
|
-
console.log(`[Tool] Executing ${
|
|
2623
|
+
console.log(`[Tool] Executing ${normalizedToolUse.name}:`, JSON.stringify(normalizedToolUse.input).slice(0, 200));
|
|
2415
2624
|
// 拦截 Task 工具 - WebUI 模式下使用同步执行 + WebSocket 实时推送
|
|
2416
2625
|
// 不再默认后台执行,避免 TaskOutput 多次轮询的性能浪费
|
|
2417
|
-
if (
|
|
2418
|
-
const input =
|
|
2626
|
+
if (normalizedToolUse.name === 'Task') {
|
|
2627
|
+
const input = normalizedToolUse.input;
|
|
2419
2628
|
const description = input.description || 'Background task';
|
|
2420
2629
|
const prompt = input.prompt || '';
|
|
2421
2630
|
const agentType = input.subagent_type || 'general-purpose';
|
|
2422
2631
|
// 验证必需参数
|
|
2423
2632
|
if (!prompt) {
|
|
2424
2633
|
const error = 'Task prompt is required';
|
|
2425
|
-
callbacks.onToolResult?.(
|
|
2634
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2426
2635
|
return { success: false, error };
|
|
2427
2636
|
}
|
|
2428
2637
|
try {
|
|
2429
2638
|
// 获取主 agent 的认证信息,传递给子 agent 复用(避免子 agent initAuth 拿到不同凭证导致 403)
|
|
2430
|
-
const mainClientConfig = this.buildClientConfig(input.model || state.model);
|
|
2639
|
+
const mainClientConfig = this.buildClientConfig(input.model || state.model, state.runtimeBackend);
|
|
2431
2640
|
// WebUI 始终使用同步执行:await 拿结果,中间过程由 TaskManager 通过 WebSocket 实时推送
|
|
2432
2641
|
const result = await state.taskManager.executeTaskSync(description, prompt, agentType, {
|
|
2433
2642
|
model: input.model || state.model,
|
|
@@ -2438,7 +2647,7 @@ export class ConversationManager {
|
|
|
2438
2647
|
authToken: mainClientConfig.authToken,
|
|
2439
2648
|
baseUrl: mainClientConfig.baseUrl,
|
|
2440
2649
|
},
|
|
2441
|
-
toolUseId:
|
|
2650
|
+
toolUseId: normalizedToolUse.id,
|
|
2442
2651
|
maxTurns: input.max_turns,
|
|
2443
2652
|
});
|
|
2444
2653
|
let output;
|
|
@@ -2460,7 +2669,7 @@ export class ConversationManager {
|
|
|
2460
2669
|
}
|
|
2461
2670
|
output = parts.join('');
|
|
2462
2671
|
}
|
|
2463
|
-
callbacks.onToolResult?.(
|
|
2672
|
+
callbacks.onToolResult?.(normalizedToolUse.id, result.success, output, result.success ? undefined : result.error, {
|
|
2464
2673
|
tool: 'Task',
|
|
2465
2674
|
agentType,
|
|
2466
2675
|
description,
|
|
@@ -2472,13 +2681,13 @@ export class ConversationManager {
|
|
|
2472
2681
|
catch (error) {
|
|
2473
2682
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2474
2683
|
console.error(`[Tool] Task execution failed:`, errorMessage);
|
|
2475
|
-
callbacks.onToolResult?.(
|
|
2684
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2476
2685
|
return { success: false, error: errorMessage };
|
|
2477
2686
|
}
|
|
2478
2687
|
}
|
|
2479
2688
|
// 拦截 ScheduleTask 工具 - inline 执行时提供倒计时 + 子 agent 渲染
|
|
2480
|
-
if (
|
|
2481
|
-
const input =
|
|
2689
|
+
if (normalizedToolUse.name === 'ScheduleTask') {
|
|
2690
|
+
const input = normalizedToolUse.input;
|
|
2482
2691
|
// 只拦截 create + once + 10分钟内的情况(即 inline 执行路径)
|
|
2483
2692
|
if (input.action === 'create' && input.type === 'once' && input.triggerAt) {
|
|
2484
2693
|
try {
|
|
@@ -2506,15 +2715,15 @@ export class ConversationManager {
|
|
|
2506
2715
|
const scheduleTool = toolRegistry.get('ScheduleTask');
|
|
2507
2716
|
if (!scheduleTool) {
|
|
2508
2717
|
const error = 'ScheduleTask tool not found in registry';
|
|
2509
|
-
callbacks.onToolResult?.(
|
|
2718
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2510
2719
|
return { success: false, error };
|
|
2511
2720
|
}
|
|
2512
|
-
const rawResult = await scheduleTool.execute(
|
|
2721
|
+
const rawResult = await scheduleTool.execute(normalizedToolUse.input);
|
|
2513
2722
|
const result = typeof rawResult === 'object' && rawResult !== null
|
|
2514
2723
|
? rawResult
|
|
2515
2724
|
: { success: true, output: String(rawResult) };
|
|
2516
2725
|
// 通知前端工具结果
|
|
2517
|
-
callbacks.onToolResult?.(
|
|
2726
|
+
callbacks.onToolResult?.(normalizedToolUse.id, result.success, result.output, result.error);
|
|
2518
2727
|
// 用差集精确找到新创建的任务
|
|
2519
2728
|
if (result.success && existingIds) {
|
|
2520
2729
|
try {
|
|
@@ -2533,15 +2742,15 @@ export class ConversationManager {
|
|
|
2533
2742
|
// list/cancel/watch 走正常工具执行路径
|
|
2534
2743
|
}
|
|
2535
2744
|
// 拦截 TaskOutput 工具 - 从 TaskManager 获取任务输出
|
|
2536
|
-
if (
|
|
2537
|
-
const input =
|
|
2745
|
+
if (normalizedToolUse.name === 'TaskOutput') {
|
|
2746
|
+
const input = normalizedToolUse.input;
|
|
2538
2747
|
const taskId = input.task_id;
|
|
2539
2748
|
const block = input.block !== false;
|
|
2540
2749
|
const timeout = input.timeout || 300000; // 默认5分钟超时
|
|
2541
2750
|
const showHistory = input.show_history || false;
|
|
2542
2751
|
if (!taskId) {
|
|
2543
2752
|
const error = 'task_id is required';
|
|
2544
|
-
callbacks.onToolResult?.(
|
|
2753
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2545
2754
|
return { success: false, error };
|
|
2546
2755
|
}
|
|
2547
2756
|
try {
|
|
@@ -2560,11 +2769,11 @@ export class ConversationManager {
|
|
|
2560
2769
|
const fallbackSuccess = typeof fallbackResult === 'string'
|
|
2561
2770
|
? true
|
|
2562
2771
|
: fallbackResult?.success ?? false;
|
|
2563
|
-
callbacks.onToolResult?.(
|
|
2772
|
+
callbacks.onToolResult?.(normalizedToolUse.id, fallbackSuccess, fallbackOutput, fallbackSuccess ? undefined : fallbackOutput);
|
|
2564
2773
|
return { success: fallbackSuccess, output: fallbackOutput, error: fallbackSuccess ? undefined : fallbackOutput };
|
|
2565
2774
|
}
|
|
2566
2775
|
const error = `Task ${taskId} not found`;
|
|
2567
|
-
callbacks.onToolResult?.(
|
|
2776
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2568
2777
|
return { success: false, error };
|
|
2569
2778
|
}
|
|
2570
2779
|
// 如果需要阻塞等待完成
|
|
@@ -2575,7 +2784,7 @@ export class ConversationManager {
|
|
|
2575
2784
|
}
|
|
2576
2785
|
if (task.status === 'running') {
|
|
2577
2786
|
const output = `Task ${taskId} is still running (timeout reached).\n\nStatus: ${task.status}\nDescription: ${task.description}`;
|
|
2578
|
-
callbacks.onToolResult?.(
|
|
2787
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2579
2788
|
return { success: true, output };
|
|
2580
2789
|
}
|
|
2581
2790
|
}
|
|
@@ -2608,23 +2817,23 @@ export class ConversationManager {
|
|
|
2608
2817
|
else if (task.error) {
|
|
2609
2818
|
output += `\nError: ${task.error}`;
|
|
2610
2819
|
}
|
|
2611
|
-
callbacks.onToolResult?.(
|
|
2820
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2612
2821
|
return { success: true, output };
|
|
2613
2822
|
}
|
|
2614
2823
|
catch (error) {
|
|
2615
2824
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2616
2825
|
console.error(`[Tool] TaskOutput execution failed:`, errorMessage);
|
|
2617
|
-
callbacks.onToolResult?.(
|
|
2826
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2618
2827
|
return { success: false, error: errorMessage };
|
|
2619
2828
|
}
|
|
2620
2829
|
}
|
|
2621
2830
|
// 拦截 AskUserQuestion 工具 - 通过 WebSocket 向前端发送问题
|
|
2622
|
-
if (
|
|
2623
|
-
const input =
|
|
2831
|
+
if (normalizedToolUse.name === 'AskUserQuestion') {
|
|
2832
|
+
const input = normalizedToolUse.input;
|
|
2624
2833
|
const questions = input.questions || [];
|
|
2625
2834
|
if (questions.length === 0) {
|
|
2626
2835
|
const error = 'No questions provided';
|
|
2627
|
-
callbacks.onToolResult?.(
|
|
2836
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2628
2837
|
return { success: false, error };
|
|
2629
2838
|
}
|
|
2630
2839
|
const answers = {};
|
|
@@ -2645,19 +2854,19 @@ export class ConversationManager {
|
|
|
2645
2854
|
.map(([header, answer]) => `"${header}"="${answer}"`)
|
|
2646
2855
|
.join(', ');
|
|
2647
2856
|
const output = `User has answered your questions: ${formattedAnswers}. You can now continue with the user's answers in mind.`;
|
|
2648
|
-
callbacks.onToolResult?.(
|
|
2857
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2649
2858
|
return { success: true, output };
|
|
2650
2859
|
}
|
|
2651
2860
|
catch (error) {
|
|
2652
2861
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2653
2862
|
console.error(`[Tool] AskUserQuestion failed:`, errorMessage);
|
|
2654
|
-
callbacks.onToolResult?.(
|
|
2863
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2655
2864
|
return { success: false, error: errorMessage };
|
|
2656
2865
|
}
|
|
2657
2866
|
}
|
|
2658
2867
|
// 拦截 GenerateBlueprint 工具 - 将对话需求结构化为蓝图
|
|
2659
|
-
if (
|
|
2660
|
-
const input =
|
|
2868
|
+
if (normalizedToolUse.name === 'GenerateBlueprint') {
|
|
2869
|
+
const input = normalizedToolUse.input;
|
|
2661
2870
|
try {
|
|
2662
2871
|
const blueprintId = `bp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
2663
2872
|
const hasModules = Array.isArray(input.modules) && input.modules.length > 0;
|
|
@@ -2735,19 +2944,19 @@ export class ConversationManager {
|
|
|
2735
2944
|
? `Modules: ${moduleCount}, Processes: ${processCount}, NFR: ${nfrCount}`
|
|
2736
2945
|
: `Requirements: ${reqCount}`;
|
|
2737
2946
|
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?.(
|
|
2947
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2739
2948
|
return { success: true, output };
|
|
2740
2949
|
}
|
|
2741
2950
|
catch (error) {
|
|
2742
2951
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2743
2952
|
console.error(`[Tool] GenerateBlueprint execution failed:`, errorMessage);
|
|
2744
|
-
callbacks.onToolResult?.(
|
|
2953
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2745
2954
|
return { success: false, error: errorMessage };
|
|
2746
2955
|
}
|
|
2747
2956
|
}
|
|
2748
2957
|
// v11.0: StartLeadAgent 不再拦截,走正常 tool.execute() 路径
|
|
2749
2958
|
// 执行前动态绑定当前会话的 WebSocket 和工作目录,确保蜂群在正确的项目路径下执行
|
|
2750
|
-
if (
|
|
2959
|
+
if (normalizedToolUse.name === 'StartLeadAgent') {
|
|
2751
2960
|
const currentCtx = StartLeadAgentTool.getContext();
|
|
2752
2961
|
if (currentCtx) {
|
|
2753
2962
|
StartLeadAgentTool.setContext({
|
|
@@ -2766,15 +2975,30 @@ export class ConversationManager {
|
|
|
2766
2975
|
}
|
|
2767
2976
|
}
|
|
2768
2977
|
// 拦截 ImageGen 工具 - 文生图 / 图生图
|
|
2769
|
-
if (
|
|
2770
|
-
const input =
|
|
2978
|
+
if (normalizedToolUse.name === 'ImageGen') {
|
|
2979
|
+
const input = normalizedToolUse.input;
|
|
2771
2980
|
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
|
|
2981
|
+
const { prompt, style, size, edit_strength, image_path, image_base64, image_mime_type, output_path } = input;
|
|
2982
|
+
console.log(`[Tool] ImageGen: ${image_path || image_base64 ? 'image-to-image' : 'text-to-image'} - ${prompt.substring(0, 50)}...`);
|
|
2983
|
+
const resolvedImageSource = resolveImageGenSource({
|
|
2984
|
+
image_path,
|
|
2985
|
+
image_base64,
|
|
2986
|
+
image_mime_type,
|
|
2987
|
+
}, state.latestImageAttachments);
|
|
2988
|
+
if (image_path && resolvedImageSource.imagePath && resolvedImageSource.imagePath !== image_path) {
|
|
2989
|
+
console.log(`[Tool] ImageGen: remapped uploaded image_path "${image_path}" -> "${resolvedImageSource.imagePath}"`);
|
|
2990
|
+
}
|
|
2991
|
+
else if (image_path && resolvedImageSource.imageBase64) {
|
|
2992
|
+
console.log(`[Tool] ImageGen: fell back to uploaded image base64 for "${image_path}"`);
|
|
2993
|
+
}
|
|
2994
|
+
const result = await geminiImageService.generateImage(prompt, style, {
|
|
2995
|
+
imagePath: resolvedImageSource.imagePath,
|
|
2996
|
+
imageBase64: resolvedImageSource.imageBase64,
|
|
2997
|
+
imageMimeType: resolvedImageSource.imageMimeType,
|
|
2998
|
+
}, output_path, size, edit_strength);
|
|
2775
2999
|
if (!result.success) {
|
|
2776
3000
|
const error = result.error || 'Image generation failed';
|
|
2777
|
-
callbacks.onToolResult?.(
|
|
3001
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2778
3002
|
return { success: false, error };
|
|
2779
3003
|
}
|
|
2780
3004
|
// 通过 WebSocket 发送图片给前端显示
|
|
@@ -2789,21 +3013,28 @@ export class ConversationManager {
|
|
|
2789
3013
|
},
|
|
2790
3014
|
}));
|
|
2791
3015
|
}
|
|
2792
|
-
const
|
|
2793
|
-
|
|
3016
|
+
const parts = ['Image generated and sent to user for preview.'];
|
|
3017
|
+
if (result.savedPath) {
|
|
3018
|
+
parts.push(`\nSaved to: ${result.savedPath}`);
|
|
3019
|
+
}
|
|
3020
|
+
if (result.generatedText) {
|
|
3021
|
+
parts.push(`\nDescription: ${result.generatedText}`);
|
|
3022
|
+
}
|
|
3023
|
+
const output = parts.join('');
|
|
3024
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2794
3025
|
return { success: true, output };
|
|
2795
3026
|
}
|
|
2796
3027
|
catch (error) {
|
|
2797
3028
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2798
3029
|
console.error(`[Tool] ImageGen execution failed:`, errorMessage);
|
|
2799
|
-
callbacks.onToolResult?.(
|
|
3030
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2800
3031
|
return { success: false, error: errorMessage };
|
|
2801
3032
|
}
|
|
2802
3033
|
}
|
|
2803
3034
|
// 拦截 Mcp 工具的 server management actions (action=list/enable/disable)
|
|
2804
3035
|
// 这些 action 需要访问 ConversationManager 的 toggleMcpServer/listMcpServers
|
|
2805
|
-
if (
|
|
2806
|
-
const input =
|
|
3036
|
+
if (normalizedToolUse.name === 'Mcp') {
|
|
3037
|
+
const input = normalizedToolUse.input;
|
|
2807
3038
|
if (input.action) {
|
|
2808
3039
|
try {
|
|
2809
3040
|
if (input.action === 'list') {
|
|
@@ -2812,13 +3043,13 @@ export class ConversationManager {
|
|
|
2812
3043
|
const output = servers.length > 0
|
|
2813
3044
|
? `MCP Servers (${servers.length}):\n${lines.join('\n')}`
|
|
2814
3045
|
: 'No MCP servers configured.';
|
|
2815
|
-
callbacks.onToolResult?.(
|
|
3046
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2816
3047
|
return { success: true, output };
|
|
2817
3048
|
}
|
|
2818
3049
|
if (input.action === 'enable' || input.action === 'disable') {
|
|
2819
3050
|
if (!input.name) {
|
|
2820
3051
|
const error = `"name" parameter is required for ${input.action} action.`;
|
|
2821
|
-
callbacks.onToolResult?.(
|
|
3052
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2822
3053
|
return { success: false, error };
|
|
2823
3054
|
}
|
|
2824
3055
|
const enabled = input.action === 'enable';
|
|
@@ -2832,23 +3063,23 @@ export class ConversationManager {
|
|
|
2832
3063
|
this.temporarilyEnabledMcpServers.delete(input.name);
|
|
2833
3064
|
}
|
|
2834
3065
|
const output = `MCP server "${input.name}" has been ${result.enabled ? 'enabled' : 'disabled'}.`;
|
|
2835
|
-
callbacks.onToolResult?.(
|
|
3066
|
+
callbacks.onToolResult?.(normalizedToolUse.id, true, output);
|
|
2836
3067
|
return { success: true, output };
|
|
2837
3068
|
}
|
|
2838
3069
|
else {
|
|
2839
3070
|
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?.(
|
|
3071
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2841
3072
|
return { success: false, error };
|
|
2842
3073
|
}
|
|
2843
3074
|
}
|
|
2844
3075
|
const error = `Unknown Mcp action: ${input.action}. Use "list", "enable", or "disable".`;
|
|
2845
|
-
callbacks.onToolResult?.(
|
|
3076
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2846
3077
|
return { success: false, error };
|
|
2847
3078
|
}
|
|
2848
3079
|
catch (error) {
|
|
2849
3080
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2850
3081
|
console.error(`[Tool] Mcp server management failed:`, errorMessage);
|
|
2851
|
-
callbacks.onToolResult?.(
|
|
3082
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
|
|
2852
3083
|
return { success: false, error: errorMessage };
|
|
2853
3084
|
}
|
|
2854
3085
|
}
|
|
@@ -2856,34 +3087,34 @@ export class ConversationManager {
|
|
|
2856
3087
|
}
|
|
2857
3088
|
// MCP 工具执行:解析 mcp__{serverName}__{toolName} 格式,调用 callMcpTool()
|
|
2858
3089
|
if (isMcpTool) {
|
|
2859
|
-
const parts =
|
|
3090
|
+
const parts = normalizedToolUse.name.split('__');
|
|
2860
3091
|
// 格式: mcp__{serverName}__{toolName}
|
|
2861
3092
|
const mcpServerName = parts[1];
|
|
2862
3093
|
const mcpToolName = parts.slice(2).join('__');
|
|
2863
3094
|
if (!mcpServerName || !mcpToolName) {
|
|
2864
|
-
const error = `Invalid MCP tool name format: ${
|
|
2865
|
-
callbacks.onToolResult?.(
|
|
3095
|
+
const error = `Invalid MCP tool name format: ${normalizedToolUse.name}`;
|
|
3096
|
+
callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
|
|
2866
3097
|
return { success: false, error };
|
|
2867
3098
|
}
|
|
2868
|
-
const mcpResult = await callMcpTool(mcpServerName, mcpToolName,
|
|
3099
|
+
const mcpResult = await callMcpTool(mcpServerName, mcpToolName, normalizedToolUse.input);
|
|
2869
3100
|
const mcpOutput = mcpResult.output || mcpResult.error || JSON.stringify(mcpResult);
|
|
2870
3101
|
const truncatedMcpOutput = mcpOutput.length > 50000
|
|
2871
3102
|
? mcpOutput.slice(0, 50000) + '\n... (output truncated)'
|
|
2872
3103
|
: mcpOutput;
|
|
2873
3104
|
// PostToolUse Hook
|
|
2874
3105
|
try {
|
|
2875
|
-
await runPostToolUseHooks(
|
|
3106
|
+
await runPostToolUseHooks(normalizedToolUse.name, normalizedToolUse.input, truncatedMcpOutput, hookSessionId);
|
|
2876
3107
|
}
|
|
2877
3108
|
catch (hookError) {
|
|
2878
3109
|
console.warn(`[Hook] PostToolUse hook execution failed:`, hookError);
|
|
2879
3110
|
}
|
|
2880
|
-
callbacks.onToolResult?.(
|
|
3111
|
+
callbacks.onToolResult?.(normalizedToolUse.id, mcpResult.success, truncatedMcpOutput, mcpResult.error ? mcpResult.error : undefined);
|
|
2881
3112
|
return { success: mcpResult.success, output: truncatedMcpOutput, error: mcpResult.error };
|
|
2882
3113
|
}
|
|
2883
3114
|
// 执行其他工具(内置 registry 工具)
|
|
2884
|
-
const result = await tool.execute(
|
|
3115
|
+
const result = await tool.execute(normalizedToolUse.input);
|
|
2885
3116
|
// 构建结构化数据
|
|
2886
|
-
const data = this.buildToolResultData(
|
|
3117
|
+
const data = this.buildToolResultData(normalizedToolUse.name, normalizedToolUse.input, result);
|
|
2887
3118
|
// 格式化输出
|
|
2888
3119
|
let output;
|
|
2889
3120
|
if (typeof result === 'string') {
|
|
@@ -2918,7 +3149,7 @@ export class ConversationManager {
|
|
|
2918
3149
|
: undefined;
|
|
2919
3150
|
// PostToolUse Hook
|
|
2920
3151
|
try {
|
|
2921
|
-
await runPostToolUseHooks(
|
|
3152
|
+
await runPostToolUseHooks(normalizedToolUse.name, normalizedToolUse.input, output, hookSessionId);
|
|
2922
3153
|
}
|
|
2923
3154
|
catch (hookError) {
|
|
2924
3155
|
console.warn(`[Hook] PostToolUse hook execution failed:`, hookError);
|
|
@@ -3467,6 +3698,10 @@ Respond ONLY with valid JSON, no other text.`;
|
|
|
3467
3698
|
}
|
|
3468
3699
|
// 构建提示上下文(与 CLI loop.ts 保持一致)
|
|
3469
3700
|
// 注意:不注入 contextUsage,保持 system prompt 稳定可缓存
|
|
3701
|
+
const runtimeBackend = state.runtimeBackend || this.getRuntimeBackend();
|
|
3702
|
+
const authStatus = webAuth.getStatus();
|
|
3703
|
+
const isAnthropicOauth = authStatus.type === 'oauth'
|
|
3704
|
+
&& getProviderForRuntimeBackend(runtimeBackend, state.model) === 'anthropic';
|
|
3470
3705
|
const promptContext = {
|
|
3471
3706
|
workingDir: state.session.cwd,
|
|
3472
3707
|
model: this.getModelId(state.model),
|
|
@@ -3480,8 +3715,12 @@ Respond ONLY with valid JSON, no other text.`;
|
|
|
3480
3715
|
debug: false,
|
|
3481
3716
|
// v2.1.0+: 语言配置 - 与 CLI 保持一致
|
|
3482
3717
|
language: configManager.get('language'),
|
|
3483
|
-
//
|
|
3484
|
-
isOfficialAuth:
|
|
3718
|
+
// 只有 Claude 官方订阅 OAuth 才使用官方 CLI 身份前缀
|
|
3719
|
+
isOfficialAuth: isAnthropicOauth && runtimeBackend === 'claude-subscription',
|
|
3720
|
+
// Console OAuth + oauthApiKey 必须使用 Agent SDK 身份前缀
|
|
3721
|
+
coreIdentityVariant: isAnthropicOauth && runtimeBackend === 'claude-compatible-api'
|
|
3722
|
+
? 'agent'
|
|
3723
|
+
: undefined,
|
|
3485
3724
|
// Agent 笔记本内容
|
|
3486
3725
|
notebookSummary,
|
|
3487
3726
|
// MCP 服务器信息(用于系统提示中的 MCP 指令)
|
|
@@ -3638,6 +3877,29 @@ You are running in web server mode accessible by multiple users. HIGHEST PRIORIT
|
|
|
3638
3877
|
// 端口转发功能提示 — 精简版
|
|
3639
3878
|
sections.push(`# Port Forwarding
|
|
3640
3879
|
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.`);
|
|
3880
|
+
// 已注册应用感知
|
|
3881
|
+
try {
|
|
3882
|
+
const apps = getAppManager().list();
|
|
3883
|
+
if (apps.length > 0) {
|
|
3884
|
+
const appLines = apps.map(a => {
|
|
3885
|
+
const status = a.status === 'running' ? `running (pid ${a.pid}, port ${a.port || '?'})` : a.status;
|
|
3886
|
+
return `- **${a.name}** [${status}]: ${a.description || 'no description'} (dir: \`${a.directory}\`, cmd: \`${a.startCommand}\`)`;
|
|
3887
|
+
}).join('\n');
|
|
3888
|
+
sections.push(`# Managed Apps
|
|
3889
|
+
You have ${apps.length} registered app(s) in the Apps page. You can start/stop/manage them via \`GET/POST /api/apps\`.
|
|
3890
|
+
${appLines}`);
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3893
|
+
catch {
|
|
3894
|
+
// AppManager 未初始化时忽略
|
|
3895
|
+
}
|
|
3896
|
+
// ImageGen 使用约束
|
|
3897
|
+
sections.push(`## ImageGen tool usage
|
|
3898
|
+
- 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.
|
|
3899
|
+
- If the conversation context includes image attachment edit preferences, copy that preference into the ImageGen tool call as \`edit_strength\` ('low' | 'medium' | 'high').
|
|
3900
|
+
- For conservative/local edits, prefer \`edit_strength: 'low'\`.
|
|
3901
|
+
- For broader but still recognizable edits, prefer \`edit_strength: 'medium'\` or \`edit_strength: 'high'\` as appropriate.
|
|
3902
|
+
- 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
3903
|
if (sections.length === 0) {
|
|
3642
3904
|
return null;
|
|
3643
3905
|
}
|
|
@@ -3894,6 +4156,9 @@ Guidelines:
|
|
|
3894
4156
|
broadcast({ type: 'tool_use_start', payload: { messageId, toolUseId, toolName, input, sessionId: targetSessionId } });
|
|
3895
4157
|
broadcast({ type: 'status', payload: { status: 'tool_executing', message: `Executing ${toolName}...`, sessionId: targetSessionId } });
|
|
3896
4158
|
},
|
|
4159
|
+
onToolUseInputReady: (toolUseId, input) => {
|
|
4160
|
+
broadcast({ type: 'tool_use_input_ready', payload: { toolUseId, input, sessionId: targetSessionId } });
|
|
4161
|
+
},
|
|
3897
4162
|
onToolUseDelta: (toolUseId, partialJson) => broadcast({ type: 'tool_use_delta', payload: { toolUseId, partialJson, sessionId: targetSessionId } }),
|
|
3898
4163
|
onToolResult: (toolUseId, success, output, error, data) => {
|
|
3899
4164
|
broadcast({ type: 'tool_result', payload: { toolUseId, success, output, error, data: data, defaultCollapsed: true, sessionId: targetSessionId } });
|
|
@@ -3934,6 +4199,13 @@ Guidelines:
|
|
|
3934
4199
|
}
|
|
3935
4200
|
return state.session.cwd;
|
|
3936
4201
|
}
|
|
4202
|
+
/**
|
|
4203
|
+
* 获取会话名称(从 sessionManager 的持久化数据中读取)
|
|
4204
|
+
*/
|
|
4205
|
+
getSessionName(sessionId) {
|
|
4206
|
+
const sessionData = this.sessionManager.loadSessionById(sessionId);
|
|
4207
|
+
return sessionData?.metadata?.name;
|
|
4208
|
+
}
|
|
3937
4209
|
/**
|
|
3938
4210
|
* 持久化会话
|
|
3939
4211
|
*/
|
|
@@ -3963,6 +4235,7 @@ Guidelines:
|
|
|
3963
4235
|
sessionData.messages = state.messages;
|
|
3964
4236
|
sessionData.chatHistory = state.chatHistory;
|
|
3965
4237
|
sessionData.currentModel = state.model;
|
|
4238
|
+
sessionData.metadata.runtimeBackend = state.runtimeBackend;
|
|
3966
4239
|
sessionData.toolFilterConfig = state.toolFilterConfig;
|
|
3967
4240
|
sessionData.systemPromptConfig = state.systemPromptConfig;
|
|
3968
4241
|
// 关键:更新 messageCount(官方规范:统计消息数)
|
|
@@ -4019,9 +4292,10 @@ Guidelines:
|
|
|
4019
4292
|
try {
|
|
4020
4293
|
// 如果会话已经在内存中,直接返回成功(避免重复创建)
|
|
4021
4294
|
if (this.sessions.has(sessionId)) {
|
|
4295
|
+
const state = this.sessions.get(sessionId);
|
|
4296
|
+
this.ensureStateModelMatchesRuntime(state);
|
|
4022
4297
|
// 同步权限模式(修复切换会话后 YOLO 模式丢失的问题)
|
|
4023
4298
|
if (permissionMode) {
|
|
4024
|
-
const state = this.sessions.get(sessionId);
|
|
4025
4299
|
state.permissionHandler.updateConfig({ mode: permissionMode });
|
|
4026
4300
|
}
|
|
4027
4301
|
return true;
|
|
@@ -4035,15 +4309,14 @@ Guidelines:
|
|
|
4035
4309
|
const session = new Session(sessionData.metadata.workingDirectory || this.cwd);
|
|
4036
4310
|
// 在后台异步获取 Git 信息,不阻塞会话切换(Git 信息主要用于 system prompt,在用户发送消息时才需要)
|
|
4037
4311
|
session.initializeGitInfo().catch(() => { });
|
|
4038
|
-
const
|
|
4039
|
-
const
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
});
|
|
4312
|
+
const runtimeBackend = sessionData.metadata.runtimeBackend || this.getRuntimeBackend();
|
|
4313
|
+
const resolvedModel = this.normalizeRuntimeModel(sessionData.currentModel || sessionData.metadata.model || this.defaultModel, runtimeBackend);
|
|
4314
|
+
const clientConfig = this.buildClientConfig(resolvedModel, runtimeBackend);
|
|
4315
|
+
const client = createConversationClient(clientConfig);
|
|
4043
4316
|
// 如果 chatHistory 为空但 messages 不为空,从 messages 构建 chatHistory
|
|
4044
4317
|
let chatHistory = sessionData.chatHistory || [];
|
|
4045
4318
|
if (chatHistory.length === 0 && sessionData.messages && sessionData.messages.length > 0) {
|
|
4046
|
-
chatHistory = this.convertMessagesToChatHistory(sessionData.messages);
|
|
4319
|
+
chatHistory = this.convertMessagesToChatHistory(sessionData.messages, runtimeBackend);
|
|
4047
4320
|
}
|
|
4048
4321
|
const resumeUserInteractionHandler = new UserInteractionHandler();
|
|
4049
4322
|
resumeUserInteractionHandler.setSessionId(sessionId);
|
|
@@ -4051,7 +4324,8 @@ Guidelines:
|
|
|
4051
4324
|
session,
|
|
4052
4325
|
client,
|
|
4053
4326
|
messages: sessionData.messages,
|
|
4054
|
-
model:
|
|
4327
|
+
model: resolvedModel,
|
|
4328
|
+
runtimeBackend,
|
|
4055
4329
|
cancelled: false,
|
|
4056
4330
|
chatHistory,
|
|
4057
4331
|
userInteractionHandler: resumeUserInteractionHandler,
|
|
@@ -4068,8 +4342,9 @@ Guidelines:
|
|
|
4068
4342
|
processingGeneration: 0,
|
|
4069
4343
|
lastActualInputTokens: 0,
|
|
4070
4344
|
messagesLenAtLastApiCall: 0,
|
|
4345
|
+
latestImageAttachments: [],
|
|
4071
4346
|
lastPersistedMessageCount: sessionData.messages.length, // 从磁盘加载时,初始化为当前消息数
|
|
4072
|
-
credentialsFingerprint: this.getCredentialsFingerprint(),
|
|
4347
|
+
credentialsFingerprint: this.getCredentialsFingerprint(runtimeBackend),
|
|
4073
4348
|
};
|
|
4074
4349
|
this.sessions.set(sessionId, state);
|
|
4075
4350
|
// 初始化 NotebookManager(SelfEvolve 重启后 resumeSession 不经过 getOrCreateSession,需要在这里初始化)
|
|
@@ -4141,7 +4416,7 @@ Guidelines:
|
|
|
4141
4416
|
/**
|
|
4142
4417
|
* 将 API 消息格式转换为 ChatHistory 格式
|
|
4143
4418
|
*/
|
|
4144
|
-
convertMessagesToChatHistory(messages) {
|
|
4419
|
+
convertMessagesToChatHistory(messages, runtimeBackend = this.getRuntimeBackend()) {
|
|
4145
4420
|
const chatHistory = [];
|
|
4146
4421
|
// 预构建 tool_use_id → tool_result 映射,用于将工具结果关联回工具调用
|
|
4147
4422
|
const toolResultMap = new Map();
|
|
@@ -4192,6 +4467,7 @@ Guidelines:
|
|
|
4192
4467
|
role: msg.role,
|
|
4193
4468
|
timestamp: Date.now(),
|
|
4194
4469
|
content: [],
|
|
4470
|
+
runtimeBackend,
|
|
4195
4471
|
// 记录此 chatEntry 对应的 messages 位置(i+1 表示包含当前消息)
|
|
4196
4472
|
_messagesLen: i + 1,
|
|
4197
4473
|
};
|