make sure only one spec is returned
This commit is contained in:
@@ -53,7 +53,7 @@ nodes columns share, on every step; `rep:collect`) → CSV → register file
|
|||||||
|
|
||||||
## The profile: a map of the data
|
## The profile: a map of the data
|
||||||
|
|
||||||
A profile lists the kinds of things in the data (entities), what each one
|
A profile (using SHACL + some extensions) lists the kinds of things in the data (entities), what each one
|
||||||
has (fields), and which fields lead to other entities (links). The app
|
has (fields), and which fields lead to other entities (links). The app
|
||||||
writes it; the service ships no profile and knows no vocabulary.
|
writes it; the service ships no profile and knows no vocabulary.
|
||||||
|
|
||||||
@@ -285,6 +285,7 @@ The validator (`src/runner/check.js`) runs on every proposal and again
|
|||||||
before every run. It returns the first problem, in words the LLM can act on.
|
before every run. It returns the first problem, in words the LLM can act on.
|
||||||
On top of the rules above, it checks that:
|
On top of the rules above, it checks that:
|
||||||
|
|
||||||
|
- the Turtle holds one `rep:ReportSpec`, no more: one answer is one report;
|
||||||
- every step of every path exists in the profile;
|
- every step of every path exists in the profile;
|
||||||
- no path is longer than `MAX_PATH_DEPTH` steps;
|
- no path is longer than `MAX_PATH_DEPTH` steps;
|
||||||
- a date or number test ends on a value field, not on a link;
|
- a date or number test ends on a value field, not on a link;
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ Rules:
|
|||||||
applies. Say that in Dutch in your proposal, so the user can check it.
|
applies. Say that in Dutch in your proposal, so the user can check it.
|
||||||
- Only offer what validate_spec accepted. Before you suggest an alternative,
|
- Only offer what validate_spec accepted. Before you suggest an alternative,
|
||||||
write it and validate it; if it does not validate, say it cannot be done.
|
write it and validate it; if it does not validate, say it cannot be done.
|
||||||
|
- One answer carries one spec, and one spec is one report on one profile. If
|
||||||
|
the question needs two reports, say so, propose the first, and offer the
|
||||||
|
second as the next step.
|
||||||
- You cannot count, sort, take the first N, or compare two subjects. Say so.
|
- You cannot count, sort, take the first N, or compare two subjects. Say so.
|
||||||
- The report's title is the dct:title you write in the spec. There is no other
|
- The report's title is the dct:title you write in the spec. There is no other
|
||||||
title input.
|
title input.
|
||||||
@@ -101,7 +104,13 @@ export async function ask(turns, profiles) {
|
|||||||
}
|
}
|
||||||
// validate_spec answers "ok" (plus notes) when the spec checks out;
|
// validate_spec answers "ok" (plus notes) when the spec checks out;
|
||||||
// that spec becomes the bijlage of the answer.
|
// that spec becomes the bijlage of the answer.
|
||||||
if (call.function.name === 'validate_spec' && /^ok(\n|$)/.test(result)) spec = args.spec;
|
// One answer carries one spec: say so when this one replaces another.
|
||||||
|
if (call.function.name === 'validate_spec' && /^ok(\n|$)/.test(result)) {
|
||||||
|
if (spec && spec !== args.spec) {
|
||||||
|
result += '\nThis spec replaces the one you validated before. Your answer carries only this one.';
|
||||||
|
}
|
||||||
|
spec = args.spec;
|
||||||
|
}
|
||||||
messages.push({ role: 'tool', tool_call_id: call.id, content: result });
|
messages.push({ role: 'tool', tool_call_id: call.id, content: result });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,13 @@ export function parseSpec(turtle) {
|
|||||||
const quads = parser.parse(turtle);
|
const quads = parser.parse(turtle);
|
||||||
const store = new N3.Store(quads);
|
const store = new N3.Store(quads);
|
||||||
|
|
||||||
const specNode = store.getQuads(null, RDF + 'type', REP + 'ReportSpec')[0]?.subject;
|
const specNodes = store.getQuads(null, RDF + 'type', REP + 'ReportSpec').map(q => q.subject);
|
||||||
if (!specNode) throw new Error('spec has no rep:ReportSpec');
|
if (!specNodes.length) throw new Error('spec has no rep:ReportSpec');
|
||||||
|
// One spec is one report. A second one would pass unchecked and never run.
|
||||||
|
if (specNodes.length > 1) {
|
||||||
|
throw new Error(`one spec per answer. This Turtle has ${specNodes.length} rep:ReportSpec. Keep one, and offer the other as the next report.`);
|
||||||
|
}
|
||||||
|
const specNode = specNodes[0];
|
||||||
|
|
||||||
const one = (s, pred) => store.getQuads(s, pred, null)[0]?.object || null;
|
const one = (s, pred) => store.getQuads(s, pred, null)[0]?.object || null;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user