chore(init): 初始化项目目录结构与 Go 模块
This commit is contained in:
7
.env.example
Normal file
7
.env.example
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# LLM API 配置
|
||||||
|
LLM_API_KEY=your-api-key-here
|
||||||
|
LLM_BASE_URL=https://api.deepseek.com
|
||||||
|
LLM_MODEL=deepseek-chat
|
||||||
|
|
||||||
|
# 服务器配置
|
||||||
|
SERVER_PORT=8091
|
||||||
113
.gitea/workflows/go-loom.yaml
Normal file
113
.gitea/workflows/go-loom.yaml
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
name: GoLoom CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
env:
|
||||||
|
GO_VERSION: '1.26'
|
||||||
|
GOLANGCI_LINT_VERSION: 'v1.57.2'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
name: Lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Download dependencies
|
||||||
|
run: go mod download
|
||||||
|
|
||||||
|
- name: Run golangci-lint
|
||||||
|
uses: golangci/golangci-lint-action@v4
|
||||||
|
with:
|
||||||
|
version: ${{ env.GOLANGCI_LINT_VERSION }}
|
||||||
|
args: --timeout=5m
|
||||||
|
|
||||||
|
test:
|
||||||
|
name: Test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Download dependencies
|
||||||
|
run: go mod download
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: go test -v -race -coverprofile=coverage.out ./...
|
||||||
|
|
||||||
|
- name: Upload coverage
|
||||||
|
if: success()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: coverage-report
|
||||||
|
path: coverage.out
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [lint, test]
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Download dependencies
|
||||||
|
run: go mod download
|
||||||
|
|
||||||
|
- name: Build binary
|
||||||
|
run: |
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
|
||||||
|
go build -ldflags="-s -w" -o goloom-server ./cmd/server
|
||||||
|
|
||||||
|
- name: Upload binary
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: goloom-server
|
||||||
|
path: goloom-server
|
||||||
|
|
||||||
|
docker:
|
||||||
|
name: Docker Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [build]
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Download binary
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: goloom-server
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Build Docker image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: false
|
||||||
|
tags: |
|
||||||
|
goloom:latest
|
||||||
|
goloom:${{ github.sha }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
docs/
|
||||||
111
CLAUDE.md
Normal file
111
CLAUDE.md
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
GoLoom is an **AI Agent Scaffold** — a Go HTTP server for building and orchestrating multi-agent LLM workflows. It supports OpenAI-compatible APIs (DeepSeek, Tongyi Qianwen, etc.), four agent orchestration patterns (LLM, Sequential, Parallel, Loop), synchronous and SSE streaming chat, and tool calling via OpenAI function calling. A Next.js frontend is documented but not yet committed.
|
||||||
|
|
||||||
|
**Module name:** `ai-agent-scaffold-go`
|
||||||
|
**Language:** Go 1.26
|
||||||
|
**Documentation language:** Chinese (docs/ directory)
|
||||||
|
|
||||||
|
## Build and Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# First-time setup
|
||||||
|
go mod init ai-agent-scaffold-go
|
||||||
|
go mod tidy
|
||||||
|
|
||||||
|
# Build
|
||||||
|
go build ./...
|
||||||
|
|
||||||
|
# Run (requires .env and configs/application.yaml — see docs/build-from-scratch.md)
|
||||||
|
go run ./cmd/server
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
go get github.com/gin-gonic/gin
|
||||||
|
go get go.uber.org/zap
|
||||||
|
go get gopkg.in/yaml.v3
|
||||||
|
go get github.com/joho/godotenv
|
||||||
|
```
|
||||||
|
|
||||||
|
No Makefile, test suite, or linting configuration exists yet. The CI file at `.gitea/workflows/go-loom.yaml` is a placeholder.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
**Three-layer design: Handler → Service → Model/LLM**
|
||||||
|
|
||||||
|
```
|
||||||
|
cmd/server/main.go — Entry point: .env → config → bootstrap → Gin server
|
||||||
|
internal/handler/handler.go — Presentation: Gin routes, request/response, SSE
|
||||||
|
internal/service/ — Business: ChatService, Agent impls, Runner, Assembler
|
||||||
|
internal/model/ — Domain: config structs, core interfaces (Agent, ChatModel, Tool, Runner)
|
||||||
|
internal/config/ — Config loading: YAML parsing + ${VAR} env expansion
|
||||||
|
internal/llm/ — OpenAI-compatible HTTP client + ChatModel adapter
|
||||||
|
pkg/types/ — Error codes (codes.go) and AppError type (errors.go)
|
||||||
|
configs/ — application.yaml + agent/*.yaml definitions
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dependency direction:** handler → service → model/llm. `model` imports nothing internal.
|
||||||
|
|
||||||
|
## Core Interfaces (internal/model/types.go)
|
||||||
|
|
||||||
|
- **Tool** — `Name()`, `Description()`, `Call(ctx, input string) (string, error)`. Uses single `query` parameter.
|
||||||
|
- **ChatModel** — `Generate()` (sync) and `Stream()` (async via channels). Holds tool list for function calling.
|
||||||
|
- **Agent** — `Name()`, `Run(ctx, ChatContent) (string, error)`, `Stream(ctx, ChatContent, chan<- string) error`
|
||||||
|
- **Runner** — session ID generation + delegates to Agent for sync/stream execution
|
||||||
|
|
||||||
|
## Agent Types (internal/service/agent.go)
|
||||||
|
|
||||||
|
1. **LLMAgent** — single LLM call with tool-call loop (max 4 rounds)
|
||||||
|
2. **SequentialAgent** — runs sub-agents in order; output injected via `{outputKey}` template vars
|
||||||
|
3. **ParallelAgent** — runs all sub-agents concurrently, concatenates results
|
||||||
|
4. **LoopAgent** — repeats sub-agents up to `maxIterations` times
|
||||||
|
|
||||||
|
## Configuration System
|
||||||
|
|
||||||
|
Three-layer config: `.env` (secrets) → `configs/application.yaml` (server settings) → `configs/agent/*.yaml` (agent definitions). Agent YAML supports `${VAR}` and `${VAR:-default}` env var expansion at load time.
|
||||||
|
|
||||||
|
## HTTP API (base path /api/v1, default port 8091)
|
||||||
|
|
||||||
|
| Method | Path | Purpose |
|
||||||
|
|--------|------|---------|
|
||||||
|
| GET | `/healthz` | Health check (no envelope) |
|
||||||
|
| GET | `/api/v1/query_ai_agent_config_list` | List registered agents |
|
||||||
|
| POST | `/api/v1/create_session` | Create session (JSON body) |
|
||||||
|
| GET | `/api/v1/create_session` | Create session (query params) |
|
||||||
|
| POST | `/api/v1/chat` | Synchronous chat |
|
||||||
|
| POST | `/api/v1/chat_stream` | SSE streaming chat |
|
||||||
|
|
||||||
|
Unified response envelope: `{ "code": "0000", "info": "success", "data": {} }`
|
||||||
|
|
||||||
|
Typical flow: list agents → create session → chat with sessionId.
|
||||||
|
|
||||||
|
## Key Design Notes
|
||||||
|
|
||||||
|
- LLM client is hand-rolled HTTP (not an SDK) — OpenAI-compatible endpoints only
|
||||||
|
- Tool calling uses single `query` parameter model, not arbitrary function signatures
|
||||||
|
- In-memory storage (sync.RWMutex + Map) for agent registry and sessions
|
||||||
|
- SSE streaming uses goroutine + channel pattern
|
||||||
|
- Assembler (`internal/service/assembler.go`) reads YAML configs and wires up the full agent/runner/chatmodel chain in one function
|
||||||
|
|
||||||
|
## Development Conventions
|
||||||
|
|
||||||
|
- **Git 提交粒度**:每完成一个功能函数即 commit 一次;接口与结构体等定义可完成一个整体部分后再提交
|
||||||
|
- **提交格式**:`<type>(<scope>): <description>`
|
||||||
|
- type:`feat` / `fix` / `refactor` / `docs` / `style` / `test` / `chore`
|
||||||
|
- scope:模块名(如 `config`、`llm`、`agent`、`handler`、`service`、`types`)
|
||||||
|
- description:中文或英文简述
|
||||||
|
- 示例:`feat(config): 实现 YAML 配置加载与环境变量展开`、`feat(llm): 添加 OpenAI 兼容 HTTP 客户端`
|
||||||
|
- **进度追踪**:每进入下一个功能代码块前,检查 `docs/plan.md` 中的完成情况;每完成一个功能,将对应条目在 plan.md 中标记为已完成
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
All detailed docs are in `docs/` (Chinese):
|
||||||
|
- `docs/architecture.md` — architecture design and design decisions
|
||||||
|
- `docs/api-reference.md` — HTTP API spec with curl examples
|
||||||
|
- `docs/build-from-scratch.md` — complete Go backend source code and build guide
|
||||||
|
- `docs/frontend-build-from-scratch.md` — complete Next.js frontend source code
|
||||||
|
- `docs/testing-guide.md` — testing conventions (standard `testing` + optional `testify`, no external mock frameworks)
|
||||||
|
- `docs/logging-guide.md` — zap logging levels, required log points, and structured field conventions
|
||||||
1
cmd/server/main.go
Normal file
1
cmd/server/main.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package main
|
||||||
14
configs/application.yaml
Normal file
14
configs/application.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
app:
|
||||||
|
name: goloom
|
||||||
|
env: development
|
||||||
|
port: ${SERVER_PORT:-8091}
|
||||||
|
|
||||||
|
llm:
|
||||||
|
base_url: ${LLM_BASE_URL}
|
||||||
|
api_key: ${LLM_API_KEY}
|
||||||
|
model: ${LLM_MODEL:-deepseek-chat}
|
||||||
|
timeout: 30s
|
||||||
|
max_retries: 3
|
||||||
|
|
||||||
|
agent:
|
||||||
|
config_dir: configs/agent
|
||||||
1
internal/config/application.go
Normal file
1
internal/config/application.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package config
|
||||||
1
internal/config/loader.go
Normal file
1
internal/config/loader.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package config
|
||||||
1
internal/handler/handler.go
Normal file
1
internal/handler/handler.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package handler
|
||||||
1
internal/llm/chatmodel.go
Normal file
1
internal/llm/chatmodel.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package llm
|
||||||
1
internal/llm/client.go
Normal file
1
internal/llm/client.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package llm
|
||||||
1
internal/model/config.go
Normal file
1
internal/model/config.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package model
|
||||||
1
internal/model/types.go
Normal file
1
internal/model/types.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package model
|
||||||
1
internal/service/agent.go
Normal file
1
internal/service/agent.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package service
|
||||||
1
internal/service/assembler.go
Normal file
1
internal/service/assembler.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package service
|
||||||
1
internal/service/chat.go
Normal file
1
internal/service/chat.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package service
|
||||||
1
internal/service/runner.go
Normal file
1
internal/service/runner.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package service
|
||||||
1
pkg/types/codes.go
Normal file
1
pkg/types/codes.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package types
|
||||||
1
pkg/types/errors.go
Normal file
1
pkg/types/errors.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package types
|
||||||
Reference in New Issue
Block a user