测试台改仪表台:启动输入换成一封信;卡片化触发器与大模型;清掉 ⓘ 说教条
**测试台**
· 启动输入不再是「调用参数」表 —— 这条流真实的起法就是客户来信,
界面上就该是一封信(发件人 / 收件人 / 主题 / 正文 / BOM 附件)。
服务端拿**真通道的抽键正则** + **真触发器的装配映射**推出调用入参:
测试台自己不解析邮件,否则试通的是测试台而不是这条流。
抽不出必填就如实报「哪个字段没命中、通道的正则要什么」,不静默起空单。
· 一屏两大块:左选流,右两节 —— 01 输入配置、02 节点指派。
· 起单钮只剩一枚(原来页头一枚、RUN 卡里一枚)。
· 改暗色仪表台:调色板集中在 .g-tb/.g-rig 的一组变量上,
TRACE 那张树 + 甘特的结构一行没动,只是纸变成了面板。
**触发器 / 大模型** 列表改卡片:一条规则、一个实例都要一眼看全
(何时起 · 起哪条流 · 开没开 / 谁家的 · 什么型号 · 密钥绑没绑)。
触发器卡是 div 不是 button —— 卡里还坐着「改规则」那枚真按钮。
**同类卡等高**:底栏钉在卡底、说明恒占两行、卡头一行截断。
实测同一货架内 13 张工具卡、6 张活动卡、3 张模型卡各自完全等高。
**删掉 19 条 ⓘ 说教横幅**(「只列有生效版的包…」那一类)。
留下的是三种:确认带里的影响说明(点了动作才出现,是决策依据)、
warn/ok 的真反馈、以及「X 不存在」这类空态。
删掉入站邮件演练整屏 —— 它验的那两步已经并进测试台的起单路径了。
新增一条接缝测试:通道抽出来的键叫 keys.customerCode,触发器映射也得照这名字取;
哪头改了名字单还是能起,只是入参悄悄变空、流走到 G1 才莫名其妙地停。
四闸绿;契约快照随本提交入库。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
* DOM 结构、类名(`g-*` + 色调 `t-*`)与文案原样保留,mock 常量换成服务端投影(README 平移规则 1/2/4)。
|
||||
* 区首页只负责导航,治理动作一律落在下钻详情页的**就地确认带**(影响预览三必答)。
|
||||
*/
|
||||
import { Ico } from '@web-shared/Ico.tsx';
|
||||
import { Card, Chip, NList, NRow, Note, PageHead, QueryGate, Rows, St } from '@web-shared/gov/primitives.tsx';
|
||||
import type { Nav } from '@web-shared/gov/gov-route.ts';
|
||||
import {
|
||||
@@ -30,10 +31,6 @@ export function SystemHome({ tab, nav }: HomeProps) {
|
||||
if (tab === 'chan') {
|
||||
return (
|
||||
<>
|
||||
<Note>
|
||||
通道实例声明<b>归属键规则</b>与默认认领岗位。归属解析三级逐级短路:会话线程 → 监听键 → 地址窗口;
|
||||
歧义或失败一律判无主——<b>宁交人,不错投</b>。
|
||||
</Note>
|
||||
<NList>
|
||||
{(channels.data?.channels ?? []).map((ch) => (
|
||||
<NRow
|
||||
@@ -64,31 +61,37 @@ export function SystemHome({ tab, nav }: HomeProps) {
|
||||
return (
|
||||
<QueryGate query={llm}>
|
||||
<>
|
||||
<Note>
|
||||
LLM 实例是<b>名称间接层</b>:活动只见自定义模型名,Provider / URL / API-Key / Model 四元在系统侧绑定。
|
||||
密钥与 endpoint 值只存治理台——不入包、不入活动、不入留痕明文。
|
||||
</Note>
|
||||
<NList>
|
||||
{/* 卡而不是行:一个实例要一眼看全「谁家的 · 什么型号 · 密钥绑没绑」 */}
|
||||
<div className="g-shelf">
|
||||
{(llm.data?.instances ?? []).map((i) => (
|
||||
<NRow
|
||||
<button
|
||||
key={i.id}
|
||||
tone={i.enabled ? 'brand' : 'mute'}
|
||||
ico="cpu"
|
||||
title={i.name}
|
||||
sub={`${i.provider} · ${i.model}`}
|
||||
cols={[
|
||||
{ k: 'Base URL', v: <span className="g-mono">{i.baseUrl}</span> },
|
||||
{ k: '系统用途', v: i.systemUse ? '是' : '—' },
|
||||
]}
|
||||
right={
|
||||
className={'g-tile t-' + (i.enabled ? 'brand' : 'mute')}
|
||||
onClick={() => nav.push({ k: 'llm', id: i.id })}
|
||||
>
|
||||
<span className="g-tile-h">
|
||||
<span className="g-tile-i">
|
||||
<Ico name="cpu" s={16} />
|
||||
</span>
|
||||
<span className="g-tile-t">
|
||||
<b>{i.name}</b>
|
||||
<em>{i.model}</em>
|
||||
</span>
|
||||
{i.systemUse && <Chip tone="brand">系统用途</Chip>}
|
||||
</span>
|
||||
<span className="g-tile-d">{i.baseUrl}</span>
|
||||
<span className="g-tile-m">
|
||||
<Chip ico="server">{i.provider}</Chip>
|
||||
</span>
|
||||
<span className="g-tile-f">
|
||||
<St tone={i.apiKeyBound ? 'ok' : 'warn'} ico={i.apiKeyBound ? 'shield-check' : 'alert-triangle'}>
|
||||
{i.apiKeyBound ? '密钥已绑定' : '密钥未绑定'}
|
||||
</St>
|
||||
}
|
||||
onClick={() => nav.push({ k: 'llm', id: i.id })}
|
||||
/>
|
||||
<span className="r">{i.enabled ? '启用' : '停用'}</span>
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
</NList>
|
||||
</div>
|
||||
</>
|
||||
</QueryGate>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user