@intent-systems/nexus 2026.1.5-3 → 2026.1.5-5
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/agents/agent-id.js +41 -0
- package/dist/agents/auth-profiles.js +114 -25
- package/dist/agents/identity-state.js +79 -0
- package/dist/agents/model-auth.js +1 -0
- package/dist/agents/model-fallback.js +15 -9
- package/dist/agents/model-selection.js +1 -1
- package/dist/agents/models-config.js +17 -11
- package/dist/agents/pi-embedded-runner.js +101 -9
- package/dist/agents/sandbox.js +12 -3
- package/dist/agents/skill-runner.js +29 -4
- package/dist/agents/skill-usage.js +114 -11
- package/dist/agents/skills-status.js +4 -4
- package/dist/agents/skills.js +18 -7
- package/dist/agents/subagent-registry.js +25 -11
- package/dist/agents/system-prompt.js +16 -0
- package/dist/agents/tool-policy.js +19 -3
- package/dist/agents/tools/browser-tool.js +5 -2
- package/dist/agents/tools/image-tool.js +93 -8
- package/dist/agents/tools/sessions-announce-target.js +5 -1
- package/dist/agents/workspace.js +55 -46
- package/dist/auto-reply/command-detection.js +2 -1
- package/dist/auto-reply/reply/directive-handling.js +153 -28
- package/dist/auto-reply/reply/directives.js +17 -2
- package/dist/auto-reply/reply/model-selection.js +8 -3
- package/dist/auto-reply/reply/queue.js +2 -2
- package/dist/auto-reply/reply.js +1 -1
- package/dist/auto-reply/thinking.js +15 -0
- package/dist/browser/chrome.js +1 -1
- package/dist/browser/client.js +2 -0
- package/dist/browser/config.js +6 -2
- package/dist/browser/pw-tools-core.js +3 -0
- package/dist/browser/routes/agent.js +14 -0
- package/dist/canvas-host/server.js +1 -1
- package/dist/capabilities/detector.js +245 -0
- package/dist/capabilities/registry.js +99 -0
- package/dist/channels/location.js +44 -0
- package/dist/channels/web/index.js +2 -0
- package/dist/cli/cloud-cli.js +12 -7
- package/dist/cli/credential-cli.js +139 -17
- package/dist/cli/gateway-cli.js +1 -1
- package/dist/cli/log-cli.js +25 -0
- package/dist/cli/pairing-cli.js +1 -1
- package/dist/cli/program.js +58 -6
- package/dist/cli/run-main.js +1 -1
- package/dist/cli/skills-cli.js +144 -21
- package/dist/cli/skills-hub-cli.js +59 -29
- package/dist/cli/tool-connector-cli.js +99 -24
- package/dist/cli/upstream-sync-cli.js +253 -96
- package/dist/cli/usage-cli.js +14 -0
- package/dist/commands/auth-choice-options.js +6 -1
- package/dist/commands/auth-choice.js +157 -5
- package/dist/commands/bootstrap-preset.js +10 -6
- package/dist/commands/capabilities.js +33 -6
- package/dist/commands/claude-md.js +3 -2
- package/dist/commands/config-view.js +1 -1
- package/dist/commands/configure.js +4 -4
- package/dist/commands/credential.js +497 -36
- package/dist/commands/cursor-rules.js +39 -19
- package/dist/commands/doctor.js +5 -4
- package/dist/commands/identity.js +28 -31
- package/dist/commands/init.js +15 -18
- package/dist/commands/log.js +134 -0
- package/dist/commands/models/fallbacks.js +1 -1
- package/dist/commands/models/image-fallbacks.js +1 -1
- package/dist/commands/models/list.js +1 -1
- package/dist/commands/models/scan.js +1 -1
- package/dist/commands/onboard-auth.js +27 -2
- package/dist/commands/onboard-eve-identity.js +7 -8
- package/dist/commands/onboard-non-interactive.js +4 -2
- package/dist/commands/onboard-quickstart.js +18 -11
- package/dist/commands/quest-state.js +271 -0
- package/dist/commands/quest.js +53 -13
- package/dist/commands/reset.js +1 -1
- package/dist/commands/sessions-ingest.js +5 -4
- package/dist/commands/setup.js +4 -2
- package/dist/commands/skills-manifest.js +2 -2
- package/dist/commands/status.js +179 -61
- package/dist/commands/suggestions.js +1 -1
- package/dist/commands/usage-tracking.js +32 -0
- package/dist/commands/usage-upload.js +6 -1
- package/dist/config/defaults.js +1 -3
- package/dist/config/includes.js +5 -7
- package/dist/config/io.js +88 -16
- package/dist/config/legacy.js +4 -2
- package/dist/config/paths.js +16 -0
- package/dist/config/sessions.js +9 -5
- package/dist/config/zod-schema.js +4 -3
- package/dist/control-plane/broker/broker.js +1022 -0
- package/dist/control-plane/compaction.js +282 -0
- package/dist/control-plane/factory.js +31 -0
- package/dist/control-plane/index.js +10 -0
- package/dist/control-plane/odu/agents.js +192 -0
- package/dist/control-plane/odu/interaction-tools.js +208 -0
- package/dist/control-plane/odu/prompt-loader.js +95 -0
- package/dist/control-plane/odu/runtime.js +479 -0
- package/dist/control-plane/odu/types.js +6 -0
- package/dist/control-plane/odu-control-plane.js +316 -0
- package/dist/control-plane/single-agent.js +249 -0
- package/dist/control-plane/types.js +11 -0
- package/dist/credentials/store.js +449 -0
- package/dist/gateway/server-browser.js +5 -4
- package/dist/gateway/server-methods/cron.js +11 -1
- package/dist/gateway/server.js +14 -7
- package/dist/infra/bonjour.js +1 -1
- package/dist/infra/event-log.js +8 -2
- package/dist/infra/path-env.js +1 -2
- package/dist/infra/provider-usage.auth.js +5 -3
- package/dist/infra/provider-usage.fetch.claude.js +16 -6
- package/dist/infra/provider-usage.fetch.minimax.js +8 -3
- package/dist/infra/provider-usage.js +9 -5
- package/dist/infra/restart.js +2 -2
- package/dist/infra/usage-settings.js +78 -0
- package/dist/infra/usage-suggestions.js +17 -5
- package/dist/infra/usage-upload.js +38 -1
- package/dist/infra/voicewake.js +2 -2
- package/dist/logging/redact.js +109 -0
- package/dist/markdown/fences.js +58 -0
- package/dist/media/image-ops.js +3 -1
- package/dist/memory/embeddings.js +146 -0
- package/dist/memory/index.js +3 -0
- package/dist/memory/internal.js +163 -0
- package/dist/pairing/pairing-store.js +218 -0
- package/dist/plugins/cli.js +42 -0
- package/dist/plugins/discovery.js +253 -0
- package/dist/plugins/install.js +181 -0
- package/dist/plugins/loader.js +290 -0
- package/dist/plugins/registry.js +105 -0
- package/dist/plugins/status.js +29 -0
- package/dist/plugins/tools.js +39 -0
- package/dist/plugins/types.js +1 -0
- package/dist/providers/github-copilot-auth.js +1 -1
- package/dist/routing/resolve-route.js +144 -0
- package/dist/routing/session-key.js +65 -0
- package/dist/sessions/send-policy.js +5 -5
- package/dist/slack/monitor.js +22 -1
- package/dist/telegram/reaction-level.js +2 -1
- package/dist/utils/provider-utils.js +28 -0
- package/dist/utils.js +4 -3
- package/dist/wizard/onboarding.js +29 -7
- package/package.json +4 -29
- package/patches/@mariozechner__pi-ai.patch +215 -0
- package/patches/playwright-core@1.57.0.patch +13 -0
- package/patches/qrcode-terminal.patch +12 -0
- package/scripts/postinstall.js +202 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interaction Agent Tools
|
|
3
|
+
*
|
|
4
|
+
* Creates tools for IAs to delegate to EAs and manage specialist agents.
|
|
5
|
+
* Ported from magic-toolbox/agentkit/tools/interaction-tools.ts
|
|
6
|
+
*/
|
|
7
|
+
import { listAgentSessions, loadSessionMetadata, } from "../../config/sessions.js";
|
|
8
|
+
/**
|
|
9
|
+
* Create all interaction agent tools
|
|
10
|
+
*
|
|
11
|
+
* Returns tool definitions in the format expected by pi-coding-agent
|
|
12
|
+
*/
|
|
13
|
+
export function createInteractionTools(_context) {
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
name: "list_my_agents",
|
|
17
|
+
description: "List all agents you can message: your own specialist agents (by short name) and external agents that have contacted you (by full name).",
|
|
18
|
+
input_schema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
limit: {
|
|
22
|
+
type: "number",
|
|
23
|
+
description: "Maximum number of agents to return (default: 20)",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: "send_message_to_agent",
|
|
30
|
+
description: 'Send a message to an EA. If task_name matches an existing EA, it will be resumed with full history. If not, a new EA will be created with that name. Use priority to control urgency: "urgent"/"high" will interrupt running EA immediately, "normal" will queue the message.',
|
|
31
|
+
input_schema: {
|
|
32
|
+
type: "object",
|
|
33
|
+
properties: {
|
|
34
|
+
task_name: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: 'Unique descriptive name for the EA (e.g., "magic-toolbox-worktrees", "merge-feature-branches")',
|
|
37
|
+
},
|
|
38
|
+
task: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Task description or message for the EA",
|
|
41
|
+
},
|
|
42
|
+
priority: {
|
|
43
|
+
type: "string",
|
|
44
|
+
enum: ["normal", "high", "urgent"],
|
|
45
|
+
description: 'Message priority: "normal" = queue (default), "high"/"urgent" = interrupt running EA immediately. Use high/urgent when: user says "stop/wait", new info invalidates current work, critical correction needed.',
|
|
46
|
+
default: "normal",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
required: ["task_name", "task"],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "inspect_agent",
|
|
54
|
+
description: "Get detailed info about a specific agent (for tie-breaking when multiple agents might match)",
|
|
55
|
+
input_schema: {
|
|
56
|
+
type: "object",
|
|
57
|
+
properties: {
|
|
58
|
+
task_name: {
|
|
59
|
+
type: "string",
|
|
60
|
+
description: "The task_name of the EA to inspect",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
required: ["task_name"],
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Handle tool invocation
|
|
70
|
+
*
|
|
71
|
+
* Called when a tool is invoked by the IA
|
|
72
|
+
*/
|
|
73
|
+
export async function handleToolInvocation(toolName, args, context) {
|
|
74
|
+
const payload = args && typeof args === "object" ? args : {};
|
|
75
|
+
switch (toolName) {
|
|
76
|
+
case "list_my_agents":
|
|
77
|
+
return await handleListMyAgents(payload, context);
|
|
78
|
+
case "send_message_to_agent":
|
|
79
|
+
return await handleSendMessageToAgent(payload, context);
|
|
80
|
+
case "inspect_agent":
|
|
81
|
+
return await handleInspectAgent(payload, context);
|
|
82
|
+
default:
|
|
83
|
+
throw new Error(`Unknown tool: ${toolName}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Handle list_my_agents tool
|
|
88
|
+
*/
|
|
89
|
+
async function handleListMyAgents(args, context) {
|
|
90
|
+
const limit = typeof args.limit === "number" && Number.isFinite(args.limit)
|
|
91
|
+
? Math.max(1, Math.trunc(args.limit))
|
|
92
|
+
: 20;
|
|
93
|
+
// Get own EAs from session storage
|
|
94
|
+
// EAs are stored as sessions with agentType: "execution" and parentSession set
|
|
95
|
+
const agentId = context.agentId.replace("-ia", ""); // Convert 'toolbox-ia' to 'toolbox'
|
|
96
|
+
const allSessions = await listAgentSessions(agentId);
|
|
97
|
+
// Load metadata for each session to check agentType
|
|
98
|
+
const eaSessions = [];
|
|
99
|
+
for (const sessionKey of allSessions.slice(0, limit)) {
|
|
100
|
+
const metadata = await loadSessionMetadata(agentId, sessionKey);
|
|
101
|
+
if (metadata && metadata.agentType === "execution") {
|
|
102
|
+
eaSessions.push({
|
|
103
|
+
sessionKey,
|
|
104
|
+
metadata,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Get external callers from broker
|
|
109
|
+
const externalAgentIds = context.broker.getExternalCallers(context.agentId);
|
|
110
|
+
// Format own EAs (show short names)
|
|
111
|
+
const ownFormatted = eaSessions
|
|
112
|
+
.map((ea) => {
|
|
113
|
+
const updated = ea.metadata.updated; // New format uses 'updated' (ISO string)
|
|
114
|
+
const lastActiveDate = updated
|
|
115
|
+
? new Date(updated).toLocaleString()
|
|
116
|
+
: "Never";
|
|
117
|
+
const taskName = ea.sessionKey; // sessionKey is the task name
|
|
118
|
+
const displayName = ea.metadata.displayName || taskName;
|
|
119
|
+
const isActive = context.broker.isAgentActive(`${context.oduName}-ea-${taskName}`);
|
|
120
|
+
const status = isActive ? "🟢 active" : "⚪ idle";
|
|
121
|
+
return `• ${displayName} (${status})\n Last active: ${lastActiveDate}`;
|
|
122
|
+
})
|
|
123
|
+
.join("\n\n");
|
|
124
|
+
// Format external callers (show full names)
|
|
125
|
+
const externalFormatted = externalAgentIds.length > 0
|
|
126
|
+
? externalAgentIds
|
|
127
|
+
.map((agentId) => {
|
|
128
|
+
const isActive = context.broker.isAgentActive(agentId);
|
|
129
|
+
const status = isActive ? "🟢 active" : "⚪ idle";
|
|
130
|
+
return `• ${agentId} (${status})\n External agent - has sent you messages`;
|
|
131
|
+
})
|
|
132
|
+
.join("\n\n")
|
|
133
|
+
: "";
|
|
134
|
+
// Build response
|
|
135
|
+
let text = "";
|
|
136
|
+
if (eaSessions.length > 0) {
|
|
137
|
+
text += `Your Specialist Agents (${eaSessions.length}):\n\n${ownFormatted}`;
|
|
138
|
+
}
|
|
139
|
+
if (externalFormatted) {
|
|
140
|
+
if (text)
|
|
141
|
+
text += "\n\n---\n\n";
|
|
142
|
+
text += `External Agents (${externalAgentIds.length}):\n\n${externalFormatted}`;
|
|
143
|
+
}
|
|
144
|
+
if (!text) {
|
|
145
|
+
text =
|
|
146
|
+
"No agents found. You can create a new one with send_message_to_agent.";
|
|
147
|
+
}
|
|
148
|
+
return text;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Handle send_message_to_agent tool
|
|
152
|
+
*/
|
|
153
|
+
async function handleSendMessageToAgent(args, context) {
|
|
154
|
+
const taskName = typeof args.task_name === "string" ? args.task_name : "";
|
|
155
|
+
const task = typeof args.task === "string" ? args.task : "";
|
|
156
|
+
if (!taskName || !task) {
|
|
157
|
+
throw new Error("Invalid arguments: task_name and task are required.");
|
|
158
|
+
}
|
|
159
|
+
const priority = typeof args.priority === "string" ? args.priority : "normal";
|
|
160
|
+
// Convert task_name to fully-qualified EA agent ID
|
|
161
|
+
const eaId = `${context.oduName}-ea-${taskName}`;
|
|
162
|
+
// Send message via broker
|
|
163
|
+
await context.broker.send({
|
|
164
|
+
id: `msg-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
|
|
165
|
+
from: context.agentId,
|
|
166
|
+
to: eaId,
|
|
167
|
+
content: task,
|
|
168
|
+
priority: priority,
|
|
169
|
+
timestamp: Date.now(),
|
|
170
|
+
metadata: {
|
|
171
|
+
source: "ia",
|
|
172
|
+
taskName,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
return `Message sent to ${taskName}. The EA will process the task and report back when complete.`;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Handle inspect_agent tool
|
|
179
|
+
*/
|
|
180
|
+
async function handleInspectAgent(args, context) {
|
|
181
|
+
const taskName = typeof args.task_name === "string" ? args.task_name : "";
|
|
182
|
+
if (!taskName) {
|
|
183
|
+
throw new Error("Invalid arguments: task_name is required.");
|
|
184
|
+
}
|
|
185
|
+
const agentId = context.agentId.replace("-ia", ""); // Convert 'toolbox-ia' to 'toolbox'
|
|
186
|
+
// Load session metadata
|
|
187
|
+
const metadata = await loadSessionMetadata(agentId, taskName);
|
|
188
|
+
if (!metadata) {
|
|
189
|
+
return `EA not found: ${taskName}`;
|
|
190
|
+
}
|
|
191
|
+
const updated = metadata.updated; // New format uses 'updated' (ISO string)
|
|
192
|
+
const created = metadata.created; // New format uses 'created' (ISO string)
|
|
193
|
+
const lastActiveDate = updated ? new Date(updated).toLocaleString() : "Never";
|
|
194
|
+
const createdDate = created ? new Date(created).toLocaleString() : "Unknown";
|
|
195
|
+
const displayName = metadata.displayName || taskName;
|
|
196
|
+
// Check if agent is currently active
|
|
197
|
+
const eaId = `${context.oduName}-ea-${taskName}`;
|
|
198
|
+
const isActive = context.broker.isAgentActive(eaId);
|
|
199
|
+
const status = isActive ? "🟢 active" : "⚪ idle";
|
|
200
|
+
return `EA: ${displayName} (${status})
|
|
201
|
+
|
|
202
|
+
Task Name: ${taskName}
|
|
203
|
+
Created: ${createdDate}
|
|
204
|
+
Last Active: ${lastActiveDate}
|
|
205
|
+
Compactions: ${metadata.compactionCount || 0}
|
|
206
|
+
|
|
207
|
+
This EA specializes in: ${metadata.displayName || "general tasks"}`;
|
|
208
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Loader for ODU System Prompts
|
|
3
|
+
*
|
|
4
|
+
* Loads prompt templates from files and substitutes {{variable}} patterns.
|
|
5
|
+
* Similar to magic-toolbox/agentkit/prompts/loader.ts
|
|
6
|
+
*/
|
|
7
|
+
import fs from "node:fs/promises";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { resolveUserPath } from "../../utils.js";
|
|
10
|
+
/**
|
|
11
|
+
* Cache for loaded prompts (performance optimization)
|
|
12
|
+
*/
|
|
13
|
+
const promptCache = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Load a prompt template from file and substitute variables
|
|
16
|
+
*
|
|
17
|
+
* @param promptPath - Path to .md file (relative to nexus root, workspace, or absolute)
|
|
18
|
+
* @param variables - Variables to substitute (e.g., { oduName: "Toolbox", oduPurpose: "..." })
|
|
19
|
+
* @returns Loaded prompt with variables substituted
|
|
20
|
+
*/
|
|
21
|
+
export async function loadPrompt(promptPath, variables = {}) {
|
|
22
|
+
// Resolve prompt path with precedence:
|
|
23
|
+
// 1. Absolute path (if provided)
|
|
24
|
+
// 2. Workspace prompts/ directory
|
|
25
|
+
// 3. Nexus bundled prompts/ directory
|
|
26
|
+
const resolvedPath = await resolvePromptPath(promptPath);
|
|
27
|
+
// Check cache first
|
|
28
|
+
const cacheKey = resolvedPath;
|
|
29
|
+
let template = promptCache.get(cacheKey);
|
|
30
|
+
if (!template) {
|
|
31
|
+
// Load from file
|
|
32
|
+
template = await fs.readFile(resolvedPath, "utf-8");
|
|
33
|
+
// Cache the template
|
|
34
|
+
promptCache.set(cacheKey, template);
|
|
35
|
+
}
|
|
36
|
+
// Substitute {{variable}} patterns
|
|
37
|
+
return substituteVariables(template, variables);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve prompt path with precedence:
|
|
41
|
+
* 1. Absolute path (if provided)
|
|
42
|
+
* 2. Workspace prompts/ directory (if exists)
|
|
43
|
+
* 3. Nexus bundled prompts/ directory
|
|
44
|
+
*
|
|
45
|
+
* @param promptPath - Path to .md file (can be relative or absolute)
|
|
46
|
+
* @returns Absolute path to prompt file
|
|
47
|
+
*/
|
|
48
|
+
async function resolvePromptPath(promptPath) {
|
|
49
|
+
// If absolute path, use directly
|
|
50
|
+
if (path.isAbsolute(promptPath)) {
|
|
51
|
+
return promptPath;
|
|
52
|
+
}
|
|
53
|
+
// Try workspace prompts/ directory first
|
|
54
|
+
const workspacePath = path.join(resolveUserPath("~/nexus/home"), "prompts", promptPath);
|
|
55
|
+
try {
|
|
56
|
+
await fs.access(workspacePath);
|
|
57
|
+
return workspacePath;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Workspace path doesn't exist, try nexus bundled prompts
|
|
61
|
+
}
|
|
62
|
+
// Try nexus bundled prompts/ directory
|
|
63
|
+
// (Resolve relative to this file's directory)
|
|
64
|
+
const nexusRootPath = path.resolve(new URL(import.meta.url).pathname, "../../../..");
|
|
65
|
+
const bundledPath = path.join(nexusRootPath, "prompts", promptPath);
|
|
66
|
+
try {
|
|
67
|
+
await fs.access(bundledPath);
|
|
68
|
+
return bundledPath;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
throw new Error(`Prompt file not found: ${promptPath} (tried workspace and bundled prompts)`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Substitute {{variable}} patterns in template
|
|
76
|
+
*
|
|
77
|
+
* @param template - Template string with {{variable}} patterns
|
|
78
|
+
* @param variables - Variables to substitute
|
|
79
|
+
* @returns Template with variables substituted
|
|
80
|
+
*/
|
|
81
|
+
function substituteVariables(template, variables) {
|
|
82
|
+
let result = template;
|
|
83
|
+
// Replace all {{variable}} patterns
|
|
84
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
85
|
+
const pattern = new RegExp(`\\{\\{${key}\\}\\}`, "g");
|
|
86
|
+
result = result.replace(pattern, value);
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Clear the prompt cache (useful for testing or hot-reloading)
|
|
92
|
+
*/
|
|
93
|
+
export function clearPromptCache() {
|
|
94
|
+
promptCache.clear();
|
|
95
|
+
}
|