Text Generation
Transformers
Safetensors
English
canopy
browser-use
web-agent
recurrent-moe
edge-llm
lightpanda
obscura
multi-agent
robotics-web
conversational
custom_code
Instructions to use psikosen/canopy-258m-r3 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use psikosen/canopy-258m-r3 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="psikosen/canopy-258m-r3", trust_remote_code=True) messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("psikosen/canopy-258m-r3", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use psikosen/canopy-258m-r3 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "psikosen/canopy-258m-r3" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "psikosen/canopy-258m-r3", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/psikosen/canopy-258m-r3
- SGLang
How to use psikosen/canopy-258m-r3 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "psikosen/canopy-258m-r3" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "psikosen/canopy-258m-r3", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "psikosen/canopy-258m-r3" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "psikosen/canopy-258m-r3", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use psikosen/canopy-258m-r3 with Docker Model Runner:
docker model run hf.co/psikosen/canopy-258m-r3
File size: 6,689 Bytes
ed79a7f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | """
Flow Reasoning Engine with Fixed-Point Forcing (FPF).
Synthesized from:
"Flow Reasoning Models: Turning Flows Into Efficient Recurrent Reasoners"
(Georgia Tech / MIT / MIT-IBM / IBM Research, Sep 2026).
Treats reasoning as iterative solution refinement toward a stable attractor.
Rather than committing irrevocably to one-shot greedy decisions, candidate
browser actions and spatial grounding coordinates undergo recurrent flow
refinement over held states:
s^{(k+1)} = Refine(s^{(k)}, Observation)
until converging to a globally consistent fixed point.
"""
from __future__ import annotations
import math
import time
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional, Tuple
from miniswardbower.core.schemas import BrowserAction, BrowserActionType, InteractiveElement, PrunedAXTree
@dataclass
class FlowRefinementState:
"""Represents the recurrent held-state evolving toward a stable attractor."""
step_index: int
candidate_action: BrowserAction
spatial_coords: Tuple[float, float]
confidence: float
residual_norm: float = 1.0
converged: bool = False
iterations_run: int = 0
refinement_trace: List[Dict[str, Any]] = field(default_factory=list)
class FlowReasoningRefiner:
"""
Recurrent Flow Reasoner with Fixed-Point Iteration for Browser Grounding & Actions.
Iteratively refines candidate coordinates and parameter schemas to prevent cascade failures.
"""
def __init__(
self,
max_refinement_depth: int = 4,
convergence_threshold: float = 0.05,
damping_factor: float = 0.65,
):
self.max_depth = max_refinement_depth
self.threshold = convergence_threshold
self.damping = damping_factor
@staticmethod
def _find_element(tree: Optional[PrunedAXTree], target_id: Optional[str]) -> Optional[InteractiveElement]:
if not tree or not target_id:
return None
for el in tree.elements:
if el.id == target_id or el.selector == target_id:
return el
return None
def refine_action(
self,
initial_action: BrowserAction,
tree: Optional[PrunedAXTree] = None,
viewport_dims: Tuple[int, int] = (1280, 900),
) -> FlowRefinementState:
"""
Runs recurrent fixed-point refinement on candidate action and coordinates.
Converges candidate toward the optimal, collision-free attractor.
"""
t0 = time.perf_counter()
vw, vh = viewport_dims
# Extract initial spatial coordinates
cur_x, cur_y = 0.0, 0.0
if getattr(initial_action, "coords", None):
cur_x, cur_y = float(initial_action.coords[0]), float(initial_action.coords[1])
elif tree and initial_action.target:
target_el = self._find_element(tree, initial_action.target)
if target_el and target_el.bbox:
bx, by, bw, bh = target_el.bbox
cur_x, cur_y = bx + bw / 2.0, by + bh / 2.0
else:
cur_x, cur_y = float(vw / 2.0), float(vh / 2.0)
else:
cur_x, cur_y = float(vw / 2.0), float(vh / 2.0)
cur_action = initial_action.model_copy(deep=True)
cur_confidence = 0.50
state = FlowRefinementState(
step_index=0,
candidate_action=cur_action,
spatial_coords=(cur_x, cur_y),
confidence=cur_confidence,
)
trace = []
# Recurrent refinement loop
for depth in range(1, self.max_depth + 1):
prev_x, prev_y = cur_x, cur_y
prev_conf = cur_confidence
# 1. Attractor gradient from DOM layout
target_el: Optional[InteractiveElement] = None
if tree and cur_action.target:
target_el = self._find_element(tree, cur_action.target)
attractor_x, attractor_y = prev_x, prev_y
target_valid = False
if target_el:
target_valid = True
if target_el.bbox:
bx, by, bw, bh = target_el.bbox
attractor_x = bx + bw / 2.0
attractor_y = by + bh / 2.0
# Type mismatch refinement (e.g. TYPE requested on non-editable tag)
if cur_action.op == BrowserActionType.TYPE:
if target_el.tag not in ("input", "textarea") and target_el.element_type not in ("textbox", "search"):
# Search for adjacent editable child/sibling in tree
for alt_el in tree.elements:
if alt_el.tag in ("input", "textarea") and alt_el.bbox:
cur_action.target = alt_el.id
cur_action.selector = alt_el.selector
abx, aby, abw, abh = alt_el.bbox
attractor_x = abx + abw / 2.0
attractor_y = aby + abh / 2.0
break
# 2. Viewport boundary attraction (keep coordinates within visible viewport)
attractor_x = max(10.0, min(float(vw - 10.0), attractor_x))
attractor_y = max(10.0, min(float(vh - 10.0), attractor_y))
# 3. Fixed-point update with damping
dx = (attractor_x - cur_x) * self.damping
dy = (attractor_y - cur_y) * self.damping
cur_x += dx
cur_y += dy
# 4. Confidence refinement
if target_valid:
cur_confidence = min(0.99, cur_confidence + 0.15)
else:
cur_confidence = max(0.20, cur_confidence - 0.10)
# Residual norm
delta_dist = math.sqrt(dx * dx + dy * dy)
residual = delta_dist / max(1.0, math.sqrt(float(vw * vw + vh * vh)))
trace.append({
"depth": depth,
"coords": (round(cur_x, 2), round(cur_y, 2)),
"residual": round(residual, 5),
"confidence": round(cur_confidence, 3),
})
if residual < self.threshold:
state.converged = True
state.iterations_run = depth
state.residual_norm = residual
break
if not state.converged:
state.iterations_run = self.max_depth
state.residual_norm = residual
cur_action.coords = (cur_x, cur_y)
state.candidate_action = cur_action
state.spatial_coords = (cur_x, cur_y)
state.confidence = cur_confidence
state.refinement_trace = trace
return state
|