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.
Files changed (128) hide show
  1. package/.lynkr/telemetry.db +0 -0
  2. package/.lynkr/telemetry.db-shm +0 -0
  3. package/.lynkr/telemetry.db-wal +0 -0
  4. package/README.md +196 -322
  5. package/lynkr-skill.tar.gz +0 -0
  6. package/package.json +4 -3
  7. package/src/api/openai-router.js +64 -13
  8. package/src/api/providers-handler.js +171 -3
  9. package/src/api/router.js +9 -2
  10. package/src/clients/circuit-breaker.js +10 -247
  11. package/src/clients/codex-process.js +342 -0
  12. package/src/clients/codex-utils.js +143 -0
  13. package/src/clients/databricks.js +210 -63
  14. package/src/clients/resilience.js +540 -0
  15. package/src/clients/retry.js +22 -167
  16. package/src/clients/standard-tools.js +23 -0
  17. package/src/config/index.js +77 -0
  18. package/src/context/compression.js +42 -9
  19. package/src/context/distill.js +492 -0
  20. package/src/orchestrator/index.js +48 -8
  21. package/src/routing/complexity-analyzer.js +258 -5
  22. package/src/routing/index.js +12 -2
  23. package/src/routing/latency-tracker.js +148 -0
  24. package/src/routing/model-tiers.js +2 -0
  25. package/src/routing/quality-scorer.js +113 -0
  26. package/src/routing/telemetry.js +464 -0
  27. package/src/server.js +13 -12
  28. package/src/tools/code-graph.js +538 -0
  29. package/src/tools/code-mode.js +304 -0
  30. package/src/tools/index.js +4 -0
  31. package/src/tools/lazy-loader.js +18 -0
  32. package/src/tools/mcp-remote.js +7 -0
  33. package/src/tools/smart-selection.js +11 -0
  34. package/src/tools/tinyfish.js +358 -0
  35. package/src/tools/truncate.js +1 -0
  36. package/src/utils/payload.js +206 -0
  37. package/src/utils/perf-timer.js +80 -0
  38. package/.github/FUNDING.yml +0 -15
  39. package/.github/workflows/README.md +0 -215
  40. package/.github/workflows/ci.yml +0 -69
  41. package/.github/workflows/index.yml +0 -62
  42. package/.github/workflows/web-tools-tests.yml +0 -56
  43. package/CITATIONS.bib +0 -6
  44. package/DEPLOYMENT.md +0 -1001
  45. package/LYNKR-TUI-PLAN.md +0 -984
  46. package/PERFORMANCE-REPORT.md +0 -866
  47. package/PLAN-per-client-model-routing.md +0 -252
  48. package/docs/42642f749da6234f41b6b425c3bb07c9.txt +0 -1
  49. package/docs/BingSiteAuth.xml +0 -4
  50. package/docs/docs-style.css +0 -478
  51. package/docs/docs.html +0 -198
  52. package/docs/google5be250e608e6da39.html +0 -1
  53. package/docs/index.html +0 -577
  54. package/docs/index.md +0 -584
  55. package/docs/robots.txt +0 -4
  56. package/docs/sitemap.xml +0 -44
  57. package/docs/style.css +0 -1223
  58. package/docs/toon-integration-spec.md +0 -130
  59. package/documentation/README.md +0 -101
  60. package/documentation/api.md +0 -806
  61. package/documentation/claude-code-cli.md +0 -679
  62. package/documentation/codex-cli.md +0 -397
  63. package/documentation/contributing.md +0 -571
  64. package/documentation/cursor-integration.md +0 -734
  65. package/documentation/docker.md +0 -874
  66. package/documentation/embeddings.md +0 -762
  67. package/documentation/faq.md +0 -713
  68. package/documentation/features.md +0 -403
  69. package/documentation/headroom.md +0 -519
  70. package/documentation/installation.md +0 -758
  71. package/documentation/memory-system.md +0 -476
  72. package/documentation/production.md +0 -636
  73. package/documentation/providers.md +0 -1009
  74. package/documentation/routing.md +0 -476
  75. package/documentation/testing.md +0 -629
  76. package/documentation/token-optimization.md +0 -325
  77. package/documentation/tools.md +0 -697
  78. package/documentation/troubleshooting.md +0 -969
  79. package/final-test.js +0 -33
  80. package/headroom-sidecar/config.py +0 -93
  81. package/headroom-sidecar/requirements.txt +0 -14
  82. package/headroom-sidecar/server.py +0 -451
  83. package/monitor-agents.sh +0 -31
  84. package/scripts/audit-log-reader.js +0 -399
  85. package/scripts/compact-dictionary.js +0 -204
  86. package/scripts/test-deduplication.js +0 -448
  87. package/src/db/database.sqlite +0 -0
  88. package/te +0 -11622
  89. package/test/README.md +0 -212
  90. package/test/azure-openai-config.test.js +0 -213
  91. package/test/azure-openai-error-resilience.test.js +0 -238
  92. package/test/azure-openai-format-conversion.test.js +0 -354
  93. package/test/azure-openai-integration.test.js +0 -287
  94. package/test/azure-openai-routing.test.js +0 -175
  95. package/test/azure-openai-streaming.test.js +0 -171
  96. package/test/bedrock-integration.test.js +0 -457
  97. package/test/comprehensive-test-suite.js +0 -928
  98. package/test/config-validation.test.js +0 -207
  99. package/test/cursor-integration.test.js +0 -484
  100. package/test/format-conversion.test.js +0 -578
  101. package/test/hybrid-routing-integration.test.js +0 -269
  102. package/test/hybrid-routing-performance.test.js +0 -428
  103. package/test/llamacpp-integration.test.js +0 -882
  104. package/test/lmstudio-integration.test.js +0 -347
  105. package/test/memory/extractor.test.js +0 -398
  106. package/test/memory/retriever.test.js +0 -613
  107. package/test/memory/retriever.test.js.bak +0 -585
  108. package/test/memory/search.test.js +0 -537
  109. package/test/memory/search.test.js.bak +0 -389
  110. package/test/memory/store.test.js +0 -344
  111. package/test/memory/store.test.js.bak +0 -312
  112. package/test/memory/surprise.test.js +0 -300
  113. package/test/memory-performance.test.js +0 -472
  114. package/test/openai-integration.test.js +0 -683
  115. package/test/openrouter-error-resilience.test.js +0 -418
  116. package/test/passthrough-mode.test.js +0 -385
  117. package/test/performance-benchmark.js +0 -351
  118. package/test/performance-tests.js +0 -528
  119. package/test/routing.test.js +0 -225
  120. package/test/toon-compression.test.js +0 -131
  121. package/test/web-tools.test.js +0 -329
  122. package/test-agents-simple.js +0 -43
  123. package/test-cli-connection.sh +0 -33
  124. package/test-learning-unit.js +0 -126
  125. package/test-learning.js +0 -112
  126. package/test-parallel-agents.sh +0 -124
  127. package/test-parallel-direct.js +0 -155
  128. package/test-subagents.sh +0 -117
@@ -1,806 +0,0 @@
1
- # API Reference
2
-
3
- Complete API reference for all Lynkr endpoints, including Claude Code CLI (Anthropic format) and Cursor IDE (OpenAI format) compatibility.
4
-
5
- ---
6
-
7
- ## Base URL
8
-
9
- **Development:**
10
- ```
11
- http://localhost:8081
12
- ```
13
-
14
- **Production:**
15
- ```
16
- https://your-domain.com
17
- ```
18
-
19
- ---
20
-
21
- ## Authentication
22
-
23
- Lynkr acts as a proxy, so authentication depends on the configured provider:
24
-
25
- **For Claude Code CLI:**
26
- ```bash
27
- export ANTHROPIC_API_KEY=dummy # Any value works
28
- export ANTHROPIC_BASE_URL=http://localhost:8081
29
- ```
30
-
31
- **For Cursor IDE:**
32
- ```
33
- API Key: sk-lynkr # Any value starting with "sk-" works
34
- Base URL: http://localhost:8081/v1
35
- ```
36
-
37
- **Note:** Real authentication happens between Lynkr and the provider (Databricks, Bedrock, etc.).
38
-
39
- ---
40
-
41
- ## Endpoints
42
-
43
- ### Chat Completion (Anthropic Format)
44
-
45
- #### POST /v1/messages
46
-
47
- Create a message using Anthropic's Messages API format.
48
-
49
- **Request:**
50
- ```bash
51
- curl -X POST http://localhost:8081/v1/messages \
52
- -H "Content-Type: application/json" \
53
- -H "anthropic-version: 2023-06-01" \
54
- -d '{
55
- "model": "claude-3-5-sonnet-20241022",
56
- "messages": [
57
- {
58
- "role": "user",
59
- "content": "What is the capital of France?"
60
- }
61
- ],
62
- "max_tokens": 1024,
63
- "temperature": 0.7
64
- }'
65
- ```
66
-
67
- **Request Body:**
68
- ```typescript
69
- {
70
- model: string; // Model name (e.g., "claude-3-5-sonnet-20241022")
71
- messages: Message[]; // Conversation history
72
- max_tokens?: number; // Max tokens to generate (default: 4096)
73
- temperature?: number; // 0.0-1.0 (default: 0.7)
74
- top_p?: number; // 0.0-1.0 (default: 1.0)
75
- top_k?: number; // Top-k sampling (default: null)
76
- stop_sequences?: string[]; // Stop generation at these sequences
77
- stream?: boolean; // Enable streaming (default: false)
78
- tools?: Tool[]; // Available tools for the model
79
- system?: string; // System prompt
80
- }
81
-
82
- interface Message {
83
- role: "user" | "assistant";
84
- content: string | Content[];
85
- }
86
-
87
- interface Content {
88
- type: "text" | "image" | "tool_use" | "tool_result";
89
- text?: string;
90
- source?: ImageSource;
91
- id?: string;
92
- name?: string;
93
- input?: object;
94
- tool_use_id?: string;
95
- content?: string | object;
96
- }
97
-
98
- interface Tool {
99
- name: string;
100
- description: string;
101
- input_schema: {
102
- type: "object";
103
- properties: object;
104
- required?: string[];
105
- };
106
- }
107
- ```
108
-
109
- **Response (Non-Streaming):**
110
- ```json
111
- {
112
- "id": "msg_01ABC123",
113
- "type": "message",
114
- "role": "assistant",
115
- "content": [
116
- {
117
- "type": "text",
118
- "text": "The capital of France is Paris."
119
- }
120
- ],
121
- "model": "claude-3-5-sonnet-20241022",
122
- "stop_reason": "end_turn",
123
- "stop_sequence": null,
124
- "usage": {
125
- "input_tokens": 15,
126
- "output_tokens": 8
127
- }
128
- }
129
- ```
130
-
131
- **Response (Streaming):**
132
- ```
133
- event: message_start
134
- data: {"type":"message_start","message":{"id":"msg_01ABC123","type":"message","role":"assistant","content":[],"model":"claude-3-5-sonnet-20241022","stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":15,"output_tokens":0}}}
135
-
136
- event: content_block_start
137
- data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
138
-
139
- event: content_block_delta
140
- data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"The"}}
141
-
142
- event: content_block_delta
143
- data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" capital"}}
144
-
145
- event: content_block_delta
146
- data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" of"}}
147
-
148
- event: content_block_delta
149
- data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" France"}}
150
-
151
- event: content_block_delta
152
- data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" is"}}
153
-
154
- event: content_block_delta
155
- data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Paris"}}
156
-
157
- event: content_block_delta
158
- data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"."}}
159
-
160
- event: content_block_stop
161
- data: {"type":"content_block_stop","index":0}
162
-
163
- event: message_delta
164
- data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":8}}
165
-
166
- event: message_stop
167
- data: {"type":"message_stop"}
168
- ```
169
-
170
- ---
171
-
172
- ### Chat Completion (OpenAI Format)
173
-
174
- #### POST /v1/chat/completions
175
-
176
- Create a chat completion using OpenAI's Chat Completions API format.
177
-
178
- **Request:**
179
- ```bash
180
- curl -X POST http://localhost:8081/v1/chat/completions \
181
- -H "Content-Type: application/json" \
182
- -H "Authorization: Bearer sk-lynkr" \
183
- -d '{
184
- "model": "claude-3.5-sonnet",
185
- "messages": [
186
- {
187
- "role": "user",
188
- "content": "What is the capital of France?"
189
- }
190
- ],
191
- "max_tokens": 1024,
192
- "temperature": 0.7,
193
- "stream": false
194
- }'
195
- ```
196
-
197
- **Request Body:**
198
- ```typescript
199
- {
200
- model: string; // Model name
201
- messages: Message[]; // Conversation history
202
- max_tokens?: number; // Max tokens to generate
203
- temperature?: number; // 0.0-2.0 (default: 0.7)
204
- top_p?: number; // 0.0-1.0
205
- n?: number; // Number of completions (default: 1)
206
- stop?: string | string[]; // Stop sequences
207
- stream?: boolean; // Enable streaming
208
- tools?: Tool[]; // Function calling tools
209
- }
210
-
211
- interface Message {
212
- role: "system" | "user" | "assistant" | "tool";
213
- content: string;
214
- name?: string; // For tool messages
215
- tool_call_id?: string; // For tool result messages
216
- tool_calls?: ToolCall[]; // For assistant tool call messages
217
- }
218
-
219
- interface ToolCall {
220
- id: string;
221
- type: "function";
222
- function: {
223
- name: string;
224
- arguments: string; // JSON string
225
- };
226
- }
227
-
228
- interface Tool {
229
- type: "function";
230
- function: {
231
- name: string;
232
- description: string;
233
- parameters: object; // JSON Schema
234
- };
235
- }
236
- ```
237
-
238
- **Response (Non-Streaming):**
239
- ```json
240
- {
241
- "id": "chatcmpl-ABC123",
242
- "object": "chat.completion",
243
- "created": 1677858242,
244
- "model": "claude-3.5-sonnet",
245
- "choices": [
246
- {
247
- "index": 0,
248
- "message": {
249
- "role": "assistant",
250
- "content": "The capital of France is Paris."
251
- },
252
- "finish_reason": "stop"
253
- }
254
- ],
255
- "usage": {
256
- "prompt_tokens": 15,
257
- "completion_tokens": 8,
258
- "total_tokens": 23
259
- }
260
- }
261
- ```
262
-
263
- **Response (Streaming):**
264
- ```
265
- data: {"id":"chatcmpl-ABC123","object":"chat.completion.chunk","created":1677858242,"model":"claude-3.5-sonnet","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
266
-
267
- data: {"id":"chatcmpl-ABC123","object":"chat.completion.chunk","created":1677858242,"model":"claude-3.5-sonnet","choices":[{"index":0,"delta":{"content":"The"},"finish_reason":null}]}
268
-
269
- data: {"id":"chatcmpl-ABC123","object":"chat.completion.chunk","created":1677858242,"model":"claude-3.5-sonnet","choices":[{"index":0,"delta":{"content":" capital"},"finish_reason":null}]}
270
-
271
- data: {"id":"chatcmpl-ABC123","object":"chat.completion.chunk","created":1677858242,"model":"claude-3.5-sonnet","choices":[{"index":0,"delta":{"content":" of"},"finish_reason":null}]}
272
-
273
- data: {"id":"chatcmpl-ABC123","object":"chat.completion.chunk","created":1677858242,"model":"claude-3.5-sonnet","choices":[{"index":0,"delta":{"content":" France"},"finish_reason":null}]}
274
-
275
- data: {"id":"chatcmpl-ABC123","object":"chat.completion.chunk","created":1677858242,"model":"claude-3.5-sonnet","choices":[{"index":0,"delta":{"content":" is"},"finish_reason":null}]}
276
-
277
- data: {"id":"chatcmpl-ABC123","object":"chat.completion.chunk","created":1677858242,"model":"claude-3.5-sonnet","choices":[{"index":0,"delta":{"content":" Paris"},"finish_reason":null}]}
278
-
279
- data: {"id":"chatcmpl-ABC123","object":"chat.completion.chunk","created":1677858242,"model":"claude-3.5-sonnet","choices":[{"index":0,"delta":{"content":"."},"finish_reason":null}]}
280
-
281
- data: {"id":"chatcmpl-ABC123","object":"chat.completion.chunk","created":1677858242,"model":"claude-3.5-sonnet","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
282
-
283
- data: [DONE]
284
- ```
285
-
286
- ---
287
-
288
- ### Embeddings
289
-
290
- #### POST /v1/embeddings
291
-
292
- Generate embeddings for text input.
293
-
294
- **Request:**
295
- ```bash
296
- curl -X POST http://localhost:8081/v1/embeddings \
297
- -H "Content-Type: application/json" \
298
- -d '{
299
- "input": "function to sort array",
300
- "model": "text-embedding-ada-002"
301
- }'
302
- ```
303
-
304
- **Request Body:**
305
- ```typescript
306
- {
307
- input: string | string[]; // Text to embed
308
- model: string; // Embedding model name
309
- }
310
- ```
311
-
312
- **Supported Models:**
313
- - `text-embedding-ada-002` (OpenAI)
314
- - `text-embedding-3-small` (OpenAI)
315
- - `text-embedding-3-large` (OpenAI)
316
- - `nomic-embed-text` (Ollama)
317
- - `all-minilm` (llama.cpp)
318
-
319
- **Response:**
320
- ```json
321
- {
322
- "object": "list",
323
- "data": [
324
- {
325
- "object": "embedding",
326
- "embedding": [0.123, -0.456, 0.789, ...],
327
- "index": 0
328
- }
329
- ],
330
- "model": "text-embedding-ada-002",
331
- "usage": {
332
- "prompt_tokens": 8,
333
- "total_tokens": 8
334
- }
335
- }
336
- ```
337
-
338
- **Configuration:**
339
- ```bash
340
- # Ollama embeddings (local)
341
- EMBEDDINGS_PROVIDER=ollama
342
- OLLAMA_API_BASE=http://localhost:11434
343
- OLLAMA_EMBEDDINGS_MODEL=nomic-embed-text
344
-
345
- # OpenAI embeddings (cloud)
346
- EMBEDDINGS_PROVIDER=openai
347
- OPENAI_API_KEY=sk-...
348
- OPENAI_EMBEDDINGS_MODEL=text-embedding-3-small
349
-
350
- # OpenRouter embeddings (cloud)
351
- EMBEDDINGS_PROVIDER=openrouter
352
- OPENROUTER_API_KEY=sk-or-v1-...
353
- OPENROUTER_EMBEDDINGS_MODEL=openai/text-embedding-3-small
354
- ```
355
-
356
- ---
357
-
358
- ### Models
359
-
360
- #### GET /v1/models
361
-
362
- List available models.
363
-
364
- **Request:**
365
- ```bash
366
- curl http://localhost:8081/v1/models
367
- ```
368
-
369
- **Response:**
370
- ```json
371
- {
372
- "object": "list",
373
- "data": [
374
- {
375
- "id": "claude-3-5-sonnet-20241022",
376
- "object": "model",
377
- "created": 1677649963,
378
- "owned_by": "anthropic"
379
- },
380
- {
381
- "id": "claude-3-opus-20240229",
382
- "object": "model",
383
- "created": 1677649963,
384
- "owned_by": "anthropic"
385
- },
386
- {
387
- "id": "qwen2.5-coder:7b",
388
- "object": "model",
389
- "created": 1677649963,
390
- "owned_by": "ollama"
391
- }
392
- ]
393
- }
394
- ```
395
-
396
- ---
397
-
398
- ### Health Checks
399
-
400
- #### GET /health/live
401
-
402
- Liveness probe - checks if server is running.
403
-
404
- **Request:**
405
- ```bash
406
- curl http://localhost:8081/health/live
407
- ```
408
-
409
- **Response:**
410
- ```json
411
- {
412
- "status": "ok",
413
- "provider": "databricks",
414
- "timestamp": "2026-01-12T00:00:00.000Z"
415
- }
416
- ```
417
-
418
- **HTTP Status:**
419
- - `200 OK` - Server is running
420
- - `503 Service Unavailable` - Server is not ready
421
-
422
- #### GET /health/ready
423
-
424
- Readiness probe - checks if server can handle requests.
425
-
426
- **Request:**
427
- ```bash
428
- curl http://localhost:8081/health/ready
429
- ```
430
-
431
- **Response:**
432
- ```json
433
- {
434
- "status": "ready",
435
- "checks": {
436
- "database": "ok",
437
- "provider": "ok"
438
- }
439
- }
440
- ```
441
-
442
- **HTTP Status:**
443
- - `200 OK` - Server is ready
444
- - `503 Service Unavailable` - Server is not ready
445
-
446
- #### GET /health/ready?deep=true
447
-
448
- Deep health check with detailed information.
449
-
450
- **Request:**
451
- ```bash
452
- curl "http://localhost:8081/health/ready?deep=true"
453
- ```
454
-
455
- **Response:**
456
- ```json
457
- {
458
- "status": "ready",
459
- "checks": {
460
- "database": "ok",
461
- "provider": "ok",
462
- "memory": {
463
- "used": "50%",
464
- "status": "ok"
465
- },
466
- "circuit_breaker": {
467
- "state": "closed",
468
- "status": "ok"
469
- }
470
- }
471
- }
472
- ```
473
-
474
- ---
475
-
476
- ### Metrics
477
-
478
- #### GET /metrics
479
-
480
- Prometheus-compatible metrics endpoint.
481
-
482
- **Request:**
483
- ```bash
484
- curl http://localhost:8081/metrics
485
- ```
486
-
487
- **Response:**
488
- ```
489
- # HELP lynkr_requests_total Total number of requests
490
- # TYPE lynkr_requests_total counter
491
- lynkr_requests_total{provider="databricks",status="200"} 1234
492
-
493
- # HELP lynkr_request_duration_seconds Request duration in seconds
494
- # TYPE lynkr_request_duration_seconds histogram
495
- lynkr_request_duration_seconds_bucket{provider="databricks",le="0.5"} 980
496
- lynkr_request_duration_seconds_bucket{provider="databricks",le="1"} 1200
497
- lynkr_request_duration_seconds_bucket{provider="databricks",le="2"} 1230
498
- lynkr_request_duration_seconds_bucket{provider="databricks",le="+Inf"} 1234
499
- lynkr_request_duration_seconds_sum{provider="databricks"} 1234.5
500
- lynkr_request_duration_seconds_count{provider="databricks"} 1234
501
-
502
- # HELP lynkr_errors_total Total number of errors
503
- # TYPE lynkr_errors_total counter
504
- lynkr_errors_total{provider="databricks",type="timeout"} 12
505
-
506
- # HELP lynkr_tokens_input_total Total input tokens
507
- # TYPE lynkr_tokens_input_total counter
508
- lynkr_tokens_input_total{provider="databricks"} 5000000
509
-
510
- # HELP lynkr_tokens_output_total Total output tokens
511
- # TYPE lynkr_tokens_output_total counter
512
- lynkr_tokens_output_total{provider="databricks"} 500000
513
-
514
- # HELP lynkr_tokens_cached_total Total cached tokens
515
- # TYPE lynkr_tokens_cached_total counter
516
- lynkr_tokens_cached_total 2000000
517
-
518
- # HELP lynkr_cache_hits_total Total cache hits
519
- # TYPE lynkr_cache_hits_total counter
520
- lynkr_cache_hits_total 850
521
-
522
- # HELP lynkr_cache_misses_total Total cache misses
523
- # TYPE lynkr_cache_misses_total counter
524
- lynkr_cache_misses_total 150
525
-
526
- # HELP lynkr_circuit_breaker_state Circuit breaker state (1=open, 0=closed)
527
- # TYPE lynkr_circuit_breaker_state gauge
528
- lynkr_circuit_breaker_state{provider="databricks",state="closed"} 1
529
-
530
- # HELP lynkr_active_requests Current active requests
531
- # TYPE lynkr_active_requests gauge
532
- lynkr_active_requests 42
533
-
534
- # HELP process_resident_memory_bytes Resident memory size in bytes
535
- # TYPE process_resident_memory_bytes gauge
536
- process_resident_memory_bytes 104857600
537
-
538
- # HELP nodejs_heap_size_used_bytes Heap size used in bytes
539
- # TYPE nodejs_heap_size_used_bytes gauge
540
- nodejs_heap_size_used_bytes 52428800
541
- ```
542
-
543
- ---
544
-
545
- ## Error Handling
546
-
547
- ### Error Response Format
548
-
549
- **Anthropic Format:**
550
- ```json
551
- {
552
- "type": "error",
553
- "error": {
554
- "type": "invalid_request_error",
555
- "message": "Missing required field: messages"
556
- }
557
- }
558
- ```
559
-
560
- **OpenAI Format:**
561
- ```json
562
- {
563
- "error": {
564
- "message": "Missing required field: messages",
565
- "type": "invalid_request_error",
566
- "code": "invalid_request"
567
- }
568
- }
569
- ```
570
-
571
- ### Error Types
572
-
573
- | HTTP Status | Error Type | Description |
574
- |-------------|------------|-------------|
575
- | 400 | `invalid_request_error` | Invalid request parameters |
576
- | 401 | `authentication_error` | Invalid or missing API key |
577
- | 403 | `permission_error` | Insufficient permissions |
578
- | 404 | `not_found_error` | Resource not found |
579
- | 429 | `rate_limit_error` | Rate limit exceeded |
580
- | 500 | `api_error` | Internal server error |
581
- | 503 | `overloaded_error` | Server overloaded (load shedding) |
582
-
583
- ### Common Errors
584
-
585
- **Missing API Key:**
586
- ```json
587
- {
588
- "type": "error",
589
- "error": {
590
- "type": "authentication_error",
591
- "message": "Missing provider API key. Set DATABRICKS_API_KEY environment variable."
592
- }
593
- }
594
- ```
595
-
596
- **Rate Limit:**
597
- ```json
598
- {
599
- "type": "error",
600
- "error": {
601
- "type": "rate_limit_error",
602
- "message": "Rate limit exceeded. Retry after 60 seconds."
603
- }
604
- }
605
- ```
606
-
607
- **Load Shedding:**
608
- ```json
609
- {
610
- "type": "error",
611
- "error": {
612
- "type": "overloaded_error",
613
- "message": "Server overloaded. Please retry."
614
- }
615
- }
616
- ```
617
-
618
- HTTP Response:
619
- ```
620
- HTTP/1.1 503 Service Unavailable
621
- Retry-After: 5
622
- Content-Type: application/json
623
-
624
- {"type":"error","error":{"type":"overloaded_error","message":"Server overloaded. Please retry."}}
625
- ```
626
-
627
- ---
628
-
629
- ## Rate Limiting
630
-
631
- Lynkr does not implement rate limiting itself. Rate limits are enforced by the underlying provider:
632
-
633
- | Provider | Rate Limit | Burst |
634
- |----------|------------|-------|
635
- | **Databricks** | Provider-specific | Provider-specific |
636
- | **AWS Bedrock** | Provider-specific | Provider-specific |
637
- | **OpenRouter** | Provider-specific | Provider-specific |
638
- | **Ollama** | No limit | No limit |
639
- | **llama.cpp** | No limit | No limit |
640
-
641
- **Handle rate limits:**
642
- ```javascript
643
- async function makeRequest(payload) {
644
- try {
645
- const response = await fetch("http://localhost:8081/v1/messages", {
646
- method: "POST",
647
- headers: { "Content-Type": "application/json" },
648
- body: JSON.stringify(payload)
649
- });
650
-
651
- if (response.status === 429) {
652
- const retryAfter = response.headers.get("Retry-After");
653
- console.log(`Rate limited. Retry after ${retryAfter}s`);
654
- await sleep(parseInt(retryAfter) * 1000);
655
- return makeRequest(payload); // Retry
656
- }
657
-
658
- return await response.json();
659
- } catch (error) {
660
- console.error("Request failed:", error);
661
- throw error;
662
- }
663
- }
664
- ```
665
-
666
- ---
667
-
668
- ## SDK Examples
669
-
670
- ### Node.js (Anthropic SDK)
671
-
672
- ```javascript
673
- import Anthropic from "@anthropic-ai/sdk";
674
-
675
- const client = new Anthropic({
676
- apiKey: "dummy", // Any value works
677
- baseURL: "http://localhost:8081"
678
- });
679
-
680
- // Non-streaming
681
- const message = await client.messages.create({
682
- model: "claude-3-5-sonnet-20241022",
683
- max_tokens: 1024,
684
- messages: [
685
- { role: "user", content: "What is the capital of France?" }
686
- ]
687
- });
688
-
689
- console.log(message.content[0].text);
690
-
691
- // Streaming
692
- const stream = await client.messages.create({
693
- model: "claude-3-5-sonnet-20241022",
694
- max_tokens: 1024,
695
- messages: [
696
- { role: "user", content: "Tell me a story" }
697
- ],
698
- stream: true
699
- });
700
-
701
- for await (const event of stream) {
702
- if (event.type === "content_block_delta") {
703
- process.stdout.write(event.delta.text);
704
- }
705
- }
706
- ```
707
-
708
- ### Python (OpenAI SDK)
709
-
710
- ```python
711
- from openai import OpenAI
712
-
713
- client = OpenAI(
714
- api_key="sk-lynkr",
715
- base_url="http://localhost:8081/v1"
716
- )
717
-
718
- # Non-streaming
719
- response = client.chat.completions.create(
720
- model="claude-3.5-sonnet",
721
- messages=[
722
- {"role": "user", "content": "What is the capital of France?"}
723
- ],
724
- max_tokens=1024
725
- )
726
-
727
- print(response.choices[0].message.content)
728
-
729
- # Streaming
730
- stream = client.chat.completions.create(
731
- model="claude-3.5-sonnet",
732
- messages=[
733
- {"role": "user", "content": "Tell me a story"}
734
- ],
735
- max_tokens=1024,
736
- stream=True
737
- )
738
-
739
- for chunk in stream:
740
- if chunk.choices[0].delta.content:
741
- print(chunk.choices[0].delta.content, end="")
742
- ```
743
-
744
- ### cURL
745
-
746
- ```bash
747
- # Non-streaming (Anthropic format)
748
- curl -X POST http://localhost:8081/v1/messages \
749
- -H "Content-Type: application/json" \
750
- -H "anthropic-version: 2023-06-01" \
751
- -d '{
752
- "model": "claude-3-5-sonnet-20241022",
753
- "messages": [{"role": "user", "content": "Hello"}],
754
- "max_tokens": 1024
755
- }'
756
-
757
- # Streaming (Anthropic format)
758
- curl -X POST http://localhost:8081/v1/messages \
759
- -H "Content-Type: application/json" \
760
- -H "anthropic-version: 2023-06-01" \
761
- -d '{
762
- "model": "claude-3-5-sonnet-20241022",
763
- "messages": [{"role": "user", "content": "Hello"}],
764
- "max_tokens": 1024,
765
- "stream": true
766
- }' \
767
- --no-buffer
768
-
769
- # Non-streaming (OpenAI format)
770
- curl -X POST http://localhost:8081/v1/chat/completions \
771
- -H "Content-Type: application/json" \
772
- -H "Authorization: Bearer sk-lynkr" \
773
- -d '{
774
- "model": "claude-3.5-sonnet",
775
- "messages": [{"role": "user", "content": "Hello"}],
776
- "max_tokens": 1024
777
- }'
778
-
779
- # Streaming (OpenAI format)
780
- curl -X POST http://localhost:8081/v1/chat/completions \
781
- -H "Content-Type: application/json" \
782
- -H "Authorization: Bearer sk-lynkr" \
783
- -d '{
784
- "model": "claude-3.5-sonnet",
785
- "messages": [{"role": "user", "content": "Hello"}],
786
- "max_tokens": 1024,
787
- "stream": true
788
- }' \
789
- --no-buffer
790
- ```
791
-
792
- ---
793
-
794
- ## Next Steps
795
-
796
- - **[Claude Code CLI Guide](claude-code-cli.md)** - Configure Claude Code CLI
797
- - **[Cursor Integration](cursor-integration.md)** - Configure Cursor IDE
798
- - **[Providers Guide](providers.md)** - Configure providers
799
- - **[Troubleshooting](troubleshooting.md)** - Common issues
800
-
801
- ---
802
-
803
- ## Getting Help
804
-
805
- - **[GitHub Discussions](https://github.com/vishalveerareddy123/Lynkr/discussions)** - Ask questions
806
- - **[GitHub Issues](https://github.com/vishalveerareddy123/Lynkr/issues)** - Report issues