build / build-push (push) Successful in 1m9s
- IntentShortcut 泛化成规则表(Rule{短语集 → Intent}):加新意图只需
① 一条 Intent ② 一个短语集 ③ RULES.add(...),不用动 AgentOrchestrator。
新增 NOTICE_PUBLISH —— 仅教职工(notice.publish),学生无落点则落回模型如实说明。
短语表只收带「发/发布」动词的说法(发布公告/发个公告/发布校园公告/发通知…),
光说「公告」「通知」更像查询,不收,避免误判。
- ★ 修 prepareOptionCall 漏拼字典工具的 fixed 参数:公文部门字典是
/api/dict/List?type=1,丢了 type 前端取回的是「没指定类型」的结果 → 空下拉。
- deptId 补 optionsKeys("k","v"):平台通用字典返回 {k,v} 而非 id/name;
服务端兜底 fetchDictOptions 的候选键也补上 k/v。
- ★ 移除 notice.publish 的 publishType 与 deptName:后端 /api/notice/Create 就是
直接发布(无 publishType 字段,是否转审批由学校「应用设置」绑定的流程决定),
声明它会让用户以为选了「存草稿」却仍然直接发出;deptName 由后端按 deptId 反查字典。
- system prompt 加第 10 条说明。
- 测试:新增 NoticeIntentFormTest(7),IntentDirectFormTest 加教师/学生两条公告用例
(仍用「一调就炸」的假 LLM 证明不过大模型);全量 71/71。
120 lines
7.4 KiB
Java
120 lines
7.4 KiB
Java
package com.yunhai.agent.tool.defs;
|
||
|
||
import com.yunhai.agent.tool.ToolDef;
|
||
import com.yunhai.agent.tool.ToolParam;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
|
||
/**
|
||
* 校园公告(校园通知)模块工具 —— 后端 CampusAnnouncement / NoticeFront,前缀 /api/notice。
|
||
*/
|
||
public final class CampusNoticeTools {
|
||
|
||
public static final String MODULE = "campusnotice";
|
||
|
||
private CampusNoticeTools() {
|
||
}
|
||
|
||
public static List<ToolDef> defs() {
|
||
List<ToolDef> list = new ArrayList<>();
|
||
|
||
list.add(ToolDef.of("notice.received", MODULE, "我收到的公告",
|
||
"分页查询当前用户收到的校园公告。用户问“最近有什么通知”“有没有未读公告”时用它。",
|
||
"GET", "/api/notice/List")
|
||
.p(ToolParam.optional("pageIndex", "integer", "页码,从 1 开始").dft("1"),
|
||
ToolParam.optional("pageSize", "integer", "每页条数,默认 10").dft("10"),
|
||
ToolParam.optional("keyword", "string", "标题关键词"),
|
||
ToolParam.optional("type", "integer", "重要程度:1 普通 / 2 重要"),
|
||
ToolParam.optional("readType", "integer", "阅读状态:0 全部 / 1 未读 / 2 已读"))
|
||
.readAt("/")
|
||
.modId(null));
|
||
|
||
list.add(ToolDef.of("notice.readTabCount", MODULE, "公告未读统计",
|
||
"查询当前用户公告的已收总数 / 未读数 / 已读数(回答“我还有几条没看”)。",
|
||
"GET", "/api/notice/ReadTabCount")
|
||
.readAt("/"));
|
||
|
||
list.add(ToolDef.of("notice.sent", MODULE, "我发出的公告",
|
||
"分页查询我发布(或有权限查看)的公告,可按状态筛选(草稿/已发布/待审批/已驳回)。",
|
||
"GET", "/api/notice/SendList")
|
||
.p(ToolParam.optional("pageIndex", "integer", "页码").dft("1"),
|
||
ToolParam.optional("pageSize", "integer", "每页条数").dft("10"),
|
||
ToolParam.optional("scope", "string", "传 user 只查自己发布的"),
|
||
ToolParam.optional("status", "integer", "0 草稿 / 1 已发布 / 2 待审批 / 3 已驳回"),
|
||
ToolParam.optional("keyword", "string", "标题关键词"))
|
||
.readAt("/list")
|
||
.modId(null));
|
||
|
||
list.add(ToolDef.of("notice.detail", MODULE, "公告详情",
|
||
"查看一条公告的正文、附件与已读情况。",
|
||
"GET", "/api/notice/Detail")
|
||
.p(ToolParam.required("serid", "integer", "公告 id"),
|
||
ToolParam.optional("type", "integer", "1 查看并标记已读(默认) / 0 仅查看不标读").dft("1"))
|
||
.readAt("/"));
|
||
|
||
list.add(ToolDef.of("notice.deptDics", MODULE, "发文部门字典",
|
||
"查询本校本模块可选的发文部门(发布公告时填 deptId 用)。"
|
||
+ "仅在用户明确问「有哪些发文部门」时使用;"
|
||
+ "发布公告时**不要**先调它 —— 表单的「发文部门」下拉会自动带出可选值。",
|
||
"GET", "/api/dict/List")
|
||
.fix("type", "1")
|
||
.readAt("/list/new"));
|
||
|
||
list.add(ToolDef.of("notice.publish", MODULE, "发布校园公告",
|
||
"发布一条校园公告,**立即生效、全站可见**(是否转审批由学校「应用设置」里的流程绑定决定,"
|
||
+ "请求侧无法选择)。调用前必须确认:标题 title、正文 content、发文部门 deptId;"
|
||
+ "缺失就直接调用本工具,系统会弹出表单让用户补齐,不要用文字反复追问;"
|
||
+ "发文部门必须来自字典,不要编造。",
|
||
"POST_JSON", "/api/notice/Create")
|
||
.p(ToolParam.required("title", "string", "公告标题")
|
||
.label("公告标题").eg("关于国庆假期安排的通知"),
|
||
ToolParam.required("content", "string", "公告正文(纯文本)")
|
||
.label("公告正文").as("textarea").eg("各位老师、同学:经学校研究决定……"),
|
||
ToolParam.required("deptId", "string", "发文部门 id,来自 notice.deptDics 的 k 字段")
|
||
.label("发文部门")
|
||
.optionsFrom("notice.deptDics").optionsKeys("k", "v"),
|
||
ToolParam.optional("type", "integer", "重要程度:1 普通 / 2 重要")
|
||
.label("重要程度").dft("1")
|
||
.options(new String[]{"1", "2"}, new String[]{"普通", "重要"}),
|
||
ToolParam.optional("receiptFlag", "integer", "是否需要阅读回执(要回执时收件人需点确认)")
|
||
.label("需要阅读回执").dft("0")
|
||
.options(new String[]{"0", "1"}, new String[]{"否", "是"}),
|
||
ToolParam.optional("smsFlag", "integer", "是否同时发短信提醒")
|
||
.label("同时发短信").dft("0")
|
||
.options(new String[]{"0", "1"}, new String[]{"否", "是"}))
|
||
.write("/list/new")
|
||
.modId(null));
|
||
|
||
list.add(ToolDef.of("notice.approvalList", MODULE, "待我审批的公告",
|
||
"查询待我审批的公告列表(公告审批中心)。",
|
||
"GET", "/api/notice/ApprovalList")
|
||
.readAt("/approval")
|
||
.p(ToolParam.optional("status", "string", "pending 待审批(默认) / approved 已通过 / rejected 已驳回 / all 全部").dft("pending"),
|
||
ToolParam.optional("pageIndex", "integer", "页码").dft("1"),
|
||
ToolParam.optional("pageSize", "integer", "每页条数").dft("10")));
|
||
|
||
list.add(ToolDef.of("notice.approve", MODULE, "通过公告审批",
|
||
"审批通过一条公告(末步通过即真实发布)。",
|
||
"POST_FORM", "/api/notice/Approve")
|
||
.p(ToolParam.required("serid", "integer", "公告 id")
|
||
.label("公告"),
|
||
ToolParam.optional("opinion", "string", "审批意见")
|
||
.label("审批意见").as("textarea").eg("内容符合要求,同意发布"))
|
||
.write("/approval")
|
||
.modId(null));
|
||
|
||
list.add(ToolDef.of("notice.reject", MODULE, "驳回公告审批",
|
||
"驳回一条公告审批(意见必填,会退回发布人)。",
|
||
"POST_FORM", "/api/notice/Reject")
|
||
.p(ToolParam.required("serid", "integer", "公告 id")
|
||
.label("公告"),
|
||
ToolParam.required("remark", "string", "驳回意见")
|
||
.label("驳回意见").as("textarea").eg("标题表述不清,请修改后重新提交"))
|
||
.write("/approval")
|
||
.modId(null));
|
||
|
||
return list;
|
||
}
|
||
}
|