Skip to content
Merged
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
28 changes: 0 additions & 28 deletions .github/workflows/plugin-api-v2.yml

This file was deleted.

81 changes: 81 additions & 0 deletions .github/workflows/plugin-api-v3.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: plugin-api-v3

on:
pull_request:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read

jobs:
contract:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: akashic-plugins/plugin-contracts
ref: 4dd69dd621e029e51e99aa428443fa3a4ec1f6cf
path: .plugin-contracts
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Check Plugin API v3
env:
PYTHONPATH: .plugin-contracts
run: python -m akashic_plugin_contracts check plugin.py

plugin-tests:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: kachofugetsu09/akashic-agent
ref: 78e50d4dfb3f4348fff37d55d9c9bdd0e002164d
path: .akashic-core
- uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: pip
cache-dependency-path: |
.akashic-core/requirements.txt
requirements.txt
- name: Stage exact Fitbit runtime
run: |
python -m venv .venv
.venv/bin/python -m pip install \
-r .akashic-core/requirements.txt \
-r .akashic-core/requirements-dev.txt \
-r requirements.txt
- name: Verify Fitbit v3 composition
env:
AKASHIC_AGENT_ROOT: .akashic-core
PYTHONPATH: .akashic-core
run: .venv/bin/python -m pytest -q tests/
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- name: Verify Fitbit panels
run: |
npm ci
npm test
- name: Check v3 source types
env:
PYTHONPATH: .akashic-core
run: >-
.venv/bin/pyright --pythonpath .venv/bin/python --level error
plugin.py dashboard.py src/mcp_bridge.py
scripts/migrate_v2_data.py
tests/test_plugin.py tests/test_dashboard.py
tests/test_manager_integration.py tests/test_mcp_v3_runtime.py
tests/test_migrate_v2_data.py
- name: Compile Python sources
run: python -m compileall -q plugin.py dashboard.py src monitor scripts tests
- name: Check diff formatting
run: git diff --check
46 changes: 46 additions & 0 deletions akashic.plugin.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
schema_version = 1
name = "fitbit"
version = "3.0.0"
api_version = 3
entrypoint = "plugin.py"

[[python]]
requirements = "requirements.txt"

[validation]
exclude_data_paths = [
"monitor.config.toml",
"monitor.config.local.toml",
"tokens.json",
"sleep_log.jsonl",
"sleep_labels.json",
"sleep_model.pkl",
"stat_events.json",
"stat_events_v2.json",
"mobile_sleep_projection.json",
"monitor.runtime.log",
"backups",
"logs",
".fitbit-v2-migration.json",
]

[[processes]]
name = "monitor"
command = ["python", "monitor/server.py"]
cwd = "."
port_env = "FITBIT_MONITOR_PORT"
formal_port = 18765
readiness_path = "/api/data"
startup_timeout_seconds = 15.0

[[mcp]]
name = "fitbit"
command = ["python", "run_mcp.py"]
required_tools = [
"get_proactive_events",
"get_sleep_context",
"acknowledge_events",
]
candidate_read_only_tools = ["get_proactive_events", "get_sleep_context"]
endpoint_env = [{env = "FITBIT_MONITOR_PORT", process = "monitor"}]
candidate_env = {FITBIT_BACKEND = "recording"}
12 changes: 7 additions & 5 deletions dashboard.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
from __future__ import annotations

from collections.abc import Mapping
from collections.abc import Mapping, Sequence
from typing import Any

import requests
from fastapi import FastAPI, HTTPException
from fastapi.responses import RedirectResponse

from agent.plugin_composition import DashboardContext


_MONITOR_URL = "http://127.0.0.1:18765"


def register(app: FastAPI, plugin_dir: object, workspace: object) -> None:
def register(app: FastAPI, context: DashboardContext) -> None:
"""Expose the monitor's current snapshot through the Akashic Dashboard."""

_ = plugin_dir, workspace
_ = context

@app.get("/api/dashboard/fitbit/overview")
def overview() -> dict[str, object]:
Expand Down Expand Up @@ -71,7 +73,7 @@ def _project_dashboard_snapshot(payload: Mapping[str, object]) -> dict[str, obje
def _project_overview(
data: Mapping[str, object],
snapshot: Mapping[str, object],
history: list[object] | None = None,
history: Sequence[object] | None = None,
) -> dict[str, object]:
"""Validate monitor payloads and build the Dashboard first-screen DTO."""

Expand Down Expand Up @@ -113,7 +115,7 @@ def _project_overview(
}


def _prediction_events(rows: list[object]) -> list[dict[str, object]]:
def _prediction_events(rows: Sequence[object]) -> list[dict[str, object]]:
"""Project stored model outputs separately from final sleep decisions."""

events: list[dict[str, object]] = []
Expand Down
15 changes: 15 additions & 0 deletions docs/v3-data-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Fitbit v3 数据迁移

Fitbit v3 只读写 `<workspace>/plugin-data/fitbit-<marketplace>`。旧数据不会在插件加载时自动移动,也不会被删除。

停用旧 Fitbit runtime 后,显式执行:

```bash
python scripts/migrate_v2_data.py \
--workspace <workspace> \
--marketplace github
```

迁移持有 workspace 实例锁,从 `mcp/fitbit-mcp/monitor` 复制已知数据文件,并在目标目录写入 `.fitbit-v2-migration.json` 内容回执。旧目录始终保留,作为恢复点。

进程内失败会删除本次新发布的目标文件;Core 进程崩溃后再次执行同一命令,会校验已发布内容并继续完成。目标已有不同内容或回执与文件不一致时,命令会明确失败,不覆盖数据。
Loading
Loading