@yeaft/webchat-agent 1.0.444 → 1.0.446
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/Dockerfile +5 -2
- package/cli.js +9 -0
- package/connection/message-router.js +5 -1
- package/connection/upgrade.js +18 -0
- package/container-manager.js +1 -0
- package/index.js +48 -36
- package/local-runtime/agent/container-manager.js +1 -0
- package/local-runtime/server/handlers/agent-output.js +17 -0
- package/local-runtime/server/handlers/client-conversation.js +24 -1
- package/local-runtime/server/handlers/client-misc.js +15 -0
- package/local-runtime/server/yeaft-managed-skill-capability.js +11 -0
- package/local-runtime/version.json +1 -1
- package/local-runtime/web/app.bundle.js +160 -98
- package/local-runtime/web/app.bundle.js.gz +0 -0
- package/local-runtime/web/index.html +2 -2
- package/local-runtime/web/style.bundle.css +1 -1
- package/local-runtime/web/style.bundle.css.gz +0 -0
- package/package.json +1 -1
- package/startup-maintenance.js +52 -0
- package/upgrade-command.js +19 -0
- package/yeaft/plugins.js +25 -11
- package/yeaft/skills.js +308 -8
- package/yeaft/web-bridge.js +122 -3
package/Dockerfile
CHANGED
|
@@ -4,7 +4,8 @@ ARG BUILD_VERSION=dev
|
|
|
4
4
|
ENV NODE_ENV=production \
|
|
5
5
|
HOME=/home/yeaft \
|
|
6
6
|
YEAFT_DIR=/home/yeaft/.yeaft \
|
|
7
|
-
WORK_DIR=/workspace
|
|
7
|
+
WORK_DIR=/workspace \
|
|
8
|
+
YEAFT_AGENT_RUNTIME=container_agent
|
|
8
9
|
|
|
9
10
|
RUN apt-get update \
|
|
10
11
|
&& apt-get install -y --no-install-recommends ca-certificates git openssh-client tini \
|
|
@@ -16,7 +17,9 @@ RUN apt-get update \
|
|
|
16
17
|
WORKDIR /app
|
|
17
18
|
COPY package.json package-lock.json ./
|
|
18
19
|
COPY agent/package.json ./agent/
|
|
19
|
-
RUN npm ci --workspace=agent --omit=dev
|
|
20
|
+
RUN npm_config_cache=/tmp/yeaft-npm-cache npm ci --workspace=agent --omit=dev \
|
|
21
|
+
&& rm -rf /tmp/yeaft-npm-cache \
|
|
22
|
+
&& install -d -m 0700 -o yeaft -g yeaft /home/yeaft/.npm
|
|
20
23
|
COPY --chown=yeaft:yeaft agent ./agent
|
|
21
24
|
RUN node -e "const fs=require('fs'); const p='agent/package.json'; const j=JSON.parse(fs.readFileSync(p)); j.version=process.argv[1].replace(/^v/, ''); fs.writeFileSync(p, JSON.stringify(j, null, 2) + '\\n')" "$BUILD_VERSION" \
|
|
22
25
|
&& chmod 0755 agent/container-entrypoint.sh
|
package/cli.js
CHANGED
|
@@ -38,9 +38,12 @@ import {
|
|
|
38
38
|
warnDeprecatedInstanceArg,
|
|
39
39
|
} from './service/config.js';
|
|
40
40
|
import {
|
|
41
|
+
buildContainerImageUpgradeMessage,
|
|
41
42
|
buildUpgradeInstallCommand,
|
|
42
43
|
buildUpgradeMetadataUrl,
|
|
43
44
|
buildUpgradeVersionCommand,
|
|
45
|
+
CONTAINER_IMAGE_UPGRADE_REASON,
|
|
46
|
+
isContainerAgentRuntime,
|
|
44
47
|
createWindowsUpgradeRun,
|
|
45
48
|
launchWindowsUpgradeScript,
|
|
46
49
|
prepareWindowsUpgradeRunner,
|
|
@@ -545,6 +548,7 @@ function parseAndStart(args) {
|
|
|
545
548
|
}
|
|
546
549
|
|
|
547
550
|
async function checkForUpdates() {
|
|
551
|
+
if (isContainerAgentRuntime()) return;
|
|
548
552
|
try {
|
|
549
553
|
const res = await fetch(buildUpgradeMetadataUrl(pkg.name));
|
|
550
554
|
if (!res.ok) return;
|
|
@@ -562,6 +566,11 @@ async function checkForUpdates() {
|
|
|
562
566
|
async function upgrade(args = []) {
|
|
563
567
|
warnDeprecatedInstanceArg(args);
|
|
564
568
|
const instanceId = resolveServiceInstanceId(args, process.env, { management: true });
|
|
569
|
+
if (isContainerAgentRuntime()) {
|
|
570
|
+
console.error(`${CONTAINER_IMAGE_UPGRADE_REASON}: ${buildContainerImageUpgradeMessage(pkg.version)}`);
|
|
571
|
+
process.exitCode = 1;
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
565
574
|
console.log(`Current version: ${pkg.version}`);
|
|
566
575
|
console.log('Checking for updates...');
|
|
567
576
|
|
|
@@ -30,7 +30,7 @@ import { getLlmConfig, updateLlmConfig, getYeaftSettings, updateYeaftSettings, g
|
|
|
30
30
|
import { loadConfig } from '../yeaft/config.js';
|
|
31
31
|
import { discoverLlmModels } from '../llm-model-discovery.js';
|
|
32
32
|
import { fetchModelsDev } from '../yeaft/llm/models-dev.js';
|
|
33
|
-
import { handleYeaftSessionSend, handleYeaftAskUserAnswer, handleYeaftSubAgentPrompt, handleYeaftTaskCancel, handleYeaftModeSwitch, handleYeaftModelSwitch, resetYeaftSession, refreshLiveSessionConfig, handleYeaftLoadHistory, handleYeaftLoadHistoryOutline, handleYeaftSearchHistory, handleYeaftLoadHistoryWindow, handleYeaftLoadMoreHistory, handleYeaftAbortThread, handleYeaftAbortAll, handleYeaftAbortTurn, handleYeaftVpSubscribe, handleYeaftVpCreate, handleYeaftVpUpdate, handleYeaftVpDelete, handleYeaftVpRead, handleYeaftListSessions, handleYeaftProjectContextSync, handleYeaftProjectMutation, handleYeaftCreateSession, handleYeaftRenameSession, handleYeaftUpdateSession, handleYeaftUpdateSessionConfig, handleYeaftArchiveSession, handleYeaftDeleteSession, handleYeaftSessionAddMember, handleYeaftSessionRemoveMember, handleYeaftSessionSetDefaultVp, handleYeaftScanWorkdirSessions, handleYeaftRestoreSession, handleYeaftDreamTrigger, handleYeaftFetchToolStats, handleYeaftFetchDebugHistory, handleYeaftMcpList, handleYeaftMcpAdd, handleYeaftMcpRemove, handleYeaftMcpReload, handleYeaftPluginCatalog, broadcastLanguageChange, broadcastYeaftSessionSnapshotEager, broadcastYeaftVpSnapshotEager, preloadYeaftSkillSlashCommands } from '../yeaft/web-bridge.js';
|
|
33
|
+
import { handleYeaftSessionSend, handleYeaftAskUserAnswer, handleYeaftSubAgentPrompt, handleYeaftTaskCancel, handleYeaftModeSwitch, handleYeaftModelSwitch, resetYeaftSession, refreshLiveSessionConfig, handleYeaftLoadHistory, handleYeaftLoadHistoryOutline, handleYeaftSearchHistory, handleYeaftLoadHistoryWindow, handleYeaftLoadMoreHistory, handleYeaftAbortThread, handleYeaftAbortAll, handleYeaftAbortTurn, handleYeaftVpSubscribe, handleYeaftVpCreate, handleYeaftVpUpdate, handleYeaftVpDelete, handleYeaftVpRead, handleYeaftListSessions, handleYeaftProjectContextSync, handleYeaftProjectMutation, handleYeaftCreateSession, handleYeaftRenameSession, handleYeaftUpdateSession, handleYeaftUpdateSessionConfig, handleYeaftArchiveSession, handleYeaftDeleteSession, handleYeaftSessionAddMember, handleYeaftSessionRemoveMember, handleYeaftSessionSetDefaultVp, handleYeaftScanWorkdirSessions, handleYeaftRestoreSession, handleYeaftDreamTrigger, handleYeaftFetchToolStats, handleYeaftFetchDebugHistory, handleYeaftMcpList, handleYeaftMcpAdd, handleYeaftMcpRemove, handleYeaftMcpReload, handleYeaftPluginCatalog, handleYeaftManagedSkill, broadcastLanguageChange, broadcastYeaftSessionSnapshotEager, broadcastYeaftVpSnapshotEager, preloadYeaftSkillSlashCommands } from '../yeaft/web-bridge.js';
|
|
34
34
|
import { startYeaftStatusRefresh, forceRefreshYeaftStatus } from '../yeaft/status-cache.js';
|
|
35
35
|
import { handleWorkCenterRequest } from '../yeaft/work-center/bridge.js';
|
|
36
36
|
import { handleBrowserRuntimeMessage } from '../browser-runtime/messages.js';
|
|
@@ -639,6 +639,10 @@ export async function handleMessage(msg) {
|
|
|
639
639
|
handleYeaftPluginCatalog(msg);
|
|
640
640
|
break;
|
|
641
641
|
|
|
642
|
+
case 'yeaft_managed_skill':
|
|
643
|
+
handleYeaftManagedSkill(msg);
|
|
644
|
+
break;
|
|
645
|
+
|
|
642
646
|
case 'yeaft_vp_create':
|
|
643
647
|
case 'unify_vp_create':
|
|
644
648
|
handleYeaftVpCreate(msg);
|
package/connection/upgrade.js
CHANGED
|
@@ -8,6 +8,10 @@ import { getConfigDir, getServiceName, getPm2AppName, getLaunchdPlistPath, DEFAU
|
|
|
8
8
|
import {
|
|
9
9
|
buildUpgradeInstallCommand,
|
|
10
10
|
buildUpgradeMetadataArgs,
|
|
11
|
+
buildContainerImageUpgradeMessage,
|
|
12
|
+
CONTAINER_AGENT_CAPABILITY,
|
|
13
|
+
CONTAINER_IMAGE_UPGRADE_REASON,
|
|
14
|
+
isContainerAgentRuntime,
|
|
11
15
|
createWindowsUpgradeRun,
|
|
12
16
|
launchWindowsUpgradeScript,
|
|
13
17
|
prepareWindowsUpgradeRunner,
|
|
@@ -175,6 +179,20 @@ function compareCmp(cur, cmp) {
|
|
|
175
179
|
}
|
|
176
180
|
|
|
177
181
|
export async function handleUpgradeAgent() {
|
|
182
|
+
if (isContainerAgentRuntime() || ctx.agentCapabilities?.includes(CONTAINER_AGENT_CAPABILITY)) {
|
|
183
|
+
const version = ctx.agentVersion || null;
|
|
184
|
+
const error = buildContainerImageUpgradeMessage(version);
|
|
185
|
+
console.warn(`[Agent] Upgrade rejected (${CONTAINER_IMAGE_UPGRADE_REASON}): ${error}`);
|
|
186
|
+
await sendToServer({
|
|
187
|
+
type: 'upgrade_agent_ack',
|
|
188
|
+
success: false,
|
|
189
|
+
reason: CONTAINER_IMAGE_UPGRADE_REASON,
|
|
190
|
+
error,
|
|
191
|
+
version,
|
|
192
|
+
});
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
178
196
|
console.log('[Agent] Upgrade requested, checking for updates...');
|
|
179
197
|
try {
|
|
180
198
|
const pkgName = ctx.pkgName || '@yeaft/webchat-agent';
|
package/container-manager.js
CHANGED
|
@@ -122,6 +122,7 @@ export function buildCreateArgs({
|
|
|
122
122
|
'--mount', `type=bind,src=${resolve(secretFile)},dst=/run/yeaft-host-secret,readonly`,
|
|
123
123
|
'--env', `SERVER_URL=${serverUrl}`,
|
|
124
124
|
'--env', `AGENT_NAME=${agentName}`,
|
|
125
|
+
'--env', 'YEAFT_AGENT_RUNTIME=container_agent',
|
|
125
126
|
'--env', 'AGENT_SECRET_FILE=/run/yeaft-host-secret',
|
|
126
127
|
'--env', 'YEAFT_DIR=/home/yeaft/.yeaft',
|
|
127
128
|
'--env', 'WORK_DIR=/workspace',
|
package/index.js
CHANGED
|
@@ -6,8 +6,6 @@ import { homedir } from 'os';
|
|
|
6
6
|
import { createAssetOutbox } from './yeaft/asset-outbox.js';
|
|
7
7
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync, chmodSync, readdirSync } from 'fs';
|
|
8
8
|
import { join, dirname } from 'path';
|
|
9
|
-
import { exec } from 'child_process';
|
|
10
|
-
import { promisify } from 'util';
|
|
11
9
|
import { fileURLToPath } from 'url';
|
|
12
10
|
import ctx from './context.js';
|
|
13
11
|
import {
|
|
@@ -22,7 +20,9 @@ import {
|
|
|
22
20
|
import { loadNodePty } from './terminal.js';
|
|
23
21
|
import { connect } from './connection.js';
|
|
24
22
|
import { loadMcpServers } from './mcp.js';
|
|
25
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
getAgentUpgradeCapability,
|
|
25
|
+
} from './upgrade-command.js';
|
|
26
26
|
import { loadConfig as loadYeaftConfig } from './yeaft/config.js';
|
|
27
27
|
import { initYeaftDir } from './yeaft/init.js';
|
|
28
28
|
import { updateBrowserRuntimeSettings } from './yeaft/config-api.js';
|
|
@@ -33,14 +33,12 @@ import {
|
|
|
33
33
|
runAfterManagedCliRuntimeCleanup,
|
|
34
34
|
summarizeManagedCliResults,
|
|
35
35
|
} from './yeaft/managed-cli.js';
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return execAsync(command, { ...options, windowsHide: true });
|
|
43
|
-
}
|
|
36
|
+
import {
|
|
37
|
+
execHiddenFileAsync,
|
|
38
|
+
resolveNpmInvocation,
|
|
39
|
+
shouldRunPeriodicCheck,
|
|
40
|
+
writePeriodicCheckMarker,
|
|
41
|
+
} from './startup-maintenance.js';
|
|
44
42
|
|
|
45
43
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
46
44
|
|
|
@@ -177,7 +175,8 @@ async function detectCapabilities() {
|
|
|
177
175
|
// agent build can speak plaintext WS frames. New servers see this and
|
|
178
176
|
// flip `agent.encryptOutbound = false`, stopping outbound encryption
|
|
179
177
|
// to this peer. Old servers ignore the unknown capability token.
|
|
180
|
-
const capabilities = ['background_tasks', 'file_editor', 'ping_session', 'plaintext-ok', 'workbench_session_routes',
|
|
178
|
+
const capabilities = ['background_tasks', 'file_editor', 'ping_session', 'plaintext-ok', 'workbench_session_routes', 'work_center', 'work_center_message_v2', 'session_history_search', 'session_history_outline', 'session_history_window_prefetch', 'file_reference_resolution', 'yeaft_plugins', 'yeaft_managed_skills'];
|
|
179
|
+
capabilities.push(getAgentUpgradeCapability());
|
|
181
180
|
if (process.platform === 'linux') capabilities.push('work_item_attachments');
|
|
182
181
|
const pty = await loadNodePty();
|
|
183
182
|
if (pty) capabilities.push('terminal');
|
|
@@ -199,7 +198,8 @@ async function ensureDependencies() {
|
|
|
199
198
|
if (!existsSync(nodeModulesPath)) {
|
|
200
199
|
console.log('[Startup] node_modules not found, running npm install...');
|
|
201
200
|
try {
|
|
202
|
-
|
|
201
|
+
const npm = resolveNpmInvocation();
|
|
202
|
+
await execHiddenFileAsync(npm.command, [...npm.argsPrefix, 'install'], { cwd: agentDir, timeout: 120000 });
|
|
203
203
|
console.log('[Startup] npm install completed');
|
|
204
204
|
} catch (e) {
|
|
205
205
|
console.warn('[Startup] npm install failed:', e.message);
|
|
@@ -222,6 +222,7 @@ async function ensureYeaftSkills() {
|
|
|
222
222
|
const installedFile = join(pluginsDir, 'installed_plugins.json');
|
|
223
223
|
const settingsFile = join(claudeDir, 'settings.json');
|
|
224
224
|
const cacheDir = join(pluginsDir, 'cache', MARKETPLACE_NAME, PLUGIN_NAME, PLUGIN_VERSION);
|
|
225
|
+
const updateCheckMarker = join(pluginsDir, '.yeaft-skills-update-check.json');
|
|
225
226
|
|
|
226
227
|
try {
|
|
227
228
|
// --- Layer 1: Clone or update the marketplace repo ---
|
|
@@ -230,38 +231,49 @@ async function ensureYeaftSkills() {
|
|
|
230
231
|
if (!existsSync(installDir)) {
|
|
231
232
|
console.log('[Startup] yeaft-skills not found, installing as marketplace plugin...');
|
|
232
233
|
mkdirSync(marketplacesDir, { recursive: true });
|
|
233
|
-
await
|
|
234
|
+
await execHiddenFileAsync('git', ['clone', REPO_URL, installDir], { timeout: 60000 });
|
|
235
|
+
writePeriodicCheckMarker(updateCheckMarker);
|
|
234
236
|
needsCacheUpdate = true;
|
|
235
237
|
console.log('[Startup] yeaft-skills installed');
|
|
236
238
|
} else {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const { stdout: h } = await execHiddenAsync('git rev-parse HEAD', { cwd: installDir, timeout: 5000 });
|
|
242
|
-
headBefore = h.trim();
|
|
243
|
-
} catch { /* ignore */ }
|
|
244
|
-
const { stdout } = await execHiddenAsync('git pull --ff-only', {
|
|
245
|
-
cwd: installDir,
|
|
246
|
-
timeout: 30000
|
|
247
|
-
});
|
|
248
|
-
if (stdout.includes('Already up to date')) {
|
|
249
|
-
console.log('[Startup] yeaft-skills is up to date');
|
|
250
|
-
} else {
|
|
251
|
-
needsCacheUpdate = true;
|
|
252
|
-
console.log('[Startup] yeaft-skills updated');
|
|
253
|
-
}
|
|
254
|
-
// Double-check: compare HEAD after pull
|
|
255
|
-
if (!needsCacheUpdate && headBefore) {
|
|
239
|
+
if (shouldRunPeriodicCheck(updateCheckMarker)) {
|
|
240
|
+
console.log('[Startup] yeaft-skills found, checking for updates...');
|
|
241
|
+
// Record HEAD before pull to detect changes
|
|
242
|
+
let headBefore = '';
|
|
256
243
|
try {
|
|
257
|
-
const { stdout:
|
|
258
|
-
|
|
244
|
+
const { stdout: h } = await execHiddenFileAsync('git', ['rev-parse', 'HEAD'], { cwd: installDir, timeout: 5000 });
|
|
245
|
+
headBefore = h.trim();
|
|
259
246
|
} catch { /* ignore */ }
|
|
247
|
+
try {
|
|
248
|
+
const { stdout } = await execHiddenFileAsync('git', ['pull', '--ff-only'], {
|
|
249
|
+
cwd: installDir,
|
|
250
|
+
timeout: 30000
|
|
251
|
+
});
|
|
252
|
+
if (stdout.includes('Already up to date')) {
|
|
253
|
+
console.log('[Startup] yeaft-skills is up to date');
|
|
254
|
+
} else {
|
|
255
|
+
needsCacheUpdate = true;
|
|
256
|
+
console.log('[Startup] yeaft-skills updated');
|
|
257
|
+
}
|
|
258
|
+
writePeriodicCheckMarker(updateCheckMarker);
|
|
259
|
+
} catch (e) {
|
|
260
|
+
writePeriodicCheckMarker(updateCheckMarker);
|
|
261
|
+
console.warn('[Startup] yeaft-skills update check failed; using cached checkout:', e.message);
|
|
262
|
+
}
|
|
263
|
+
// Double-check: compare HEAD after pull
|
|
264
|
+
if (!needsCacheUpdate && headBefore) {
|
|
265
|
+
try {
|
|
266
|
+
const { stdout: h2 } = await execHiddenFileAsync('git', ['rev-parse', 'HEAD'], { cwd: installDir, timeout: 5000 });
|
|
267
|
+
if (h2.trim() !== headBefore) needsCacheUpdate = true;
|
|
268
|
+
} catch { /* ignore */ }
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
console.log('[Startup] yeaft-skills update check skipped; recently checked');
|
|
260
272
|
}
|
|
261
273
|
}
|
|
262
274
|
// Get current commit SHA for installed_plugins.json
|
|
263
275
|
try {
|
|
264
|
-
const { stdout: sha } = await
|
|
276
|
+
const { stdout: sha } = await execHiddenFileAsync('git', ['rev-parse', 'HEAD'], { cwd: installDir, timeout: 5000 });
|
|
265
277
|
gitSha = sha.trim();
|
|
266
278
|
} catch { /* non-critical */ }
|
|
267
279
|
|
|
@@ -122,6 +122,7 @@ export function buildCreateArgs({
|
|
|
122
122
|
'--mount', `type=bind,src=${resolve(secretFile)},dst=/run/yeaft-host-secret,readonly`,
|
|
123
123
|
'--env', `SERVER_URL=${serverUrl}`,
|
|
124
124
|
'--env', `AGENT_NAME=${agentName}`,
|
|
125
|
+
'--env', 'YEAFT_AGENT_RUNTIME=container_agent',
|
|
125
126
|
'--env', 'AGENT_SECRET_FILE=/run/yeaft-host-secret',
|
|
126
127
|
'--env', 'YEAFT_DIR=/home/yeaft/.yeaft',
|
|
127
128
|
'--env', 'WORK_DIR=/workspace',
|
|
@@ -882,6 +882,23 @@ export async function handleAgentOutput(agentId, agent, msg) {
|
|
|
882
882
|
break;
|
|
883
883
|
}
|
|
884
884
|
|
|
885
|
+
case 'yeaft_managed_skill_result': {
|
|
886
|
+
const targetClient = msg._requestClientId ? webClients.get(msg._requestClientId) : null;
|
|
887
|
+
if (targetClient?.authenticated && (CONFIG.skipAuth || targetClient.userId === agent.ownerId)) {
|
|
888
|
+
await sendToWebClient(targetClient, {
|
|
889
|
+
type: 'yeaft_managed_skill_result',
|
|
890
|
+
agentId,
|
|
891
|
+
requestId: msg.requestId || null,
|
|
892
|
+
scope: msg.scope || null,
|
|
893
|
+
sessionId: msg.sessionId || null,
|
|
894
|
+
result: msg.result || null,
|
|
895
|
+
catalog: msg.catalog || { tools: [], skills: [], skillSources: [], mcpServers: [] },
|
|
896
|
+
error: msg.error || null,
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
break;
|
|
900
|
+
}
|
|
901
|
+
|
|
885
902
|
case 'yeaft_tool_stats':
|
|
886
903
|
// 2026-05-13: relay tool-call counters from the agent to the web
|
|
887
904
|
// client that requested them. Whitelist `snapshot`/`registered`/
|
|
@@ -31,6 +31,10 @@ import {
|
|
|
31
31
|
agentSupportsYeaftPlugins,
|
|
32
32
|
YEAFT_PLUGINS_UNSUPPORTED_ERROR,
|
|
33
33
|
} from '../yeaft-plugin-capability.js';
|
|
34
|
+
import {
|
|
35
|
+
agentSupportsYeaftManagedSkills,
|
|
36
|
+
YEAFT_MANAGED_SKILLS_UNSUPPORTED_ERROR,
|
|
37
|
+
} from '../yeaft-managed-skill-capability.js';
|
|
34
38
|
|
|
35
39
|
|
|
36
40
|
function isRetiredCollabSessionId(id) {
|
|
@@ -56,6 +60,14 @@ function emptyYeaftPluginCatalog(error = null) {
|
|
|
56
60
|
};
|
|
57
61
|
}
|
|
58
62
|
|
|
63
|
+
function emptyYeaftManagedSkillResult(error = null) {
|
|
64
|
+
return {
|
|
65
|
+
type: 'yeaft_managed_skill_result',
|
|
66
|
+
catalog: { tools: [], skills: [], skillSources: [], mcpServers: [] },
|
|
67
|
+
...(error ? { error } : {}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
59
71
|
async function sendVpSnapshotError(client, msg, error) {
|
|
60
72
|
await sendToWebClient(client, {
|
|
61
73
|
type: 'yeaft_output',
|
|
@@ -1650,6 +1662,15 @@ export async function handleClientConversation(clientId, client, msg, checkAgent
|
|
|
1650
1662
|
});
|
|
1651
1663
|
return true;
|
|
1652
1664
|
}
|
|
1665
|
+
if (relayType === 'yeaft_managed_skill'
|
|
1666
|
+
&& !agentSupportsYeaftManagedSkills(agents.get(relayAgentId))) {
|
|
1667
|
+
await sendToWebClient(client, {
|
|
1668
|
+
...emptyYeaftManagedSkillResult(YEAFT_MANAGED_SKILLS_UNSUPPORTED_ERROR),
|
|
1669
|
+
agentId: relayAgentId,
|
|
1670
|
+
requestId: msg.requestId || null,
|
|
1671
|
+
});
|
|
1672
|
+
return true;
|
|
1673
|
+
}
|
|
1653
1674
|
const relayAgent = agents.get(relayAgentId);
|
|
1654
1675
|
if (!relayAgent || relayAgent.ws?.readyState !== 1) {
|
|
1655
1676
|
if (relayType === 'yeaft_fetch_tool_stats') {
|
|
@@ -1676,7 +1697,9 @@ export async function handleClientConversation(clientId, client, msg, checkAgent
|
|
|
1676
1697
|
// Direct catalog replies are request-scoped. Carry the browser client
|
|
1677
1698
|
// identity through the Agent so another owner tab cannot accidentally
|
|
1678
1699
|
// consume a response for this picker request.
|
|
1679
|
-
if (relayType === 'yeaft_plugin_catalog'
|
|
1700
|
+
if (relayType === 'yeaft_plugin_catalog' || relayType === 'yeaft_managed_skill') {
|
|
1701
|
+
rest._requestClientId = clientId;
|
|
1702
|
+
}
|
|
1680
1703
|
if (rest.type === 'yeaft_session_send' || rest.type === 'yeaft_session_chat') {
|
|
1681
1704
|
trackUserTurn(client.userId, Buffer.byteLength(JSON.stringify(msg)));
|
|
1682
1705
|
const sessionId = typeof rest.sessionId === 'string' ? rest.sessionId.trim() : '';
|
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
// may receive remote upgrade commands. Version thresholds are insufficient:
|
|
14
14
|
// builds without this capability may still inherit the installed package cwd.
|
|
15
15
|
export const SAFE_REMOTE_UPGRADE_CAPABILITY = 'remote_upgrade_safe';
|
|
16
|
+
export const CONTAINER_AGENT_CAPABILITY = 'container_agent';
|
|
17
|
+
export const CONTAINER_IMAGE_UPGRADE_REASON = 'container_image_upgrade_required';
|
|
16
18
|
export { YEAFT_PLUGINS_CAPABILITY, YEAFT_PLUGINS_UNSUPPORTED_ERROR };
|
|
17
19
|
|
|
18
20
|
async function rejectUnsupportedYeaftPlugins(client, msg, agentId) {
|
|
@@ -59,6 +61,19 @@ export async function handleClientMisc(clientId, client, msg, checkAgentAccess)
|
|
|
59
61
|
if (!upgradeAgentId) break;
|
|
60
62
|
if (!await checkAgentAccess(upgradeAgentId)) break;
|
|
61
63
|
const upgradeAgent = agents.get(upgradeAgentId);
|
|
64
|
+
if (Array.isArray(upgradeAgent?.capabilities)
|
|
65
|
+
&& upgradeAgent.capabilities.includes(CONTAINER_AGENT_CAPABILITY)) {
|
|
66
|
+
await sendToWebClient(client, {
|
|
67
|
+
type: 'upgrade_agent_ack',
|
|
68
|
+
agentId: upgradeAgentId,
|
|
69
|
+
success: false,
|
|
70
|
+
reason: CONTAINER_IMAGE_UPGRADE_REASON,
|
|
71
|
+
version: upgradeAgent?.version || null,
|
|
72
|
+
requiredCapability: CONTAINER_AGENT_CAPABILITY,
|
|
73
|
+
error: 'Container Agent is managed as a Docker image. Pull the configured image and recreate the same container through the Server/Sandbox lifecycle while keeping its persistent volumes and host-side agent-secret file.',
|
|
74
|
+
});
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
62
77
|
if (requiresManualUpgradeBridge(upgradeAgent?.capabilities, upgradeAgent?.platform)) {
|
|
63
78
|
await sendToWebClient(client, {
|
|
64
79
|
type: 'upgrade_agent_ack',
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { YEAFT_PLUGINS_CAPABILITY } from './yeaft-plugin-capability.js';
|
|
2
|
+
|
|
3
|
+
export const YEAFT_MANAGED_SKILLS_CAPABILITY = 'yeaft_managed_skills';
|
|
4
|
+
export const YEAFT_MANAGED_SKILLS_UNSUPPORTED_ERROR = 'The selected Agent does not support Skill management; upgrade and restart the Agent';
|
|
5
|
+
|
|
6
|
+
export function agentSupportsYeaftManagedSkills(agent) {
|
|
7
|
+
if (agent?.capabilityMetadataProvided !== true) return false;
|
|
8
|
+
const capabilities = Array.isArray(agent.capabilities) ? agent.capabilities : [];
|
|
9
|
+
return capabilities.includes(YEAFT_PLUGINS_CAPABILITY)
|
|
10
|
+
&& capabilities.includes(YEAFT_MANAGED_SKILLS_CAPABILITY);
|
|
11
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.0.
|
|
1
|
+
{"version":"1.0.446"}
|