oh-langfuse 0.1.78 → 0.1.79
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/bin/cli.js +30 -21
- package/codex_langfuse_notify.py +1 -1
- package/langfuse_hook.py +1 -1
- package/package.json +1 -1
- package/scripts/codex-langfuse-setup.mjs +25 -14
- package/scripts/langfuse-setup.mjs +27 -16
- package/scripts/opencode-langfuse-run.mjs +21 -10
- package/scripts/opencode-langfuse-setup.mjs +48 -22
- package/scripts/real-self-verify.mjs +21 -9
- package/scripts/update-langfuse-runtime.mjs +29 -12
package/bin/cli.js
CHANGED
|
@@ -9,8 +9,12 @@ import { resolveOpencodeCli } from "../scripts/resolve-opencode-cli.mjs";
|
|
|
9
9
|
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
10
10
|
const scriptsDir = path.join(rootDir, "scripts");
|
|
11
11
|
|
|
12
|
-
const DEFAULT_LANGFUSE_BASE_URL = "
|
|
13
|
-
const
|
|
12
|
+
const DEFAULT_LANGFUSE_BASE_URL = "https://metrics.openharmonyinsight.cn";
|
|
13
|
+
const LEGACY_LANGFUSE_BASE_URLS = new Set([
|
|
14
|
+
"http://120.46.221.227:3000",
|
|
15
|
+
"https://120.46.221.227:3000",
|
|
16
|
+
]);
|
|
17
|
+
const DEFAULT_LANGFUSE_PUBLIC_KEY = "pk-lf-da0c90a7-6e93-4eb7-bb86-c1047c8d187d";
|
|
14
18
|
const DEFAULT_LANGFUSE_SECRET_KEY = "sk-lf-0269b85d-bfdc-442c-bfa3-e737954e3315";
|
|
15
19
|
const USER_ID_PATTERN = /^[a-z](?:\d{8}|wx\d{7})$/;
|
|
16
20
|
const USER_ID_PATTERN_TEXT = "^[a-z](?:\\d{8}|wx\\d{7})$";
|
|
@@ -115,13 +119,18 @@ function mask(v) {
|
|
|
115
119
|
return `${v.slice(0, 4)}...${v.slice(-4)}`;
|
|
116
120
|
}
|
|
117
121
|
|
|
118
|
-
function hasValue(v) {
|
|
119
|
-
return typeof v === "string" && v.trim().length > 0;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
function hasValue(v) {
|
|
123
|
+
return typeof v === "string" && v.trim().length > 0;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function normalizeLegacyBaseUrl(baseUrl) {
|
|
127
|
+
const value = String(baseUrl || "").trim().replace(/\/+$/, "");
|
|
128
|
+
return LEGACY_LANGFUSE_BASE_URLS.has(value) ? DEFAULT_LANGFUSE_BASE_URL : baseUrl;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function normalizeUserId(v) {
|
|
132
|
+
return String(v || "").trim();
|
|
133
|
+
}
|
|
125
134
|
|
|
126
135
|
function isValidUserId(v) {
|
|
127
136
|
return USER_ID_PATTERN.test(normalizeUserId(v));
|
|
@@ -506,18 +515,18 @@ async function askMultiChoice(rl, label, choices, options = {}) {
|
|
|
506
515
|
.map((idx) => choices[idx].value);
|
|
507
516
|
}
|
|
508
517
|
|
|
509
|
-
function langfuseConfig(overrides = {}) {
|
|
510
|
-
const config = {
|
|
511
|
-
baseUrl: envDefault("LANGFUSE_BASEURL", envDefault("LANGFUSE_HOST", DEFAULT_LANGFUSE_BASE_URL)),
|
|
512
|
-
publicKey: envDefault("LANGFUSE_PUBLIC_KEY", DEFAULT_LANGFUSE_PUBLIC_KEY),
|
|
513
|
-
secretKey: envDefault("LANGFUSE_SECRET_KEY", DEFAULT_LANGFUSE_SECRET_KEY),
|
|
514
|
-
userId: ""
|
|
515
|
-
};
|
|
516
|
-
for (const [key, value] of Object.entries(overrides)) {
|
|
517
|
-
if (hasValue(value)) config[key] = value;
|
|
518
|
-
}
|
|
519
|
-
return config;
|
|
520
|
-
}
|
|
518
|
+
function langfuseConfig(overrides = {}) {
|
|
519
|
+
const config = {
|
|
520
|
+
baseUrl: normalizeLegacyBaseUrl(envDefault("LANGFUSE_BASEURL", envDefault("LANGFUSE_HOST", DEFAULT_LANGFUSE_BASE_URL))),
|
|
521
|
+
publicKey: envDefault("LANGFUSE_PUBLIC_KEY", DEFAULT_LANGFUSE_PUBLIC_KEY),
|
|
522
|
+
secretKey: envDefault("LANGFUSE_SECRET_KEY", DEFAULT_LANGFUSE_SECRET_KEY),
|
|
523
|
+
userId: ""
|
|
524
|
+
};
|
|
525
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
526
|
+
if (hasValue(value)) config[key] = key === "baseUrl" ? normalizeLegacyBaseUrl(value) : value;
|
|
527
|
+
}
|
|
528
|
+
return config;
|
|
529
|
+
}
|
|
521
530
|
|
|
522
531
|
async function collectLangfuseConfig(rl, { requireUserId = false, overrides = {} } = {}) {
|
|
523
532
|
const config = langfuseConfig(overrides);
|
package/codex_langfuse_notify.py
CHANGED
|
@@ -1516,7 +1516,7 @@ def main() -> int:
|
|
|
1516
1516
|
or os.environ.get("LANGFUSE_BASEURL")
|
|
1517
1517
|
or os.environ.get("LANGFUSE_HOST")
|
|
1518
1518
|
or config.get("baseUrl")
|
|
1519
|
-
or "https://
|
|
1519
|
+
or "https://metrics.openharmonyinsight.cn"
|
|
1520
1520
|
)
|
|
1521
1521
|
user_id = (
|
|
1522
1522
|
find_value(payload, ("user_id", "userId", "username", "userName"))
|
package/langfuse_hook.py
CHANGED
|
@@ -1183,7 +1183,7 @@ def main() -> int:
|
|
|
1183
1183
|
|
|
1184
1184
|
public_key = os.environ.get("CC_LANGFUSE_PUBLIC_KEY") or os.environ.get("LANGFUSE_PUBLIC_KEY")
|
|
1185
1185
|
secret_key = os.environ.get("CC_LANGFUSE_SECRET_KEY") or os.environ.get("LANGFUSE_SECRET_KEY")
|
|
1186
|
-
host = os.environ.get("CC_LANGFUSE_BASE_URL") or os.environ.get("LANGFUSE_BASEURL") or "https://
|
|
1186
|
+
host = os.environ.get("CC_LANGFUSE_BASE_URL") or os.environ.get("LANGFUSE_BASEURL") or "https://metrics.openharmonyinsight.cn"
|
|
1187
1187
|
|
|
1188
1188
|
if not public_key or not secret_key:
|
|
1189
1189
|
warn("Missing Langfuse public/secret key in hook environment; exiting.")
|
package/package.json
CHANGED
|
@@ -7,13 +7,23 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
import { defaultWindowsNpmCliCandidates, listSystemCliCandidates } from "./cli-detection-utils.mjs";
|
|
8
8
|
import { writeRuntimeInstallRecord } from "./runtime-state-utils.mjs";
|
|
9
9
|
|
|
10
|
-
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
10
|
+
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
|
+
const DEFAULT_LANGFUSE_BASE_URL = "https://metrics.openharmonyinsight.cn";
|
|
12
|
+
const LEGACY_LANGFUSE_BASE_URLS = new Set([
|
|
13
|
+
"http://120.46.221.227:3000",
|
|
14
|
+
"https://120.46.221.227:3000",
|
|
15
|
+
]);
|
|
16
|
+
const USER_ID_PATTERN = /^[a-z](?:\d{8}|wx\d{7})$/;
|
|
17
|
+
const USER_ID_PATTERN_TEXT = "^[a-z](?:\\d{8}|wx\\d{7})$";
|
|
18
|
+
|
|
19
|
+
function normalizeLegacyBaseUrl(baseUrl) {
|
|
20
|
+
const value = String(baseUrl || "").trim().replace(/\/+$/, "");
|
|
21
|
+
return LEGACY_LANGFUSE_BASE_URLS.has(value) ? DEFAULT_LANGFUSE_BASE_URL : baseUrl;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function normalizeUserId(v) {
|
|
25
|
+
return String(v || "").trim();
|
|
26
|
+
}
|
|
17
27
|
|
|
18
28
|
function assertValidUserId(userId) {
|
|
19
29
|
if (!USER_ID_PATTERN.test(normalizeUserId(userId))) {
|
|
@@ -463,13 +473,14 @@ async function main() {
|
|
|
463
473
|
args.publicKey || process.env.LANGFUSE_PUBLIC_KEY || "pk-lf-da0c90a7-6e93-4eb7-bb86-c1047c8d187d";
|
|
464
474
|
const secretKey =
|
|
465
475
|
args.secretKey || process.env.LANGFUSE_SECRET_KEY || "sk-lf-0269b85d-bfdc-442c-bfa3-e737954e3315";
|
|
466
|
-
const baseUrl =
|
|
467
|
-
args.langfuseBaseUrl ||
|
|
468
|
-
args.langfuseHost ||
|
|
469
|
-
args.host ||
|
|
470
|
-
process.env.LANGFUSE_BASEURL ||
|
|
471
|
-
process.env.LANGFUSE_HOST ||
|
|
472
|
-
|
|
476
|
+
const baseUrl = normalizeLegacyBaseUrl(
|
|
477
|
+
args.langfuseBaseUrl ||
|
|
478
|
+
args.langfuseHost ||
|
|
479
|
+
args.host ||
|
|
480
|
+
process.env.LANGFUSE_BASEURL ||
|
|
481
|
+
process.env.LANGFUSE_HOST ||
|
|
482
|
+
DEFAULT_LANGFUSE_BASE_URL
|
|
483
|
+
);
|
|
473
484
|
const userId = normalizeUserId(args.userId || args.userid || "");
|
|
474
485
|
if (!userId || typeof userId !== "string") {
|
|
475
486
|
throw new Error("缺少参数:--userId=你的工号");
|
|
@@ -7,15 +7,25 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
import { defaultWindowsNpmCliCandidates, listSystemCliCandidates } from "./cli-detection-utils.mjs";
|
|
8
8
|
import { writeRuntimeInstallRecord } from "./runtime-state-utils.mjs";
|
|
9
9
|
|
|
10
|
-
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
|
-
const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
10
|
+
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
|
|
12
|
+
|
|
13
|
+
const DEFAULT_LANGFUSE_BASE_URL = "https://metrics.openharmonyinsight.cn";
|
|
14
|
+
const LEGACY_LANGFUSE_BASE_URLS = new Set([
|
|
15
|
+
"http://120.46.221.227:3000",
|
|
16
|
+
"https://120.46.221.227:3000",
|
|
17
|
+
]);
|
|
18
|
+
const USER_ID_PATTERN = /^[a-z](?:\d{8}|wx\d{7})$/;
|
|
19
|
+
const USER_ID_PATTERN_TEXT = "^[a-z](?:\\d{8}|wx\\d{7})$";
|
|
20
|
+
|
|
21
|
+
function normalizeLegacyBaseUrl(baseUrl) {
|
|
22
|
+
const value = String(baseUrl || "").trim().replace(/\/+$/, "");
|
|
23
|
+
return LEGACY_LANGFUSE_BASE_URLS.has(value) ? DEFAULT_LANGFUSE_BASE_URL : baseUrl;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function normalizeUserId(v) {
|
|
27
|
+
return String(v || "").trim();
|
|
28
|
+
}
|
|
19
29
|
|
|
20
30
|
function assertValidUserId(userId) {
|
|
21
31
|
if (!USER_ID_PATTERN.test(normalizeUserId(userId))) {
|
|
@@ -473,13 +483,14 @@ async function main() {
|
|
|
473
483
|
}
|
|
474
484
|
assertValidUserId(userId);
|
|
475
485
|
|
|
476
|
-
const langfuseHost =
|
|
477
|
-
args.langfuseBaseUrl ||
|
|
478
|
-
args.langfuseHost ||
|
|
479
|
-
args.host ||
|
|
480
|
-
process.env.LANGFUSE_BASEURL ||
|
|
481
|
-
process.env.LANGFUSE_HOST ||
|
|
482
|
-
|
|
486
|
+
const langfuseHost = normalizeLegacyBaseUrl(
|
|
487
|
+
args.langfuseBaseUrl ||
|
|
488
|
+
args.langfuseHost ||
|
|
489
|
+
args.host ||
|
|
490
|
+
process.env.LANGFUSE_BASEURL ||
|
|
491
|
+
process.env.LANGFUSE_HOST ||
|
|
492
|
+
DEFAULT_LANGFUSE_BASE_URL
|
|
493
|
+
);
|
|
483
494
|
|
|
484
495
|
const publicKey =
|
|
485
496
|
args.publicKey || process.env.LANGFUSE_PUBLIC_KEY || "pk-lf-da0c90a7-6e93-4eb7-bb86-c1047c8d187d";
|
|
@@ -3,12 +3,22 @@ import { fileURLToPath } from "node:url";
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
4
|
import { resolveOpencodeCli } from "./resolve-opencode-cli.mjs";
|
|
5
5
|
|
|
6
|
-
const USER_ID_PATTERN = /^[a-z](?:\d{8}|wx\d{7})$/;
|
|
7
|
-
const USER_ID_PATTERN_TEXT = "^[a-z](?:\\d{8}|wx\\d{7})$";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
const USER_ID_PATTERN = /^[a-z](?:\d{8}|wx\d{7})$/;
|
|
7
|
+
const USER_ID_PATTERN_TEXT = "^[a-z](?:\\d{8}|wx\\d{7})$";
|
|
8
|
+
const DEFAULT_LANGFUSE_BASE_URL = "https://metrics.openharmonyinsight.cn";
|
|
9
|
+
const LEGACY_LANGFUSE_BASE_URLS = new Set([
|
|
10
|
+
"http://120.46.221.227:3000",
|
|
11
|
+
"https://120.46.221.227:3000",
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
function normalizeLegacyBaseUrl(baseUrl) {
|
|
15
|
+
const value = String(baseUrl || "").trim().replace(/\/+$/, "");
|
|
16
|
+
return LEGACY_LANGFUSE_BASE_URLS.has(value) ? DEFAULT_LANGFUSE_BASE_URL : baseUrl;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function normalizeUserId(v) {
|
|
20
|
+
return String(v || "").trim();
|
|
21
|
+
}
|
|
12
22
|
|
|
13
23
|
function assertValidUserId(userId) {
|
|
14
24
|
if (!USER_ID_PATTERN.test(normalizeUserId(userId))) {
|
|
@@ -42,7 +52,7 @@ function main() {
|
|
|
42
52
|
args.publicKey || process.env.LANGFUSE_PUBLIC_KEY || "pk-lf-da0c90a7-6e93-4eb7-bb86-c1047c8d187d";
|
|
43
53
|
const secretKey =
|
|
44
54
|
args.secretKey || process.env.LANGFUSE_SECRET_KEY || "sk-lf-0269b85d-bfdc-442c-bfa3-e737954e3315";
|
|
45
|
-
const baseUrl = args.langfuseBaseUrl || process.env.LANGFUSE_BASEURL ||
|
|
55
|
+
const baseUrl = normalizeLegacyBaseUrl(args.langfuseBaseUrl || process.env.LANGFUSE_BASEURL || DEFAULT_LANGFUSE_BASE_URL);
|
|
46
56
|
const userId = normalizeUserId(args.userId || args.userid || "");
|
|
47
57
|
if (!userId) {
|
|
48
58
|
throw new Error("Missing userId. Run with --userId=your-id.");
|
|
@@ -54,9 +64,10 @@ function main() {
|
|
|
54
64
|
const setupPath = path.join(scriptsDir, "opencode-langfuse-setup.mjs");
|
|
55
65
|
const setupExtra = [];
|
|
56
66
|
if (args["no-set-env"]) setupExtra.push("--no-set-env");
|
|
57
|
-
if (args["skip-plugin-install"]) setupExtra.push("--skip-plugin-install");
|
|
58
|
-
if (userId) setupExtra.push(`--userId=${userId}`);
|
|
59
|
-
|
|
67
|
+
if (args["skip-plugin-install"]) setupExtra.push("--skip-plugin-install");
|
|
68
|
+
if (userId) setupExtra.push(`--userId=${userId}`);
|
|
69
|
+
setupExtra.push(`--langfuseBaseUrl=${baseUrl}`);
|
|
70
|
+
runNodeScript(setupPath, setupExtra);
|
|
60
71
|
|
|
61
72
|
// 2) 直接带环境变量启动 opencode(本进程内有效)
|
|
62
73
|
const cmdArg = args.cmd || "opencode";
|
|
@@ -8,14 +8,24 @@ import { shouldSuppressAgentLogLine } from "./log-filter-utils.mjs";
|
|
|
8
8
|
import { writeRuntimeInstallRecord } from "./runtime-state-utils.mjs";
|
|
9
9
|
import { resolveOpencodeCli } from "./resolve-opencode-cli.mjs";
|
|
10
10
|
|
|
11
|
-
const USER_ID_PATTERN = /^[a-z](?:\d{8}|wx\d{7})$/;
|
|
12
|
-
const USER_ID_PATTERN_TEXT = "^[a-z](?:\\d{8}|wx\\d{7})$";
|
|
13
|
-
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
14
|
-
const packageJson = JSON.parse(fs.readFileSync(path.join(rootDir, "package.json"), "utf8"));
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
const USER_ID_PATTERN = /^[a-z](?:\d{8}|wx\d{7})$/;
|
|
12
|
+
const USER_ID_PATTERN_TEXT = "^[a-z](?:\\d{8}|wx\\d{7})$";
|
|
13
|
+
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
14
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(rootDir, "package.json"), "utf8"));
|
|
15
|
+
const DEFAULT_LANGFUSE_BASE_URL = "https://metrics.openharmonyinsight.cn";
|
|
16
|
+
const LEGACY_LANGFUSE_BASE_URLS = new Set([
|
|
17
|
+
"http://120.46.221.227:3000",
|
|
18
|
+
"https://120.46.221.227:3000",
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
function normalizeLegacyBaseUrl(baseUrl) {
|
|
22
|
+
const value = String(baseUrl || "").trim().replace(/\/+$/, "");
|
|
23
|
+
return LEGACY_LANGFUSE_BASE_URLS.has(value) ? DEFAULT_LANGFUSE_BASE_URL : baseUrl;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function normalizeUserId(v) {
|
|
27
|
+
return String(v || "").trim();
|
|
28
|
+
}
|
|
19
29
|
|
|
20
30
|
function assertValidUserId(userId) {
|
|
21
31
|
if (!USER_ID_PATTERN.test(normalizeUserId(userId))) {
|
|
@@ -709,7 +719,7 @@ export function getPatchedLangfuseDistIndexJs() {
|
|
|
709
719
|
"export const LangfusePlugin = async ({ client }) => {",
|
|
710
720
|
" const publicKey = process.env.LANGFUSE_PUBLIC_KEY;",
|
|
711
721
|
" const secretKey = process.env.LANGFUSE_SECRET_KEY;",
|
|
712
|
-
' const baseUrl = process.env.LANGFUSE_BASEURL ?? "https://
|
|
722
|
+
' const baseUrl = process.env.LANGFUSE_BASEURL ?? "https://metrics.openharmonyinsight.cn";',
|
|
713
723
|
' const environment = process.env.LANGFUSE_ENVIRONMENT ?? "development";',
|
|
714
724
|
"",
|
|
715
725
|
" const userIdFromConfig = await readConfiguredUserId();",
|
|
@@ -1036,7 +1046,7 @@ function windowsGitPathBootstrap() {
|
|
|
1036
1046
|
];
|
|
1037
1047
|
}
|
|
1038
1048
|
|
|
1039
|
-
function writeWindowsUpdateCheckScript(dir) {
|
|
1049
|
+
function writeWindowsUpdateCheckScript(dir) {
|
|
1040
1050
|
if (process.platform !== "win32") return null;
|
|
1041
1051
|
ensureDir(dir);
|
|
1042
1052
|
const p = path.join(dir, "oh-langfuse-opencode-update-check.ps1");
|
|
@@ -1055,10 +1065,25 @@ function writeWindowsUpdateCheckScript(dir) {
|
|
|
1055
1065
|
""
|
|
1056
1066
|
].join("\r\n");
|
|
1057
1067
|
fs.writeFileSync(p, "\ufeff" + ps, "utf8");
|
|
1058
|
-
return p;
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
function
|
|
1068
|
+
return p;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
function readRealOpencodeFromManagedShim(shimPath) {
|
|
1072
|
+
try {
|
|
1073
|
+
if (!shimPath || !fs.existsSync(shimPath)) return "";
|
|
1074
|
+
const text = fs.readFileSync(shimPath, "utf8");
|
|
1075
|
+
const cmdMatch = text.match(/set\s+"OH_LANGFUSE_REAL_OPENCODE=([^"]+)"/i);
|
|
1076
|
+
if (cmdMatch?.[1] && fs.existsSync(cmdMatch[1])) return path.resolve(cmdMatch[1]);
|
|
1077
|
+
const shMatch = text.match(/^OH_LANGFUSE_REAL_OPENCODE=(?:"([^"]+)"|'([^']+)'|([^\r\n]+))/m);
|
|
1078
|
+
const candidate = shMatch?.[1] || shMatch?.[2] || shMatch?.[3];
|
|
1079
|
+
if (candidate && fs.existsSync(candidate.trim())) return path.resolve(candidate.trim());
|
|
1080
|
+
} catch {
|
|
1081
|
+
// Best effort only; setup can still fall back to ordinary CLI discovery.
|
|
1082
|
+
}
|
|
1083
|
+
return "";
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
function writeOpencodeCommandShim(opencodeDir, { publicKey, secretKey, baseUrl, userId, realOpencodeCli }) {
|
|
1062
1087
|
const shimDir = path.join(opencodeDir, "bin");
|
|
1063
1088
|
ensureDir(shimDir);
|
|
1064
1089
|
if (process.platform === "win32") {
|
|
@@ -1502,8 +1527,9 @@ async function main() {
|
|
|
1502
1527
|
args.publicKey || process.env.LANGFUSE_PUBLIC_KEY || "pk-lf-da0c90a7-6e93-4eb7-bb86-c1047c8d187d";
|
|
1503
1528
|
const secretKey =
|
|
1504
1529
|
args.secretKey || process.env.LANGFUSE_SECRET_KEY || "sk-lf-0269b85d-bfdc-442c-bfa3-e737954e3315";
|
|
1505
|
-
const baseUrl =
|
|
1506
|
-
args.langfuseBaseUrl || process.env.LANGFUSE_BASEURL ||
|
|
1530
|
+
const baseUrl = normalizeLegacyBaseUrl(
|
|
1531
|
+
args.langfuseBaseUrl || process.env.LANGFUSE_BASEURL || DEFAULT_LANGFUSE_BASE_URL
|
|
1532
|
+
);
|
|
1507
1533
|
const userId = normalizeUserId(args.userId || args.userid || "");
|
|
1508
1534
|
if (!userId || typeof userId !== "string") {
|
|
1509
1535
|
throw new Error("缺少参数:--userId=你的工号");
|
|
@@ -1574,12 +1600,12 @@ async function main() {
|
|
|
1574
1600
|
writeJsonPretty(opencodeJsonPath, merged);
|
|
1575
1601
|
let realOpencodeCli = resolveOpencodeCli(args.cmd);
|
|
1576
1602
|
const shimDir = path.join(opencodeDir, "bin");
|
|
1577
|
-
if (realOpencodeCli) {
|
|
1578
|
-
const relativeToShim = path.relative(path.resolve(shimDir), path.resolve(realOpencodeCli));
|
|
1579
|
-
if (relativeToShim && !relativeToShim.startsWith("..") && !path.isAbsolute(relativeToShim)) {
|
|
1580
|
-
realOpencodeCli =
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1603
|
+
if (realOpencodeCli) {
|
|
1604
|
+
const relativeToShim = path.relative(path.resolve(shimDir), path.resolve(realOpencodeCli));
|
|
1605
|
+
if (relativeToShim && !relativeToShim.startsWith("..") && !path.isAbsolute(relativeToShim)) {
|
|
1606
|
+
realOpencodeCli = readRealOpencodeFromManagedShim(realOpencodeCli);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1583
1609
|
console.log(`已更新:${opencodeJsonPath}`);
|
|
1584
1610
|
|
|
1585
1611
|
const launcher = writeWindowsLauncherCmd(opencodeDir, { publicKey, secretKey, baseUrl, userId });
|
|
@@ -9,8 +9,12 @@ import { resolveOpencodeCli } from "./resolve-opencode-cli.mjs";
|
|
|
9
9
|
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
10
10
|
const packageJson = JSON.parse(fs.readFileSync(path.join(rootDir, "package.json"), "utf8"));
|
|
11
11
|
|
|
12
|
-
const DEFAULT_LANGFUSE_BASE_URL = "
|
|
13
|
-
const
|
|
12
|
+
const DEFAULT_LANGFUSE_BASE_URL = "https://metrics.openharmonyinsight.cn";
|
|
13
|
+
const LEGACY_LANGFUSE_BASE_URLS = new Set([
|
|
14
|
+
"http://120.46.221.227:3000",
|
|
15
|
+
"https://120.46.221.227:3000",
|
|
16
|
+
]);
|
|
17
|
+
const DEFAULT_LANGFUSE_PUBLIC_KEY = "pk-lf-da0c90a7-6e93-4eb7-bb86-c1047c8d187d";
|
|
14
18
|
const DEFAULT_LANGFUSE_SECRET_KEY = "sk-lf-0269b85d-bfdc-442c-bfa3-e737954e3315";
|
|
15
19
|
const OPENCODE_NATIVE_AGENT_TURN_NAMES = new Set(["session.llm:ai.streamText.doStream"]);
|
|
16
20
|
|
|
@@ -145,7 +149,7 @@ function findOnPath(names) {
|
|
|
145
149
|
return "";
|
|
146
150
|
}
|
|
147
151
|
|
|
148
|
-
function localCodexCliCandidates() {
|
|
152
|
+
function localCodexCliCandidates() {
|
|
149
153
|
if (process.platform !== "win32") return ["codex"];
|
|
150
154
|
const localAppData = process.env.LOCALAPPDATA || path.join(os.homedir(), "AppData", "Local");
|
|
151
155
|
const codexBin = path.join(localAppData, "OpenAI", "Codex", "bin");
|
|
@@ -163,12 +167,20 @@ function localCodexCliCandidates() {
|
|
|
163
167
|
// Fall back to PATH probing below.
|
|
164
168
|
}
|
|
165
169
|
return [...candidates, "codex.cmd", "codex.exe", "codex"].filter(Boolean);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function normalizeLegacyBaseUrl(baseUrl) {
|
|
173
|
+
const value = String(baseUrl || "").trim().replace(/\/+$/, "");
|
|
174
|
+
return LEGACY_LANGFUSE_BASE_URLS.has(value) ? DEFAULT_LANGFUSE_BASE_URL : baseUrl;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function configFromArgs(args) {
|
|
178
|
+
return {
|
|
179
|
+
baseUrl: String(
|
|
180
|
+
normalizeLegacyBaseUrl(
|
|
181
|
+
args.langfuseBaseUrl || args.langfuseHost || args.host || process.env.LANGFUSE_BASEURL || process.env.LANGFUSE_HOST || DEFAULT_LANGFUSE_BASE_URL
|
|
182
|
+
)
|
|
183
|
+
),
|
|
172
184
|
publicKey: String(args.publicKey || process.env.LANGFUSE_PUBLIC_KEY || DEFAULT_LANGFUSE_PUBLIC_KEY),
|
|
173
185
|
secretKey: String(args.secretKey || process.env.LANGFUSE_SECRET_KEY || DEFAULT_LANGFUSE_SECRET_KEY),
|
|
174
186
|
userId: String(args.userId || args.userid || process.env.LANGFUSE_USER_ID || process.env.CC_USER_ID || "").trim(),
|
|
@@ -10,7 +10,11 @@ import { writeRuntimeInstallRecord } from "./runtime-state-utils.mjs";
|
|
|
10
10
|
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
11
|
const packageJson = JSON.parse(fs.readFileSync(path.join(rootDir, "package.json"), "utf8"));
|
|
12
12
|
|
|
13
|
-
const DEFAULT_LANGFUSE_BASE_URL = "
|
|
13
|
+
const DEFAULT_LANGFUSE_BASE_URL = "https://metrics.openharmonyinsight.cn";
|
|
14
|
+
const LEGACY_LANGFUSE_BASE_URLS = new Set([
|
|
15
|
+
"http://120.46.221.227:3000",
|
|
16
|
+
"https://120.46.221.227:3000",
|
|
17
|
+
]);
|
|
14
18
|
const DEFAULT_LANGFUSE_PUBLIC_KEY = "pk-lf-da0c90a7-6e93-4eb7-bb86-c1047c8d187d";
|
|
15
19
|
const DEFAULT_LANGFUSE_SECRET_KEY = "sk-lf-0269b85d-bfdc-442c-bfa3-e737954e3315";
|
|
16
20
|
|
|
@@ -98,7 +102,7 @@ function codexConfig(home) {
|
|
|
98
102
|
};
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
function opencodeConfig(home) {
|
|
105
|
+
function opencodeConfig(home) {
|
|
102
106
|
const config = readJsonIfExists(path.join(home, ".config", "opencode-plugin-langfuse", "config.json")) || {};
|
|
103
107
|
return {
|
|
104
108
|
baseUrl: process.env.LANGFUSE_BASEURL || process.env.LANGFUSE_HOST,
|
|
@@ -106,16 +110,29 @@ function opencodeConfig(home) {
|
|
|
106
110
|
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
|
107
111
|
userId: config.userId || config.usrid || process.env.LANGFUSE_USER_ID,
|
|
108
112
|
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function normalizeLegacyBaseUrl(baseUrl) {
|
|
116
|
+
const value = String(baseUrl || "").trim().replace(/\/+$/, "");
|
|
117
|
+
return LEGACY_LANGFUSE_BASE_URLS.has(value) ? DEFAULT_LANGFUSE_BASE_URL : baseUrl;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function mergedConfig(target, args) {
|
|
121
|
+
const home = os.homedir();
|
|
122
|
+
const existing = target === "claude" ? claudeConfig(home) : target === "codex" ? codexConfig(home) : opencodeConfig(home);
|
|
123
|
+
const baseUrl = normalizeLegacyBaseUrl(
|
|
124
|
+
args.langfuseBaseUrl ||
|
|
125
|
+
args.langfuseHost ||
|
|
126
|
+
args.host ||
|
|
127
|
+
existing.baseUrl ||
|
|
128
|
+
process.env.LANGFUSE_BASEURL ||
|
|
129
|
+
DEFAULT_LANGFUSE_BASE_URL
|
|
130
|
+
);
|
|
131
|
+
const config = {
|
|
132
|
+
baseUrl,
|
|
133
|
+
publicKey: args.publicKey || existing.publicKey || process.env.LANGFUSE_PUBLIC_KEY || DEFAULT_LANGFUSE_PUBLIC_KEY,
|
|
134
|
+
secretKey: args.secretKey || existing.secretKey || process.env.LANGFUSE_SECRET_KEY || DEFAULT_LANGFUSE_SECRET_KEY,
|
|
135
|
+
userId: args.userId || args.userid || existing.userId || process.env.LANGFUSE_USER_ID || process.env.CC_USER_ID || "",
|
|
119
136
|
};
|
|
120
137
|
if (!config.userId) throw new Error(`Missing user id for ${target}; provide --userId=<employee-id> or run setup first.`);
|
|
121
138
|
return config;
|