micro--go-micro
9fdcc24cce
* docs: design note for flow steps + Checkpoint durable execution
* docs: fold in durable-execution decisions (State struct, single Step, run retention, retry)
* docs: rename State.Payload to State.Data
* feat(flow): ordered steps + Checkpoint durable execution
A flow can now be an ordered list of steps (a task with stages) instead
of a single LLM turn. State carries typed Data plus a Stage marker; each
step is checkpointed before and after via a pluggable Checkpoint
(store-backed by default), so a run survives a crash and resumes where it
stopped without re-running completed steps. Flow-level Retry with a
per-step override; runs retained for audit unless DeleteOnSuccess.
Step actions: Call (RPC), LLM (augmented turn), Dispatch (to an agent),
or any StepFunc. Single-step and agent-dispatch flows are unchanged.
* feat(flow): top-level re-exports + durable flow example
Expose the step/checkpoint API from the micro package (FlowSteps,
FlowStep, FlowState, FlowRetry, FlowWithCheckpoint, FlowCall/LLM/Dispatch,
Checkpoint, StoreCheckpoint) and add a runnable, key-free example
demonstrating crash + resume.
* docs: document durable flow steps (guide, README, CLI help)
* docs: blog post + changelog for durable workflows
* fix(flow): scope checkpoint keys by flow name (flow/{name}/runs/{id})
Run keys were flow/runs/{id} — a single global keyspace shared by every
flow on the default store. Namespace them by flow name so each flow's
state is kept apart. StoreCheckpoint now takes a scope argument (the flow
passes its name by default).
* feat(store): Scope handle; scope agent and flow state by name
Add store.Scope(s, database, table) — a store handle that confines every
operation to a database/table without mutating the shared store, so
co-located components don't clobber each other's table (the failure mode
of the global Init(Table(...)) approach).
Use it to keep each agent's memory and plan in its own table
(agent/{name}) and each flow's runs in its own (flow/{name}), instead of
one global table partitioned only by key prefix. Services already scope
by service name.
* feat: consistent state model — service store scoping, flow registry, list/history CLI
- service: scope store via store.Scope (database service / table name),
retiring the Init(store.Table(name)) global-mutation hack; bridge the
default store so handlers using store.DefaultStore stay isolated.
- flow: register in the registry as type=flow while running (with trigger
and step count), deregister on Stop. Live discovery, like agents.
- cli: micro flow list (registry), micro flow runs <name> (durable store),
micro agent history <name> (durable store). list = running, runs/history
= durable, mirroring the service model.
* test: mini-universe end-to-end harness + scheduled GitHub Action
internal/harness/universe boots a small but real go-micro world — four
services, a durable checkout flow that crashes at payment and resumes,
and a guardrailed agent with a tool wrapper reached over RPC — drives the
scenario, asserts the end state (10 checks), and shuts down. Everything
is real except the LLM (mocked), so it's deterministic and needs no key;
-provider anthropic runs it live. Exits non-zero on failure, so it's an
end-to-end test, not just a demo.
Adds .github/workflows/universe.yml (push/PR/daily/dispatch) running the
universe + existing harnesses on the mock provider, plus an opt-in job
that runs live when ANTHROPIC_API_KEY is set. 'make harness' runs them
locally.
* ci: run the live universe job against AtlasCloud (ATLASCLOUD_API_KEY)
* ci: run the live universe job only on schedule or manual dispatch
The deterministic mock job still runs on push/PR/daily; the live
(AtlasCloud) job runs daily and on manual workflow_dispatch only, so
changes don't burn API credits on every PR but can still be checked
against a real model on demand.
---------
Co-authored-by: Claude <noreply@anthropic.com>
90 行
2.7 KiB
Makefile
90 行
2.7 KiB
Makefile
NAME = micro
|
|
GIT_COMMIT = $(shell git rev-parse --short HEAD)
|
|
GIT_TAG = $(shell git describe --abbrev=0 --tags --always --match "v*")
|
|
GIT_IMPORT = go-micro.dev/v5/cmd/micro
|
|
BUILD_DATE = $(shell date +%s)
|
|
LDFLAGS = -X $(GIT_IMPORT).BuildDate=$(BUILD_DATE) -X $(GIT_IMPORT).GitCommit=$(GIT_COMMIT) -X $(GIT_IMPORT).GitTag=$(GIT_TAG)
|
|
|
|
# GORELEASER_DOCKER_IMAGE = ghcr.io/goreleaser/goreleaser-cross:v1.25.7
|
|
GORELEASER_DOCKER_IMAGE = ghcr.io/goreleaser/goreleaser:latest
|
|
|
|
.PHONY: test test-race test-coverage harness lint fmt install-tools proto clean help gorelease-dry-run gorelease-dry-run-docker
|
|
|
|
# Default target
|
|
help:
|
|
@echo "Go Micro Development Tasks"
|
|
@echo ""
|
|
@echo " make test - Run tests"
|
|
@echo " make test-race - Run tests with race detector"
|
|
@echo " make test-coverage - Run tests with coverage"
|
|
@echo " make lint - Run linter"
|
|
@echo " make fmt - Format code"
|
|
@echo " make install-tools - Install development tools"
|
|
@echo " make proto - Generate protobuf code"
|
|
@echo " make clean - Clean build artifacts"
|
|
|
|
$(NAME):
|
|
CGO_ENABLED=0 go build -ldflags "-s -w ${LDFLAGS}" -o $(NAME) cmd/micro/main.go
|
|
|
|
# Run tests
|
|
test:
|
|
go test -v ./...
|
|
|
|
# Run tests with race detector
|
|
test-race:
|
|
go test -v -race ./...
|
|
|
|
# Run tests with coverage
|
|
test-coverage:
|
|
go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
|
|
go tool cover -html=coverage.out -o coverage.html
|
|
@echo "Coverage report: coverage.html"
|
|
|
|
# Run the end-to-end harnesses (deterministic, mock LLM — no API key).
|
|
# The universe harness exits non-zero on assertion failure.
|
|
harness:
|
|
go run ./internal/harness/universe
|
|
go run ./internal/harness/agent-flow
|
|
go run ./internal/harness/plan-delegate
|
|
|
|
# Run linter
|
|
lint:
|
|
golangci-lint run
|
|
|
|
# Format code
|
|
fmt:
|
|
gofmt -s -w .
|
|
goimports -w .
|
|
|
|
# Install development tools
|
|
install-tools:
|
|
@echo "Installing development tools..."
|
|
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
|
go install golang.org/x/tools/cmd/goimports@latest
|
|
go install github.com/kyoh86/richgo@latest
|
|
go install go-micro.dev/v5/cmd/protoc-gen-micro@latest
|
|
@echo "Tools installed successfully"
|
|
|
|
# Generate protobuf code
|
|
proto:
|
|
@echo "Generating protobuf code..."
|
|
find . -name "*.proto" -not -path "./vendor/*" -exec protoc --proto_path=. --micro_out=. --go_out=. {} \;
|
|
|
|
# Clean build artifacts
|
|
clean:
|
|
rm -f coverage.out coverage.html
|
|
find . -name "*.test" -type f -delete
|
|
go clean -cache -testcache
|
|
|
|
# Try binary release
|
|
gorelease-dry-run:
|
|
docker run \
|
|
--rm \
|
|
-e CGO_ENABLED=0 \
|
|
-v $(CURDIR):/$(NAME) \
|
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
-w /$(NAME) \
|
|
$(GORELEASER_DOCKER_IMAGE) \
|
|
--clean --verbose --skip=publish,validate --snapshot
|
|
|