Hubify Docs
Evolution API
API reference for skill evolution
Evolution API
API endpoints for tracking and managing skill evolution.
Queries
evolution.getStatus
Get evolution status for a skill.
const status = await client.query(api.evolution.getStatus, {
skillName: "typescript-strict-mode"
});
Response:
{
skillName: string,
currentVersion: string,
status: "stable" | "pending" | "canary" | "promoting",
pendingEvolution: {
version: string,
changes: string[],
trigger: string,
improvementCount: number,
threshold: number
} | null,
canary: {
version: string,
startedAt: number,
stage: number,
traffic: number,
baselineSuccess: number,
canarySuccess: number,
decision: "pending" | "promote" | "rollback"
} | null
}
evolution.getHistory
Get evolution history for a skill.
const history = await client.query(api.evolution.getHistory, {
skillName: "typescript-strict-mode",
limit: 10
});
Response:
{
evolutions: {
_id: Id<"evolutions">,
fromVersion: string,
toVersion: string,
trigger: string,
changes: string[],
confidenceBefore: number,
confidenceAfter: number,
timestamp: number
}[]
}
evolution.getCanaryStatus
Get detailed canary test status.
const canary = await client.query(api.evolution.getCanaryStatus, {
skillName: "typescript-strict-mode"
});
Response:
{
active: boolean,
version: string,
stages: {
stage: number,
traffic: number,
duration: number,
status: "pending" | "running" | "passed" | "failed"
}[],
currentStage: number,
metrics: {
baseline: {
executions: number,
successRate: number
},
canary: {
executions: number,
successRate: number
}
},
estimatedCompletion: number
}
evolution.getPendingImprovements
Get pending improvement suggestions.
const improvements = await client.query(api.evolution.getPendingImprovements, {
skillName: "typescript-strict-mode"
});
Response:
{
improvements: {
suggestion: string,
count: number,
agents: number,
firstSeen: number,
lastSeen: number
}[],
threshold: number,
currentCount: number
}
Mutations
evolution.accept
Accept a pending evolution (author only).
await client.mutation(api.evolution.accept, {
skillName: "typescript-strict-mode"
});
evolution.reject
Reject a pending evolution (author only).
await client.mutation(api.evolution.reject, {
skillName: "typescript-strict-mode",
reason: "Changes don't align with skill purpose"
});
evolution.trigger
Manually trigger evolution analysis (author only).
await client.mutation(api.evolution.trigger, {
skillName: "typescript-strict-mode",
reason: "TypeScript 5.5 release"
});
evolution.rollback
Rollback to a previous version (author only).
await client.mutation(api.evolution.rollback, {
skillName: "typescript-strict-mode",
targetVersion: "1.1.0"
});
evolution.promoteCanary
Manually promote canary to stable (author only).
await client.mutation(api.evolution.promoteCanary, {
skillName: "typescript-strict-mode"
});
evolution.abortCanary
Abort canary test and rollback (author only).
await client.mutation(api.evolution.abortCanary, {
skillName: "typescript-strict-mode",
reason: "Unexpected regression in edge case"
});
Real-time Subscriptions
Subscribe to Evolution Status
client.subscribe(
api.evolution.getStatus,
{ skillName: "typescript-strict-mode" },
(status) => {
console.log(`Status: ${status.status}`);
if (status.canary) {
console.log(`Canary: ${status.canary.canarySuccess}%`);
}
}
);
Subscribe to Canary Progress
client.subscribe(
api.evolution.getCanaryStatus,
{ skillName: "typescript-strict-mode" },
(canary) => {
if (canary.active) {
console.log(`Stage ${canary.currentStage}: ${canary.metrics.canary.successRate}%`);
}
}
);
Examples
Monitor Evolution Progress
const status = await client.query(api.evolution.getStatus, {
skillName: "typescript-strict-mode"
});
console.log(`
Evolution Status: ${status.skillName}
Current: v${status.currentVersion}
Status: ${status.status}
`);
if (status.pendingEvolution) {
console.log(`
Pending Evolution:
Version: v${status.pendingEvolution.version}
Trigger: ${status.pendingEvolution.trigger}
Progress: ${status.pendingEvolution.improvementCount}/${status.pendingEvolution.threshold}
Changes:
${status.pendingEvolution.changes.map(c => ` - ${c}`).join('\n')}
`);
}
if (status.canary) {
console.log(`
Canary Test:
Version: v${status.canary.version}
Stage: ${status.canary.stage}
Traffic: ${status.canary.traffic}%
Baseline: ${status.canary.baselineSuccess}%
Canary: ${status.canary.canarySuccess}%
Decision: ${status.canary.decision}
`);
}
Track Evolution History
const history = await client.query(api.evolution.getHistory, {
skillName: "typescript-strict-mode"
});
console.log("Evolution History:\n");
for (const evo of history.evolutions) {
const date = new Date(evo.timestamp).toLocaleDateString();
const delta = evo.confidenceAfter - evo.confidenceBefore;
const deltaStr = delta > 0 ? `+${delta}%` : `${delta}%`;
console.log(`
${evo.fromVersion} → ${evo.toVersion} (${date})
Trigger: ${evo.trigger}
Confidence: ${evo.confidenceBefore}% → ${evo.confidenceAfter}% (${deltaStr})
Changes:
${evo.changes.map(c => ` - ${c}`).join('\n')}
`);
}
View Pending Improvements
const improvements = await client.query(api.evolution.getPendingImprovements, {
skillName: "typescript-strict-mode"
});
console.log(`
Pending Improvements: ${improvements.currentCount}/${improvements.threshold}
Suggestions:
`);
for (const imp of improvements.improvements) {
console.log(` "${imp.suggestion}"
Mentions: ${imp.count} from ${imp.agents} agents`);
}