@akagilnc/pi-workflow-roles 0.1.5286 → 0.1.5295
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acp-host/production-host.js +87 -95
- package/dist/diarist-contracts.js +19 -0
- package/dist/headless-host/production-host.js +87 -95
- package/dist/ticket-provenance.js +25 -29
- package/package.json +1 -1
- package/resources/diarist-collect.md +4 -4
- package/src/diarist-contracts.ts +23 -0
- package/src/diarist-role.ts +39 -44
- package/src/diarist.ts +9 -29
- package/src/role-runtime.ts +13 -7
- package/src/ticket-provenance.ts +31 -44
|
@@ -1107,6 +1107,20 @@ function projectDiaristSessions(value) {
|
|
|
1107
1107
|
if (raw === void 0) return [];
|
|
1108
1108
|
return projectTicketProvenanceSessions(raw);
|
|
1109
1109
|
}
|
|
1110
|
+
function projectDiaristTicketSessions(value) {
|
|
1111
|
+
const raw = value.ticketSessions;
|
|
1112
|
+
if (!Array.isArray(raw)) return void 0;
|
|
1113
|
+
const perTicket = /* @__PURE__ */ new Map();
|
|
1114
|
+
for (const entry of raw) {
|
|
1115
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) return void 0;
|
|
1116
|
+
const { ticketNumber, sessions: rawSessions } = entry;
|
|
1117
|
+
if (!isSafePositiveTicketNumber(ticketNumber)) return void 0;
|
|
1118
|
+
const sessions = projectTicketProvenanceSessions(rawSessions);
|
|
1119
|
+
if (sessions === void 0) return void 0;
|
|
1120
|
+
perTicket.set(ticketNumber, [...perTicket.get(ticketNumber) ?? [], ...sessions]);
|
|
1121
|
+
}
|
|
1122
|
+
return Array.from(perTicket, ([ticketNumber, sessions]) => ({ ticketNumber, sessions }));
|
|
1123
|
+
}
|
|
1110
1124
|
var DIARIST_OUTPUT_TOOL_NAME;
|
|
1111
1125
|
var init_diarist_contracts = __esm({
|
|
1112
1126
|
"src/diarist-contracts.ts"() {
|
|
@@ -4888,42 +4902,37 @@ async function projectSessionRanges(input) {
|
|
|
4888
4902
|
}
|
|
4889
4903
|
return { entries };
|
|
4890
4904
|
}
|
|
4891
|
-
async function
|
|
4892
|
-
const
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4905
|
+
async function reprojectTicketProvenanceBatch(input) {
|
|
4906
|
+
const projections = [];
|
|
4907
|
+
for (const ticket of input.tickets) {
|
|
4908
|
+
const recordInput = ticketProvenanceRecordInput(
|
|
4909
|
+
ticket.ticketNumber,
|
|
4910
|
+
input.cwd,
|
|
4911
|
+
input.home,
|
|
4912
|
+
input.runDirectory
|
|
4913
|
+
);
|
|
4914
|
+
const entries = [];
|
|
4915
|
+
for (let s = 0; s < ticket.sessions.length; s += 1) {
|
|
4916
|
+
const projected = await projectSessionRanges({
|
|
4917
|
+
s,
|
|
4918
|
+
session: ticket.sessions[s],
|
|
4919
|
+
...input.home === void 0 ? {} : { home: input.home }
|
|
4920
|
+
});
|
|
4921
|
+
entries.push(...projected.entries);
|
|
4922
|
+
}
|
|
4923
|
+
projections.push({ ticket, recordInput, entries });
|
|
4904
4924
|
}
|
|
4905
|
-
const entries
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4925
|
+
for (const { ticket, recordInput, entries } of projections) {
|
|
4926
|
+
if (ticket.sessions.length === 0) continue;
|
|
4927
|
+
appendSitianRecord({
|
|
4928
|
+
...recordInput,
|
|
4929
|
+
payload: {
|
|
4930
|
+
type: "ticket-provenance-append",
|
|
4931
|
+
sessions: ticket.sessions,
|
|
4932
|
+
lines: entries
|
|
4933
|
+
}
|
|
4912
4934
|
});
|
|
4913
|
-
entries.push(...projected.entries);
|
|
4914
4935
|
}
|
|
4915
|
-
const pointer = appendSitianRecord({
|
|
4916
|
-
...recordInput,
|
|
4917
|
-
payload: {
|
|
4918
|
-
type: "ticket-provenance-append",
|
|
4919
|
-
sessions: input.sessions,
|
|
4920
|
-
lines: entries
|
|
4921
|
-
}
|
|
4922
|
-
});
|
|
4923
|
-
return {
|
|
4924
|
-
recordFile: pointer.recordFile,
|
|
4925
|
-
lines: entries.filter((entry) => "speaker" in entry)
|
|
4926
|
-
};
|
|
4927
4936
|
}
|
|
4928
4937
|
var TicketProvenanceInputError;
|
|
4929
4938
|
var init_ticket_provenance = __esm({
|
|
@@ -21877,6 +21886,37 @@ init_terminating_infrastructure();
|
|
|
21877
21886
|
init_diarist_contracts();
|
|
21878
21887
|
init_diarist_contracts();
|
|
21879
21888
|
import { Type as Type16 } from "typebox";
|
|
21889
|
+
var diaristSessionsSchema = Type16.Array(
|
|
21890
|
+
Type16.Object(
|
|
21891
|
+
{
|
|
21892
|
+
path: Type16.Optional(Type16.String({ description: "\u4F1A\u8BDD\u5377\u7EDD\u5BF9\u6216\u53EF\u8BFB\u8DEF\u5F84" })),
|
|
21893
|
+
ranges: Type16.Optional(
|
|
21894
|
+
Type16.Array(
|
|
21895
|
+
Type16.Object(
|
|
21896
|
+
{
|
|
21897
|
+
from: Type16.Optional(
|
|
21898
|
+
Type16.Object(
|
|
21899
|
+
{ id: Type16.Optional(Type16.String()), line: Type16.Optional(Type16.Unknown()) },
|
|
21900
|
+
{ additionalProperties: true, description: "\u8D77\u70B9\uFF1A\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00" }
|
|
21901
|
+
)
|
|
21902
|
+
),
|
|
21903
|
+
to: Type16.Optional(
|
|
21904
|
+
Type16.Object(
|
|
21905
|
+
{ id: Type16.Optional(Type16.String()), line: Type16.Optional(Type16.Unknown()) },
|
|
21906
|
+
{ additionalProperties: true, description: "\u7EC8\u70B9\uFF1A\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00" }
|
|
21907
|
+
)
|
|
21908
|
+
)
|
|
21909
|
+
},
|
|
21910
|
+
{ additionalProperties: true, description: "\u4E00\u6BB5\u5BF9\u8BDD\u533A\u95F4" }
|
|
21911
|
+
),
|
|
21912
|
+
{ description: "\u672C\u5377\u672C\u8F6E\u5404\u533A\u95F4\uFF1B\u81F3\u5C11\u4E00\u6BB5" }
|
|
21913
|
+
)
|
|
21914
|
+
)
|
|
21915
|
+
},
|
|
21916
|
+
{ additionalProperties: true, description: "\u4E00\u5377\u4F1A\u8BDD\u7684\u8FB9\u754C" }
|
|
21917
|
+
),
|
|
21918
|
+
{ description: "\u5BF9\u8BDD\u8FB9\u754C\uFF1B\u7A7A\u5217\u8868\uFF1D\u672C\u8F6E\u65E0\u5BF9\u8BDD\u53EF\u5212\u3002\u7AEF\u70B9\u65E0\u6CD5\u6307\u540D\u65F6\u8D70 reask\uFF0C\u4E0D\u4E2D\u6B62\u3002" }
|
|
21919
|
+
);
|
|
21880
21920
|
var diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
21881
21921
|
openToolObject(
|
|
21882
21922
|
Type16.Object({
|
|
@@ -21898,53 +21938,17 @@ var diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
|
21898
21938
|
description: "status \u4E3A escalate \u65F6\uFF1A\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u7684\u539F\u56E0"
|
|
21899
21939
|
})
|
|
21900
21940
|
),
|
|
21901
|
-
sessions: Type16.Optional(
|
|
21941
|
+
sessions: Type16.Optional(diaristSessionsSchema),
|
|
21942
|
+
ticketSessions: Type16.Optional(
|
|
21902
21943
|
Type16.Array(
|
|
21903
21944
|
Type16.Object(
|
|
21904
21945
|
{
|
|
21905
|
-
|
|
21906
|
-
|
|
21907
|
-
),
|
|
21908
|
-
ranges: Type16.Optional(
|
|
21909
|
-
Type16.Array(
|
|
21910
|
-
Type16.Object(
|
|
21911
|
-
{
|
|
21912
|
-
from: Type16.Optional(
|
|
21913
|
-
Type16.Object(
|
|
21914
|
-
{
|
|
21915
|
-
id: Type16.Optional(Type16.String()),
|
|
21916
|
-
line: Type16.Optional(Type16.Unknown())
|
|
21917
|
-
},
|
|
21918
|
-
{
|
|
21919
|
-
additionalProperties: true,
|
|
21920
|
-
description: "\u8D77\u70B9\uFF1A\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00"
|
|
21921
|
-
}
|
|
21922
|
-
)
|
|
21923
|
-
),
|
|
21924
|
-
to: Type16.Optional(
|
|
21925
|
-
Type16.Object(
|
|
21926
|
-
{
|
|
21927
|
-
id: Type16.Optional(Type16.String()),
|
|
21928
|
-
line: Type16.Optional(Type16.Unknown())
|
|
21929
|
-
},
|
|
21930
|
-
{
|
|
21931
|
-
additionalProperties: true,
|
|
21932
|
-
description: "\u7EC8\u70B9\uFF1A\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00"
|
|
21933
|
-
}
|
|
21934
|
-
)
|
|
21935
|
-
)
|
|
21936
|
-
},
|
|
21937
|
-
{ additionalProperties: true, description: "\u4E00\u6BB5\u5BF9\u8BDD\u533A\u95F4" }
|
|
21938
|
-
),
|
|
21939
|
-
{ description: "\u672C\u5377\u672C\u8F6E\u5404\u533A\u95F4\uFF1B\u81F3\u5C11\u4E00\u6BB5" }
|
|
21940
|
-
)
|
|
21941
|
-
)
|
|
21946
|
+
ticketNumber: Type16.Unknown({ description: "\u672C\u6761\u8FB9\u754C\u6240\u5F52\u7968\u53F7\uFF08\u6B63\u6574\u6570\uFF09" }),
|
|
21947
|
+
sessions: diaristSessionsSchema
|
|
21942
21948
|
},
|
|
21943
|
-
{ additionalProperties: true
|
|
21949
|
+
{ additionalProperties: true }
|
|
21944
21950
|
),
|
|
21945
|
-
{
|
|
21946
|
-
description: "\u672C\u7968\u5BF9\u8BDD\u8FB9\u754C\uFF1B\u7A7A\u5217\u8868\uFF1D\u672C\u8F6E\u65E0\u5BF9\u8BDD\u53EF\u5212\u3002\u7AEF\u70B9\u65E0\u6CD5\u6307\u540D\u65F6\u8D70 reask\uFF0C\u4E0D\u4E2D\u6B62\u3002"
|
|
21947
|
-
}
|
|
21951
|
+
{ description: "\u591A\u7968\u5EAD\u9010\u7968\u5BF9\u8BDD\u8FB9\u754C\uFF1B\u4E00\u6B21\u4EA4\u5377\u5404\u7968\u5404\u81EA\u5206\u5F55\u3002\u4E0E\u5355\u7968 sessions \u4E8C\u9009\u4E00\u3002" }
|
|
21948
21952
|
)
|
|
21949
21953
|
)
|
|
21950
21954
|
})
|
|
@@ -21953,7 +21957,7 @@ var diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
|
21953
21957
|
var DIARIST_TOOL_SPEC = {
|
|
21954
21958
|
name: DIARIST_OUTPUT_TOOL_NAME,
|
|
21955
21959
|
label: "\u8D77\u5C45\u90CE\u8F93\u51FA",
|
|
21956
|
-
description: "\u8D77\u5C45\u90CE\u4EA4\
|
|
21960
|
+
description: "\u8D77\u5C45\u90CE\u4EA4\u5355\u7968 sessions \u6216\u591A\u7968\u9010\u7968 ticketSessions \u8FB9\u754C\uFF1B\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u5219 escalate\u3002",
|
|
21957
21961
|
promptSnippet: "\u8D77\u5C45\u90CE\u4EA4\u8FB9\u754C",
|
|
21958
21962
|
parameters: diaristOutputSchema
|
|
21959
21963
|
};
|
|
@@ -22003,18 +22007,7 @@ init_diarist_contracts();
|
|
|
22003
22007
|
// src/diarist.ts
|
|
22004
22008
|
init_ticket_provenance();
|
|
22005
22009
|
async function commitDiaristProjection(input) {
|
|
22006
|
-
|
|
22007
|
-
ticketNumber: input.ticketNumber,
|
|
22008
|
-
cwd: input.cwd,
|
|
22009
|
-
...input.home === void 0 ? {} : { home: input.home },
|
|
22010
|
-
sessions: input.sessions,
|
|
22011
|
-
...input.runDirectory === void 0 ? {} : { runDirectory: input.runDirectory }
|
|
22012
|
-
});
|
|
22013
|
-
return {
|
|
22014
|
-
ticketNumber: input.ticketNumber,
|
|
22015
|
-
volumeRecordFile: result.recordFile,
|
|
22016
|
-
lineCount: result.lines.length
|
|
22017
|
-
};
|
|
22010
|
+
await reprojectTicketProvenanceBatch(input);
|
|
22018
22011
|
}
|
|
22019
22012
|
|
|
22020
22013
|
// src/role-runtime.ts
|
|
@@ -24122,7 +24115,7 @@ function readDiaristRunCoordinates(ctx) {
|
|
|
24122
24115
|
...bound === void 0 ? {} : { boundTicketNumber: bound }
|
|
24123
24116
|
};
|
|
24124
24117
|
}
|
|
24125
|
-
var DIARIST_BOUNDS_REASK = "\u8FB9\u754C\u65E0\u6CD5\u4F7F\u7528\u3002\u8BF7\u91CD\u4EA4 sessions\
|
|
24118
|
+
var DIARIST_BOUNDS_REASK = "\u8FB9\u754C\u65E0\u6CD5\u4F7F\u7528\u3002\u591A\u7968\u8BF7\u9010\u7968\u91CD\u4EA4 ticketSessions\uFF0C\u5355\u7968\u91CD\u4EA4 sessions\uFF1B\u6BCF\u5377 path + ranges\uFF0C\u6BCF\u7AEF\u4EE5\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00\u6307\u540D\u3002";
|
|
24126
24119
|
function createDiaristRoleRuntime(roleHost, dependencies) {
|
|
24127
24120
|
return createFiledOfficerRuntime(
|
|
24128
24121
|
roleHost,
|
|
@@ -24142,18 +24135,17 @@ function createDiaristRoleRuntime(roleHost, dependencies) {
|
|
|
24142
24135
|
await bindTicketNumberOnRunDirectory(coords.runDirectory, ticketNumber);
|
|
24143
24136
|
}
|
|
24144
24137
|
}
|
|
24145
|
-
const
|
|
24146
|
-
|
|
24138
|
+
const singleSessions = submitted && !Object.hasOwn(submitted, "ticketSessions") ? projectDiaristSessions(parameters) : void 0;
|
|
24139
|
+
const ticketSessions = submitted && Object.hasOwn(submitted, "ticketSessions") ? projectDiaristTicketSessions(submitted) : singleSessions === void 0 ? void 0 : [{ ticketNumber: ticketNumber ?? null, sessions: singleSessions }];
|
|
24140
|
+
if (ticketSessions === void 0) {
|
|
24147
24141
|
throw new ParentQueueReaskError(DIARIST_BOUNDS_REASK);
|
|
24148
24142
|
}
|
|
24149
|
-
let facts;
|
|
24150
24143
|
try {
|
|
24151
|
-
|
|
24152
|
-
ticketNumber: ticketNumber ?? null,
|
|
24144
|
+
await commitDiaristProjection({
|
|
24153
24145
|
cwd: coords.projectRoot,
|
|
24154
24146
|
home: coords.home,
|
|
24155
24147
|
runDirectory: coords.runDirectory,
|
|
24156
|
-
|
|
24148
|
+
tickets: ticketSessions
|
|
24157
24149
|
});
|
|
24158
24150
|
} catch (error) {
|
|
24159
24151
|
if (error instanceof ParentQueueReaskError) throw error;
|
|
@@ -130,3 +130,22 @@ export function projectDiaristSessions(value) {
|
|
|
130
130
|
return [];
|
|
131
131
|
return projectTicketProvenanceSessions(raw);
|
|
132
132
|
}
|
|
133
|
+
/** Present multi-ticket bounds take precedence over the legacy single-ticket sessions. */
|
|
134
|
+
export function projectDiaristTicketSessions(value) {
|
|
135
|
+
const raw = value.ticketSessions;
|
|
136
|
+
if (!Array.isArray(raw))
|
|
137
|
+
return undefined;
|
|
138
|
+
const perTicket = new Map();
|
|
139
|
+
for (const entry of raw) {
|
|
140
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry))
|
|
141
|
+
return undefined;
|
|
142
|
+
const { ticketNumber, sessions: rawSessions } = entry;
|
|
143
|
+
if (!isSafePositiveTicketNumber(ticketNumber))
|
|
144
|
+
return undefined;
|
|
145
|
+
const sessions = projectTicketProvenanceSessions(rawSessions);
|
|
146
|
+
if (sessions === undefined)
|
|
147
|
+
return undefined;
|
|
148
|
+
perTicket.set(ticketNumber, [...(perTicket.get(ticketNumber) ?? []), ...sessions]);
|
|
149
|
+
}
|
|
150
|
+
return Array.from(perTicket, ([ticketNumber, sessions]) => ({ ticketNumber, sessions }));
|
|
151
|
+
}
|
|
@@ -934,6 +934,20 @@ function projectDiaristSessions(value) {
|
|
|
934
934
|
if (raw === void 0) return [];
|
|
935
935
|
return projectTicketProvenanceSessions(raw);
|
|
936
936
|
}
|
|
937
|
+
function projectDiaristTicketSessions(value) {
|
|
938
|
+
const raw = value.ticketSessions;
|
|
939
|
+
if (!Array.isArray(raw)) return void 0;
|
|
940
|
+
const perTicket = /* @__PURE__ */ new Map();
|
|
941
|
+
for (const entry of raw) {
|
|
942
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) return void 0;
|
|
943
|
+
const { ticketNumber, sessions: rawSessions } = entry;
|
|
944
|
+
if (!isSafePositiveTicketNumber(ticketNumber)) return void 0;
|
|
945
|
+
const sessions = projectTicketProvenanceSessions(rawSessions);
|
|
946
|
+
if (sessions === void 0) return void 0;
|
|
947
|
+
perTicket.set(ticketNumber, [...perTicket.get(ticketNumber) ?? [], ...sessions]);
|
|
948
|
+
}
|
|
949
|
+
return Array.from(perTicket, ([ticketNumber, sessions]) => ({ ticketNumber, sessions }));
|
|
950
|
+
}
|
|
937
951
|
var DIARIST_OUTPUT_TOOL_NAME;
|
|
938
952
|
var init_diarist_contracts = __esm({
|
|
939
953
|
"src/diarist-contracts.ts"() {
|
|
@@ -5768,42 +5782,37 @@ async function projectSessionRanges(input) {
|
|
|
5768
5782
|
}
|
|
5769
5783
|
return { entries };
|
|
5770
5784
|
}
|
|
5771
|
-
async function
|
|
5772
|
-
const
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5785
|
+
async function reprojectTicketProvenanceBatch(input) {
|
|
5786
|
+
const projections = [];
|
|
5787
|
+
for (const ticket of input.tickets) {
|
|
5788
|
+
const recordInput = ticketProvenanceRecordInput(
|
|
5789
|
+
ticket.ticketNumber,
|
|
5790
|
+
input.cwd,
|
|
5791
|
+
input.home,
|
|
5792
|
+
input.runDirectory
|
|
5793
|
+
);
|
|
5794
|
+
const entries = [];
|
|
5795
|
+
for (let s = 0; s < ticket.sessions.length; s += 1) {
|
|
5796
|
+
const projected = await projectSessionRanges({
|
|
5797
|
+
s,
|
|
5798
|
+
session: ticket.sessions[s],
|
|
5799
|
+
...input.home === void 0 ? {} : { home: input.home }
|
|
5800
|
+
});
|
|
5801
|
+
entries.push(...projected.entries);
|
|
5802
|
+
}
|
|
5803
|
+
projections.push({ ticket, recordInput, entries });
|
|
5784
5804
|
}
|
|
5785
|
-
const entries
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5805
|
+
for (const { ticket, recordInput, entries } of projections) {
|
|
5806
|
+
if (ticket.sessions.length === 0) continue;
|
|
5807
|
+
appendSitianRecord({
|
|
5808
|
+
...recordInput,
|
|
5809
|
+
payload: {
|
|
5810
|
+
type: "ticket-provenance-append",
|
|
5811
|
+
sessions: ticket.sessions,
|
|
5812
|
+
lines: entries
|
|
5813
|
+
}
|
|
5792
5814
|
});
|
|
5793
|
-
entries.push(...projected.entries);
|
|
5794
5815
|
}
|
|
5795
|
-
const pointer = appendSitianRecord({
|
|
5796
|
-
...recordInput,
|
|
5797
|
-
payload: {
|
|
5798
|
-
type: "ticket-provenance-append",
|
|
5799
|
-
sessions: input.sessions,
|
|
5800
|
-
lines: entries
|
|
5801
|
-
}
|
|
5802
|
-
});
|
|
5803
|
-
return {
|
|
5804
|
-
recordFile: pointer.recordFile,
|
|
5805
|
-
lines: entries.filter((entry) => "speaker" in entry)
|
|
5806
|
-
};
|
|
5807
5816
|
}
|
|
5808
5817
|
var TicketProvenanceInputError;
|
|
5809
5818
|
var init_ticket_provenance = __esm({
|
|
@@ -22935,6 +22944,37 @@ init_terminating_infrastructure();
|
|
|
22935
22944
|
init_diarist_contracts();
|
|
22936
22945
|
init_diarist_contracts();
|
|
22937
22946
|
import { Type as Type18 } from "typebox";
|
|
22947
|
+
var diaristSessionsSchema = Type18.Array(
|
|
22948
|
+
Type18.Object(
|
|
22949
|
+
{
|
|
22950
|
+
path: Type18.Optional(Type18.String({ description: "\u4F1A\u8BDD\u5377\u7EDD\u5BF9\u6216\u53EF\u8BFB\u8DEF\u5F84" })),
|
|
22951
|
+
ranges: Type18.Optional(
|
|
22952
|
+
Type18.Array(
|
|
22953
|
+
Type18.Object(
|
|
22954
|
+
{
|
|
22955
|
+
from: Type18.Optional(
|
|
22956
|
+
Type18.Object(
|
|
22957
|
+
{ id: Type18.Optional(Type18.String()), line: Type18.Optional(Type18.Unknown()) },
|
|
22958
|
+
{ additionalProperties: true, description: "\u8D77\u70B9\uFF1A\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00" }
|
|
22959
|
+
)
|
|
22960
|
+
),
|
|
22961
|
+
to: Type18.Optional(
|
|
22962
|
+
Type18.Object(
|
|
22963
|
+
{ id: Type18.Optional(Type18.String()), line: Type18.Optional(Type18.Unknown()) },
|
|
22964
|
+
{ additionalProperties: true, description: "\u7EC8\u70B9\uFF1A\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00" }
|
|
22965
|
+
)
|
|
22966
|
+
)
|
|
22967
|
+
},
|
|
22968
|
+
{ additionalProperties: true, description: "\u4E00\u6BB5\u5BF9\u8BDD\u533A\u95F4" }
|
|
22969
|
+
),
|
|
22970
|
+
{ description: "\u672C\u5377\u672C\u8F6E\u5404\u533A\u95F4\uFF1B\u81F3\u5C11\u4E00\u6BB5" }
|
|
22971
|
+
)
|
|
22972
|
+
)
|
|
22973
|
+
},
|
|
22974
|
+
{ additionalProperties: true, description: "\u4E00\u5377\u4F1A\u8BDD\u7684\u8FB9\u754C" }
|
|
22975
|
+
),
|
|
22976
|
+
{ description: "\u5BF9\u8BDD\u8FB9\u754C\uFF1B\u7A7A\u5217\u8868\uFF1D\u672C\u8F6E\u65E0\u5BF9\u8BDD\u53EF\u5212\u3002\u7AEF\u70B9\u65E0\u6CD5\u6307\u540D\u65F6\u8D70 reask\uFF0C\u4E0D\u4E2D\u6B62\u3002" }
|
|
22977
|
+
);
|
|
22938
22978
|
var diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
22939
22979
|
openToolObject(
|
|
22940
22980
|
Type18.Object({
|
|
@@ -22956,53 +22996,17 @@ var diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
|
22956
22996
|
description: "status \u4E3A escalate \u65F6\uFF1A\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u7684\u539F\u56E0"
|
|
22957
22997
|
})
|
|
22958
22998
|
),
|
|
22959
|
-
sessions: Type18.Optional(
|
|
22999
|
+
sessions: Type18.Optional(diaristSessionsSchema),
|
|
23000
|
+
ticketSessions: Type18.Optional(
|
|
22960
23001
|
Type18.Array(
|
|
22961
23002
|
Type18.Object(
|
|
22962
23003
|
{
|
|
22963
|
-
|
|
22964
|
-
|
|
22965
|
-
),
|
|
22966
|
-
ranges: Type18.Optional(
|
|
22967
|
-
Type18.Array(
|
|
22968
|
-
Type18.Object(
|
|
22969
|
-
{
|
|
22970
|
-
from: Type18.Optional(
|
|
22971
|
-
Type18.Object(
|
|
22972
|
-
{
|
|
22973
|
-
id: Type18.Optional(Type18.String()),
|
|
22974
|
-
line: Type18.Optional(Type18.Unknown())
|
|
22975
|
-
},
|
|
22976
|
-
{
|
|
22977
|
-
additionalProperties: true,
|
|
22978
|
-
description: "\u8D77\u70B9\uFF1A\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00"
|
|
22979
|
-
}
|
|
22980
|
-
)
|
|
22981
|
-
),
|
|
22982
|
-
to: Type18.Optional(
|
|
22983
|
-
Type18.Object(
|
|
22984
|
-
{
|
|
22985
|
-
id: Type18.Optional(Type18.String()),
|
|
22986
|
-
line: Type18.Optional(Type18.Unknown())
|
|
22987
|
-
},
|
|
22988
|
-
{
|
|
22989
|
-
additionalProperties: true,
|
|
22990
|
-
description: "\u7EC8\u70B9\uFF1A\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00"
|
|
22991
|
-
}
|
|
22992
|
-
)
|
|
22993
|
-
)
|
|
22994
|
-
},
|
|
22995
|
-
{ additionalProperties: true, description: "\u4E00\u6BB5\u5BF9\u8BDD\u533A\u95F4" }
|
|
22996
|
-
),
|
|
22997
|
-
{ description: "\u672C\u5377\u672C\u8F6E\u5404\u533A\u95F4\uFF1B\u81F3\u5C11\u4E00\u6BB5" }
|
|
22998
|
-
)
|
|
22999
|
-
)
|
|
23004
|
+
ticketNumber: Type18.Unknown({ description: "\u672C\u6761\u8FB9\u754C\u6240\u5F52\u7968\u53F7\uFF08\u6B63\u6574\u6570\uFF09" }),
|
|
23005
|
+
sessions: diaristSessionsSchema
|
|
23000
23006
|
},
|
|
23001
|
-
{ additionalProperties: true
|
|
23007
|
+
{ additionalProperties: true }
|
|
23002
23008
|
),
|
|
23003
|
-
{
|
|
23004
|
-
description: "\u672C\u7968\u5BF9\u8BDD\u8FB9\u754C\uFF1B\u7A7A\u5217\u8868\uFF1D\u672C\u8F6E\u65E0\u5BF9\u8BDD\u53EF\u5212\u3002\u7AEF\u70B9\u65E0\u6CD5\u6307\u540D\u65F6\u8D70 reask\uFF0C\u4E0D\u4E2D\u6B62\u3002"
|
|
23005
|
-
}
|
|
23009
|
+
{ description: "\u591A\u7968\u5EAD\u9010\u7968\u5BF9\u8BDD\u8FB9\u754C\uFF1B\u4E00\u6B21\u4EA4\u5377\u5404\u7968\u5404\u81EA\u5206\u5F55\u3002\u4E0E\u5355\u7968 sessions \u4E8C\u9009\u4E00\u3002" }
|
|
23006
23010
|
)
|
|
23007
23011
|
)
|
|
23008
23012
|
})
|
|
@@ -23011,7 +23015,7 @@ var diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
|
23011
23015
|
var DIARIST_TOOL_SPEC = {
|
|
23012
23016
|
name: DIARIST_OUTPUT_TOOL_NAME,
|
|
23013
23017
|
label: "\u8D77\u5C45\u90CE\u8F93\u51FA",
|
|
23014
|
-
description: "\u8D77\u5C45\u90CE\u4EA4\
|
|
23018
|
+
description: "\u8D77\u5C45\u90CE\u4EA4\u5355\u7968 sessions \u6216\u591A\u7968\u9010\u7968 ticketSessions \u8FB9\u754C\uFF1B\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u5219 escalate\u3002",
|
|
23015
23019
|
promptSnippet: "\u8D77\u5C45\u90CE\u4EA4\u8FB9\u754C",
|
|
23016
23020
|
parameters: diaristOutputSchema
|
|
23017
23021
|
};
|
|
@@ -23061,18 +23065,7 @@ init_diarist_contracts();
|
|
|
23061
23065
|
// src/diarist.ts
|
|
23062
23066
|
init_ticket_provenance();
|
|
23063
23067
|
async function commitDiaristProjection(input) {
|
|
23064
|
-
|
|
23065
|
-
ticketNumber: input.ticketNumber,
|
|
23066
|
-
cwd: input.cwd,
|
|
23067
|
-
...input.home === void 0 ? {} : { home: input.home },
|
|
23068
|
-
sessions: input.sessions,
|
|
23069
|
-
...input.runDirectory === void 0 ? {} : { runDirectory: input.runDirectory }
|
|
23070
|
-
});
|
|
23071
|
-
return {
|
|
23072
|
-
ticketNumber: input.ticketNumber,
|
|
23073
|
-
volumeRecordFile: result.recordFile,
|
|
23074
|
-
lineCount: result.lines.length
|
|
23075
|
-
};
|
|
23068
|
+
await reprojectTicketProvenanceBatch(input);
|
|
23076
23069
|
}
|
|
23077
23070
|
|
|
23078
23071
|
// src/role-runtime.ts
|
|
@@ -24215,7 +24208,7 @@ function readDiaristRunCoordinates(ctx) {
|
|
|
24215
24208
|
...bound === void 0 ? {} : { boundTicketNumber: bound }
|
|
24216
24209
|
};
|
|
24217
24210
|
}
|
|
24218
|
-
var DIARIST_BOUNDS_REASK = "\u8FB9\u754C\u65E0\u6CD5\u4F7F\u7528\u3002\u8BF7\u91CD\u4EA4 sessions\
|
|
24211
|
+
var DIARIST_BOUNDS_REASK = "\u8FB9\u754C\u65E0\u6CD5\u4F7F\u7528\u3002\u591A\u7968\u8BF7\u9010\u7968\u91CD\u4EA4 ticketSessions\uFF0C\u5355\u7968\u91CD\u4EA4 sessions\uFF1B\u6BCF\u5377 path + ranges\uFF0C\u6BCF\u7AEF\u4EE5\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00\u6307\u540D\u3002";
|
|
24219
24212
|
function createDiaristRoleRuntime(roleHost, dependencies) {
|
|
24220
24213
|
return createFiledOfficerRuntime(
|
|
24221
24214
|
roleHost,
|
|
@@ -24235,18 +24228,17 @@ function createDiaristRoleRuntime(roleHost, dependencies) {
|
|
|
24235
24228
|
await bindTicketNumberOnRunDirectory(coords.runDirectory, ticketNumber);
|
|
24236
24229
|
}
|
|
24237
24230
|
}
|
|
24238
|
-
const
|
|
24239
|
-
|
|
24231
|
+
const singleSessions = submitted && !Object.hasOwn(submitted, "ticketSessions") ? projectDiaristSessions(parameters) : void 0;
|
|
24232
|
+
const ticketSessions = submitted && Object.hasOwn(submitted, "ticketSessions") ? projectDiaristTicketSessions(submitted) : singleSessions === void 0 ? void 0 : [{ ticketNumber: ticketNumber ?? null, sessions: singleSessions }];
|
|
24233
|
+
if (ticketSessions === void 0) {
|
|
24240
24234
|
throw new ParentQueueReaskError(DIARIST_BOUNDS_REASK);
|
|
24241
24235
|
}
|
|
24242
|
-
let facts;
|
|
24243
24236
|
try {
|
|
24244
|
-
|
|
24245
|
-
ticketNumber: ticketNumber ?? null,
|
|
24237
|
+
await commitDiaristProjection({
|
|
24246
24238
|
cwd: coords.projectRoot,
|
|
24247
24239
|
home: coords.home,
|
|
24248
24240
|
runDirectory: coords.runDirectory,
|
|
24249
|
-
|
|
24241
|
+
tickets: ticketSessions
|
|
24250
24242
|
});
|
|
24251
24243
|
} catch (error) {
|
|
24252
24244
|
if (error instanceof ParentQueueReaskError) throw error;
|
|
@@ -231,39 +231,35 @@ async function projectSessionRanges(input) {
|
|
|
231
231
|
return { entries };
|
|
232
232
|
}
|
|
233
233
|
/**
|
|
234
|
-
*
|
|
234
|
+
* Project every submitted boundary before appending any ticket's record.
|
|
235
235
|
* #1090: 纯追加——不回读已成录历史查重、不折叠、不刷新;同一区间再次提交也留下新的追加记录。
|
|
236
236
|
* 证不出的 body 原字节原样留卷。
|
|
237
237
|
*/
|
|
238
|
-
export async function
|
|
239
|
-
const
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
238
|
+
export async function reprojectTicketProvenanceBatch(input) {
|
|
239
|
+
const projections = [];
|
|
240
|
+
for (const ticket of input.tickets) {
|
|
241
|
+
const recordInput = ticketProvenanceRecordInput(ticket.ticketNumber, input.cwd, input.home, input.runDirectory);
|
|
242
|
+
const entries = [];
|
|
243
|
+
for (let s = 0; s < ticket.sessions.length; s += 1) {
|
|
244
|
+
const projected = await projectSessionRanges({
|
|
245
|
+
s,
|
|
246
|
+
session: ticket.sessions[s],
|
|
247
|
+
...(input.home === undefined ? {} : { home: input.home }),
|
|
248
|
+
});
|
|
249
|
+
entries.push(...projected.entries);
|
|
250
|
+
}
|
|
251
|
+
projections.push({ ticket, recordInput, entries });
|
|
246
252
|
}
|
|
247
|
-
const entries
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
253
|
+
for (const { ticket, recordInput, entries } of projections) {
|
|
254
|
+
if (ticket.sessions.length === 0)
|
|
255
|
+
continue;
|
|
256
|
+
appendSitianRecord({
|
|
257
|
+
...recordInput,
|
|
258
|
+
payload: {
|
|
259
|
+
type: "ticket-provenance-append",
|
|
260
|
+
sessions: ticket.sessions,
|
|
261
|
+
lines: entries,
|
|
262
|
+
},
|
|
254
263
|
});
|
|
255
|
-
entries.push(...projected.entries);
|
|
256
264
|
}
|
|
257
|
-
const pointer = appendSitianRecord({
|
|
258
|
-
...recordInput,
|
|
259
|
-
payload: {
|
|
260
|
-
type: "ticket-provenance-append",
|
|
261
|
-
sessions: input.sessions,
|
|
262
|
-
lines: entries,
|
|
263
|
-
},
|
|
264
|
-
});
|
|
265
|
-
return {
|
|
266
|
-
recordFile: pointer.recordFile,
|
|
267
|
-
lines: entries.filter((entry) => "speaker" in entry),
|
|
268
|
-
};
|
|
269
265
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## 任务
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
判断本庭要办哪些票、每票对话起止于何处并交出各自边界;正文与定位由机械按边界从会话卷投影。不整块誊录正文,不自行搜集材料替代机械投影;本文件不新立职掌、不替 soul 立法、不复制 schema 与 CLI 说明。
|
|
8
8
|
|
|
9
9
|
## 如何定边界
|
|
10
10
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
- 本仓相关会话卷(路径里的 `_` 在目录名里常写作 `-`;主 clone 与 worktree 可能共用或分列,自行辨认)
|
|
14
14
|
- 本票票面与评论:用 `gh` 或等价方式读 GitHub issue
|
|
15
15
|
|
|
16
|
-
调用方只给传召文与 `--project`。边界定不下来就如实说明并走既有 reask/escalate,不编造。
|
|
16
|
+
调用方只给传召文与 `--project`。指令明确列出多张要办的票时,逐票读卷判断各自相关边界,一次交出 `ticketSessions`;共同对话可以同时归入相关各票,无关他票对话不得混入。单票沿用 `sessions`。边界定不下来就如实说明并走既有 reask/escalate,不编造。
|
|
17
17
|
|
|
18
18
|
## 何谓本票对话
|
|
19
19
|
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
|
|
30
30
|
## 本票身份
|
|
31
31
|
|
|
32
|
-
由你(本席 LLM
|
|
32
|
+
由你(本席 LLM)判断当前要办的票;多票庭逐票划界,同时照旧申报本庭主票身份,在交卷对象上以 typed 字段交出——代码不做认票裁定(ADR 0075:起居郎 LLM 自行认票;认得出→有录,真无票→无录;机械层不做引文/票号/相关性判定)。
|
|
33
33
|
|
|
34
34
|
- 认得出本庭对象:`status: completed` 且 `ticketNumber: N`,并交边界。
|
|
35
35
|
- 真无票对象(方案/派单/处置案等):`status: completed` 且 `ticketNumber: null`(或省略)。真无票是合法结果,不入录。
|
|
36
36
|
- 本庭明确要新建票、但 issue 尚未建号:不是认票失败。以 `status: completed`、`ticketNumber: null` 交出已辨明的本案对话边界;起居录先随无号 run 暂存,建号后由既有归卷流程补归该号。不要借用旁票号。
|
|
37
37
|
- 认不出本庭对象是哪一张:`status: escalate` 并写明 `reason`。识别不了就上抛,不得省略票号假装无录,也不得猜一个号。
|
|
38
38
|
- 不得从旁及的他票或任何猜测里挑一个号顶替认不出的身份。
|
|
39
|
-
- 传召文自然会提轮次、决定编号、commit sha
|
|
39
|
+
- 传召文自然会提轮次、决定编号、commit sha、邻票号;要办的是指令明确列出的票,不是文中出现的每一个数字。
|
package/src/diarist-contracts.ts
CHANGED
|
@@ -42,6 +42,11 @@ export type DiaristOutput =
|
|
|
42
42
|
* Malformed endpoints → accept hook reasks (`reask-not-explode`).
|
|
43
43
|
*/
|
|
44
44
|
readonly sessions?: readonly TicketProvenanceSession[];
|
|
45
|
+
/** Per-ticket dialogue bounds for a single multi-ticket summons (#1107). */
|
|
46
|
+
readonly ticketSessions?: readonly {
|
|
47
|
+
readonly ticketNumber: number;
|
|
48
|
+
readonly sessions: readonly TicketProvenanceSession[];
|
|
49
|
+
}[];
|
|
45
50
|
}
|
|
46
51
|
| {
|
|
47
52
|
/** LLM cannot tell which ticket this summons is about — escalate, never wash into 无录. */
|
|
@@ -179,3 +184,21 @@ export function projectDiaristSessions(
|
|
|
179
184
|
if (raw === undefined) return [];
|
|
180
185
|
return projectTicketProvenanceSessions(raw);
|
|
181
186
|
}
|
|
187
|
+
|
|
188
|
+
/** Present multi-ticket bounds take precedence over the legacy single-ticket sessions. */
|
|
189
|
+
export function projectDiaristTicketSessions(
|
|
190
|
+
value: Record<string, unknown>,
|
|
191
|
+
): readonly { readonly ticketNumber: number; readonly sessions: readonly TicketProvenanceSession[] }[] | undefined {
|
|
192
|
+
const raw = value.ticketSessions;
|
|
193
|
+
if (!Array.isArray(raw)) return undefined;
|
|
194
|
+
const perTicket = new Map<number, TicketProvenanceSession[]>();
|
|
195
|
+
for (const entry of raw) {
|
|
196
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) return undefined;
|
|
197
|
+
const { ticketNumber, sessions: rawSessions } = entry as Record<string, unknown>;
|
|
198
|
+
if (!isSafePositiveTicketNumber(ticketNumber)) return undefined;
|
|
199
|
+
const sessions = projectTicketProvenanceSessions(rawSessions);
|
|
200
|
+
if (sessions === undefined) return undefined;
|
|
201
|
+
perTicket.set(ticketNumber, [...(perTicket.get(ticketNumber) ?? []), ...sessions]);
|
|
202
|
+
}
|
|
203
|
+
return Array.from(perTicket, ([ticketNumber, sessions]) => ({ ticketNumber, sessions }));
|
|
204
|
+
}
|
package/src/diarist-role.ts
CHANGED
|
@@ -19,6 +19,38 @@ export { validateRecordedDiaristOutput };
|
|
|
19
19
|
* 起居郎交卷形状。
|
|
20
20
|
* #901:交边界(sessions);正文与不可解析原字节由机械投影。
|
|
21
21
|
*/
|
|
22
|
+
const diaristSessionsSchema = Type.Array(
|
|
23
|
+
Type.Object(
|
|
24
|
+
{
|
|
25
|
+
path: Type.Optional(Type.String({ description: "会话卷绝对或可读路径" })),
|
|
26
|
+
ranges: Type.Optional(
|
|
27
|
+
Type.Array(
|
|
28
|
+
Type.Object(
|
|
29
|
+
{
|
|
30
|
+
from: Type.Optional(
|
|
31
|
+
Type.Object(
|
|
32
|
+
{ id: Type.Optional(Type.String()), line: Type.Optional(Type.Unknown()) },
|
|
33
|
+
{ additionalProperties: true, description: "起点:原生 id 或本轮行号二选一" },
|
|
34
|
+
),
|
|
35
|
+
),
|
|
36
|
+
to: Type.Optional(
|
|
37
|
+
Type.Object(
|
|
38
|
+
{ id: Type.Optional(Type.String()), line: Type.Optional(Type.Unknown()) },
|
|
39
|
+
{ additionalProperties: true, description: "终点:原生 id 或本轮行号二选一" },
|
|
40
|
+
),
|
|
41
|
+
),
|
|
42
|
+
},
|
|
43
|
+
{ additionalProperties: true, description: "一段对话区间" },
|
|
44
|
+
),
|
|
45
|
+
{ description: "本卷本轮各区间;至少一段" },
|
|
46
|
+
),
|
|
47
|
+
),
|
|
48
|
+
},
|
|
49
|
+
{ additionalProperties: true, description: "一卷会话的边界" },
|
|
50
|
+
),
|
|
51
|
+
{ description: "对话边界;空列表=本轮无对话可划。端点无法指名时走 reask,不中止。" },
|
|
52
|
+
);
|
|
53
|
+
|
|
22
54
|
export const diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
23
55
|
openToolObject(
|
|
24
56
|
Type.Object({
|
|
@@ -42,54 +74,17 @@ export const diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
|
42
74
|
description: "status 为 escalate 时:认不出本庭对象的原因",
|
|
43
75
|
}),
|
|
44
76
|
),
|
|
45
|
-
sessions: Type.Optional(
|
|
77
|
+
sessions: Type.Optional(diaristSessionsSchema),
|
|
78
|
+
ticketSessions: Type.Optional(
|
|
46
79
|
Type.Array(
|
|
47
80
|
Type.Object(
|
|
48
81
|
{
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
),
|
|
52
|
-
ranges: Type.Optional(
|
|
53
|
-
Type.Array(
|
|
54
|
-
Type.Object(
|
|
55
|
-
{
|
|
56
|
-
from: Type.Optional(
|
|
57
|
-
Type.Object(
|
|
58
|
-
{
|
|
59
|
-
id: Type.Optional(Type.String()),
|
|
60
|
-
line: Type.Optional(Type.Unknown()),
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
additionalProperties: true,
|
|
64
|
-
description: "起点:原生 id 或本轮行号二选一",
|
|
65
|
-
},
|
|
66
|
-
),
|
|
67
|
-
),
|
|
68
|
-
to: Type.Optional(
|
|
69
|
-
Type.Object(
|
|
70
|
-
{
|
|
71
|
-
id: Type.Optional(Type.String()),
|
|
72
|
-
line: Type.Optional(Type.Unknown()),
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
additionalProperties: true,
|
|
76
|
-
description: "终点:原生 id 或本轮行号二选一",
|
|
77
|
-
},
|
|
78
|
-
),
|
|
79
|
-
),
|
|
80
|
-
},
|
|
81
|
-
{ additionalProperties: true, description: "一段对话区间" },
|
|
82
|
-
),
|
|
83
|
-
{ description: "本卷本轮各区间;至少一段" },
|
|
84
|
-
),
|
|
85
|
-
),
|
|
82
|
+
ticketNumber: Type.Unknown({ description: "本条边界所归票号(正整数)" }),
|
|
83
|
+
sessions: diaristSessionsSchema,
|
|
86
84
|
},
|
|
87
|
-
{ additionalProperties: true
|
|
85
|
+
{ additionalProperties: true },
|
|
88
86
|
),
|
|
89
|
-
{
|
|
90
|
-
description:
|
|
91
|
-
"本票对话边界;空列表=本轮无对话可划。端点无法指名时走 reask,不中止。",
|
|
92
|
-
},
|
|
87
|
+
{ description: "多票庭逐票对话边界;一次交卷各票各自分录。与单票 sessions 二选一。" },
|
|
93
88
|
),
|
|
94
89
|
),
|
|
95
90
|
}),
|
|
@@ -109,7 +104,7 @@ export const DIARIST_TOOL_SPEC = {
|
|
|
109
104
|
name: DIARIST_OUTPUT_TOOL_NAME,
|
|
110
105
|
label: "起居郎输出",
|
|
111
106
|
description:
|
|
112
|
-
"
|
|
107
|
+
"起居郎交单票 sessions 或多票逐票 ticketSessions 边界;认不出本庭对象则 escalate。",
|
|
113
108
|
promptSnippet: "起居郎交边界",
|
|
114
109
|
parameters: diaristOutputSchema,
|
|
115
110
|
} as const;
|
package/src/diarist.ts
CHANGED
|
@@ -4,42 +4,22 @@
|
|
|
4
4
|
* session volumes (pure append, no cross-submit dedupe). No human view.
|
|
5
5
|
* No lifecycle here (ADR 0018): the seat prepares, the role envelope commits.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { reprojectTicketProvenanceBatch } from "./ticket-provenance.ts";
|
|
8
8
|
import type { TicketProvenanceSession } from "./ticket-provenance-contracts.ts";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
* Populated by the envelope accept hook — never from model self-report.
|
|
13
|
-
*/
|
|
14
|
-
export type DiaristCommitFacts = {
|
|
15
|
-
readonly ticketNumber: number | null;
|
|
16
|
-
readonly volumeRecordFile: string;
|
|
17
|
-
/** Dialogue lines written by this reproject. */
|
|
18
|
-
readonly lineCount: number;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Append a diary projection from LLM-submitted bounds (#1090).
|
|
11
|
+
* Append per-ticket diary projections from LLM-submitted bounds (#1090 / #1107).
|
|
23
12
|
* Shape projection of sessions is the caller's job (accept hook);
|
|
24
|
-
* this seam only copies source facts into
|
|
13
|
+
* this seam only copies source facts into each ticket's volume.
|
|
25
14
|
*/
|
|
26
15
|
export async function commitDiaristProjection(input: {
|
|
27
|
-
readonly ticketNumber: number | null;
|
|
28
16
|
readonly cwd: string;
|
|
29
17
|
readonly home?: string;
|
|
30
18
|
readonly runDirectory?: string;
|
|
31
|
-
readonly
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
sessions: input.sessions,
|
|
38
|
-
...(input.runDirectory === undefined ? {} : { runDirectory: input.runDirectory }),
|
|
39
|
-
});
|
|
40
|
-
return {
|
|
41
|
-
ticketNumber: input.ticketNumber,
|
|
42
|
-
volumeRecordFile: result.recordFile,
|
|
43
|
-
lineCount: result.lines.length,
|
|
44
|
-
};
|
|
19
|
+
readonly tickets: readonly {
|
|
20
|
+
readonly ticketNumber: number | null;
|
|
21
|
+
readonly sessions: readonly TicketProvenanceSession[];
|
|
22
|
+
}[];
|
|
23
|
+
}): Promise<void> {
|
|
24
|
+
await reprojectTicketProvenanceBatch(input);
|
|
45
25
|
}
|
package/src/role-runtime.ts
CHANGED
|
@@ -73,6 +73,7 @@ import {
|
|
|
73
73
|
import { SECRETARIAT_OUTPUT_TOOL_NAME } from "./secretariat-contracts.ts";
|
|
74
74
|
import {
|
|
75
75
|
projectDiaristSessions,
|
|
76
|
+
projectDiaristTicketSessions,
|
|
76
77
|
} from "./diarist-contracts.ts";
|
|
77
78
|
import { commitDiaristProjection } from "./diarist.ts";
|
|
78
79
|
import { TicketProvenanceInputError } from "./ticket-provenance.ts";
|
|
@@ -834,7 +835,7 @@ function readDiaristRunCoordinates(ctx: HostContext): {
|
|
|
834
835
|
|
|
835
836
|
/** Plain-language re-ask when diarist bounds cannot be used (#901 / reask-not-explode). */
|
|
836
837
|
const DIARIST_BOUNDS_REASK =
|
|
837
|
-
"
|
|
838
|
+
"边界无法使用。多票请逐票重交 ticketSessions,单票重交 sessions;每卷 path + ranges,每端以原生 id 或本轮行号二选一指名。" as const;
|
|
838
839
|
/**
|
|
839
840
|
* #708 / #779 / #901: 起居郎 public seat on the shared filed-officer envelope.
|
|
840
841
|
* LLM judges ticket + dialogue bounds; mechanical layer reprojects the unique
|
|
@@ -870,18 +871,23 @@ export function createDiaristRoleRuntime(
|
|
|
870
871
|
await bindTicketNumberOnRunDirectory(coords.runDirectory, ticketNumber);
|
|
871
872
|
}
|
|
872
873
|
}
|
|
873
|
-
const
|
|
874
|
-
|
|
874
|
+
const singleSessions = submitted && !Object.hasOwn(submitted, "ticketSessions")
|
|
875
|
+
? projectDiaristSessions(parameters)
|
|
876
|
+
: undefined;
|
|
877
|
+
const ticketSessions = submitted && Object.hasOwn(submitted, "ticketSessions")
|
|
878
|
+
? projectDiaristTicketSessions(submitted)
|
|
879
|
+
: singleSessions === undefined
|
|
880
|
+
? undefined
|
|
881
|
+
: [{ ticketNumber: ticketNumber ?? null, sessions: singleSessions }];
|
|
882
|
+
if (ticketSessions === undefined) {
|
|
875
883
|
throw new ParentQueueReaskError(DIARIST_BOUNDS_REASK);
|
|
876
884
|
}
|
|
877
|
-
let facts;
|
|
878
885
|
try {
|
|
879
|
-
|
|
880
|
-
ticketNumber: ticketNumber ?? null,
|
|
886
|
+
await commitDiaristProjection({
|
|
881
887
|
cwd: coords.projectRoot,
|
|
882
888
|
home: coords.home,
|
|
883
889
|
runDirectory: coords.runDirectory,
|
|
884
|
-
|
|
890
|
+
tickets: ticketSessions,
|
|
885
891
|
});
|
|
886
892
|
} catch (error) {
|
|
887
893
|
// Bound/session input failures → reask via typed identity (not message prefix).
|
package/src/ticket-provenance.ts
CHANGED
|
@@ -162,11 +162,6 @@ export async function rehomeUnboundTicketProvenance(
|
|
|
162
162
|
await unlink(source);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
export type ReprojectTicketProvenanceResult = {
|
|
166
|
-
readonly recordFile: string;
|
|
167
|
-
readonly lines: readonly TicketProvenanceLine[];
|
|
168
|
-
};
|
|
169
|
-
|
|
170
165
|
/**
|
|
171
166
|
* Resolve a bound endpoint against this round's session lines.
|
|
172
167
|
* id → first physical line carrying that native id; line → that 1-based line.
|
|
@@ -327,53 +322,45 @@ async function projectSessionRanges(input: {
|
|
|
327
322
|
}
|
|
328
323
|
|
|
329
324
|
/**
|
|
330
|
-
*
|
|
325
|
+
* Project every submitted boundary before appending any ticket's record.
|
|
331
326
|
* #1090: 纯追加——不回读已成录历史查重、不折叠、不刷新;同一区间再次提交也留下新的追加记录。
|
|
332
327
|
* 证不出的 body 原字节原样留卷。
|
|
333
328
|
*/
|
|
334
|
-
export async function
|
|
335
|
-
readonly ticketNumber: number | null;
|
|
329
|
+
export async function reprojectTicketProvenanceBatch(input: {
|
|
336
330
|
readonly cwd: string;
|
|
337
331
|
readonly home?: string;
|
|
338
332
|
readonly runDirectory?: string;
|
|
339
|
-
readonly
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
333
|
+
readonly tickets: readonly {
|
|
334
|
+
readonly ticketNumber: number | null;
|
|
335
|
+
readonly sessions: readonly TicketProvenanceSession[];
|
|
336
|
+
}[];
|
|
337
|
+
}): Promise<void> {
|
|
338
|
+
const projections = [];
|
|
339
|
+
for (const ticket of input.tickets) {
|
|
340
|
+
const recordInput = ticketProvenanceRecordInput(
|
|
341
|
+
ticket.ticketNumber, input.cwd, input.home, input.runDirectory,
|
|
342
|
+
);
|
|
343
|
+
const entries: (TicketProvenanceLine | TicketProvenanceRaw)[] = [];
|
|
344
|
+
for (let s = 0; s < ticket.sessions.length; s += 1) {
|
|
345
|
+
const projected = await projectSessionRanges({
|
|
346
|
+
s,
|
|
347
|
+
session: ticket.sessions[s]!,
|
|
348
|
+
...(input.home === undefined ? {} : { home: input.home }),
|
|
349
|
+
});
|
|
350
|
+
entries.push(...projected.entries);
|
|
351
|
+
}
|
|
352
|
+
projections.push({ ticket, recordInput, entries });
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
-
const entries
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
355
|
+
for (const { ticket, recordInput, entries } of projections) {
|
|
356
|
+
if (ticket.sessions.length === 0) continue;
|
|
357
|
+
appendSitianRecord({
|
|
358
|
+
...recordInput,
|
|
359
|
+
payload: {
|
|
360
|
+
type: "ticket-provenance-append",
|
|
361
|
+
sessions: ticket.sessions,
|
|
362
|
+
lines: entries,
|
|
363
|
+
},
|
|
362
364
|
});
|
|
363
|
-
entries.push(...projected.entries);
|
|
364
365
|
}
|
|
365
|
-
|
|
366
|
-
const pointer = appendSitianRecord({
|
|
367
|
-
...recordInput,
|
|
368
|
-
payload: {
|
|
369
|
-
type: "ticket-provenance-append",
|
|
370
|
-
sessions: input.sessions,
|
|
371
|
-
lines: entries,
|
|
372
|
-
},
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
return {
|
|
376
|
-
recordFile: pointer.recordFile,
|
|
377
|
-
lines: entries.filter((entry): entry is TicketProvenanceLine => "speaker" in entry),
|
|
378
|
-
};
|
|
379
366
|
}
|