dsh-composer-ux 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -805,6 +805,23 @@ var MENU_FIELDS = [
805
805
  "menuSelectAll"
806
806
  ];
807
807
  var MENU_NATIVE_FIELD = "menuNative";
808
+ var QUICK_PROMPTS_FIELD = "quickPrompts";
809
+ var OPTIMIZER_TIER_FIELD = "optimizerTier";
810
+ var QUICK_TEXT_MAX = 4e3;
811
+ var OPTIMIZE_OUTPUT_MAX = 12e3;
812
+ var OPTIMIZER_API_PATH = "/composer-ux/optimize";
813
+ var DEFAULT_OPTIMIZER_TIER = "advanced";
814
+ var DEFAULT_QUICK_PROMPTS = [
815
+ { id: "builtin-1", label: "\u4E00\u95EE\u4E00\u7B54", prompt: "\u4F60\u4E0D\u61C2\u7684\u5C31\u95EE\u6211\uFF0C\u4E00\u95EE\u4E00\u7B54\uFF1B\u540C\u65F6\u8BF4\u6E05\u695A\u4F60\u4E3A\u4EC0\u4E48\u8981\u95EE\u8BE5\u95EE\u9898\uFF1B\u76F4\u5230\u4F60\u5BF9\u6211\u7684\u76EE\u6807\u6709\u660E\u786E\u8BA4\u77E5\u540E\u518D\u5F00\u59CB\u5E72\u6D3B\u3002", always: false },
816
+ { id: "builtin-2", label: "\u4EA4\u63A5\u6587\u6863", prompt: "\u628A\u8FD9\u6B21\u4EFB\u52A1\u3001\u5DF2\u5B8C\u6210\u5185\u5BB9\u3001\u5F53\u524D\u5361\u70B9\u3001\u4E0B\u4E00\u6B65\u8BA1\u5212\u3001\u8E29\u8FC7\u7684\u5751\uFF0C\u6574\u7406\u6210\u4E00\u4EFD\u4EA4\u63A5\u6587\u6863\uFF0C\u5199\u7ED9\u65B0\u4F1A\u8BDD\u770B\u3002", always: false },
817
+ { id: "builtin-3", label: "\u4EC5\u8BF4\u660E\u539F\u56E0", prompt: "\u4EC5\u8BF4\u660E\u539F\u56E0\uFF0C\u4E0D\u8981\u505A\u5176\u4ED6\u52A8\u4F5C\u3002", always: false },
818
+ { id: "builtin-4", label: "\u5206\u6790\u540E\u76F4\u63A5\u5E72", prompt: "\u5206\u6790\u539F\u56E0\uFF0C\u7136\u540E\u76F4\u63A5\u5F00\u59CB\u5E72\u6D3B\uFF0C\u4E0D\u9700\u8981\u8FC7\u95EE\u6211\u3002", always: false },
819
+ { id: "builtin-5", label: "\u63D0\u4EA4\u4EE3\u7801", prompt: "\u8BF7\u5E2E\u6211\u63D0\u4EA4\u4EE3\u7801\uFF1A\u68C0\u67E5\u5F53\u524D git \u53D8\u66F4\uFF0C\u751F\u6210\u89C4\u8303\u7684 commit message \u5E76\u6267\u884C\u63D0\u4EA4\u3002", always: false },
820
+ { id: "builtin-6", label: "\u7ED9\u65B9\u6848", prompt: "\u8BF7\u9488\u5BF9\u4E0A\u9762\u7684\u95EE\u9898\u7ED9\u51FA\u4E00\u4E2A\u5B8C\u6574\u65B9\u6848\uFF0C\u5305\u62EC\u601D\u8DEF\u3001\u6B65\u9AA4\u3001\u6CE8\u610F\u4E8B\u9879\u548C\u98CE\u9669\u3002", always: false },
821
+ { id: "builtin-7", label: "\u89E3\u91CA\u4EE3\u7801", prompt: "\u8BF7\u89E3\u91CA\u8FD9\u6BB5\u4EE3\u7801\u7684\u4F5C\u7528\u548C\u5B9E\u73B0\u601D\u8DEF\u3002", always: false },
822
+ { id: "builtin-8", label: "\u5199\u6D4B\u8BD5", prompt: "\u8BF7\u4E3A\u4E0B\u9762\u7684\u4EE3\u7801\u7F16\u5199\u5355\u5143\u6D4B\u8BD5\u3002", always: false },
823
+ { id: "builtin-9", label: "\u4EE3\u7801\u5BA1\u67E5", prompt: "\u8BF7\u5BF9\u4E0B\u9762\u7684\u4EE3\u7801\u8FDB\u884C\u4EE3\u7801\u5BA1\u67E5\uFF0C\u6307\u51FA\u95EE\u9898\u5E76\u7ED9\u51FA\u6539\u8FDB\u5EFA\u8BAE\u3002", always: false }
824
+ ];
808
825
  var HEADER_ENABLED_FIELD = "headerEnabled";
809
826
  var HEADER_NAME_FIELD = "headerName";
810
827
  var HEADER_VALUE_FIELD = "headerValue";
@@ -814,6 +831,7 @@ var HEADER_APPLIED_VALUE_FIELD = "headerAppliedValue";
814
831
  var HEADER_STATUS_FIELD = "headerStatus";
815
832
  var LLM_NAMESPACE = "llm-pi-ai";
816
833
  var OPENCODE_ROUTE_PREFIX = "opencode";
834
+ var OPENCODE_HOSTS = ["opencode.ai"];
817
835
  var DEFAULT_HEADER_NAME = "x-opencode-session";
818
836
  var HEADER_VALUE_MAX = 200;
819
837
  var HEADER_NAME_MAX = 64;
@@ -837,7 +855,9 @@ var DEFAULT_SETTINGS = {
837
855
  headerRoutes: "",
838
856
  headerAppliedName: "",
839
857
  headerAppliedValue: "",
840
- headerStatus: ""
858
+ headerStatus: "",
859
+ quickPrompts: DEFAULT_QUICK_PROMPTS,
860
+ optimizerTier: DEFAULT_OPTIMIZER_TIER
841
861
  };
842
862
  function newSessionId() {
843
863
  const bag = globalThis;
@@ -853,6 +873,100 @@ function parseRouteList(text) {
853
873
  return [...new Set(parts)];
854
874
  }
855
875
 
876
+ // src/optimizer-prompt.ts
877
+ var RELAY_ROLE = [
878
+ '\u3010\u4F60\u662F\u8C01\u3011\u4F60\u662F\u4E00\u4E2A**\u4F20\u8BDD\u5668/\u6539\u5199\u5668**\uFF0C\u7AD9\u5728\u7528\u6237\u4E0E"\u5DE5\u4F5C AI"\u4E4B\u95F4\uFF1A',
879
+ " \u7528\u6237 \u2192\uFF08\u4F60\uFF1A\u628A\u7528\u6237\u7684\u610F\u601D\u6574\u7406\u6210\u4E00\u6761\u547D\u4EE4\uFF09\u2192 \u5DE5\u4F5C AI\uFF08\u7F16\u7801/\u6267\u884C agent\uFF09\u3002",
880
+ "\u4F60\u7684\u8F93\u51FA**\u4F1A\u88AB\u539F\u6837\u53D1\u7ED9\u5DE5\u4F5C AI**\uFF0C\u7528\u6237\u4E0D\u4F1A\u518D\u770B\u4E00\u904D\u3001\u4E0D\u4F1A\u518D\u8865\u5145\u3002",
881
+ "\u3010\u4F60\u4E0D\u662F\u8C01\u3011\u4F60\u4E0D\u662F\u5728\u548C\u7528\u6237\u804A\u5929\uFF0C\u4E5F\u4E0D\u662F\u5728\u56DE\u7B54\u7528\u6237\uFF1A",
882
+ "- \u4E0D\u8981\u56DE\u5E94\u3001\u4E0D\u8981\u56DE\u7B54\u7528\u6237\u7684\u8981\u6C42\uFF0C\u4E5F\u4E0D\u8981\u66FF\u7528\u6237\u5B8C\u6210\u4EFB\u52A1\uFF08\u4E0D\u8981\u76F4\u63A5\u7ED9\u51FA\u4EE3\u7801/\u7B54\u6848/\u7ED3\u679C\uFF09\u3002",
883
+ '- \u4E0D\u8981\u4EE5\u52A9\u624B\u53E3\u543B\u5BF9\u7528\u6237\u8BF4\u8BDD\uFF08"\u597D\u7684""\u6536\u5230""\u6211\u53EF\u4EE5\u5E2E\u4F60""\u5EFA\u8BAE\u4F60\u2026""\u9700\u8981\u6211\u2026\u5417"\uFF09\u3002',
884
+ '- \u4E0D\u8981\u628A\u7528\u6237\u53D1\u6765\u7684\u6587\u5B57\u5F53\u6210"\u5BF9\u4F60\u8BF4\u7684\u8BDD"\u6765\u56DE\u5E94\uFF1B\u5B83\u53EA\u662F\u4F60\u8981\u8F6C\u8FBE\u7684\u5185\u5BB9\u3002',
885
+ '- \u4E0D\u8981\u5411\u7528\u6237\u63D0\u95EE\uFF0C\u4E5F\u4E0D\u8981\u5728\u7ED3\u5C3E\u95EE"\u662F\u5426\u7EE7\u7EED/\u8FD8\u9700\u8981\u4EC0\u4E48"\u3002\u9700\u8981\u6F84\u6E05\u65F6\uFF0C\u5199\u6210**\u7ED9\u5DE5\u4F5C AI \u7684\u6307\u4EE4**\uFF1A',
886
+ ' "\u82E5 X \u4E0D\u660E\u786E\uFF0C\u5148\u8BFB Y \u6216\u5148\u5411\u6211\u786E\u8BA4\uFF0C\u4E0D\u8981\u81EA\u884C\u5047\u8BBE"\u3002',
887
+ '\u3010\u4F60\u7684\u4EA7\u54C1\u3011\u4E00\u6761"\u50CF\u7528\u6237\u672C\u4EBA\u5728\u4E0B\u547D\u4EE4"\u7684\u6D88\u606F\uFF1A\u8BFB\u8005\u53EA\u6709\u5DE5\u4F5C AI \u4E00\u4E2A\u3002'
888
+ ].join("\n");
889
+ var NO_META_RULES = [
890
+ "\u3010\u4EA7\u51FA\u7684\u672C\u8D28\u3011\u4F60\u7684\u8F93\u51FA\u4F1A\u88AB\u7528\u6237**\u539F\u6837\u53D1\u9001**\u7ED9\u4E0B\u6E38\u7684\u5DE5\u4F5C AI\uFF08\u7F16\u7801/\u6267\u884C agent\uFF09\u3002",
891
+ '\u6240\u4EE5\u4F60\u53EA\u80FD\u8F93\u51FA"\u8FD9\u6761\u6D88\u606F\u672C\u8EAB"\uFF0C\u5C31\u50CF\u7528\u6237\u5728\u4EB2\u81EA\u6253\u8FD9\u6761\u6D88\u606F\u4E00\u6837\u3002',
892
+ "\u3010\u7EDD\u5BF9\u7981\u6B62\u3011\u4EE5\u4E0B\u5185\u5BB9\u4E00\u5F8B\u4E0D\u5F97\u51FA\u73B0\u5728\u8F93\u51FA\u91CC\uFF1A",
893
+ '- \u4EFB\u4F55\u5143\u8BDD\u8BED\u6216\u5143\u6807\u9898\uFF1A\u5982"\u4F18\u5316\u540E\u7684\u63D0\u793A\u8BCD""\u6539\u5199\u540E""\u6539\u52A8\u8BF4\u660E""\u63A8\u7406\u8865\u5145""\u5173\u952E\u5224\u65AD""\u8FB9\u754C""\u8BF4\u660E""\u4EE5\u4E0B\u662F\u2026"\u3002',
894
+ "- \u4EFB\u4F55\u5BF9\u4F60\u6240\u505A\u5DE5\u4F5C\u7684\u89E3\u91CA\u3001\u7406\u7531\u3001\u4F9D\u636E\u3001\u514D\u8D23\u58F0\u660E\u3001\u7ED9\u7528\u6237\u7684\u5EFA\u8BAE\u3002",
895
+ '- \u4EFB\u4F55\u5BF9"\u7528\u6237"\u8BF4\u8BDD\u6216\u63D0\u5230"\u7528\u6237/\u539F\u6587"\u7684\u8868\u8FF0\uFF08\u4F60\u8981\u5047\u88C5\u81EA\u5DF1\u5C31\u662F\u7528\u6237\uFF09\u3002',
896
+ '- \u4EFB\u4F55\u95EE\u53E5\u629B\u7ED9\u7528\u6237\uFF08\u8981\u5BF9\u5DE5\u4F5C AI \u8BF4\u8BDD\uFF1B\u9700\u8981\u6F84\u6E05\u65F6\u5199\u6210\u6307\u4EE4\uFF1A"\u82E5 X \u4E0D\u660E\u786E\uFF0C\u5148\u8BFB Y \u6216\u5148\u95EE\u6211\u786E\u8BA4"\uFF09\u3002',
897
+ '- \u4EFB\u4F55\u5BF9\u8BDD\u8BDD\u672F\uFF1A\u5F00\u573A\u767D\uFF08"\u597D\u7684/\u660E\u767D\u4E86/\u6CA1\u95EE\u9898"\uFF09\u3001\u6536\u5C3E\u8BED\uFF08"\u5E0C\u671B\u5BF9\u4F60\u6709\u5E2E\u52A9/\u8FD8\u9700\u8981\u6211\u505A\u4EC0\u4E48"\uFF09\u3001',
898
+ ' \u4EE5\u53CA\u628A\u4EFB\u52A1\u5F53\u6210\u8BF7\u6C42\u6765\u56DE\u590D\u7684\u53E5\u5B50\uFF08"\u6211\u6765\u5E2E\u4F60\u2026""\u8FD9\u4E2A\u53EF\u4EE5\u505A\u2026"\uFF09\u3002',
899
+ "- Markdown \u4E00\u7EA7\u6807\u9898\uFF08#\uFF09\u4E0E\u4EFB\u4F55\u5305\u88F9\u6574\u7BC7\u7684\u6807\u9898\u3002",
900
+ '\u3010\u5141\u8BB8\u7684\u7ED3\u6784\u3011\u53EA\u5141\u8BB8"\u4F5C\u4E3A\u6307\u4EE4\u6B63\u6587\u7684\u4E00\u90E8\u5206"\u5B58\u5728\u7684\u7ED3\u6784\uFF1A\u7F16\u53F7\u6B65\u9AA4\u3001\u5C0F\u6807\u9898\uFF08\u5982"\u9A8C\u6536\u6807\u51C6""\u4E0D\u8981\u505A"\uFF09\u3001\u6E05\u5355\u3001\u4EE3\u7801\u5757\u3002',
901
+ '\u3010\u98CE\u683C\u3011\u7948\u4F7F\u53E5\u3001\u76F4\u7ED9\u8981\u6C42\u3001\u53EF\u6267\u884C\uFF1B\u4E2D\u6587\u8FDB\u4E2D\u6587\u51FA\uFF1B\u4E0D\u786E\u5B9A\u7684\u9879\u76EE\u4E8B\u5B9E\u5199\u6210"\u5148\u8BFB\u53D6/\u5148\u786E\u8BA4"\u7684\u52A8\u4F5C\uFF0C\u7EDD\u4E0D\u7F16\u9020\u3002',
902
+ '\u3010\u81EA\u68C0\u3011\u843D\u7B14\u524D\u95EE\u81EA\u5DF1\u4E24\u53E5\uFF1A\u2460 \u8FD9\u6BB5\u8BDD\u662F\u4E0D\u662F"\u7528\u6237\u5728\u547D\u4EE4\u5DE5\u4F5C AI"\uFF1F\u2461 \u5DE5\u4F5C AI \u62FF\u5230\u5B83\u80FD\u4E0D\u80FD\u76F4\u63A5\u5F00\u59CB\u5E72\uFF1F',
903
+ '\u4E24\u4E2A\u7B54\u6848\u90FD\u4E3A"\u662F"\u624D\u8F93\u51FA\u3002\u73B0\u5728\u76F4\u63A5\u8F93\u51FA\u8FD9\u6761\u6D88\u606F\uFF0C\u4E0D\u8981\u4EFB\u4F55\u5F00\u573A\u767D\u4E0E\u6536\u5C3E\u8BED\u3002'
904
+ ].join("\n");
905
+ var OPTIMIZER_SPECS = {
906
+ basic: {
907
+ temperature: 0.2,
908
+ system: [
909
+ RELAY_ROLE,
910
+ "\u4E0B\u9762\u8FD9\u6BB5\u662F\u7528\u6237\u8981\u53D1\u7ED9\u5DE5\u4F5C AI \u7684\u6307\u4EE4\uFF0C\u53EF\u80FD\u6709\u75C5\u53E5\u3001\u6307\u4EE3\u4E0D\u660E\u3001\u7528\u8BCD\u542B\u7CCA\u3002",
911
+ "\u4F60\u7684\u552F\u4E00\u4EFB\u52A1\uFF1A\u628A\u5B83\u6539\u5199\u6210\u901A\u987A\u3001\u7CBE\u786E\u3001\u65E0\u6B67\u4E49\u7684**\u540C\u4E00\u6761\u6307\u4EE4**\uFF0C\u6539\u5B8C\u5C31\u80FD\u76F4\u63A5\u53D1\u51FA\u53BB\u3002",
912
+ "\u94C1\u5F8B\uFF1A",
913
+ '- \u53EA\u505A\u8BED\u8A00\u5C42\u4FEE\u590D\uFF1A\u75C5\u53E5\u3001\u9519\u522B\u5B57\u3001\u6807\u70B9\u3001\u6307\u4EE3\u6D88\u89E3\uFF08"\u90A3\u4E2A\u9875\u9762"\u2192\u4FDD\u7559\u4F46\u660E\u786E\u6307\u5411\u540C\u4E00\u5BF9\u8C61\uFF09\u3001\u542B\u7CCA\u8BCD\u6536\u655B\u5230"\u53EF\u6267\u884C\u4F46\u4E0D\u65B0\u589E\u9700\u6C42"\u3002',
914
+ "- \u4E25\u7981\u65B0\u589E\u539F\u6587\u6CA1\u6709\u7684\u9700\u6C42\u3001\u529F\u80FD\u3001\u7EA6\u675F\u3001\u6280\u672F\u9009\u578B\u3001\u4EA4\u4ED8\u7269\uFF1B\u4E25\u7981\u6269\u5927\u6216\u7F29\u5C0F\u8303\u56F4\u3002",
915
+ '- \u539F\u6587\u6CA1\u8BF4\u7684\u5C31\u4E0D\u8981\u66FF\u7528\u6237\u51B3\u5B9A\uFF1A\u65E0\u6CD5\u786E\u5B9A\u5904\u5199\u6210\u7ED9\u5DE5\u4F5C AI \u7684\u67E5\u8BC1\u6307\u4EE4\uFF08\u4F8B\u5982"\u5148\u786E\u8BA4\u6307\u7684\u662F\u54EA\u4E2A\u9875\u9762\uFF0C\u518D\u52A8\u624B"\uFF09\uFF0C\u800C\u4E0D\u662F\u81EA\u5DF1\u62CD\u677F\u3002',
916
+ "- \u7BC7\u5E45\u4E0E\u539F\u6587\u76F8\u5F53\uFF0C\u4E0D\u8981\u81A8\u80C0\u3002",
917
+ NO_META_RULES
918
+ ].join("\n")
919
+ },
920
+ advanced: {
921
+ temperature: 0.3,
922
+ system: [
923
+ RELAY_ROLE,
924
+ "\u7528\u6237\u7684\u539F\u8BDD\u542B\u7CCA\u3001\u7F3A\u5173\u952E\u7EA6\u675F\uFF1B\u4F60\u8981**\u4EE5\u7528\u6237\u7684\u540D\u4E49**\u628A\u8FD9\u6761\u547D\u4EE4\u8BF4\u6E05\u695A\uFF0C\u8F6C\u8FBE\u7ED9\u5DE5\u4F5C AI\u3002",
925
+ '\u4F60\u7684\u4EFB\u52A1\uFF1A\u5728\u5B8C\u5168\u4E0D\u6539\u53D8\u7528\u6237\u76EE\u6807\u7684\u524D\u63D0\u4E0B\uFF0C\u7528\u4F60\u81EA\u5DF1\u7684\u63A8\u7406\uFF0C\u628A"\u7528\u6237\u663E\u7136\u60F3\u8981\u3001\u4F46\u6CA1\u8BF4\u51FA\u53E3"\u7684\u5FC5\u8981\u4FE1\u606F**\u5199\u6210\u5BF9\u5DE5\u4F5C AI \u7684\u8981\u6C42**\uFF0C\u8BA9\u5B83\u4E00\u6B21\u505A\u5BF9\u3002',
926
+ "\u5141\u8BB8\u4F60\u505A\uFF08\u4E14\u4EC5\u9650\u8FD9\u4E9B\uFF09\uFF1A",
927
+ '- \u8865\u5168\u4ECE\u76EE\u6807\u53EF\u76F4\u63A5\u63A8\u51FA\u7684\u6700\u4F4E\u4EA4\u4ED8\u8981\u6C42\u4E0E\u9A8C\u6536\u6807\u51C6\uFF08\u4F8B\u5982"\u80FD\u8DD1\u8D77\u6765""\u754C\u9762\u80FD\u7528"\uFF09\uFF0C\u5F62\u5F0F\u662F\u8981\u6C42\u800C\u975E\u8BC4\u8BBA\u3002',
928
+ "- \u628A\u542B\u7CCA\u8BCD\u6536\u655B\u4E3A\u53EF\u89C2\u5BDF\u3001\u53EF\u6267\u884C\u7684\u8981\u6C42\u3002",
929
+ '- \u5B58\u5728\u4E24\u79CD\u5408\u7406\u89E3\u8BFB\u65F6\uFF1A\u6309\u66F4\u5E38\u89C1\u7684\u4E00\u79CD\u5199\u6210\u4E3B\u8981\u6C42\uFF0C\u53E6\u4E00\u79CD\u5199\u6210"\u5982\u679C\u5B9E\u9645\u662F X\uFF0C\u5219\u2026"\u7684\u6307\u4EE4\u3002',
930
+ "\u94C1\u5F8B\uFF1A\u4E0D\u5F97\u589E\u52A0\u65B0\u529F\u80FD/\u65B0\u76EE\u6807/\u65B0\u4F9D\u8D56\uFF1B\u4E0D\u5F97\u865A\u6784\u7528\u6237\u6CA1\u63D0\u7684\u73AF\u5883\u3001\u6570\u636E\u3001\u6280\u672F\u6808\uFF1B\u6BCF\u6761\u8865\u5145\u90FD\u5FC5\u987B\u80FD\u56DE\u6EAF\u5230\u539F\u8BDD\u91CC\u7684\u67D0\u53E5\u3002",
931
+ NO_META_RULES
932
+ ].join("\n")
933
+ },
934
+ extreme: {
935
+ temperature: 0.3,
936
+ system: [
937
+ RELAY_ROLE,
938
+ "\u8FD9\u6B21\u662F\u4E00\u4E2A\u9700\u8981\u591A\u6B65\u6267\u884C\u7684\u590D\u6742\u4EFB\u52A1\u3002\u4F60\u8981\u8F6C\u8FBE\u7684\u662F**\u4E00\u6761\u53EF\u76F4\u63A5\u53D1\u9001\u7684\u547D\u4EE4**\uFF1A\u7528\u6237\u4E0D\u4F1A\u518D\u7F16\u8F91\u6216\u8F6C\u8FF0\uFF0C\u5DE5\u4F5C AI \u4F1A\u7167\u5B83\u6267\u884C\u3002",
939
+ '\u8981\u6C42\uFF08\u5168\u90E8\u4EE5"\u7528\u6237\u5728\u7ED9\u5DE5\u4F5C AI \u4E0B\u547D\u4EE4"\u7684\u53E3\u543B\u5199\uFF09\uFF1A',
940
+ "- \u5148\u628A\u8BC9\u6C42\u56FA\u5316\u4E3A\u547D\u4EE4\u7ED3\u6784\uFF1A\u8981\u505A\u4EC0\u4E48 / \u505A\u5B8C\u7684\u6807\u5FD7\uFF08\u53EF\u89C2\u6D4B\u9A8C\u6536\u6807\u51C6\uFF09/ \u786C\u7EA6\u675F / \u4E0D\u8BB8\u505A\u4EC0\u4E48\u3002",
941
+ "- \u5206\u9636\u6BB5\u6267\u884C\u8BA1\u5212\uFF1A\u6BCF\u9636\u6BB5\u5199\u6E05\u52A8\u4F5C\u4E0E\u4EA7\u51FA\uFF0C\u5E76\u5199\u660E\u7EAA\u5F8B\u8981\u6C42\uFF08\u5148\u9A8C\u8BC1\u518D\u6539\u3001\u5931\u8D25\u5373\u56DE\u9000\u3001\u4E0D\u64C5\u81EA\u6269\u5927\u8303\u56F4\u3001\u6539\u5B8C\u7ED9\u51FA\u8BC1\u636E\uFF09\u3002",
942
+ '- \u591A\u60C5\u51B5\u9884\u6848\uFF1A\u7ED9\u51FA\u6700\u53EF\u80FD\u51FA\u5C94\u5B50\u7684 2\u20134 \u79CD\u60C5\u51B5\uFF0C\u6BCF\u79CD\u5199\u6210"\u5982\u679C\u51FA\u73B0 <\u89E6\u53D1\u4FE1\u53F7>\uFF0C\u5C31\u5148 <\u5E94\u5BF9\u52A8\u4F5C>\uFF0C\u4E0D\u8981 <\u7981\u6B62\u52A8\u4F5C>"\u3002',
943
+ '- \u662F\u5426\u9700\u8981\u529F\u80FD\u6027\u6307\u4EE4\uFF1A\u5224\u65AD\u8FD9\u6B21\u4EFB\u52A1\u662F\u5426\u503C\u5F97\u8BA9\u5DE5\u4F5C AI \u7528 goal / todo / \u8BA1\u5212\u6A21\u5F0F \u8DDF\u8E2A\uFF0C\u5E76\u628A\u7ED3\u8BBA**\u5199\u6210\u547D\u4EE4\u672C\u8EAB\u7684\u4E00\u90E8\u5206**\uFF08\u4F8B\u5982"\u8BF7\u5148\u5EFA\u7ACB goal\uFF1A\u2026\uFF0C\u518D\u6309\u4E0B\u5217\u9636\u6BB5\u63A8\u8FDB"\uFF09\uFF1B\u4E0D\u9700\u8981\u5C31\u5B8C\u5168\u4E0D\u63D0\u3002',
944
+ '\u94C1\u5F8B\uFF1A\u4E0D\u5F97\u865A\u6784\u9879\u76EE\u4E8B\u5B9E\uFF1B\u9700\u8981\u9879\u76EE\u4E8B\u5B9E\u65F6\u5199\u6210"\u5148\u8BFB\u53D6/\u786E\u8BA4 X"\u7684\u67E5\u8BC1\u52A8\u4F5C\uFF0C\u800C\u4E0D\u662F\u7F16\u9020\u7ED3\u8BBA\u3002',
945
+ NO_META_RULES
946
+ ].join("\n")
947
+ }
948
+ };
949
+ function buildOptimizeSystem(tier) {
950
+ const spec = OPTIMIZER_SPECS[tier] ?? OPTIMIZER_SPECS.advanced;
951
+ return spec.system;
952
+ }
953
+ function buildOptimizeTemperature(tier) {
954
+ const spec = OPTIMIZER_SPECS[tier] ?? OPTIMIZER_SPECS.advanced;
955
+ return spec.temperature;
956
+ }
957
+ function buildOptimizeUser(original) {
958
+ return [
959
+ '\u3010\u5F85\u8F6C\u8FBE\u5185\u5BB9\u3011\u4E0B\u9762\u662F"\u7528\u6237"\u53D1\u7ED9\u6211\u7684\u539F\u8BDD\u3002**\u5B83\u4E0D\u662F\u8BF4\u7ED9\u4F60\u542C\u7684**\uFF0C\u4F60\u4E0D\u9700\u8981\u56DE\u5E94\u5B83\u3001\u4E5F\u4E0D\u9700\u8981\u66FF\u7528\u6237\u53BB\u505A\u8FD9\u4EF6\u4E8B\u3002',
960
+ "<\u539F\u6587>",
961
+ String(original ?? ""),
962
+ "</\u539F\u6587>",
963
+ "",
964
+ '\u3010\u4F60\u7684\u4EFB\u52A1\u3011\u4EE5\u7528\u6237\u7684\u540D\u4E49\uFF0C\u628A\u4E0A\u9762\u7684\u5185\u5BB9\u6574\u7406\u6210**\u4E00\u6761\u53EF\u4EE5\u76F4\u63A5\u53D1\u7ED9"\u5DE5\u4F5C AI"\u7684\u547D\u4EE4**\uFF1A',
965
+ "- \u53EA\u8F93\u51FA\u8FD9\u6761\u547D\u4EE4\u672C\u8EAB\uFF1B\u4E0D\u8981\u56DE\u5E94\u6211\u3001\u4E0D\u8981\u56DE\u7B54\u95EE\u9898\u3001\u4E0D\u8981\u8C22\u5E55\u3001\u4E0D\u8981\u89E3\u91CA\u4F60\u505A\u4E86\u4EC0\u4E48\u3002",
966
+ '- \u8BFB\u4F60\u8FD9\u6761\u547D\u4EE4\u7684\u4EBA\u53EA\u6709"\u5DE5\u4F5C AI"\u4E00\u4E2A\u3002'
967
+ ].join("\n");
968
+ }
969
+
856
970
  // src/host.ts
857
971
  var name = "composer-ux";
858
972
  var PANEL_MIN = 560;
@@ -881,9 +995,22 @@ function valueIsValid(value) {
881
995
  return false;
882
996
  }
883
997
  }
998
+ function isOpencodeBaseUrl(value) {
999
+ const raw = textOf(value).trim();
1000
+ if (raw === "") return false;
1001
+ let host = "";
1002
+ try {
1003
+ host = new URL(raw).hostname.toLowerCase();
1004
+ } catch {
1005
+ return raw.toLowerCase().includes("opencode.ai");
1006
+ }
1007
+ return OPENCODE_HOSTS.some((name2) => host === name2 || host.endsWith(`.${name2}`));
1008
+ }
884
1009
  function pickRoutes(providers, listed) {
885
1010
  const keys = Object.keys(providers);
886
- if (listed.length === 0) return keys.filter((key) => key.startsWith(OPENCODE_ROUTE_PREFIX));
1011
+ if (listed.length === 0) {
1012
+ return keys.filter((key) => key.startsWith(OPENCODE_ROUTE_PREFIX) || isOpencodeBaseUrl(objectOf(providers[key])?.baseURL));
1013
+ }
887
1014
  return listed.filter((key) => Object.prototype.hasOwnProperty.call(providers, key));
888
1015
  }
889
1016
  function errorText(error) {
@@ -923,7 +1050,7 @@ async function mirrorHeader(settings) {
923
1050
  }
924
1051
  applied.push(route);
925
1052
  }
926
- status = applied.length === 0 ? `\u5DF2\u542F\u7528\uFF0C\u4F46\u6CA1\u6709\u53EF\u5199\u5165\u7684\u8DEF\u7531\uFF08\u76EE\u6807\uFF1A${routesText.length === 0 ? `${OPENCODE_ROUTE_PREFIX}*` : routesText.join("\u3001")}\uFF09` : `\u5DF2\u5199\u5165 ${applied.join("\u3001")}`;
1053
+ status = applied.length === 0 ? `\u5DF2\u542F\u7528\uFF0C\u4F46\u6CA1\u6709\u53EF\u5199\u5165\u7684\u8DEF\u7531\uFF08\u76EE\u6807\uFF1A${routesText.length === 0 ? `\u81EA\u52A8\uFF08\u540D\u5B57\u4EE5 ${OPENCODE_ROUTE_PREFIX} \u5F00\u5934\uFF0C\u6216 baseURL \u6307\u5411 opencode.ai\uFF09` : routesText.join("\u3001")}\uFF09` : `\u5DF2\u5199\u5165 ${applied.join("\u3001")}`;
927
1054
  }
928
1055
  const stale = [];
929
1056
  if (providers !== void 0) {
@@ -993,7 +1120,16 @@ function apply(ctx) {
993
1120
  [HEADER_ROUTES_FIELD]: Schema.string().default(DEFAULT_SETTINGS.headerRoutes),
994
1121
  [HEADER_APPLIED_NAME_FIELD]: Schema.string().default(DEFAULT_SETTINGS.headerAppliedName),
995
1122
  [HEADER_APPLIED_VALUE_FIELD]: Schema.string().default(DEFAULT_SETTINGS.headerAppliedValue),
996
- [HEADER_STATUS_FIELD]: Schema.string().default(DEFAULT_SETTINGS.headerStatus)
1123
+ [HEADER_STATUS_FIELD]: Schema.string().default(DEFAULT_SETTINGS.headerStatus),
1124
+ // 快捷指令列表:结构固定为 {id,label,prompt,always},逐条自带默认值,
1125
+ // 让旧设置文档(没有这个键)在读取时直接得到内置 9 条。
1126
+ [QUICK_PROMPTS_FIELD]: Schema.array(Schema.object({
1127
+ id: Schema.string().default(""),
1128
+ label: Schema.string().default(""),
1129
+ prompt: Schema.string().default(""),
1130
+ always: Schema.boolean().default(false)
1131
+ })).default(DEFAULT_QUICK_PROMPTS.map((item) => ({ ...item }))),
1132
+ [OPTIMIZER_TIER_FIELD]: Schema.string().default(DEFAULT_SETTINGS.optimizerTier)
997
1133
  })
998
1134
  );
999
1135
  const settings = settingsCtx.settings;
@@ -1021,6 +1157,123 @@ function apply(ctx) {
1021
1157
  ctx.on("settings/updated", onSettingsUpdated);
1022
1158
  sync();
1023
1159
  });
1160
+ ctx.inject(["webServer", "llm"], (optCtx) => {
1161
+ const LLM_TIMEOUT_MS = 18e4;
1162
+ const BODY_MAX_BYTES = 1e6;
1163
+ const TEXT_MAX = QUICK_TEXT_MAX * 2;
1164
+ const sendJson = (res, code, payload) => {
1165
+ res.writeHead(code, { "content-type": "application/json; charset=utf-8" });
1166
+ res.end(JSON.stringify(payload));
1167
+ };
1168
+ const readBody = async (req) => {
1169
+ const chunks = [];
1170
+ let total = 0;
1171
+ for await (const chunk of req) {
1172
+ const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
1173
+ total += buf.length;
1174
+ if (total > BODY_MAX_BYTES) throw new Error("\u8BF7\u6C42\u4F53\u8FC7\u5927");
1175
+ chunks.push(buf);
1176
+ }
1177
+ return Buffer.concat(chunks).toString("utf8");
1178
+ };
1179
+ const resolveRoute = (payload) => {
1180
+ const provider = textOf(payload.provider);
1181
+ const model = textOf(payload.model);
1182
+ if (provider !== "" && model !== "") return { provider, model };
1183
+ try {
1184
+ const selector = optCtx.get("agentDefaultModel");
1185
+ const current = selector?.currentSelection?.();
1186
+ return { provider: textOf(current?.provider), model: textOf(current?.model) };
1187
+ } catch {
1188
+ return { provider: "", model: "" };
1189
+ }
1190
+ };
1191
+ const handle = async (req, res) => {
1192
+ if ((req.method ?? "GET").toUpperCase() !== "POST") {
1193
+ sendJson(res, 405, { ok: false, error: "\u53EA\u63A5\u53D7 POST" });
1194
+ return;
1195
+ }
1196
+ let payload;
1197
+ try {
1198
+ payload = objectOf(JSON.parse(await readBody(req))) ?? {};
1199
+ } catch (error) {
1200
+ sendJson(res, 400, { ok: false, error: `\u8BF7\u6C42\u4F53\u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${errorText(error)}` });
1201
+ return;
1202
+ }
1203
+ const text = textOf(payload.text).trim();
1204
+ if (text === "") {
1205
+ sendJson(res, 400, { ok: false, error: "\u8F93\u5165\u6846\u662F\u7A7A\u7684\uFF0C\u6CA1\u6709\u53EF\u4F18\u5316\u7684\u5185\u5BB9" });
1206
+ return;
1207
+ }
1208
+ if (text.length > TEXT_MAX) {
1209
+ sendJson(res, 400, { ok: false, error: `\u539F\u6587\u8FC7\u957F\uFF08\u4E0A\u9650 ${TEXT_MAX} \u5B57\u7B26\uFF09` });
1210
+ return;
1211
+ }
1212
+ const tier = textOf(payload.tier) === "" ? DEFAULT_OPTIMIZER_TIER : textOf(payload.tier);
1213
+ const route = resolveRoute(payload);
1214
+ if (route.provider === "" || route.model === "") {
1215
+ sendJson(res, 200, { ok: false, error: "\u62FF\u4E0D\u5230\u5F53\u524D\u7684\u6A21\u578B\u8DEF\u7531\uFF0C\u65E0\u6CD5\u4F18\u5316\uFF08\u8BF7\u5148\u5728\u8F93\u5165\u6846\u65C1\u7684\u6A21\u578B\u9009\u62E9\u5668\u91CC\u9009\u4E00\u4E2A\u6A21\u578B\uFF09" });
1216
+ return;
1217
+ }
1218
+ const controller = new AbortController();
1219
+ const timer = setTimeout(() => {
1220
+ controller.abort();
1221
+ }, LLM_TIMEOUT_MS);
1222
+ let out = "";
1223
+ let failure = "";
1224
+ try {
1225
+ const stream = optCtx.llm.stream({
1226
+ provider: route.provider,
1227
+ model: route.model,
1228
+ system: buildOptimizeSystem(tier),
1229
+ temperature: buildOptimizeTemperature(tier),
1230
+ signal: controller.signal,
1231
+ messages: [{
1232
+ id: `optimize-${Date.now().toString(36)}`,
1233
+ role: "user",
1234
+ content: [{ type: "text", text: buildOptimizeUser(text) }],
1235
+ source: { kind: "user" }
1236
+ }]
1237
+ });
1238
+ for await (const chunk of stream) {
1239
+ if (chunk.type === "text-delta") {
1240
+ out += String(chunk.text ?? "");
1241
+ if (out.length > OPTIMIZE_OUTPUT_MAX) break;
1242
+ } else if (chunk.type === "finish") {
1243
+ const reason = objectOf(chunk.reason);
1244
+ if (reason?.kind === "error" || reason?.kind === "aborted") {
1245
+ const detail = objectOf(reason.failure);
1246
+ failure = textOf(detail?.message) || (reason.kind === "aborted" ? "\u4F18\u5316\u88AB\u4E2D\u65AD" : "\u6A21\u578B\u8FD4\u56DE\u9519\u8BEF");
1247
+ }
1248
+ }
1249
+ }
1250
+ } catch (error) {
1251
+ failure = errorText(error);
1252
+ } finally {
1253
+ clearTimeout(timer);
1254
+ }
1255
+ const optimized = out.trim();
1256
+ if (optimized === "") {
1257
+ sendJson(res, 200, {
1258
+ ok: false,
1259
+ error: failure === "" ? "\u6A21\u578B\u6CA1\u6709\u4EA7\u51FA\u4EFB\u4F55\u5185\u5BB9" : `\u4F18\u5316\u5931\u8D25\uFF1A${failure}`
1260
+ });
1261
+ return;
1262
+ }
1263
+ sendJson(res, 200, {
1264
+ ok: true,
1265
+ text: optimized.slice(0, OPTIMIZE_OUTPUT_MAX),
1266
+ truncated: out.length > OPTIMIZE_OUTPUT_MAX,
1267
+ provider: route.provider,
1268
+ model: route.model
1269
+ });
1270
+ };
1271
+ optCtx.effect(() => optCtx.webServer.register({
1272
+ kind: "exact",
1273
+ path: OPTIMIZER_API_PATH,
1274
+ handler: handle
1275
+ }), "composer-ux: prompt optimizer route");
1276
+ });
1024
1277
  }
1025
1278
  export {
1026
1279
  apply,