@iblai/iblai-js 2.3.11 → 2.3.13
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/data-layer/playwright/agent-skills-helpers.d.ts +166 -0
- package/dist/data-layer/playwright/claw-sandbox-helpers.d.ts +0 -80
- package/dist/data-layer/playwright/index.d.ts +4 -2
- package/dist/playwright/index.cjs +413 -150
- package/dist/playwright/index.cjs.map +1 -1
- package/dist/playwright/index.d.ts +127 -41
- package/dist/playwright/index.esm.js +400 -151
- package/dist/playwright/index.esm.js.map +1 -1
- package/dist/playwright/playwright/agent-skills-helpers.d.ts +166 -0
- package/dist/playwright/playwright/claw-sandbox-helpers.d.ts +0 -80
- package/dist/playwright/playwright/index.d.ts +4 -2
- package/dist/security/playwright/agent-skills-helpers.d.ts +166 -0
- package/dist/security/playwright/claw-sandbox-helpers.d.ts +0 -80
- package/dist/security/playwright/index.d.ts +4 -2
- package/dist/web-containers/playwright/agent-skills-helpers.d.ts +166 -0
- package/dist/web-containers/playwright/claw-sandbox-helpers.d.ts +0 -80
- package/dist/web-containers/playwright/index.d.ts +4 -2
- package/dist/web-containers/source/index.esm.js +158 -79
- package/dist/web-containers/source/next/index.esm.js +163 -80
- package/dist/web-utils/playwright/agent-skills-helpers.d.ts +166 -0
- package/dist/web-utils/playwright/claw-sandbox-helpers.d.ts +0 -80
- package/dist/web-utils/playwright/index.d.ts +4 -2
- package/package.json +4 -4
|
@@ -1741,15 +1741,6 @@ async function switchToSandboxTab(page) {
|
|
|
1741
1741
|
await test$1.expect(page.getByRole('heading', { name: 'Sandbox' }).or(page.getByText('Sandbox'))).toBeVisible({ timeout: 10000 });
|
|
1742
1742
|
logger.info('Switched to Sandbox tab');
|
|
1743
1743
|
}
|
|
1744
|
-
/**
|
|
1745
|
-
* Switch to the Skills tab inside the edit-mentor modal.
|
|
1746
|
-
*/
|
|
1747
|
-
async function switchToSkillsTab(page) {
|
|
1748
|
-
const tab = page.getByRole('tab', { name: 'Skills', exact: true });
|
|
1749
|
-
await test$1.expect(tab).toBeVisible({ timeout: 10000 });
|
|
1750
|
-
await tab.click();
|
|
1751
|
-
logger.info('Switched to Skills tab');
|
|
1752
|
-
}
|
|
1753
1744
|
// ============================
|
|
1754
1745
|
// Instance Table Helpers (not-connected state)
|
|
1755
1746
|
// ============================
|
|
@@ -2249,96 +2240,251 @@ async function editAgentPrompt(page, field, content) {
|
|
|
2249
2240
|
logger.info(`Edited agent prompt "${field}" with ${content.length} chars`);
|
|
2250
2241
|
}
|
|
2251
2242
|
// ============================
|
|
2252
|
-
//
|
|
2243
|
+
// Combined Workflow Helpers
|
|
2244
|
+
// ============================
|
|
2245
|
+
/**
|
|
2246
|
+
* Full workflow: open Sandbox tab, create a new instance, connect the mentor to it.
|
|
2247
|
+
* Returns when the mentor is successfully connected.
|
|
2248
|
+
*/
|
|
2249
|
+
async function setupSandboxInstance(page, instance) {
|
|
2250
|
+
await switchToSandboxTab(page);
|
|
2251
|
+
await createInstance(page, instance);
|
|
2252
|
+
await connectToInstance(page, instance.name);
|
|
2253
|
+
await verifyConnectedInstanceCard(page);
|
|
2254
|
+
logger.info(`Sandbox setup complete for "${instance.name}"`);
|
|
2255
|
+
}
|
|
2256
|
+
/**
|
|
2257
|
+
* Full workflow: open Sandbox tab, disconnect the current instance (if any),
|
|
2258
|
+
* then delete it from the table.
|
|
2259
|
+
*/
|
|
2260
|
+
async function teardownSandboxInstance(page, instanceName) {
|
|
2261
|
+
await switchToSandboxTab(page);
|
|
2262
|
+
// If a connected instance is present, disconnect first
|
|
2263
|
+
const disconnectButton = page.getByRole('button', { name: /^Disconnect$/i });
|
|
2264
|
+
if (await disconnectButton.isVisible().catch(() => false)) {
|
|
2265
|
+
await disconnectInstance(page);
|
|
2266
|
+
}
|
|
2267
|
+
await deleteInstance(page, instanceName);
|
|
2268
|
+
logger.info(`Sandbox teardown complete for "${instanceName}"`);
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
// Agent Skills helpers — the Skills section of the edit-agent dialog
|
|
2272
|
+
// ("Agent Skills" / "Available Skills" sub-tabs, skill CRUD with the
|
|
2273
|
+
// General/Resources dialog tabs, skill resources, and the chat `/` skill
|
|
2274
|
+
// picker). Kept separate from the Claw sandbox helpers, mirroring the
|
|
2275
|
+
// agent-skills / claw split in the data layer.
|
|
2276
|
+
//
|
|
2277
|
+
// Flake-resistance rules used throughout:
|
|
2278
|
+
// - Every dialog is captured ONCE via `page.getByRole('dialog', { name })`
|
|
2279
|
+
// (the accessible name comes from the dialog title only), and all fields
|
|
2280
|
+
// and buttons are resolved from that scoped locator. Dialogs stack here —
|
|
2281
|
+
// New/Edit Skill sits over the edit-agent dialog, resource dialogs sit
|
|
2282
|
+
// over Edit Skill — so unscoped text filters would match several dialogs.
|
|
2283
|
+
// - Rows are located via their test ids (`agent-skill-row`,
|
|
2284
|
+
// `available-skill-row`, `skill-resource-row`) filtered by visible name,
|
|
2285
|
+
// never via CSS classes.
|
|
2286
|
+
// - All waits are element-renders or toasts — never networkidle/timeouts.
|
|
2287
|
+
// - Page-level queries are used only for true portals: toasts, the dropdown
|
|
2288
|
+
// menu contents (they portal to document.body), and the Radix Select
|
|
2289
|
+
// listbox inside resource dialogs.
|
|
2290
|
+
// ============================
|
|
2291
|
+
// Navigation
|
|
2253
2292
|
// ============================
|
|
2254
2293
|
/**
|
|
2255
|
-
*
|
|
2294
|
+
* Switch to the Skills tab inside the edit-agent dialog and wait for the
|
|
2295
|
+
* skills section to render.
|
|
2296
|
+
*/
|
|
2297
|
+
async function switchToSkillsTab(page) {
|
|
2298
|
+
const tab = page.getByRole('tab', { name: 'Skills', exact: true });
|
|
2299
|
+
await test$1.expect(tab).toBeVisible({ timeout: 10000 });
|
|
2300
|
+
await tab.click();
|
|
2301
|
+
await test$1.expect(page.getByTestId('agent-skills-content')).toBeVisible({ timeout: 10000 });
|
|
2302
|
+
logger.info('Switched to Skills tab');
|
|
2303
|
+
}
|
|
2304
|
+
/** The Skills section container — scope for rows, sub-tabs, and pagination. */
|
|
2305
|
+
function skillsSection(page) {
|
|
2306
|
+
return page.getByTestId('agent-skills-content');
|
|
2307
|
+
}
|
|
2308
|
+
/** A row on the "Agent Skills" sub-tab, located by the skill's name. */
|
|
2309
|
+
function agentSkillRow(page, skillName) {
|
|
2310
|
+
return skillsSection(page)
|
|
2311
|
+
.getByTestId('agent-skill-row')
|
|
2312
|
+
.filter({ hasText: skillName });
|
|
2313
|
+
}
|
|
2314
|
+
/** A row on the "Available Skills" sub-tab, located by the skill's name. */
|
|
2315
|
+
function availableSkillRow(page, skillName) {
|
|
2316
|
+
return skillsSection(page)
|
|
2317
|
+
.getByTestId('available-skill-row')
|
|
2318
|
+
.filter({ hasText: skillName });
|
|
2319
|
+
}
|
|
2320
|
+
/**
|
|
2321
|
+
* Verify the Skills section is loaded: the section container and its
|
|
2322
|
+
* "Agent Skills" / "Available Skills" sub-tabs are visible.
|
|
2256
2323
|
*/
|
|
2257
2324
|
async function verifySkillsTabVisible(page) {
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2325
|
+
const section = skillsSection(page);
|
|
2326
|
+
await test$1.expect(section).toBeVisible({ timeout: 10000 });
|
|
2327
|
+
await test$1.expect(page.getByTestId('agent-skills-tab-agent')).toBeVisible({ timeout: 10000 });
|
|
2328
|
+
await test$1.expect(page.getByTestId('agent-skills-tab-available')).toBeVisible({ timeout: 10000 });
|
|
2329
|
+
logger.info('Skills section is visible with Agent/Available sub-tabs');
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* Switch to the "Agent Skills" sub-tab (the agent's own skills, with enable
|
|
2333
|
+
* toggles; the default sub-tab) and wait for its panel to render.
|
|
2334
|
+
*/
|
|
2335
|
+
async function switchToAgentSkillsSubTab(page) {
|
|
2336
|
+
await page.getByTestId('agent-skills-tab-agent').click();
|
|
2337
|
+
await test$1.expect(skillsSection(page)
|
|
2338
|
+
.getByTestId('agent-skill-row')
|
|
2261
2339
|
.first()
|
|
2262
|
-
.
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2340
|
+
.or(page.getByText(/No skills enabled for this agent yet/i))).toBeVisible({ timeout: 10000 });
|
|
2341
|
+
logger.info('Switched to Agent Skills sub-tab');
|
|
2342
|
+
}
|
|
2343
|
+
/**
|
|
2344
|
+
* Switch to the "Available Skills" sub-tab (the platform catalog, paged
|
|
2345
|
+
* server-side 10 per page) and wait for its panel to render past the
|
|
2346
|
+
* loading spinner.
|
|
2347
|
+
*/
|
|
2348
|
+
async function switchToAvailableSkillsSubTab(page) {
|
|
2349
|
+
await page.getByTestId('agent-skills-tab-available').click();
|
|
2350
|
+
await test$1.expect(skillsSection(page)
|
|
2351
|
+
.getByTestId('available-skill-row')
|
|
2352
|
+
.first()
|
|
2353
|
+
.or(page.getByText(/No skills available for this platform/i))).toBeVisible({ timeout: 10000 });
|
|
2354
|
+
logger.info('Switched to Available Skills sub-tab');
|
|
2355
|
+
}
|
|
2356
|
+
/**
|
|
2357
|
+
* Go to a page of the currently visible skills list via the numbered
|
|
2358
|
+
* IblPagination buttons (the pagination renders nothing on a single page).
|
|
2359
|
+
*/
|
|
2360
|
+
async function goToSkillsListPage(page, pageNumber) {
|
|
2361
|
+
await skillsSection(page)
|
|
2362
|
+
.getByRole('navigation')
|
|
2363
|
+
.getByText(String(pageNumber), { exact: true })
|
|
2364
|
+
.click();
|
|
2365
|
+
logger.info(`Went to skills list page ${pageNumber}`);
|
|
2366
|
+
}
|
|
2367
|
+
/**
|
|
2368
|
+
* Verify the "Available Skills" empty state ("No skills available for this
|
|
2369
|
+
* platform…") is shown.
|
|
2370
|
+
*/
|
|
2371
|
+
async function verifySkillsEmptyState(page) {
|
|
2268
2372
|
await test$1.expect(page.getByText(/No skills available for this platform/i)).toBeVisible({
|
|
2269
2373
|
timeout: 10000,
|
|
2270
2374
|
});
|
|
2271
|
-
logger.info('Skills
|
|
2375
|
+
logger.info('Available Skills empty state is displayed');
|
|
2272
2376
|
}
|
|
2273
2377
|
/**
|
|
2274
|
-
* Verify
|
|
2378
|
+
* Verify the "Agent Skills" empty state ("No skills enabled for this agent
|
|
2379
|
+
* yet…") is shown.
|
|
2275
2380
|
*/
|
|
2276
|
-
async function
|
|
2277
|
-
await test$1.expect(page.getByText(/No skills
|
|
2381
|
+
async function verifyAgentSkillsEmptyState(page) {
|
|
2382
|
+
await test$1.expect(page.getByText(/No skills enabled for this agent yet/i)).toBeVisible({
|
|
2278
2383
|
timeout: 10000,
|
|
2279
2384
|
});
|
|
2280
|
-
logger.info('Skills empty state is displayed');
|
|
2385
|
+
logger.info('Agent Skills empty state is displayed');
|
|
2281
2386
|
}
|
|
2282
2387
|
/**
|
|
2283
|
-
* Count the
|
|
2284
|
-
* Each row represents an available (enabled) platform skill.
|
|
2388
|
+
* Count the skill rows on the "Agent Skills" sub-tab (max 10 per page).
|
|
2285
2389
|
*/
|
|
2286
2390
|
async function getSkillRowCount(page) {
|
|
2287
|
-
const
|
|
2288
|
-
|
|
2289
|
-
logger.info(`${count} skill row(s) displayed`);
|
|
2391
|
+
const count = await skillsSection(page).getByTestId('agent-skill-row').count();
|
|
2392
|
+
logger.info(`${count} agent skill row(s) displayed`);
|
|
2290
2393
|
return count;
|
|
2291
2394
|
}
|
|
2292
2395
|
/**
|
|
2293
|
-
* Verify that a specific skill row is visible
|
|
2396
|
+
* Verify that a specific skill row is visible on the "Agent Skills" sub-tab.
|
|
2294
2397
|
*/
|
|
2295
2398
|
async function verifySkillVisible(page, skillName) {
|
|
2296
|
-
|
|
2297
|
-
.locator('div.rounded-lg.border.p-6')
|
|
2298
|
-
.filter({ hasText: skillName })
|
|
2299
|
-
.filter({ has: page.getByRole('switch') });
|
|
2300
|
-
await test$1.expect(row).toBeVisible({ timeout: 10000 });
|
|
2399
|
+
await test$1.expect(agentSkillRow(page, skillName)).toBeVisible({ timeout: 10000 });
|
|
2301
2400
|
logger.info(`Skill "${skillName}" is visible`);
|
|
2302
2401
|
}
|
|
2402
|
+
// ============================
|
|
2403
|
+
// Attach / Detach / Toggle
|
|
2404
|
+
// ============================
|
|
2405
|
+
/**
|
|
2406
|
+
* Attach a platform skill to the agent from the "Available Skills" sub-tab.
|
|
2407
|
+
* Waits for the toast and for the row to flip to its "Added" chip.
|
|
2408
|
+
*/
|
|
2409
|
+
async function addSkillToAgent(page, skillName) {
|
|
2410
|
+
const row = availableSkillRow(page, skillName);
|
|
2411
|
+
await row.getByRole('button', { name: `Add ${skillName} to this agent` }).click();
|
|
2412
|
+
await test$1.expect(page.getByText(`${skillName} added`, { exact: false })).toBeVisible({
|
|
2413
|
+
timeout: 10000,
|
|
2414
|
+
});
|
|
2415
|
+
await test$1.expect(row.getByText('Added', { exact: true })).toBeVisible({ timeout: 10000 });
|
|
2416
|
+
logger.info(`Added skill "${skillName}" to the agent`);
|
|
2417
|
+
}
|
|
2303
2418
|
/**
|
|
2304
|
-
*
|
|
2419
|
+
* Verify a catalog row shows the "Added" chip (already on the agent, or
|
|
2420
|
+
* shadowed by a same-slug private skill) and offers no Add button.
|
|
2421
|
+
*/
|
|
2422
|
+
async function verifySkillAdded(page, skillName) {
|
|
2423
|
+
const row = availableSkillRow(page, skillName);
|
|
2424
|
+
await test$1.expect(row.getByText('Added', { exact: true })).toBeVisible({ timeout: 10000 });
|
|
2425
|
+
await test$1.expect(row.getByRole('button', { name: `Add ${skillName} to this agent` })).toBeHidden();
|
|
2426
|
+
logger.info(`Skill "${skillName}" shows as Added`);
|
|
2427
|
+
}
|
|
2428
|
+
/**
|
|
2429
|
+
* Open the three-dots actions menu for a skill row. The menu content portals
|
|
2430
|
+
* to document.body, so the returned locator is page-level by design.
|
|
2431
|
+
*/
|
|
2432
|
+
async function openSkillActionsMenu(page, skillName) {
|
|
2433
|
+
const actionsButton = page.getByRole('button', { name: `${skillName} actions` });
|
|
2434
|
+
await test$1.expect(actionsButton).toBeVisible({ timeout: 10000 });
|
|
2435
|
+
await actionsButton.click();
|
|
2436
|
+
const menu = page.getByRole('menu');
|
|
2437
|
+
await test$1.expect(menu).toBeVisible({ timeout: 5000 });
|
|
2438
|
+
return menu;
|
|
2439
|
+
}
|
|
2440
|
+
/**
|
|
2441
|
+
* Detach a skill from the agent via its row menu ("Remove from Agent") on the
|
|
2442
|
+
* "Agent Skills" sub-tab. Waits for the toast and for the row to disappear.
|
|
2443
|
+
*/
|
|
2444
|
+
async function removeSkillFromAgent(page, skillName) {
|
|
2445
|
+
const menu = await openSkillActionsMenu(page, skillName);
|
|
2446
|
+
await menu.getByRole('menuitem', { name: /Remove from Agent/i }).click();
|
|
2447
|
+
await test$1.expect(page.getByText(`${skillName} removed`, { exact: false })).toBeVisible({
|
|
2448
|
+
timeout: 10000,
|
|
2449
|
+
});
|
|
2450
|
+
logger.info(`Removed skill "${skillName}" from the agent`);
|
|
2451
|
+
}
|
|
2452
|
+
/**
|
|
2453
|
+
* Check if a specific skill is currently enabled (its row Switch state) on
|
|
2454
|
+
* the "Agent Skills" sub-tab.
|
|
2305
2455
|
*/
|
|
2306
2456
|
async function isSkillEnabled(page, skillName) {
|
|
2307
|
-
const switchEl = page
|
|
2457
|
+
const switchEl = agentSkillRow(page, skillName).getByRole('switch');
|
|
2308
2458
|
await test$1.expect(switchEl).toBeVisible({ timeout: 10000 });
|
|
2309
2459
|
const enabled = await switchEl.isChecked();
|
|
2310
2460
|
logger.info(`Skill "${skillName}" is ${enabled ? 'enabled' : 'disabled'}`);
|
|
2311
2461
|
return enabled;
|
|
2312
2462
|
}
|
|
2313
2463
|
/**
|
|
2314
|
-
* Enable
|
|
2315
|
-
* No-op if already enabled.
|
|
2464
|
+
* Enable an attached skill by flipping its Switch on (PATCHes the assignment;
|
|
2465
|
+
* attaching itself is `addSkillToAgent`). No-op if already enabled.
|
|
2316
2466
|
*/
|
|
2317
2467
|
async function enableSkill(page, skillName) {
|
|
2318
|
-
|
|
2319
|
-
const isDisabled = await disabledSwitch.isVisible().catch(() => false);
|
|
2320
|
-
if (!isDisabled) {
|
|
2468
|
+
if (await isSkillEnabled(page, skillName)) {
|
|
2321
2469
|
logger.info(`Skill "${skillName}" already enabled`);
|
|
2322
2470
|
return;
|
|
2323
2471
|
}
|
|
2324
|
-
await
|
|
2472
|
+
await agentSkillRow(page, skillName).getByRole('switch').click();
|
|
2325
2473
|
await test$1.expect(page.getByText(`${skillName} enabled`, { exact: false })).toBeVisible({
|
|
2326
2474
|
timeout: 10000,
|
|
2327
2475
|
});
|
|
2328
2476
|
logger.info(`Enabled skill "${skillName}"`);
|
|
2329
2477
|
}
|
|
2330
2478
|
/**
|
|
2331
|
-
* Disable
|
|
2332
|
-
* No-op if already disabled.
|
|
2479
|
+
* Disable an attached skill by flipping its Switch off, without detaching it
|
|
2480
|
+
* (detaching is `removeSkillFromAgent`). No-op if already disabled.
|
|
2333
2481
|
*/
|
|
2334
2482
|
async function disableSkill(page, skillName) {
|
|
2335
|
-
|
|
2336
|
-
const isEnabled = await enabledSwitch.isVisible().catch(() => false);
|
|
2337
|
-
if (!isEnabled) {
|
|
2483
|
+
if (!(await isSkillEnabled(page, skillName))) {
|
|
2338
2484
|
logger.info(`Skill "${skillName}" already disabled`);
|
|
2339
2485
|
return;
|
|
2340
2486
|
}
|
|
2341
|
-
await
|
|
2487
|
+
await agentSkillRow(page, skillName).getByRole('switch').click();
|
|
2342
2488
|
await test$1.expect(page.getByText(`${skillName} disabled`, { exact: false })).toBeVisible({
|
|
2343
2489
|
timeout: 10000,
|
|
2344
2490
|
});
|
|
@@ -2358,188 +2504,291 @@ async function toggleSkill(page, skillName) {
|
|
|
2358
2504
|
return true;
|
|
2359
2505
|
}
|
|
2360
2506
|
/**
|
|
2361
|
-
* Open the "New Skill" dialog
|
|
2362
|
-
*
|
|
2507
|
+
* Open the "New Skill" dialog from the Skills section. Returns the dialog
|
|
2508
|
+
* locator — resolve every field from it (the dialog stacks over the
|
|
2509
|
+
* edit-agent dialog, so page-level field queries would be ambiguous).
|
|
2363
2510
|
*/
|
|
2364
2511
|
async function openNewSkillDialog(page) {
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
const dialog = page.getByRole('dialog'
|
|
2512
|
+
await skillsSection(page).getByRole('button', { name: /^New Skill$/ }).click();
|
|
2513
|
+
// Accessible name comes from the dialog title only — never matches the
|
|
2514
|
+
// "New Skill" button text inside the edit-agent dialog behind it.
|
|
2515
|
+
const dialog = page.getByRole('dialog', { name: 'New Skill' });
|
|
2369
2516
|
return waitForDialogReady(page, dialog);
|
|
2370
2517
|
}
|
|
2371
2518
|
/**
|
|
2372
|
-
* Type content into the RichTextEditor Instruction field
|
|
2373
|
-
*
|
|
2374
|
-
*
|
|
2375
|
-
* `dialog` scopes the lookups to the open skill modal so the
|
|
2376
|
-
* contenteditable `.first()` and the "Instruction" label don't match
|
|
2377
|
-
* elements on the modal behind it. The keyboard is page-global.
|
|
2519
|
+
* Type content into the RichTextEditor Instruction field (a contenteditable
|
|
2520
|
+
* region). `dialog` scopes the editor lookup to the open skill modal.
|
|
2378
2521
|
*/
|
|
2379
2522
|
async function fillInstructionEditor(dialog, content) {
|
|
2380
2523
|
const page = dialog.page();
|
|
2381
|
-
// RichTextEditor uses a contenteditable region
|
|
2382
2524
|
const editor = dialog.locator('[contenteditable="true"]').first();
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
await page.keyboard.type(content);
|
|
2390
|
-
}
|
|
2391
|
-
return;
|
|
2525
|
+
await test$1.expect(editor).toBeVisible({ timeout: 5000 });
|
|
2526
|
+
await editor.click();
|
|
2527
|
+
await page.keyboard.press('ControlOrMeta+A');
|
|
2528
|
+
await page.keyboard.press('Delete');
|
|
2529
|
+
if (content) {
|
|
2530
|
+
await page.keyboard.type(content);
|
|
2392
2531
|
}
|
|
2393
|
-
// Fallback: a plain labelled input/textarea named "Instruction"
|
|
2394
|
-
const textarea = dialog.getByLabel('Instruction');
|
|
2395
|
-
await textarea.fill(content);
|
|
2396
2532
|
}
|
|
2397
2533
|
/**
|
|
2398
|
-
* Fill the skill form
|
|
2399
|
-
*
|
|
2400
|
-
*
|
|
2401
|
-
* The Instruction field is a rich-text (markdown) editor.
|
|
2534
|
+
* Fill the skill form (used by both the New and Edit dialogs). Every field is
|
|
2535
|
+
* resolved from `dialog`; labels use exact matches so "Name" can never match
|
|
2536
|
+
* a "File Name" field in a stacked resource dialog.
|
|
2402
2537
|
*/
|
|
2403
2538
|
async function fillSkillForm(dialog, values) {
|
|
2404
|
-
|
|
2405
|
-
|
|
2539
|
+
if (values.onlyThisAgent !== undefined) {
|
|
2540
|
+
const privateSwitch = dialog.getByRole('switch', { name: 'Only This Agent' });
|
|
2541
|
+
if ((await privateSwitch.isChecked()) !== values.onlyThisAgent) {
|
|
2542
|
+
await privateSwitch.click();
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
await dialog.getByLabel('Name', { exact: true }).fill(values.name);
|
|
2546
|
+
await dialog.getByLabel('Slug', { exact: true }).fill(values.slug);
|
|
2406
2547
|
if (values.version !== undefined) {
|
|
2407
|
-
await dialog.getByLabel('Version').fill(values.version);
|
|
2548
|
+
await dialog.getByLabel('Version', { exact: true }).fill(values.version);
|
|
2549
|
+
}
|
|
2550
|
+
if (values.category !== undefined) {
|
|
2551
|
+
await dialog.getByLabel('Category', { exact: true }).fill(values.category);
|
|
2408
2552
|
}
|
|
2409
2553
|
if (values.description !== undefined) {
|
|
2410
|
-
await dialog.getByLabel('Description').fill(values.description);
|
|
2554
|
+
await dialog.getByLabel('Description', { exact: true }).fill(values.description);
|
|
2411
2555
|
}
|
|
2412
2556
|
if (values.instruction !== undefined) {
|
|
2413
2557
|
await fillInstructionEditor(dialog, values.instruction);
|
|
2414
2558
|
}
|
|
2415
2559
|
}
|
|
2416
2560
|
/**
|
|
2417
|
-
* Create a new platform-level skill via the Skills
|
|
2561
|
+
* Create a new platform-level skill via the Skills section.
|
|
2418
2562
|
*/
|
|
2419
2563
|
async function createSkill(page, values) {
|
|
2420
2564
|
const dialog = await openNewSkillDialog(page);
|
|
2421
2565
|
await fillSkillForm(dialog, values);
|
|
2422
|
-
const createButton = dialog.getByRole('button', { name: /^Create$/
|
|
2566
|
+
const createButton = dialog.getByRole('button', { name: /^Create$/ });
|
|
2423
2567
|
await test$1.expect(createButton).toBeEnabled({ timeout: 5000 });
|
|
2424
2568
|
await createButton.click();
|
|
2425
2569
|
await test$1.expect(page.getByText('Skill created', { exact: false })).toBeVisible({
|
|
2426
2570
|
timeout: 10000,
|
|
2427
2571
|
});
|
|
2572
|
+
await test$1.expect(dialog).toBeHidden({ timeout: 5000 });
|
|
2428
2573
|
logger.info(`Created skill "${values.name}"`);
|
|
2429
2574
|
}
|
|
2430
2575
|
/**
|
|
2431
|
-
* Open the
|
|
2432
|
-
* Returns the
|
|
2433
|
-
*/
|
|
2434
|
-
async function openSkillActionsMenu(page, skillName) {
|
|
2435
|
-
const actionsButton = page.getByRole('button', { name: `${skillName} actions` });
|
|
2436
|
-
await test$1.expect(actionsButton).toBeVisible({ timeout: 10000 });
|
|
2437
|
-
await actionsButton.click();
|
|
2438
|
-
const menu = page.getByRole('menu');
|
|
2439
|
-
await test$1.expect(menu).toBeVisible({ timeout: 5000 });
|
|
2440
|
-
return menu;
|
|
2441
|
-
}
|
|
2442
|
-
/**
|
|
2443
|
-
* Open the Edit Skill dialog from the actions menu.
|
|
2444
|
-
* Returns the dialog locator.
|
|
2576
|
+
* Open the Edit Skill dialog for a row (lands on the General sub-tab).
|
|
2577
|
+
* Returns the dialog locator — resolve fields and sub-tabs from it.
|
|
2445
2578
|
*/
|
|
2446
2579
|
async function openEditSkillDialog(page, skillName) {
|
|
2447
|
-
await openSkillActionsMenu(page, skillName);
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
await editItem.click();
|
|
2451
|
-
const dialog = page.getByRole('dialog').filter({ hasText: 'Edit Skill' });
|
|
2580
|
+
const menu = await openSkillActionsMenu(page, skillName);
|
|
2581
|
+
await menu.getByRole('menuitem', { name: /^Edit$/ }).click();
|
|
2582
|
+
const dialog = page.getByRole('dialog', { name: 'Edit Skill' });
|
|
2452
2583
|
return waitForDialogReady(page, dialog);
|
|
2453
2584
|
}
|
|
2454
2585
|
/**
|
|
2455
|
-
* Edit an existing platform-level skill.
|
|
2456
|
-
* @param skillName - The current name of the skill to edit
|
|
2457
|
-
* @param updates - Fields to update on the skill
|
|
2586
|
+
* Edit an existing platform-level skill (General sub-tab fields).
|
|
2458
2587
|
*/
|
|
2459
2588
|
async function editSkill(page, skillName, updates) {
|
|
2460
2589
|
const dialog = await openEditSkillDialog(page, skillName);
|
|
2590
|
+
if (updates.onlyThisAgent !== undefined) {
|
|
2591
|
+
const privateSwitch = dialog.getByRole('switch', { name: 'Only This Agent' });
|
|
2592
|
+
if ((await privateSwitch.isChecked()) !== updates.onlyThisAgent) {
|
|
2593
|
+
await privateSwitch.click();
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2461
2596
|
if (updates.name !== undefined) {
|
|
2462
|
-
await dialog.getByLabel('Name').fill(updates.name);
|
|
2597
|
+
await dialog.getByLabel('Name', { exact: true }).fill(updates.name);
|
|
2463
2598
|
}
|
|
2464
2599
|
if (updates.slug !== undefined) {
|
|
2465
|
-
await dialog.getByLabel('Slug').fill(updates.slug);
|
|
2600
|
+
await dialog.getByLabel('Slug', { exact: true }).fill(updates.slug);
|
|
2466
2601
|
}
|
|
2467
2602
|
if (updates.version !== undefined) {
|
|
2468
|
-
await dialog.getByLabel('Version').fill(updates.version);
|
|
2603
|
+
await dialog.getByLabel('Version', { exact: true }).fill(updates.version);
|
|
2604
|
+
}
|
|
2605
|
+
if (updates.category !== undefined) {
|
|
2606
|
+
await dialog.getByLabel('Category', { exact: true }).fill(updates.category);
|
|
2469
2607
|
}
|
|
2470
2608
|
if (updates.description !== undefined) {
|
|
2471
|
-
await dialog.getByLabel('Description').fill(updates.description);
|
|
2609
|
+
await dialog.getByLabel('Description', { exact: true }).fill(updates.description);
|
|
2472
2610
|
}
|
|
2473
2611
|
if (updates.instruction !== undefined) {
|
|
2474
2612
|
await fillInstructionEditor(dialog, updates.instruction);
|
|
2475
2613
|
}
|
|
2476
|
-
const saveButton = dialog.getByRole('button', { name: /^Save$/
|
|
2614
|
+
const saveButton = dialog.getByRole('button', { name: /^Save$/ });
|
|
2477
2615
|
await test$1.expect(saveButton).toBeEnabled({ timeout: 5000 });
|
|
2478
2616
|
await saveButton.click();
|
|
2479
2617
|
await test$1.expect(page.getByText('Skill updated', { exact: false })).toBeVisible({
|
|
2480
2618
|
timeout: 10000,
|
|
2481
2619
|
});
|
|
2482
|
-
|
|
2620
|
+
await test$1.expect(dialog).toBeHidden({ timeout: 5000 });
|
|
2621
|
+
logger.info(`Edited skill "${skillName}"`);
|
|
2483
2622
|
}
|
|
2484
2623
|
/**
|
|
2485
|
-
* Delete a platform-level skill, confirming the
|
|
2624
|
+
* Delete a platform-level skill via its row menu, confirming the
|
|
2625
|
+
* "Delete Skill" dialog.
|
|
2486
2626
|
*/
|
|
2487
2627
|
async function deleteSkill(page, skillName) {
|
|
2488
|
-
await openSkillActionsMenu(page, skillName);
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
await
|
|
2492
|
-
|
|
2493
|
-
await test$1.expect(dialog).toBeVisible({ timeout: 5000 });
|
|
2494
|
-
const confirmButton = dialog.getByRole('button', { name: /^Delete$/i });
|
|
2495
|
-
await test$1.expect(confirmButton).toBeVisible({ timeout: 5000 });
|
|
2496
|
-
await confirmButton.click();
|
|
2628
|
+
const menu = await openSkillActionsMenu(page, skillName);
|
|
2629
|
+
await menu.getByRole('menuitem', { name: /^Delete$/ }).click();
|
|
2630
|
+
const confirm = page.getByRole('dialog', { name: 'Delete Skill' });
|
|
2631
|
+
await test$1.expect(confirm).toBeVisible({ timeout: 5000 });
|
|
2632
|
+
await confirm.getByRole('button', { name: /^Delete$/ }).click();
|
|
2497
2633
|
await test$1.expect(page.getByText('Skill deleted', { exact: false })).toBeVisible({
|
|
2498
2634
|
timeout: 10000,
|
|
2499
2635
|
});
|
|
2636
|
+
await test$1.expect(confirm).toBeHidden({ timeout: 5000 });
|
|
2500
2637
|
logger.info(`Deleted skill "${skillName}"`);
|
|
2501
2638
|
}
|
|
2502
2639
|
/**
|
|
2503
2640
|
* Open the delete confirmation for a skill and cancel it (no deletion).
|
|
2504
2641
|
*/
|
|
2505
2642
|
async function cancelDeleteSkill(page, skillName) {
|
|
2506
|
-
await openSkillActionsMenu(page, skillName);
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
await
|
|
2511
|
-
|
|
2512
|
-
await cancelButton.click();
|
|
2513
|
-
await test$1.expect(dialog).not.toBeVisible({ timeout: 5000 });
|
|
2643
|
+
const menu = await openSkillActionsMenu(page, skillName);
|
|
2644
|
+
await menu.getByRole('menuitem', { name: /^Delete$/ }).click();
|
|
2645
|
+
const confirm = page.getByRole('dialog', { name: 'Delete Skill' });
|
|
2646
|
+
await test$1.expect(confirm).toBeVisible({ timeout: 5000 });
|
|
2647
|
+
await confirm.getByRole('button', { name: /^Cancel$/ }).click();
|
|
2648
|
+
await test$1.expect(confirm).toBeHidden({ timeout: 5000 });
|
|
2514
2649
|
logger.info(`Cancelled delete of skill "${skillName}"`);
|
|
2515
2650
|
}
|
|
2516
2651
|
// ============================
|
|
2517
|
-
//
|
|
2652
|
+
// Skill Resources (Edit Skill → Resources sub-tab)
|
|
2518
2653
|
// ============================
|
|
2519
2654
|
/**
|
|
2520
|
-
*
|
|
2521
|
-
*
|
|
2655
|
+
* Switch the open Edit Skill dialog to its Resources sub-tab. Pass the
|
|
2656
|
+
* dialog returned by `openEditSkillDialog`; returns the resources section
|
|
2657
|
+
* locator to scope row lookups.
|
|
2522
2658
|
*/
|
|
2523
|
-
async function
|
|
2524
|
-
await
|
|
2525
|
-
|
|
2526
|
-
await
|
|
2527
|
-
|
|
2528
|
-
|
|
2659
|
+
async function switchToSkillResourcesSubTab(editSkillDialog) {
|
|
2660
|
+
await editSkillDialog.getByTestId('skill-dialog-tab-files').click();
|
|
2661
|
+
const section = editSkillDialog.getByTestId('skill-resources-section');
|
|
2662
|
+
await test$1.expect(section).toBeVisible({ timeout: 5000 });
|
|
2663
|
+
logger.info('Switched to the Resources sub-tab');
|
|
2664
|
+
return section;
|
|
2665
|
+
}
|
|
2666
|
+
/** A resource row inside the Resources sub-tab, located by filename. */
|
|
2667
|
+
function resourceRow(section, filename) {
|
|
2668
|
+
return section.getByTestId('skill-resource-row').filter({ hasText: filename });
|
|
2529
2669
|
}
|
|
2530
2670
|
/**
|
|
2531
|
-
*
|
|
2532
|
-
*
|
|
2671
|
+
* Open the "New Resource" dialog from the resources section. Returns the
|
|
2672
|
+
* dialog locator (it stacks over the Edit Skill dialog).
|
|
2533
2673
|
*/
|
|
2534
|
-
async function
|
|
2535
|
-
await
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2674
|
+
async function openNewResourceDialog(page, resourcesSection) {
|
|
2675
|
+
await resourcesSection.getByRole('button', { name: /^New Resource$/ }).click();
|
|
2676
|
+
const dialog = page.getByRole('dialog', { name: 'New Resource' });
|
|
2677
|
+
await test$1.expect(dialog).toBeVisible({ timeout: 5000 });
|
|
2678
|
+
return dialog;
|
|
2679
|
+
}
|
|
2680
|
+
/**
|
|
2681
|
+
* Add a text resource (reference/script) via the "New Resource" dialog.
|
|
2682
|
+
* The type Select's listbox portals inside the dialog panel, so options are
|
|
2683
|
+
* resolved from the dialog too.
|
|
2684
|
+
*/
|
|
2685
|
+
async function addTextResource(page, resourcesSection, { filename, content, type = 'Reference' }) {
|
|
2686
|
+
const dialog = await openNewResourceDialog(page, resourcesSection);
|
|
2687
|
+
if (type !== 'Reference') {
|
|
2688
|
+
await dialog.getByRole('combobox').click();
|
|
2689
|
+
await dialog.getByRole('option', { name: type, exact: true }).click();
|
|
2540
2690
|
}
|
|
2541
|
-
await
|
|
2542
|
-
|
|
2691
|
+
await dialog.getByLabel('File Name', { exact: true }).fill(filename);
|
|
2692
|
+
await dialog.getByLabel('Content', { exact: true }).fill(content);
|
|
2693
|
+
await dialog.getByRole('button', { name: /^Add Resource$/ }).click();
|
|
2694
|
+
await test$1.expect(page.getByText('Resource added', { exact: false })).toBeVisible({
|
|
2695
|
+
timeout: 10000,
|
|
2696
|
+
});
|
|
2697
|
+
await test$1.expect(dialog).toBeHidden({ timeout: 5000 });
|
|
2698
|
+
await test$1.expect(resourceRow(resourcesSection, filename)).toBeVisible({ timeout: 10000 });
|
|
2699
|
+
logger.info(`Added text resource "${filename}"`);
|
|
2700
|
+
}
|
|
2701
|
+
/**
|
|
2702
|
+
* Upload a binary asset resource via the "New Resource" dialog. `filePath`
|
|
2703
|
+
* is passed to Playwright's setInputFiles (absolute or test-relative).
|
|
2704
|
+
*/
|
|
2705
|
+
async function uploadAssetResource(page, resourcesSection, filePath) {
|
|
2706
|
+
const dialog = await openNewResourceDialog(page, resourcesSection);
|
|
2707
|
+
await dialog.getByRole('combobox').click();
|
|
2708
|
+
await dialog.getByRole('option', { name: 'Asset', exact: true }).click();
|
|
2709
|
+
await dialog.getByTestId('resource-file-input').setInputFiles(filePath);
|
|
2710
|
+
await dialog.getByRole('button', { name: /^Upload$/ }).click();
|
|
2711
|
+
await test$1.expect(page.getByText('Resource uploaded', { exact: false })).toBeVisible({
|
|
2712
|
+
timeout: 30000,
|
|
2713
|
+
});
|
|
2714
|
+
await test$1.expect(dialog).toBeHidden({ timeout: 5000 });
|
|
2715
|
+
logger.info(`Uploaded asset resource from "${filePath}"`);
|
|
2716
|
+
}
|
|
2717
|
+
/**
|
|
2718
|
+
* Open a resource row's three-dots menu. The menu content portals to
|
|
2719
|
+
* document.body (above the dialog), so the returned locator is page-level.
|
|
2720
|
+
*/
|
|
2721
|
+
async function openResourceActionsMenu(page, resourcesSection, filename) {
|
|
2722
|
+
await resourceRow(resourcesSection, filename)
|
|
2723
|
+
.getByRole('button', { name: `${filename} actions` })
|
|
2724
|
+
.click();
|
|
2725
|
+
const menu = page.getByRole('menu');
|
|
2726
|
+
await test$1.expect(menu).toBeVisible({ timeout: 5000 });
|
|
2727
|
+
return menu;
|
|
2728
|
+
}
|
|
2729
|
+
/**
|
|
2730
|
+
* Edit a text resource in place via its row menu ("Edit Resource" dialog).
|
|
2731
|
+
*/
|
|
2732
|
+
async function editTextResource(page, resourcesSection, filename, updates) {
|
|
2733
|
+
const menu = await openResourceActionsMenu(page, resourcesSection, filename);
|
|
2734
|
+
await menu.getByRole('menuitem', { name: /^Edit$/ }).click();
|
|
2735
|
+
const dialog = page.getByRole('dialog', { name: 'Edit Resource' });
|
|
2736
|
+
await test$1.expect(dialog).toBeVisible({ timeout: 5000 });
|
|
2737
|
+
if (updates.filename !== undefined) {
|
|
2738
|
+
await dialog.getByLabel('File Name', { exact: true }).fill(updates.filename);
|
|
2739
|
+
}
|
|
2740
|
+
if (updates.content !== undefined) {
|
|
2741
|
+
await dialog.getByLabel('Content', { exact: true }).fill(updates.content);
|
|
2742
|
+
}
|
|
2743
|
+
await dialog.getByRole('button', { name: /^Save$/ }).click();
|
|
2744
|
+
await test$1.expect(page.getByText('Resource saved', { exact: false })).toBeVisible({
|
|
2745
|
+
timeout: 10000,
|
|
2746
|
+
});
|
|
2747
|
+
await test$1.expect(dialog).toBeHidden({ timeout: 5000 });
|
|
2748
|
+
logger.info(`Edited resource "${filename}"`);
|
|
2749
|
+
}
|
|
2750
|
+
/**
|
|
2751
|
+
* Delete a resource row via its menu, confirming the "Delete Resource"
|
|
2752
|
+
* dialog. Waits for the toast and for the row to disappear.
|
|
2753
|
+
*/
|
|
2754
|
+
async function deleteResource(page, resourcesSection, filename) {
|
|
2755
|
+
const menu = await openResourceActionsMenu(page, resourcesSection, filename);
|
|
2756
|
+
await menu.getByRole('menuitem', { name: /^Delete$/ }).click();
|
|
2757
|
+
const confirm = page.getByRole('dialog', { name: 'Delete Resource' });
|
|
2758
|
+
await test$1.expect(confirm).toBeVisible({ timeout: 5000 });
|
|
2759
|
+
await confirm.getByRole('button', { name: /^Delete$/ }).click();
|
|
2760
|
+
await test$1.expect(page.getByText('Resource deleted', { exact: false })).toBeVisible({
|
|
2761
|
+
timeout: 10000,
|
|
2762
|
+
});
|
|
2763
|
+
await test$1.expect(confirm).toBeHidden({ timeout: 5000 });
|
|
2764
|
+
await test$1.expect(resourceRow(resourcesSection, filename)).toBeHidden({ timeout: 10000 });
|
|
2765
|
+
logger.info(`Deleted resource "${filename}"`);
|
|
2766
|
+
}
|
|
2767
|
+
// ============================
|
|
2768
|
+
// Chat `/` Skill Picker
|
|
2769
|
+
// ============================
|
|
2770
|
+
/**
|
|
2771
|
+
* Type a `/` query into the chat composer and wait for the skill picker
|
|
2772
|
+
* listbox to open (its lazy fetch may show a loading row first on cold
|
|
2773
|
+
* cache — waiting on the listbox element covers both paths).
|
|
2774
|
+
*/
|
|
2775
|
+
async function openSlashSkillPicker(page, query = '/') {
|
|
2776
|
+
const composer = page.locator('#chat-input-textarea');
|
|
2777
|
+
await test$1.expect(composer).toBeVisible({ timeout: 10000 });
|
|
2778
|
+
await composer.click();
|
|
2779
|
+
await composer.fill(query);
|
|
2780
|
+
await test$1.expect(page.getByTestId('slash-skill-picker')).toBeVisible({ timeout: 15000 });
|
|
2781
|
+
logger.info(`Slash skill picker open for query "${query}"`);
|
|
2782
|
+
}
|
|
2783
|
+
/**
|
|
2784
|
+
* Pick a skill from the open `/` picker by its visible name. The picker
|
|
2785
|
+
* closes and the composer is left holding the inserted `/slug ` invocation.
|
|
2786
|
+
*/
|
|
2787
|
+
async function selectSlashSkill(page, skillName) {
|
|
2788
|
+
const picker = page.getByTestId('slash-skill-picker');
|
|
2789
|
+
await picker.getByRole('option', { name: new RegExp(skillName, 'i') }).click();
|
|
2790
|
+
await test$1.expect(picker).toBeHidden({ timeout: 5000 });
|
|
2791
|
+
logger.info(`Selected slash skill "${skillName}"`);
|
|
2543
2792
|
}
|
|
2544
2793
|
|
|
2545
2794
|
// ============================
|
|
@@ -6951,6 +7200,8 @@ exports.addGraderCriterion = addGraderCriterion;
|
|
|
6951
7200
|
exports.addManualScore = addManualScore;
|
|
6952
7201
|
exports.addMemory = addMemory;
|
|
6953
7202
|
exports.addQaPairsManually = addQaPairsManually;
|
|
7203
|
+
exports.addSkillToAgent = addSkillToAgent;
|
|
7204
|
+
exports.addTextResource = addTextResource;
|
|
6954
7205
|
exports.archiveFirstMemory = archiveFirstMemory;
|
|
6955
7206
|
exports.archiveMemoryByContent = archiveMemoryByContent;
|
|
6956
7207
|
exports.billingAutoRechargeSection = billingAutoRechargeSection;
|
|
@@ -7011,6 +7262,7 @@ exports.deleteInstance = deleteInstance;
|
|
|
7011
7262
|
exports.deleteKey = deleteKey;
|
|
7012
7263
|
exports.deleteMemoryByContent = deleteMemoryByContent;
|
|
7013
7264
|
exports.deleteQaItem = deleteQaItem;
|
|
7265
|
+
exports.deleteResource = deleteResource;
|
|
7014
7266
|
exports.deleteSkill = deleteSkill;
|
|
7015
7267
|
exports.deleteTask = deleteTask;
|
|
7016
7268
|
exports.disableSkill = disableSkill;
|
|
@@ -7021,6 +7273,7 @@ exports.editGraderCriterion = editGraderCriterion;
|
|
|
7021
7273
|
exports.editInstance = editInstance;
|
|
7022
7274
|
exports.editLink = editLink;
|
|
7023
7275
|
exports.editSkill = editSkill;
|
|
7276
|
+
exports.editTextResource = editTextResource;
|
|
7024
7277
|
exports.editTool = editTool;
|
|
7025
7278
|
exports.enableSkill = enableSkill;
|
|
7026
7279
|
exports.enableSupport = enableSupport;
|
|
@@ -7217,6 +7470,7 @@ exports.goToLastPage = goToLastPage;
|
|
|
7217
7470
|
exports.goToNextPage = goToNextPage;
|
|
7218
7471
|
exports.goToPage = goToPage;
|
|
7219
7472
|
exports.goToPreviousPage = goToPreviousPage;
|
|
7473
|
+
exports.goToSkillsListPage = goToSkillsListPage;
|
|
7220
7474
|
exports.graderTabBody = graderTabBody;
|
|
7221
7475
|
exports.inviteUserTest = inviteUserTest;
|
|
7222
7476
|
exports.isEvaluationTabVisible = isEvaluationTabVisible;
|
|
@@ -7275,6 +7529,7 @@ exports.openRunResults = openRunResults;
|
|
|
7275
7529
|
exports.openScheduleTaskDialog = openScheduleTaskDialog;
|
|
7276
7530
|
exports.openScreenSharePromptEditor = openScreenSharePromptEditor;
|
|
7277
7531
|
exports.openSkillActionsMenu = openSkillActionsMenu;
|
|
7532
|
+
exports.openSlashSkillPicker = openSlashSkillPicker;
|
|
7278
7533
|
exports.openStartEvaluationDialog = openStartEvaluationDialog;
|
|
7279
7534
|
exports.openTicket = openTicket;
|
|
7280
7535
|
exports.overrideGradeResult = overrideGradeResult;
|
|
@@ -7290,6 +7545,7 @@ exports.refreshEvaluationDetail = refreshEvaluationDetail;
|
|
|
7290
7545
|
exports.refreshTickets = refreshTickets;
|
|
7291
7546
|
exports.reliableClick = reliableClick;
|
|
7292
7547
|
exports.reliableFill = reliableFill;
|
|
7548
|
+
exports.removeSkillFromAgent = removeSkillFromAgent;
|
|
7293
7549
|
exports.removeTraceScore = removeTraceScore;
|
|
7294
7550
|
exports.renameKey = renameKey;
|
|
7295
7551
|
exports.replyToTicket = replyToTicket;
|
|
@@ -7316,6 +7572,7 @@ exports.selectLLMModel = selectLLMModel;
|
|
|
7316
7572
|
exports.selectLlmProvider = selectLlmProvider;
|
|
7317
7573
|
exports.selectPrivacyAction = selectPrivacyAction;
|
|
7318
7574
|
exports.selectPrivateMode = selectPrivateMode;
|
|
7575
|
+
exports.selectSlashSkill = selectSlashSkill;
|
|
7319
7576
|
exports.selectSttProvider = selectSttProvider;
|
|
7320
7577
|
exports.selectTaskInList = selectTaskInList;
|
|
7321
7578
|
exports.selectToolKeySetMode = selectToolKeySetMode;
|
|
@@ -7358,6 +7615,8 @@ exports.submitLinkModal = submitLinkModal;
|
|
|
7358
7615
|
exports.submitLlmJudge = submitLlmJudge;
|
|
7359
7616
|
exports.submitToolModal = submitToolModal;
|
|
7360
7617
|
exports.switchToAddItemsSubTab = switchToAddItemsSubTab;
|
|
7618
|
+
exports.switchToAgentSkillsSubTab = switchToAgentSkillsSubTab;
|
|
7619
|
+
exports.switchToAvailableSkillsSubTab = switchToAvailableSkillsSubTab;
|
|
7361
7620
|
exports.switchToEvaluationTab = switchToEvaluationTab;
|
|
7362
7621
|
exports.switchToGraderSubTab = switchToGraderSubTab;
|
|
7363
7622
|
exports.switchToGraderTab = switchToGraderTab;
|
|
@@ -7368,6 +7627,7 @@ exports.switchToPrivacyTab = switchToPrivacyTab;
|
|
|
7368
7627
|
exports.switchToPrivateModeTab = switchToPrivateModeTab;
|
|
7369
7628
|
exports.switchToSandboxTab = switchToSandboxTab;
|
|
7370
7629
|
exports.switchToScreenShareTab = switchToScreenShareTab;
|
|
7630
|
+
exports.switchToSkillResourcesSubTab = switchToSkillResourcesSubTab;
|
|
7371
7631
|
exports.switchToSkillsTab = switchToSkillsTab;
|
|
7372
7632
|
exports.switchToSupportTab = switchToSupportTab;
|
|
7373
7633
|
exports.switchToTasksTab = switchToTasksTab;
|
|
@@ -7379,8 +7639,10 @@ exports.toggleAutoPush = toggleAutoPush;
|
|
|
7379
7639
|
exports.toggleMemorySwitch = toggleMemorySwitch;
|
|
7380
7640
|
exports.toggleSkill = toggleSkill;
|
|
7381
7641
|
exports.toolFields = toolFields;
|
|
7642
|
+
exports.uploadAssetResource = uploadAssetResource;
|
|
7382
7643
|
exports.uploadQaCsv = uploadQaCsv;
|
|
7383
7644
|
exports.verifyAgentConfigPromptsVisible = verifyAgentConfigPromptsVisible;
|
|
7645
|
+
exports.verifyAgentSkillsEmptyState = verifyAgentSkillsEmptyState;
|
|
7384
7646
|
exports.verifyAuditLogEmptyState = verifyAuditLogEmptyState;
|
|
7385
7647
|
exports.verifyAuditLogEntryStructure = verifyAuditLogEntryStructure;
|
|
7386
7648
|
exports.verifyAuditLogGenericError = verifyAuditLogGenericError;
|
|
@@ -7400,6 +7662,7 @@ exports.verifyMemoryNotExists = verifyMemoryNotExists;
|
|
|
7400
7662
|
exports.verifyMemoryTabMemoriesList = verifyMemoryTabMemoriesList;
|
|
7401
7663
|
exports.verifyMemoryTabSettings = verifyMemoryTabSettings;
|
|
7402
7664
|
exports.verifyPreparingPhase = verifyPreparingPhase;
|
|
7665
|
+
exports.verifySkillAdded = verifySkillAdded;
|
|
7403
7666
|
exports.verifySkillVisible = verifySkillVisible;
|
|
7404
7667
|
exports.verifySkillsEmptyState = verifySkillsEmptyState;
|
|
7405
7668
|
exports.verifySkillsTabVisible = verifySkillsTabVisible;
|