Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ clicky
!task/ui/tsconfig.json
!examples/enitity/Taskfile.yaml
!examples/enitity/webapp/index.html
!examples/enitity/webapp/.oxlintrc.json
!examples/enitity/webapp/package.json
!examples/enitity/webapp/pnpm-lock.yaml
!examples/enitity/webapp/pnpm-workspace.yaml
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ library in your own application, see [CLAUDE.md](CLAUDE.md) and [README.md](READ
make build # build ./clicky from ./cmd/clicky (NEVER run `go build` directly)
make test # go test -v ./... (ROOT module only — example modules are separate)
make lint # golangci-lint v2.8.0 (pinned into .bin/) + go vet ./...
make lint-clicky-ui # run clicky-ui's custom oxlint rules against the entity demo webapp
make fmt # gofmt -s -w . and `go mod tidy` across every module in GO_MODULES
make check # fmt + lint + test
make task-ui # rebuild the embedded Preact task-UI bundle (task/ui/dist/taskui.js)
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,14 @@ install: build
mv clicky /usr/local/bin/clicky

# Run linter
.PHONY: lint
.PHONY: lint lint-clicky-ui
lint: golangci-lint
$(GOLANGCI_LINT) run ./...
go vet ./...

lint-clicky-ui:
cd examples/enitity/webapp && pnpm install --frozen-lockfile && pnpm run lint:clicky-ui

.PHONY: golangci-lint
golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
$(GOLANGCI_LINT): $(LOCALBIN)
Expand Down
6 changes: 3 additions & 3 deletions aichat/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

_ "github.com/flanksource/captain/pkg/ai/provider" // registers the agent backends
capapi "github.com/flanksource/captain/pkg/api"
"github.com/flanksource/commons-db/shell"
)

// AgentOptions configures the captain agent engine (EngineAgent models). The
Expand Down Expand Up @@ -143,11 +144,10 @@ func (s *Server) agentRequest(req ChatRequest, resumeID string) capapi.Spec {
return capapi.Spec{
Prompt: capapi.Prompt{User: prompt, System: s.system},
Model: capapi.Model{Effort: capapi.Effort(req.ReasoningEffort), Temperature: req.Temperature},
Budget: capapi.Budget{Cost: req.Budget.Cost, MaxTokens: req.Budget.MaxTokens},
Budget: capapi.Budget{Cost: req.Budget.Cost, MaxTokens: req.Budget.MaxTokens, MaxTurns: s.opts.Agent.MaxTurns},
Permissions: perms,
Context: capapi.Context{Dir: s.opts.Agent.Cwd},
Setup: &shell.Setup{Cwd: s.opts.Agent.Cwd},
SessionID: resumeID,
MaxTurns: s.opts.Agent.MaxTurns,
}
}

Expand Down
2 changes: 1 addition & 1 deletion aichat/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ func TestAgentModelsInCatalog(t *testing.T) {
}{
"claude-agent-sonnet": {EngineAgent, capapi.BackendClaudeAgent, ""},
"codex-gpt-5-codex": {EngineAgent, capapi.BackendCodexCLI, "gpt-5-codex"},
"anthropic/claude-sonnet-4-6": {EngineGenkit, "", ""},
"anthropic/claude-sonnet-5": {EngineGenkit, "", ""},
}
for id, want := range cases {
m, err := LookupModel(id)
Expand Down
37 changes: 21 additions & 16 deletions aichat/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,30 +81,35 @@ type ModelInfo struct {
}

// DefaultModelID is the chat backend's default, mirroring captain pkg/ai
// (Anthropic claude-sonnet-4 is captain's NewAnthropic default).
const DefaultModelID = "anthropic/claude-sonnet-4-5"

// defaultCatalog is the v1 model menu. Mirrors captain pkg/ai provider defaults
// so the chat agrees with the rest of the stack.
// (Anthropic Sonnet 5 is captain's default).
const DefaultModelID = "anthropic/claude-sonnet-5"

// defaultCatalog is the model menu: only the latest generally-available model
// per tier for each provider — no preview or superseded entries. Mirrors
// captain pkg/ai's catalog so the chat agrees with the rest of the stack.
//
// Provider currency (reviewed 2026-07-02):
// - Anthropic: Fable 5 (most capable), Opus 4.8, Sonnet 5, Haiku 4.5. Mythos 5
// is Project Glasswing invite-only, so it is intentionally excluded.
// - OpenAI: GPT-5.5 (flagship) and GPT-5.4 mini. GPT-5.6 is preview-only.
// - Google: Gemini 2.5 Pro is the newest GA Pro (all Gemini 3.x Pro models are
// still preview), paired with the GA Gemini 3.5 Flash.
var defaultCatalog = []Model{
{ID: "anthropic/claude-sonnet-4-6", Provider: ProviderAnthropic, Label: "Claude Sonnet 4.6", Reasoning: true, ContextWindow: 200000},
{ID: "anthropic/claude-opus-4-8", Provider: ProviderAnthropic, Label: "Claude Opus 4.8", Reasoning: true, ContextWindow: 200000},
{ID: "anthropic/claude-fable-5", Provider: ProviderAnthropic, Label: "Claude Fable 5", Reasoning: true, ContextWindow: 1000000},
{ID: "anthropic/claude-opus-4-8", Provider: ProviderAnthropic, Label: "Claude Opus 4.8", Reasoning: true, ContextWindow: 1000000},
{ID: "anthropic/claude-sonnet-5", Provider: ProviderAnthropic, Label: "Claude Sonnet 5", Reasoning: true, ContextWindow: 1000000},
{ID: "anthropic/claude-haiku-4-5", Provider: ProviderAnthropic, Label: "Claude Haiku 4.5", Reasoning: true, ContextWindow: 200000},
{ID: "anthropic/claude-sonnet-4-5", Provider: ProviderAnthropic, Label: "Claude Sonnet 4.5", Reasoning: true, ContextWindow: 200000},
{ID: "anthropic/claude-opus-4-1", Provider: ProviderAnthropic, Label: "Claude Opus 4.1", Reasoning: true, ContextWindow: 200000},
{ID: "anthropic/claude-3-5-haiku-latest", Provider: ProviderAnthropic, Label: "Claude 3.5 Haiku", Reasoning: false, ContextWindow: 200000},
{ID: "openai/gpt-4o", Provider: ProviderOpenAI, Label: "GPT-4o", Reasoning: false, ContextWindow: 128000},
{ID: "openai/o3", Provider: ProviderOpenAI, Label: "OpenAI o3", Reasoning: true, ContextWindow: 200000},
{ID: "openai/o4-mini", Provider: ProviderOpenAI, Label: "OpenAI o4-mini", Reasoning: true, ContextWindow: 200000},
{ID: "openai/gpt-5.5", Provider: ProviderOpenAI, Label: "GPT-5.5", Reasoning: true, ContextWindow: 1000000},
{ID: "openai/gpt-5.4-mini", Provider: ProviderOpenAI, Label: "GPT-5.4 mini", Reasoning: true, ContextWindow: 400000},
{ID: "googleai/gemini-2.5-pro", Provider: ProviderGoogle, Label: "Gemini 2.5 Pro", Reasoning: true, ContextWindow: 1048576},
{ID: "googleai/gemini-2.5-flash", Provider: ProviderGoogle, Label: "Gemini 2.5 Flash", Reasoning: true, ContextWindow: 1048576},
{ID: "googleai/gemini-3.5-flash", Provider: ProviderGoogle, Label: "Gemini 3.5 Flash", Reasoning: true, ContextWindow: 1048576},

// Agent-framework models (captain pkg/ai StreamingProvider). These run a
// supervised local subprocess that owns its own tools; ids carry the
// backend prefix captain's InferBackend recognises, and Backend is set
// explicitly so codex slugs (which look like gpt-*) are not misrouted.
{ID: "claude-agent-sonnet", Engine: EngineAgent, Backend: capapi.BackendClaudeAgent, Provider: "claude-agent", Label: "Claude Agent · Sonnet", Reasoning: true, ContextWindow: 200000},
{ID: "claude-agent-opus", Engine: EngineAgent, Backend: capapi.BackendClaudeAgent, Provider: "claude-agent", Label: "Claude Agent · Opus", Reasoning: true, ContextWindow: 200000},
{ID: "claude-agent-sonnet", Engine: EngineAgent, Backend: capapi.BackendClaudeAgent, Provider: "claude-agent", Label: "Claude Agent · Sonnet", Reasoning: true, ContextWindow: 1000000},
{ID: "claude-agent-opus", Engine: EngineAgent, Backend: capapi.BackendClaudeAgent, Provider: "claude-agent", Label: "Claude Agent · Opus", Reasoning: true, ContextWindow: 1000000},
{ID: "claude-agent-haiku", Engine: EngineAgent, Backend: capapi.BackendClaudeAgent, Provider: "claude-agent", Label: "Claude Agent · Haiku", Reasoning: true, ContextWindow: 200000},
{ID: "codex-gpt-5-codex", Engine: EngineAgent, Backend: capapi.BackendCodexCLI, AgentModel: "gpt-5-codex", Provider: "codex-cli", Label: "Codex · GPT-5", Reasoning: true, ContextWindow: 400000},
}
Expand Down
6 changes: 3 additions & 3 deletions aichat/models_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestSetModelCatalogAndReset(t *testing.T) {
if err := SetModelCatalog([]Model{{ID: "openai/only-model", Label: "Only"}}); err != nil {
t.Fatalf("SetModelCatalog: %v", err)
}
if _, err := LookupModel("openai/gpt-4o"); err == nil {
if _, err := LookupModel("openai/gpt-5.5"); err == nil {
t.Error("expected built-in model to be absent after SetModelCatalog")
}
m, err := LookupModel("openai/only-model")
Expand All @@ -67,7 +67,7 @@ func TestSetModelCatalogAndReset(t *testing.T) {
}

ResetModelCatalog()
if _, err := LookupModel("openai/gpt-4o"); err != nil {
if _, err := LookupModel("openai/gpt-5.5"); err != nil {
t.Fatalf("built-in model should be restored: %v", err)
}
}
Expand All @@ -84,7 +84,7 @@ func TestRegisterModelValidation(t *testing.T) {
func TestAnthropicCatalogIncludesRequestedModels(t *testing.T) {
for _, id := range []string{
"anthropic/claude-haiku-4-5",
"anthropic/claude-sonnet-4-6",
"anthropic/claude-sonnet-5",
"anthropic/claude-opus-4-8",
} {
m, err := LookupModel(id)
Expand Down
17 changes: 17 additions & 0 deletions examples/enitity/webapp/.oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json",
"jsPlugins": [
{
"name": "clicky-ui",
"specifier": "../../../../clicky-ui/packages/ui/oxlint-plugins/clicky-ui.js"
}
],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"rules": {
"clicky-ui/prefer-clicky-components": "error",
"clicky-ui/no-adhoc-overlay": "error",
"clicky-ui/prefer-tailwind-classes": "error",
"clicky-ui/prefer-theme-tokens": "error",
"clicky-ui/prefer-clicky-icons": "error"
},
"ignorePatterns": ["dist", "node_modules"]
}
2 changes: 2 additions & 0 deletions examples/enitity/webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"type": "module",
"scripts": {
"dev": "vite",
"lint:clicky-ui": "oxlint -c .oxlintrc.json src vite.config.ts --quiet",
"build": "tsc -b && vite build",
"preview": "vite preview"
},
Expand Down Expand Up @@ -35,6 +36,7 @@
"@types/react": "^18.3.28",
"@types/react-dom": "^18.3.7",
"@vitejs/plugin-react": "^5.0.4",
"oxlint": "catalog:",
"react-grab": "catalog:",
"tailwindcss": "^4.2.2",
"typescript": "~5.9.3",
Expand Down
Loading
Loading