Files
yunhai-agent-service/src/main/java/com/yunhai/agent/tool/defs/CampusNoticeTools.java
T
lijing d2c6c185b5
build / build-push (push) Successful in 1m9s
feat(notice): 「发布校园公告」裸意图直达表单 + 修发文部门下拉与假的发布方式
- 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。
2026-10-12 18:54:15 +08:00

120 lines
7.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}