feat(plugin): dialectic_list_arguments tool + clarify topic_detail desc

Two changes that fix bug #1 from the first e2e debate run (judge could
not see arguments, returned a hollow 'tie' verdict despite real pro/con
posts being in the DB):

1. New tool `dialectic_list_arguments` — hits the existing backend
   endpoint GET /api/topics/{id}/arguments and returns the full
   transcript (pro/con/judge entries with camp, agent_id, content,
   posted_at) in posted order. Used by judges composing verdicts and
   by debaters reading what opponents have said.

2. Updated `dialectic_topic_detail` description to make the split
   explicit: it returns the new camps array (added in the matching
   backend commit) so agents can locate their own allocation, but
   does NOT return arguments — list_arguments is the right tool.

Manifest contracts.tools updated (jiti loader requires this — see
[[reference-meridian-plugin-contract]]) plus internal logger count
bumped from 7 → 8 tools.

E2e verified on sim:
  - main agent calls topic_detail → sees camps array with self as 'pro'
  - judge agent calls list_arguments → reads pro/con content
  - judge rationale directly quotes claims from both sides
  - topic → completed with non-trivial binary verdict

Deploy note: jiti prefers .js when colocated; deploy must rm src/*.js
or pre-build before the new .ts takes effect (see e2e findings memory).
This commit is contained in:
h z
2026-05-23 22:03:49 +01:00
parent dd4c58ec8c
commit 63fc342238
2 changed files with 31 additions and 4 deletions

View File

@@ -15,7 +15,8 @@
"dialectic_signup", "dialectic_signup",
"dialectic_post_argument", "dialectic_post_argument",
"dialectic_submit_verdict", "dialectic_submit_verdict",
"dialectic_view_verdict" "dialectic_view_verdict",
"dialectic_list_arguments"
] ]
}, },
"configSchema": { "configSchema": {

View File

@@ -73,8 +73,10 @@ export function registerDialecticTools(api: ToolApi): void {
api.registerTool((ctx: { agentId?: string }) => ({ api.registerTool((ctx: { agentId?: string }) => ({
name: 'dialectic_topic_detail', name: 'dialectic_topic_detail',
description: description:
'Get full detail for one Dialectic topic — lifecycle timestamps, status, ' + 'Get one Dialectic topic — lifecycle timestamps, status, verdict_schema_id, ' +
'verdict_schema_id, allocated camps if past signup_close, and verdict if completed.', "and the `camps` array (0 rows pre-signup_close, 3 rows after — use this to " +
"find which camp YOU were allocated to: scan camps[].agent_id for your id). " +
"Does NOT include arguments — call dialectic_list_arguments for the transcript.",
parameters: { parameters: {
type: 'object', type: 'object',
additionalProperties: false, additionalProperties: false,
@@ -88,6 +90,30 @@ export function registerDialecticTools(api: ToolApi): void {
}), }),
})); }));
api.registerTool((ctx: { agentId?: string }) => ({
name: 'dialectic_list_arguments',
description:
"Fetch the full argument transcript for a topic in posted order " +
"(pro / con / judge entries with author agent_id, content, posted_at). " +
"Use this when you need to read what other camps have argued — e.g. " +
"before posting your own rebuttal, or as the judge composing a verdict. " +
"Backend filters by topic visibility (public readable by anyone, private " +
"requires auth). Empty array if the topic is still pre-debate.",
parameters: {
type: 'object',
additionalProperties: false,
properties: { topic_id: { type: 'string' } },
required: ['topic_id'],
},
execute: async (_id: string, params: Record<string, any>) =>
asContent(async () => {
const client = new BackendClient({ baseUrl: backendUrl, agentId: ctx.agentId ?? '' });
return await client.get(
`/api/topics/${encodeURIComponent(params.topic_id)}/arguments`
);
}),
}));
api.registerTool((ctx: { agentId?: string }) => ({ api.registerTool((ctx: { agentId?: string }) => ({
name: 'dialectic_propose_topic', name: 'dialectic_propose_topic',
description: description:
@@ -280,7 +306,7 @@ export function registerDialecticTools(api: ToolApi): void {
}), }),
})); }));
api.logger.info(`[dialectic] registered 7 tools (backend=${backendUrl})`); api.logger.info(`[dialectic] registered 8 tools (backend=${backendUrl})`);
} }
/** Wraps an async backend call and converts result/error into MCP content shape. */ /** Wraps an async backend call and converts result/error into MCP content shape. */