psyclaw 0.30.2 → 0.30.4
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/README.md +6 -6
- package/dist/apps/panel/index.html +27 -1
- package/dist/apps/panel/observability.js +6 -3
- package/dist/src/adapters/pi/extension.js +16 -6
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/adapters/pi/model.d.ts +1 -0
- package/dist/src/adapters/pi/model.js +30 -18
- package/dist/src/adapters/pi/model.js.map +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/cli.js.map +1 -1
- package/dist/src/core/provider-endpoint.d.ts +4 -0
- package/dist/src/core/provider-endpoint.js +23 -0
- package/dist/src/core/provider-endpoint.js.map +1 -0
- package/dist/src/observability/config.d.ts +6 -0
- package/dist/src/observability/config.js +36 -5
- package/dist/src/observability/config.js.map +1 -1
- package/dist/src/observability/error-context.d.ts +20 -0
- package/dist/src/observability/error-context.js +104 -0
- package/dist/src/observability/error-context.js.map +1 -0
- package/dist/src/observability/expected.d.ts +10 -0
- package/dist/src/observability/expected.js +37 -0
- package/dist/src/observability/expected.js.map +1 -0
- package/dist/src/observability/identity.d.ts +10 -0
- package/dist/src/observability/identity.js +24 -0
- package/dist/src/observability/identity.js.map +1 -0
- package/dist/src/observability/index.d.ts +12 -2
- package/dist/src/observability/index.js +67 -9
- package/dist/src/observability/index.js.map +1 -1
- package/dist/src/observability/langfuse.d.ts +27 -0
- package/dist/src/observability/langfuse.js +65 -0
- package/dist/src/observability/langfuse.js.map +1 -0
- package/dist/src/observability/llm.d.ts +105 -0
- package/dist/src/observability/llm.js +185 -0
- package/dist/src/observability/llm.js.map +1 -0
- package/dist/src/observability/node-sdks.d.ts +9 -0
- package/dist/src/observability/node-sdks.js +80 -10
- package/dist/src/observability/node-sdks.js.map +1 -1
- package/dist/src/observability/notice.js +1 -1
- package/dist/src/observability/notice.js.map +1 -1
- package/dist/src/observability/preference.d.ts +3 -0
- package/dist/src/observability/preference.js +13 -0
- package/dist/src/observability/preference.js.map +1 -1
- package/dist/src/orchestration/pi-executor.js +10 -1
- package/dist/src/orchestration/pi-executor.js.map +1 -1
- package/dist/src/orchestration/runner.js +3 -3
- package/dist/src/orchestration/runner.js.map +1 -1
- package/dist/src/panel/server.js +64 -3
- package/dist/src/panel/server.js.map +1 -1
- package/dist/src/setup.d.ts +1 -0
- package/dist/src/setup.js +4 -8
- package/dist/src/setup.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ PsyClaw 是面向社会科学研究的智能体工作台。它把研究项目、
|
|
|
4
4
|
|
|
5
5
|
PsyClaw 自有代码使用 MIT 许可证;随 npm 包内置的 Academic Research Skills 位于 `vendor/ars`,保持上游署名并单独遵循 CC BY-NC 4.0,仅限非商业用途。
|
|
6
6
|
|
|
7
|
-
当前版本:`0.30.
|
|
7
|
+
当前版本:`0.30.4`。正式命令、用户配置目录和后续发布统一使用 `psyclaw`。
|
|
8
8
|
|
|
9
9
|
## 发布流程
|
|
10
10
|
|
|
@@ -21,19 +21,19 @@ RELEASE_MESSAGE="release: describe the change" pnpm release:push
|
|
|
21
21
|
需要 Node.js `>=22.19.0`。官方 npm 源:
|
|
22
22
|
|
|
23
23
|
```powershell
|
|
24
|
-
npm install -g psyclaw@0.30.
|
|
24
|
+
npm install -g psyclaw@0.30.4
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
如果本机 npm 配置把 registry 误写成带有 `~/` 的地址,请显式指定官方源:
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
npm install -g psyclaw@0.30.
|
|
30
|
+
npm install -g psyclaw@0.30.4 --registry=https://registry.npmjs.org/
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
中国大陆网络较慢或无法访问官方源时:
|
|
34
34
|
|
|
35
35
|
```powershell
|
|
36
|
-
npm install -g psyclaw@0.30.
|
|
36
|
+
npm install -g psyclaw@0.30.4 --registry=https://registry.npmmirror.com
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
或安装脚本:
|
|
@@ -46,7 +46,7 @@ PSYCLAW_CN=1 curl -fsSL https://exekiel179.github.io/psyclaw/install.sh | sh
|
|
|
46
46
|
```powershell
|
|
47
47
|
# Windows PowerShell
|
|
48
48
|
irm https://exekiel179.github.io/psyclaw/install.ps1 | iex
|
|
49
|
-
# 可选:$env:PSYCLAW_CN = "1";$env:PSYCLAW_VERSION = "0.30.
|
|
49
|
+
# 可选:$env:PSYCLAW_CN = "1";$env:PSYCLAW_VERSION = "0.30.4"
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
检测到国内 npm registry(如 npmmirror)、`PSYCLAW_CN=1` 或 `PSYCLAW_GITHUB_MIRROR` 时,内置路径统一走国内可用路由:
|
|
@@ -105,7 +105,7 @@ psyclaw evidence add notes\source.md --level user
|
|
|
105
105
|
| 更新 PsyClaw 和内置运行时 | `psyclaw update` |
|
|
106
106
|
| 导出会话 | 使用 Pi 内置的 `/export` |
|
|
107
107
|
| 匿名产品遥测 | `psyclaw telemetry status`、`psyclaw telemetry off`、`psyclaw telemetry on`(默认开启;对话中 `/telemetry`) |
|
|
108
|
-
| 打开科研面板 | 在对话中输入 `/panel
|
|
108
|
+
| 打开科研面板 | 在对话中输入 `/panel`(Provider 页可选填 Base URL,指向 OpenAI 兼容网关) |
|
|
109
109
|
| 查看或切换 Provider | 在对话中输入 `/provider` 或 `/provider <id>` |
|
|
110
110
|
| 管理启动横幅宠物 | `/pet`、`/pet on`、`/pet off`(默认关闭) |
|
|
111
111
|
| 管理 Skill | `/skill`(未安装→安装并默认启用;已启用→停用) |
|
|
@@ -2181,6 +2181,10 @@
|
|
|
2181
2181
|
<h2>配置凭据 (API Key)</h2>
|
|
2182
2182
|
</div>
|
|
2183
2183
|
<div class="form">
|
|
2184
|
+
<div class="field">
|
|
2185
|
+
<label for="provider-base-url">Base URL(可选,留空使用模型预设地址)</label>
|
|
2186
|
+
<input id="provider-base-url" type="url" inputmode="url" autocomplete="off" spellcheck="false" placeholder="https://api.example.com/v1">
|
|
2187
|
+
</div>
|
|
2184
2188
|
<div class="field">
|
|
2185
2189
|
<label for="provider-key">API Key(留空不覆盖已有凭据)</label>
|
|
2186
2190
|
<input id="provider-key" type="password" autocomplete="off" placeholder="输入当前 Provider 的专属 Key">
|
|
@@ -2851,6 +2855,22 @@ function updateModels() {
|
|
|
2851
2855
|
if (state.active.provider === $("provider-select").value && state.active.model) {
|
|
2852
2856
|
$("model-select").value = state.active.model;
|
|
2853
2857
|
}
|
|
2858
|
+
updateBaseUrl();
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2861
|
+
function updateBaseUrl() {
|
|
2862
|
+
const input = $("provider-base-url");
|
|
2863
|
+
if (!input) return;
|
|
2864
|
+
input.value = currentModel()?.endpoint || "";
|
|
2865
|
+
}
|
|
2866
|
+
|
|
2867
|
+
function isHttpEndpoint(value) {
|
|
2868
|
+
try {
|
|
2869
|
+
const url = new URL(value);
|
|
2870
|
+
return (url.protocol === "http:" || url.protocol === "https:") && !url.username && !url.password && !url.hash;
|
|
2871
|
+
} catch {
|
|
2872
|
+
return false;
|
|
2873
|
+
}
|
|
2854
2874
|
}
|
|
2855
2875
|
|
|
2856
2876
|
async function loadProvider() {
|
|
@@ -2927,6 +2947,7 @@ function currentModel() {
|
|
|
2927
2947
|
}
|
|
2928
2948
|
|
|
2929
2949
|
$("provider-select").addEventListener("change", updateModels);
|
|
2950
|
+
$("model-select").addEventListener("change", updateBaseUrl);
|
|
2930
2951
|
|
|
2931
2952
|
$("save-provider").addEventListener("click", async () => {
|
|
2932
2953
|
const feedback = $("provider-feedback");
|
|
@@ -2947,10 +2968,15 @@ $("save-provider").addEventListener("click", async () => {
|
|
|
2947
2968
|
|
|
2948
2969
|
$("configure-provider").addEventListener("click", async () => {
|
|
2949
2970
|
const feedback = $("config-feedback"), model = currentModel(), key = $("provider-key").value;
|
|
2971
|
+
const customBaseUrl = $("provider-base-url")?.value.trim() || "";
|
|
2950
2972
|
if (!model) {
|
|
2951
2973
|
feedback.textContent = "请选择模型";
|
|
2952
2974
|
return;
|
|
2953
2975
|
}
|
|
2976
|
+
if (customBaseUrl && !isHttpEndpoint(customBaseUrl)) {
|
|
2977
|
+
feedback.textContent = "Base URL 仅支持 http 或 https,且不能包含凭据或片段";
|
|
2978
|
+
return;
|
|
2979
|
+
}
|
|
2954
2980
|
feedback.textContent = "正在保存凭据...";
|
|
2955
2981
|
try {
|
|
2956
2982
|
await json("/api/provider-config", {
|
|
@@ -2959,7 +2985,7 @@ $("configure-provider").addEventListener("click", async () => {
|
|
|
2959
2985
|
body: JSON.stringify({
|
|
2960
2986
|
id: model.provider,
|
|
2961
2987
|
name: model.provider,
|
|
2962
|
-
baseUrl: model.endpoint,
|
|
2988
|
+
baseUrl: customBaseUrl || model.endpoint,
|
|
2963
2989
|
api: model.provider === "anthropic" ? "anthropic-messages" : "openai-completions",
|
|
2964
2990
|
apiKeyEnv: model.apiKeyEnv,
|
|
2965
2991
|
modelId: $("model-select").value,
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
).trim();
|
|
33
33
|
const surface = fromWindow.surface === "panel" || fromWindow.surface === "website" ? fromWindow.surface : "web";
|
|
34
34
|
const release = String(fromWindow.release || "").trim();
|
|
35
|
-
|
|
35
|
+
const distinctId = String(fromWindow.distinctId || "").trim();
|
|
36
|
+
return { sentryDsn, posthogKey, posthogHost, surface, release, distinctId };
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
async function loadEsm(url) {
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
const mod = await loadEsm("https://cdn.jsdelivr.net/npm/posthog-js@1/+esm");
|
|
57
58
|
const posthog = mod.default || mod.posthog || mod;
|
|
58
59
|
const panel = config.surface === "panel";
|
|
59
|
-
|
|
60
|
+
const init = {
|
|
60
61
|
api_host: config.posthogHost,
|
|
61
62
|
person_profiles: "identified_only",
|
|
62
63
|
autocapture: true,
|
|
@@ -74,7 +75,9 @@
|
|
|
74
75
|
loaded: function (client) {
|
|
75
76
|
client.register({ surface: config.surface, app: "psyclaw" });
|
|
76
77
|
},
|
|
77
|
-
}
|
|
78
|
+
};
|
|
79
|
+
if (config.distinctId) init.bootstrap = { distinctID: config.distinctId };
|
|
80
|
+
posthog.init(config.posthogKey, init);
|
|
78
81
|
window.posthog = posthog;
|
|
79
82
|
}
|
|
80
83
|
|
|
@@ -35,7 +35,7 @@ import { continuouslyWorkWarningText, isContinuouslyWorkEnabled, } from "../../s
|
|
|
35
35
|
import { assertHumanVerifyGate, formatVerifyChecklist, isNaturalPlanConfirm, isPlanRitualConfirm, PLAN_RITUAL_PHRASE, ensureDefaultVerifyChecklist, loadVerifyChecklist } from "../../verify/checklist.js";
|
|
36
36
|
import { formatSessionHelp, formatSessionHelpBrief } from "../../session/help.js";
|
|
37
37
|
import { openResearchWorkbench } from "../../panel/workbench.js";
|
|
38
|
-
import { captureAgentError, initNodeObservability, readTelemetryPreference, shutdownObservability, trackGateWaiting, writeTelemetryPreference, } from "../../observability/index.js";
|
|
38
|
+
import { captureAgentError, initNodeObservability, readTelemetryPreference, shutdownObservability, trackGateWaiting, trackSkillInstall, withAgentSpan, writeTelemetryPreference, } from "../../observability/index.js";
|
|
39
39
|
/** Codex-style slash surface: bare command, or command + trailing free text. No subcommand trees. */
|
|
40
40
|
function parseInitArgs(args) {
|
|
41
41
|
const goal = args.trim();
|
|
@@ -43,8 +43,8 @@ function parseInitArgs(args) {
|
|
|
43
43
|
return {};
|
|
44
44
|
return { paradigm: "survey-observational", goal };
|
|
45
45
|
}
|
|
46
|
-
async function notifyError(ctx, error) {
|
|
47
|
-
await captureAgentError(error, { phase: "extension" });
|
|
46
|
+
async function notifyError(ctx, error, extra = {}) {
|
|
47
|
+
await captureAgentError(error, { phase: "extension", cwd: ctx.cwd, ...extra });
|
|
48
48
|
ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
|
|
49
49
|
}
|
|
50
50
|
const activeAgentRuns = new Set();
|
|
@@ -744,9 +744,19 @@ async function queueModelSkillInstall(pi, ctx, row) {
|
|
|
744
744
|
const approved = await ctx.ui.confirm("交给当前模型安装 Skill?", `${row.name}\n来源:${row.sourceRef}\n安装位置:${skillScopeLabel(scope)}\n目标目录:${recommendedSkillTarget(ctx.cwd, row.id, scope)}\n模型将检查仓库并使用文件与命令工具完成安装;安装后默认启用。`);
|
|
745
745
|
if (!approved)
|
|
746
746
|
return;
|
|
747
|
-
await
|
|
748
|
-
|
|
749
|
-
|
|
747
|
+
await withAgentSpan("cli.skill_install", { phase: "skill_install", scope, skill_id: row.id }, async () => {
|
|
748
|
+
try {
|
|
749
|
+
await markRecommendedSkillDesired(ctx.cwd, row.id, scope);
|
|
750
|
+
}
|
|
751
|
+
catch (error) {
|
|
752
|
+
void trackSkillInstall("error", { skill_id: row.id, scope, status: "error" });
|
|
753
|
+
await notifyError(ctx, error, { phase: "skill_install", skill_id: row.id, scope });
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
void trackSkillInstall("queued", { skill_id: row.id, scope, status: "queued" });
|
|
757
|
+
pi.sendUserMessage(modelSkillInstallTask(ctx.cwd, row, scope), ctx.isIdle() ? {} : { deliverAs: "followUp" });
|
|
758
|
+
ctx.ui.notify(`已将 ${row.name} 的安装任务交给当前模型(默认启用),目标为${skillScopeLabel(scope)}。完成后请执行 /reload。`, "info");
|
|
759
|
+
});
|
|
750
760
|
}
|
|
751
761
|
async function showSkillManager(pi, ctx) {
|
|
752
762
|
if (!ctx.hasUI || typeof ctx.ui.custom !== "function") {
|