Resolving Queries & Auditing
The council.resolve() method submits a query for multi-LLM deliberation. The council.resolutions sub-namespace provides access to resolution history and detailed audit trails showing how each member voted.
Method Reference
| Method | HTTP | Endpoint | Returns |
|---|---|---|---|
council.resolve(params) | POST | /v1/council/resolve | CouncilResolveResponse |
council.resolutions.list(params?) | GET | /v1/council/resolutions | CouncilResolutionsListResponse |
council.resolutions.get(sessionId) | GET | /v1/council/resolutions/{sessionId} | CouncilResolutionDetail |
council.resolutions.audit(sessionId) | GET | /v1/council/resolutions/{sessionId}/audit | AuditResponse |
Resolve a Query
Submit a query for multi-model consensus resolution. You can either reference a saved council by ID or provide ad-hoc council members inline.
import { Chaos } from '@chaoslabs/ai-sdk';
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
// Resolve using a saved council
const resolution = await chaos.council.resolve({
query: 'Should we increase the AAVE WETH collateral factor from 80% to 85%?',
council_id: 'council-abc123',
answer_options: ['Yes, increase to 85%', 'No, keep at 80%', 'Increase to 82.5% as compromise'],
});
console.log(`Session: ${resolution.session_id}`);
console.log(`Status: ${resolution.status}`);
console.log(`Message: ${resolution.message}`);import { Chaos } from '@chaoslabs/ai-sdk';
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
// Resolve with ad-hoc members (no saved council needed)
const resolution = await chaos.council.resolve({
query: 'Is the current USDC depeg risk elevated enough to reduce exposure?',
consensus_algorithm: 'majority_vote',
council_members: [
{
member_id: 'mem-abc123',
provider: 'anthropic',
model_id: 'claude-sonnet-4-20250514',
model_name: 'Risk Analyst',
system_prompt: 'You are a stablecoin risk specialist.',
},
{
member_id: 'mem-def456',
provider: 'openai',
model_id: 'gpt-4o',
model_name: 'Market Analyst',
},
],
consensus_algorithm_kwargs: { min_confidence: 0.6 },
answer_options: ['Yes, reduce exposure', 'No, maintain current exposure'],
});
console.log(`Session: ${resolution.session_id}`);CouncilResolveParams
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | The question to deliberate on |
council_id | string | No | ID of a saved council to use |
consensus_algorithm | string | No | Override consensus algorithm (for ad-hoc resolution) |
consensus_algorithm_kwargs | Record<string, unknown> | No | Algorithm-specific keyword arguments |
council_members | Array<{...}> | No | Ad-hoc member definitions (see below) |
answer_options | string[] | No | Constrain answers to these options |
Ad-hoc council member fields:
| Field | Type | Required | Description |
|---|---|---|---|
member_id | string | Yes | Member identifier |
provider | string | Yes | LLM provider |
model_id | string | Yes | Model identifier |
model_name | string | Yes | Display name for the member |
system_prompt | string | No | System prompt for this resolution |
List Resolutions
Browse the history of all council resolutions with pagination and filtering.
import { Chaos } from '@chaoslabs/ai-sdk';
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
// List with pagination
const { resolutions, total, page, page_size } = await chaos.council.resolutions.list({
page: 1,
pageSize: 20,
});
console.log(`Page ${page} of ${Math.ceil(total / page_size)} (${total} total)\n`);
for (const r of resolutions) {
console.log(`[${r.status}] ${r.query.slice(0, 80)}`);
console.log(` Result: ${r.final_result ?? 'pending'}`);
console.log(` Council: ${r.council_name ?? 'ad-hoc'}`);
console.log(` Session: ${r.session_id}`);
console.log(` Date: ${r.created_at}\n`);
}
// Filter by status and council
const completed = await chaos.council.resolutions.list({
status: 'completed',
councilId: 'council-abc123',
});
// Filter by final result
const approvals = await chaos.council.resolutions.list({
finalResult: 'Yes, increase to 85%',
});CouncilResolutionsListParams
| Field | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number (1-indexed) |
pageSize | number | No | Results per page |
status | string | No | Filter by resolution status |
finalResult | string | No | Filter by final result text |
councilId | string | No | Filter by council ID |
Get Resolution Detail
Retrieve the full detail of a specific resolution, including all vote data and the final result. CouncilResolutionDetail extends AuditResponse with additional council and result fields.
import { Chaos } from '@chaoslabs/ai-sdk';
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
const detail = await chaos.council.resolutions.get('session-abc123');
console.log(`Query: ${detail.query}`);
console.log(`Status: ${detail.status}`);
console.log(`Final Result: ${detail.finalResult}`);
console.log(`Council: ${detail.councilName ?? 'ad-hoc'} (${detail.councilId ?? 'n/a'})`);
console.log(`Created: ${detail.createdAt}`);
console.log(`Completed: ${detail.completedAt}`);
if (detail.answerOptions) {
console.log(`Answer Options: ${detail.answerOptions.join(', ')}`);
}
console.log(`\nVotes: ${detail.voteTally.completed_votes}/${detail.voteTally.total_votes}`);
for (const [choice, count] of Object.entries(detail.voteTally.choices)) {
console.log(` ${choice}: ${count}`);
}Audit a Resolution
Inspect the full audit trail: every member's vote, reasoning, confidence score, timing, and any dissenting opinions.
import { Chaos } from '@chaoslabs/ai-sdk';
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
const audit = await chaos.council.resolutions.audit('session-abc123');
console.log(`Query: ${audit.query}`);
console.log(`Status: ${audit.status}`);
console.log(`Created: ${audit.createdAt}`);
console.log(`Completed: ${audit.completedAt}`);
// Vote tally
console.log(`\nTally (${audit.voteTally.completed_votes}/${audit.voteTally.total_votes} completed, ${audit.voteTally.failed_votes} failed):`);
for (const [choice, count] of Object.entries(audit.voteTally.choices)) {
const pct = ((count / audit.voteTally.completed_votes) * 100).toFixed(0);
console.log(` ${choice}: ${count} votes (${pct}%)`);
}
// Individual votes
console.log('\nMember Votes:');
for (const vote of audit.memberVotes) {
const label = vote.model_name ?? `${vote.provider}/${vote.model_id}`;
if (vote.status === 'completed') {
console.log(` ${label} -> ${vote.choice}`);
console.log(` Confidence: ${((vote.confidence ?? 0) * 100).toFixed(0)}%`);
console.log(` Reasoning: ${vote.reasoning}`);
console.log(` Time: ${vote.elapsed_ms}ms`);
} else {
console.log(` ${label} -> [${vote.status}]`);
}
}
// Dissenting opinions
if (audit.dissentSummary.length > 0) {
console.log('\nDissenting Opinions:');
for (const d of audit.dissentSummary) {
console.log(` Member ${d.member_id}: chose "${d.choice}"`);
console.log(` ${d.reasoning}`);
}
} else {
console.log('\nNo dissenting opinions (unanimous decision).');
}AuditResponse
| Field | Type | Description |
|---|---|---|
sessionId | string | Resolution session identifier |
query | string | The original query |
status | string | Resolution status |
createdAt | string | ISO 8601 creation timestamp |
completedAt | string | null | ISO 8601 completion timestamp |
memberVotes | ModelVote[] | Individual vote from each member |
contextSources | unknown[] | Context sources used during deliberation |
dissentSummary | AuditDissent[] | Members who voted against the consensus |
voteTally | VoteTally | Aggregated vote counts |
ModelVote
| Field | Type | Description |
|---|---|---|
provider | string | LLM provider |
model_id | string | Model identifier |
model_name | string | null | Display name |
member_id | string | null | Council member ID |
status | 'completed' | 'failed' | 'pending' | Vote status |
choice | string | null | The member's chosen answer |
reasoning | string | null | The member's reasoning |
confidence | number | null | Confidence score (0-1) |
elapsed_ms | number | null | Time taken in milliseconds |
VoteTally
| Field | Type | Description |
|---|---|---|
total_votes | number | Total votes expected |
completed_votes | number | Votes successfully cast |
failed_votes | number | Votes that failed |
choices | Record<string, number> | Count per choice |
AuditDissent
| Field | Type | Description |
|---|---|---|
member_id | string | Dissenting member ID |
choice | string | The dissenter's choice |
reasoning | string | Why the member dissented |
CouncilResolutionDetail
Extends AuditResponse with:
| Field | Type | Description |
|---|---|---|
councilId | string | null | Council used (null for ad-hoc) |
councilName | string | null | Council display name |
finalResult | string | null | Consensus result |
answerOptions | string[] | null | Answer options provided |