@chanlerdev/scorel 0.0.2 → 0.0.3
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 +55 -2
- package/dist/index.js +395 -31
- package/dist/index.js.map +3 -3
- package/docs/CHANGELOG.md +53 -0
- package/docs/ROADMAP.md +19 -0
- package/docs/spec/channels.md +15 -5
- package/docs/spec/ship/S0087-gui-ui-polish-sweep.md +153 -0
- package/docs/spec/ship/S0088-gui-streaming-thinking-contract.md +35 -0
- package/docs/spec/ship/S0089-memory-reliability-and-dream-trigger.md +84 -0
- package/docs/spec/ship/S0090-gui-provider-delete-and-dark-code-theme.md +77 -0
- package/docs/spec/ship/S0091-built-in-qq-and-wechat-im-extensions.md +125 -0
- package/docs/spec/ship/S0092-im-message-media-and-human-cadence.md +83 -0
- package/docs/spec/ship/S0093-gui-im-settings-platform-layout.md +66 -0
- package/docs/spec/ship/S0094-im-inbound-runtime.md +67 -0
- package/docs/spec/ship/S0095-gui-im-session-list-refresh.md +36 -0
- package/extensions/builtin/loopback/skills/loopback/SKILL.md +2 -0
- package/extensions/builtin/qq/adapter.d.ts +27 -0
- package/extensions/builtin/qq/adapter.js +384 -0
- package/extensions/builtin/qq/scorel.extension.json +7 -0
- package/extensions/builtin/qq/skills/qq/SKILL.md +9 -0
- package/extensions/builtin/telegram/adapter.d.ts +1 -1
- package/extensions/builtin/telegram/adapter.js +7 -0
- package/extensions/builtin/telegram/skills/telegram/SKILL.md +2 -0
- package/extensions/builtin/wechat/adapter.d.ts +24 -0
- package/extensions/builtin/wechat/adapter.js +226 -0
- package/extensions/builtin/wechat/scorel.extension.json +7 -0
- package/extensions/builtin/wechat/skills/wechat/SKILL.md +9 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -257,10 +257,18 @@ var init_src2 = __esm({
|
|
|
257
257
|
this.#assertDaemonConnected();
|
|
258
258
|
return (await this.#request("fetch_provider_models", input)).models;
|
|
259
259
|
}
|
|
260
|
+
async removeModelProvider(input) {
|
|
261
|
+
this.#assertDaemonConnected();
|
|
262
|
+
return this.#request("remove_model_provider", input);
|
|
263
|
+
}
|
|
260
264
|
async getMemorySettings(input) {
|
|
261
265
|
this.#assertDaemonConnected();
|
|
262
266
|
return (await this.#request("get_memory_settings", input)).memory;
|
|
263
267
|
}
|
|
268
|
+
async getMemoryStatus(input) {
|
|
269
|
+
this.#assertDaemonConnected();
|
|
270
|
+
return (await this.#request("get_memory_status", input)).status;
|
|
271
|
+
}
|
|
264
272
|
async upsertMemorySettings(input) {
|
|
265
273
|
this.#assertDaemonConnected();
|
|
266
274
|
return (await this.#request("upsert_memory_settings", input)).memory;
|
|
@@ -799,7 +807,7 @@ var init_sessions = __esm({
|
|
|
799
807
|
// packages/core/src/config/index.ts
|
|
800
808
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
801
809
|
import { join as join4 } from "node:path";
|
|
802
|
-
var SCOREL_CONFIG_SCHEMA, scorelUserRoot, scorelUserConfigPath, scorelSessionsDir, scorelProjectConfigPath, loadScorelConfig, loadScorelConfigProfile, listProviderConnections, listAvailableModels, listProviderModels, resolveModelSelection, renderModelProfileConfig, renderMemoryConfig, renderExtensionConfig, DEFAULT_MEMORY_CONFIG, loadMemory, loadExtensions, loadProviders, loadProviderProfiles, loadProviderModels, loadAvailableModels, loadRoles, readConfigText, parseToml, parseEditableConfig, renderRawConfig, emptyRawConfig, stripComment, requireString, normalizeProviderName, requireProviderCredential, resolveProviderApiKey, providerCredentialSummary, requireNumber, requireNonNegativeNumber, requireCompactThreshold, requireBoolean, requireCustomApi, requireProviderType, requireSection, ensureSection, setConfigValue, assertKnownKey, setValue, parseTomlValue, stripTrailingSlashes, requireIdentifier, tomlString, renderTomlValue, requireModelRole, modelRoles;
|
|
810
|
+
var SCOREL_CONFIG_SCHEMA, scorelUserRoot, scorelUserConfigPath, scorelSessionsDir, scorelProjectConfigPath, loadScorelConfig, loadScorelConfigProfile, listProviderConnections, listAvailableModels, listProviderModels, resolveModelSelection, renderModelProfileConfig, removeProvider, renderMemoryConfig, renderExtensionConfig, DEFAULT_MEMORY_CONFIG, loadMemory, loadExtensions, loadProviders, loadProviderProfiles, loadProviderModels, loadAvailableModels, loadRoles, readConfigText, parseToml, parseEditableConfig, renderRawConfig, emptyRawConfig, stripComment, requireString, normalizeProviderName, requireProviderCredential, resolveProviderApiKey, providerCredentialSummary, requireNumber, requireNonNegativeNumber, requireCompactThreshold, requireBoolean, requireCustomApi, requireProviderType, requireSection, ensureSection, setConfigValue, assertKnownKey, setValue, parseTomlValue, stripTrailingSlashes, requireIdentifier, tomlString, renderTomlValue, requireModelRole, modelRoles;
|
|
803
811
|
var init_config = __esm({
|
|
804
812
|
"packages/core/src/config/index.ts"() {
|
|
805
813
|
"use strict";
|
|
@@ -974,6 +982,9 @@ var init_config = __esm({
|
|
|
974
982
|
};
|
|
975
983
|
renderModelProfileConfig = (input) => {
|
|
976
984
|
const raw = parseEditableConfig(input.existingConfigText);
|
|
985
|
+
if (input.removeProviderId) {
|
|
986
|
+
removeProvider(raw, requireIdentifier(input.removeProviderId, "removeProviderId"));
|
|
987
|
+
}
|
|
977
988
|
if (input.providerType || input.provider || input.apiKeyEnv || input.apiKey || input.api || input.baseUrl) {
|
|
978
989
|
const providerId = requireIdentifier(input.providerId, "providerId");
|
|
979
990
|
const providerType = requireProviderType(input.providerType, "providerType");
|
|
@@ -1081,6 +1092,34 @@ var init_config = __esm({
|
|
|
1081
1092
|
}
|
|
1082
1093
|
return renderRawConfig(raw);
|
|
1083
1094
|
};
|
|
1095
|
+
removeProvider = (raw, providerId) => {
|
|
1096
|
+
delete raw.providers[providerId];
|
|
1097
|
+
const removedProviderModels = /* @__PURE__ */ new Set();
|
|
1098
|
+
for (const [providerModelId, providerModel] of Object.entries(raw.providerModels)) {
|
|
1099
|
+
if (providerModel.provider === providerId) {
|
|
1100
|
+
delete raw.providerModels[providerModelId];
|
|
1101
|
+
removedProviderModels.add(providerModelId);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
const removedAvailableModels = /* @__PURE__ */ new Set();
|
|
1105
|
+
for (const [availableModelId, availableModel] of Object.entries(raw.availableModels)) {
|
|
1106
|
+
if (availableModel.model && removedProviderModels.has(availableModel.model)) {
|
|
1107
|
+
delete raw.availableModels[availableModelId];
|
|
1108
|
+
removedAvailableModels.add(availableModelId);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
if (!raw.modelProfile?.roles) return;
|
|
1112
|
+
const fallbackModelId = Object.keys(raw.availableModels).sort()[0];
|
|
1113
|
+
if (!fallbackModelId) {
|
|
1114
|
+
delete raw.modelProfile;
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
for (const role of ["primary", "standard", "auxiliary"]) {
|
|
1118
|
+
if (!raw.modelProfile.roles[role] || removedAvailableModels.has(raw.modelProfile.roles[role])) {
|
|
1119
|
+
raw.modelProfile.roles[role] = fallbackModelId;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
};
|
|
1084
1123
|
renderMemoryConfig = (input) => {
|
|
1085
1124
|
const raw = parseEditableConfig(input.existingConfigText);
|
|
1086
1125
|
raw.memory = {
|
|
@@ -2413,7 +2452,7 @@ var init_tools = __esm({
|
|
|
2413
2452
|
});
|
|
2414
2453
|
|
|
2415
2454
|
// packages/core/src/channel/index.ts
|
|
2416
|
-
var createSendChannelMessageTool, parseSendChannelMessageInput, isRecord3;
|
|
2455
|
+
var createSendChannelMessageTool, parseSendChannelMessageInput, parseAttachments, optionalString2, isRecord3;
|
|
2417
2456
|
var init_channel = __esm({
|
|
2418
2457
|
"packages/core/src/channel/index.ts"() {
|
|
2419
2458
|
"use strict";
|
|
@@ -2426,7 +2465,7 @@ var init_channel = __esm({
|
|
|
2426
2465
|
const result = await options.sendCurrent(input);
|
|
2427
2466
|
return {
|
|
2428
2467
|
content: [{ type: "text", text: `Channel message sent to ${result.channel}:${result.target}` }],
|
|
2429
|
-
details: result
|
|
2468
|
+
details: { ...result, attachments: result.attachments ?? input.attachments?.length ?? 0 }
|
|
2430
2469
|
};
|
|
2431
2470
|
}
|
|
2432
2471
|
});
|
|
@@ -2434,8 +2473,10 @@ var init_channel = __esm({
|
|
|
2434
2473
|
if (!isRecord3(value)) {
|
|
2435
2474
|
throw new Error("SendChannelMessage args must be an object");
|
|
2436
2475
|
}
|
|
2437
|
-
|
|
2438
|
-
|
|
2476
|
+
const text = typeof value.text === "string" && value.text.trim().length > 0 ? value.text : void 0;
|
|
2477
|
+
const attachments = parseAttachments(value.attachments);
|
|
2478
|
+
if (!text && attachments.length === 0) {
|
|
2479
|
+
throw new Error("SendChannelMessage requires text or attachments");
|
|
2439
2480
|
}
|
|
2440
2481
|
if (value.channel !== void 0 && (typeof value.channel !== "string" || value.channel.trim().length === 0)) {
|
|
2441
2482
|
throw new Error("SendChannelMessage.channel must be a non-empty string when provided");
|
|
@@ -2444,11 +2485,49 @@ var init_channel = __esm({
|
|
|
2444
2485
|
throw new Error("SendChannelMessage.target must be current when provided");
|
|
2445
2486
|
}
|
|
2446
2487
|
return {
|
|
2447
|
-
text:
|
|
2488
|
+
...text ? { text } : {},
|
|
2489
|
+
...attachments.length > 0 ? { attachments } : {},
|
|
2448
2490
|
...typeof value.channel === "string" ? { channel: value.channel } : {},
|
|
2449
2491
|
...value.target === "current" ? { target: "current" } : {}
|
|
2450
2492
|
};
|
|
2451
2493
|
};
|
|
2494
|
+
parseAttachments = (value) => {
|
|
2495
|
+
if (value === void 0) {
|
|
2496
|
+
return [];
|
|
2497
|
+
}
|
|
2498
|
+
if (!Array.isArray(value)) {
|
|
2499
|
+
throw new Error("SendChannelMessage.attachments must be an array");
|
|
2500
|
+
}
|
|
2501
|
+
return value.map((item, index) => {
|
|
2502
|
+
if (!isRecord3(item)) {
|
|
2503
|
+
throw new Error(`SendChannelMessage.attachments.${index} must be an object`);
|
|
2504
|
+
}
|
|
2505
|
+
if (item.type !== "image" && item.type !== "file") {
|
|
2506
|
+
throw new Error(`SendChannelMessage.attachments.${index}.type must be image or file`);
|
|
2507
|
+
}
|
|
2508
|
+
const path = optionalString2(item.path, `SendChannelMessage.attachments.${index}.path`);
|
|
2509
|
+
const url = optionalString2(item.url, `SendChannelMessage.attachments.${index}.url`);
|
|
2510
|
+
if (!path && !url) {
|
|
2511
|
+
throw new Error(`SendChannelMessage.attachments.${index} requires path or url`);
|
|
2512
|
+
}
|
|
2513
|
+
return {
|
|
2514
|
+
type: item.type,
|
|
2515
|
+
...path ? { path } : {},
|
|
2516
|
+
...url ? { url } : {},
|
|
2517
|
+
...optionalString2(item.mimeType, `SendChannelMessage.attachments.${index}.mimeType`) ? { mimeType: optionalString2(item.mimeType, `SendChannelMessage.attachments.${index}.mimeType`) } : {},
|
|
2518
|
+
...optionalString2(item.caption, `SendChannelMessage.attachments.${index}.caption`) ? { caption: optionalString2(item.caption, `SendChannelMessage.attachments.${index}.caption`) } : {}
|
|
2519
|
+
};
|
|
2520
|
+
});
|
|
2521
|
+
};
|
|
2522
|
+
optionalString2 = (value, name) => {
|
|
2523
|
+
if (value === void 0 || value === "") {
|
|
2524
|
+
return void 0;
|
|
2525
|
+
}
|
|
2526
|
+
if (typeof value !== "string") {
|
|
2527
|
+
throw new Error(`${name} must be a string`);
|
|
2528
|
+
}
|
|
2529
|
+
return value;
|
|
2530
|
+
};
|
|
2452
2531
|
isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2453
2532
|
}
|
|
2454
2533
|
});
|
|
@@ -2669,7 +2748,7 @@ var init_instructions = __esm({
|
|
|
2669
2748
|
import { appendFile, mkdir as mkdir3, readFile as readFile7, writeFile as writeFile3 } from "node:fs/promises";
|
|
2670
2749
|
import { homedir as homedir3 } from "node:os";
|
|
2671
2750
|
import { join as join6 } from "node:path";
|
|
2672
|
-
var memoryDate, scorelMemoryPaths, scorelSessionMemoryPaths, buildMemoryContext, renderMemoryHarness, appendDailyEntry, createAppendDailyTool, renderDailyEntry, readSessionMemory, writeSessionMemory, renderSessionMemory, ensureMemoryFiles, ensureFile, readOptional, trimForContext, compactLine, renderList, renderBullets, normalizeMarkdownFile, parseAppendDailyInput, requireString3, optionalStringArray, isRecord5, safeProjectId, isNodeErrorCode2;
|
|
2751
|
+
var memoryDate, scorelMemoryPaths, scorelSessionMemoryPaths, buildMemoryContext, renderMemoryHarness, appendDailyEntry, createAppendDailyTool, renderDailyEntry, readMemoryDreamState, writeMemoryDreamState, readSessionMemory, writeSessionMemory, renderSessionMemory, ensureMemoryFiles, ensureFile, readOptional, trimForContext, compactLine, renderList, renderBullets, normalizeMarkdownFile, parseAppendDailyInput, validateAppendDailyInput, isLowSignalSummary, containsNormalizedDailyEntry, normalizeDailyText, requireString3, optionalStringArray, optionalNumber2, optionalString3, parseLastFailure, isRecord5, safeProjectId, isNodeErrorCode2;
|
|
2673
2752
|
var init_memory = __esm({
|
|
2674
2753
|
"packages/core/src/memory/index.ts"() {
|
|
2675
2754
|
"use strict";
|
|
@@ -2739,7 +2818,11 @@ var init_memory = __esm({
|
|
|
2739
2818
|
await ensureMemoryFiles(paths);
|
|
2740
2819
|
const text = options.text.trim();
|
|
2741
2820
|
if (!text) {
|
|
2742
|
-
return { path: paths.todayDailyPath, entry: "", date: paths.today };
|
|
2821
|
+
return { path: paths.todayDailyPath, entry: "", date: paths.today, skippedReason: "empty" };
|
|
2822
|
+
}
|
|
2823
|
+
const existing = await readOptional(paths.todayDailyPath);
|
|
2824
|
+
if (containsNormalizedDailyEntry(existing, text)) {
|
|
2825
|
+
return { path: paths.todayDailyPath, entry: "", date: paths.today, skippedReason: "duplicate" };
|
|
2743
2826
|
}
|
|
2744
2827
|
const time = new Date((options.now ?? Date.now)()).toISOString().slice(11, 16);
|
|
2745
2828
|
const entry = `- ${time} ${text.replace(/\s+/g, " ")}
|
|
@@ -2756,6 +2839,7 @@ var init_memory = __esm({
|
|
|
2756
2839
|
].join(" "),
|
|
2757
2840
|
execute: async (_toolCallId, args) => {
|
|
2758
2841
|
const input = parseAppendDailyInput(args);
|
|
2842
|
+
validateAppendDailyInput(input);
|
|
2759
2843
|
const result = await appendDailyEntry({
|
|
2760
2844
|
projectId: options.projectId,
|
|
2761
2845
|
homeDir: options.homeDir,
|
|
@@ -2766,11 +2850,12 @@ var init_memory = __esm({
|
|
|
2766
2850
|
return {
|
|
2767
2851
|
content: [{
|
|
2768
2852
|
type: "text",
|
|
2769
|
-
text: result.entry ? `Daily appended: ${result.date}` :
|
|
2853
|
+
text: result.entry ? `Daily appended: ${result.date}` : `Daily append skipped: ${result.skippedReason ?? "empty"}`
|
|
2770
2854
|
}],
|
|
2771
2855
|
details: {
|
|
2772
2856
|
path: result.path,
|
|
2773
|
-
date: result.date
|
|
2857
|
+
date: result.date,
|
|
2858
|
+
skippedReason: result.skippedReason
|
|
2774
2859
|
}
|
|
2775
2860
|
};
|
|
2776
2861
|
}
|
|
@@ -2781,10 +2866,45 @@ var init_memory = __esm({
|
|
|
2781
2866
|
renderList("Completed", input.completed),
|
|
2782
2867
|
renderList("Decisions", input.decisions),
|
|
2783
2868
|
renderList("Follow-ups", input.followUps),
|
|
2784
|
-
renderList("Memory candidates", input.memoryCandidates)
|
|
2869
|
+
renderList("Memory candidates", input.memoryCandidates),
|
|
2870
|
+
renderList("Evidence", input.evidence)
|
|
2785
2871
|
].filter(Boolean);
|
|
2786
2872
|
return sections.join(" ");
|
|
2787
2873
|
};
|
|
2874
|
+
readMemoryDreamState = async (options) => {
|
|
2875
|
+
const paths = scorelMemoryPaths(options);
|
|
2876
|
+
const text = await readOptional(paths.dreamStatePath);
|
|
2877
|
+
if (!text.trim()) return void 0;
|
|
2878
|
+
try {
|
|
2879
|
+
const parsed = JSON.parse(text);
|
|
2880
|
+
if (parsed.projectId !== options.projectId) return void 0;
|
|
2881
|
+
return {
|
|
2882
|
+
projectId: options.projectId,
|
|
2883
|
+
dirty: Boolean(parsed.dirty),
|
|
2884
|
+
running: Boolean(parsed.running),
|
|
2885
|
+
sessionId: optionalString3(parsed.sessionId),
|
|
2886
|
+
clientId: optionalString3(parsed.clientId),
|
|
2887
|
+
lastDailyAppendAt: optionalNumber2(parsed.lastDailyAppendAt),
|
|
2888
|
+
lastDailyPath: optionalString3(parsed.lastDailyPath),
|
|
2889
|
+
scheduledFor: optionalNumber2(parsed.scheduledFor),
|
|
2890
|
+
lastAttemptAt: optionalNumber2(parsed.lastAttemptAt),
|
|
2891
|
+
lastSuccessAt: optionalNumber2(parsed.lastSuccessAt),
|
|
2892
|
+
lastFailure: parseLastFailure(parsed.lastFailure),
|
|
2893
|
+
lastProjectMemoryUpdateAt: optionalNumber2(parsed.lastProjectMemoryUpdateAt),
|
|
2894
|
+
lastRootMemoryUpdateAt: optionalNumber2(parsed.lastRootMemoryUpdateAt)
|
|
2895
|
+
};
|
|
2896
|
+
} catch {
|
|
2897
|
+
return void 0;
|
|
2898
|
+
}
|
|
2899
|
+
};
|
|
2900
|
+
writeMemoryDreamState = async (options) => {
|
|
2901
|
+
const paths = scorelMemoryPaths(options);
|
|
2902
|
+
await mkdir3(paths.projectDir, { recursive: true, mode: 448 });
|
|
2903
|
+
const state = { ...options.state, projectId: options.projectId };
|
|
2904
|
+
await writeFile3(paths.dreamStatePath, `${JSON.stringify(state, null, 2)}
|
|
2905
|
+
`, { encoding: "utf8", mode: 384 });
|
|
2906
|
+
return state;
|
|
2907
|
+
};
|
|
2788
2908
|
readSessionMemory = async (options) => {
|
|
2789
2909
|
const paths = scorelSessionMemoryPaths(options);
|
|
2790
2910
|
return trimForContext(await readOptional(paths.sessionMemoryPath), 12e3, "tail");
|
|
@@ -2869,9 +2989,45 @@ var init_memory = __esm({
|
|
|
2869
2989
|
completed: optionalStringArray(value.completed, "completed"),
|
|
2870
2990
|
decisions: optionalStringArray(value.decisions, "decisions"),
|
|
2871
2991
|
followUps: optionalStringArray(value.followUps, "followUps"),
|
|
2872
|
-
memoryCandidates: optionalStringArray(value.memoryCandidates, "memoryCandidates")
|
|
2992
|
+
memoryCandidates: optionalStringArray(value.memoryCandidates, "memoryCandidates"),
|
|
2993
|
+
evidence: optionalStringArray(value.evidence, "evidence")
|
|
2873
2994
|
};
|
|
2874
2995
|
};
|
|
2996
|
+
validateAppendDailyInput = (input) => {
|
|
2997
|
+
const summary = compactLine(input.summary, 500);
|
|
2998
|
+
if (isLowSignalSummary(summary)) {
|
|
2999
|
+
throw new Error("AppendDaily.summary is too generic; include concrete durable progress or a decision");
|
|
3000
|
+
}
|
|
3001
|
+
const details = [
|
|
3002
|
+
...input.completed ?? [],
|
|
3003
|
+
...input.decisions ?? [],
|
|
3004
|
+
...input.followUps ?? [],
|
|
3005
|
+
...input.memoryCandidates ?? [],
|
|
3006
|
+
...input.evidence ?? []
|
|
3007
|
+
].map((value) => compactLine(value, 240)).filter(Boolean);
|
|
3008
|
+
if (details.length === 0) {
|
|
3009
|
+
throw new Error("AppendDaily requires at least one completed item, decision, follow-up, memory candidate, or evidence item");
|
|
3010
|
+
}
|
|
3011
|
+
};
|
|
3012
|
+
isLowSignalSummary = (value) => {
|
|
3013
|
+
const normalized = value.toLowerCase().replace(/\s+/g, "");
|
|
3014
|
+
return [
|
|
3015
|
+
"done",
|
|
3016
|
+
"completed",
|
|
3017
|
+
"finished",
|
|
3018
|
+
"updated",
|
|
3019
|
+
"\u7EE7\u7EED\u63A8\u8FDB",
|
|
3020
|
+
"\u5B8C\u6210\u4EFB\u52A1",
|
|
3021
|
+
"\u5DF2\u5904\u7406",
|
|
3022
|
+
"\u5904\u7406\u5B8C\u6210",
|
|
3023
|
+
"\u505A\u4E86\u4E00\u4E9B\u4FEE\u6539"
|
|
3024
|
+
].includes(normalized);
|
|
3025
|
+
};
|
|
3026
|
+
containsNormalizedDailyEntry = (daily, text) => {
|
|
3027
|
+
const needle = normalizeDailyText(text);
|
|
3028
|
+
return daily.split("\n").map((line) => line.replace(/^-\s+\d\d:\d\d\s+/, "")).some((line) => normalizeDailyText(line) === needle);
|
|
3029
|
+
};
|
|
3030
|
+
normalizeDailyText = (value) => value.replace(/\s+/g, " ").trim().toLowerCase();
|
|
2875
3031
|
requireString3 = (value, name) => {
|
|
2876
3032
|
if (typeof value !== "string" || !value.trim()) {
|
|
2877
3033
|
throw new Error(`AppendDaily.${name} must be a non-empty string`);
|
|
@@ -2887,6 +3043,14 @@ var init_memory = __esm({
|
|
|
2887
3043
|
}
|
|
2888
3044
|
return value.map((item) => item.trim()).filter(Boolean);
|
|
2889
3045
|
};
|
|
3046
|
+
optionalNumber2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
3047
|
+
optionalString3 = (value) => typeof value === "string" && value.trim() ? value : void 0;
|
|
3048
|
+
parseLastFailure = (value) => {
|
|
3049
|
+
if (!isRecord5(value)) return void 0;
|
|
3050
|
+
const at = optionalNumber2(value.at);
|
|
3051
|
+
const message = optionalString3(value.message);
|
|
3052
|
+
return at !== void 0 && message ? { at, message } : void 0;
|
|
3053
|
+
};
|
|
2890
3054
|
isRecord5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2891
3055
|
safeProjectId = (projectId) => {
|
|
2892
3056
|
if (!/^[A-Za-z0-9_-]+$/.test(projectId)) {
|
|
@@ -2921,6 +3085,8 @@ var init_pi_ai = __esm({
|
|
|
2921
3085
|
for await (const event of stream) {
|
|
2922
3086
|
if (event.type === "text_delta") {
|
|
2923
3087
|
yield { type: "text_delta", delta: event.delta };
|
|
3088
|
+
} else if (event.type === "thinking_delta") {
|
|
3089
|
+
yield { type: "thinking_delta", delta: event.delta };
|
|
2924
3090
|
}
|
|
2925
3091
|
}
|
|
2926
3092
|
return fromPiAssistant(await stream.result());
|
|
@@ -3111,7 +3277,8 @@ var init_pi_ai = __esm({
|
|
|
3111
3277
|
completed: Type.Optional(Type.Array(Type.String())),
|
|
3112
3278
|
decisions: Type.Optional(Type.Array(Type.String())),
|
|
3113
3279
|
followUps: Type.Optional(Type.Array(Type.String())),
|
|
3114
|
-
memoryCandidates: Type.Optional(Type.Array(Type.String()))
|
|
3280
|
+
memoryCandidates: Type.Optional(Type.Array(Type.String())),
|
|
3281
|
+
evidence: Type.Optional(Type.Array(Type.String()))
|
|
3115
3282
|
});
|
|
3116
3283
|
case "Skill":
|
|
3117
3284
|
return Type.Object({
|
|
@@ -3250,6 +3417,7 @@ var init_runtime = __esm({
|
|
|
3250
3417
|
}
|
|
3251
3418
|
async *#runProviderTurn(context, systemPrompt, options, signal) {
|
|
3252
3419
|
let text = "";
|
|
3420
|
+
let thinking = "";
|
|
3253
3421
|
yield { type: "message_start", role: "assistant" };
|
|
3254
3422
|
try {
|
|
3255
3423
|
const stream = this.#provider.streamTurn({
|
|
@@ -3265,7 +3433,7 @@ var init_runtime = __esm({
|
|
|
3265
3433
|
}
|
|
3266
3434
|
const next = await stream.next();
|
|
3267
3435
|
if (next.done) {
|
|
3268
|
-
const message = normalizeAssistantMessage(next.value, text, signal.aborted ? "cancelled" : "end_turn");
|
|
3436
|
+
const message = normalizeAssistantMessage(next.value, { thinking, text }, signal.aborted ? "cancelled" : "end_turn");
|
|
3269
3437
|
if (message) {
|
|
3270
3438
|
yield { type: "message_end", message };
|
|
3271
3439
|
}
|
|
@@ -3274,16 +3442,19 @@ var init_runtime = __esm({
|
|
|
3274
3442
|
if (next.value.type === "text_delta") {
|
|
3275
3443
|
text += next.value.delta;
|
|
3276
3444
|
yield next.value;
|
|
3445
|
+
} else if (next.value.type === "thinking_delta") {
|
|
3446
|
+
thinking += next.value.delta;
|
|
3447
|
+
yield next.value;
|
|
3277
3448
|
}
|
|
3278
3449
|
}
|
|
3279
|
-
const cancelledMessage = partialAssistantMessage(text, "cancelled");
|
|
3450
|
+
const cancelledMessage = partialAssistantMessage({ thinking, text }, "cancelled");
|
|
3280
3451
|
if (cancelledMessage) {
|
|
3281
3452
|
yield { type: "message_end", message: cancelledMessage };
|
|
3282
3453
|
}
|
|
3283
3454
|
return { stopReason: "cancelled" };
|
|
3284
3455
|
} catch (cause) {
|
|
3285
3456
|
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
3286
|
-
const partial = partialAssistantMessage(text, "error");
|
|
3457
|
+
const partial = partialAssistantMessage({ thinking, text }, "error");
|
|
3287
3458
|
if (partial) {
|
|
3288
3459
|
yield { type: "message_end", message: partial };
|
|
3289
3460
|
}
|
|
@@ -3334,23 +3505,26 @@ var init_runtime = __esm({
|
|
|
3334
3505
|
};
|
|
3335
3506
|
}
|
|
3336
3507
|
};
|
|
3337
|
-
normalizeAssistantMessage = (value,
|
|
3508
|
+
normalizeAssistantMessage = (value, streamed, fallbackStopReason) => {
|
|
3338
3509
|
if (value) {
|
|
3339
3510
|
if (!isAssistantMessage(value)) {
|
|
3340
3511
|
throw new Error(`Provider returned ${value.role} message instead of assistant`);
|
|
3341
3512
|
}
|
|
3342
3513
|
return value;
|
|
3343
3514
|
}
|
|
3344
|
-
return partialAssistantMessage(
|
|
3515
|
+
return partialAssistantMessage(streamed, fallbackStopReason);
|
|
3345
3516
|
};
|
|
3346
3517
|
isAssistantMessage = (message) => message.role === "assistant";
|
|
3347
|
-
partialAssistantMessage = (
|
|
3348
|
-
if (text.length === 0) {
|
|
3518
|
+
partialAssistantMessage = (streamed, stopReason) => {
|
|
3519
|
+
if (streamed.thinking.length === 0 && streamed.text.length === 0) {
|
|
3349
3520
|
return void 0;
|
|
3350
3521
|
}
|
|
3351
3522
|
return {
|
|
3352
3523
|
role: "assistant",
|
|
3353
|
-
content: [
|
|
3524
|
+
content: [
|
|
3525
|
+
...streamed.thinking ? [{ type: "thinking", text: streamed.thinking }] : [],
|
|
3526
|
+
...streamed.text ? [{ type: "text", text: streamed.text }] : []
|
|
3527
|
+
],
|
|
3354
3528
|
stopReason,
|
|
3355
3529
|
meta: stopReason === "end_turn" ? void 0 : { partial: true }
|
|
3356
3530
|
};
|
|
@@ -4619,6 +4793,7 @@ var init_src4 = __esm({
|
|
|
4619
4793
|
#loadConfigProfile;
|
|
4620
4794
|
#createRuntime;
|
|
4621
4795
|
#memoryHomeDir;
|
|
4796
|
+
#onSessionListChanged;
|
|
4622
4797
|
#now;
|
|
4623
4798
|
#createId;
|
|
4624
4799
|
#sessions = /* @__PURE__ */ new Map();
|
|
@@ -4643,6 +4818,7 @@ var init_src4 = __esm({
|
|
|
4643
4818
|
this.#loadConfigProfile = options.loadConfigProfile;
|
|
4644
4819
|
this.#createRuntime = options.createRuntime;
|
|
4645
4820
|
this.#memoryHomeDir = options.memoryHomeDir;
|
|
4821
|
+
this.#onSessionListChanged = options.onSessionListChanged;
|
|
4646
4822
|
this.#now = options.now ?? Date.now;
|
|
4647
4823
|
this.#createId = options.createId ?? (() => crypto.randomUUID());
|
|
4648
4824
|
this.#registry = new ProjectRegistry({
|
|
@@ -4819,6 +4995,10 @@ var init_src4 = __esm({
|
|
|
4819
4995
|
this.#respond(connection, message, await this.#handleUpsertModelProfile(message));
|
|
4820
4996
|
break;
|
|
4821
4997
|
}
|
|
4998
|
+
case "remove_model_provider": {
|
|
4999
|
+
this.#respond(connection, message, await this.#handleRemoveModelProvider(message));
|
|
5000
|
+
break;
|
|
5001
|
+
}
|
|
4822
5002
|
case "fetch_provider_models": {
|
|
4823
5003
|
this.#respond(connection, message, { models: await this.#fetchProviderModels(message.projectId, message.providerId) });
|
|
4824
5004
|
break;
|
|
@@ -4827,6 +5007,10 @@ var init_src4 = __esm({
|
|
|
4827
5007
|
this.#respond(connection, message, { memory: await this.#memorySettingsForProject(message.projectId) });
|
|
4828
5008
|
break;
|
|
4829
5009
|
}
|
|
5010
|
+
case "get_memory_status": {
|
|
5011
|
+
this.#respond(connection, message, { status: await this.#memoryStatusForProject(message.projectId) });
|
|
5012
|
+
break;
|
|
5013
|
+
}
|
|
4830
5014
|
case "upsert_memory_settings": {
|
|
4831
5015
|
this.#respond(connection, message, { memory: await this.#handleUpsertMemorySettings(message) });
|
|
4832
5016
|
break;
|
|
@@ -4892,6 +5076,9 @@ var init_src4 = __esm({
|
|
|
4892
5076
|
workDir: lane.project.workDir,
|
|
4893
5077
|
model: request.meta.model
|
|
4894
5078
|
});
|
|
5079
|
+
if (created) {
|
|
5080
|
+
this.#onSessionListChanged?.({ projectId: lane.project.projectId, sessionId });
|
|
5081
|
+
}
|
|
4895
5082
|
this.#respond(connection, request, { sessionId });
|
|
4896
5083
|
}
|
|
4897
5084
|
async #handleLoadSession(connection, request) {
|
|
@@ -5332,10 +5519,21 @@ var init_src4 = __esm({
|
|
|
5332
5519
|
delta: rawEvent.delta
|
|
5333
5520
|
});
|
|
5334
5521
|
break;
|
|
5522
|
+
case "thinking_delta":
|
|
5523
|
+
this.#broadcastTransient(lane.session.header.sessionId, {
|
|
5524
|
+
type: "thinking_delta",
|
|
5525
|
+
sessionId: lane.session.header.sessionId,
|
|
5526
|
+
clientId,
|
|
5527
|
+
ts: this.#now(),
|
|
5528
|
+
eventId: state.assistantEventId,
|
|
5529
|
+
delta: rawEvent.delta
|
|
5530
|
+
});
|
|
5531
|
+
break;
|
|
5335
5532
|
case "message_end": {
|
|
5336
5533
|
await this.#appendDiagnostic(lane.session.header.sessionId, "assistant_result", {
|
|
5337
5534
|
clientId,
|
|
5338
5535
|
stopReason: rawEvent.message.stopReason,
|
|
5536
|
+
thinkingBlocks: countContentBlocks(rawEvent.message, "thinking"),
|
|
5339
5537
|
textBlocks: countContentBlocks(rawEvent.message, "text"),
|
|
5340
5538
|
toolCalls: countContentBlocks(rawEvent.message, "tool_call"),
|
|
5341
5539
|
inputTokens: rawEvent.message.usage?.inputTokens,
|
|
@@ -5531,12 +5729,21 @@ var init_src4 = __esm({
|
|
|
5531
5729
|
homeDir: this.#memoryHomeDir,
|
|
5532
5730
|
now: this.#now,
|
|
5533
5731
|
onAppend: async (result) => {
|
|
5534
|
-
|
|
5535
|
-
clientId,
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5732
|
+
if (result.entry) {
|
|
5733
|
+
await this.#markMemoryDreamDirty(lane, clientId, result.path);
|
|
5734
|
+
}
|
|
5735
|
+
try {
|
|
5736
|
+
await this.#appendDiagnostic(lane.session.header.sessionId, "memory_daily_appended", {
|
|
5737
|
+
clientId,
|
|
5738
|
+
path: result.path,
|
|
5739
|
+
date: result.date,
|
|
5740
|
+
skippedReason: result.skippedReason
|
|
5741
|
+
});
|
|
5742
|
+
} catch {
|
|
5743
|
+
}
|
|
5744
|
+
if (result.entry) {
|
|
5745
|
+
await this.#scheduleMemoryDream(lane, clientId);
|
|
5746
|
+
}
|
|
5540
5747
|
}
|
|
5541
5748
|
})
|
|
5542
5749
|
);
|
|
@@ -5767,7 +5974,10 @@ var init_src4 = __esm({
|
|
|
5767
5974
|
...context.senderDisplayName ? [`sender_display_name: ${context.senderDisplayName}`] : [],
|
|
5768
5975
|
...context.mentionedBot !== void 0 ? [`mentioned_bot: ${context.mentionedBot}`] : [],
|
|
5769
5976
|
"",
|
|
5770
|
-
"Use SendChannelMessage to reply to the current conversation when needed."
|
|
5977
|
+
"Use SendChannelMessage to reply to the current conversation when needed.",
|
|
5978
|
+
"In IM, send a short acknowledgement before long work so the user does not think the bot is stuck.",
|
|
5979
|
+
"For longer tasks, send concise progress updates instead of waiting until every tool call has finished.",
|
|
5980
|
+
"Keep replies conversational and avoid exposing internal tool names unless they help the user."
|
|
5771
5981
|
];
|
|
5772
5982
|
return this.#appendPersistent(lane, {
|
|
5773
5983
|
type: "harness_item",
|
|
@@ -5808,6 +6018,22 @@ var init_src4 = __esm({
|
|
|
5808
6018
|
lastActivityAt: this.#now()
|
|
5809
6019
|
};
|
|
5810
6020
|
const delayMs = Math.max(0, memory.dreamIdleMinutes) * 60 * 1e3;
|
|
6021
|
+
const scheduledFor = this.#now() + delayMs;
|
|
6022
|
+
const currentState = await readMemoryDreamState({
|
|
6023
|
+
projectId: lane.project.projectId,
|
|
6024
|
+
homeDir: this.#memoryHomeDir,
|
|
6025
|
+
now: this.#now
|
|
6026
|
+
});
|
|
6027
|
+
await this.#writeMemoryDreamState(lane.project.projectId, {
|
|
6028
|
+
...currentState ?? {},
|
|
6029
|
+
projectId: String(lane.project.projectId),
|
|
6030
|
+
dirty: true,
|
|
6031
|
+
running: schedule.running,
|
|
6032
|
+
sessionId: String(lane.session.header.sessionId),
|
|
6033
|
+
clientId: String(clientId),
|
|
6034
|
+
lastDailyAppendAt: currentState?.lastDailyAppendAt ?? schedule.lastActivityAt,
|
|
6035
|
+
scheduledFor
|
|
6036
|
+
});
|
|
5811
6037
|
schedule.timer = setTimeout(() => {
|
|
5812
6038
|
void this.#runIdleMemoryDream(projectId).catch((cause) => {
|
|
5813
6039
|
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
@@ -5826,6 +6052,26 @@ var init_src4 = __esm({
|
|
|
5826
6052
|
idleMinutes: memory.dreamIdleMinutes
|
|
5827
6053
|
});
|
|
5828
6054
|
}
|
|
6055
|
+
async #markMemoryDreamDirty(lane, clientId, dailyPath) {
|
|
6056
|
+
const current = await readMemoryDreamState({
|
|
6057
|
+
projectId: lane.project.projectId,
|
|
6058
|
+
homeDir: this.#memoryHomeDir,
|
|
6059
|
+
now: this.#now
|
|
6060
|
+
});
|
|
6061
|
+
await this.#writeMemoryDreamState(lane.project.projectId, {
|
|
6062
|
+
projectId: String(lane.project.projectId),
|
|
6063
|
+
dirty: true,
|
|
6064
|
+
running: current?.running ?? false,
|
|
6065
|
+
sessionId: String(lane.session.header.sessionId),
|
|
6066
|
+
clientId: String(clientId),
|
|
6067
|
+
lastDailyAppendAt: this.#now(),
|
|
6068
|
+
lastDailyPath: dailyPath,
|
|
6069
|
+
lastFailure: current?.lastFailure,
|
|
6070
|
+
lastSuccessAt: current?.lastSuccessAt,
|
|
6071
|
+
lastProjectMemoryUpdateAt: current?.lastProjectMemoryUpdateAt,
|
|
6072
|
+
lastRootMemoryUpdateAt: current?.lastRootMemoryUpdateAt
|
|
6073
|
+
});
|
|
6074
|
+
}
|
|
5829
6075
|
async #runIdleMemoryDream(projectId) {
|
|
5830
6076
|
const schedule = this.#memoryDreams.get(projectId);
|
|
5831
6077
|
if (!schedule || schedule.running) {
|
|
@@ -5834,10 +6080,28 @@ var init_src4 = __esm({
|
|
|
5834
6080
|
schedule.running = true;
|
|
5835
6081
|
schedule.timer = void 0;
|
|
5836
6082
|
this.#memoryDreams.set(projectId, schedule);
|
|
6083
|
+
const beforeRun = await readMemoryDreamState({
|
|
6084
|
+
projectId,
|
|
6085
|
+
homeDir: this.#memoryHomeDir,
|
|
6086
|
+
now: this.#now
|
|
6087
|
+
});
|
|
6088
|
+
await this.#writeMemoryDreamState(projectId, {
|
|
6089
|
+
...beforeRun ?? { projectId: String(projectId), dirty: true },
|
|
6090
|
+
projectId: String(projectId),
|
|
6091
|
+
running: true,
|
|
6092
|
+
lastAttemptAt: this.#now()
|
|
6093
|
+
});
|
|
5837
6094
|
try {
|
|
5838
6095
|
const lane = await this.#getLane(schedule.sessionId);
|
|
5839
6096
|
const memory = await this.#safeMemorySettingsForRuntime(lane, schedule.clientId);
|
|
5840
6097
|
if (!memory.enabled || !memory.autoDream) {
|
|
6098
|
+
await this.#writeMemoryDreamState(projectId, {
|
|
6099
|
+
...beforeRun ?? { projectId: String(projectId) },
|
|
6100
|
+
projectId: String(projectId),
|
|
6101
|
+
dirty: false,
|
|
6102
|
+
running: false,
|
|
6103
|
+
lastFailure: { at: this.#now(), message: "Memory dream disabled" }
|
|
6104
|
+
});
|
|
5841
6105
|
return;
|
|
5842
6106
|
}
|
|
5843
6107
|
const generated = await this.#generateMemoryUpdate(lane, memory);
|
|
@@ -5860,10 +6124,82 @@ var init_src4 = __esm({
|
|
|
5860
6124
|
path: paths.rootMemoryPath
|
|
5861
6125
|
});
|
|
5862
6126
|
}
|
|
6127
|
+
const now = this.#now();
|
|
6128
|
+
const latestState = await readMemoryDreamState({ projectId, homeDir: this.#memoryHomeDir, now: this.#now });
|
|
6129
|
+
const hasNewDailyDuringRun = latestState?.lastDailyAppendAt !== void 0 && beforeRun?.lastDailyAppendAt !== void 0 && latestState.lastDailyAppendAt > beforeRun.lastDailyAppendAt;
|
|
6130
|
+
await this.#writeMemoryDreamState(projectId, {
|
|
6131
|
+
...latestState ?? { projectId: String(projectId) },
|
|
6132
|
+
projectId: String(projectId),
|
|
6133
|
+
dirty: hasNewDailyDuringRun,
|
|
6134
|
+
running: false,
|
|
6135
|
+
...hasNewDailyDuringRun ? {} : { scheduledFor: void 0 },
|
|
6136
|
+
lastSuccessAt: now,
|
|
6137
|
+
lastFailure: void 0,
|
|
6138
|
+
...generated?.projectMemory?.trim() ? { lastProjectMemoryUpdateAt: now } : {},
|
|
6139
|
+
...memory.promoteRoot && generated?.rootMemory?.trim() ? { lastRootMemoryUpdateAt: now } : {}
|
|
6140
|
+
});
|
|
6141
|
+
if (hasNewDailyDuringRun) {
|
|
6142
|
+
await this.#scheduleMemoryDream(lane, schedule.clientId);
|
|
6143
|
+
}
|
|
6144
|
+
} catch (cause) {
|
|
6145
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
6146
|
+
await this.#writeMemoryDreamState(projectId, {
|
|
6147
|
+
...await readMemoryDreamState({ projectId, homeDir: this.#memoryHomeDir, now: this.#now }) ?? { projectId: String(projectId) },
|
|
6148
|
+
projectId: String(projectId),
|
|
6149
|
+
dirty: true,
|
|
6150
|
+
running: false,
|
|
6151
|
+
lastFailure: { at: this.#now(), message }
|
|
6152
|
+
});
|
|
6153
|
+
throw cause;
|
|
5863
6154
|
} finally {
|
|
5864
6155
|
this.#memoryDreams.delete(projectId);
|
|
5865
6156
|
}
|
|
5866
6157
|
}
|
|
6158
|
+
async #memoryStatusForProject(projectId) {
|
|
6159
|
+
const state = await readMemoryDreamState({
|
|
6160
|
+
projectId,
|
|
6161
|
+
homeDir: this.#memoryHomeDir,
|
|
6162
|
+
now: this.#now
|
|
6163
|
+
});
|
|
6164
|
+
await this.#recoverMemoryDream(projectId, state);
|
|
6165
|
+
const recovered = await readMemoryDreamState({
|
|
6166
|
+
projectId,
|
|
6167
|
+
homeDir: this.#memoryHomeDir,
|
|
6168
|
+
now: this.#now
|
|
6169
|
+
});
|
|
6170
|
+
return {
|
|
6171
|
+
projectId,
|
|
6172
|
+
dirty: recovered?.dirty ?? false,
|
|
6173
|
+
running: recovered?.running ?? false,
|
|
6174
|
+
...recovered?.lastDailyAppendAt !== void 0 ? { lastDailyAppendAt: recovered.lastDailyAppendAt } : {},
|
|
6175
|
+
...recovered?.lastDailyPath ? { lastDailyPath: recovered.lastDailyPath } : {},
|
|
6176
|
+
...recovered?.scheduledFor !== void 0 ? { scheduledFor: recovered.scheduledFor } : {},
|
|
6177
|
+
...recovered?.lastAttemptAt !== void 0 ? { lastAttemptAt: recovered.lastAttemptAt } : {},
|
|
6178
|
+
...recovered?.lastSuccessAt !== void 0 ? { lastSuccessAt: recovered.lastSuccessAt } : {},
|
|
6179
|
+
...recovered?.lastFailure ? { lastFailure: recovered.lastFailure } : {},
|
|
6180
|
+
...recovered?.lastProjectMemoryUpdateAt !== void 0 ? { lastProjectMemoryUpdateAt: recovered.lastProjectMemoryUpdateAt } : {},
|
|
6181
|
+
...recovered?.lastRootMemoryUpdateAt !== void 0 ? { lastRootMemoryUpdateAt: recovered.lastRootMemoryUpdateAt } : {}
|
|
6182
|
+
};
|
|
6183
|
+
}
|
|
6184
|
+
async #recoverMemoryDream(projectId, state) {
|
|
6185
|
+
if (!state?.dirty || this.#memoryDreams.has(projectId)) {
|
|
6186
|
+
return;
|
|
6187
|
+
}
|
|
6188
|
+
const lane = [...this.#sessions.values()].find((candidate) => candidate.project.projectId === projectId);
|
|
6189
|
+
if (!lane) {
|
|
6190
|
+
return;
|
|
6191
|
+
}
|
|
6192
|
+
const clientId = state.clientId ? asClientId(state.clientId) : asClientId("client_memory_recovery");
|
|
6193
|
+
await this.#scheduleMemoryDream(lane, clientId);
|
|
6194
|
+
}
|
|
6195
|
+
async #writeMemoryDreamState(projectId, state) {
|
|
6196
|
+
await writeMemoryDreamState({
|
|
6197
|
+
projectId,
|
|
6198
|
+
homeDir: this.#memoryHomeDir,
|
|
6199
|
+
now: this.#now,
|
|
6200
|
+
state
|
|
6201
|
+
});
|
|
6202
|
+
}
|
|
5867
6203
|
async #generateMemoryUpdate(lane, memory) {
|
|
5868
6204
|
const selectedModel = await this.#selectedModelFromMeta(
|
|
5869
6205
|
{ projectId: lane.project.projectId, modelSelection: { role: "auxiliary" } },
|
|
@@ -6130,13 +6466,17 @@ var init_src4 = __esm({
|
|
|
6130
6466
|
if (!extension) {
|
|
6131
6467
|
throw new Error(`channel_adapter_unavailable: ${current.extensionId}`);
|
|
6132
6468
|
}
|
|
6133
|
-
await extension.adapter.sendMessage(current.target, {
|
|
6469
|
+
await extension.adapter.sendMessage(current.target, {
|
|
6470
|
+
...input.text ? { text: input.text } : {},
|
|
6471
|
+
...input.attachments ? { attachments: input.attachments } : {}
|
|
6472
|
+
});
|
|
6134
6473
|
await this.#appendDiagnostic(lane.session.header.sessionId, "channel_message_sent", {
|
|
6135
6474
|
extensionId: current.extensionId,
|
|
6136
6475
|
channel: current.channel,
|
|
6137
|
-
externalConversationId: current.externalConversationId
|
|
6476
|
+
externalConversationId: current.externalConversationId,
|
|
6477
|
+
attachments: input.attachments?.length ?? 0
|
|
6138
6478
|
});
|
|
6139
|
-
return { channel: current.channel, target: "current" };
|
|
6479
|
+
return { channel: current.channel, target: "current", attachments: input.attachments?.length ?? 0 };
|
|
6140
6480
|
}
|
|
6141
6481
|
})
|
|
6142
6482
|
);
|
|
@@ -6305,6 +6645,7 @@ var init_src4 = __esm({
|
|
|
6305
6645
|
externalConversationId,
|
|
6306
6646
|
projectId: project.projectId
|
|
6307
6647
|
});
|
|
6648
|
+
this.#onSessionListChanged?.({ projectId: project.projectId, sessionId });
|
|
6308
6649
|
return binding;
|
|
6309
6650
|
}
|
|
6310
6651
|
async #ensureDefaultWorkspaceProject() {
|
|
@@ -6427,6 +6768,29 @@ var init_src4 = __esm({
|
|
|
6427
6768
|
});
|
|
6428
6769
|
return this.#listModels(project.projectId);
|
|
6429
6770
|
}
|
|
6771
|
+
async #handleRemoveModelProvider(request) {
|
|
6772
|
+
const project = await this.#registry.require(request.projectId);
|
|
6773
|
+
const configPath = join10(project.workDir, ".scorel", "config.toml");
|
|
6774
|
+
let existingConfigText;
|
|
6775
|
+
try {
|
|
6776
|
+
existingConfigText = await readFile11(configPath, "utf8");
|
|
6777
|
+
} catch (cause) {
|
|
6778
|
+
if (!isNodeErrorCode4(cause, "ENOENT")) {
|
|
6779
|
+
throw cause;
|
|
6780
|
+
}
|
|
6781
|
+
}
|
|
6782
|
+
await mkdir6(join10(project.workDir, ".scorel"), { recursive: true });
|
|
6783
|
+
await writeFile6(
|
|
6784
|
+
configPath,
|
|
6785
|
+
renderModelProfileConfig({
|
|
6786
|
+
removeProviderId: request.providerId,
|
|
6787
|
+
existingConfigText
|
|
6788
|
+
}),
|
|
6789
|
+
"utf8"
|
|
6790
|
+
);
|
|
6791
|
+
const profile = await this.#listModels(project.projectId);
|
|
6792
|
+
return { ...profile, removed: true };
|
|
6793
|
+
}
|
|
6430
6794
|
async #memorySettingsForProject(projectId) {
|
|
6431
6795
|
const config = await this.#configProfileForProject(projectId).catch((cause) => {
|
|
6432
6796
|
if (isMissingConfigError(cause)) {
|