Resolving Queries & Auditing

Updated

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

MethodHTTPEndpointReturns
council.resolve(params)POST/v1/council/resolveCouncilResolveResponse
council.resolutions.list(params?)GET/v1/council/resolutionsCouncilResolutionsListResponse
council.resolutions.get(sessionId)GET/v1/council/resolutions/{sessionId}CouncilResolutionDetail
council.resolutions.audit(sessionId)GET/v1/council/resolutions/{sessionId}/auditAuditResponse

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.

resolve-with-council.ts
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}`);
resolve-ad-hoc.ts
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

FieldTypeRequiredDescription
querystringYesThe question to deliberate on
council_idstringNoID of a saved council to use
consensus_algorithmstringNoOverride consensus algorithm (for ad-hoc resolution)
consensus_algorithm_kwargsRecord<string, unknown>NoAlgorithm-specific keyword arguments
council_membersArray<{...}>NoAd-hoc member definitions (see below)
answer_optionsstring[]NoConstrain answers to these options

Ad-hoc council member fields:

FieldTypeRequiredDescription
member_idstringYesMember identifier
providerstringYesLLM provider
model_idstringYesModel identifier
model_namestringYesDisplay name for the member
system_promptstringNoSystem prompt for this resolution
[@portabletext/react] Unknown block type "callout", specify a component for it in the `components.types` prop

List Resolutions

Browse the history of all council resolutions with pagination and filtering.

list-resolutions.ts
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

FieldTypeRequiredDescription
pagenumberNoPage number (1-indexed)
pageSizenumberNoResults per page
statusstringNoFilter by resolution status
finalResultstringNoFilter by final result text
councilIdstringNoFilter 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.

get-resolution.ts
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.

audit-resolution.ts
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

FieldTypeDescription
sessionIdstringResolution session identifier
querystringThe original query
statusstringResolution status
createdAtstringISO 8601 creation timestamp
completedAtstring | nullISO 8601 completion timestamp
memberVotesModelVote[]Individual vote from each member
contextSourcesunknown[]Context sources used during deliberation
dissentSummaryAuditDissent[]Members who voted against the consensus
voteTallyVoteTallyAggregated vote counts

ModelVote

FieldTypeDescription
providerstringLLM provider
model_idstringModel identifier
model_namestring | nullDisplay name
member_idstring | nullCouncil member ID
status'completed' | 'failed' | 'pending'Vote status
choicestring | nullThe member's chosen answer
reasoningstring | nullThe member's reasoning
confidencenumber | nullConfidence score (0-1)
elapsed_msnumber | nullTime taken in milliseconds

VoteTally

FieldTypeDescription
total_votesnumberTotal votes expected
completed_votesnumberVotes successfully cast
failed_votesnumberVotes that failed
choicesRecord<string, number>Count per choice

AuditDissent

FieldTypeDescription
member_idstringDissenting member ID
choicestringThe dissenter's choice
reasoningstringWhy the member dissented

CouncilResolutionDetail

Extends AuditResponse with:

FieldTypeDescription
councilIdstring | nullCouncil used (null for ad-hoc)
councilNamestring | nullCouncil display name
finalResultstring | nullConsensus result
answerOptionsstring[] | nullAnswer options provided
Was this helpful?