# Rozbudowa narzedzia Ten plik opisuje, jak dodawac nowe grupy zadan, zadania i skrypty, zeby kolejny agent nie musial projektowac procesu od zera. ## Zasada architektury Kazde zadanie powinno dzialac w tym samym modelu: 1. Pobierz aktualne dane. 2. Zbuduj plan. 3. Zapisz plan do `clients//plans/` jako `.json` i `.md`. 4. W trybie `--plan-only` nie wdrazaj zmian. 5. Po akceptacji uzytkownika wdrazaj tylko plan zapisany w JSON. 6. Zapisz historie do: - `clients//history/YYYY-MM-DD.jsonl` - `clients//changes/YYYY-MM-DD.md` Agent AI prowadzi uzytkownika, ale logika pobierania danych, analizy i wdrozenia zmian ma byc w Pythonie. ## Granice zadan i rytm kontroli Jedno zadanie powinno miec jeden rytm kontroli i jeden typ decyzji. Nie mieszaj w jednym zadaniu prostych ustawien konfiguracyjnych, budzetow, strategii stawek, zapytan uzytkownikow i reklam, bo te obszary sprawdza sie z rozna czestotliwoscia i niosa inne ryzyka. Przyklady podzialu: - ustawienia podstawowe, np. lokalizacje, sieci, jezyki - zwykle raz w miesiacu albo po zmianach, - budzety i pacing - zwykle co tydzien, - strategie stawek - zwykle co tydzien albo co dwa tygodnie, z ocena wolumenu konwersji, - zapytania i wykluczenia - zwykle co tydzien, - reklamy i zasoby - zwykle co dwa do czterech tygodni, - struktura konta i kampanii - zwykle miesiecznie albo kwartalnie. Opis zadania w `config/tasks.toml` ma jasno mowic, co jest w zakresie i czego zadanie nie analizuje. Jesli obszar wymaga innej czestotliwosci, dodaj osobne zadanie albo osobna grupe. ## Dodanie nowej grupy zadan Przed dodaniem wiekszego zakresu sprawdz: ```text OLD_COMMANDS_CHECKLIST.md ``` To jest lista rzeczy sprawdzanych przez stary system z `D:\google ads\`. Edytuj: ```text config/tasks.toml ``` Dodaj nowa grupe: ```toml [[groups]] id = "search" name = "Kampanie Search" ``` Zadania beda numerowane automatycznie jako `2.1`, `2.2`, itd. w zaleznosci od kolejnosci grup. ## Dodanie nowego zadania do grupy W `config/tasks.toml` dodaj zadanie pod odpowiednia grupa: ```toml [[groups.tasks]] id = "check_search_settings" name = "Sprawdzenie ustawien" description = "Sprawdza ustawienia kampanii Search wedlug regul globalnych i wyjatkow klienta." ``` `id` jest techniczne i musi byc stabilne. `name` i `description` sa dla uzytkownika. ## Plik zadania w Pythonie Dodaj modul w: ```text src/gads_v2/tasks/ ``` Przyklad nazwy: ```text src/gads_v2/tasks/search_settings_check.py ``` Minimalny wzorzec funkcji: ```python def run_check_search_settings( client_config: ClientConfig, global_rules: dict, plan_only: bool = False, apply_plan_path: str | None = None, confirm_apply: str | None = None, show_navigation: bool = True, ) -> None: ... ``` Wymagania: - `plan_only=True` zawsze tylko zapisuje plan. - `apply_plan_path` wdraza tylko wskazany plan JSON. - `confirm_apply` musi wymagac wartosci `TAK`. - `show_navigation=False` musi ukrywac pytanie `Co dalej`, bo uzywa tego tryb sekwencji. ## Struktura planu Plan powinien miec klase lub slownik z metodami: ```python to_dict() from_dict() ``` Plan JSON musi zawierac: ```json { "created_at": "...", "client": "example.pl", "task": "task_id", "changes": [] } ``` Plan Markdown powinien zawierac: - krotkie podsumowanie, - tabele po kampaniach, jesli zadanie dotyczy kampanii, - tabele planowanych dzialan, - ostrzezenia lub pominiete reguly. ## Podpiecie zadania do CLI Edytuj: ```text src/gads_v2/cli.py ``` 1. Zaimportuj funkcje zadania: ```python from .tasks.search_settings_check import run_check_search_settings ``` 2. Dodaj `id` do argumentu `--task`: ```python parser.add_argument("--task", choices=["sync_pla_cl1", "check_pla_settings", "check_search_settings"], ...) ``` 3. Dodaj obsluge w `run_task()`: ```python if task_id == "check_search_settings": run_check_search_settings( client, global_rules, plan_only=plan_only, apply_plan_path=apply_plan_path, confirm_apply=confirm_apply, show_navigation=show_navigation, ) return ``` ## Reguly globalne i wyjatki klientow Reguly trzymaj w: ```text config/clients.toml ``` Przyklad globalny: ```toml [global_rules.search_settings] require_presence_only = true require_search_partners_off = true ``` Wyjatek per klient: ```toml [clients."example.pl".search_settings] require_search_partners_off = false ``` W kodzie uzywaj: ```python rules = client_config.effective_rules(global_rules, "search_settings") ``` ## Pominiecia zadan przy ALL Jesli zadanie ma byc pomijane tylko przy pelnym wyborze `ALL` / `--all-groups`, dodaj je przy konkretnym kliencie: ```toml [clients."example.pl"] google_ads_customer_id = "123-456-7890" skip_in_all = ["split_pla_cl1_bestsellers"] ``` Pominiecie dotyczy tylko `ALL` / `--all-groups`. Reczny wybor zadania albo grupy nadal uruchamia wskazany zakres. ## Numeracja i wybory Lista zadan uzywa formatu: ```text 1.1 - pierwsze zadanie w pierwszej grupie 1.2 - drugie zadanie w pierwszej grupie 1.0 - wszystkie zadania z pierwszej grupy ALL - wszystkie zadania ze wszystkich grup ``` Nie dodawaj recznej numeracji do `tasks.toml`. Numeracja wynika z kolejnosci grup i zadan. ## Test po dodaniu zadania Uruchom: ```powershell python -m compileall -q gads.py src python gads.py analiza-klienta --client-number 1 python gads.py analiza-klienta --client-number 1 --select --plan-only ``` Jesli zadanie wdraza zmiany, przetestuj najpierw tylko `--plan-only`. ## Format komunikacji agentow Instrukcja dla agentow jest w: ```text AGENTS.md ``` Po dodaniu nowego typu zadania dopisz tam tylko specjalne zasady, jesli agent ma wiedziec cos ponad standardowy przeplyw. ## Rozbudowa bazy wiedzy Baza wiedzy projektu jest w: ```text knowledge/ ``` Najwazniejsze pliki: - `knowledge/sources/` - materialy zrodlowe, np. artykuly, notatki, eksport ze starej LanceDB. - `knowledge/rules.jsonl` - atomowe reguly uzywane przez narzedzie. - `knowledge/imports.jsonl` - historia importow. - `knowledge/lancedb/` - metadane indeksu semantycznego. Fizyczny indeks LanceDB jest domyslnie w `%LOCALAPPDATA%\google-ads-ver2-knowledge-lancedb`, bo katalog projektu moze byc synchronizowany i blokowac operacje zapisu LanceDB. Dodawanie wiedzy: ```powershell python gads.py wiedza dodaj --file "knowledge/sources/plik.md" --source "czytelna_nazwa_zrodla" --dry-run python gads.py wiedza dodaj --file "knowledge/sources/plik.md" --source "czytelna_nazwa_zrodla" ``` Jednorazowy import starej bazy LanceDB: ```powershell python gads.py wiedza import-stare --from "D:\google ads\lancedb" python gads.py wiedza indeksuj ``` Ten import nie przypisuje regul do zadan. `task_ids` oraz `suggested_task_ids` pozostaja puste. Wznawialny przeglad regul bez przypisan: ```powershell python gads.py wiedza przypisz python gads.py wiedza przypisz --restart ``` Domyslnie `wiedza przypisz` pokazuje jedna regule, pelny kontekst decyzji i konczy porcje po jednej odpowiedzi. Reguly sa przegladane w kolejnosci zapisanej w `knowledge/rules.jsonl`, a nie sortowane po tematach. To ulatwia uzytkownikowi porownanie ekranu przegladu z plikiem i kolejnoscia importu. Wieksze partie uruchamiaj tylko jawnie, np. `python gads.py wiedza przypisz --limit 10`. Zasady przegladu: - `Q` przerywa bez przesuniecia kursora, wiec wznowienie zacznie od tej samej reguly. - `P` pomija regule i zapisuje postep. - `U` pyta o potwierdzenie `USUN`, a potem trwale usuwa biezaca regule z `knowledge/rules.jsonl`. - Numer zadania lub `task_id` dopisuje regule do zadania. - Po dodaniu nowych zadan do `config/tasks.toml` uruchom `python gads.py wiedza przypisz --restart`. - Stan kursora jest w `knowledge/review_state.json`. - Po usunieciu reguly stan kursora zapisuje takze klucz sortowania, zeby wznowienie zaczelo od nastepnej reguly mimo braku usunietego `id` w pliku. - Po fizycznym usunieciu regul trzeba odbudowac LanceDB przez `python gads.py wiedza indeksuj`, bo indeks jest tylko lokalna kopia do wyszukiwania. Zasady: - Najpierw uruchom `--dry-run`, zeby sprawdzic plik bez kosztu API. - Import przez API wymaga `OPENAI_API_KEY` w `.env`. - Opcjonalny model ustaw przez `KNOWLEDGE_OPENAI_MODEL` albo `--model`. - Reguly przypisuj tylko do istniejacych `task_id` z `config/tasks.toml`. - Importer moze zapisac propozycje w `suggested_task_ids`, ale nie wolno uznawac ich za aktywne przypisanie do zadania. - Regula staje sie regula zadania dopiero po akceptacji uzytkownika przez pytanie skryptu albo komenda: ```powershell python gads.py wiedza zatwierdz --rule-id "" --task "" ``` - Odrzucenie propozycji: ```powershell python gads.py wiedza odrzuc --rule-id "" --task "" ``` - Jesli wiedza dotyczy zadania, ktorego jeszcze nie ma, zostaw `task_ids` i `suggested_task_ids` puste i zaplanuj osobne zadanie w `config/tasks.toml`. - Reguly z `knowledge/rules.jsonl` wspieraja analize i uzasadnienie planu. Nie wolno traktowac ich jako automatycznej zgody na wdrozenie zmian. - `rules.jsonl` jest zrodlem prawdy. LanceDB, gdy zostanie dodane, ma byc tylko indeksem semantycznym odbudowywanym z JSONL. - Po zmianach w `rules.jsonl` odswiez indeks: ```powershell python gads.py wiedza indeksuj ``` - Wyszukiwanie semantyczne: ```powershell python gads.py wiedza szukaj-ai "zapytanie opisowe" ``` - Kazda regula powinna miec metadane: `status`, `created_at`, `updated_at`, `source_file`, `duplicate_of`, `supersedes`. - Nie kasuj regul recznie przy porzadkowaniu bazy. Zmieniaj status: ```powershell python gads.py wiedza archiwizuj --rule-id "" python gads.py wiedza aktywuj --rule-id "" python gads.py wiedza duplikat --rule-id "" --duplicate-of "" ``` - Po imporcie sprawdz wynik: ```powershell python gads.py wiedza szukaj "temat" python gads.py wiedza propozycje python gads.py wiedza reguly --task check_pla_settings python gads.py wiedza lista --topic shopping python gads.py wiedza statystyki ```