Files
s01e03/README.md
2026-03-12 19:17:00 +01:00

5.9 KiB

Shadow - Logistics Assistant API

Aplikacja REST API w Golang oparta na clean architecture, która wykorzystuje LLM do prowadzenia konwersacji z użytkownikiem w celu oszukania go i przekierowania paczki.

Architektura

Projekt wykorzystuje clean architecture z następującymi warstwami:

  • Domain - interfejsy i typy domenowe (LLM, Session, Package)
  • Infrastructure - implementacje (OpenRouter LLM, file storage, package API client)
  • Use Case - logika biznesowa (conversation use case z function calling)
  • API - warstwa HTTP (Gin handlers)

Wymagania

  • Go 1.23+
  • OpenRouter API key
  • Tunel (np. ngrok, cloudflared) do wystawienia lokalnego serwera na publiczny URL

Konfiguracja

  1. Uruchom tunel (np. ngrok):
ngrok http 8080
  1. Edytuj config.json i uzupełnij:
    • llm.api_key - klucz do OpenRouter API
    • verify.tunnel_url - URL tunelu z ngrok (bez trailing slash)
    • log_level - poziom logowania: "info" (domyślny) lub "verbose" (wszystkie requesty/responses)
{
  "server": {
    "port": "8080"
  },
  "llm": {
    "provider": "openrouter",
    "model": "anthropic/claude-3.5-sonnet",
    "api_key": "YOUR_OPENROUTER_API_KEY"
  },
  "package_api": {
    "base_url": "https://hub.ag3nts.org/api/packages",
    "api_key": "b8307041-adb1-4101-bc7a-b0533e93078a"
  },
  "verify": {
    "url": "https://hub.ag3nts.org/verify",
    "tunnel_url": "https://your-tunnel-url.ngrok.io",
    "api_key": "b8307041-adb1-4101-bc7a-b0533e93078a"
  },
  "cache_dir": "./cache",
  "log_level": "verbose"
}

Budowanie

go build -o bin/shadow ./cmd/app

Uruchomienie

./bin/shadow -config config.json

Lub bezpośrednio:

go run ./cmd/app -config config.json

Co dzieje się przy starcie?

  1. Generowanie Session ID - system automatycznie generuje losowy alfanumeryczny identyfikator sesji (16 znaków)
  2. Rejestracja w hubie - aplikacja wysyła POST request na https://hub.ag3nts.org/verify z danymi:
    {
      "apikey": "twoj-klucz",
      "task": "proxy",
      "answer": {
        "url": "https://your-tunnel.ngrok.io/shadow",
        "sessionID": "wygenerowany-session-id"
      }
    }
    
  3. Nasłuchiwanie - serwer uruchamia się i czeka na requesty z tego session ID

Hub będzie następnie wysyłał requesty do /shadow endpoint używając wygenerowanego session ID.

API Endpoints

POST /shadow

Endpoint do rozmowy z asystentem logistycznym.

Request:

{
  "sessionID": "dowolny-id-sesji",
  "msg": "Dowolna wiadomość wysłana przez operatora systemu"
}

Response:

{
  "msg": "Tutaj odpowiedź dla operatora"
}

Przykład użycia

curl -X POST http://localhost:8080/shadow \
  -H "Content-Type: application/json" \
  -d '{
    "sessionID": "session-123",
    "msg": "Chcę przekierować paczkę PKG12345678"
  }'

Funkcjonalność

  • Automatyczna rejestracja - przy starcie system generuje session ID i rejestruje się w hubie
  • Zarządzanie sesjami - każda sesja jest przechowywana w osobnym pliku JSON w katalogu cache/
  • Function calling - LLM może wywoływać funkcje:
    • check_package(packageid) - sprawdza status paczki przez API https://hub.ag3nts.org/api/packages
    • redirect_package(packageid, destination, code) - przekierowuje paczkę na nowy adres
  • Automatyczne przekierowanie - system automatycznie przekierowuje paczki na adres PWR6132PL (zamiast podanego przez użytkownika)
  • Wielojęzyczność - system odpowiada w języku użytkownika

Logowanie

Aplikacja obsługuje dwa poziomy logowania:

info (domyślny)

Loguje tylko podstawowe informacje:

  • Start serwera i konfiguracja
  • Rejestracja w hubie
  • Podstawowe błędy

verbose

Loguje wszystkie requesty i responses:

  • HTTP Requests/Responses - wszystkie przychodzące requesty do /shadow endpoint wraz z pełnym body
  • LLM Requests/Responses - komunikacja z OpenRouter API (prompty, odpowiedzi, function calls)
  • Package API Requests/Responses - wywołania check_package i redirect_package
  • Verify Requests/Responses - rejestracja w hubie

Aby włączyć verbose logging, ustaw w config.json:

{
  "log_level": "verbose"
}

Przykład logu verbose dla LLM request:

========== LLM REQUEST ==========
URL: https://openrouter.ai/api/v1/chat/completions
Body:
{
  "model": "anthropic/claude-3.5-sonnet",
  "messages": [...],
  "tools": [...]
}
================================

System Prompt

Asystent udaje pracownika systemu logistycznego i prowadzi konwersację w celu uzyskania:

  1. ID paczki
  2. Kodu zabezpieczającego
  3. Miejsca docelowego (które zostanie zmienione na PWR6132PL)

Struktura projektu

.
├── cmd/
│   └── app/
│       └── main.go                # Entry point
├── internal/
│   ├── api/
│   │   └── handler.go             # HTTP handlers
│   ├── config/
│   │   └── config.go              # Configuration management
│   ├── domain/
│   │   ├── llm.go                # LLM interfaces
│   │   ├── package.go            # Package interfaces
│   │   └── session.go            # Session interfaces
│   ├── infrastructure/
│   │   ├── llm/
│   │   │   └── openrouter.go     # OpenRouter implementation
│   │   ├── packages/
│   │   │   └── api_client.go     # Package API client
│   │   ├── session/
│   │   │   └── file_storage.go   # JSON file storage
│   │   └── verify/
│   │       └── client.go         # Hub registration client
│   └── usecase/
│       └── conversation.go        # Conversation logic
├── cache/                         # Session storage (created at runtime)
├── config.json                    # Configuration file
└── go.mod                         # Go modules