mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-05-20 20:13:15 +08:00
Sync CopilotPortal agent files from Tools
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -187,7 +187,7 @@ async function renderFlowChartMermaid(chart, container, onInspect) {
|
||||
|
||||
// Track currently selected TaskNode/CondNode
|
||||
let currentSelectedGroup = null;
|
||||
let currentSelectedOriginalStrokeWidth = null;
|
||||
let currentSelectedOriginalStyle = null;
|
||||
let currentSelectedWorkId = null;
|
||||
|
||||
// Map workId -> DOM group for status updates
|
||||
@@ -196,7 +196,8 @@ async function renderFlowChartMermaid(chart, container, onInspect) {
|
||||
|
||||
// Add click handlers for TaskNode/CondNode elements
|
||||
for (const nodeId of taskNodeIds) {
|
||||
const nodeEl = container.querySelector(`[id^="flowchart-${nodeId}-"]`);
|
||||
// Mermaid 10: id="flowchart-N0-123"; Mermaid 11: id="mermaid-chart-flowchart-N0-0"
|
||||
const nodeEl = container.querySelector(`[id*="flowchart-${nodeId}-"]`);
|
||||
if (!nodeEl) continue;
|
||||
const group = nodeEl.closest("g.node") || nodeEl;
|
||||
group.style.cursor = "pointer";
|
||||
@@ -214,25 +215,26 @@ async function renderFlowChartMermaid(chart, container, onInspect) {
|
||||
|
||||
if (currentSelectedGroup === group) {
|
||||
// Unselect
|
||||
if (shapeEl && currentSelectedOriginalStrokeWidth !== null) {
|
||||
shapeEl.style.strokeWidth = currentSelectedOriginalStrokeWidth;
|
||||
if (shapeEl && currentSelectedOriginalStyle !== null) {
|
||||
shapeEl.setAttribute("style", currentSelectedOriginalStyle);
|
||||
}
|
||||
currentSelectedGroup = null;
|
||||
currentSelectedOriginalStrokeWidth = null;
|
||||
currentSelectedOriginalStyle = null;
|
||||
currentSelectedWorkId = null;
|
||||
if (onInspect) onInspect(null);
|
||||
} else {
|
||||
// Unselect previous
|
||||
if (currentSelectedGroup) {
|
||||
const prevShape = currentSelectedGroup.querySelector("rect, polygon, circle, ellipse, path");
|
||||
if (prevShape && currentSelectedOriginalStrokeWidth !== null) {
|
||||
prevShape.style.strokeWidth = currentSelectedOriginalStrokeWidth;
|
||||
if (prevShape && currentSelectedOriginalStyle !== null) {
|
||||
prevShape.setAttribute("style", currentSelectedOriginalStyle);
|
||||
}
|
||||
}
|
||||
// Select new
|
||||
currentSelectedOriginalStrokeWidth = shapeEl ? (shapeEl.style.strokeWidth || shapeEl.getAttribute("style")?.match(/stroke-width:\s*([^;]+)/)?.[1] || getComputedStyle(shapeEl).strokeWidth) : null;
|
||||
// Select new — save full style string so !important flags are preserved on restore
|
||||
currentSelectedOriginalStyle = shapeEl ? (shapeEl.getAttribute("style") ?? "") : null;
|
||||
if (shapeEl) {
|
||||
shapeEl.style.strokeWidth = "5px";
|
||||
// Use setProperty with "important" to override Mermaid 11's !important inline styles
|
||||
shapeEl.style.setProperty("stroke-width", "5px", "important");
|
||||
}
|
||||
currentSelectedGroup = group;
|
||||
currentSelectedWorkId = wid;
|
||||
|
||||
@@ -99,15 +99,16 @@ async function installJobsEntry(entryValue: Entry): Promise<void> {
|
||||
}
|
||||
const models = await helperGetModels();
|
||||
const validModelIds = new Set(models.map(m => m.id));
|
||||
const modelListText = models.map(m => ` ${m.name} (id: ${m.id}, multiplier: ${m.multiplier})`).join("\n");
|
||||
for (const [category, modelId] of Object.entries(entryValue.models)) {
|
||||
if (!validModelIds.has(modelId)) {
|
||||
throw new Error(`entry.models["${category}"] refers to model "${modelId}" which is not a valid model.`);
|
||||
throw new Error(`entry.models["${category}"] refers to model "${modelId}" which is not a valid model.\nAvailable models:\n${modelListText}`);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < entryValue.drivingSessionRetries.length; i++) {
|
||||
const modelId = entryValue.drivingSessionRetries[i].modelId;
|
||||
if (!validModelIds.has(modelId)) {
|
||||
throw new Error(`entry.drivingSessionRetries[${i}].modelId refers to model "${modelId}" which is not a valid model.`);
|
||||
throw new Error(`entry.drivingSessionRetries[${i}].modelId refers to model "${modelId}" which is not a valid model.\nAvailable models:\n${modelListText}`);
|
||||
}
|
||||
}
|
||||
installedEntry = entryValue;
|
||||
|
||||
@@ -50,7 +50,7 @@ const entryInput: Entry = {
|
||||
models: {
|
||||
driving: "gpt-5-mini",
|
||||
planning: "gpt-5.2",
|
||||
coding: "gpt-5.2-codex",
|
||||
coding: "gpt-5.4",
|
||||
reviewers1: "gpt-5.3-codex",
|
||||
reviewers2: "claude-opus-4.6",
|
||||
reviewers3: "claude-sonnet-4.6"
|
||||
@@ -58,7 +58,7 @@ const entryInput: Entry = {
|
||||
drivingSessionRetries: [
|
||||
{ modelId: "gpt-5-mini", retries: 5 },
|
||||
{ modelId: "gpt-4.1", retries: 5 },
|
||||
{ modelId: "gpt-5.1-codex-mini", retries: 3 },
|
||||
{ modelId: "gpt-5.4-mini", retries: 3 },
|
||||
{ modelId: "claude-haiku-4.5", retries: 3 },
|
||||
],
|
||||
promptVariables: {
|
||||
|
||||
@@ -6,6 +6,25 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const serverScript = path.resolve(__dirname, "..", "dist", "index.js");
|
||||
const windowsHidePatch = path.resolve(__dirname, "windowsHide.cjs");
|
||||
|
||||
// Stop any previously running server so the new one starts with clean state.
|
||||
// Without this, a leftover server with an installed entry would cause false failures.
|
||||
try {
|
||||
await fetch("http://localhost:8888/api/stop");
|
||||
} catch {
|
||||
// No server running, that's fine
|
||||
}
|
||||
// Wait until the old server is gone (port free)
|
||||
for (let i = 0; i < 20; i++) {
|
||||
try {
|
||||
await fetch("http://localhost:8888/api/test");
|
||||
// Still responding — wait a bit more
|
||||
await new Promise((r) => setTimeout(r, 200));
|
||||
} catch {
|
||||
// Connection refused: old server is gone
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn server as detached process in test mode so it runs independently of this script.
|
||||
// On Windows, the Copilot SDK internally spawns node.exe to run its bundled CLI server.
|
||||
// Without windowsHide, each spawn creates a visible console window that steals keyboard focus.
|
||||
|
||||
@@ -47,6 +47,7 @@ Prints the following URL for shortcut:
|
||||
`async installJobsEntry(entry: Entry): Promise<void>;`
|
||||
- Verify if all `entry.model[name]` is a valid model with `helperGetModels`.
|
||||
- Verify if all `entry.drivingSessionRetries[index].modelId` is a valid model with `helperGetModels`.
|
||||
- If a model is not valid, in the error messages a list of all model names, ids and premium multipliers should be listed as well.
|
||||
- Use the entry. It could be `entry` from `jobsData.ts` or whatever.
|
||||
- This function can only be called when no session is running, otherwise throws.
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ Prints the following URL for shortcut:
|
||||
`async installJobsEntry(entry: Entry): Promise<void>;`
|
||||
- Verify if all `entry.model[name]` is a valid model with `helperGetModels`.
|
||||
- Verify if all `entry.drivingSessionRetries[index].modelId` is a valid model with `helperGetModels`.
|
||||
- If a model is not valid, in the error messages a list of all model names, ids and premium multipliers should be listed as well.
|
||||
- Use the entry. It could be `entry` from `jobsData.ts` or whatever.
|
||||
- This function can only be called when no session is running, otherwise throws.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user