Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
144 changes: 144 additions & 0 deletions cmd/download_weights.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package cmd

import (
"context"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/CognitiveOS-Project/cpm/internal/weights"
"github.com/spf13/cobra"
)

var (
downloadProvider string
downloadKind string
downloadFormat string
downloadOutput string
downloadDryRun bool
)

var downloadWeightsCmd = &cobra.Command{
Use: "download-weights <model-name>",
Short: "Download model weights from a provider",
Long: `Download model weights (GGUF, safetensors) from a weight provider.

Provider: hf (Hugging Face Hub) — searches public GGUF models sorted by downloads.
cpm download-weights --provider hf --kind wide --type gguf google/gemma-4-2b
cpm download-weights --provider hf --kind raw --type gguf CognitiveOS/raw-model

Files are placed at:
--kind raw → /cognitiveos/models/raw/raw-model-<name>.gguf (skip if exists)
--kind wide → /cognitiveos/models/wide/active/<filename>.gguf
`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
modelName := args[0]

var kind weights.Kind
switch downloadKind {
case "raw":
kind = weights.KindRaw
case "wide":
kind = weights.KindWide
default:
return fmt.Errorf("invalid --kind: %q (must be raw or wide)", downloadKind)
}

var format weights.Format
switch downloadFormat {
case "gguf":
format = weights.FormatGGUF
case "safetensors":
format = weights.FormatSafeTensors
default:
return fmt.Errorf("invalid --type: %q (must be gguf or safetensors)", downloadFormat)
}

var prov weights.Provider
switch downloadProvider {
case "hf":
prov = weights.NewHFProvider()
default:
return fmt.Errorf("invalid --provider: %q (must be hf)", downloadProvider)
}

ctx := context.Background()

candidates, err := prov.Search(ctx, modelName, 5)
if err != nil {
return fmt.Errorf("search: %w", err)
}

formatExt := "." + format.String()

var match *weights.Candidate
for i := range candidates {
if strings.HasSuffix(strings.ToLower(candidates[i].Filename), formatExt) {
match = &candidates[i]
break
}
}
if match == nil {
for i := range candidates {
if strings.Contains(strings.ToLower(candidates[i].Filename), strings.ToLower(modelName)) {
match = &candidates[i]
break
}
}
}
if match == nil && len(candidates) > 0 {
match = &candidates[0]
}
if match == nil {
return fmt.Errorf("no %s files found for %q", formatExt, modelName)
}

dest := downloadOutput
if dest == "" {
dest = resolveDest(kind, match)
}
fmt.Printf("Found: %s\n", match.DownloadURL)
fmt.Printf("File: %s\n", match.Filename)
fmt.Printf("Dest: %s\n", dest)

if downloadDryRun {
return nil
}

if kind == weights.KindRaw {
if _, err := os.Stat(dest); err == nil {
fmt.Printf("File already exists at %s — skipping (use --kind wide to re-download)\n", dest)
return nil
}
}

fmt.Println("Downloading...")
if err := weights.Download(ctx, match.DownloadURL, dest, match.SHA256, weights.TextProgress); err != nil {
return fmt.Errorf("download: %w", err)
}
fmt.Printf("✓ Downloaded to %s\n", dest)
return nil
},
}

func resolveDest(kind weights.Kind, c *weights.Candidate) string {
dir := weights.ModelDir(kind)
if kind == weights.KindRaw {
base := strings.TrimSuffix(c.Filename, filepath.Ext(c.Filename))
name := fmt.Sprintf("raw-model-%s%s", base, filepath.Ext(c.Filename))
return filepath.Join(dir, name)
}
return filepath.Join(dir, c.Filename)
}

func init() {
fs := downloadWeightsCmd.Flags()
fs.StringVar(&downloadProvider, "provider", "hf", "Weight provider (hf)")
fs.StringVar(&downloadKind, "kind", "wide", "Model kind (raw or wide)")
fs.StringVar(&downloadFormat, "type", "gguf", "File format (gguf or safetensors)")
fs.StringVar(&downloadOutput, "output", "", "Custom output path (overrides default)")
fs.BoolVar(&downloadDryRun, "dry-run", false, "Show what would be downloaded without downloading")
rootCmd.AddCommand(downloadWeightsCmd)
}
155 changes: 115 additions & 40 deletions cmd/init_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/spf13/cobra"
)

var initTemplate string

var initCmd = &cobra.Command{
Use: "init [<dir>]",
Short: "Create a .cgp skeleton directory",
Expand All @@ -23,58 +25,131 @@ var initCmd = &cobra.Command{
return fmt.Errorf("directory %q already exists", dir)
}

dirs := []string{
filepath.Join(dir, "prompts", "templates"),
filepath.Join(dir, "tools"),
}
for _, d := range dirs {
if err := os.MkdirAll(d, 0755); err != nil {
return fmt.Errorf("create %s: %w", d, err)
}
switch initTemplate {
case "gguf-model":
return initGGUFModel(dir)
default:
return initDefault(dir)
}
},
}

manifest := map[string]interface{}{
"name": filepath.Base(dir),
"version": "0.1.0",
"description": "Describe what this patch does",
"author": "",
"license": "MIT",
"hardware_requirements": map[string]interface{}{
"min_ram_mb": 512,
"min_storage_mb": 50,
},
"runtime": map[string]interface{}{
"system_prompt": "prompts/system.md",
"tools_root": "tools",
},
func initDefault(dir string) error {
dirs := []string{
filepath.Join(dir, "prompts", "templates"),
filepath.Join(dir, "tools"),
}
for _, d := range dirs {
if err := os.MkdirAll(d, 0755); err != nil {
return fmt.Errorf("create %s: %w", d, err)
}
}

mf, err := os.Create(filepath.Join(dir, "cognitive.json"))
if err != nil {
return fmt.Errorf("create cognitive.json: %w", err)
}
defer mf.Close()
manifest := map[string]interface{}{
"name": filepath.Base(dir),
"version": "0.1.0",
"description": "Describe what this patch does",
"author": "",
"license": "MIT",
"hardware_requirements": map[string]interface{}{
"min_ram_mb": 512,
"min_storage_mb": 50,
},
"runtime": map[string]interface{}{
"system_prompt": "prompts/system.md",
"tools_root": "tools",
},
}

enc := json.NewEncoder(mf)
enc.SetIndent("", " ")
if err := enc.Encode(manifest); err != nil {
return fmt.Errorf("write cognitive.json: %w", err)
}
if err := writeManifest(dir, manifest); err != nil {
return err
}

systemPrompt := `# System Prompt
systemPrompt := `# System Prompt

You are a CognitiveOS skill. When loaded, your behavior is defined here.
`
if err := os.WriteFile(filepath.Join(dir, "prompts", "system.md"), []byte(systemPrompt), 0644); err != nil {
return fmt.Errorf("write system.md: %w", err)
}
if err := os.WriteFile(filepath.Join(dir, "prompts", "system.md"), []byte(systemPrompt), 0644); err != nil {
return fmt.Errorf("write system.md: %w", err)
}

fmt.Printf("✓ Created .cgp skeleton in %s/\n", dir)
fmt.Printf(" Next: edit %s and add your tools/prompts\n", filepath.Join(dir, "cognitive.json"))
return nil
},
fmt.Printf("✓ Created .cgp skeleton in %s/\n", dir)
fmt.Printf(" Next: edit %s and add your tools/prompts\n", filepath.Join(dir, "cognitive.json"))
return nil
}

func initGGUFModel(dir string) error {
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("create %s: %w", dir, err)
}

manifest := map[string]interface{}{
"name": filepath.Base(dir),
"version": "1.0.0",
"description": "GGUF model distributed via CognitiveOS",
"author": "",
"license": "MIT",
"source": map[string]interface{}{
"repository": "",
"issues": "",
},
"hardware_requirements": map[string]interface{}{
"min_ram_mb": 4096,
"min_storage_mb": 2048,
"npu_required": false,
},
"checksum": map[string]interface{}{
"sha256": "",
},
"brain": map[string]interface{}{
"wide_model": map[string]interface{}{
"base_model": filepath.Base(dir),
"weights": map[string]interface{}{
"remote": map[string]interface{}{
"source": "huggingface",
"model_id": "org/model-name",
"filename": "model-name-Q4_K_M.gguf",
"format": "gguf",
"quant": "Q4_K_M",
"size_bytes": 0,
},
},
"parameters": map[string]interface{}{
"temperature": 0.7,
"num_ctx": 8192,
},
},
},
"runtime": map[string]interface{}{
"capabilities": []string{"model.llm", "model.chat"},
},
}

if err := writeManifest(dir, manifest); err != nil {
return err
}

fmt.Printf("✓ Created gguf-model skeleton in %s/\n", dir)
fmt.Printf(" Next: edit cognitive.json — set model_id, filename, quant, size_bytes\n")
return nil
}

func writeManifest(dir string, manifest map[string]interface{}) error {
mf, err := os.Create(filepath.Join(dir, "cognitive.json"))
if err != nil {
return fmt.Errorf("create cognitive.json: %w", err)
}
defer mf.Close()

enc := json.NewEncoder(mf)
enc.SetIndent("", " ")
if err := enc.Encode(manifest); err != nil {
return fmt.Errorf("write cognitive.json: %w", err)
}
return nil
}

func init() {
initCmd.Flags().StringVar(&initTemplate, "template", "", "Skeleton template (gguf-model)")
rootCmd.AddCommand(initCmd)
}
Loading
Loading