-
-
Notifications
You must be signed in to change notification settings - Fork 59
Expand file tree
/
Copy path.env.example
More file actions
1019 lines (927 loc) · 43.5 KB
/
Copy path.env.example
File metadata and controls
1019 lines (927 loc) · 43.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# ==============================================================================
# LYNKR CONFIGURATION - All Environment Variables
# ==============================================================================
# Copy this file to .env and fill in your values.
#
# FORMAT: Use plain KEY=VALUE syntax (no "export" prefix).
# Good: MODEL_PROVIDER=bedrock
# Bad: export MODEL_PROVIDER=bedrock
#
# Every variable Lynkr reads from the environment is documented below with:
# - A one-line DESCRIPTION
# - An example value
# - Allowed values when finite (e.g. true|false, or a known provider set)
#
# Variables that need secrets are shown commented-out with a placeholder so the
# file is safe to commit.
# ==============================================================================
# ==============================================================================
# 1. TIER ROUTING (the main routing knob — REQUIRED)
# ==============================================================================
# Format: TIER_<LEVEL>=provider:model[:variant]
# Supported providers: ollama, openai, atlas, azure-openai, azure-anthropic,
# openrouter, edenai, databricks, bedrock, vertex, zai,
# moonshot, llamacpp, lmstudio
#
# When all 4 TIER_* are set, Lynkr enters "tier routing mode":
# - MODEL_PROVIDER auto-detected from TIER_SIMPLE
# - FALLBACK_PROVIDER auto-detected from TIER_REASONING
# - FALLBACK_ENABLED becomes automatic
# - Only validates credentials for providers actually used in tiers
#
# Setting MODEL_PROVIDER / FALLBACK_PROVIDER alongside tier routing is rejected.
# DESCRIPTION: Provider:model for trivial single-shot tasks (greetings, formatting)
TIER_SIMPLE=ollama:qwen2.5-coder:latest
# DESCRIPTION: Provider:model for moderate tasks (code edits, small refactors)
TIER_MEDIUM=ollama:qwen2.5-coder:latest
# DESCRIPTION: Provider:model for complex tasks (multi-file changes, design)
TIER_COMPLEX=moonshot:kimi-k2-thinking
# DESCRIPTION: Provider:model for hard reasoning (algorithms, debugging)
TIER_REASONING=moonshot:kimi-k2-thinking
# DESCRIPTION: Auto-fallback when the tier provider fails. Auto-true under tier routing.
# Values: true | false
FALLBACK_ENABLED=false
# DESCRIPTION: Fallback provider when tier provider fails (cannot be local).
# One of: databricks, azure-anthropic, azure-openai, openrouter, edenai, openai, atlas, bedrock
FALLBACK_PROVIDER=databricks
# DESCRIPTION: [DEPRECATED legacy knob] primary provider for credential validation.
# Auto-detected when TIER_* is set. Same allowed values as FALLBACK_PROVIDER plus ollama/llamacpp/lmstudio/vertex/zai/moonshot.
MODEL_PROVIDER=ollama
# DESCRIPTION: [DEPRECATED] legacy preference for Ollama. Use TIER_SIMPLE=ollama:<model> instead.
# Values: true | false
# PREFER_OLLAMA=false
# ==============================================================================
# 2. PER-PROVIDER CONFIG
# ==============================================================================
# ------------------------------------------------------------------------------
# Anthropic (direct + OAuth subscription mode)
# ------------------------------------------------------------------------------
# OAuth mode: when using `lynkr wrap claude`, the OAuth token from `claude login`
# is forwarded automatically — no API key needed.
# DESCRIPTION: Anthropic API key. Only needed when NOT using OAuth subscription.
# ANTHROPIC_API_KEY=sk-ant-your-key-here
# ------------------------------------------------------------------------------
# Azure Anthropic (Anthropic-format endpoint, OAuth-friendly)
# ------------------------------------------------------------------------------
# DESCRIPTION: Endpoint URL for Azure-hosted Anthropic (also used as OAuth passthrough target).
AZURE_ANTHROPIC_ENDPOINT=https://api.anthropic.com/v1/messages
# DESCRIPTION: API key for Azure Anthropic. Not needed if OAuth token is being forwarded.
# AZURE_ANTHROPIC_API_KEY=your-azure-anthropic-key
# DESCRIPTION: Anthropic API version header.
AZURE_ANTHROPIC_VERSION=2023-06-01
# ------------------------------------------------------------------------------
# Azure OpenAI
# ------------------------------------------------------------------------------
# DESCRIPTION: Azure OpenAI endpoint URL (standard or AI Foundry format).
# AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
# DESCRIPTION: Azure OpenAI API key.
# AZURE_OPENAI_API_KEY=your-azure-openai-key
# DESCRIPTION: Deployment name (e.g. gpt-4o, gpt-5.2-chat).
AZURE_OPENAI_DEPLOYMENT=gpt-4o
# DESCRIPTION: API version to use.
AZURE_OPENAI_API_VERSION=2024-08-01-preview
# ------------------------------------------------------------------------------
# OpenAI (direct)
# ------------------------------------------------------------------------------
# DESCRIPTION: OpenAI API key.
# OPENAI_API_KEY=sk-your-openai-api-key
# DESCRIPTION: Default OpenAI model.
OPENAI_MODEL=gpt-4o
# DESCRIPTION: Chat completions endpoint (can point at any OpenAI-compatible host).
OPENAI_ENDPOINT=https://api.openai.com/v1/chat/completions
# DESCRIPTION: Optional OpenAI org id.
# OPENAI_ORGANIZATION=org-your-org-id
# ------------------------------------------------------------------------------
# Atlas Cloud (OpenAI-compatible)
# ------------------------------------------------------------------------------
# DESCRIPTION: Atlas Cloud API key from https://www.atlascloud.ai/console/api-keys.
# ATLASCLOUD_API_KEY=your-atlas-cloud-api-key
# DESCRIPTION: Default Atlas Cloud text model.
ATLASCLOUD_MODEL=qwen/qwen3.8-max
# DESCRIPTION: Atlas Cloud Chat Completions endpoint.
ATLASCLOUD_ENDPOINT=https://api.atlascloud.ai/v1/chat/completions
# ------------------------------------------------------------------------------
# Ollama (local models)
# ------------------------------------------------------------------------------
# DESCRIPTION: Default Ollama model id.
OLLAMA_MODEL=qwen2.5-coder:latest
# DESCRIPTION: Ollama server endpoint.
OLLAMA_ENDPOINT=http://localhost:11434
# DESCRIPTION: Per-request timeout in milliseconds.
OLLAMA_TIMEOUT_MS=120000
# DESCRIPTION: Ollama `keep_alive` parameter (e.g. "5m", "30m", "-1" for forever).
# OLLAMA_KEEP_ALIVE=5m
# DESCRIPTION: Cap on how many tools are injected when routing through Ollama.
OLLAMA_MAX_TOOLS_FOR_ROUTING=3
# DESCRIPTION: Embedding model (for semantic cache and Cursor @Codebase).
OLLAMA_EMBEDDINGS_MODEL=nomic-embed-text
# DESCRIPTION: Embeddings endpoint URL.
OLLAMA_EMBEDDINGS_ENDPOINT=http://localhost:11434/api/embeddings
# ------------------------------------------------------------------------------
# OpenRouter (100+ models via single API)
# ------------------------------------------------------------------------------
# DESCRIPTION: OpenRouter API key.
# OPENROUTER_API_KEY=your-openrouter-key
# DESCRIPTION: Default OpenRouter model.
OPENROUTER_MODEL=openai/gpt-4o-mini
# DESCRIPTION: Embedding model used through OpenRouter.
OPENROUTER_EMBEDDINGS_MODEL=openai/text-embedding-ada-002
# DESCRIPTION: OpenRouter chat completions endpoint.
OPENROUTER_ENDPOINT=https://openrouter.ai/api/v1/chat/completions
# DESCRIPTION: Cap on tool count sent during routing.
OPENROUTER_MAX_TOOLS_FOR_ROUTING=15
# Eden AI (600+ models via single API, OpenAI-compatible, EU/GDPR)
# DESCRIPTION: Eden AI API key.
# EDENAI_API_KEY=your-edenai-key
# DESCRIPTION: Default Eden AI model (provider/model naming).
EDENAI_MODEL=openai/gpt-4o-mini
# DESCRIPTION: Embedding model used through Eden AI.
EDENAI_EMBEDDINGS_MODEL=openai/text-embedding-ada-002
# DESCRIPTION: Eden AI chat completions endpoint (OpenAI-compatible v3).
EDENAI_ENDPOINT=https://api.edenai.run/v3/chat/completions
# ------------------------------------------------------------------------------
# Databricks
# ------------------------------------------------------------------------------
# DESCRIPTION: Databricks workspace base URL.
# DATABRICKS_API_BASE=https://your-workspace.cloud.databricks.com
# DESCRIPTION: Databricks personal access token.
# DATABRICKS_API_KEY=dapi1234567890abcdef
# DESCRIPTION: Path to the serving endpoint to invoke.
# DATABRICKS_ENDPOINT_PATH=/serving-endpoints/databricks-claude-sonnet-4-5/invocations
# ------------------------------------------------------------------------------
# AWS Bedrock (uses Bedrock API Key, NOT IAM)
# ------------------------------------------------------------------------------
# DESCRIPTION: Bedrock bearer API key (starts with ABSK, generated in AWS console).
# AWS_BEDROCK_API_KEY=ABSK...your-bedrock-api-key
# DESCRIPTION: AWS region.
AWS_BEDROCK_REGION=us-east-1
# DESCRIPTION: Fallback region if AWS_BEDROCK_REGION is unset.
# AWS_REGION=us-east-1
# DESCRIPTION: Default Bedrock model id (often a US inference profile).
AWS_BEDROCK_MODEL_ID=us.anthropic.claude-3-5-sonnet-20241022-v2:0
# ------------------------------------------------------------------------------
# Moonshot AI (Kimi)
# ------------------------------------------------------------------------------
# DESCRIPTION: Moonshot API key.
# MOONSHOT_API_KEY=your-moonshot-api-key
# DESCRIPTION: Moonshot chat completions endpoint.
MOONSHOT_ENDPOINT=https://api.moonshot.ai/v1/chat/completions
# DESCRIPTION: Default Moonshot model.
MOONSHOT_MODEL=kimi-k2-thinking
# ------------------------------------------------------------------------------
# Google Vertex AI / Gemini
# ------------------------------------------------------------------------------
# DESCRIPTION: Vertex/Gemini API key (preferred name).
# VERTEX_API_KEY=your-google-api-key
# DESCRIPTION: Fallback Google API key if VERTEX_API_KEY is unset.
# GOOGLE_API_KEY=your-google-api-key
# DESCRIPTION: Default Gemini model.
VERTEX_MODEL=gemini-2.0-flash
# ------------------------------------------------------------------------------
# llama.cpp (local GGUF server)
# ------------------------------------------------------------------------------
# DESCRIPTION: llama.cpp server base URL.
LLAMACPP_ENDPOINT=http://localhost:8080
# DESCRIPTION: llama.cpp model name to request.
LLAMACPP_MODEL=default
# DESCRIPTION: Per-request timeout in ms.
LLAMACPP_TIMEOUT_MS=120000
# DESCRIPTION: Optional bearer token if your llama.cpp server requires auth.
# LLAMACPP_API_KEY=your-optional-api-key
# DESCRIPTION: Embeddings endpoint (defaults to ENDPOINT + /embeddings).
LLAMACPP_EMBEDDINGS_ENDPOINT=http://localhost:8080/embeddings
# ------------------------------------------------------------------------------
# LM Studio
# ------------------------------------------------------------------------------
# DESCRIPTION: LM Studio OpenAI-compatible endpoint.
LMSTUDIO_ENDPOINT=http://localhost:1234
# DESCRIPTION: LM Studio model id to request.
LMSTUDIO_MODEL=default
# DESCRIPTION: Per-request timeout in ms.
LMSTUDIO_TIMEOUT_MS=120000
# DESCRIPTION: Optional bearer token.
# LMSTUDIO_API_KEY=your-optional-api-key
# ------------------------------------------------------------------------------
# Z.AI (Zhipu AI)
# ------------------------------------------------------------------------------
# DESCRIPTION: Z.AI API key.
# ZAI_API_KEY=your-zai-api-key
# DESCRIPTION: Z.AI Anthropic-compatible messages endpoint.
ZAI_ENDPOINT=https://api.z.ai/api/anthropic/v1/messages
# DESCRIPTION: Default Z.AI model.
ZAI_MODEL=GLM-4.7
# DESCRIPTION: Max concurrent in-flight Z.AI requests.
ZAI_MAX_CONCURRENT=2
# ------------------------------------------------------------------------------
# Baidu Qianfan (ERNIE)
# ------------------------------------------------------------------------------
# DESCRIPTION: Baidu Qianfan API key (format: bce-v3/ALTAK-...).
# BAIDU_API_KEY=your-baidu-qianfan-api-key
# DESCRIPTION: Qianfan v2 OpenAI-compatible chat completions endpoint.
BAIDU_ENDPOINT=https://qianfan.baidubce.com/v2/chat/completions
# DESCRIPTION: Default Baidu ERNIE model.
BAIDU_MODEL=glm-5.2
# ------------------------------------------------------------------------------
# Codex (uses your ChatGPT subscription via local codex CLI)
# ------------------------------------------------------------------------------
# DESCRIPTION: Enable the Codex local provider (requires `codex` CLI installed).
# Values: true | false
# CODEX_ENABLED=true
# DESCRIPTION: Codex model id.
# CODEX_MODEL=gpt-5.3-codex
# DESCRIPTION: Path to the `codex` binary; auto-detected if unset.
# CODEX_BINARY_PATH=codex
# DESCRIPTION: Per-request timeout in ms.
# CODEX_TIMEOUT=120000
# ------------------------------------------------------------------------------
# Embeddings provider override
# ------------------------------------------------------------------------------
# DESCRIPTION: Force a specific embeddings provider (otherwise inferred from MODEL_PROVIDER).
# One of: ollama, llamacpp, openrouter, openai
# EMBEDDINGS_PROVIDER=ollama
# ==============================================================================
# 3. SERVER
# ==============================================================================
# DESCRIPTION: HTTP port the proxy listens on.
PORT=8080
# DESCRIPTION: Pino log level.
# Values: trace | debug | info | warn | error | fatal | silent
LOG_LEVEL=info
# DESCRIPTION: Node runtime mode. "development" enables pino-pretty (requires install).
# Values: development | production | test
NODE_ENV=production
# DESCRIPTION: Max JSON request body size (express bodyParser units, e.g. "1gb").
REQUEST_JSON_LIMIT=1gb
# DESCRIPTION: SQLite path for session storage.
SESSION_DB_PATH=./data/sessions.db
# DESCRIPTION: Absolute path to the workspace Lynkr operates on.
WORKSPACE_ROOT=/path/to/your/workspace
# DESCRIPTION: Pretty-print SQL statements to stdout (very verbose).
# Values: 1 | unset
# DEBUG_SQL=1
# DESCRIPTION: Print per-stage timing breakdowns to stdout.
# Values: true | false
# PERF_TIMER=false
# DESCRIPTION: Persistent file logging via pino-roll.
# Values: true | false
# LOG_FILE_ENABLED=true
# DESCRIPTION: Log file path.
# LOG_FILE_PATH=./logs/lynkr.log
# DESCRIPTION: Log file verbosity.
# LOG_FILE_LEVEL=debug
# DESCRIPTION: Roll frequency.
# Values: daily | hourly | <bytes>
# LOG_FILE_FREQUENCY=daily
# DESCRIPTION: Max rotated files to retain.
# LOG_FILE_MAX_FILES=14
# ==============================================================================
# 4. ROUTING INTELLIGENCE
# ==============================================================================
# DESCRIPTION: Include `lynkr_interaction` block in every successful response showing where it routed.
# Values: true | false
LYNKR_VISIBLE_ROUTING=false
# DESCRIPTION: Cost-optimized routing (downgrade tier when safe).
# Values: true | false
LYNKR_COST_OPTIMIZE=true
# DESCRIPTION: Enable cascading retry/escalation between tiers.
# Values: true | false
LYNKR_CASCADE_ENABLED=false
# DESCRIPTION: For OAuth/subscription requests, score the last N user messages
# instead of just the latest one. Catches "this conversation HAD a complex
# turn earlier" (e.g. an "audit credentials" ask 4 turns back) without
# inflating short follow-ups ("yes", "continue"). Combined with
# LYNKR_INTENT_DECAY as exponential recency weighting; the message with
# the highest decayed score wins.
# Values: positive integer (default 5). Set 1 to disable (latest-only).
LYNKR_INTENT_WINDOW_N=5
# DESCRIPTION: Per-turn exponential decay applied during window scoring.
# weighted_score = raw_score * decay^age, where age=0 is the latest user
# message. Higher (~0.9) = old turns linger longer; lower (~0.5) = old
# turns forgotten faster. 0.7 means a complex turn from 4 messages back
# contributes ~24% of its raw score to the max comparison.
# Values: float in (0, 1] (default 0.7).
LYNKR_INTENT_DECAY=0.7
# DESCRIPTION: Shadow-mode policy name (records what an alt policy would do without applying it).
# LYNKR_SHADOW_POLICY=
# DESCRIPTION: Master switch for the budget enforcer middleware.
# Values: true | false (set "false" to disable)
LYNKR_BUDGET_ENFORCER=true
# DESCRIPTION: Enable the regret-estimator post-hoc routing critic.
# Values: true | false
LYNKR_REGRET_ESTIMATOR=false
# ---- Sticky sessions (WS1) -----------------------------------------
# DESCRIPTION: Cache-aware sticky session pinning. Once a session is
# routed, subsequent turns reuse the pinned provider/model instead of
# re-deciding — avoids a cold-cache re-read (~10× that turn's input cost)
# on every provider switch. Re-decides on compaction, guard escalation
# (risk/context/vision), or economic downgrade below the switch-max
# threshold. Vision requests are pinExempt (per-turn upgrade, no re-pin).
# Values: true | false (default true — set "false" to disable)
LYNKR_STICKY_SESSIONS=true
# DESCRIPTION: TTL for a session pin (ms). Older pins are evicted by the
# 5-minute cleanup tick in src/sessions/cleanup.js.
# Default: 6 hours (21_600_000 ms).
LYNKR_STICKY_TTL_MS=21600000
# DESCRIPTION: Prompt-token cap under which an economic downgrade may
# override the pin. Above this the cold-cache re-read dominates the
# per-token savings, so the pin wins even if the fresh routing decision
# picks a cheaper model. Default 20 000.
LYNKR_SWITCH_MAX_PROMPT_TOKENS=20000
# DESCRIPTION: WS1.5 upward-drift margin. A pinned session re-decides when
# the latest user message's heuristic score exceeds the pinned tier's
# calibrated ceiling + this margin. Smaller = pins escape sooner (more
# re-routes, better tier fidelity); larger = stickier pins (fewer cold
# cache reads, risk of under-tiering). Live guidance: with tool-baseline
# subtraction active, trivial turns score 5-15 and mid-weight asks 22-35,
# so 5 splits them cleanly; the old default of 15 let 32-scoring
# architecture questions ride a SIMPLE pin.
LYNKR_PIN_DRIFT_MARGIN=5
# DESCRIPTION: WS6 cascade verification (EXPERIMENTAL). After a cheap-tier
# (SIMPLE/MEDIUM) response, run structural checks (language drift,
# degeneration, truncation, malformed tool calls, empty/echo) plus a coarse
# content score. A failing answer is DISCARDED and the request escalates up
# the tier ladder — a routing mistake costs seconds, not a garbage answer.
# Failed attempts feed the learning loop as hard negatives. Expensive-tier
# answers are never re-verified. Values: true | false (default off).
# LYNKR_CASCADE_VERIFY=true
# ---- Learning loop (WS5) -------------------------------------------
# DESCRIPTION: Minimum kNN index size before the router will use its
# advice. Below this size the router returns null (heuristic wins).
# Post-WS5 the confidence returned by query() is also damped by
# min(1, size/1000) so a small index advises weakly rather than not
# at all. Default 100 (WS5 lowered from the pre-WS5 default of 1000).
LYNKR_KNN_MIN_INDEX_SIZE=100
# DESCRIPTION: HIGH-confidence threshold above which a kNN suggestion
# overrides the tier-config model directly. Values in (0, 1].
LYNKR_KNN_CONFIDENCE_HIGH=0.7
# DESCRIPTION: LOW-confidence threshold. Between LOW and HIGH the
# suggestion is treated as "ambiguous" and — subject to the WS2 leash
# (only escalate when telemetry.underProvisionedPct ≥ 2%) — may bump
# the tier one level for safety.
LYNKR_KNN_CONFIDENCE_LOW=0.4
# NOTE: LYNKR_AUTO_CALIBRATE and LYNKR_TELEMETRY_DB_PATH used to live
# here. Both are now hardcoded — auto-calibration is always armed (it
# self-gates on telemetry sample count) and the telemetry DB lives at
# `<cwd>/.lynkr/telemetry.db`. Tests use `telemetry._setDbPathForTests()`
# / `_disableForTests()` to isolate their state.
# DESCRIPTION: Forward incoming OAuth Bearer tokens straight to the upstream Anthropic endpoint.
# Set automatically by `lynkr wrap claude`.
# Values: true | false
# LYNKR_OAUTH_PASSTHROUGH=true
# DESCRIPTION: Upstream URL used for OAuth passthrough (defaults to AZURE_ANTHROPIC_ENDPOINT).
# LYNKR_OAUTH_PASSTHROUGH_URL=https://api.anthropic.com/v1/messages
# DESCRIPTION: Inject long-term memory into OAuth-passthrough requests.
# Values: true | false
# LYNKR_OAUTH_MEMORY_INJECTION=false
# DESCRIPTION: Run client-supplied preflight commands (cwd = workspace) and short-circuit if they all pass.
# Values: true | false
LYNKR_PREFLIGHT_ENABLED=false
# DESCRIPTION: Per-command timeout for preflight checks, in ms.
LYNKR_PREFLIGHT_TIMEOUT_MS=120000
# DESCRIPTION: Show stats summary on exit when running `lynkr wrap claude`.
# Values: true | false
LYNKR_WRAP_SHOW_STATS=true
# DESCRIPTION: OpenClaw mode — rewrites response `model` field with actual provider/model used.
# Values: true | false
# OPENCLAW_MODE=false
# DESCRIPTION: Default fallback model name when no tier/provider model is known.
# MODEL_DEFAULT=claude-3-5-sonnet
# DESCRIPTION: JSON of per-model price overrides for the cost registry.
# Format: {"model-name":{"input":0.5,"output":1.5}}
# MODEL_PRICE_OVERRIDES={}
# DESCRIPTION: Suggestion-mode model override.
# Values: default (same as MODEL_PROVIDER) | none | <model-name>
SUGGESTION_MODE_MODEL=default
# ==============================================================================
# 5. TOOL EXECUTION
# ==============================================================================
# DESCRIPTION: Inject native tool definitions into Ollama requests (for models without tool-calling).
# Values: true | false (default true)
INJECT_TOOLS_OLLAMA=true
# DESCRIPTION: Inject native tool definitions into llama.cpp requests.
# Values: true | false (default true)
INJECT_TOOLS_LLAMACPP=true
# ==============================================================================
# 5b. UPSTREAM STREAMING
# ==============================================================================
# DESCRIPTION: Kill switch for native-format streaming passthrough (Anthropic
# client + Anthropic upstream pipes SSE bytes straight through, skipping the
# buffered orchestrator).
# Values: true | false (default true)
LYNKR_NATIVE_PASSTHROUGH=true
# DESCRIPTION: Kill switch for cross-format streaming (OpenAI upstream SSE
# reshaped into Anthropic events in flight instead of buffering).
# Values: true | false (default true)
LYNKR_STREAM_TRANSFORM=true
# DESCRIPTION: Buffer Ollama responses instead of streaming. Buffering repairs
# leaked <think> tags from thinking models (MiniMax) but delivers all at once.
# Values: true | false (default true — set false to stream)
LYNKR_OLLAMA_BUFFER_RESPONSES=true
# DESCRIPTION: Providers eligible for the cross-format stream transform.
# Values: comma-separated (default openai,atlas,azure-openai,openrouter,databricks,lmstudio,llamacpp,moonshot)
#LYNKR_STREAM_TRANSFORM_PROVIDERS=openai,azure-openai
# DESCRIPTION: Abort a passthrough stream when the upstream goes silent this long.
LYNKR_STREAM_IDLE_TIMEOUT_MS=60000
# DESCRIPTION: Smart tool selection strategy (also feeds the routing complexity analyzer).
# Values: heuristic | aggressive | conservative | disabled
SMART_TOOL_SELECTION_MODE=heuristic
# DESCRIPTION: Token budget the smart-selector tries to stay under.
SMART_TOOL_SELECTION_TOKEN_BUDGET=2500
# DESCRIPTION: Master switch for the MCP sandbox.
# Values: true | false
MCP_SANDBOX_ENABLED=true
# DESCRIPTION: Container image used when sandboxing MCP servers.
# MCP_SANDBOX_IMAGE=node:20-alpine
# DESCRIPTION: Sandbox runtime.
# Values: docker | podman
MCP_SANDBOX_RUNTIME=docker
# DESCRIPTION: Workspace mount point inside the container.
MCP_SANDBOX_CONTAINER_WORKSPACE=/workspace
# DESCRIPTION: Mount the host workspace into the container.
# Values: true | false
MCP_SANDBOX_MOUNT_WORKSPACE=true
# DESCRIPTION: Allow network access from inside the sandbox.
# Values: true | false
MCP_SANDBOX_ALLOW_NETWORKING=false
# DESCRIPTION: Docker network mode.
# Values: none | bridge | host | <custom>
MCP_SANDBOX_NETWORK_MODE=none
# DESCRIPTION: Comma-separated env vars to forward into the sandbox.
MCP_SANDBOX_PASSTHROUGH_ENV=PATH,LANG,LC_ALL,TERM,HOME
# DESCRIPTION: Extra bind mounts (HOST:CONTAINER[:ro], comma-separated).
# MCP_SANDBOX_EXTRA_MOUNTS=/host/path:/container/path:ro
# DESCRIPTION: Timeout for a single MCP tool call (ms).
MCP_SANDBOX_TIMEOUT_MS=20000
# DESCRIPTION: Run as this user inside the container.
# MCP_SANDBOX_USER=node
# DESCRIPTION: Override container entrypoint.
# MCP_SANDBOX_ENTRYPOINT=/bin/sh
# DESCRIPTION: Reuse the same sandbox container across calls within a session.
# Values: true | false
MCP_SANDBOX_REUSE_SESSION=true
# DESCRIPTION: Mount the container root filesystem read-only.
# Values: true | false
MCP_SANDBOX_READ_ONLY_ROOT=false
# DESCRIPTION: Set --security-opt no-new-privileges.
# Values: true | false
MCP_SANDBOX_NO_NEW_PRIVILEGES=true
# DESCRIPTION: Linux capabilities to drop (comma-separated, or "ALL").
MCP_SANDBOX_DROP_CAPABILITIES=ALL
# DESCRIPTION: Linux capabilities to add back.
# MCP_SANDBOX_ADD_CAPABILITIES=NET_BIND_SERVICE
# DESCRIPTION: Container memory limit.
MCP_SANDBOX_MEMORY_LIMIT=512m
# DESCRIPTION: Container CPU limit (cores).
MCP_SANDBOX_CPU_LIMIT=1.0
# DESCRIPTION: Max PIDs inside the container.
MCP_SANDBOX_PIDS_LIMIT=100
# DESCRIPTION: How tool permissions are decided.
# Values: auto | allowlist | denylist | prompt
MCP_SANDBOX_PERMISSION_MODE=auto
# DESCRIPTION: Comma-separated tool names always allowed.
# MCP_SANDBOX_PERMISSION_ALLOW=tool1,tool2
# DESCRIPTION: Comma-separated tool names always denied.
# MCP_SANDBOX_PERMISSION_DENY=tool3,tool4
# DESCRIPTION: Single MCP servers.json manifest path.
# MCP_SERVER_MANIFEST=~/.claude/mcp/servers.json
# DESCRIPTION: Comma-separated directories scanned for MCP manifests.
MCP_MANIFEST_DIRS=~/.claude/mcp
# ==============================================================================
# 6. COMPRESSION & CACHING
# ==============================================================================
# DESCRIPTION: Master switch for the in-memory prompt cache.
# Values: true | false
PROMPT_CACHE_ENABLED=true
# DESCRIPTION: Max number of prompts to cache.
PROMPT_CACHE_MAX_ENTRIES=1000
# DESCRIPTION: Cache entry TTL (ms).
PROMPT_CACHE_TTL_MS=300000
# DESCRIPTION: Master switch for semantic (embedding-based) response cache.
# Values: true | false
SEMANTIC_CACHE_ENABLED=true
# DESCRIPTION: Cosine-similarity threshold for a cache hit.
SEMANTIC_CACHE_THRESHOLD=0.95
# DESCRIPTION: Max number of cached entries.
SEMANTIC_CACHE_MAX_ENTRIES=50
# DESCRIPTION: Cache entry TTL (ms).
SEMANTIC_CACHE_TTL_MS=300000
# DESCRIPTION: Enable TOON (token-optimized object notation) encoding for large structured payloads.
# Values: true | false
TOON_ENABLED=true
# DESCRIPTION: Minimum byte size before TOON encoding kicks in.
TOON_MIN_BYTES=4096
# DESCRIPTION: Continue without TOON on encoder failure instead of erroring.
# Values: true | false
TOON_FAIL_OPEN=true
# DESCRIPTION: Log per-request TOON savings stats.
# Values: true | false
TOON_LOG_STATS=true
# DESCRIPTION: Enable GCF (Graph Compact Format) encoding for large structured payloads.
# Drop-in alternative to TOON; takes precedence over TOON when enabled. Opt-in.
# Values: true | false
GCF_ENABLED=false
# DESCRIPTION: Minimum byte size before GCF encoding kicks in.
GCF_MIN_BYTES=4096
# DESCRIPTION: Continue without GCF on encoder failure instead of erroring.
# Values: true | false
GCF_FAIL_OPEN=true
# DESCRIPTION: Log per-request GCF savings stats.
# Values: true | false
GCF_LOG_STATS=true
# DESCRIPTION: Round-trip verify each encoding and keep the original JSON on any mismatch
# (makes the compression provably lossless per payload; adds one decode per converted blob).
# Values: true | false
GCF_VERIFY=true
# DESCRIPTION: Master switch for Headroom sidecar context compression.
# Values: true | false
HEADROOM_ENABLED=true
# DESCRIPTION: Headroom sidecar endpoint.
HEADROOM_ENDPOINT=http://localhost:8787
# DESCRIPTION: Sidecar request timeout in ms.
HEADROOM_TIMEOUT_MS=5000
# DESCRIPTION: Skip compression below this estimated token count.
HEADROOM_MIN_TOKENS=100
# DESCRIPTION: Operating mode.
# Values: audit (observe only) | optimize (apply)
HEADROOM_MODE=optimize
# DESCRIPTION: Provider hint that selects which cache markers to emit.
# Values: anthropic | openai | google
HEADROOM_PROVIDER=anthropic
# DESCRIPTION: Sidecar log level.
# Values: debug | info | warning | error
HEADROOM_LOG_LEVEL=info
# DESCRIPTION: Auto-manage a Docker container for the sidecar.
# Values: true | false
HEADROOM_DOCKER_ENABLED=true
# DESCRIPTION: Sidecar image name.
HEADROOM_DOCKER_IMAGE=lynkr/headroom-sidecar:latest
# DESCRIPTION: Sidecar container name.
HEADROOM_DOCKER_CONTAINER_NAME=lynkr-headroom
# DESCRIPTION: Host port the sidecar publishes on.
HEADROOM_DOCKER_PORT=8787
# DESCRIPTION: Sidecar memory limit.
HEADROOM_DOCKER_MEMORY_LIMIT=512m
# DESCRIPTION: Sidecar CPU limit.
HEADROOM_DOCKER_CPU_LIMIT=1.0
# DESCRIPTION: Docker restart policy for the sidecar.
HEADROOM_DOCKER_RESTART_POLICY=unless-stopped
# DESCRIPTION: Optional Docker network the sidecar joins.
# HEADROOM_DOCKER_NETWORK=lynkr-network
# DESCRIPTION: Build context path when auto-building the sidecar image.
HEADROOM_DOCKER_BUILD_CONTEXT=./headroom-sidecar
# DESCRIPTION: Auto-build the image if not found locally.
# Values: true | false
HEADROOM_DOCKER_AUTO_BUILD=true
# DESCRIPTION: Smart-crusher transform (compress large text blocks).
# Values: true | false
HEADROOM_SMART_CRUSHER=true
# DESCRIPTION: Min token count before smart-crusher engages.
HEADROOM_SMART_CRUSHER_MIN_TOKENS=200
# DESCRIPTION: Max items the smart-crusher processes per request.
HEADROOM_SMART_CRUSHER_MAX_ITEMS=15
# DESCRIPTION: Tool-crusher transform (compress large tool results).
# Values: true | false
HEADROOM_TOOL_CRUSHER=true
# DESCRIPTION: Cache-aligner transform (align cache breakpoints).
# Values: true | false
HEADROOM_CACHE_ALIGNER=true
# DESCRIPTION: Rolling-window transform (keep newest N turns intact).
# Values: true | false
HEADROOM_ROLLING_WINDOW=true
# DESCRIPTION: How many recent turns the rolling window keeps verbatim.
HEADROOM_KEEP_TURNS=10
# DESCRIPTION: CCR (Compress-Cache-Retrieve) mode.
# Values: true | false
HEADROOM_CCR=true
# DESCRIPTION: TTL for CCR cached chunks (seconds).
HEADROOM_CCR_TTL=300
# DESCRIPTION: LLMLingua ML compression (requires GPU).
# Values: true | false
HEADROOM_LLMLINGUA=false
# DESCRIPTION: Device for LLMLingua model.
# Values: auto | cpu | cuda | mps
HEADROOM_LLMLINGUA_DEVICE=auto
# DESCRIPTION: TencentDB-Agent-Memory sidecar (team memory hub: L0-L3 chat
# memory, Skills, Wiki, CodeGraph). When enabled, `lynkr start` launches the
# memory-core + memory-hub containers from Docker Hub (agentmemory/*) — same
# pattern as the Headroom sidecar. Panel UI: http://localhost:8125
# Requires Docker (skips gracefully if unavailable). Containers persist
# across Lynkr restarts (remove with: docker rm -f tdai-memory-core tdai-memory-hub).
# Values: true | false
TENCENTDB_MEMORY_ENABLED=true
# DESCRIPTION: Let Lynkr manage the containers. Set false if you run the
# stack yourself via the project's deploy scripts.
# Values: true | false
# TENCENTDB_MEMORY_DOCKER_ENABLED=true
# DESCRIPTION: LLM endpoint the memory services use for extraction and wiki
# ingest. Defaults to Lynkr's own OpenAI-compatible endpoint (tier routing
# picks the model), so no extra API key is needed. Override to point at a
# provider directly.
# TENCENTDB_MEMORY_LLM_BASE_URL=http://host.docker.internal:8081/v1
# TENCENTDB_MEMORY_LLM_API_KEY=lynkr-local
# TENCENTDB_MEMORY_LLM_MODEL=auto
# DESCRIPTION: Memory extraction style. `code` extracts changes/issues/tool
# usage (coding agents); `chat` extracts general conversational facts.
# Values: code | chat
# TENCENTDB_MEMORY_PROMPT_MODE=code
# DESCRIPTION: Host port overrides (defaults shown).
# TENCENTDB_MEMORY_CORE_PORT=8420
# TENCENTDB_MEMORY_PANEL_PORT=8125
# TENCENTDB_MEMORY_KNOWLEDGE_PORT=8424
# DESCRIPTION: Master switch for the long-term Titans-inspired memory system.
# Values: true | false
MEMORY_ENABLED=true
# DESCRIPTION: Max memories retrieved per request.
MEMORY_RETRIEVAL_LIMIT=5
# DESCRIPTION: Surprise threshold above which a turn is written to memory.
MEMORY_SURPRISE_THRESHOLD=0.3
# DESCRIPTION: Hard cap on memory age (days).
MEMORY_MAX_AGE_DAYS=90
# DESCRIPTION: Hard cap on total memory count.
MEMORY_MAX_COUNT=10000
# DESCRIPTION: Include cross-session global memories.
# Values: true | false
MEMORY_INCLUDE_GLOBAL=true
# DESCRIPTION: How retrieved memories are injected.
# Values: system | user | assistant
MEMORY_INJECTION_FORMAT=system
# DESCRIPTION: Auto-extract memories from turns.
# Values: true | false
MEMORY_EXTRACTION_ENABLED=true
# DESCRIPTION: Apply time-based decay to memory scores.
# Values: true | false
MEMORY_DECAY_ENABLED=true
# DESCRIPTION: Half-life for memory decay (days).
MEMORY_DECAY_HALF_LIFE=30
# DESCRIPTION: Memory rendering format.
# Values: compact | verbose | json
MEMORY_FORMAT=compact
# DESCRIPTION: Dedupe memories before injection.
# Values: true | false
MEMORY_DEDUP_ENABLED=true
# DESCRIPTION: Turns of history to scan for dedup.
MEMORY_DEDUP_LOOKBACK=5
# DESCRIPTION: Track input/output tokens per request.
# Values: true | false
TOKEN_TRACKING_ENABLED=true
# DESCRIPTION: System prompt rendering strategy.
# Values: dynamic | static | minimal
SYSTEM_PROMPT_MODE=dynamic
# DESCRIPTION: How verbose tool descriptions are.
# Values: minimal | normal | verbose
TOOL_DESCRIPTIONS=minimal
# DESCRIPTION: Summarize older history turns instead of dropping them.
# Values: true | false
HISTORY_COMPRESSION_ENABLED=true
# DESCRIPTION: How many recent turns to keep verbatim.
HISTORY_KEEP_RECENT_TURNS=10
# DESCRIPTION: Summarize history older than the recent window.
# Values: true | false
HISTORY_SUMMARIZE_OLDER=true
# DESCRIPTION: Token budget that triggers a "you're approaching the limit" warning.
TOKEN_BUDGET_WARNING=100000
# DESCRIPTION: Hard token budget ceiling.
TOKEN_BUDGET_MAX=180000
# DESCRIPTION: Refuse requests over TOKEN_BUDGET_MAX instead of warning.
# Values: true | false
TOKEN_BUDGET_ENFORCEMENT=true
# DESCRIPTION: Caveman terse-output injection (cuts output tokens at the cost of style).
# Values: true | false
CAVEMAN_ENABLED=false
# DESCRIPTION: Aggressiveness of the brevity instruction.
# Values: lite | full | ultra
CAVEMAN_LEVEL=lite
# DESCRIPTION: Render markdown to ANSI for CLIs without a markdown renderer.
# Leave false for Claude Code (it renders markdown itself).
# Values: true | false
MARKDOWN_RENDER_ANSI=false
# ==============================================================================
# 7. POLICY & SAFETY
# ==============================================================================
# DESCRIPTION: Hard cap on routing/tool-call steps per request.
POLICY_MAX_STEPS=20
# DESCRIPTION: Hard cap on tool calls per request.
POLICY_MAX_TOOL_CALLS=12
# DESCRIPTION: Force-terminate after this many same-tool calls in a row (loop guard).
POLICY_TOOL_LOOP_THRESHOLD=10
# DESCRIPTION: Comma-separated tool names that are never allowed.
# POLICY_DISALLOWED_TOOLS=dangerous_tool1,dangerous_tool2
# DESCRIPTION: Allow `git push`.
# Values: true | false
POLICY_GIT_ALLOW_PUSH=false
# DESCRIPTION: Allow `git pull`.
# Values: true | false
POLICY_GIT_ALLOW_PULL=true
# DESCRIPTION: Allow `git commit`.
# Values: true | false
POLICY_GIT_ALLOW_COMMIT=true
# DESCRIPTION: Test command run before allowing a commit (when REQUIRE_TESTS=true).
# POLICY_GIT_TEST_COMMAND=npm test
# DESCRIPTION: Refuse commits unless POLICY_GIT_TEST_COMMAND passes.
# Values: true | false
POLICY_GIT_REQUIRE_TESTS=false
# DESCRIPTION: Regex that commit messages must match.
# POLICY_GIT_COMMIT_REGEX=^(feat|fix|docs|style|refactor|test|chore):
# DESCRIPTION: Auto-stash uncommitted changes before risky git operations.
# Values: true | false
POLICY_GIT_AUTOSTASH=false
# DESCRIPTION: Comma-separated paths that file tools may touch (allowlist).
# POLICY_FILE_ALLOWED_PATHS=/path1,/path2
# DESCRIPTION: Comma-separated paths that file tools may NOT touch.
POLICY_FILE_BLOCKED_PATHS=/.env,.env,/etc/passwd,/etc/shadow
# DESCRIPTION: Apply the safe-commands allowlist to bash tool calls.
# Values: true | false
POLICY_SAFE_COMMANDS_ENABLED=true
# DESCRIPTION: JSON config for the safe-commands allowlist.
# POLICY_SAFE_COMMANDS_CONFIG={"allowed":["ls","cat","grep"]}
# DESCRIPTION: Master switch for the security content filter.
# Values: true | false
SECURITY_CONTENT_FILTER_ENABLED=true
# DESCRIPTION: Block requests when the filter triggers (vs. just log).
# Values: true | false
SECURITY_BLOCK_ON_DETECTION=true
# DESCRIPTION: Master switch for the security rate limiter.
# Values: true | false
SECURITY_RATE_LIMIT_ENABLED=true
# DESCRIPTION: Per-IP request cap per minute.
SECURITY_PER_IP_LIMIT=100
# DESCRIPTION: Per-endpoint request cap per minute.
SECURITY_PER_ENDPOINT_LIMIT=1000
# DESCRIPTION: Persist security events to disk.
# Values: true | false
SECURITY_AUDIT_LOG_ENABLED=true
# DESCRIPTION: Directory for the security audit log.
SECURITY_AUDIT_LOG_DIR=./logs
# ==============================================================================
# 8. AGENTS
# ==============================================================================
# DESCRIPTION: Inject agent-delegation instructions into the system prompt
# when the client declares a Task tool (tools always execute on the client).
# Values: true | false
AGENTS_ENABLED=true
# ==============================================================================
# 9. RATE LIMITING & BUDGETS
# ==============================================================================
# DESCRIPTION: Master switch for the per-session rate limiter.
# Values: true | false
RATE_LIMIT_ENABLED=true
# DESCRIPTION: Sliding window length (ms).
RATE_LIMIT_WINDOW_MS=60000
# DESCRIPTION: Max requests per window.
RATE_LIMIT_MAX=100
# DESCRIPTION: How requests are bucketed.
# Values: session | ip | both
RATE_LIMIT_KEY_BY=session
# ==============================================================================
# 10. WEB TOOLS
# ==============================================================================
# DESCRIPTION: Endpoint for the WebSearch tool (often a local SearXNG instance).
WEB_SEARCH_ENDPOINT=http://localhost:8888/search
# DESCRIPTION: Bearer token for the search endpoint.
# WEB_SEARCH_API_KEY=your-search-key
# DESCRIPTION: Allow searching any host (overrides the allowlist).
# Values: true | false
WEB_SEARCH_ALLOW_ALL=true
# DESCRIPTION: Comma-separated allowlist of search hosts.
# WEB_SEARCH_ALLOWED_HOSTS=localhost,127.0.0.1
# DESCRIPTION: Per-search timeout (ms).
WEB_SEARCH_TIMEOUT_MS=10000
# DESCRIPTION: Retry failed searches.
# Values: true | false
WEB_SEARCH_RETRY_ENABLED=true
# DESCRIPTION: Max retry attempts on failure.
WEB_SEARCH_MAX_RETRIES=2
# DESCRIPTION: Max bytes of page body shown in WebFetch results.
WEB_FETCH_BODY_PREVIEW_MAX=10000
# DESCRIPTION: TinyFish.ai API key (enables the WebAgent browser-automation tool).
# TINYFISH_API_KEY=sk-tinyfish-your-key
# DESCRIPTION: TinyFish automation endpoint.
TINYFISH_ENDPOINT=https://agent.tinyfish.ai/v1/automation/run-sse
# DESCRIPTION: Browser profile preset.
# Values: lite | standard | stealth
TINYFISH_BROWSER_PROFILE=lite
# DESCRIPTION: Per-run timeout (ms).
TINYFISH_TIMEOUT_MS=120000
# DESCRIPTION: Route the browser through a residential proxy.
# Values: true | false
TINYFISH_PROXY_ENABLED=false
# DESCRIPTION: Proxy egress country (ISO 3166 alpha-2).
TINYFISH_PROXY_COUNTRY=US
# ==============================================================================
# 11. WORKSPACE / TEST RUNNER
# ==============================================================================
# DESCRIPTION: Test command the workspace runner invokes.
# WORKSPACE_TEST_COMMAND=npm test
# DESCRIPTION: Extra args appended to the test command.
# WORKSPACE_TEST_ARGS=--coverage
# DESCRIPTION: Test timeout (ms).
WORKSPACE_TEST_TIMEOUT_MS=600000
# DESCRIPTION: How tests are sandboxed.
# Values: auto | docker | none
WORKSPACE_TEST_SANDBOX=auto
# DESCRIPTION: Coverage report paths the runner picks up.
WORKSPACE_TEST_COVERAGE_FILES=coverage/coverage-summary.json
# DESCRIPTION: JSON array of named test profiles.
# WORKSPACE_TEST_PROFILES=[{"name":"unit","command":"npm test"}]
# DESCRIPTION: Storage path for the Files tool.
FILES_STORAGE_PATH=./data/files
# DESCRIPTION: Max stored files (LRU cap).
FILES_MAX_COUNT=1000
# DESCRIPTION: Max per-file size in MB.
FILES_MAX_SIZE_MB=100
# ==============================================================================
# 12. OBSERVABILITY (audit, error logs)
# ==============================================================================
# DESCRIPTION: Master switch for the LLM audit log.
# Values: true | false
LLM_AUDIT_ENABLED=false
# DESCRIPTION: Audit log file path.
# LLM_AUDIT_LOG_FILE=./logs/llm-audit.log
# DESCRIPTION: Include audit annotations on each entry.
# Values: true | false
LLM_AUDIT_ANNOTATIONS=true
# DESCRIPTION: Max system-prompt chars retained per audit entry.
LLM_AUDIT_MAX_SYSTEM_LENGTH=2000
# DESCRIPTION: Max user-message chars retained per audit entry.
LLM_AUDIT_MAX_USER_LENGTH=3000
# DESCRIPTION: Max response chars retained per audit entry.
LLM_AUDIT_MAX_RESPONSE_LENGTH=3000
# DESCRIPTION: Legacy fallback for max content length.
LLM_AUDIT_MAX_CONTENT_LENGTH=5000
# DESCRIPTION: Rotated audit file count.
LLM_AUDIT_MAX_FILES=30
# DESCRIPTION: Per-file rotation size.
LLM_AUDIT_MAX_SIZE=100M
# DESCRIPTION: Deduplicate repeated audit payloads via dictionary compression.
# Values: true | false
LLM_AUDIT_DEDUP_ENABLED=true
# DESCRIPTION: Path to the dedup dictionary file.
# LLM_AUDIT_DEDUP_DICT_PATH=./logs/llm-audit-dictionary.jsonl
# DESCRIPTION: LRU cache size for the dedup dictionary.
LLM_AUDIT_DEDUP_CACHE_SIZE=100
# DESCRIPTION: Smallest payload size (bytes) eligible for dedup.
LLM_AUDIT_DEDUP_MIN_SIZE=500
# DESCRIPTION: Sanitize secrets out of dedup-eligible payloads.
# Values: true | false
LLM_AUDIT_DEDUP_SANITIZE=true
# DESCRIPTION: Cache dedup state per session.
# Values: true | false
LLM_AUDIT_DEDUP_SESSION_CACHE=true
# DESCRIPTION: Persist oversized-payload errors to disk.
# Values: true | false
OVERSIZED_ERROR_LOGGING_ENABLED=true
# DESCRIPTION: Bytes above which a payload is considered "oversized".
OVERSIZED_ERROR_THRESHOLD=200
# DESCRIPTION: Where oversized-error dumps go.
OVERSIZED_ERROR_LOG_DIR=./logs/oversized-errors
# DESCRIPTION: Max retained oversized-error dump files.
OVERSIZED_ERROR_MAX_FILES=100
# ==============================================================================
# 13. HOT RELOAD
# ==============================================================================
# DESCRIPTION: Hot-reload config when .env changes.
# Values: true | false
HOT_RELOAD_ENABLED=true
# DESCRIPTION: Debounce window for the reload watcher (ms).
HOT_RELOAD_DEBOUNCE_MS=1000
# ==============================================================================
# 14. CLUSTERING & LOAD SHEDDING
# ==============================================================================
# DESCRIPTION: Run the proxy in multi-worker cluster mode.
# Values: true | false
CLUSTER_ENABLED=false
# DESCRIPTION: Worker count.
# Values: auto | <integer>
CLUSTER_WORKERS=auto
# DESCRIPTION: Heap-utilization fraction above which load shedding triggers.
LOAD_SHEDDING_HEAP_THRESHOLD=0.95
# DESCRIPTION: RSS-memory fraction above which load shedding triggers.
LOAD_SHEDDING_MEMORY_THRESHOLD=0.85
# DESCRIPTION: In-flight request count above which load shedding triggers.
LOAD_SHEDDING_ACTIVE_REQUESTS_THRESHOLD=1000
# DESCRIPTION: Master switch for the worker thread pool (heavy parsing, embeddings).
# Values: true | false
WORKER_POOL_ENABLED=true
# DESCRIPTION: Worker pool size. 0 = auto (CPU cores - 1).
WORKER_POOL_SIZE=0
# DESCRIPTION: Per-task timeout (ms).
WORKER_TASK_TIMEOUT_MS=5000
# DESCRIPTION: Payload size (bytes) above which work is offloaded to the pool.
WORKER_OFFLOAD_THRESHOLD_BYTES=10000
# DESCRIPTION: Large-payload optimization (chunked encoding, streaming).