Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
64cad76
Merge pull request #1 from Zoo-Code-Org/main
iskandarsulaili May 21, 2026
a40bdc1
feat: implement Self-Improving Manager for adaptive learning
iskandarsulaili May 21, 2026
9805793
feat: Enhance SelfImprovingManager with MemoryStore and SkillUsageSto…
iskandarsulaili May 22, 2026
c6d0b55
feat: Implement ReviewPromptFactory and TranscriptRecall for self-imp…
iskandarsulaili May 22, 2026
445e9ed
feat: Enhance self-improvement system with user message tracking and …
iskandarsulaili May 22, 2026
0ff067a
Merge branch 'main' into selfimproving
iskandarsulaili May 22, 2026
f15a9a6
feat: Implement memory backend system with AgentMemoryAdapter and Mem…
iskandarsulaili May 22, 2026
fb39c36
fix: harden self-improving memory deletion and recall
iskandarsulaili May 22, 2026
9f2688f
fix: tighten self-improving pattern merges
iskandarsulaili May 22, 2026
53490f1
test: tighten self-improving regression coverage
iskandarsulaili May 22, 2026
f1210f7
fix: harden transcript recall loading
iskandarsulaili May 22, 2026
327a7d3
refactor: align self-improving shared types
iskandarsulaili May 22, 2026
f90b884
fix: refine self-improving memory search and scoring
iskandarsulaili May 22, 2026
e38aad8
fix: serialize transcript recall lazy initialization
iskandarsulaili May 22, 2026
7860dc1
fix: preserve substring text in agentmemory forget search
iskandarsulaili May 22, 2026
4f72974
fix: capture interactive user corrections for self-improving
iskandarsulaili May 23, 2026
29af44c
fix: feed code index search hits into self-improving
iskandarsulaili May 23, 2026
f658165
test: verify extension startup initializes self-improving
iskandarsulaili May 23, 2026
f672d56
feat: add skill mutation APIs and auto-skill toggle
iskandarsulaili May 23, 2026
732be8f
feat: wire self-improving auto skill actions
iskandarsulaili May 23, 2026
02ed3ae
feat: expose auto-skill toggle in experimental settings
iskandarsulaili May 23, 2026
f6d3408
test: cover auto-skill experiment gating
iskandarsulaili May 23, 2026
3dacd05
Merge branch 'main' into selfimproving
iskandarsulaili May 23, 2026
7cf030e
Add configurable self-improving memory backend settings
iskandarsulaili May 23, 2026
99ce4f2
[verified] Add workspace/global self-improving scope controls
iskandarsulaili May 23, 2026
7a8a95c
feat: live refresh skills settings on skill updates
iskandarsulaili May 23, 2026
b6b80aa
fix: avoid blocking submitUserMessage on correction telemetry
iskandarsulaili May 23, 2026
813f4c9
fix: make default auto-skill lookup source-aware
iskandarsulaili May 23, 2026
f024a3f
fix: support secondary mode slugs in skill updates
iskandarsulaili May 23, 2026
3b8b150
refactor: type getGlobalStateSafe against GlobalState
iskandarsulaili May 23, 2026
1c17fdc
test: assert global routing for self-improving settings
iskandarsulaili May 23, 2026
b5b4c8b
test: verify self-improving settings stay local before save
iskandarsulaili May 23, 2026
3f5c5c7
i18n: localize self-improving scope labels
iskandarsulaili May 23, 2026
4dbb091
fix: validate SKILL.md structure before persisting
iskandarsulaili May 23, 2026
00d160e
fix: commit learning state after pattern persistence
iskandarsulaili May 23, 2026
d15bda4
fix: align AgentMemoryAdapter with agentmemory v3 API and harden Lear…
iskandarsulaili May 24, 2026
0173e13
fix: lower self-improving thresholds and pass tool names on failure
iskandarsulaili May 25, 2026
2c372f6
feat: Hermes-style curator review with candidate rendering and archiv…
iskandarsulaili May 25, 2026
54b0207
feat: add self-improving status UI component in experimental settings
iskandarsulaili May 25, 2026
785fc7c
fix: Small div fix
iskandarsulaili May 25, 2026
698ac62
Hermes-grade curator: LLM umbrella consolidation, tar.gz backup+rollb…
iskandarsulaili May 26, 2026
b806206
self-improving: activate by persisted config (bypass experiment gate)
iskandarsulaili May 26, 2026
fd40e09
self-improving: activate by persisted config (bypass experiment gate)
iskandarsulaili May 26, 2026
e8ed699
Merge branch 'main' into selfimproving
iskandarsulaili May 26, 2026
61b5549
self-improving: insights engine, curator overhaul, skill usage tracking
iskandarsulaili May 27, 2026
dcb8a8c
self-improving: lower toolNames threshold to 1, autoSkills experiment…
iskandarsulaili May 27, 2026
7245e6f
self-improving: triggerReview on task completion + streaming_failed a…
iskandarsulaili May 27, 2026
8368b06
self-improving: auto-mode orchestrator + mode factory + selfImproving…
iskandarsulaili May 27, 2026
1531d39
self-improving: review team + trust service + selfImprovingReviewTeam…
iskandarsulaili May 27, 2026
f9c1e19
self-improving: resilience service (streaming backoff/recovery) + too…
iskandarsulaili May 27, 2026
560bcf5
self-improving: QuestionEvaluatorService + selfImprovingQuestionEvalu…
iskandarsulaili May 27, 2026
fdb7253
missed commit
iskandarsulaili May 27, 2026
607499a
i18n: add SELF_IMPROVING_QUESTION_EVALUATION locale strings across al…
iskandarsulaili May 27, 2026
0193cb4
fix: TS errors blocking push — add mode_switch to ClineAsk, fix Date→…
iskandarsulaili May 28, 2026
1c98acb
fix: ReviewTeamService payload property checks, ActionExecutor skills…
iskandarsulaili May 28, 2026
deb3706
self-improving: direct Task.ts references for ToolErrorHealer/Resilie…
iskandarsulaili May 28, 2026
6ed7673
self-improving: fix ToolErrorHealer ordering in Task.ts, TrustService…
iskandarsulaili May 28, 2026
c5a8f21
self-improving: attempt_completion dedup via last result tracking + t…
iskandarsulaili May 28, 2026
4ce3ae7
Merge remote-tracking branch 'upstream/main' into selfimproving
iskandarsulaili May 28, 2026
ad7dc26
resolve merge conflict: keep our pnpm-lock.yaml, fix ShadowCheckpoint…
iskandarsulaili May 28, 2026
2ced1a1
docs: add Experimental warning banner + full comparison table vs Zoo-…
iskandarsulaili May 28, 2026
e8c5d4e
fix: FAQ formatting — bold Q/A labels, each on separate line with bla…
iskandarsulaili May 28, 2026
0106a88
fix: FAQ for readibility and add special messages
iskandarsulaili May 28, 2026
2153c7d
fix: README formatting
iskandarsulaili May 28, 2026
f5df9ae
self-improving: AutoModeOrchestrator edge cases + ReviewTeamService s…
iskandarsulaili May 28, 2026
f0b0bf5
self-improving: SelfImprovingManager constructor ordering fix + ModeF…
iskandarsulaili May 28, 2026
3213bf7
self-improving: FeedbackCollector, PatternAnalyzer improvements + Lea…
iskandarsulaili May 28, 2026
bfc2741
self-improving: fix TS — add getPromptContext alias on ImprovementApp…
iskandarsulaili May 28, 2026
0d6e1df
self-improving: ToolErrorHealer updates + Task.ts, responses.ts, READ…
iskandarsulaili May 28, 2026
c60e2ac
self-improving: QuestionEvaluatorService updates + 17 locale i18n add…
iskandarsulaili May 28, 2026
5ac0051
self-improving: mode types + ModeSelector + ExperimentalSettings UI +…
iskandarsulaili May 28, 2026
a43f714
self-improving: git.ts kaizen infrastructure + mode types + fix kaize…
iskandarsulaili May 28, 2026
b03b59a
self-improving: ResilienceService + CascadeTracker + ErrorClassifier …
iskandarsulaili May 28, 2026
200a350
Merge branch 'main' into selfimproving
iskandarsulaili May 28, 2026
20aa468
self-improving: SelfImprovingStatus + SettingsView UI + experiment wi…
iskandarsulaili May 29, 2026
e102f2c
self-improving: README KAIZEN docs + mode type fixes
iskandarsulaili May 29, 2026
f40ec06
self-improving: locale i18n re-sync across all 17 languages
iskandarsulaili May 29, 2026
3f36a6e
self-improving: ActionExecutor, ModeFactoryService, ReviewTeamService…
iskandarsulaili May 29, 2026
f333522
self-improving: CustomModesManager + ActionExecutor + ModeFactoryServ…
iskandarsulaili May 29, 2026
9a2873a
self-improving: ContextProxy + webviewMessageHandler + SettingsView w…
iskandarsulaili May 29, 2026
099a0af
self-improving: VerificationEngine + CodeIndexAdapter + ClineProvider…
iskandarsulaili May 29, 2026
41c6149
self-improving: RequirementsVerifier + AttemptCompletionTool wiring +…
iskandarsulaili May 29, 2026
ccc3e54
self-improving: KeywordConflictResolver + LLMConflictResolver + Requi…
iskandarsulaili May 29, 2026
44f81e9
self-improving: SettingsView conflict-resolver UI wiring
iskandarsulaili May 29, 2026
751de2b
self-improving: RequirementsVerifier + VerificationEngine init + Self…
iskandarsulaili May 29, 2026
1d65dea
self-improving: remove stale SettingsView conflict-resolver wiring (r…
iskandarsulaili May 29, 2026
1e73b1a
self-improving: i18n locale strings + ExperimentalSettings UI + test …
iskandarsulaili May 29, 2026
873c1c8
modes: ONE-SHOT + KAIZEN orchestrators now delegate via new_task (gro…
iskandarsulaili May 29, 2026
8a0d75a
modes: add Phase 0 Deep Research to ONE-SHOT + KAIZEN orchestrators, …
iskandarsulaili May 29, 2026
d15f215
self-improving: PreventionEngine setCodeIndexAdapter + CodeIndexAdapt…
iskandarsulaili May 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
325 changes: 108 additions & 217 deletions README.md

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions packages/types/src/__tests__/learning-memory.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// npx vitest run packages/types/src/__tests__/learning-memory.test.ts

import {
DEFAULT_LEARNING_CONFIG,
EMPTY_LEARNING_STATE,
learningConfigSchema,
learningStateSchema,
memoryContextSchema,
type LearningState,
type MemoryContext,
} from "../index.js"

describe("learning types", () => {
it("exports the default learning config", () => {
expect(DEFAULT_LEARNING_CONFIG).toMatchObject({
enabled: false,
reviewOnTurnCount: 10,
reviewOnToolIterationCount: 50,
})
})

it("parses the empty learning state", () => {
const result = learningStateSchema.safeParse(EMPTY_LEARNING_STATE)

expect(result.success).toBe(true)
expect(result.data).toEqual(EMPTY_LEARNING_STATE)
})

it("applies learning config defaults", () => {
const result = learningConfigSchema.parse({})

expect(result).toEqual(DEFAULT_LEARNING_CONFIG)
})

it("preserves TypeScript inference for learning state", () => {
const state: LearningState = EMPTY_LEARNING_STATE

expect(state.version).toBe(1)
})
})

describe("memory types", () => {
it("parses a valid memory context", () => {
const input: MemoryContext = {
entries: [],
revision: 0,
generatedAt: Date.now(),
}

const result = memoryContextSchema.safeParse(input)

expect(result.success).toBe(true)
expect(result.data).toEqual(input)
})

it("rejects more than ten memory entries", () => {
const result = memoryContextSchema.safeParse({
entries: Array.from({ length: 11 }, (_, index) => ({
id: `entry-${index}`,
content: "memory",
source: "learning",
createdAt: index,
updatedAt: index,
})),
revision: 0,
generatedAt: Date.now(),
})

expect(result.success).toBe(false)
})
})
45 changes: 44 additions & 1 deletion packages/types/src/experiment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,31 @@ import type { Keys, Equals, AssertEqual } from "./type-fu.js"
* ExperimentId
*/

export const experimentIds = ["preventFocusDisruption", "imageGeneration", "runSlashCommand", "customTools"] as const
export const experimentIds = [
"preventFocusDisruption",
"imageGeneration",
"runSlashCommand",
"customTools",
"selfImproving",
"selfImprovingAutoSkills",
"selfImprovingAutoMode",
"selfImprovingReviewTeam",
"selfImprovingFullTrust",
"selfImprovingQuestionEvaluation",
"selfImprovingPromptQuality",
"selfImprovingToolPreference",
"selfImprovingSkillMerge",
"selfImprovingPersistCounts",
"selfImprovingCodeIndex",
"oneShotOrchestrator",
"kaizenOrchestrator",
"preventionEngine",
"cascadeTracker",
"resilienceService",
"toolErrorHealer",
"verificationEngine",
"requirementsVerification",
] as const

export const experimentIdsSchema = z.enum(experimentIds)

Expand All @@ -21,6 +45,25 @@ export const experimentsSchema = z.object({
imageGeneration: z.boolean().optional(),
runSlashCommand: z.boolean().optional(),
customTools: z.boolean().optional(),
selfImproving: z.boolean().optional(),
selfImprovingAutoSkills: z.boolean().optional(),
selfImprovingAutoMode: z.boolean().optional(),
selfImprovingReviewTeam: z.boolean().optional(),
selfImprovingFullTrust: z.boolean().optional(),
selfImprovingQuestionEvaluation: z.boolean().optional(),
selfImprovingPromptQuality: z.boolean().optional(),
selfImprovingToolPreference: z.boolean().optional(),
selfImprovingSkillMerge: z.boolean().optional(),
selfImprovingPersistCounts: z.boolean().optional(),
selfImprovingCodeIndex: z.boolean().optional(),
oneShotOrchestrator: z.boolean().optional(),
kaizenOrchestrator: z.boolean().optional(),
preventionEngine: z.boolean().optional(),
cascadeTracker: z.boolean().optional(),
resilienceService: z.boolean().optional(),
toolErrorHealer: z.boolean().optional(),
verificationEngine: z.boolean().optional(),
requirementsVerification: z.boolean().optional(),
})

export type Experiments = z.infer<typeof experimentsSchema>
Expand Down
18 changes: 18 additions & 0 deletions packages/types/src/global-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ export const DEFAULT_CHECKPOINT_TIMEOUT_SECONDS = 15
* GlobalSettings
*/

export const selfImprovingScopeSchema = z.enum(["workspace", "global"])

export type SelfImprovingScope = z.infer<typeof selfImprovingScopeSchema>

export const globalSettingsSchema = z.object({
currentApiConfigName: z.string().optional(),
listApiConfigMeta: z.array(providerSettingsEntrySchema).optional(),
Expand All @@ -92,6 +96,20 @@ export const globalSettingsSchema = z.object({
imageGenerationProvider: z.enum(["openrouter"]).optional(),
openRouterImageApiKey: z.string().optional(),
openRouterImageGenerationSelectedModel: z.string().optional(),
memoryBackend: z.enum(["builtin", "agentmemory"]).optional(),
agentMemoryUrl: z.string().optional(),
selfImprovingScope: selfImprovingScopeSchema.optional(),
selfImprovingAutoSkillsScope: selfImprovingScopeSchema.optional(),

// KAIZEN orchestrator configuration
kaizenFrequency: z.number().min(1).max(100).optional(),
kaizenMiniGoal: z.string().optional(),
kaizenLimit: z.number().min(1).max(1000).optional(),

// KAIZEN git auto-push configuration
kaizenAutoPush: z.boolean().optional(),
kaizenRemoteName: z.string().optional(),
kaizenCommitTemplate: z.string().optional(),

customCondensingPrompt: z.string().optional(),

Expand Down
3 changes: 3 additions & 0 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ export * from "./global-settings.js"
export * from "./history.js"
export * from "./image-generation.js"
export * from "./ipc.js"
export * from "./learning.js"
export * from "./marketplace.js"
export * from "./mcp.js"
export * from "./message.js"
export * from "./memory.js"
export * from "./mode.js"
export * from "./model.js"
export * from "./provider-settings.js"
Expand Down
205 changes: 205 additions & 0 deletions packages/types/src/learning.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import { z } from "zod"

/**
* FeedbackSignal - types of learning observations
*/
export const feedbackSignalSchema = z.enum([
"USER_CORRECTION",
"TASK_SUCCESS",
"TASK_FAILURE",
"PATTERN_REPEAT",
"CODE_INDEX_HIT",
"PROMPT_QUALITY",
"TOOL_PREFERENCE",
])

export type FeedbackSignal = z.infer<typeof feedbackSignalSchema>

/**
* LearningConfig - configuration for the learning system
*/
export const learningConfigSchema = z.object({
enabled: z.boolean().default(false),
reviewOnTurnCount: z.number().int().min(1).default(5),
reviewOnToolIterationCount: z.number().int().min(1).default(20),
reviewOnEveryTurn: z.boolean().default(false),
maxStoredPatterns: z.number().int().min(1).default(100),
maxStoredEvents: z.number().int().min(1).default(500),
maxPromptPatterns: z.number().int().min(1).default(5),
curatorEnabled: z.boolean().default(true),
curatorIntervalMs: z.number().int().min(60000).default(3600000),
staleAfterDays: z.number().int().min(1).default(14),
archiveAfterDays: z.number().int().min(1).default(60),
codeIndexCorrelationEnabled: z.boolean().default(true),
})

export type LearningConfig = z.infer<typeof learningConfigSchema>

export const DEFAULT_LEARNING_CONFIG: LearningConfig = {
enabled: true,
reviewOnTurnCount: 3,
reviewOnToolIterationCount: 10,
reviewOnEveryTurn: false,
maxStoredPatterns: 100,
maxStoredEvents: 500,
maxPromptPatterns: 5,
curatorEnabled: true,
curatorIntervalMs: 3_600_000,
staleAfterDays: 14,
archiveAfterDays: 60,
codeIndexCorrelationEnabled: true,
}

/**
* LearningEvent - a single learning observation
*/
export const learningEventSchema = z.object({
id: z.string(),
signal: feedbackSignalSchema,
timestamp: z.number(),
taskId: z.string().optional(),
workspacePath: z.string().optional(),
mode: z.string().optional(),
context: z.object({
userTurnCount: z.number().optional(),
toolIterationCount: z.number().optional(),
toolNames: z.array(z.string()).optional(),
promptFingerprint: z.string().optional(),
errorKey: z.string().optional(),
codeIndex: z
.object({
available: z.boolean(),
hits: z.number(),
topScore: z.number().optional(),
})
.optional(),
}),
outcome: z.object({
success: z.boolean().optional(),
corrected: z.boolean().optional(),
summary: z.string().optional(),
confidenceDelta: z.number().optional(),
}),
})

export type LearningEvent = z.infer<typeof learningEventSchema>

/**
* PatternState - lifecycle state for learned patterns
*/
export const patternStateSchema = z.enum(["active", "stale", "archived"])

export type PatternState = z.infer<typeof patternStateSchema>

/**
* PatternType - category of learned pattern
*/
export const patternTypeSchema = z.enum(["prompt", "tool", "error", "skill", "code-index"])

export type PatternType = z.infer<typeof patternTypeSchema>

/**
* LearnedPattern - a pattern extracted from learning events
*/
export const learnedPatternSchema = z.object({
id: z.string(),
patternType: patternTypeSchema,
state: patternStateSchema,
summary: z.string(),
confidenceScore: z.number().min(0).max(1),
frequency: z.number().int().min(0),
successRate: z.number().min(0).max(1),
firstSeenAt: z.number(),
lastSeenAt: z.number(),
lastAppliedAt: z.number().optional(),
sourceSignals: z.array(feedbackSignalSchema),
context: z.object({
toolNames: z.array(z.string()).optional(),
errorKeys: z.array(z.string()).optional(),
modes: z.array(z.string()).optional(),
workspacePaths: z.array(z.string()).optional(),
promptFingerprint: z.string().optional(),
}),
})

export type LearnedPattern = z.infer<typeof learnedPatternSchema>

/**
* ActionType - types of improvement actions
*/
export const actionTypeSchema = z.enum([
"PROMPT_ENRICHMENT",
"TOOL_PREFERENCE",
"ERROR_AVOIDANCE",
"SKILL_SUGGESTION",
"SKILL_CREATE",
"SKILL_UPDATE",
"SKILL_MERGE",
])

export type ActionType = z.infer<typeof actionTypeSchema>

/**
* ImprovementAction - an action to apply based on learned patterns
*/
export const improvementActionSchema = z.object({
id: z.string(),
actionType: actionTypeSchema,
target: z.enum(["system-prompt", "task-execution", "skills-manager", "review-queue"]),
payload: z.record(z.string(), z.unknown()),
timestamp: z.number(),
})

export type ImprovementAction = z.infer<typeof improvementActionSchema>

/**
* LearningTelemetry - telemetry counters for the learning system
*/
export const learningTelemetrySchema = z.object({
promptEnrichmentUses: z.number().int().default(0),
toolPreferenceUses: z.number().int().default(0),
errorAvoidanceUses: z.number().int().default(0),
skillSuggestionCount: z.number().int().default(0),
lastReviewAt: z.number().optional(),
lastCuratorRunAt: z.number().optional(),
})

export type LearningTelemetry = z.infer<typeof learningTelemetrySchema>

/**
* LearningState - full serializable state of the learning system
*/
export const learningStateSchema = z.object({
version: z.literal(1),
config: learningConfigSchema,
counters: z.object({
userTurnsSinceReview: z.number().int().default(0),
toolIterationsSinceReview: z.number().int().default(0),
}),
patterns: z.array(learnedPatternSchema).default([]),
archivedPatterns: z.array(learnedPatternSchema).default([]),
recentEvents: z.array(learningEventSchema).default([]),
pendingActions: z.array(improvementActionSchema).default([]),
telemetry: learningTelemetrySchema,
})

export type LearningState = z.infer<typeof learningStateSchema>

export const EMPTY_LEARNING_STATE: LearningState = {
version: 1,
config: DEFAULT_LEARNING_CONFIG,
counters: {
userTurnsSinceReview: 0,
toolIterationsSinceReview: 0,
},
patterns: [],
archivedPatterns: [],
recentEvents: [],
pendingActions: [],
telemetry: {
promptEnrichmentUses: 0,
toolPreferenceUses: 0,
errorAvoidanceUses: 0,
skillSuggestionCount: 0,
},
}
Loading