feat(tools): כלי legal_predecessor_context — הקשר מריצות-קודמות לסוכן (#220) #5
@@ -148,6 +148,20 @@ export class LegalApi {
|
|||||||
// Return static style guide reference
|
// Return static style guide reference
|
||||||
return "ראה skill-legal-decision/SKILL.md — מדריך סגנון מלא של דפנה תמיר";
|
return "ראה skill-legal-decision/SKILL.md — מדריך סגנון מלא של דפנה תמיר";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recent conclusions of prior heartbeat runs across a case's issues (#220,
|
||||||
|
* "seance"). Lets a resuming agent read what earlier sessions concluded
|
||||||
|
* instead of re-deriving context from scratch.
|
||||||
|
*/
|
||||||
|
async getPredecessorForCase(
|
||||||
|
caseNumber: string,
|
||||||
|
limit = 5,
|
||||||
|
): Promise<PredecessorResponse> {
|
||||||
|
return this.request(
|
||||||
|
`/api/operations/cases/${encodeURIComponent(caseNumber)}/predecessor?limit=${limit}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
@@ -260,3 +274,21 @@ export interface QAResponse {
|
|||||||
}>;
|
}>;
|
||||||
status: string;
|
status: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PredecessorRun {
|
||||||
|
run_id: string;
|
||||||
|
status: string;
|
||||||
|
started_at: string | null;
|
||||||
|
finished_at: string | null;
|
||||||
|
summary: string | null;
|
||||||
|
error_code: string | null;
|
||||||
|
session_id: string | null;
|
||||||
|
agent_name: string | null;
|
||||||
|
identifier: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PredecessorResponse {
|
||||||
|
ok: boolean;
|
||||||
|
case_number: string;
|
||||||
|
runs: PredecessorRun[];
|
||||||
|
}
|
||||||
|
|||||||
@@ -507,6 +507,40 @@ const plugin = definePlugin({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ctx.tools.register(
|
||||||
|
"legal_predecessor_context",
|
||||||
|
{
|
||||||
|
displayName: "הקשר מריצות קודמות",
|
||||||
|
description:
|
||||||
|
"Recent conclusions from prior heartbeat runs on this case (the 'summary' each run left). Call this when RESUMING work on a case to see what earlier sessions already did/decided — instead of re-deriving context from scratch. Provide the case number.",
|
||||||
|
parametersSchema: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
case_number: {
|
||||||
|
type: "string",
|
||||||
|
description: "Case number (e.g. 1043-02-26)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["case_number"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
const { case_number } = params as { case_number: string };
|
||||||
|
const result = await api.getPredecessorForCase(case_number);
|
||||||
|
// Readable digest for the agent — each prior run's conclusion,
|
||||||
|
// newest-first, summaries trimmed to keep the wake context lean.
|
||||||
|
const lines = result.runs.map((r) => {
|
||||||
|
const summary = (r.summary ?? "").trim().slice(0, 600);
|
||||||
|
const when = r.finished_at ?? r.started_at ?? "";
|
||||||
|
return `▸ ${r.agent_name ?? "?"} · ${r.identifier ?? ""} · ${when} · ${r.status}\n${summary}`;
|
||||||
|
});
|
||||||
|
const content = lines.length
|
||||||
|
? lines.join("\n\n")
|
||||||
|
: "אין ריצות קודמות עם מסקנות לתיק זה.";
|
||||||
|
return { content, data: result };
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// ── Events ─────────────────────────────────────────────────────
|
// ── Events ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
ctx.events.on("issue.created", async (event) => {
|
ctx.events.on("issue.created", async (event) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user