opencodekit 0.21.0 → 0.21.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/index.js CHANGED
@@ -20,7 +20,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
20
 
21
21
  //#endregion
22
22
  //#region package.json
23
- var version = "0.21.0";
23
+ var version = "0.21.1";
24
24
 
25
25
  //#endregion
26
26
  //#region src/utils/license.ts
@@ -102,12 +102,16 @@ If a newer user instruction conflicts with an earlier one, follow the newer inst
102
102
  - Don't stop early when another tool call would improve the result
103
103
  - Keep calling tools until the task is complete **and** verification passes
104
104
  - If a tool returns empty or partial results, retry with a different strategy before giving up (see Empty Result Recovery)
105
+ - For present-day facts, external APIs, provider behavior, and prior-session context claims, check tools or memory first instead of answering from stale recall
106
+ - If the user provides a specific URL, file path, error log, screenshot, or artifact, inspect that exact evidence before abstracting from it
105
107
 
106
108
  ### Dependency Checks
107
109
 
108
110
  - Before taking an action, check whether prerequisite discovery, lookup, or memory retrieval steps are required
109
111
  - Don't skip prerequisite steps because the final action seems obvious
110
112
  - If a task depends on the output of a prior step, resolve that dependency first
113
+ - Don't claim a capability, tool, or context is unavailable until you've checked the relevant tool, memory, or file evidence
114
+ - If the user writes as if prior context exists ("continue", "that bug", "my project", "what we decided"), search memory or prior sessions before asking them to restate it
111
115
 
112
116
  ### Empty Result Recovery
113
117
 
@@ -115,7 +119,8 @@ If a lookup, search, or tool call returns empty, partial, or suspiciously narrow
115
119
 
116
120
  1. Don't immediately conclude that no results exist
117
121
  2. Try at least 1-2 fallback strategies (alternative query terms, broader filters, different source/tool)
118
- 3. Only then report "no results found" along with what strategies were attempted
122
+ 3. If results look off-target, refine and retry before concluding the task is blocked
123
+ 4. Only then report "no results found" along with what strategies were attempted
119
124
 
120
125
  ### Completeness Tracking
121
126
 
@@ -123,6 +128,8 @@ If a lookup, search, or tool call returns empty, partial, or suspiciously narrow
123
128
  - Maintain an internal checklist of deliverables (use TodoWrite for multi-step work)
124
129
  - For lists, batches, or paginated results: determine expected scope, track processed items, confirm full coverage
125
130
  - If any item is blocked by missing data, mark it `[blocked]` and state exactly what is missing
131
+ - For multi-part requests, address every part and synthesize the result instead of making the user inspect raw logs or partial outputs
132
+ - Once you start a task, see it through to a natural stopping point unless blocked by a real dependency or reversibility constraint
126
133
 
127
134
  ### Plan Quality Gate
128
135
 
@@ -311,6 +318,9 @@ Ask only when:
311
318
  - Ambiguity materially changes outcome
312
319
  - Action is destructive/irreversible
313
320
 
321
+ Before asking, prefer a reversible action, tool lookup, or narrow assumption when that can resolve the ambiguity safely.
322
+ If a question is still needed, ask at most one targeted question when possible.
323
+
314
324
  Keep questions targeted and minimal.
315
325
 
316
326
  ---
@@ -461,12 +471,14 @@ When tilth MCP is available with `--edit` mode, use hash-anchored edits as a **f
461
471
  ## Output Style
462
472
 
463
473
  - Be concise, direct, and collaborative
474
+ - Keep tone constructive and matter-of-fact; avoid condescension
464
475
  - Prefer deterministic outputs over prose-heavy explanations
465
476
  - Cite concrete file paths and line numbers for non-trivial claims
466
477
  - **No cheerleading** — avoid motivational language, artificial reassurance, or filler ("Got it!", "Great question!", "Sure thing!")
467
478
  - **Never narrate abstractly** — explain what you're doing and why, not that you're "going to look into this"
468
479
  - **Code reviews: bugs first** — identify bugs, risks, and regressions before style or readability comments
469
480
  - **Flat lists preferred** — use sections for hierarchy instead of deeply nested bullets
481
+ - Own mistakes directly and fix them without excessive apology or self-abasement
470
482
 
471
483
  _Complexity is the enemy. Minimize moving parts._
472
484
 
Binary file
@@ -12,11 +12,11 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@google/stitch-sdk": "^0.0.3",
15
- "@opencode-ai/plugin": "1.4.6"
15
+ "@opencode-ai/plugin": "1.4.9"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/node": "^25.3.0",
19
19
  "bun-types": "^1.3.9",
20
20
  "typescript": "^5.9.3"
21
21
  }
22
- }
22
+ }
@@ -864,6 +864,65 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk, directory }) => {
864
864
  ),
865
865
  );
866
866
  }
867
+
868
+ // Sanitize tool definitions: strip non-standard fields like
869
+ // "custom" (wrapping eager_input_streaming) injected by
870
+ // runtime layers. These cause "Extra inputs are not permitted"
871
+ // on the Copilot API.
872
+ const toolSource = modifiedBody || body;
873
+ if (Array.isArray(toolSource?.tools)) {
874
+ let toolsChanged = false;
875
+ const sanitizedTools = toolSource.tools.map(
876
+ (tool: any) => {
877
+ if (!tool || typeof tool !== "object") return tool;
878
+
879
+ let result = tool;
880
+
881
+ // Strip top-level non-standard fields from tool object
882
+ if (
883
+ "custom" in result ||
884
+ "eager_input_streaming" in result
885
+ ) {
886
+ toolsChanged = true;
887
+ const {
888
+ custom: _custom,
889
+ eager_input_streaming: _eis,
890
+ ...clean
891
+ } = result;
892
+ result = clean;
893
+ }
894
+
895
+ // Also check nested function object (Chat Completions format)
896
+ if (
897
+ result.function &&
898
+ typeof result.function === "object" &&
899
+ ("custom" in result.function ||
900
+ "eager_input_streaming" in result.function)
901
+ ) {
902
+ toolsChanged = true;
903
+ const {
904
+ custom: _c,
905
+ eager_input_streaming: _e,
906
+ ...cleanFn
907
+ } = result.function;
908
+ result = { ...result, function: cleanFn };
909
+ }
910
+
911
+ return result;
912
+ },
913
+ );
914
+
915
+ if (toolsChanged) {
916
+ modifiedBody = {
917
+ ...(modifiedBody || body),
918
+ tools: sanitizedTools,
919
+ };
920
+ log(
921
+ "debug",
922
+ "Stripped non-standard fields (custom/eager_input_streaming) from tool definitions",
923
+ );
924
+ }
925
+ }
867
926
  } catch {}
868
927
 
869
928
  const headers: Record<string, string> = {
@@ -8,116 +8,116 @@
8
8
  import type { Plugin } from "@opencode-ai/plugin";
9
9
 
10
10
  const TASK_KEYWORDS: Record<string, string[]> = {
11
- coding: [
12
- "code",
13
- "bug",
14
- "repo",
15
- "refactor",
16
- "test",
17
- "implement",
18
- "fix",
19
- "function",
20
- "api",
21
- "add",
22
- "update",
23
- "remove",
24
- ],
25
- research: [
26
- "research",
27
- "compare",
28
- "find",
29
- "latest",
30
- "sources",
31
- "analyze",
32
- "look up",
33
- ],
34
- writing: [
35
- "write",
36
- "rewrite",
37
- "draft",
38
- "email",
39
- "memo",
40
- "blog",
41
- "copy",
42
- "tone",
43
- ],
44
- review: ["review", "audit", "critique", "inspect", "evaluate", "assess"],
45
- planning: ["plan", "roadmap", "strategy", "framework", "outline"],
46
- analysis: ["analyze", "explain", "break down", "diagnose", "root cause"],
11
+ coding: [
12
+ "code",
13
+ "bug",
14
+ "repo",
15
+ "refactor",
16
+ "test",
17
+ "implement",
18
+ "fix",
19
+ "function",
20
+ "api",
21
+ "add",
22
+ "update",
23
+ "remove",
24
+ ],
25
+ research: [
26
+ "research",
27
+ "compare",
28
+ "find",
29
+ "latest",
30
+ "sources",
31
+ "analyze",
32
+ "look up",
33
+ ],
34
+ writing: [
35
+ "write",
36
+ "rewrite",
37
+ "draft",
38
+ "email",
39
+ "memo",
40
+ "blog",
41
+ "copy",
42
+ "tone",
43
+ ],
44
+ review: ["review", "audit", "critique", "inspect", "evaluate", "assess"],
45
+ planning: ["plan", "roadmap", "strategy", "framework", "outline"],
46
+ analysis: ["analyze", "explain", "break down", "diagnose", "root cause"],
47
47
  };
48
48
 
49
49
  function detectTask(prompt: string): string {
50
- const lowered = prompt.toLowerCase();
51
- const scores: Record<string, number> = {};
52
- for (const [task, keywords] of Object.entries(TASK_KEYWORDS)) {
53
- scores[task] = keywords.filter((k) => lowered.includes(k)).length;
54
- }
55
- const best = Object.entries(scores).sort((a, b) => b[1] - a[1]);
56
- return best[0]?.[1] ? best[0][0] : "analysis";
50
+ const lowered = prompt.toLowerCase();
51
+ const scores: Record<string, number> = {};
52
+ for (const [task, keywords] of Object.entries(TASK_KEYWORDS)) {
53
+ scores[task] = keywords.filter((k) => lowered.includes(k)).length;
54
+ }
55
+ const best = Object.entries(scores).sort((a, b) => b[1] - a[1]);
56
+ return best[0]?.[1] ? best[0][0] : "analysis";
57
57
  }
58
58
 
59
59
  function inferIntensity(prompt: string, task: string): string {
60
- const lowered = prompt.toLowerCase();
61
- if (
62
- ["careful", "deep", "thorough", "critical", "production"].some((t) =>
63
- lowered.includes(t),
64
- )
65
- ) {
66
- return "Deep";
67
- }
68
- if (task === "coding" || task === "research" || task === "review") {
69
- return "Standard";
70
- }
71
- return "Light";
60
+ const lowered = prompt.toLowerCase();
61
+ if (
62
+ ["careful", "deep", "thorough", "critical", "production"].some((t) =>
63
+ lowered.includes(t),
64
+ )
65
+ ) {
66
+ return "Deep";
67
+ }
68
+ if (task === "coding" || task === "research" || task === "review") {
69
+ return "Standard";
70
+ }
71
+ return "Light";
72
72
  }
73
73
 
74
74
  function buildToolRules(task: string): string {
75
- const rules: Record<string, string> = {
76
- coding:
77
- "Inspect the relevant files and dependencies first. Validate the final change with the narrowest useful checks before broadening scope.",
78
- research:
79
- "Retrieve evidence from reliable sources before concluding. Do not guess facts that can be checked.",
80
- review:
81
- "Read enough surrounding context to understand intent before critiquing. Distinguish confirmed issues from plausible risks.",
82
- };
83
- return (
84
- rules[task] ||
85
- "Use tools or extra context only when they materially improve correctness or completeness."
86
- );
75
+ const rules: Record<string, string> = {
76
+ coding:
77
+ "Inspect the relevant files and dependencies first. Validate the final change with the narrowest useful checks before broadening scope.",
78
+ research:
79
+ "Retrieve evidence from reliable sources before concluding. Do not guess facts that can be checked.",
80
+ review:
81
+ "Read enough surrounding context to understand intent before critiquing. Distinguish confirmed issues from plausible risks.",
82
+ };
83
+ return (
84
+ rules[task] ||
85
+ "Use tools or extra context only when they materially improve correctness or completeness."
86
+ );
87
87
  }
88
88
 
89
89
  function buildOutputContract(task: string): string {
90
- const contracts: Record<string, string> = {
91
- coding:
92
- "Return the result in a practical execution format: concise summary, concrete changes or code, validation notes, and any remaining risks.",
93
- research:
94
- "Return a structured synthesis with key findings, supporting evidence, uncertainty where relevant, and a concise bottom line.",
95
- writing:
96
- "Return polished final copy in the requested tone and format. If useful, include a short rationale for major editorial choices.",
97
- review:
98
- "Return findings grouped by severity or importance, explain why each matters, and suggest the smallest credible next step.",
99
- };
100
- return (
101
- contracts[task] ||
102
- "Return a clear, well-structured response matched to the task, with no unnecessary verbosity."
103
- );
90
+ const contracts: Record<string, string> = {
91
+ coding:
92
+ "Return the result in a practical execution format: concise summary, concrete changes or code, validation notes, and any remaining risks.",
93
+ research:
94
+ "Return a structured synthesis with key findings, supporting evidence, uncertainty where relevant, and a concise bottom line.",
95
+ writing:
96
+ "Return polished final copy in the requested tone and format. If useful, include a short rationale for major editorial choices.",
97
+ review:
98
+ "Return findings grouped by severity or importance, explain why each matters, and suggest the smallest credible next step.",
99
+ };
100
+ return (
101
+ contracts[task] ||
102
+ "Return a clear, well-structured response matched to the task, with no unnecessary verbosity."
103
+ );
104
104
  }
105
105
 
106
106
  function upgradePrompt(userPrompt: string): string {
107
- const normalized = userPrompt.trim().replace(/\s+/g, " ");
108
- const task = detectTask(normalized);
109
- const intensity = inferIntensity(normalized, task);
110
- const toolRules = buildToolRules(task);
111
- const outputContract = buildOutputContract(task);
112
-
113
- if (normalized.includes("Objective:") && normalized.includes("Context:")) {
114
- return userPrompt;
115
- }
116
- if (normalized.length < 15 || normalized.split(" ").length < 3) {
117
- return userPrompt;
118
- }
119
-
120
- return `Objective:
107
+ const normalized = userPrompt.trim().replace(/\s+/g, " ");
108
+ const task = detectTask(normalized);
109
+ const intensity = inferIntensity(normalized, task);
110
+ const toolRules = buildToolRules(task);
111
+ const outputContract = buildOutputContract(task);
112
+
113
+ if (normalized.includes("Objective:") && normalized.includes("Context:")) {
114
+ return userPrompt;
115
+ }
116
+ if (normalized.length < 15 || normalized.split(" ").length < 3) {
117
+ return userPrompt;
118
+ }
119
+
120
+ return `Objective:
121
121
  - Complete this task: ${normalized}
122
122
  - Optimize for a correct, useful result rather than a merely plausible one.
123
123
 
@@ -147,47 +147,45 @@ Done Criteria:
147
147
  }
148
148
 
149
149
  export const PromptLeverage: Plugin = async ({ client }) => {
150
- console.log("PromptLeverage: Initializing...");
151
-
152
- const showToast = async (message: string) => {
153
- try {
154
- await client.tui.showToast({
155
- body: {
156
- title: "PromptLeverage",
157
- message,
158
- variant: "info",
159
- duration: 3000,
160
- },
161
- });
162
- } catch {
163
- /* Toast API unavailable */
164
- }
165
- };
166
-
167
- return {
168
- "experimental.chat.messages.transform": async (input: any, output: any) => {
169
- try {
170
- const msgs = output.messages || input.messages || [];
171
-
172
- // Find the last message with parts (user message)
173
- for (let i = msgs.length - 1; i >= 0; i--) {
174
- const msg = msgs[i];
175
- if (msg?.parts) {
176
- for (const part of msg.parts) {
177
- if (part.type === "text" && part.text) {
178
- const upgraded = upgradePrompt(part.text);
179
- if (upgraded !== part.text) {
180
- part.text = upgraded;
181
- showToast("Upgraded prompt!");
182
- }
183
- }
184
- }
185
- break; // Only upgrade the most recent message
186
- }
187
- }
188
- } catch (e: any) {
189
- showToast(`Error: ${e.message}`);
190
- }
191
- },
192
- };
150
+ const showToast = async (message: string) => {
151
+ try {
152
+ await client.tui.showToast({
153
+ body: {
154
+ title: "PromptLeverage",
155
+ message,
156
+ variant: "info",
157
+ duration: 3000,
158
+ },
159
+ });
160
+ } catch {
161
+ /* Toast API unavailable */
162
+ }
163
+ };
164
+
165
+ return {
166
+ "experimental.chat.messages.transform": async (input: any, output: any) => {
167
+ try {
168
+ const msgs = output.messages || input.messages || [];
169
+
170
+ // Find the last message with parts (user message)
171
+ for (let i = msgs.length - 1; i >= 0; i--) {
172
+ const msg = msgs[i];
173
+ if (msg?.parts) {
174
+ for (const part of msg.parts) {
175
+ if (part.type === "text" && part.text) {
176
+ const upgraded = upgradePrompt(part.text);
177
+ if (upgraded !== part.text) {
178
+ part.text = upgraded;
179
+ showToast("Upgraded prompt!");
180
+ }
181
+ }
182
+ }
183
+ break; // Only upgrade the most recent message
184
+ }
185
+ }
186
+ } catch (e: any) {
187
+ showToast(`Error: ${e.message}`);
188
+ }
189
+ },
190
+ };
193
191
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencodekit",
3
- "version": "0.21.0",
3
+ "version": "0.21.1",
4
4
  "description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
5
5
  "keywords": [
6
6
  "agents",
@@ -1,228 +0,0 @@
1
- /**
2
- * Prompt Leverage Plugin
3
- *
4
- * Automatically upgrades every user prompt with the seven-block framework before the AI processes it.
5
- * This enforces prompt-leverage on ALL user input without relying on the AI to remember the rule.
6
- *
7
- * Hooks used:
8
- * - chat.message: Upgrades user message as it arrives
9
- */
10
-
11
- import type { Plugin } from "@opencode-ai/plugin";
12
-
13
- interface PromptFramework {
14
- objective: string;
15
- context: string;
16
- workStyle: string;
17
- toolRules: string;
18
- outputContract: string;
19
- verification: string;
20
- doneCriteria: string;
21
- }
22
-
23
- const TASK_KEYWORDS: Record<string, string[]> = {
24
- coding: [
25
- "code",
26
- "bug",
27
- "repo",
28
- "refactor",
29
- "test",
30
- "implement",
31
- "fix",
32
- "function",
33
- "api",
34
- "add",
35
- "update",
36
- "remove",
37
- ],
38
- research: [
39
- "research",
40
- "compare",
41
- "find",
42
- "latest",
43
- "sources",
44
- "analyze",
45
- "look up",
46
- ],
47
- writing: [
48
- "write",
49
- "rewrite",
50
- "draft",
51
- "email",
52
- "memo",
53
- "blog",
54
- "copy",
55
- "tone",
56
- ],
57
- review: ["review", "audit", "critique", "inspect", "evaluate", "assess"],
58
- planning: ["plan", "roadmap", "strategy", "framework", "outline"],
59
- analysis: ["analyze", "explain", "break down", "diagnose", "root cause"],
60
- };
61
-
62
- function detectTask(prompt: string): string {
63
- const lowered = prompt.toLowerCase();
64
- const scores: Record<string, number> = {};
65
-
66
- for (const [task, keywords] of Object.entries(TASK_KEYWORDS)) {
67
- scores[task] = keywords.filter((k) => lowered.includes(k)).length;
68
- }
69
-
70
- const best = Object.entries(scores).sort((a, b) => b[1] - a[1]);
71
- return best[0]?.[1] ? best[0][0] : "analysis";
72
- }
73
-
74
- function inferIntensity(prompt: string, task: string): string {
75
- const lowered = prompt.toLowerCase();
76
- if (
77
- lowered.includes("careful") ||
78
- lowered.includes("deep") ||
79
- lowered.includes("thorough") ||
80
- lowered.includes("critical") ||
81
- lowered.includes("production")
82
- ) {
83
- return "Deep";
84
- }
85
- if (task === "coding" || task === "research" || task === "review") {
86
- return "Standard";
87
- }
88
- return "Light";
89
- }
90
-
91
- function buildToolRules(task: string): string {
92
- const rules: Record<string, string> = {
93
- coding:
94
- "Inspect the relevant files and dependencies first. Validate the final change with the narrowest useful checks before broadening scope.",
95
- research:
96
- "Retrieve evidence from reliable sources before concluding. Do not guess facts that can be checked.",
97
- review:
98
- "Read enough surrounding context to understand intent before critiquing. Distinguish confirmed issues from plausible risks.",
99
- };
100
- return (
101
- rules[task] ||
102
- "Use tools or extra context only when they materially improve correctness or completeness."
103
- );
104
- }
105
-
106
- function buildOutputContract(task: string): string {
107
- const contracts: Record<string, string> = {
108
- coding:
109
- "Return the result in a practical execution format: concise summary, concrete changes or code, validation notes, and any remaining risks.",
110
- research:
111
- "Return a structured synthesis with key findings, supporting evidence, uncertainty where relevant, and a concise bottom line.",
112
- writing:
113
- "Return polished final copy in the requested tone and format. If useful, include a short rationale for major editorial choices.",
114
- review:
115
- "Return findings grouped by severity or importance, explain why each matters, and suggest the smallest credible next step.",
116
- };
117
- return (
118
- contracts[task] ||
119
- "Return a clear, well-structured response matched to the task, with no unnecessary verbosity."
120
- );
121
- }
122
-
123
- function upgradePrompt(userPrompt: string): string {
124
- const normalized = userPrompt.trim().replace(/\s+/g, " ");
125
- const task = detectTask(normalized);
126
- const intensity = inferIntensity(normalized, task);
127
- const toolRules = buildToolRules(task);
128
- const outputContract = buildOutputContract(task);
129
-
130
- // If prompt is already upgraded (contains framework blocks), skip
131
- if (normalized.includes("Objective:") && normalized.includes("Context:")) {
132
- return userPrompt;
133
- }
134
-
135
- // Simple prompts don't need full framework
136
- if (normalized.length < 15 || normalized.split(" ").length < 3) {
137
- return userPrompt;
138
- }
139
-
140
- return `Objective:
141
- - Complete this task: ${normalized}
142
- - Optimize for a correct, useful result rather than a merely plausible one.
143
-
144
- Context:
145
- - Preserve the user's original intent and constraints.
146
- - Surface any key assumptions if required information is missing.
147
-
148
- Work Style:
149
- - Task type: ${task}
150
- - Effort level: ${intensity}
151
- - Understand the problem broadly enough to avoid narrow mistakes, then go deep where the risk or complexity is highest.
152
- - Use first-principles reasoning before proposing changes.
153
- - For non-trivial work, review the result once with fresh eyes before finalizing.
154
-
155
- Tool Rules:
156
- - ${toolRules}
157
-
158
- Output Contract:
159
- - ${outputContract}
160
-
161
- Verification:
162
- - Check correctness, completeness, and edge cases.
163
- - Improve obvious weaknesses if a better approach is available within scope.
164
-
165
- Done Criteria:
166
- - Stop only when the response satisfies the task, matches the requested format, and passes the verification step.`;
167
- }
168
-
169
- export const PromptLeverage: Plugin = async ({ client }) => {
170
- console.log("PromptLeverage: Initializing...");
171
-
172
- const showToast = async (message: string) => {
173
- try {
174
- await client.tui.showToast({
175
- body: {
176
- title: "PromptLeverage",
177
- message,
178
- variant: "info",
179
- duration: 3000,
180
- },
181
- });
182
- } catch {
183
- /* Toast API unavailable */
184
- }
185
- };
186
-
187
- return {
188
- "chat.message": async (input, output) => {
189
- // Upgrade user message - check different structures
190
- showToast(
191
- `Hook fired, msg: ${JSON.stringify(input.message).slice(0, 100)}`,
192
- );
193
-
194
- // Try parts array
195
- if (input.message?.parts) {
196
- for (const part of input.message.parts) {
197
- if (part.type === "text" && part.text) {
198
- const upgraded = upgradePrompt(part.text);
199
- if (upgraded !== part.text) {
200
- part.text = upgraded;
201
- showToast("Upgraded user prompt");
202
- }
203
- }
204
- }
205
- }
206
- // Try direct text field
207
- else if (input.message?.text) {
208
- const upgraded = upgradePrompt(input.message.text);
209
- if (upgraded !== input.message.text) {
210
- input.message.text = upgraded;
211
- showToast("Upgraded user prompt");
212
- }
213
- }
214
- // Try content array
215
- else if (input.message?.content) {
216
- for (const part of input.message.content) {
217
- if (part.type === "text" && part.text) {
218
- const upgraded = upgradePrompt(part.text);
219
- if (upgraded !== part.text) {
220
- part.text = upgraded;
221
- showToast("Upgraded user prompt");
222
- }
223
- }
224
- }
225
- }
226
- },
227
- };
228
- };