Skip to content
This repository was archived by the owner on Apr 3, 2026. It is now read-only.

Commit 98eb2bc

Browse files
author
Loki
committed
docs: update README and AGENTS.md with update, install-daemon, and all v0.4.0 features
1 parent 522ff52 commit 98eb2bc

2 files changed

Lines changed: 155 additions & 39 deletions

File tree

AGENTS.md

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,44 @@ Single-binary Go proxy that translates OpenAI `/v1/embeddings` to Amazon Bedrock
1010
| **Test** | `go test ./... -v -count=1` |
1111
| **Lint** | `golangci-lint run ./...` |
1212
| **Run** | `./embedrock --port 8089 --region us-east-1` |
13+
| **Update** | `./embedrock update` |
14+
| **Install daemon** | `sudo ./embedrock install-daemon` |
1315

1416
## Before You Start
1517

1618
- Read `ARCHITECTURE.md` for the full design and file layout.
17-
- This is a **small codebase** (~6 files). Read it all before making changes.
19+
- This is a **small codebase** (~10 files). Read it all before making changes.
1820
- Go 1.26+ required. Dependencies: `go mod download`.
1921

2022
## File Layout
2123

2224
```
23-
types.go → Embedder interface, OpenAI-compatible request/response types
24-
handler.go → HTTP handler (routing, input parsing, responses)
25-
bedrock.go → BedrockEmbedder (Titan + Cohere model families)
26-
mock_test.go → MockEmbedder for tests
27-
handler_test.go → HTTP handler tests
28-
bedrock_test.go → Model detection tests
29-
cmd/embedrock/ → CLI entry point (main.go)
25+
types.go → Embedder interface, OpenAI-compatible request/response types
26+
handler.go → HTTP handler (routing, input parsing, responses)
27+
bedrock.go → BedrockEmbedder (Titan + Cohere model families)
28+
mock_test.go → MockEmbedder for tests
29+
handler_test.go → HTTP handler tests (20 tests)
30+
bedrock_test.go → Model detection tests
31+
cmd/embedrock/main.go → CLI entry point (flags, subcommands, server startup)
32+
cmd/embedrock/update.go → Self-update command (GitHub releases, checksum verification)
33+
cmd/embedrock/update_test.go → Update tests (mock GitHub API, 6 tests)
34+
cmd/embedrock/daemon.go → Install-daemon command (systemd unit file generation)
35+
cmd/embedrock/daemon_test.go → Daemon tests (unit file generation, root check)
3036
```
3137

3238
## Rules
3339

3440
1. **Always run tests before committing:** `go test ./... -v -count=1`
3541
2. **Always run build to verify:** `go build ./cmd/embedrock/`
3642
3. **TDD preferred:** Write a failing test first, then implement.
37-
4. **No new dependencies** without a strong reason — keep the binary small.
43+
4. **No new dependencies** without a strong reason — keep the binary small (stdlib only in cmd/).
3844
5. **Don't break the OpenAI API contract** — clients expect exact `/v1/embeddings` format.
3945
6. **Single-model design:** One embedrock process = one Bedrock model. Per-request model switching is rejected (HTTP 400).
4046
7. **Context propagation:** All `Embed()` calls take `context.Context`. Always pass request context through.
41-
8. **Error hygiene:** Never leak internal/AWS errors to API clients. Return generic messages; log details server-side.
47+
8. **Error hygiene:** Never leak internal/AWS errors to API clients. Return generic `"embedding failed"` message; log details server-side.
4248
9. **No hardcoded AWS credentials.** Uses instance profile / env vars / shared config.
49+
10. **HTTP timeouts required:** All HTTP clients must have explicit timeouts. Server uses `http.Server` with read/write/idle timeouts.
50+
11. **Test stability:** Tests must NOT modify the real test binary. Use `t.TempDir()` for temp files. Run tests twice to verify stability.
4351

4452
## Architecture Notes
4553

@@ -48,16 +56,34 @@ cmd/embedrock/ → CLI entry point (main.go)
4856
- Handler parses three input formats: typed single, typed batch, raw JSON fallback.
4957
- Token usage is approximated (~4 chars/token) since we don't have a tokenizer.
5058
- Server binds to `127.0.0.1` by default (uses host IAM creds — don't expose).
59+
- `runUpdate` / `runUpdateTo` split allows tests to inject a temp binary path.
60+
- `updateHTTPClient` has 30s timeout — never use `http.DefaultClient` or bare `http.Get`.
61+
62+
## CLI Structure
63+
64+
```
65+
main.go:
66+
1. Parse flags (--port, --host, --region, --model, --version)
67+
2. Handle --version (before subcommands)
68+
3. Handle subcommands: "update", "install-daemon", or unknown → error
69+
4. Start server
70+
```
71+
72+
Subcommands are positional args after flags: `embedrock --port 9090 install-daemon`
5173

5274
## Testing Patterns
5375

5476
- Use `MockEmbedder` from `mock_test.go` — no AWS creds needed for handler tests.
5577
- `httptest.NewRecorder()` + `httptest.NewRequest()` for HTTP tests.
78+
- `httptest.NewServer` for mocking GitHub API in update tests.
79+
- `t.TempDir()` for temp files that auto-clean.
80+
- `runUpdateTo(version, apiBase, execPathOverride)` for update tests — never use `runUpdate` directly in tests (would overwrite the test binary).
5681
- Bedrock integration tests require real AWS credentials and model access.
57-
- Test both happy path AND error paths (invalid input, embedder failures, model mismatches).
82+
- Test both happy path AND error paths (invalid input, embedder failures, model mismatches, checksum mismatches, API errors).
5883

5984
## CI
6085

6186
GitHub Actions (`.github/workflows/`):
62-
- Tests run on push/PR
63-
- Releases build cross-platform binaries via goreleaser
87+
- `ci.yml` — Tests run on push/PR
88+
- `release.yml` — Builds cross-platform binaries on tag push (linux/darwin × arm64/amd64)
89+
- `checksums.txt` included in every release for `embedrock update` verification

README.md

Lines changed: 116 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# embedrock 🪨
22

3-
OpenAI-compatible Bedrock embedding proxy for OpenClaw and Friends. Drop-in replacement for any tool expecting `/v1/embeddings`.
3+
OpenAI-compatible embedding proxy for Amazon Bedrock. Drop-in replacement for any tool expecting `/v1/embeddings`.
44

55
## Why?
66

@@ -20,6 +20,8 @@ Zero API keys needed — uses your AWS credentials (instance profile, env vars,
2020

2121
Model family is auto-detected by ID prefix. Titan and Cohere use different Bedrock request/response formats — embedrock handles this transparently.
2222

23+
> **Single-model design:** Each embedrock process serves one model. If a request specifies a different model, it returns HTTP 400 with a clear error. Run multiple instances for multiple models.
24+
2325
## Install
2426

2527
**From releases:**
@@ -32,6 +34,14 @@ chmod +x /usr/local/bin/embedrock
3234
# Linux amd64
3335
curl -fsSL https://github.com/inceptionstack/embedrock/releases/latest/download/embedrock-linux-amd64 -o /usr/local/bin/embedrock
3436
chmod +x /usr/local/bin/embedrock
37+
38+
# macOS arm64 (Apple Silicon)
39+
curl -fsSL https://github.com/inceptionstack/embedrock/releases/latest/download/embedrock-darwin-arm64 -o /usr/local/bin/embedrock
40+
chmod +x /usr/local/bin/embedrock
41+
42+
# macOS amd64
43+
curl -fsSL https://github.com/inceptionstack/embedrock/releases/latest/download/embedrock-darwin-amd64 -o /usr/local/bin/embedrock
44+
chmod +x /usr/local/bin/embedrock
3545
```
3646

3747
**From source:**
@@ -52,10 +62,75 @@ embedrock --model cohere.embed-v4:0
5262
# Custom config
5363
embedrock --port 9090 --region eu-west-1 --model cohere.embed-english-v3
5464

55-
# Flags
65+
# Show version
66+
embedrock --version
67+
68+
# All flags
5669
embedrock --help
5770
```
5871

72+
### CLI Reference
73+
74+
| Flag | Default | Description |
75+
|------|---------|-------------|
76+
| `--port` | `8089` | Port to listen on |
77+
| `--host` | `127.0.0.1` | Host to bind to |
78+
| `--region` | `us-east-1` | AWS region for Bedrock |
79+
| `--model` | `amazon.titan-embed-text-v2:0` | Bedrock embedding model ID |
80+
| `--version` | | Show version and exit |
81+
82+
### Subcommands
83+
84+
| Command | Description |
85+
|---------|-------------|
86+
| `embedrock update` | Self-update to the latest release from GitHub |
87+
| `sudo embedrock install-daemon` | Install as a systemd service |
88+
89+
## Self-Update
90+
91+
embedrock can update itself in place:
92+
93+
```bash
94+
embedrock update
95+
```
96+
97+
This will:
98+
1. Check GitHub for the latest release
99+
2. Download the correct binary for your OS/architecture
100+
3. Verify the SHA-256 checksum
101+
4. Replace the current binary atomically
102+
5. Restart the systemd service if running as one (requires root)
103+
104+
If running as a non-root user with a systemd service:
105+
```
106+
Updated embedrock from v0.3.0 to v0.4.0
107+
Restart embedrock.service manually (requires sudo)
108+
```
109+
110+
## Install as Daemon
111+
112+
Install embedrock as a systemd service with one command:
113+
114+
```bash
115+
# Install with defaults (port 8089, us-east-1, Titan v2)
116+
sudo embedrock install-daemon
117+
118+
# Install with custom settings
119+
sudo embedrock --port 9090 --region eu-west-1 --model cohere.embed-v4:0 install-daemon
120+
```
121+
122+
This will:
123+
1. Copy the binary to `/usr/local/bin/embedrock`
124+
2. Write a systemd unit file to `/etc/systemd/system/embedrock.service`
125+
3. Run `systemctl daemon-reload`, `enable`, and `start`
126+
127+
The CLI flags you pass (`--port`, `--region`, `--model`) are baked into the service's `ExecStart` command.
128+
129+
To check service status:
130+
```bash
131+
systemctl status embedrock
132+
```
133+
59134
## API
60135

61136
**Health check:**
@@ -81,30 +156,39 @@ curl -X POST http://127.0.0.1:8089/v1/embeddings \
81156
-d '{"input": ["First text", "Second text"], "model": "amazon.titan-embed-text-v2:0"}'
82157
```
83158

84-
## Run as a Service
159+
**Response format:**
85160

86-
```bash
87-
sudo tee /etc/systemd/system/embedrock.service > /dev/null << 'EOF'
88-
[Unit]
89-
Description=embedrock - Bedrock embedding proxy
90-
After=network.target
91-
92-
[Service]
93-
Type=simple
94-
User=ec2-user
95-
ExecStart=/usr/local/bin/embedrock --port 8089 --region us-east-1 --model cohere.embed-v4:0
96-
Restart=always
97-
RestartSec=5
98-
99-
[Install]
100-
WantedBy=multi-user.target
101-
EOF
102-
103-
sudo systemctl daemon-reload
104-
sudo systemctl enable embedrock
105-
sudo systemctl start embedrock
161+
```json
162+
{
163+
"object": "list",
164+
"data": [
165+
{
166+
"object": "embedding",
167+
"index": 0,
168+
"embedding": [0.123, -0.456, ...]
169+
}
170+
],
171+
"model": "amazon.titan-embed-text-v2:0",
172+
"usage": {
173+
"prompt_tokens": 3,
174+
"total_tokens": 3
175+
}
176+
}
177+
```
178+
179+
**Error responses:**
180+
181+
```json
182+
{
183+
"error": {
184+
"message": "model 'cohere.embed-v4:0' is not available; this server is configured with 'amazon.titan-embed-text-v2:0'",
185+
"type": "invalid_request"
186+
}
187+
}
106188
```
107189

190+
Internal errors return a generic `"embedding failed"` message — no AWS internals are leaked to clients.
191+
108192
## OpenClaw Configuration
109193

110194
```json
@@ -130,19 +214,25 @@ sudo systemctl start embedrock
130214
## Development
131215

132216
```bash
217+
# Install dependencies
218+
go mod download
219+
133220
# Run tests
134-
go test ./... -v
221+
go test ./... -v -count=1
135222

136223
# Build
137224
go build ./cmd/embedrock/
138225

139226
# Build with version info
140-
go build -ldflags "-X main.version=v0.2.0" ./cmd/embedrock/
227+
go build -ldflags "-X main.version=v0.4.0 -X main.commit=$(git rev-parse --short HEAD) -X main.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" ./cmd/embedrock/
228+
229+
# Lint (requires golangci-lint)
230+
golangci-lint run ./...
141231
```
142232

143233
## Architecture
144234

145-
See [ARCHITECTURE.md](ARCHITECTURE.md) for design details.
235+
See [ARCHITECTURE.md](ARCHITECTURE.md) for design details and [AGENTS.md](AGENTS.md) for AI coding agent guidelines.
146236

147237
## License
148238

0 commit comments

Comments
 (0)