lynkr 8.0.0 → 9.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.lynkr/telemetry.db +0 -0
- package/.lynkr/telemetry.db-shm +0 -0
- package/.lynkr/telemetry.db-wal +0 -0
- package/README.md +196 -322
- package/lynkr-skill.tar.gz +0 -0
- package/package.json +4 -3
- package/src/api/openai-router.js +64 -13
- package/src/api/providers-handler.js +171 -3
- package/src/api/router.js +9 -2
- package/src/clients/circuit-breaker.js +10 -247
- package/src/clients/codex-process.js +342 -0
- package/src/clients/codex-utils.js +143 -0
- package/src/clients/databricks.js +210 -63
- package/src/clients/resilience.js +540 -0
- package/src/clients/retry.js +22 -167
- package/src/clients/standard-tools.js +23 -0
- package/src/config/index.js +77 -0
- package/src/context/compression.js +42 -9
- package/src/context/distill.js +492 -0
- package/src/orchestrator/index.js +48 -8
- package/src/routing/complexity-analyzer.js +258 -5
- package/src/routing/index.js +12 -2
- package/src/routing/latency-tracker.js +148 -0
- package/src/routing/model-tiers.js +2 -0
- package/src/routing/quality-scorer.js +113 -0
- package/src/routing/telemetry.js +464 -0
- package/src/server.js +13 -12
- package/src/tools/code-graph.js +538 -0
- package/src/tools/code-mode.js +304 -0
- package/src/tools/index.js +4 -0
- package/src/tools/lazy-loader.js +18 -0
- package/src/tools/mcp-remote.js +7 -0
- package/src/tools/smart-selection.js +11 -0
- package/src/tools/tinyfish.js +358 -0
- package/src/tools/truncate.js +1 -0
- package/src/utils/payload.js +206 -0
- package/src/utils/perf-timer.js +80 -0
- package/.github/FUNDING.yml +0 -15
- package/.github/workflows/README.md +0 -215
- package/.github/workflows/ci.yml +0 -69
- package/.github/workflows/index.yml +0 -62
- package/.github/workflows/web-tools-tests.yml +0 -56
- package/CITATIONS.bib +0 -6
- package/DEPLOYMENT.md +0 -1001
- package/LYNKR-TUI-PLAN.md +0 -984
- package/PERFORMANCE-REPORT.md +0 -866
- package/PLAN-per-client-model-routing.md +0 -252
- package/docs/42642f749da6234f41b6b425c3bb07c9.txt +0 -1
- package/docs/BingSiteAuth.xml +0 -4
- package/docs/docs-style.css +0 -478
- package/docs/docs.html +0 -198
- package/docs/google5be250e608e6da39.html +0 -1
- package/docs/index.html +0 -577
- package/docs/index.md +0 -584
- package/docs/robots.txt +0 -4
- package/docs/sitemap.xml +0 -44
- package/docs/style.css +0 -1223
- package/docs/toon-integration-spec.md +0 -130
- package/documentation/README.md +0 -101
- package/documentation/api.md +0 -806
- package/documentation/claude-code-cli.md +0 -679
- package/documentation/codex-cli.md +0 -397
- package/documentation/contributing.md +0 -571
- package/documentation/cursor-integration.md +0 -734
- package/documentation/docker.md +0 -874
- package/documentation/embeddings.md +0 -762
- package/documentation/faq.md +0 -713
- package/documentation/features.md +0 -403
- package/documentation/headroom.md +0 -519
- package/documentation/installation.md +0 -758
- package/documentation/memory-system.md +0 -476
- package/documentation/production.md +0 -636
- package/documentation/providers.md +0 -1009
- package/documentation/routing.md +0 -476
- package/documentation/testing.md +0 -629
- package/documentation/token-optimization.md +0 -325
- package/documentation/tools.md +0 -697
- package/documentation/troubleshooting.md +0 -969
- package/final-test.js +0 -33
- package/headroom-sidecar/config.py +0 -93
- package/headroom-sidecar/requirements.txt +0 -14
- package/headroom-sidecar/server.py +0 -451
- package/monitor-agents.sh +0 -31
- package/scripts/audit-log-reader.js +0 -399
- package/scripts/compact-dictionary.js +0 -204
- package/scripts/test-deduplication.js +0 -448
- package/src/db/database.sqlite +0 -0
- package/te +0 -11622
- package/test/README.md +0 -212
- package/test/azure-openai-config.test.js +0 -213
- package/test/azure-openai-error-resilience.test.js +0 -238
- package/test/azure-openai-format-conversion.test.js +0 -354
- package/test/azure-openai-integration.test.js +0 -287
- package/test/azure-openai-routing.test.js +0 -175
- package/test/azure-openai-streaming.test.js +0 -171
- package/test/bedrock-integration.test.js +0 -457
- package/test/comprehensive-test-suite.js +0 -928
- package/test/config-validation.test.js +0 -207
- package/test/cursor-integration.test.js +0 -484
- package/test/format-conversion.test.js +0 -578
- package/test/hybrid-routing-integration.test.js +0 -269
- package/test/hybrid-routing-performance.test.js +0 -428
- package/test/llamacpp-integration.test.js +0 -882
- package/test/lmstudio-integration.test.js +0 -347
- package/test/memory/extractor.test.js +0 -398
- package/test/memory/retriever.test.js +0 -613
- package/test/memory/retriever.test.js.bak +0 -585
- package/test/memory/search.test.js +0 -537
- package/test/memory/search.test.js.bak +0 -389
- package/test/memory/store.test.js +0 -344
- package/test/memory/store.test.js.bak +0 -312
- package/test/memory/surprise.test.js +0 -300
- package/test/memory-performance.test.js +0 -472
- package/test/openai-integration.test.js +0 -683
- package/test/openrouter-error-resilience.test.js +0 -418
- package/test/passthrough-mode.test.js +0 -385
- package/test/performance-benchmark.js +0 -351
- package/test/performance-tests.js +0 -528
- package/test/routing.test.js +0 -225
- package/test/toon-compression.test.js +0 -131
- package/test/web-tools.test.js +0 -329
- package/test-agents-simple.js +0 -43
- package/test-cli-connection.sh +0 -33
- package/test-learning-unit.js +0 -126
- package/test-learning.js +0 -112
- package/test-parallel-agents.sh +0 -124
- package/test-parallel-direct.js +0 -155
- package/test-subagents.sh +0 -117
|
@@ -1,636 +0,0 @@
|
|
|
1
|
-
# Production Hardening Guide
|
|
2
|
-
|
|
3
|
-
Complete guide to deploying Lynkr in production with 14 hardening features for reliability, observability, and security.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
Lynkr includes 14 production-ready features:
|
|
10
|
-
- **Reliability:** Circuit breakers, retries, load shedding, graceful shutdown
|
|
11
|
-
- **Observability:** Prometheus metrics, structured logging, health checks
|
|
12
|
-
- **Security:** Input validation, policy enforcement, sandboxing
|
|
13
|
-
- **Performance:** Minimal overhead (~7μs), 140K req/sec throughput
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## Reliability Features
|
|
18
|
-
|
|
19
|
-
### 1. Circuit Breaker Pattern
|
|
20
|
-
|
|
21
|
-
Protects against cascading failures to external services.
|
|
22
|
-
|
|
23
|
-
**States:**
|
|
24
|
-
- `CLOSED` - Normal operation
|
|
25
|
-
- `OPEN` - Failing fast (provider down)
|
|
26
|
-
- `HALF_OPEN` - Testing recovery
|
|
27
|
-
|
|
28
|
-
**Configuration:**
|
|
29
|
-
```bash
|
|
30
|
-
# Failures before opening circuit
|
|
31
|
-
CIRCUIT_BREAKER_FAILURE_THRESHOLD=5 # default: 5
|
|
32
|
-
|
|
33
|
-
# Successes needed to close from half-open
|
|
34
|
-
CIRCUIT_BREAKER_SUCCESS_THRESHOLD=2 # default: 2
|
|
35
|
-
|
|
36
|
-
# Time before attempting recovery (ms)
|
|
37
|
-
CIRCUIT_BREAKER_TIMEOUT=60000 # default: 60000 (1 min)
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
**How it works:**
|
|
41
|
-
1. 5 failures → Circuit OPEN
|
|
42
|
-
2. Wait 60 seconds
|
|
43
|
-
3. Try 1 request → Circuit HALF_OPEN
|
|
44
|
-
4. 2 successes → Circuit CLOSED
|
|
45
|
-
|
|
46
|
-
### 2. Exponential Backoff with Jitter
|
|
47
|
-
|
|
48
|
-
Automatic retries for transient failures.
|
|
49
|
-
|
|
50
|
-
**Configuration:**
|
|
51
|
-
```bash
|
|
52
|
-
# Max retry attempts
|
|
53
|
-
API_RETRY_MAX_RETRIES=3 # default: 3
|
|
54
|
-
|
|
55
|
-
# Initial retry delay (ms)
|
|
56
|
-
API_RETRY_INITIAL_DELAY=1000 # default: 1000
|
|
57
|
-
|
|
58
|
-
# Maximum retry delay (ms)
|
|
59
|
-
API_RETRY_MAX_DELAY=30000 # default: 30000
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
**Retry schedule:**
|
|
63
|
-
- Attempt 1: Immediate
|
|
64
|
-
- Attempt 2: 1s + jitter (±500ms)
|
|
65
|
-
- Attempt 3: 2s + jitter (±1s)
|
|
66
|
-
- Attempt 4: 4s + jitter (±2s)
|
|
67
|
-
|
|
68
|
-
**Retryable errors:**
|
|
69
|
-
- 5xx status codes
|
|
70
|
-
- Network timeouts
|
|
71
|
-
- Connection errors
|
|
72
|
-
|
|
73
|
-
**Non-retryable errors:**
|
|
74
|
-
- 4xx status codes
|
|
75
|
-
- Authentication errors
|
|
76
|
-
- Validation errors
|
|
77
|
-
|
|
78
|
-
### 3. Load Shedding
|
|
79
|
-
|
|
80
|
-
Proactive request rejection when system is overloaded.
|
|
81
|
-
|
|
82
|
-
**Configuration:**
|
|
83
|
-
```bash
|
|
84
|
-
# Memory usage threshold (0-1)
|
|
85
|
-
LOAD_SHEDDING_MEMORY_THRESHOLD=0.85 # default: 0.85 (85%)
|
|
86
|
-
|
|
87
|
-
# Heap usage threshold (0-1)
|
|
88
|
-
LOAD_SHEDDING_HEAP_THRESHOLD=0.90 # default: 0.90 (90%)
|
|
89
|
-
|
|
90
|
-
# Max concurrent requests
|
|
91
|
-
LOAD_SHEDDING_ACTIVE_REQUESTS_THRESHOLD=1000 # default: 1000
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Behavior:**
|
|
95
|
-
- Returns HTTP 503 during overload
|
|
96
|
-
- Includes `Retry-After` header
|
|
97
|
-
- Cached state (1s) for performance
|
|
98
|
-
|
|
99
|
-
**Monitoring:**
|
|
100
|
-
```bash
|
|
101
|
-
curl http://localhost:8081/metrics | grep lynkr_load_shedding
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### 4. Graceful Shutdown
|
|
105
|
-
|
|
106
|
-
Zero-downtime deployments.
|
|
107
|
-
|
|
108
|
-
**Configuration:**
|
|
109
|
-
```bash
|
|
110
|
-
# Shutdown timeout (ms)
|
|
111
|
-
GRACEFUL_SHUTDOWN_TIMEOUT=30000 # default: 30000 (30s)
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
**Sequence:**
|
|
115
|
-
1. Receive SIGTERM/SIGINT
|
|
116
|
-
2. Stop accepting new requests
|
|
117
|
-
3. Complete in-flight requests (max 30s)
|
|
118
|
-
4. Close database connections
|
|
119
|
-
5. Exit
|
|
120
|
-
|
|
121
|
-
**Kubernetes:**
|
|
122
|
-
```yaml
|
|
123
|
-
spec:
|
|
124
|
-
containers:
|
|
125
|
-
- name: lynkr
|
|
126
|
-
lifecycle:
|
|
127
|
-
preStop:
|
|
128
|
-
exec:
|
|
129
|
-
command: ["/bin/sh", "-c", "sleep 5"]
|
|
130
|
-
terminationGracePeriodSeconds: 35
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## Observability
|
|
136
|
-
|
|
137
|
-
### 5. Prometheus Metrics
|
|
138
|
-
|
|
139
|
-
Comprehensive metrics collection.
|
|
140
|
-
|
|
141
|
-
**Endpoint:**
|
|
142
|
-
```bash
|
|
143
|
-
curl http://localhost:8081/metrics
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
**Request Metrics:**
|
|
147
|
-
```
|
|
148
|
-
# Request rate
|
|
149
|
-
lynkr_requests_total{provider="databricks",status="200"} 1234
|
|
150
|
-
|
|
151
|
-
# Latency histogram
|
|
152
|
-
lynkr_request_duration_seconds_bucket{provider="databricks",le="0.5"} 980
|
|
153
|
-
lynkr_request_duration_seconds_bucket{provider="databricks",le="1"} 1200
|
|
154
|
-
lynkr_request_duration_seconds_sum 1234.5
|
|
155
|
-
lynkr_request_duration_seconds_count 1234
|
|
156
|
-
|
|
157
|
-
# Error rate
|
|
158
|
-
lynkr_errors_total{provider="databricks",type="timeout"} 12
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
**Token Metrics:**
|
|
162
|
-
```
|
|
163
|
-
# Token usage
|
|
164
|
-
lynkr_tokens_input_total{provider="databricks"} 5000000
|
|
165
|
-
lynkr_tokens_output_total{provider="databricks"} 500000
|
|
166
|
-
lynkr_tokens_cached_total 2000000
|
|
167
|
-
|
|
168
|
-
# Cache hits
|
|
169
|
-
lynkr_cache_hits_total 850
|
|
170
|
-
lynkr_cache_misses_total 150
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
**System Metrics:**
|
|
174
|
-
```
|
|
175
|
-
# Memory usage
|
|
176
|
-
process_resident_memory_bytes 104857600
|
|
177
|
-
nodejs_heap_size_used_bytes 52428800
|
|
178
|
-
|
|
179
|
-
# Circuit breaker state
|
|
180
|
-
lynkr_circuit_breaker_state{provider="databricks",state="closed"} 1
|
|
181
|
-
|
|
182
|
-
# Active requests
|
|
183
|
-
lynkr_active_requests 42
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
**Configuration:**
|
|
187
|
-
```bash
|
|
188
|
-
METRICS_ENABLED=true # default: true
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### 6. Structured Logging
|
|
192
|
-
|
|
193
|
-
JSON logs with request ID correlation via [Pino](https://github.com/pinojs/pino).
|
|
194
|
-
|
|
195
|
-
**Log Level Philosophy:**
|
|
196
|
-
- **`info`** — Meaningful milestones: request received (minimal), request completed (duration + tokens), errors, retries, fallbacks
|
|
197
|
-
- **`debug`** — Operational details: request body previews, tool injection, streaming chunks, intermediate conversions, tool mapping
|
|
198
|
-
|
|
199
|
-
**Console Configuration:**
|
|
200
|
-
```bash
|
|
201
|
-
LOG_LEVEL=info # options: error, warn, info, debug (default: info)
|
|
202
|
-
REQUEST_LOGGING_ENABLED=true # default: true
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
In development mode (`NODE_ENV=development`), logs are pretty-printed via `pino-pretty`.
|
|
206
|
-
|
|
207
|
-
**File Logging (optional):**
|
|
208
|
-
|
|
209
|
-
Persistent log files with automatic daily rotation via [pino-roll](https://github.com/pinojs/pino-roll). Enable by setting `LOG_FILE_ENABLED=true`.
|
|
210
|
-
|
|
211
|
-
```bash
|
|
212
|
-
LOG_FILE_ENABLED=true # default: false
|
|
213
|
-
LOG_FILE_PATH=./logs/lynkr.log # default: <cwd>/logs/lynkr.log
|
|
214
|
-
LOG_FILE_LEVEL=debug # default: debug (captures all levels)
|
|
215
|
-
LOG_FILE_FREQUENCY=daily # options: daily, hourly, custom (default: daily)
|
|
216
|
-
LOG_FILE_MAX_FILES=14 # rotated files to keep (default: 14)
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
Rotated files are named with timestamps (e.g., `lynkr.log.2025-07-12`). The log directory is created automatically.
|
|
220
|
-
|
|
221
|
-
**Log format (JSON):**
|
|
222
|
-
```json
|
|
223
|
-
{
|
|
224
|
-
"level": "info",
|
|
225
|
-
"time": 1705123456789,
|
|
226
|
-
"msg": "Request processed",
|
|
227
|
-
"requestId": "req_abc123",
|
|
228
|
-
"provider": "databricks",
|
|
229
|
-
"statusCode": 200,
|
|
230
|
-
"duration": 1250,
|
|
231
|
-
"tokens": {
|
|
232
|
-
"input": 1250,
|
|
233
|
-
"output": 234,
|
|
234
|
-
"cached": 750
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
**Querying log files:**
|
|
240
|
-
```bash
|
|
241
|
-
# Tail live logs
|
|
242
|
-
tail -f ./logs/lynkr.log | npx pino-pretty
|
|
243
|
-
|
|
244
|
-
# Find errors in the last 24 hours
|
|
245
|
-
cat ./logs/lynkr.log | jq 'select(.level >= 50)'
|
|
246
|
-
|
|
247
|
-
# Filter by provider
|
|
248
|
-
cat ./logs/lynkr.log | jq 'select(.provider == "databricks")'
|
|
249
|
-
|
|
250
|
-
# Search for slow requests (>2s)
|
|
251
|
-
cat ./logs/lynkr.log | jq 'select(.duration > 2000)'
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
**Log aggregation:**
|
|
255
|
-
- **Stdout** — Captured by Docker/K8s log drivers
|
|
256
|
-
- **File rotation** — For standalone deployments or local debugging
|
|
257
|
-
- **External** — Forward JSON logs to Elasticsearch, Splunk, Grafana Loki, etc.
|
|
258
|
-
|
|
259
|
-
### 7. Health Checks
|
|
260
|
-
|
|
261
|
-
Kubernetes-ready health endpoints.
|
|
262
|
-
|
|
263
|
-
**Liveness Probe:**
|
|
264
|
-
```bash
|
|
265
|
-
curl http://localhost:8081/health/live
|
|
266
|
-
|
|
267
|
-
# Returns:
|
|
268
|
-
{
|
|
269
|
-
"status": "ok",
|
|
270
|
-
"provider": "databricks",
|
|
271
|
-
"timestamp": "2026-01-12T00:00:00.000Z"
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
**Readiness Probe:**
|
|
276
|
-
```bash
|
|
277
|
-
curl http://localhost:8081/health/ready
|
|
278
|
-
|
|
279
|
-
# Returns:
|
|
280
|
-
{
|
|
281
|
-
"status": "ready",
|
|
282
|
-
"checks": {
|
|
283
|
-
"database": "ok",
|
|
284
|
-
"provider": "ok"
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
**Deep Health Check:**
|
|
290
|
-
```bash
|
|
291
|
-
curl "http://localhost:8081/health/ready?deep=true"
|
|
292
|
-
|
|
293
|
-
# Returns:
|
|
294
|
-
{
|
|
295
|
-
"status": "ready",
|
|
296
|
-
"checks": {
|
|
297
|
-
"database": "ok",
|
|
298
|
-
"provider": "ok",
|
|
299
|
-
"memory": {"used": "50%", "status": "ok"},
|
|
300
|
-
"circuit_breaker": {"state": "closed", "status": "ok"}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
**Kubernetes:**
|
|
306
|
-
```yaml
|
|
307
|
-
livenessProbe:
|
|
308
|
-
httpGet:
|
|
309
|
-
path: /health/live
|
|
310
|
-
port: 8081
|
|
311
|
-
initialDelaySeconds: 10
|
|
312
|
-
periodSeconds: 10
|
|
313
|
-
|
|
314
|
-
readinessProbe:
|
|
315
|
-
httpGet:
|
|
316
|
-
path: /health/ready
|
|
317
|
-
port: 8081
|
|
318
|
-
initialDelaySeconds: 5
|
|
319
|
-
periodSeconds: 5
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
**Configuration:**
|
|
323
|
-
```bash
|
|
324
|
-
HEALTH_CHECK_ENABLED=true # default: true
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
---
|
|
328
|
-
|
|
329
|
-
## Security
|
|
330
|
-
|
|
331
|
-
### 8. Input Validation
|
|
332
|
-
|
|
333
|
-
Zero-dependency schema validation.
|
|
334
|
-
|
|
335
|
-
**Validates:**
|
|
336
|
-
- Request body structure
|
|
337
|
-
- Required fields
|
|
338
|
-
- Field types
|
|
339
|
-
- Value constraints
|
|
340
|
-
|
|
341
|
-
**Example:**
|
|
342
|
-
```javascript
|
|
343
|
-
// Invalid request
|
|
344
|
-
{
|
|
345
|
-
"model": 123, // Should be string
|
|
346
|
-
"max_tokens": -1 // Should be positive
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Returns 400 Bad Request
|
|
350
|
-
{
|
|
351
|
-
"error": "Invalid request",
|
|
352
|
-
"details": [
|
|
353
|
-
"model must be string",
|
|
354
|
-
"max_tokens must be positive"
|
|
355
|
-
]
|
|
356
|
-
}
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
### 9. Policy Enforcement
|
|
360
|
-
|
|
361
|
-
Environment-driven guardrails.
|
|
362
|
-
|
|
363
|
-
**Git Policies:**
|
|
364
|
-
```bash
|
|
365
|
-
# Allow git push (default: disabled)
|
|
366
|
-
POLICY_GIT_ALLOW_PUSH=false
|
|
367
|
-
|
|
368
|
-
# Require tests before commit (default: disabled)
|
|
369
|
-
POLICY_GIT_REQUIRE_TESTS=false
|
|
370
|
-
|
|
371
|
-
# Custom test command
|
|
372
|
-
POLICY_GIT_TEST_COMMAND="npm test"
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
**Web Fetch Policies:**
|
|
376
|
-
```bash
|
|
377
|
-
# Allowed hosts for web_fetch tool
|
|
378
|
-
WEB_SEARCH_ALLOWED_HOSTS=github.com,stackoverflow.com
|
|
379
|
-
|
|
380
|
-
# Web search endpoint
|
|
381
|
-
WEB_SEARCH_ENDPOINT=http://localhost:8888/search
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
**Workspace Policies:**
|
|
385
|
-
```bash
|
|
386
|
-
# Workspace root directory
|
|
387
|
-
WORKSPACE_ROOT=/path/to/projects
|
|
388
|
-
|
|
389
|
-
# Max agent loop iterations
|
|
390
|
-
POLICY_MAX_STEPS=8
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
### 10. Sandboxing
|
|
394
|
-
|
|
395
|
-
Optional Docker isolation for MCP tools.
|
|
396
|
-
|
|
397
|
-
**Configuration:**
|
|
398
|
-
```bash
|
|
399
|
-
# Enable MCP sandbox
|
|
400
|
-
MCP_SANDBOX_ENABLED=true # default: true
|
|
401
|
-
|
|
402
|
-
# Docker image for sandbox
|
|
403
|
-
MCP_SANDBOX_IMAGE=ubuntu:22.04
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
**How it works:**
|
|
407
|
-
1. MCP tool invoked
|
|
408
|
-
2. Launch Docker container
|
|
409
|
-
3. Execute tool in container
|
|
410
|
-
4. Return result
|
|
411
|
-
5. Destroy container
|
|
412
|
-
|
|
413
|
-
**Benefits:**
|
|
414
|
-
- Isolated execution
|
|
415
|
-
- Resource limits
|
|
416
|
-
- No host access
|
|
417
|
-
- Safe for untrusted tools
|
|
418
|
-
|
|
419
|
-
---
|
|
420
|
-
|
|
421
|
-
## Deployment
|
|
422
|
-
|
|
423
|
-
### Kubernetes
|
|
424
|
-
|
|
425
|
-
**deployment.yaml:**
|
|
426
|
-
```yaml
|
|
427
|
-
apiVersion: apps/v1
|
|
428
|
-
kind: Deployment
|
|
429
|
-
metadata:
|
|
430
|
-
name: lynkr
|
|
431
|
-
spec:
|
|
432
|
-
replicas: 3
|
|
433
|
-
selector:
|
|
434
|
-
matchLabels:
|
|
435
|
-
app: lynkr
|
|
436
|
-
template:
|
|
437
|
-
metadata:
|
|
438
|
-
labels:
|
|
439
|
-
app: lynkr
|
|
440
|
-
spec:
|
|
441
|
-
containers:
|
|
442
|
-
- name: lynkr
|
|
443
|
-
image: lynkr:latest
|
|
444
|
-
ports:
|
|
445
|
-
- containerPort: 8081
|
|
446
|
-
env:
|
|
447
|
-
- name: MODEL_PROVIDER
|
|
448
|
-
value: "databricks"
|
|
449
|
-
- name: DATABRICKS_API_KEY
|
|
450
|
-
valueFrom:
|
|
451
|
-
secretKeyRef:
|
|
452
|
-
name: lynkr-secrets
|
|
453
|
-
key: databricks-api-key
|
|
454
|
-
resources:
|
|
455
|
-
requests:
|
|
456
|
-
cpu: "500m"
|
|
457
|
-
memory: "512Mi"
|
|
458
|
-
limits:
|
|
459
|
-
cpu: "2"
|
|
460
|
-
memory: "2Gi"
|
|
461
|
-
livenessProbe:
|
|
462
|
-
httpGet:
|
|
463
|
-
path: /health/live
|
|
464
|
-
port: 8081
|
|
465
|
-
initialDelaySeconds: 10
|
|
466
|
-
periodSeconds: 10
|
|
467
|
-
readinessProbe:
|
|
468
|
-
httpGet:
|
|
469
|
-
path: /health/ready
|
|
470
|
-
port: 8081
|
|
471
|
-
initialDelaySeconds: 5
|
|
472
|
-
periodSeconds: 5
|
|
473
|
-
---
|
|
474
|
-
apiVersion: v1
|
|
475
|
-
kind: Service
|
|
476
|
-
metadata:
|
|
477
|
-
name: lynkr
|
|
478
|
-
spec:
|
|
479
|
-
selector:
|
|
480
|
-
app: lynkr
|
|
481
|
-
ports:
|
|
482
|
-
- port: 80
|
|
483
|
-
targetPort: 8081
|
|
484
|
-
type: LoadBalancer
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
### Docker Compose
|
|
488
|
-
|
|
489
|
-
See [Docker Deployment Guide](docker.md) for complete setup.
|
|
490
|
-
|
|
491
|
-
### Systemd
|
|
492
|
-
|
|
493
|
-
**lynkr.service:**
|
|
494
|
-
```ini
|
|
495
|
-
[Unit]
|
|
496
|
-
Description=Lynkr Proxy
|
|
497
|
-
After=network.target
|
|
498
|
-
|
|
499
|
-
[Service]
|
|
500
|
-
Type=simple
|
|
501
|
-
User=lynkr
|
|
502
|
-
WorkingDirectory=/opt/lynkr
|
|
503
|
-
EnvironmentFile=/etc/lynkr/lynkr.env
|
|
504
|
-
ExecStart=/usr/bin/node /opt/lynkr/index.js
|
|
505
|
-
Restart=always
|
|
506
|
-
RestartSec=10
|
|
507
|
-
|
|
508
|
-
[Install]
|
|
509
|
-
WantedBy=multi-user.target
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
```bash
|
|
513
|
-
sudo systemctl enable lynkr
|
|
514
|
-
sudo systemctl start lynkr
|
|
515
|
-
sudo journalctl -u lynkr -f
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
---
|
|
519
|
-
|
|
520
|
-
## Monitoring
|
|
521
|
-
|
|
522
|
-
### Prometheus
|
|
523
|
-
|
|
524
|
-
**prometheus.yml:**
|
|
525
|
-
```yaml
|
|
526
|
-
scrape_configs:
|
|
527
|
-
- job_name: 'lynkr'
|
|
528
|
-
static_configs:
|
|
529
|
-
- targets: ['localhost:8081']
|
|
530
|
-
metrics_path: '/metrics'
|
|
531
|
-
scrape_interval: 15s
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
### Grafana Dashboard
|
|
535
|
-
|
|
536
|
-
**Key metrics to monitor:**
|
|
537
|
-
- Request rate (req/sec)
|
|
538
|
-
- Latency percentiles (p50, p95, p99)
|
|
539
|
-
- Error rate
|
|
540
|
-
- Token usage
|
|
541
|
-
- Cache hit rate
|
|
542
|
-
- Circuit breaker state
|
|
543
|
-
- Memory usage
|
|
544
|
-
|
|
545
|
-
**Sample queries:**
|
|
546
|
-
```promql
|
|
547
|
-
# Request rate
|
|
548
|
-
rate(lynkr_requests_total[5m])
|
|
549
|
-
|
|
550
|
-
# 95th percentile latency
|
|
551
|
-
histogram_quantile(0.95, rate(lynkr_request_duration_seconds_bucket[5m]))
|
|
552
|
-
|
|
553
|
-
# Error rate
|
|
554
|
-
rate(lynkr_errors_total[5m]) / rate(lynkr_requests_total[5m])
|
|
555
|
-
|
|
556
|
-
# Cache hit rate
|
|
557
|
-
lynkr_cache_hits_total / (lynkr_cache_hits_total + lynkr_cache_misses_total)
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
---
|
|
561
|
-
|
|
562
|
-
## Best Practices
|
|
563
|
-
|
|
564
|
-
### 1. Use Reverse Proxy
|
|
565
|
-
|
|
566
|
-
```nginx
|
|
567
|
-
server {
|
|
568
|
-
listen 443 ssl;
|
|
569
|
-
server_name lynkr.example.com;
|
|
570
|
-
|
|
571
|
-
ssl_certificate /path/to/cert.pem;
|
|
572
|
-
ssl_certificate_key /path/to/key.pem;
|
|
573
|
-
|
|
574
|
-
location / {
|
|
575
|
-
proxy_pass http://localhost:8081;
|
|
576
|
-
proxy_set_header Host $host;
|
|
577
|
-
proxy_set_header X-Real-IP $remote_addr;
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
### 2. Set Resource Limits
|
|
583
|
-
|
|
584
|
-
```yaml
|
|
585
|
-
resources:
|
|
586
|
-
requests:
|
|
587
|
-
cpu: "500m"
|
|
588
|
-
memory: "512Mi"
|
|
589
|
-
limits:
|
|
590
|
-
cpu: "2"
|
|
591
|
-
memory: "2Gi"
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
### 3. Enable All Hardening Features
|
|
595
|
-
|
|
596
|
-
```bash
|
|
597
|
-
CIRCUIT_BREAKER_FAILURE_THRESHOLD=5
|
|
598
|
-
LOAD_SHEDDING_MEMORY_THRESHOLD=0.85
|
|
599
|
-
GRACEFUL_SHUTDOWN_TIMEOUT=30000
|
|
600
|
-
METRICS_ENABLED=true
|
|
601
|
-
HEALTH_CHECK_ENABLED=true
|
|
602
|
-
```
|
|
603
|
-
|
|
604
|
-
### 4. Monitor Metrics
|
|
605
|
-
|
|
606
|
-
- Set up Prometheus + Grafana
|
|
607
|
-
- Alert on high error rates
|
|
608
|
-
- Alert on high latency
|
|
609
|
-
- Monitor token usage
|
|
610
|
-
|
|
611
|
-
### 5. Rotate Secrets
|
|
612
|
-
|
|
613
|
-
```bash
|
|
614
|
-
# Rotate API keys regularly
|
|
615
|
-
kubectl create secret generic lynkr-secrets \
|
|
616
|
-
--from-literal=databricks-api-key=new-key \
|
|
617
|
-
--dry-run=client -o yaml | kubectl apply -f -
|
|
618
|
-
|
|
619
|
-
# Rollout restart
|
|
620
|
-
kubectl rollout restart deployment/lynkr
|
|
621
|
-
```
|
|
622
|
-
|
|
623
|
-
---
|
|
624
|
-
|
|
625
|
-
## Next Steps
|
|
626
|
-
|
|
627
|
-
- **[Docker Deployment](docker.md)** - Docker setup
|
|
628
|
-
- **[API Reference](api.md)** - API endpoints
|
|
629
|
-
- **[Troubleshooting](troubleshooting.md)** - Common issues
|
|
630
|
-
|
|
631
|
-
---
|
|
632
|
-
|
|
633
|
-
## Getting Help
|
|
634
|
-
|
|
635
|
-
- **[GitHub Discussions](https://github.com/vishalveerareddy123/Lynkr/discussions)** - Ask questions
|
|
636
|
-
- **[GitHub Issues](https://github.com/vishalveerareddy123/Lynkr/issues)** - Report issues
|