feat(skills): P3 config_schema + P4 Versionierung mit Rollback
P3 — Skill-Configuration
- aria-brain/skills.py: SKILL_CONFIGS_FILE (/shared/config/skill_configs.json)
als zentrale Werte-Persistenz. _normalize_config_schema validiert die
Schema-Felder (name/type/label/secret/description/default), CFG_<UPPER_NAME>
ENV beim run_skill. create_skill + update_skill akzeptieren config_schema.
- agent.py: skill_set_config Brain-Tool fuer ARIA. skill_create/update um
config_schema-Property erweitert.
- main.py: GET/POST /skills/{name}/config — secret-Werte in Antwort gemaskt.
P4 — Versionierung mit Rollback
- aria-brain/skills.py: archive_current_version archiviert nach
versions/v_<ts>/ (ohne venv/logs). update_skill ruft das automatisch auf
bevor strukturelle Aenderungen passieren. list_skill_versions,
rollback_skill (mit Safety-Snapshot + automatischem venv-Rebuild),
delete_skill_version.
- agent.py: skill_list_versions, skill_rollback Brain-Tools.
- main.py: GET /skills/{name}/versions, POST /skills/{name}/rollback,
DELETE /skills/{name}/versions/{version_id}.
UI
- diagnostic/index.html: Skill-Detail um Config-Form (typ-spezifisch,
Secrets als password-Input mit ***SET***-Hinweis) und Versions-Liste
mit Rollback-/Delete-Button.
- android SkillBrowser: SkillDetailModal laedt config_schema + versions
on-mount. Config-Form (TextInput + Switch fuer boolean), Versionen mit
Rollback-Confirm. brainApi um SkillConfigField/SkillVersion +
getSkillConfig/setSkillConfig/listSkillVersions/rollbackSkill/
deleteSkillVersion erweitert.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -158,6 +158,26 @@ export interface Skill {
|
||||
version?: string;
|
||||
author?: string; // "aria" | "stefan"
|
||||
setup_error?: string;
|
||||
// P3: konfigurierbare Werte (API-Keys, IDs etc.) — Stefan setzt sie hier,
|
||||
// Skill bekommt sie als CFG_<NAME> ENV. Werte selbst kommen via /config.
|
||||
config_schema?: SkillConfigField[];
|
||||
// P4: Versions-Historie. Detail-Liste kommt via /versions.
|
||||
version_history?: { version_id: string; archived_at?: string; summary?: string }[];
|
||||
}
|
||||
|
||||
export interface SkillConfigField {
|
||||
name: string;
|
||||
type: 'string' | 'number' | 'boolean' | 'password';
|
||||
label?: string;
|
||||
secret?: boolean;
|
||||
description?: string;
|
||||
default?: any;
|
||||
}
|
||||
|
||||
export interface SkillVersion {
|
||||
version_id: string;
|
||||
archived_at?: string;
|
||||
summary?: string;
|
||||
}
|
||||
|
||||
/** Trigger-Manifest wie aus Brain `/triggers/list` zurueckkommt. */
|
||||
@@ -395,7 +415,46 @@ export const brainApi = {
|
||||
|
||||
/** Letzte Run-Logs eines Skills. */
|
||||
getSkillLogs(name: string, limit: number = 20): Promise<any[]> {
|
||||
return _send(`/skills/${encodeURIComponent(name)}/logs?limit=${limit}`);
|
||||
return _send(`/skills/${encodeURIComponent(name)}/logs?limit=${limit}`)
|
||||
.then((r: any) => Array.isArray(r) ? r : (r?.logs || []));
|
||||
},
|
||||
|
||||
/** P3: Config-Schema + aktuelle Werte (secret-Felder gemaskt mit '***SET***'). */
|
||||
getSkillConfig(name: string): Promise<{ schema: SkillConfigField[]; values: Record<string, any> }> {
|
||||
return _send(`/skills/${encodeURIComponent(name)}/config`)
|
||||
.then((r: any) => ({ schema: r?.schema || [], values: r?.values || {} }));
|
||||
},
|
||||
|
||||
/** P3: Config-Werte komplett ueberschreiben. Werte greifen ab dem naechsten Run. */
|
||||
setSkillConfig(name: string, values: Record<string, any>): Promise<{ ok: boolean; values: Record<string, any> }> {
|
||||
return _send(`/skills/${encodeURIComponent(name)}/config`, {
|
||||
method: 'POST',
|
||||
body: { values },
|
||||
timeoutMs: 10000,
|
||||
});
|
||||
},
|
||||
|
||||
/** P4: Liste archivierter Versionen, neueste zuerst. */
|
||||
listSkillVersions(name: string): Promise<SkillVersion[]> {
|
||||
return _send(`/skills/${encodeURIComponent(name)}/versions`)
|
||||
.then((r: any) => r?.versions || []);
|
||||
},
|
||||
|
||||
/** P4: Rollback auf eine fruehere Version. Aktueller Stand wird automatisch gesichert. */
|
||||
rollbackSkill(name: string, versionId: string): Promise<{ ok: boolean; rolled_back_to: string; safety_snapshot: string }> {
|
||||
return _send(`/skills/${encodeURIComponent(name)}/rollback`, {
|
||||
method: 'POST',
|
||||
body: { version_id: versionId },
|
||||
timeoutMs: 60000, // venv-Rebuild kann dauern
|
||||
});
|
||||
},
|
||||
|
||||
/** P4: Einzelne Version dauerhaft loeschen. */
|
||||
deleteSkillVersion(name: string, versionId: string): Promise<{ ok: boolean; deleted: string }> {
|
||||
return _send(`/skills/${encodeURIComponent(name)}/versions/${encodeURIComponent(versionId)}`, {
|
||||
method: 'DELETE',
|
||||
timeoutMs: 10000,
|
||||
});
|
||||
},
|
||||
|
||||
// ── OAuth ────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user