mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
docs: fix inaccuracies, add translations, and expand channel docs (#1837)
## Config field fixes (cross-verified against Go source) - MaixCam: server_address → host + port - IRC: use_tls → tls, channels_to_join → channels (all 6 languages) - WeCom AI Bot: callback port 18791 → 18790 - credential_encryption: base_url → api_base, add required model field, remove incorrect passphrase-only mode docs - providers.md: agents.defaults.model → model_name (×4), remove non-existent session.backlog_limit - migration guide, troubleshooting: agents.defaults.model → model_name - ANTIGRAVITY_AUTH: fix file path, Go 1.21 → 1.25, model → model_name - spawn-tasks: fix truncated file, add Heartbeat introduction - tools_configuration: add Tavily/SearXNG/GLMSearch, exec allow_remote/ timeout_seconds/custom_allow_patterns, cron allow_command, skills github/search_cache, clawhub timeout/max_zip_size/max_response_size - configuration: fix builtin skills path (build-time embedded, not cwd), HEARTBEAT.md marked auto-generated ## Broken link fixes (15 total) - chat-apps.md: WeCom/Matrix links with wrong relative paths - providers.md: migration link with extra docs/ prefix - hardware-compatibility.md: README links with wrong depth (all 5 langs) - chat-apps.md: WhatsApp dead links → anchor links (zh/ja) ## Getting-started accuracy - README (all 6 langs): add picoclaw.io as recommended download, add missing picoclaw model CLI command - docker.md: clarify first-run trigger condition (all 6 langs) - configuration.md: fix builtin skills path description (all 6 langs) ## QQ channel - Add quick setup via q.qq.com/qqbot/openclaw (one-click bot creation) - Add manual setup as fallback (all 6 languages) ## Feishu channel - Update setup flow: WebSocket/SDK mode, no webhook URL needed - Preserve Lark international domain note (all 6 languages) ## chat-apps.md - Add Feishu, Slack, IRC, OneBot detail sections (all 6 languages) - Add MaixCam section to ja/fr/pt-br/vi - Fix all channel doc links to point to correct language version ## New translations (25 files, 5 docs × 5 languages) debug.md, credential_encryption.md, hardware-compatibility.md, ANTIGRAVITY_AUTH.md, ANTIGRAVITY_USAGE.md → zh/ja/fr/pt-br/vi ## Channel docs (6 languages each, 60 new files) telegram, discord, qq, feishu, maixcam, dingtalk, line, slack, onebot, wecom/wecom_aibot, wecom/wecom_app, wecom/wecom_bot Co-authored-by: BeaconCat <BeaconCat@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,809 @@
|
||||
> Retour au [README](../../README.fr.md)
|
||||
|
||||
# Guide d'authentification et d'intégration Antigravity
|
||||
|
||||
## Aperçu
|
||||
|
||||
**Antigravity** (Google Cloud Code Assist) est un fournisseur de modèles IA soutenu par Google qui offre l'accès à des modèles tels que Claude Opus 4.6 et Gemini via l'infrastructure cloud de Google. Ce document fournit un guide complet sur le fonctionnement de l'authentification, la récupération des modèles et l'implémentation d'un nouveau fournisseur dans PicoClaw.
|
||||
|
||||
---
|
||||
|
||||
## Table des matières
|
||||
|
||||
1. [Flux d'authentification](#flux-dauthentification)
|
||||
2. [Détails de l'implémentation OAuth](#détails-de-limplémentation-oauth)
|
||||
3. [Gestion des jetons](#gestion-des-jetons)
|
||||
4. [Récupération de la liste des modèles](#récupération-de-la-liste-des-modèles)
|
||||
5. [Suivi de l'utilisation](#suivi-de-lutilisation)
|
||||
6. [Structure du plugin fournisseur](#structure-du-plugin-fournisseur)
|
||||
7. [Exigences d'intégration](#exigences-dintégration)
|
||||
8. [Points de terminaison API](#points-de-terminaison-api)
|
||||
9. [Configuration](#configuration)
|
||||
10. [Créer un nouveau fournisseur dans PicoClaw](#créer-un-nouveau-fournisseur-dans-picoclaw)
|
||||
|
||||
---
|
||||
|
||||
## Flux d'authentification
|
||||
|
||||
### 1. OAuth 2.0 avec PKCE
|
||||
|
||||
Antigravity utilise **OAuth 2.0 avec PKCE (Proof Key for Code Exchange)** pour une authentification sécurisée :
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────────┐
|
||||
│ Client │ ───(1) Generate PKCE Pair────────> │ │
|
||||
│ │ ───(2) Open Auth URL─────────────> │ Google OAuth │
|
||||
│ │ │ Server │
|
||||
│ │ <──(3) Redirect with Code───────── │ │
|
||||
│ │ └─────────────────┘
|
||||
│ │ ───(4) Exchange Code for Tokens──> │ Token URL │
|
||||
│ │ │ │
|
||||
│ │ <──(5) Access + Refresh Tokens──── │ │
|
||||
└─────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
### 2. Étapes détaillées
|
||||
|
||||
#### Étape 1 : Générer les paramètres PKCE
|
||||
```typescript
|
||||
function generatePkce(): { verifier: string; challenge: string } {
|
||||
const verifier = randomBytes(32).toString("hex");
|
||||
const challenge = createHash("sha256").update(verifier).digest("base64url");
|
||||
return { verifier, challenge };
|
||||
}
|
||||
```
|
||||
|
||||
#### Étape 2 : Construire l'URL d'autorisation
|
||||
```typescript
|
||||
const AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
|
||||
const REDIRECT_URI = "http://localhost:51121/oauth-callback";
|
||||
|
||||
function buildAuthUrl(params: { challenge: string; state: string }): string {
|
||||
const url = new URL(AUTH_URL);
|
||||
url.searchParams.set("client_id", CLIENT_ID);
|
||||
url.searchParams.set("response_type", "code");
|
||||
url.searchParams.set("redirect_uri", REDIRECT_URI);
|
||||
url.searchParams.set("scope", SCOPES.join(" "));
|
||||
url.searchParams.set("code_challenge", params.challenge);
|
||||
url.searchParams.set("code_challenge_method", "S256");
|
||||
url.searchParams.set("state", params.state);
|
||||
url.searchParams.set("access_type", "offline");
|
||||
url.searchParams.set("prompt", "consent");
|
||||
return url.toString();
|
||||
}
|
||||
```
|
||||
|
||||
**Portées requises :**
|
||||
```typescript
|
||||
const SCOPES = [
|
||||
"https://www.googleapis.com/auth/cloud-platform",
|
||||
"https://www.googleapis.com/auth/userinfo.email",
|
||||
"https://www.googleapis.com/auth/userinfo.profile",
|
||||
"https://www.googleapis.com/auth/cclog",
|
||||
"https://www.googleapis.com/auth/experimentsandconfigs",
|
||||
];
|
||||
```
|
||||
|
||||
#### Étape 3 : Gérer le callback OAuth
|
||||
|
||||
**Mode automatique (développement local) :**
|
||||
- Démarrer un serveur HTTP local sur le port 51121
|
||||
- Attendre la redirection de Google
|
||||
- Extraire le code d'autorisation des paramètres de requête
|
||||
|
||||
**Mode manuel (distant/sans interface graphique) :**
|
||||
- Afficher l'URL d'autorisation à l'utilisateur
|
||||
- L'utilisateur complète l'authentification dans son navigateur
|
||||
- L'utilisateur colle l'URL de redirection complète dans le terminal
|
||||
- Analyser le code depuis l'URL collée
|
||||
|
||||
#### Étape 4 : Échanger le code contre des jetons
|
||||
```typescript
|
||||
const TOKEN_URL = "https://oauth2.googleapis.com/token";
|
||||
|
||||
async function exchangeCode(params: {
|
||||
code: string;
|
||||
verifier: string;
|
||||
}): Promise<{ access: string; refresh: string; expires: number }> {
|
||||
const response = await fetch(TOKEN_URL, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: new URLSearchParams({
|
||||
client_id: CLIENT_ID,
|
||||
client_secret: CLIENT_SECRET,
|
||||
code: params.code,
|
||||
grant_type: "authorization_code",
|
||||
redirect_uri: REDIRECT_URI,
|
||||
code_verifier: params.verifier,
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
return {
|
||||
access: data.access_token,
|
||||
refresh: data.refresh_token,
|
||||
expires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000, // 5 min buffer
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### Étape 5 : Récupérer les données utilisateur supplémentaires
|
||||
|
||||
**E-mail de l'utilisateur :**
|
||||
```typescript
|
||||
async function fetchUserEmail(accessToken: string): Promise<string | undefined> {
|
||||
const response = await fetch(
|
||||
"https://www.googleapis.com/oauth2/v1/userinfo?alt=json",
|
||||
{ headers: { Authorization: `Bearer ${accessToken}` } }
|
||||
);
|
||||
const data = await response.json();
|
||||
return data.email;
|
||||
}
|
||||
```
|
||||
|
||||
**ID du projet (requis pour les appels API) :**
|
||||
```typescript
|
||||
async function fetchProjectId(accessToken: string): Promise<string> {
|
||||
const headers = {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "google-api-nodejs-client/9.15.1",
|
||||
"X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1",
|
||||
"Client-Metadata": JSON.stringify({
|
||||
ideType: "IDE_UNSPECIFIED",
|
||||
platform: "PLATFORM_UNSPECIFIED",
|
||||
pluginType: "GEMINI",
|
||||
}),
|
||||
};
|
||||
|
||||
const response = await fetch(
|
||||
"https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist",
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
metadata: {
|
||||
ideType: "IDE_UNSPECIFIED",
|
||||
platform: "PLATFORM_UNSPECIFIED",
|
||||
pluginType: "GEMINI",
|
||||
},
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
return data.cloudaicompanionProject || "rising-fact-p41fc"; // Valeur par défaut
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Détails de l'implémentation OAuth
|
||||
|
||||
### Identifiants client
|
||||
|
||||
**Important :** Ceux-ci sont encodés en base64 dans le code source pour la synchronisation avec pi-ai :
|
||||
|
||||
```typescript
|
||||
const decode = (s: string) => Buffer.from(s, "base64").toString();
|
||||
|
||||
const CLIENT_ID = decode(
|
||||
"MTA3MTAwNjA2MDU5MS10bWhzc2luMmgyMWxjcmUyMzV2dG9sb2poNGc0MDNlcC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbQ=="
|
||||
);
|
||||
const CLIENT_SECRET = decode("R09DU1BYLUs1OEZXUjQ4NkxkTEoxbUxCOHNYQzR6NnFEQWY=");
|
||||
```
|
||||
|
||||
### Modes de flux OAuth
|
||||
|
||||
1. **Flux automatique** (machines locales avec navigateur) :
|
||||
- Ouvre le navigateur automatiquement
|
||||
- Le serveur de callback local capture la redirection
|
||||
- Aucune interaction utilisateur requise après l'authentification initiale
|
||||
|
||||
2. **Flux manuel** (distant/sans interface/WSL2) :
|
||||
- URL affichée pour copier-coller manuellement
|
||||
- L'utilisateur complète l'authentification dans un navigateur externe
|
||||
- L'utilisateur colle l'URL de redirection complète
|
||||
|
||||
```typescript
|
||||
function shouldUseManualOAuthFlow(isRemote: boolean): boolean {
|
||||
return isRemote || isWSL2Sync();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Gestion des jetons
|
||||
|
||||
### Structure du profil d'authentification
|
||||
|
||||
```typescript
|
||||
type OAuthCredential = {
|
||||
type: "oauth";
|
||||
provider: "google-antigravity";
|
||||
access: string; // Jeton d'accès
|
||||
refresh: string; // Jeton de rafraîchissement
|
||||
expires: number; // Horodatage d'expiration (ms depuis epoch)
|
||||
email?: string; // E-mail de l'utilisateur
|
||||
projectId?: string; // ID du projet Google Cloud
|
||||
};
|
||||
```
|
||||
|
||||
### Rafraîchissement des jetons
|
||||
|
||||
Les identifiants incluent un jeton de rafraîchissement qui peut être utilisé pour obtenir de nouveaux jetons d'accès lorsque le jeton actuel expire. L'expiration est définie avec un tampon de 5 minutes pour éviter les conditions de concurrence.
|
||||
|
||||
---
|
||||
|
||||
## Récupération de la liste des modèles
|
||||
|
||||
### Récupérer les modèles disponibles
|
||||
|
||||
```typescript
|
||||
const BASE_URL = "https://cloudcode-pa.googleapis.com";
|
||||
|
||||
async function fetchAvailableModels(
|
||||
accessToken: string,
|
||||
projectId: string
|
||||
): Promise<Model[]> {
|
||||
const headers = {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "antigravity",
|
||||
"X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1",
|
||||
};
|
||||
|
||||
const response = await fetch(
|
||||
`${BASE_URL}/v1internal:fetchAvailableModels`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify({ project: projectId }),
|
||||
}
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
// Retourne les modèles avec les informations de quota
|
||||
return Object.entries(data.models).map(([modelId, modelInfo]) => ({
|
||||
id: modelId,
|
||||
displayName: modelInfo.displayName,
|
||||
quotaInfo: {
|
||||
remainingFraction: modelInfo.quotaInfo?.remainingFraction,
|
||||
resetTime: modelInfo.quotaInfo?.resetTime,
|
||||
isExhausted: modelInfo.quotaInfo?.isExhausted,
|
||||
},
|
||||
}));
|
||||
}
|
||||
```
|
||||
|
||||
### Format de réponse
|
||||
|
||||
```typescript
|
||||
type FetchAvailableModelsResponse = {
|
||||
models?: Record<string, {
|
||||
displayName?: string;
|
||||
quotaInfo?: {
|
||||
remainingFraction?: number | string;
|
||||
resetTime?: string; // Horodatage ISO 8601
|
||||
isExhausted?: boolean;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Suivi de l'utilisation
|
||||
|
||||
### Récupérer les données d'utilisation
|
||||
|
||||
```typescript
|
||||
export async function fetchAntigravityUsage(
|
||||
token: string,
|
||||
timeoutMs: number
|
||||
): Promise<ProviderUsageSnapshot> {
|
||||
// 1. Récupérer les crédits et les informations du plan
|
||||
const loadCodeAssistRes = await fetch(
|
||||
`${BASE_URL}/v1internal:loadCodeAssist`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
metadata: {
|
||||
ideType: "ANTIGRAVITY",
|
||||
platform: "PLATFORM_UNSPECIFIED",
|
||||
pluginType: "GEMINI",
|
||||
},
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
// Extraire les informations de crédits
|
||||
const { availablePromptCredits, planInfo, currentTier } = data;
|
||||
|
||||
// 2. Récupérer les quotas des modèles
|
||||
const modelsRes = await fetch(
|
||||
`${BASE_URL}/v1internal:fetchAvailableModels`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
body: JSON.stringify({ project: projectId }),
|
||||
}
|
||||
);
|
||||
|
||||
// Construire les fenêtres d'utilisation
|
||||
return {
|
||||
provider: "google-antigravity",
|
||||
displayName: "Google Antigravity",
|
||||
windows: [
|
||||
{ label: "Credits", usedPercent: calculateUsedPercent(available, monthly) },
|
||||
// Quotas individuels des modèles...
|
||||
],
|
||||
plan: currentTier?.name || planType,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Structure de la réponse d'utilisation
|
||||
|
||||
```typescript
|
||||
type ProviderUsageSnapshot = {
|
||||
provider: "google-antigravity";
|
||||
displayName: string;
|
||||
windows: UsageWindow[];
|
||||
plan?: string;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
type UsageWindow = {
|
||||
label: string; // "Credits" ou ID du modèle
|
||||
usedPercent: number; // 0-100
|
||||
resetAt?: number; // Horodatage de réinitialisation du quota
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Structure du plugin fournisseur
|
||||
|
||||
### Définition du plugin
|
||||
|
||||
```typescript
|
||||
const antigravityPlugin = {
|
||||
id: "google-antigravity-auth",
|
||||
name: "Google Antigravity Auth",
|
||||
description: "OAuth flow for Google Antigravity (Cloud Code Assist)",
|
||||
configSchema: emptyPluginConfigSchema(),
|
||||
|
||||
register(api: PicoClawPluginApi) {
|
||||
api.registerProvider({
|
||||
id: "google-antigravity",
|
||||
label: "Google Antigravity",
|
||||
docsPath: "/providers/models",
|
||||
aliases: ["antigravity"],
|
||||
|
||||
auth: [
|
||||
{
|
||||
id: "oauth",
|
||||
label: "Google OAuth",
|
||||
hint: "PKCE + localhost callback",
|
||||
kind: "oauth",
|
||||
run: async (ctx: ProviderAuthContext) => {
|
||||
// Implémentation OAuth ici
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### ProviderAuthContext
|
||||
|
||||
```typescript
|
||||
type ProviderAuthContext = {
|
||||
config: PicoClawConfig;
|
||||
agentDir?: string;
|
||||
workspaceDir?: string;
|
||||
prompter: WizardPrompter; // Invites/notifications UI
|
||||
runtime: RuntimeEnv; // Journalisation, etc.
|
||||
isRemote: boolean; // Exécution à distance ou non
|
||||
openUrl: (url: string) => Promise<void>; // Ouverture du navigateur
|
||||
oauth: {
|
||||
createVpsAwareHandlers: Function;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### ProviderAuthResult
|
||||
|
||||
```typescript
|
||||
type ProviderAuthResult = {
|
||||
profiles: Array<{
|
||||
profileId: string;
|
||||
credential: AuthProfileCredential;
|
||||
}>;
|
||||
configPatch?: Partial<PicoClawConfig>;
|
||||
defaultModel?: string;
|
||||
notes?: string[];
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Exigences d'intégration
|
||||
|
||||
### 1. Environnement/dépendances requis
|
||||
|
||||
- Go ≥ 1.25
|
||||
- Base de code PicoClaw (`pkg/providers/` et `pkg/auth/`)
|
||||
- Packages de la bibliothèque standard `crypto` et `net/http`
|
||||
|
||||
### 2. En-têtes requis pour les appels API
|
||||
|
||||
```typescript
|
||||
const REQUIRED_HEADERS = {
|
||||
"Authorization": `Bearer ${accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "antigravity", // ou "google-api-nodejs-client/9.15.1"
|
||||
"X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1",
|
||||
};
|
||||
|
||||
// Pour les appels loadCodeAssist, inclure également :
|
||||
const CLIENT_METADATA = {
|
||||
ideType: "ANTIGRAVITY", // ou "IDE_UNSPECIFIED"
|
||||
platform: "PLATFORM_UNSPECIFIED",
|
||||
pluginType: "GEMINI",
|
||||
};
|
||||
```
|
||||
|
||||
### 3. Assainissement des schémas de modèles
|
||||
|
||||
Antigravity utilise des modèles compatibles Gemini, les schémas d'outils doivent donc être assainis :
|
||||
|
||||
```typescript
|
||||
const GOOGLE_SCHEMA_UNSUPPORTED_KEYWORDS = new Set([
|
||||
"patternProperties",
|
||||
"additionalProperties",
|
||||
"$schema",
|
||||
"$id",
|
||||
"$ref",
|
||||
"$defs",
|
||||
"definitions",
|
||||
"examples",
|
||||
"minLength",
|
||||
"maxLength",
|
||||
"minimum",
|
||||
"maximum",
|
||||
"multipleOf",
|
||||
"pattern",
|
||||
"format",
|
||||
"minItems",
|
||||
"maxItems",
|
||||
"uniqueItems",
|
||||
"minProperties",
|
||||
"maxProperties",
|
||||
]);
|
||||
|
||||
// Nettoyer le schéma avant l'envoi
|
||||
function cleanToolSchemaForGemini(schema: Record<string, unknown>): unknown {
|
||||
// Supprimer les mots-clés non supportés
|
||||
// S'assurer que le niveau supérieur a type: "object"
|
||||
// Aplatir les unions anyOf/oneOf
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Gestion des blocs de réflexion (modèles Claude)
|
||||
|
||||
Pour les modèles Claude via Antigravity, les blocs de réflexion nécessitent un traitement spécial :
|
||||
|
||||
```typescript
|
||||
const ANTIGRAVITY_SIGNATURE_RE = /^[A-Za-z0-9+/]+={0,2}$/;
|
||||
|
||||
export function sanitizeAntigravityThinkingBlocks(
|
||||
messages: AgentMessage[]
|
||||
): AgentMessage[] {
|
||||
// Valider les signatures de réflexion
|
||||
// Normaliser les champs de signature
|
||||
// Rejeter les blocs de réflexion non signés
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Points de terminaison API
|
||||
|
||||
### Points de terminaison d'authentification
|
||||
|
||||
| Point de terminaison | Méthode | Objectif |
|
||||
|---------------------|---------|----------|
|
||||
| `https://accounts.google.com/o/oauth2/v2/auth` | GET | Autorisation OAuth |
|
||||
| `https://oauth2.googleapis.com/token` | POST | Échange de jetons |
|
||||
| `https://www.googleapis.com/oauth2/v1/userinfo` | GET | Informations utilisateur (e-mail) |
|
||||
|
||||
### Points de terminaison Cloud Code Assist
|
||||
|
||||
| Point de terminaison | Méthode | Objectif |
|
||||
|---------------------|---------|----------|
|
||||
| `https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist` | POST | Charger les infos du projet, crédits, plan |
|
||||
| `https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels` | POST | Lister les modèles disponibles avec quotas |
|
||||
| `https://cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse` | POST | Point de terminaison de streaming de chat |
|
||||
|
||||
**Format de requête API (chat) :**
|
||||
Le point de terminaison `v1internal:streamGenerateContent` attend une enveloppe encapsulant la requête Gemini standard :
|
||||
|
||||
```json
|
||||
{
|
||||
"project": "your-project-id",
|
||||
"model": "model-id",
|
||||
"request": {
|
||||
"contents": [...],
|
||||
"systemInstruction": {...},
|
||||
"generationConfig": {...},
|
||||
"tools": [...]
|
||||
},
|
||||
"requestType": "agent",
|
||||
"userAgent": "antigravity",
|
||||
"requestId": "agent-timestamp-random"
|
||||
}
|
||||
```
|
||||
|
||||
**Format de réponse API (SSE) :**
|
||||
Chaque message SSE (`data: {...}`) est encapsulé dans un champ `response` :
|
||||
|
||||
```json
|
||||
{
|
||||
"response": {
|
||||
"candidates": [...],
|
||||
"usageMetadata": {...},
|
||||
"modelVersion": "...",
|
||||
"responseId": "..."
|
||||
},
|
||||
"traceId": "...",
|
||||
"metadata": {}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### Configuration config.json
|
||||
|
||||
```json
|
||||
{
|
||||
"model_list": [
|
||||
{
|
||||
"model_name": "gemini-flash",
|
||||
"model": "antigravity/gemini-3-flash",
|
||||
"auth_method": "oauth"
|
||||
}
|
||||
],
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model_name": "gemini-flash"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Stockage du profil d'authentification
|
||||
|
||||
Les profils d'authentification sont stockés dans `~/.picoclaw/auth.json` :
|
||||
|
||||
```json
|
||||
{
|
||||
"credentials": {
|
||||
"google-antigravity": {
|
||||
"access_token": "ya29...",
|
||||
"refresh_token": "1//...",
|
||||
"expires_at": "2026-01-01T00:00:00Z",
|
||||
"provider": "google-antigravity",
|
||||
"auth_method": "oauth",
|
||||
"email": "user@example.com",
|
||||
"project_id": "my-project-id"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Créer un nouveau fournisseur dans PicoClaw
|
||||
|
||||
Les fournisseurs PicoClaw sont implémentés en tant que packages Go sous `pkg/providers/`. Pour ajouter un nouveau fournisseur :
|
||||
|
||||
### Implémentation étape par étape
|
||||
|
||||
#### 1. Créer le fichier du fournisseur
|
||||
|
||||
Créez un nouveau fichier Go dans `pkg/providers/` :
|
||||
|
||||
```
|
||||
pkg/providers/
|
||||
└── your_provider.go
|
||||
```
|
||||
|
||||
#### 2. Implémenter l'interface Provider
|
||||
|
||||
Votre fournisseur doit implémenter l'interface `Provider` définie dans `pkg/providers/types.go` :
|
||||
|
||||
```go
|
||||
package providers
|
||||
|
||||
type YourProvider struct {
|
||||
apiKey string
|
||||
apiBase string
|
||||
}
|
||||
|
||||
func NewYourProvider(apiKey, apiBase, proxy string) *YourProvider {
|
||||
if apiBase == "" {
|
||||
apiBase = "https://api.your-provider.com/v1"
|
||||
}
|
||||
return &YourProvider{apiKey: apiKey, apiBase: apiBase}
|
||||
}
|
||||
|
||||
func (p *YourProvider) Chat(ctx context.Context, messages []Message, tools []Tool, cb StreamCallback) error {
|
||||
// Implémenter la complétion de chat avec streaming
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Enregistrer dans la factory
|
||||
|
||||
Ajoutez votre fournisseur au switch de protocole dans `pkg/providers/factory.go` :
|
||||
|
||||
```go
|
||||
case "your-provider":
|
||||
return NewYourProvider(sel.apiKey, sel.apiBase, sel.proxy), nil
|
||||
```
|
||||
|
||||
#### 4. Ajouter la configuration par défaut (optionnel)
|
||||
|
||||
Ajoutez une entrée par défaut dans `pkg/config/defaults.go` :
|
||||
|
||||
```go
|
||||
{
|
||||
ModelName: "your-model",
|
||||
Model: "your-provider/model-name",
|
||||
APIKey: "",
|
||||
},
|
||||
```
|
||||
|
||||
#### 5. Ajouter le support d'authentification (optionnel)
|
||||
|
||||
Si votre fournisseur nécessite OAuth ou une authentification spéciale, ajoutez un cas dans `cmd/picoclaw/internal/auth/helpers.go` :
|
||||
|
||||
```go
|
||||
case "your-provider":
|
||||
authLoginYourProvider()
|
||||
```
|
||||
|
||||
#### 6. Configurer via `config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"model_list": [
|
||||
{
|
||||
"model_name": "your-model",
|
||||
"model": "your-provider/model-name",
|
||||
"api_key": "your-api-key",
|
||||
"api_base": "https://api.your-provider.com/v1"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tester votre implémentation
|
||||
|
||||
### Commandes CLI
|
||||
|
||||
```bash
|
||||
# S'authentifier avec un fournisseur
|
||||
picoclaw auth login --provider your-provider
|
||||
|
||||
# Lister les modèles (pour Antigravity)
|
||||
picoclaw auth models
|
||||
|
||||
# Démarrer la passerelle
|
||||
picoclaw gateway
|
||||
|
||||
# Exécuter un agent avec un modèle spécifique
|
||||
picoclaw agent -m "Hello" --model your-model
|
||||
```
|
||||
|
||||
### Variables d'environnement pour les tests
|
||||
|
||||
```bash
|
||||
# Remplacer le modèle par défaut
|
||||
export PICOCLAW_AGENTS_DEFAULTS_MODEL=your-model
|
||||
|
||||
# Remplacer les paramètres du fournisseur
|
||||
export PICOCLAW_MODEL_LIST='[{"model_name":"your-model","model":"your-provider/model-name","api_key":"..."}]'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Références
|
||||
|
||||
- **Fichiers source :**
|
||||
- `pkg/providers/antigravity_provider.go` - Implémentation du fournisseur Antigravity
|
||||
- `pkg/auth/oauth.go` - Implémentation du flux OAuth
|
||||
- `pkg/auth/store.go` - Stockage des identifiants d'authentification (`~/.picoclaw/auth.json`)
|
||||
- `pkg/providers/factory.go` - Factory des fournisseurs et routage de protocole
|
||||
- `pkg/providers/types.go` - Définitions de l'interface fournisseur
|
||||
- `cmd/picoclaw/internal/auth/helpers.go` - Commandes CLI d'authentification
|
||||
|
||||
- **Documentation :**
|
||||
- `docs/ANTIGRAVITY_USAGE.md` - Guide d'utilisation d'Antigravity
|
||||
- `docs/migration/model-list-migration.md` - Guide de migration
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
1. **Projet Google Cloud :** Antigravity nécessite que Gemini for Google Cloud soit activé sur votre projet Google Cloud
|
||||
2. **Quotas :** Utilise les quotas du projet Google Cloud (pas de facturation séparée)
|
||||
3. **Accès aux modèles :** Les modèles disponibles dépendent de la configuration de votre projet Google Cloud
|
||||
4. **Blocs de réflexion :** Les modèles Claude via Antigravity nécessitent un traitement spécial des blocs de réflexion avec signatures
|
||||
5. **Assainissement des schémas :** Les schémas d'outils doivent être assainis pour supprimer les mots-clés JSON Schema non supportés
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## Gestion des erreurs courantes
|
||||
|
||||
### 1. Limitation de débit (HTTP 429)
|
||||
|
||||
Antigravity retourne une erreur 429 lorsque les quotas du projet/modèle sont épuisés. La réponse d'erreur contient souvent un `quotaResetDelay` dans le champ `details`.
|
||||
|
||||
**Exemple d'erreur 429 :**
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": 429,
|
||||
"message": "You have exhausted your capacity on this model. Your quota will reset after 4h30m28s.",
|
||||
"status": "RESOURCE_EXHAUSTED",
|
||||
"details": [
|
||||
{
|
||||
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
|
||||
"metadata": {
|
||||
"quotaResetDelay": "4h30m28.060903746s"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Réponses vides (modèles restreints)
|
||||
|
||||
Certains modèles peuvent apparaître dans la liste des modèles disponibles mais retourner une réponse vide (200 OK mais flux SSE vide). Cela se produit généralement pour les modèles en préversion ou restreints que le projet actuel n'a pas la permission d'utiliser.
|
||||
|
||||
**Traitement :** Traiter les réponses vides comme des erreurs informant l'utilisateur que le modèle pourrait être restreint ou invalide pour son projet.
|
||||
|
||||
---
|
||||
|
||||
## Dépannage
|
||||
|
||||
### "Token expired" (jeton expiré)
|
||||
- Rafraîchir les jetons OAuth : `picoclaw auth login --provider antigravity`
|
||||
|
||||
### "Gemini for Google Cloud is not enabled" (Gemini for Google Cloud n'est pas activé)
|
||||
- Activer l'API dans votre Google Cloud Console
|
||||
|
||||
### "Project not found" (projet non trouvé)
|
||||
- Vérifier que votre projet Google Cloud a les API nécessaires activées
|
||||
- Vérifier que l'ID du projet est correctement récupéré lors de l'authentification
|
||||
|
||||
### Les modèles n'apparaissent pas dans la liste
|
||||
- Vérifier que l'authentification OAuth s'est terminée avec succès
|
||||
- Vérifier le stockage du profil d'authentification : `~/.picoclaw/auth.json`
|
||||
- Relancer `picoclaw auth login --provider antigravity`
|
||||
@@ -0,0 +1,72 @@
|
||||
> Retour au [README](../../README.fr.md)
|
||||
|
||||
# Utiliser le fournisseur Antigravity dans PicoClaw
|
||||
|
||||
Ce guide explique comment configurer et utiliser le fournisseur **Antigravity** (Google Cloud Code Assist) dans PicoClaw.
|
||||
|
||||
## Prérequis
|
||||
|
||||
1. Un compte Google.
|
||||
2. Google Cloud Code Assist activé (généralement disponible via l'intégration « Gemini for Google Cloud »).
|
||||
|
||||
## 1. Authentification
|
||||
|
||||
Pour vous authentifier avec Antigravity, exécutez la commande suivante :
|
||||
|
||||
```bash
|
||||
picoclaw auth login --provider antigravity
|
||||
```
|
||||
|
||||
### Authentification manuelle (Headless/VPS)
|
||||
Si vous exécutez PicoClaw sur un serveur (Coolify/Docker) et ne pouvez pas accéder à `localhost`, suivez ces étapes :
|
||||
1. Exécutez la commande ci-dessus.
|
||||
2. Copiez l'URL fournie et ouvrez-la dans votre navigateur local.
|
||||
3. Complétez la connexion.
|
||||
4. Votre navigateur sera redirigé vers une URL `localhost:51121` (qui ne se chargera pas).
|
||||
5. **Copiez cette URL finale** depuis la barre d'adresse de votre navigateur.
|
||||
6. **Collez-la dans le terminal** où PicoClaw attend.
|
||||
|
||||
PicoClaw extraira automatiquement le code d'autorisation et terminera le processus.
|
||||
|
||||
## 2. Gestion des modèles
|
||||
|
||||
### Lister les modèles disponibles
|
||||
Pour voir quels modèles sont accessibles à votre projet et vérifier leurs quotas :
|
||||
|
||||
```bash
|
||||
picoclaw auth models
|
||||
```
|
||||
|
||||
### Changer de modèle
|
||||
Vous pouvez modifier le modèle par défaut dans `~/.picoclaw/config.json` ou le remplacer via le CLI :
|
||||
|
||||
```bash
|
||||
# Remplacer pour une seule commande
|
||||
picoclaw agent -m "Hello" --model claude-opus-4-6-thinking
|
||||
```
|
||||
|
||||
## 3. Utilisation en production (Coolify/Docker)
|
||||
|
||||
Si vous déployez via Coolify ou Docker, suivez ces étapes pour tester :
|
||||
|
||||
1. **Variables d'environnement** :
|
||||
* `PICOCLAW_AGENTS_DEFAULTS_MODEL=gemini-flash`
|
||||
2. **Persistance de l'authentification** :
|
||||
Si vous vous êtes connecté localement, vous pouvez copier vos identifiants vers le serveur :
|
||||
```bash
|
||||
scp ~/.picoclaw/auth.json user@your-server:~/.picoclaw/
|
||||
```
|
||||
*Alternativement*, exécutez la commande `auth login` une fois sur le serveur si vous avez un accès terminal.
|
||||
|
||||
## 4. Dépannage
|
||||
|
||||
* **Réponse vide** : Si un modèle renvoie une réponse vide, il peut être restreint pour votre projet. Essayez `gemini-3-flash` ou `claude-opus-4-6-thinking`.
|
||||
* **429 Limite de débit** : Antigravity a des quotas stricts. PicoClaw affichera le « temps de réinitialisation » dans le message d'erreur si vous atteignez une limite.
|
||||
* **404 Non trouvé** : Assurez-vous d'utiliser un ID de modèle provenant de la liste `picoclaw auth models`. Utilisez l'ID court (par ex. `gemini-3-flash`) et non le chemin complet.
|
||||
|
||||
## 5. Résumé des modèles fonctionnels
|
||||
|
||||
D'après les tests, les modèles suivants sont les plus fiables :
|
||||
* `gemini-3-flash` (Rapide, haute disponibilité)
|
||||
* `gemini-2.5-flash-lite` (Léger)
|
||||
* `claude-opus-4-6-thinking` (Puissant, inclut le raisonnement)
|
||||
+77
-55
@@ -8,22 +8,22 @@ Communiquez avec votre PicoClaw via Telegram, Discord, WhatsApp, Matrix, QQ, Din
|
||||
|
||||
> **Note** : Tous les canaux basés sur les webhooks (LINE, WeCom, etc.) sont servis sur un seul serveur HTTP Gateway partagé (`gateway.host`:`gateway.port`, par défaut `127.0.0.1:18790`). Il n'y a pas de ports par canal à configurer. Note : Feishu utilise le mode WebSocket/SDK et n'utilise pas le serveur HTTP webhook partagé.
|
||||
|
||||
| Canal | Configuration |
|
||||
| ------------ | -------------------------------------- |
|
||||
| **Telegram** | Facile (juste un token) |
|
||||
| **Discord** | Facile (bot token + intents) |
|
||||
| **WhatsApp** | Facile (natif : scan QR ; ou bridge URL) |
|
||||
| **Matrix** | Moyen (homeserver + bot access token) |
|
||||
| **QQ** | Facile (AppID + AppSecret) |
|
||||
| **DingTalk** | Moyen (identifiants de l'application) |
|
||||
| **LINE** | Moyen (identifiants + webhook URL) |
|
||||
| **WeCom AI Bot** | Moyen (Token + clé AES) |
|
||||
| **Feishu** | Moyen (App ID + Secret, mode WebSocket) |
|
||||
| **Slack** | Moyen (Bot token + App token) |
|
||||
| **IRC** | Moyen (serveur + configuration TLS) |
|
||||
| **OneBot** | Moyen (QQ via protocole OneBot) |
|
||||
| **MaixCam** | Facile (intégration matérielle Sipeed) |
|
||||
| **Pico** | Native PicoClaw protocol |
|
||||
| Canal | Difficulté | Description | Documentation |
|
||||
| -------------------- | ------------------ | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| **Telegram** | ⭐ Facile | Recommandé, transcription vocale, long polling (pas d'IP publique requise) | [Documentation](../channels/telegram/README.fr.md) |
|
||||
| **Discord** | ⭐ Facile | Socket Mode, groupes/DM, écosystème bot riche | [Documentation](../channels/discord/README.fr.md) |
|
||||
| **WhatsApp** | ⭐ Facile | Natif (scan QR) ou Bridge URL | [Documentation](#whatsapp) |
|
||||
| **Slack** | ⭐ Facile | **Socket Mode** (pas d'IP publique requise), entreprise | [Documentation](../channels/slack/README.fr.md) |
|
||||
| **Matrix** | ⭐⭐ Moyen | Protocole fédéré, auto-hébergement possible | [Documentation](../channels/matrix/README.fr.md) |
|
||||
| **QQ** | ⭐⭐ Moyen | API bot officielle, communauté chinoise | [Documentation](../channels/qq/README.fr.md) |
|
||||
| **DingTalk** | ⭐⭐ Moyen | Mode Stream (pas d'IP publique requise), entreprise | [Documentation](../channels/dingtalk/README.fr.md) |
|
||||
| **LINE** | ⭐⭐⭐ Avancé | HTTPS Webhook requis | [Documentation](../channels/line/README.fr.md) |
|
||||
| **WeCom (企业微信)** | ⭐⭐⭐ Avancé | Bot groupe (Webhook), app personnalisée (API), AI Bot | [Bot](../channels/wecom/wecom_bot/README.fr.md) / [App](../channels/wecom/wecom_app/README.fr.md) / [AI Bot](../channels/wecom/wecom_aibot/README.fr.md) |
|
||||
| **Feishu (飞书)** | ⭐⭐⭐ Avancé | Collaboration entreprise, fonctionnalités riches | [Documentation](../channels/feishu/README.fr.md) |
|
||||
| **IRC** | ⭐⭐ Moyen | Serveur + configuration TLS | - |
|
||||
| **OneBot** | ⭐⭐ Moyen | Compatible NapCat/Go-CQHTTP, écosystème communautaire | [Documentation](../channels/onebot/README.fr.md) |
|
||||
| **MaixCam** | ⭐ Facile | Canal d'intégration matérielle pour caméras AI Sipeed | [Documentation](../channels/maixcam/README.fr.md) |
|
||||
| **Pico** | ⭐ Facile | Canal protocole natif PicoClaw | |
|
||||
|
||||
<details>
|
||||
<summary><b>Telegram</b> (Recommandé)</summary>
|
||||
@@ -168,12 +168,13 @@ Si `session_store_path` est vide, la session est stockée dans `<workspace>/what
|
||||
<details>
|
||||
<summary><b>QQ</b></summary>
|
||||
|
||||
**1. Créer un bot**
|
||||
**Configuration rapide (recommandée)**
|
||||
|
||||
- Allez sur [QQ Open Platform](https://q.qq.com/#)
|
||||
- Créez une application → Obtenez **AppID** et **AppSecret**
|
||||
QQ Open Platform propose une page de configuration en un clic pour les bots compatibles OpenClaw :
|
||||
|
||||
**2. Configurer**
|
||||
1. Ouvrez [QQ Bot Quick Start](https://q.qq.com/qqbot/openclaw/index.html) et scannez le QR code pour vous connecter
|
||||
2. Un bot est créé automatiquement — copiez l'**App ID** et l'**App Secret**
|
||||
3. Configurez PicoClaw :
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -188,13 +189,20 @@ Si `session_store_path` est vide, la session est stockée dans `<workspace>/what
|
||||
}
|
||||
```
|
||||
|
||||
> Définissez `allow_from` vide pour autoriser tous les utilisateurs, ou spécifiez des numéros QQ pour restreindre l'accès.
|
||||
4. Lancez `picoclaw gateway` et ouvrez QQ pour discuter avec votre bot
|
||||
|
||||
**3. Lancer**
|
||||
> L'App Secret n'est affiché qu'une seule fois. Enregistrez-le immédiatement — le consulter à nouveau forcera une réinitialisation.
|
||||
>
|
||||
> Les bots créés via la page de configuration rapide sont initialement réservés au créateur et ne prennent pas en charge les discussions de groupe. Pour activer l'accès en groupe, configurez le mode sandbox sur la [QQ Open Platform](https://q.qq.com/).
|
||||
|
||||
```bash
|
||||
picoclaw gateway
|
||||
```
|
||||
**Configuration manuelle**
|
||||
|
||||
Si vous préférez créer le bot manuellement :
|
||||
|
||||
* Connectez-vous sur [QQ Open Platform](https://q.qq.com/) pour vous inscrire en tant que développeur
|
||||
* Créez un bot QQ — personnalisez son avatar et son nom
|
||||
* Copiez l'**App ID** et l'**App Secret** depuis les paramètres du bot
|
||||
* Configurez comme indiqué ci-dessus et lancez `picoclaw gateway`
|
||||
|
||||
</details>
|
||||
|
||||
@@ -261,7 +269,7 @@ picoclaw gateway
|
||||
picoclaw gateway
|
||||
```
|
||||
|
||||
Pour toutes les options (`device_id`, `join_on_invite`, `group_trigger`, `placeholder`, `reasoning_channel_id`), voir le [Guide de Configuration du Canal Matrix](docs/channels/matrix/README.md).
|
||||
Pour toutes les options (`device_id`, `join_on_invite`, `group_trigger`, `placeholder`, `reasoning_channel_id`), voir le [Guide de Configuration du Canal Matrix](../channels/matrix/README.md).
|
||||
|
||||
</details>
|
||||
|
||||
@@ -322,7 +330,7 @@ PicoClaw prend en charge trois types d'intégration WeCom :
|
||||
**Option 2 : WeCom App (Application personnalisée)** - Plus de fonctionnalités, messagerie proactive, chat privé uniquement
|
||||
**Option 3 : WeCom AI Bot (Bot IA)** - Bot IA officiel, réponses en streaming, prend en charge les discussions de groupe et privées
|
||||
|
||||
Voir le [Guide de Configuration WeCom AI Bot](docs/channels/wecom/wecom_aibot/README.zh.md) pour les instructions détaillées.
|
||||
Voir le [Guide de Configuration WeCom AI Bot](../channels/wecom/wecom_aibot/README.fr.md) pour les instructions détaillées.
|
||||
|
||||
**Configuration rapide - WeCom Bot :**
|
||||
|
||||
@@ -396,7 +404,7 @@ picoclaw gateway
|
||||
**1. Créer un AI Bot**
|
||||
|
||||
* Allez dans la console d'administration WeCom → Gestion des applications → AI Bot
|
||||
* Dans les paramètres du AI Bot, configurez l'URL de callback : `http://your-server:18791/webhook/wecom-aibot`
|
||||
* Dans les paramètres du AI Bot, configurez l'URL de callback : `http://your-server:18790/webhook/wecom-aibot`
|
||||
* Copiez **Token** et cliquez sur "Générer aléatoirement" pour **EncodingAESKey**
|
||||
|
||||
**2. Configurer**
|
||||
@@ -430,10 +438,14 @@ picoclaw gateway
|
||||
<details>
|
||||
<summary><b>Feishu (飞书)</b></summary>
|
||||
|
||||
PicoClaw se connecte à Feishu via le mode WebSocket/SDK — aucune URL webhook publique ni serveur de callback nécessaire.
|
||||
|
||||
**1. Créer une application**
|
||||
|
||||
* Allez sur [Feishu Open Platform](https://open.feishu.cn/)
|
||||
* Créez une application → Obtenez **App ID** et **App Secret**
|
||||
* Allez sur [Feishu Open Platform](https://open.feishu.cn/) et créez une application
|
||||
* Dans les paramètres de l'application, activez la capacité **Bot**
|
||||
* Créez une version et publiez l'application (l'application doit être publiée pour prendre effet)
|
||||
* Copiez l'**App ID** (commence par `cli_`) et l'**App Secret**
|
||||
|
||||
**2. Configurer**
|
||||
|
||||
@@ -443,23 +455,25 @@ picoclaw gateway
|
||||
"feishu": {
|
||||
"enabled": true,
|
||||
"app_id": "cli_xxx",
|
||||
"app_secret": "xxx",
|
||||
"encrypt_key": "",
|
||||
"verification_token": "",
|
||||
"app_secret": "YOUR_APP_SECRET",
|
||||
"allow_from": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> Feishu utilise le mode WebSocket/SDK et ne nécessite pas de serveur webhook.
|
||||
Optionnel : `encrypt_key` et `verification_token` pour le chiffrement des événements (recommandé en production).
|
||||
|
||||
**3. Lancer**
|
||||
**3. Lancer et discuter**
|
||||
|
||||
```bash
|
||||
picoclaw gateway
|
||||
```
|
||||
|
||||
Ouvrez Feishu, recherchez le nom de votre bot et commencez à discuter. Vous pouvez aussi ajouter le bot à un groupe — utilisez `group_trigger.mention_only: true` pour ne répondre que lorsqu'il est @mentionné.
|
||||
|
||||
Pour toutes les options, voir le [Guide de Configuration du Canal Feishu](../channels/feishu/README.fr.md).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@@ -467,9 +481,10 @@ picoclaw gateway
|
||||
|
||||
**1. Créer une application Slack**
|
||||
|
||||
* Allez sur [Slack API](https://api.slack.com/apps)
|
||||
* Créez une nouvelle application
|
||||
* Obtenez le **Bot Token** et l'**App Token**
|
||||
* Allez sur [Slack API](https://api.slack.com/apps) et créez une nouvelle application
|
||||
* Sous **OAuth & Permissions**, ajoutez les scopes bot : `chat:write`, `app_mentions:read`, `im:history`, `im:read`, `im:write`
|
||||
* Installez l'application dans votre workspace
|
||||
* Copiez le **Bot Token** (`xoxb-...`) et l'**App-Level Token** (`xapp-...`, activez Socket Mode pour l'obtenir)
|
||||
|
||||
**2. Configurer**
|
||||
|
||||
@@ -478,8 +493,8 @@ picoclaw gateway
|
||||
"channels": {
|
||||
"slack": {
|
||||
"enabled": true,
|
||||
"bot_token": "xoxb-your-bot-token",
|
||||
"app_token": "xapp-your-app-token",
|
||||
"bot_token": "xoxb-YOUR-BOT-TOKEN",
|
||||
"app_token": "xapp-YOUR-APP-TOKEN",
|
||||
"allow_from": []
|
||||
}
|
||||
}
|
||||
@@ -497,42 +512,44 @@ picoclaw gateway
|
||||
<details>
|
||||
<summary><b>IRC</b></summary>
|
||||
|
||||
**1. Configurer le serveur IRC**
|
||||
|
||||
* Préparez les informations de votre serveur IRC (adresse, port, canal)
|
||||
|
||||
**2. Configurer**
|
||||
**1. Configurer**
|
||||
|
||||
```json
|
||||
{
|
||||
"channels": {
|
||||
"irc": {
|
||||
"enabled": true,
|
||||
"server": "irc.example.com:6697",
|
||||
"server": "irc.libera.chat:6697",
|
||||
"tls": true,
|
||||
"nick": "picoclaw-bot",
|
||||
"channel": "#your-channel",
|
||||
"use_tls": true,
|
||||
"channels": ["#your-channel"],
|
||||
"password": "",
|
||||
"allow_from": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**3. Lancer**
|
||||
Optionnel : `nickserv_password` pour l'authentification NickServ, `sasl_user`/`sasl_password` pour l'authentification SASL.
|
||||
|
||||
**2. Lancer**
|
||||
|
||||
```bash
|
||||
picoclaw gateway
|
||||
```
|
||||
|
||||
Le bot se connectera au serveur IRC et rejoindra les canaux spécifiés.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>OneBot</b></summary>
|
||||
<summary><b>OneBot (QQ via protocole OneBot)</b></summary>
|
||||
|
||||
**1. Configurer OneBot**
|
||||
OneBot est un protocole ouvert pour les bots QQ. PicoClaw se connecte à toute implémentation compatible OneBot v11 (par ex. [Lagrange](https://github.com/LagrangeDev/Lagrange.Core), [NapCat](https://github.com/NapNeko/NapCatQQ)) via WebSocket.
|
||||
|
||||
* Installez une implémentation OneBot compatible (par ex. go-cqhttp, Lagrange)
|
||||
* Configurez la connexion WebSocket
|
||||
**1. Configurer une implémentation OneBot**
|
||||
|
||||
Installez et exécutez un framework de bot QQ compatible OneBot v11. Activez son serveur WebSocket.
|
||||
|
||||
**2. Configurer**
|
||||
|
||||
@@ -541,14 +558,19 @@ picoclaw gateway
|
||||
"channels": {
|
||||
"onebot": {
|
||||
"enabled": true,
|
||||
"ws_url": "ws://localhost:8080",
|
||||
"ws_url": "ws://127.0.0.1:8080",
|
||||
"access_token": "",
|
||||
"allow_from": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> OneBot permet d'utiliser QQ via le protocole OneBot standard.
|
||||
| Champ | Description |
|
||||
|-------|-------------|
|
||||
| `ws_url` | URL WebSocket de l'implémentation OneBot |
|
||||
| `access_token` | Token d'accès pour l'authentification (si configuré dans OneBot) |
|
||||
| `reconnect_interval` | Intervalle de reconnexion en secondes (par défaut : 5) |
|
||||
|
||||
**3. Lancer**
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ Par défaut, les compétences sont chargées depuis :
|
||||
|
||||
1. `~/.picoclaw/workspace/skills` (workspace)
|
||||
2. `~/.picoclaw/skills` (global)
|
||||
3. `<current-working-directory>/skills` (builtin)
|
||||
3. `<chemin-intégré-à-la-compilation>/skills` (intégré)
|
||||
|
||||
Pour les configurations avancées/de test, vous pouvez remplacer la racine des compétences builtin avec :
|
||||
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
> Retour au [README](../../README.fr.md)
|
||||
|
||||
# Chiffrement des identifiants
|
||||
|
||||
PicoClaw prend en charge le chiffrement des valeurs `api_key` dans les entrées de configuration `model_list`.
|
||||
Les clés chiffrées sont stockées sous forme de chaînes `enc://<base64>` et déchiffrées automatiquement au démarrage.
|
||||
|
||||
---
|
||||
|
||||
## Démarrage rapide
|
||||
|
||||
**1. Définir votre phrase secrète**
|
||||
|
||||
```bash
|
||||
export PICOCLAW_KEY_PASSPHRASE="your-passphrase"
|
||||
```
|
||||
|
||||
**2. Chiffrer une clé API**
|
||||
|
||||
Exécutez `picoclaw onboard` — il vous demande votre phrase secrète et génère la clé SSH,
|
||||
puis re-chiffre automatiquement toutes les entrées `api_key` en clair dans votre configuration
|
||||
lors du prochain appel à `SaveConfig`. La valeur `enc://` résultante ressemblera à :
|
||||
|
||||
```
|
||||
enc://AAAA...base64...
|
||||
```
|
||||
|
||||
**3. Coller la sortie dans votre configuration**
|
||||
|
||||
```json
|
||||
{
|
||||
"model_list": [
|
||||
{
|
||||
"model_name": "gpt-4o",
|
||||
"model": "openai/gpt-4o",
|
||||
"api_key": "enc://AAAA...base64...",
|
||||
"api_base": "https://api.openai.com/v1"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Formats `api_key` pris en charge
|
||||
|
||||
| Format | Exemple | Comportement |
|
||||
|--------|---------|--------------|
|
||||
| Texte clair | `sk-abc123` | Utilisé tel quel |
|
||||
| Référence fichier | `file://openai.key` | Contenu lu depuis le même répertoire que le fichier de configuration |
|
||||
| Chiffré | `enc://<base64>` | Déchiffré au démarrage avec `PICOCLAW_KEY_PASSPHRASE` |
|
||||
| Vide | `""` | Transmis tel quel (utilisé avec `auth_method: oauth`) |
|
||||
|
||||
---
|
||||
|
||||
## Conception cryptographique
|
||||
|
||||
### Dérivation de clé
|
||||
|
||||
Le chiffrement utilise **HKDF-SHA256** avec une clé privée SSH comme second facteur.
|
||||
|
||||
```
|
||||
sshHash = SHA256(ssh_private_key_file_bytes)
|
||||
ikm = HMAC-SHA256(key=sshHash, message=passphrase)
|
||||
aes_key = HKDF-SHA256(ikm, salt, info="picoclaw-credential-v1", 32 bytes)
|
||||
```
|
||||
|
||||
### Chiffrement
|
||||
|
||||
```
|
||||
AES-256-GCM(key=aes_key, nonce=random[12], plaintext=api_key)
|
||||
```
|
||||
|
||||
### Format de transmission
|
||||
|
||||
```
|
||||
enc://<base64( salt[16] + nonce[12] + ciphertext )>
|
||||
```
|
||||
|
||||
| Champ | Taille | Description |
|
||||
|-------|--------|-------------|
|
||||
| `salt` | 16 octets | Aléatoire par chiffrement ; fourni à HKDF |
|
||||
| `nonce` | 12 octets | Aléatoire par chiffrement ; IV AES-GCM |
|
||||
| `ciphertext` | variable | Texte chiffré AES-256-GCM + tag d'authentification de 16 octets |
|
||||
|
||||
Le tag d'authentification GCM est automatiquement ajouté au texte chiffré. Toute altération provoque l'échec du déchiffrement avec une erreur plutôt que de retourner un texte clair corrompu.
|
||||
|
||||
### Performance
|
||||
|
||||
| Opération | Durée (ARM Cortex-A) |
|
||||
|-----------|----------------------|
|
||||
| Dérivation de clé (HKDF) | < 1 ms |
|
||||
| Déchiffrement AES-256-GCM | < 1 ms |
|
||||
| **Surcoût total au démarrage** | **< 2 ms par clé** |
|
||||
|
||||
---
|
||||
|
||||
## Sécurité à deux facteurs avec clé SSH
|
||||
|
||||
Lorsqu'une clé privée SSH est fournie, casser le chiffrement nécessite **les deux** :
|
||||
|
||||
1. La **phrase secrète** (`PICOCLAW_KEY_PASSPHRASE`)
|
||||
2. Le **fichier de clé privée SSH**
|
||||
|
||||
Cela signifie qu'un fichier de configuration divulgué seul ne suffit pas pour récupérer la clé API, même si la phrase secrète est faible. La clé SSH apporte 256 bits d'entropie (Ed25519) indépendamment de la force de la phrase secrète.
|
||||
|
||||
### Modèle de menace
|
||||
|
||||
| Ce que l'attaquant possède | Peut-il déchiffrer ? |
|
||||
|---------------------------|---------------------|
|
||||
| Fichier de configuration uniquement | Non — nécessite la phrase secrète + la clé SSH |
|
||||
| Clé SSH uniquement | Non — nécessite la phrase secrète |
|
||||
| Phrase secrète uniquement | Non — nécessite la clé SSH |
|
||||
| Fichier de configuration + clé SSH + phrase secrète | Oui — compromission totale |
|
||||
|
||||
---
|
||||
|
||||
## Variables d'environnement
|
||||
|
||||
| Variable | Requis | Description |
|
||||
|----------|--------|-------------|
|
||||
| `PICOCLAW_KEY_PASSPHRASE` | Oui (pour `enc://`) | Phrase secrète utilisée pour la dérivation de clé |
|
||||
| `PICOCLAW_SSH_KEY_PATH` | Non | Chemin vers la clé privée SSH. Si non défini, détection automatique depuis `~/.ssh/picoclaw_ed25519.key` |
|
||||
|
||||
### Détection automatique de la clé SSH
|
||||
|
||||
Si `PICOCLAW_SSH_KEY_PATH` n'est pas défini, PicoClaw recherche la clé dédiée :
|
||||
|
||||
```
|
||||
~/.ssh/picoclaw_ed25519.key
|
||||
```
|
||||
|
||||
Ce fichier dédié évite les conflits avec les clés SSH existantes de l'utilisateur.
|
||||
Exécutez `picoclaw onboard` pour le générer automatiquement.
|
||||
|
||||
`os.UserHomeDir()` est utilisé pour la résolution multiplateforme du répertoire personnel (lit `USERPROFILE` sous Windows, `HOME` sous Unix/macOS).
|
||||
|
||||
> **Remarque :** Un fichier de clé SSH est requis pour le chiffrement des identifiants. Si aucune clé n'est trouvée et que `PICOCLAW_SSH_KEY_PATH` n'est pas défini, le chiffrement/déchiffrement échouera. Exécutez `picoclaw onboard` pour générer la clé automatiquement.
|
||||
|
||||
---
|
||||
|
||||
## Migration
|
||||
|
||||
Étant donné que les seuls éléments secrets sont `PICOCLAW_KEY_PASSPHRASE` et le fichier de clé privée SSH, la migration est simple :
|
||||
|
||||
1. Copiez le fichier de configuration sur la nouvelle machine.
|
||||
2. Définissez `PICOCLAW_KEY_PASSPHRASE` avec la même valeur.
|
||||
3. Copiez le fichier de clé privée SSH au même chemin (ou définissez `PICOCLAW_SSH_KEY_PATH` vers son nouvel emplacement).
|
||||
|
||||
Aucun re-chiffrement n'est nécessaire.
|
||||
|
||||
---
|
||||
|
||||
## Considérations de sécurité
|
||||
|
||||
- **La phrase secrète et la clé SSH sont toutes deux requises.** La clé SSH agit comme un second facteur — sans elle, le chiffrement/déchiffrement échouera. Exécutez `picoclaw onboard` pour générer la clé si elle n'existe pas.
|
||||
- **La clé SSH est en lecture seule à l'exécution.** PicoClaw n'écrit ni ne modifie jamais le fichier de clé SSH.
|
||||
- **Les clés en texte clair restent prises en charge.** Les configurations existantes sans `enc://` ne sont pas affectées.
|
||||
- **Le format `enc://` est versionné** via le champ `info` de HKDF (`picoclaw-credential-v1`), permettant de futures mises à niveau d'algorithme sans casser les valeurs chiffrées existantes.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Débogage de PicoClaw
|
||||
|
||||
> Retour au [README](../../README.fr.md)
|
||||
|
||||
PicoClaw effectue de multiples interactions complexes en arrière-plan pour chaque requête qu'il reçoit — du routage des messages et de l'évaluation de la complexité, à l'exécution des outils et à l'adaptation aux défaillances de modèle. Pouvoir voir exactement ce qui se passe est crucial, non seulement pour résoudre les problèmes potentiels, mais aussi pour véritablement comprendre le fonctionnement de l'agent.
|
||||
|
||||
## Démarrer PicoClaw en mode débogage
|
||||
|
||||
Pour obtenir des informations détaillées sur ce que fait l'agent (requêtes LLM, appels d'outils, routage des messages), vous pouvez démarrer la passerelle PicoClaw avec le drapeau de débogage :
|
||||
|
||||
```bash
|
||||
picoclaw gateway --debug
|
||||
# or
|
||||
picoclaw gateway -d
|
||||
```
|
||||
|
||||
Dans ce mode, le système formate les logs de manière détaillée et affiche des aperçus des prompts système et des résultats d'exécution des outils.
|
||||
|
||||
## Désactiver la troncature des logs (logs complets)
|
||||
|
||||
Par défaut, PicoClaw tronque les chaînes très longues (comme le *Prompt Système* ou les résultats JSON volumineux) dans les logs de débogage afin de garder la console lisible.
|
||||
|
||||
Si vous avez besoin d'inspecter la sortie complète d'une commande ou le payload exact envoyé au modèle LLM, vous pouvez utiliser le drapeau `--no-truncate`.
|
||||
|
||||
**Remarque :** Ce drapeau fonctionne *uniquement* en combinaison avec le mode `--debug`.
|
||||
|
||||
```bash
|
||||
picoclaw gateway --debug --no-truncate
|
||||
|
||||
```
|
||||
|
||||
Lorsque ce drapeau est actif, la fonction de troncature globale est désactivée. Cela est extrêmement utile pour :
|
||||
|
||||
* Vérifier la syntaxe exacte des messages envoyés au fournisseur.
|
||||
* Lire la sortie complète d'outils comme `exec`, `web_fetch` ou `read_file`.
|
||||
* Déboguer l'historique de session sauvegardé en mémoire.
|
||||
@@ -12,6 +12,7 @@ git clone https://github.com/sipeed/picoclaw.git
|
||||
cd picoclaw
|
||||
|
||||
# 2. Premier lancement — génère automatiquement docker/data/config.json puis s'arrête
|
||||
# (se déclenche uniquement quand config.json et workspace/ sont tous deux absents)
|
||||
docker compose -f docker/docker-compose.yml --profile gateway up
|
||||
# Le conteneur affiche "First-run setup complete." et s'arrête.
|
||||
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
> Retour au [README](../../README.fr.md)
|
||||
|
||||
# 🖥️ PicoClaw Liste de compatibilité matérielle
|
||||
|
||||
PicoClaw fonctionne sur pratiquement n'importe quel appareil Linux. Cette page répertorie les puces, produits et cartes de développement vérifiés.
|
||||
|
||||
**Votre matériel n'est pas listé ?** Soumettez une PR pour l'ajouter ! Les fabricants de matériel sont invités à contribuer et à co-promouvoir.
|
||||
|
||||
---
|
||||
|
||||
## 1. Support de puces vérifié
|
||||
|
||||
### x86
|
||||
|
||||
| Fabricant | Puce | Notes |
|
||||
|-----------|------|-------|
|
||||
| Intel | Any x86 CPU (i386+) | Tous les processeurs de bureau/serveur/portable |
|
||||
| AMD | Any x86 CPU | Tous les processeurs de bureau/serveur/portable |
|
||||
|
||||
### ARM
|
||||
|
||||
| Sous-arch | Puces typiques | Notes |
|
||||
|-----------|----------------|-------|
|
||||
| ARMv6 | [BCM2835](https://www.raspberrypi.com/documentation/computers/processors.html#bcm2835) (Raspberry Pi 1/Zero) | Monocœur ARM1176JZF-S |
|
||||
| ARMv7 | [Allwinner V3s](https://linux-sunxi.org/V3s) | Monocœur Cortex-A7, utilisé dans LicheePi Zero |
|
||||
| ARM64 | [Allwinner H618](https://linux-sunxi.org/H618) | Quadricœur Cortex-A53, utilisé dans Orange Pi Zero 3 |
|
||||
| ARM64 | [BCM2711](https://www.raspberrypi.com/documentation/computers/processors.html#bcm2711) (Raspberry Pi 4) | Quadricœur Cortex-A72 |
|
||||
| ARM64 | [BCM2712](https://www.raspberrypi.com/documentation/computers/processors.html#bcm2712) (Raspberry Pi 5) | Quadricœur Cortex-A76 |
|
||||
| ARM64 | [AX630C](https://www.axera-tech.com/) (爱芯元智) | Bicœur Cortex-A53 + NPU, utilisé dans NanoKVM-Pro / MaixCAM2 |
|
||||
|
||||
### RISC-V (riscv64)
|
||||
|
||||
| Fabricant | Puce | Cœur | Notes |
|
||||
|-----------|------|------|-------|
|
||||
| [SOPHGO (算能)](https://www.sophgo.com/) | SG2002 | C906 @ 1GHz | 256MB DDR3 intégré, utilisé dans LicheeRV-Nano / NanoKVM / MaixCAM |
|
||||
| [Allwinner (全志)](https://www.allwinnertech.com/) | V861 | Dual C907 | 128MB DDR3L intégré, 1 TOPS NPU, caméra AI 4K SiP |
|
||||
| [Allwinner (全志)](https://www.allwinnertech.com/) | V881 | C907 | Série de caméras AI RISC-V |
|
||||
| [Arterytek (匠芯创)](https://www.arterytek.com/) | D213 | RISC-V | Utilisé dans HaaS506-LD1 RTU industriel |
|
||||
| [SpacemiT (进迭)](https://www.spacemit.com/) | K1 | 8x X60 @ 1.8GHz | Utilisé dans Milk-V Jupiter, BananaPi BPI-F3 |
|
||||
| [SpacemiT (进迭)](https://www.spacemit.com/) | K3 | 8x X100 @ 2.5GHz | Conforme RVA23, RVV 1024 bits, inférence AI FP8 |
|
||||
| [Zhihe (知合)](https://www.zhihe-tech.com/) | A210 | High-perf RISC-V | 8 cœurs, 16MB cache L3, classe bureau |
|
||||
| [Canaan (嘉楠)](https://www.canaan-creative.com/) | K230 | Dual C908 @ 1.6GHz | 6 TOPS KPU, utilisé dans CanMV-K230 |
|
||||
|
||||
### MIPS
|
||||
|
||||
| Fabricant | Puce | Notes |
|
||||
|-----------|------|-------|
|
||||
| MediaTek | [MT7620](https://www.mediatek.com/products/home-networking/mt7620) | MIPS24KEc @ 580MHz, utilisé dans de nombreux routeurs OpenWrt (ex. Xiaomi Router 3G) |
|
||||
|
||||
### LoongArch (loong64)
|
||||
|
||||
| Fabricant | Puce | Notes |
|
||||
|-----------|------|-------|
|
||||
| [Loongson (龙芯)](https://www.loongson.cn/) | 3A5000 | Quadricœur LA464 @ 2.5GHz, bureau/station de travail |
|
||||
| [Loongson (龙芯)](https://www.loongson.cn/) | 3A6000 | Quadricœur 4C/8T @ 2.5GHz, IPC comparable à Intel 10e génération |
|
||||
| [Loongson (龙芯)](https://www.loongson.cn/) | 2K1000LA | Bicœur @ 1GHz, applications industrielles/IoT |
|
||||
|
||||
---
|
||||
|
||||
## 2. Produits vérifiés (par date de sortie)
|
||||
|
||||
Produits grand public, routeurs et appareils industriels testés avec PicoClaw.
|
||||
|
||||
| Année | Produit | Arch | SoC | RAM | Catégorie |
|
||||
|-------|---------|------|-----|-----|-----------|
|
||||
| 2009 | Nokia N900 | ARM (A8) | OMAP3430 | 256MB | Smartphone |
|
||||
| 2012 | Samsung Galaxy Note 10.1 (N8000) | ARM (A9) | Exynos 4412 | 2GB | Tablette |
|
||||
| 2016 | Xiaomi Router 3G (小米路由器3G) | MIPS | MT7620 | 256MB | Routeur (OpenWrt) |
|
||||
| 2018 | Phicomm N1 (斐讯N1) | ARM64 (A53) | S905D | 2GB | Boîtier TV / Serveur domestique |
|
||||
| 2019 | Xiaomi AI Speaker (小爱音箱) | ARM64 (A53) | — | 256MB | Enceinte connectée |
|
||||
| 2024 | [NanoKVM](https://wiki.sipeed.com/hardware/en/kvm/NanoKVM/introduction.html) | RISC-V | SG2002 | 256MB | IP-KVM |
|
||||
| 2025 | HaaS506-LD1 | RISC-V | D213 | 128MB | RTU industriel |
|
||||
| 2025 | [NanoKVM-Pro](https://wiki.sipeed.com/hardware/en/kvm/NanoKVM_Pro/introduction.html) | ARM64 (A53) | AX630C | 1GB | IP-KVM Pro |
|
||||
| 2026 | [MaixCAM2](https://wiki.sipeed.com/hardware/en/maixcam/index.html) | ARM64 (A53) | AX630C | 1/4GB | Caméra AI 4K |
|
||||
|
||||
---
|
||||
|
||||
## 3. Cartes de développement vérifiées (par date de sortie)
|
||||
|
||||
| Année | Carte | Arch | SoC | RAM | Lien d'achat |
|
||||
|-------|-------|------|-----|-----|--------------|
|
||||
| 2012 | [Raspberry Pi 1 Model B](https://www.raspberrypi.com/products/) | ARMv6 | BCM2835 | 512MB | — |
|
||||
| 2015 | [Raspberry Pi 2 Model B](https://www.raspberrypi.com/products/raspberry-pi-2-model-b/) | ARMv7 (A7) | BCM2836 | 1GB | — |
|
||||
| 2015 | [Raspberry Pi Zero](https://www.raspberrypi.com/products/raspberry-pi-zero/) | ARMv6 | BCM2835 | 512MB | — |
|
||||
| 2016 | [Raspberry Pi 3 Model B](https://www.raspberrypi.com/products/raspberry-pi-3-model-b/) | ARM64 (A53) | BCM2837 | 1GB | — |
|
||||
| 2017 | [LicheePi Zero](https://wiki.sipeed.com/hardware/en/lichee/Zero/Zero.html) | ARMv7 (A7) | Allwinner V3s | 64MB | [Sipeed](https://sipeed.com/) |
|
||||
| 2019 | [Raspberry Pi 4 Model B](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/) | ARM64 (A72) | BCM2711 | 1~8GB | [RPi](https://www.raspberrypi.com/) |
|
||||
| 2023 | [Raspberry Pi 5](https://www.raspberrypi.com/products/raspberry-pi-5/) | ARM64 (A76) | BCM2712 | 2~8GB | [RPi](https://www.raspberrypi.com/) |
|
||||
| 2024 | [LicheeRV-Nano](https://wiki.sipeed.com/hardware/en/lichee/RV_Nano/1_intro.html) | RISC-V | SG2002 | 256MB | [AliExpress](https://www.aliexpress.com/item/1005006519668532.html) |
|
||||
| 2024 | [MaixCAM-Pro](https://wiki.sipeed.com/hardware/en/maixcam/index.html) | RISC-V | SG2002 | 256MB | [Sipeed](https://sipeed.com/) |
|
||||
| 2024 | [Milk-V Duo 64M](https://milkv.io/docs/duo/getting-started/duo) | RISC-V | CV1800B | 64MB | [Milk-V](https://milkv.io/) |
|
||||
| 2024 | [CanMV-K230](https://developer.canaan-creative.com/k230_canmv/en/main/) | RISC-V | K230 | 512MB | [Canaan](https://www.canaan-creative.com/) |
|
||||
|
||||
---
|
||||
|
||||
## 4. Fonctionne également sur
|
||||
|
||||
### Téléphones Android (via Termux)
|
||||
|
||||
Tout téléphone Android ARM64 (2015+) avec 1 Go+ de RAM. Installez [Termux](https://github.com/termux/termux-app), utilisez `proot` pour exécuter PicoClaw.
|
||||
|
||||
> Voir [README : Exécuter sur d'anciens téléphones Android](../../README.fr.md#-run-on-old-android-phones) pour les instructions de configuration.
|
||||
|
||||
### Bureau / Serveur / Cloud
|
||||
|
||||
| Plateforme | Notes |
|
||||
|------------|-------|
|
||||
| x86_64 Linux | Binaire natif, aucune dépendance |
|
||||
| x86_64 Windows | Binaire natif |
|
||||
| macOS (Intel / Apple Silicon) | Binaire natif |
|
||||
| Docker (any platform) | `docker compose` en une ligne, voir [Guide Docker](docker.md) |
|
||||
| OpenWrt routers | Builds MIPS/ARM, nécessite >32 Mo de RAM libre |
|
||||
| FreeBSD / NetBSD | Builds x86_64 et arm64 disponibles |
|
||||
|
||||
---
|
||||
|
||||
## 5. Configuration minimale requise
|
||||
|
||||
| Ressource | Minimum | Recommandé |
|
||||
|-----------|---------|------------|
|
||||
| RAM | 10 Mo libres | 32 Mo+ libres |
|
||||
| Stockage | 20 Mo (binaire) | 50 Mo+ (avec espace de travail) |
|
||||
| CPU | N'importe lequel (monocœur 0,6 GHz+) | — |
|
||||
| OS | Linux (kernel 3.x+) | Linux 5.x+ |
|
||||
| Réseau | Requis (pour les appels API LLM) | Ethernet ou WiFi |
|
||||
|
||||
---
|
||||
|
||||
## 6. Comment tester et contribuer
|
||||
|
||||
```bash
|
||||
# 1. Télécharger pour votre architecture
|
||||
wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw_Linux_arm64.tar.gz
|
||||
tar xzf picoclaw_Linux_arm64.tar.gz
|
||||
|
||||
# 2. Initialiser
|
||||
./picoclaw onboard
|
||||
|
||||
# 3. Tester
|
||||
./picoclaw agent -m "Hello, what board am I running on?"
|
||||
```
|
||||
|
||||
Builds disponibles : `linux-amd64`, `linux-arm64`, `linux-arm`, `linux-riscv64`, `linux-loong64`, `linux-mipsle`
|
||||
|
||||
### Ajouter votre matériel
|
||||
|
||||
1. Forkez ce dépôt
|
||||
2. Ajoutez votre puce / produit / carte dans le tableau approprié
|
||||
3. Incluez : nom, architecture, SoC, RAM, année et un lien si disponible
|
||||
4. Soumettez une PR
|
||||
|
||||
Fabricants de matériel : vous souhaitez ajouter un support officiel ou co-promouvoir ? Ouvrez une issue ou contactez-nous via [Discord](https://discord.gg/V4sAZ9XWpN).
|
||||
@@ -93,7 +93,7 @@ Cette conception permet également le **support multi-agents** avec une sélecti
|
||||
],
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": "gpt-5.4"
|
||||
"model_name": "gpt-5.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,13 +266,13 @@ L'ancienne configuration `providers` est **dépréciée** mais toujours prise en
|
||||
],
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": "glm-4.7"
|
||||
"model_name": "glm-4.7"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Pour un guide de migration détaillé, voir [docs/migration/model-list-migration.md](docs/migration/model-list-migration.md).
|
||||
Pour un guide de migration détaillé, voir [migration/model-list-migration.md](../migration/model-list-migration.md).
|
||||
|
||||
### Architecture des Fournisseurs
|
||||
|
||||
@@ -298,7 +298,7 @@ Cela maintient le runtime léger tout en faisant des nouveaux backends compatibl
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"workspace": "~/.picoclaw/workspace",
|
||||
"model": "glm-4.7",
|
||||
"model_name": "glm-4.7",
|
||||
"max_tokens": 8192,
|
||||
"temperature": 0.7,
|
||||
"max_tool_iterations": 20
|
||||
@@ -328,12 +328,11 @@ picoclaw agent -m "Hello"
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": "anthropic/claude-opus-4-5"
|
||||
"model_name": "anthropic/claude-opus-4-5"
|
||||
}
|
||||
},
|
||||
"session": {
|
||||
"dm_scope": "per-channel-peer",
|
||||
"backlog_limit": 20
|
||||
"dm_scope": "per-channel-peer"
|
||||
},
|
||||
"providers": {
|
||||
"openrouter": {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
**Correction :** Dans `~/.picoclaw/config.json` (ou votre chemin de configuration) :
|
||||
|
||||
1. **agents.defaults.model** doit correspondre à un `model_name` dans `model_list` (par ex. `"openrouter-free"`).
|
||||
1. **agents.defaults.model_name** doit correspondre à un `model_name` dans `model_list` (par ex. `"openrouter-free"`).
|
||||
2. Le **model** de cette entrée doit être un identifiant de modèle OpenRouter valide, par exemple :
|
||||
- `"openrouter/free"` – niveau gratuit automatique
|
||||
- `"google/gemini-2.0-flash-exp:free"`
|
||||
@@ -28,7 +28,7 @@ Exemple :
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": "openrouter-free"
|
||||
"model_name": "openrouter-free"
|
||||
}
|
||||
},
|
||||
"model_list": [
|
||||
|
||||
Reference in New Issue
Block a user