-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathlemmacomputer-claude-config.py
More file actions
92 lines (85 loc) · 4 KB
/
Copy pathlemmacomputer-claude-config.py
File metadata and controls
92 lines (85 loc) · 4 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
#!/usr/bin/env python3
"""Write Claude Desktop's root-owned LemmaComputer managed settings."""
import json
import os
import sys
def main() -> None:
if len(sys.argv) != 9:
raise SystemExit(
"usage: lemmacomputer-claude-config PATH MODEL TRANSPORT_MODEL "
"SERVICE_CLASS ALLOWED_SERVICE_CLASSES LABEL COWORK_ENABLED CODE_ENABLED"
)
path, model, transport_model, default_service_class, allowed_value, label, cowork_enabled, code_enabled = sys.argv[1:]
allowed_service_classes = [value for value in allowed_value.split(",") if value]
if not allowed_service_classes or any(value not in {"lite", "balanced", "pro"} for value in allowed_service_classes):
raise SystemExit("invalid allowed Claude model modes")
if default_service_class == "auto":
default_service_class = "balanced" if "balanced" in allowed_service_classes else allowed_service_classes[0]
if default_service_class not in {"lite", "balanced", "pro"}:
raise SystemExit("invalid Claude model mode")
if default_service_class not in allowed_service_classes:
raise SystemExit("default Claude model mode is not allowed")
if transport_model == "lemmacomputer-auto":
# Claude Desktop 1.22209.3 rejects gateway model IDs that do not look
# Anthropic-owned before it opens Cowork, and exposes its independent
# effort control only for exact built-in capability IDs. Its pinned
# normalizer removes a trailing release date, so these three distinct
# client-adapter IDs all resolve to the qualified sonnet-4-6 UI
# capability without selecting an Anthropic provider route. The
# loopback broker maps the exact IDs only to provider-neutral
# LemmaComputer service classes.
modes = [
("claude-sonnet-4-6-20260101", "Lite — organization route", "lite"),
("claude-sonnet-4-6-20260102", "Balanced — organization route", "balanced"),
("claude-sonnet-4-6-20260103", "Pro — organization route", "pro"),
]
modes = [item for item in modes if item[2] in allowed_service_classes]
modes.sort(key=lambda item: item[2] != default_service_class)
inference_models = [{
"name": name,
"labelOverride": mode_label,
"anthropicFamilyTier": "sonnet",
"isFamilyDefault": service_class == default_service_class,
} for name, mode_label, service_class in modes]
else:
inference_models = [{
"name": model,
"labelOverride": label,
"anthropicFamilyTier": "sonnet",
"isFamilyDefault": True,
}]
document = {
"inferenceProvider": "gateway",
"inferenceGatewayBaseUrl": "http://127.0.0.1:4312",
"inferenceGatewayApiKey": "lemmacomputer-loopback-broker",
"inferenceGatewayAuthScheme": "bearer",
"modelDiscoveryEnabled": False,
"inferenceModels": inference_models,
"disableDeploymentModeChooser": True,
"disableDeepLinkRegistration": True,
"chatTabEnabled": True,
"chatAdvancedFileAnalysisEnabled": False,
"isClaudeCodeForDesktopEnabled": code_enabled == "true",
"coworkTabEnabled": cowork_enabled == "true",
"secureVmFeaturesEnabled": cowork_enabled == "true",
"allowedWorkspaceFolders": ["/home/kasm-user"],
"disableBundledSkills": True,
"autoModeEnabled": False,
"toolSearchEnabled": False,
"managedMcpServers": [{
"name": "LemmaComputer connectors",
"transport": "stdio",
"command": "/usr/local/libexec/lemmacomputer-connectors-stdio",
"args": [],
}],
"isLocalDevMcpEnabled": False,
"isDesktopExtensionEnabled": False,
}
with open(path, "w", encoding="utf-8") as output:
json.dump(document, output, separators=(",", ":"))
output.write("\n")
os.chmod(path, 0o644)
if os.geteuid() == 0:
os.chown(path, 0, 0)
if __name__ == "__main__":
main()