From ad8379fffaa6f15c17e0c161512294a48ce1a398 Mon Sep 17 00:00:00 2001 From: Endri Bezati Date: Sun, 8 Nov 2026 23:11:18 +0100 Subject: [PATCH 1/2] chore: remove the @path editor and the agent and tool keys nothing reads No producer has a `@path` decorator: wfpy's `path` is an argument of `@viewer`. The property panel's `@path` editor never rendered, and the annotation wizard's template wrote `@path(paths=[...])`, which makes the Python source fail to import. Both go; a `path` annotation a project defines itself falls through to the generic editor like any custom annotation. Also removed, each with no reader anywhere in the platform or the products: `wf:toolSpec` on tool nodes (the external-actor flag it set alongside stays), `cal:agentStateful` and `WorkflowDiagramMetadata.AGENT_STATEFUL`, the model storage's never-called `clearAgentContextMetadata`, and the property panel's `createTabs` and `inlineMarkdown`. First step of moving wfpy's own features out of the platform: what has no reader is deleted before the rest moves to wfpy-ide. Claude-Session: https://claude.ai/code/session_01EToj6RJRMSSHQiqGNMU9wv --- CHANGELOG.md | 9 + .../src/editing-action-handlers.ts | 36 --- packages/diagram-client/src/property-panel.ts | 207 +----------------- .../src/model/graph-gmodel-source.ts | 1 - .../src/server/source-model-storage.ts | 41 ---- packages/shared/src/diagram-types.ts | 2 - 6 files changed, 11 insertions(+), 285 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d93ed18..2579625 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,15 @@ platform API version. ### Removed +- **The `@path` annotation editor and its wizard template.** No producer has + a `@path` decorator (wfpy's `path` is an argument of `@viewer`), so the + property panel's editor never rendered, and the wizard's template wrote a + decorator the Python source cannot import. A `path` annotation a project + defines itself still opens in the generic editor. +- **Agent and tool keys nothing reads**: `wf:toolSpec` on tool nodes (the + external-actor flag stays), `cal:agentStateful` and its constant, the + never-called agent-metadata reset in the model storage, and the property + panel's unused tab builder and inline-Markdown renderer. - **Element types the model never emits**, with their client classes and views, server mappings, shape hints and layout branches: `node:proxy`, the two collapsed nodes, the if-branch, if-join, foreach-join and inline-if diff --git a/packages/diagram-client/src/editing-action-handlers.ts b/packages/diagram-client/src/editing-action-handlers.ts index f928554..29da2e4 100644 --- a/packages/diagram-client/src/editing-action-handlers.ts +++ b/packages/diagram-client/src/editing-action-handlers.ts @@ -590,7 +590,6 @@ export class WorkflowEditAnnotationsActionHandler implements IActionHandler { items: [ { id: 'tool', label: '@tool (external execution)', description: 'cmd, args, inheritStdio, ...' }, { id: 'viewer', label: '@viewer (open outputs in VS Code)', description: 'open, diff, openWith (viewType)' }, - { id: 'path', label: '@path (external tool search paths)', description: 'paths=["./bin", "./tools"]' }, { id: 'custom', label: 'Custom annotation…', description: 'Enter any name and arguments' } ], placeHolder: 'Choose an annotation template' @@ -725,41 +724,6 @@ export class WorkflowEditAnnotationsActionHandler implements IActionHandler { if (title === undefined) return; annotationText = `@viewer(\n action="diff",\n inputs=${inputsExpr.trim()},\n token="last",\n title=${toWfStringLiteral(title)}\n)`; } - } else if (template === 'path') { - annotationName = 'path'; - - const paths: string[] = []; - - for (;;) { - const next = await VscodeUi.instance.inputBox({ - prompt: paths.length === 0 ? 'Add path (e.g. ./bin)' : 'Add another path (optional)' - }); - if (next === undefined) return; - const trimmed = next.trim(); - if (trimmed) { - paths.push(trimmed); - } - - if (paths.length === 0) { - continue; - } - - const addMore = await VscodeUi.instance.quickPick({ - items: [ - { id: 'yes', label: 'Add another path' }, - { id: 'no', label: 'Done' } - ], - placeHolder: 'Add another path?' - }); - if (addMore !== 'yes') { - break; - } - } - - if (paths.length === 0) return; - - const listExpr = `[${paths.map(p => toWfStringLiteral(p)).join(', ')}]`; - annotationText = `@path(\n paths=${listExpr}\n)`; } else { const name = await VscodeUi.instance.inputBox({ prompt: 'Annotation name (without @)', diff --git a/packages/diagram-client/src/property-panel.ts b/packages/diagram-client/src/property-panel.ts index 029916d..64a89bd 100644 --- a/packages/diagram-client/src/property-panel.ts +++ b/packages/diagram-client/src/property-panel.ts @@ -494,42 +494,6 @@ export class PropertyPanel implements ISelectionListener, IGModelRootListener { container?.lastElementChild?.scrollIntoView({ behavior: 'smooth', block: 'end' }); } - protected createTabs(container: HTMLElement, tabs: Array<{ id: string, label: string, buildContent: (content: HTMLElement) => void }>): void { - const header = document.createElement('div'); - header.className = 'property-tabs-header'; - - const bodyWrap = document.createElement('div'); - bodyWrap.style.flex = '1'; - bodyWrap.style.overflowY = 'auto'; - - let first = true; - for (const tab of tabs) { - const btn = document.createElement('button'); - btn.className = 'property-tab-btn' + (first ? ' active' : ''); - btn.textContent = tab.label; - - const tabContent = document.createElement('div'); - tabContent.className = 'property-tab-content' + (first ? ' active' : ''); - tabContent.dataset.tabId = tab.id; - - btn.addEventListener('click', () => { - Array.from(header.querySelectorAll('.property-tab-btn')).forEach(b => b.classList.remove('active')); - Array.from(bodyWrap.querySelectorAll('.property-tab-content')).forEach(c => c.classList.remove('active')); - btn.classList.add('active'); - tabContent.classList.add('active'); - }); - - tab.buildContent(tabContent); - - header.appendChild(btn); - bodyWrap.appendChild(tabContent); - first = false; - } - - container.appendChild(header); - container.appendChild(bodyWrap); - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any protected updateContentForNode(node: any, content: HTMLElement, requestAgentDiscovery = true): void { const args = node.args || {}; @@ -938,13 +902,6 @@ export class PropertyPanel implements ISelectionListener, IGModelRootListener { return renderMarkdownSafe(md); } - /** - * Convert inline markdown (bold, italic, code, links) to sanitized HTML. - */ - protected inlineMarkdown(text: string): string { - return renderInlineMarkdownSafe(text); - } - /** * Shorten a file path to just the last 2 path segments for display. */ @@ -3557,171 +3514,11 @@ export class PropertyPanel implements ISelectionListener, IGModelRootListener { body.appendChild(backendGrid); } - if (name === 'path') { - if (argsMap.has('path') && !argsMap.has('paths')) { - argsMap.set('paths', argsMap.get('path') ?? ''); - argsMap.delete('path'); - } - - const pathsContainer = document.createElement('div'); - pathsContainer.className = 'annotation-args-container'; - - const pathsHeader = document.createElement('div'); - pathsHeader.className = 'annotation-args-header'; - - const pathsTitle = document.createElement('div'); - pathsTitle.className = 'annotation-args-title'; - pathsTitle.textContent = 'paths (list)'; - - const pathsMode = document.createElement('div'); - pathsMode.className = 'annotation-args-mode'; - - const toRawBtn = document.createElement('button'); - toRawBtn.type = 'button'; - toRawBtn.className = 'mini-btn'; - toRawBtn.textContent = 'Raw…'; - - const toListBtn = document.createElement('button'); - toListBtn.type = 'button'; - toListBtn.className = 'mini-btn'; - toListBtn.textContent = 'List…'; - - pathsMode.appendChild(toListBtn); - pathsMode.appendChild(toRawBtn); - pathsHeader.appendChild(pathsTitle); - pathsHeader.appendChild(pathsMode); - - const pathsHelp = document.createElement('div'); - pathsHelp.className = 'annotation-args-help'; - pathsHelp.textContent = 'Each row is a directory path (string literal).'; - - const pathsList = document.createElement('div'); - pathsList.className = 'annotation-args-list'; - - const addPathBtn = document.createElement('button'); - addPathBtn.type = 'button'; - addPathBtn.className = 'mini-btn'; - addPathBtn.textContent = 'Add path'; - - const rawRow = document.createElement('div'); - rawRow.className = 'annotation-field'; - const rawLabel = document.createElement('div'); - rawLabel.className = 'annotation-label'; - rawLabel.textContent = 'paths (expression)'; - const rawTextarea = document.createElement('textarea'); - rawTextarea.className = 'annotation-input annotation-textarea'; - rawTextarea.rows = 3; - rawTextarea.placeholder = 'e.g. ["./bin", "./tools"]'; - rawRow.appendChild(rawLabel); - rawRow.appendChild(rawTextarea); - - let pathItems: string[] = []; - let mode: 'list' | 'raw' = 'list'; - - const renderPathList = () => { - pathsList.innerHTML = ''; - pathItems.forEach((val, idx) => { - const row = document.createElement('div'); - row.className = 'annotation-args-item'; - - const idxEl = document.createElement('div'); - idxEl.className = 'annotation-args-index'; - idxEl.textContent = String(idx); - - const inp = document.createElement('input'); - inp.className = 'annotation-input annotation-args-input'; - inp.value = val; - inp.placeholder = 'path'; - inp.addEventListener('input', () => { - pathItems[idx] = inp.value; - argsMap.set('paths', this.serializeWfStringListExpr(pathItems)); - }); - - const rm = document.createElement('button'); - rm.type = 'button'; - rm.className = 'mini-btn danger icon-only'; - rm.title = 'Remove path'; - rm.setAttribute('aria-label', 'Remove path'); - const rmIcon = document.createElement('span'); - rmIcon.className = 'codicon codicon-remove'; - rm.appendChild(rmIcon); - rm.addEventListener('click', () => { - pathItems.splice(idx, 1); - argsMap.set('paths', this.serializeWfStringListExpr(pathItems)); - renderPathList(); - }); - - row.appendChild(idxEl); - row.appendChild(inp); - row.appendChild(rm); - pathsList.appendChild(row); - }); - }; - - const setMode = (next: 'list' | 'raw') => { - mode = next; - const showList = mode === 'list'; - pathsList.style.display = showList ? '' : 'none'; - addPathBtn.style.display = showList ? '' : 'none'; - pathsHelp.style.display = showList ? '' : 'none'; - rawRow.style.display = showList ? 'none' : ''; - }; - - addPathBtn.addEventListener('click', () => { - pathItems.push(''); - argsMap.set('paths', this.serializeWfStringListExpr(pathItems)); - renderPathList(); - }); - - rawTextarea.addEventListener('input', () => { - argsMap.set('paths', rawTextarea.value); - }); - - toRawBtn.addEventListener('click', () => { - rawTextarea.value = argsMap.get('paths') ?? ''; - setMode('raw'); - }); - - toListBtn.addEventListener('click', () => { - const parsed = this.tryParseWfStringListExpr(argsMap.get('paths') ?? ''); - if (!parsed) { - VscodeUi.instance.infoMessage('Cannot switch to list mode: paths is not a list of string literals.'); - setMode('raw'); - return; - } - pathItems = parsed; - argsMap.set('paths', this.serializeWfStringListExpr(pathItems)); - renderPathList(); - setMode('list'); - }); - - const initialPathsExpr = argsMap.get('paths') ?? ''; - const parsed = this.tryParseWfStringListExpr(initialPathsExpr); - if (parsed) { - pathItems = parsed; - argsMap.set('paths', this.serializeWfStringListExpr(pathItems)); - renderPathList(); - setMode('list'); - } else { - rawTextarea.value = initialPathsExpr; - setMode('raw'); - } - - pathsContainer.appendChild(pathsHeader); - pathsContainer.appendChild(pathsHelp); - pathsContainer.appendChild(pathsList); - pathsContainer.appendChild(addPathBtn); - pathsContainer.appendChild(rawRow); - body.appendChild(pathsContainer); - } - // Show remaining args (custom annotation args, or tool extras) const reserved = new Set( name === 'tool' ? ['cmd', 'args', 'inheritStdio'] - : (name === 'path' - ? ['paths', 'path'] - : (name === 'agent' ? [ + : (name === 'agent' ? [ // Identity / model 'prompt', 'claudeAgent', 'skill', 'model', 'provider', 'endpoint', 'timeoutMs', 'contextBudget', 'stateful', @@ -3736,7 +3533,7 @@ export class PropertyPanel implements ISelectionListener, IGModelRootListener { 'lspLanguageId', 'lspExtraFlags', 'lspPort', 'lspSeverityThreshold', 'lspMaxRepairAttempts', // Output validators editor 'outputValidators' - ] : [])) + ] : []) ); // Remaining args = genuinely custom annotation args (no dedicated control // above). Each renders as an editable key/value row with its own remove button; diff --git a/packages/diagram-server/src/model/graph-gmodel-source.ts b/packages/diagram-server/src/model/graph-gmodel-source.ts index 62a6ed4..b0be471 100644 --- a/packages/diagram-server/src/model/graph-gmodel-source.ts +++ b/packages/diagram-server/src/model/graph-gmodel-source.ts @@ -552,7 +552,6 @@ export class GraphGModelSource { if (node.meta['tool']) { gnode.args = { ...(gnode.args ?? {}), - 'wf:toolSpec': node.meta['tool'], [WorkflowDiagramMetadata.IS_EXTERNAL_ACTOR]: true }; } diff --git a/packages/diagram-server/src/server/source-model-storage.ts b/packages/diagram-server/src/server/source-model-storage.ts index 0bb2564..21e9e8f 100644 --- a/packages/diagram-server/src/server/source-model-storage.ts +++ b/packages/diagram-server/src/server/source-model-storage.ts @@ -1523,46 +1523,6 @@ export class WorkflowSourceModelStorage implements SourceModelStorage { visit(root); } - /** - * Remove all agent context metadata from GNodes so it can be cleanly re-applied - * without leftover data from a previous cycle. - * - * Note: execution-glow state (`IS_EXECUTING`, `cal-node-active` CSS) is NOT cleared - * here. It is cleared synchronously inside `applyViewerOverlayToEdges()` right before - * the new overlay is applied. This avoids a race condition where a stale - * `ComputedBoundsAction` arriving between the `await` gap (clear ↔ overlay read) - * could submit the model without the active-glow CSS class, causing the glow to - * flicker/disappear. - */ - private clearAgentContextMetadata(root: GModelRoot): void { - const agentKeys: string[] = [ - WorkflowDiagramMetadata.AGENT_CHAT_HISTORY, - WorkflowDiagramMetadata.AGENT_FIRE_COUNT, - WorkflowDiagramMetadata.AGENT_CONTEXT_BUDGET, - WorkflowDiagramMetadata.AGENT_TRUNCATION_STRATEGY, - WorkflowDiagramMetadata.AGENT_MODEL, - WorkflowDiagramMetadata.AGENT_STATEFUL, - WorkflowDiagramMetadata.AGENT_SKILL_STATUS, - ]; - const visit = (element: any): void => { - if (element instanceof GNode) { - const args = element.args as Record | undefined; - if (args) { - for (const key of agentKeys) { - delete args[key]; - } - } - } - const children = element.children as any[] | undefined; - if (Array.isArray(children)) { - for (const child of children) { - visit(child); - } - } - }; - visit(root); - } - /** * Tracks the in-flight deferred agent-enrichment discovery so tests can await it. Not used for * correctness in production (fire-and-forget); convergence relies on the warm cache, not this @@ -1985,7 +1945,6 @@ export class WorkflowSourceModelStorage implements SourceModelStorage { if (entry.model) { (element.args as any)[WorkflowDiagramMetadata.AGENT_MODEL] = entry.model; } - (element.args as any)[WorkflowDiagramMetadata.AGENT_STATEFUL] = entry.stateful; } } const children = element.children as any[] | undefined; diff --git a/packages/shared/src/diagram-types.ts b/packages/shared/src/diagram-types.ts index abdcb2d..f0ed19b 100644 --- a/packages/shared/src/diagram-types.ts +++ b/packages/shared/src/diagram-types.ts @@ -317,8 +317,6 @@ export namespace WorkflowDiagramMetadata { export const AGENT_TRUNCATION_STRATEGY = 'cal:agentTruncationStrategy'; /** Model identifier (e.g. "openai/gpt-5-mini"). */ export const AGENT_MODEL = 'cal:agentModel'; - /** Whether the agent is stateful. */ - export const AGENT_STATEFUL = 'cal:agentStateful'; /** Skill status summary for agent node. */ export const AGENT_SKILL_STATUS = 'cal:agentSkillStatus'; From 191358e1d07e9884619c67e47f16e74a6b0b824d Mon Sep 17 00:00:00 2001 From: Endri Bezati Date: Sun, 8 Nov 2026 23:15:41 +0100 Subject: [PATCH 2/2] fix: what the review of the dead-leftovers removal turned up - The agent-context section appended to a tab only the removed `createTabs` built; it now appends to the panel content directly, which is where it always landed. - The tab stylesheet rules (and their theme overrides) styled nothing once `createTabs` was gone; removed, with their rows in the selector baseline. - `renderInlineMarkdownSafe` had one caller, the removed `inlineMarkdown`. - The agent-context entry types still declared `stateful`, now unread. - The changelog gave the wrong reason for the `@path` template: wfpy does set tool search paths, with `@config(path=[...])`; the template wrote a decorator that does not exist for it. - The agent reserved-key list is indented as the expression it now is. Claude-Session: https://claude.ai/code/session_01EToj6RJRMSSHQiqGNMU9wv --- CHANGELOG.md | 17 +++-- packages/diagram-client/src/markdown.ts | 5 -- .../diagram-client/src/property-panel.css | 76 ------------------- packages/diagram-client/src/property-panel.ts | 34 ++++----- .../fixtures/property-selectors-baseline.json | 7 -- .../test/run-agent-outputs-render.test.ts | 1 - .../src/server/source-model-storage.ts | 4 - 7 files changed, 26 insertions(+), 118 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2579625..cf09f96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,14 +9,17 @@ platform API version. ### Removed - **The `@path` annotation editor and its wizard template.** No producer has - a `@path` decorator (wfpy's `path` is an argument of `@viewer`), so the - property panel's editor never rendered, and the wizard's template wrote a - decorator the Python source cannot import. A `path` annotation a project - defines itself still opens in the generic editor. + a `@path` decorator: wfpy sets a workflow's tool search paths with + `@config(path=[...])`. The property panel's editor never rendered, and the + wizard's "external tool search paths" template wrote `@path(...)`, which the + Python source cannot import. A `path` annotation a project defines itself + still opens in the generic editor. - **Agent and tool keys nothing reads**: `wf:toolSpec` on tool nodes (the - external-actor flag stays), `cal:agentStateful` and its constant, the - never-called agent-metadata reset in the model storage, and the property - panel's unused tab builder and inline-Markdown renderer. + external-actor flag stays), `cal:agentStateful` and its constant + `WorkflowDiagramMetadata.AGENT_STATEFUL` (a removal from the shared API, for + the next minor version), the never-called agent-metadata reset in the model + storage, and the property panel's unused tab builder with its stylesheet + rules, and its inline-Markdown renderer with the helper only it called. - **Element types the model never emits**, with their client classes and views, server mappings, shape hints and layout branches: `node:proxy`, the two collapsed nodes, the if-branch, if-join, foreach-join and inline-if diff --git a/packages/diagram-client/src/markdown.ts b/packages/diagram-client/src/markdown.ts index 2267d1b..4332697 100644 --- a/packages/diagram-client/src/markdown.ts +++ b/packages/diagram-client/src/markdown.ts @@ -24,11 +24,6 @@ export function renderDocumentMarkdownSafe(src: string): string { return DOMPurify.sanitize(documentMd.render(src)); } -/** Render inline Markdown (no block wrapping) to sanitized HTML. */ -export function renderInlineMarkdownSafe(src: string): string { - return DOMPurify.sanitize(md.renderInline(src)); -} - /** * Cheap heuristic for "is this worth rendering as Markdown?" — used to keep * plain text in pre-wrap form instead of paying markdown layout for it. diff --git a/packages/diagram-client/src/property-panel.css b/packages/diagram-client/src/property-panel.css index 490297f..265f336 100644 --- a/packages/diagram-client/src/property-panel.css +++ b/packages/diagram-client/src/property-panel.css @@ -47,64 +47,6 @@ container-name: pp-panel; } -/* ============================================ - Property Panel Tabs - ============================================ */ - -.property-tabs-header { - position: sticky; - top: 0; - z-index: 10; - display: flex; - flex-direction: row; - overflow-x: auto; - border-bottom: 1px solid var(--vscode-panel-border); - background: var(--vscode-editorGroupHeader-tabsBackground, #2d2d2d); - -ms-overflow-style: none; - scrollbar-width: none; - flex-shrink: 0; -} - -.property-tabs-header::-webkit-scrollbar { - display: none; -} - -.property-tab-btn { - flex: 0 0 auto; - padding: 8px 12px; - background: transparent; - border: none; - border-bottom: 1px solid transparent; - color: var(--vscode-tab-inactiveForeground, #8b8b8b); - cursor: pointer; - font-size: 11px; - font-weight: 600; - letter-spacing: 0.3px; - text-transform: uppercase; - transition: color 0.15s ease, border-color 0.15s ease; - outline: none; -} - -.property-tab-btn:hover { - color: var(--vscode-tab-hoverForeground, #cccccc); - background: var(--vscode-list-hoverBackground, rgba(90, 93, 94, 0.31)); -} - -.property-tab-btn.active { - color: var(--vscode-tab-activeForeground, #ffffff); - border-bottom: 1px solid var(--vscode-focusBorder, #007fd4); -} - -.property-tab-content { - display: none; - flex-direction: column; - height: 100%; -} - -.property-tab-content.active { - display: flex; -} - .property-panel.collapsed { transform: translateX(-100%); } @@ -588,24 +530,6 @@ letter-spacing: 0.6px; } -/* Tabs: minimal, accent underline. */ -.property-tabs-header { - background: transparent; - border-bottom: 1px solid var(--pp-border); -} -.property-tab-btn { - color: var(--pp-muted); - border-bottom-color: transparent; -} -.property-tab-btn:hover { - color: var(--vscode-foreground); - background: transparent; -} -.property-tab-btn.active { - color: var(--vscode-foreground); - border-bottom-color: var(--pp-accent); -} - /* Sections: plain header (no fill), hairline separators between sections. */ .property-section { border-bottom: 1px solid var(--pp-border); diff --git a/packages/diagram-client/src/property-panel.ts b/packages/diagram-client/src/property-panel.ts index 64a89bd..3331e9d 100644 --- a/packages/diagram-client/src/property-panel.ts +++ b/packages/diagram-client/src/property-panel.ts @@ -4,7 +4,6 @@ import { ISelectionListener, IActionDispatcher, TYPES } from '@eclipse-glsp/clie import { renderMarkdownSafe, renderDocumentMarkdownSafe, - renderInlineMarkdownSafe, looksLikeMarkdown as looksLikeMarkdownShared, } from './markdown'; import { html, render, nothing, type TemplateResult } from 'lit'; @@ -353,8 +352,7 @@ export class PropertyPanel implements ISelectionListener, IGModelRootListener { const section = this.buildAgentContextSection(args); if (!section) return; - const agentTab = content.querySelector('.property-tab-content[data-tab-id="agent"]') as HTMLElement | null; - (agentTab ?? content).appendChild(section); + content.appendChild(section); this.scrollAgentToLatest(section); } @@ -3519,21 +3517,21 @@ export class PropertyPanel implements ISelectionListener, IGModelRootListener { name === 'tool' ? ['cmd', 'args', 'inheritStdio'] : (name === 'agent' ? [ - // Identity / model - 'prompt', 'claudeAgent', 'skill', 'model', 'provider', 'endpoint', - 'timeoutMs', 'contextBudget', 'stateful', - // Backend / runtime controls (dropdowns above) - 'truncationStrategy', 'fireableWithoutInput', 'transport', 'connector', 'mode', 'cliToolsMode', 'reasoningEffort', - // Sub-block toggles - 'useClaudeAgent', 'useSkill', 'usePrompt', 'useSkillHooks', - // MCP block - 'useMcp', 'mcpServers', 'mcpServerConfigs', 'mcpTransport', - // LSP block (+ shorthand scalars) - 'useLsp', 'lspServers', 'lspServerConfigs', 'lspCommand', 'lspArgs', - 'lspLanguageId', 'lspExtraFlags', 'lspPort', 'lspSeverityThreshold', 'lspMaxRepairAttempts', - // Output validators editor - 'outputValidators' - ] : []) + // Identity / model + 'prompt', 'claudeAgent', 'skill', 'model', 'provider', 'endpoint', + 'timeoutMs', 'contextBudget', 'stateful', + // Backend / runtime controls (dropdowns above) + 'truncationStrategy', 'fireableWithoutInput', 'transport', 'connector', 'mode', 'cliToolsMode', 'reasoningEffort', + // Sub-block toggles + 'useClaudeAgent', 'useSkill', 'usePrompt', 'useSkillHooks', + // MCP block + 'useMcp', 'mcpServers', 'mcpServerConfigs', 'mcpTransport', + // LSP block (+ shorthand scalars) + 'useLsp', 'lspServers', 'lspServerConfigs', 'lspCommand', 'lspArgs', + 'lspLanguageId', 'lspExtraFlags', 'lspPort', 'lspSeverityThreshold', 'lspMaxRepairAttempts', + // Output validators editor + 'outputValidators' + ] : []) ); // Remaining args = genuinely custom annotation args (no dedicated control // above). Each renders as an editable key/value row with its own remove button; diff --git a/packages/diagram-client/test/fixtures/property-selectors-baseline.json b/packages/diagram-client/test/fixtures/property-selectors-baseline.json index 5eb3979..1682907 100644 --- a/packages/diagram-client/test/fixtures/property-selectors-baseline.json +++ b/packages/diagram-client/test/fixtures/property-selectors-baseline.json @@ -135,13 +135,6 @@ ".property-section-header:hover": 3, ".property-section.collapsed .property-section-content": 1, ".property-section.collapsed .property-section-header .section-icon": 1, -".property-tab-btn": 2, -".property-tab-btn.active": 2, -".property-tab-btn:hover": 2, -".property-tab-content": 1, -".property-tab-content.active": 1, -".property-tabs-header": 2, -".property-tabs-header::-webkit-scrollbar": 1, ".property-value": 1, ".property-value.read-only": 1, ".property-value.read-only .mini-btn": 1 diff --git a/packages/diagram-client/test/run-agent-outputs-render.test.ts b/packages/diagram-client/test/run-agent-outputs-render.test.ts index d07d4d1..4a24237 100644 --- a/packages/diagram-client/test/run-agent-outputs-render.test.ts +++ b/packages/diagram-client/test/run-agent-outputs-render.test.ts @@ -11,7 +11,6 @@ import { describe, expect, it, vi } from 'vitest'; vi.mock('../src/markdown', () => ({ renderMarkdownSafe: (src: string) => `${src}`, - renderInlineMarkdownSafe: (src: string) => src, looksLikeMarkdown: () => true })); diff --git a/packages/diagram-server/src/server/source-model-storage.ts b/packages/diagram-server/src/server/source-model-storage.ts index 21e9e8f..f069e13 100644 --- a/packages/diagram-server/src/server/source-model-storage.ts +++ b/packages/diagram-server/src/server/source-model-storage.ts @@ -1895,7 +1895,6 @@ export class WorkflowSourceModelStorage implements SourceModelStorage { const byInstanceName = new Map; @@ -1903,7 +1902,6 @@ export class WorkflowSourceModelStorage implements SourceModelStorage { const byEntityName = new Map; @@ -1976,7 +1974,6 @@ export class WorkflowSourceModelStorage implements SourceModelStorage { entityName: string; fireCount: number; model?: string; - stateful: boolean; contextBudget: number; truncationStrategy: string; chatHistory: Array<{ role: string; content: string }>; @@ -2004,7 +2001,6 @@ export class WorkflowSourceModelStorage implements SourceModelStorage { entityName: string; fireCount: number; model?: string; - stateful: boolean; contextBudget: number; truncationStrategy: string; chatHistory: Array<{ role: string; content: string }>;