@chanlerdev/scorel 0.0.6 → 0.0.8
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 +5 -3
- package/dist/index.js +599 -67
- package/dist/index.js.map +4 -4
- package/docs/CHANGELOG.md +53 -0
- package/docs/ROADMAP.md +5 -4
- package/docs/spec/channels.md +1 -1
- package/docs/spec/events.md +28 -10
- package/docs/spec/runtime.md +3 -3
- package/docs/spec/session.md +4 -4
- package/docs/spec/ship/S0106-snip-context-control.md +1 -1
- package/docs/spec/ship/S0107-system-reminder-unification.md +112 -51
- package/docs/spec/ship/S0108-gui-bundled-cli-runtime.md +1 -1
- package/docs/spec/ship/S0109-scorel-run-headless-task-runner.md +172 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2762,12 +2762,7 @@ var init_tools = __esm({
|
|
|
2762
2762
|
return {
|
|
2763
2763
|
content: [{
|
|
2764
2764
|
type: "text",
|
|
2765
|
-
text:
|
|
2766
|
-
`Snipped user turn ${result.anchorUserEventId}.`,
|
|
2767
|
-
`Hidden through ${result.throughEventId}.`,
|
|
2768
|
-
`${result.hiddenEventCount} event(s) will be omitted from future model context.`,
|
|
2769
|
-
"Original session JSONL remains unchanged."
|
|
2770
|
-
].join(" ")
|
|
2765
|
+
text: "Snipped the selected user turn. It will be omitted from future model context."
|
|
2771
2766
|
}],
|
|
2772
2767
|
details: result
|
|
2773
2768
|
};
|
|
@@ -3419,15 +3414,65 @@ var init_memory = __esm({
|
|
|
3419
3414
|
}
|
|
3420
3415
|
});
|
|
3421
3416
|
|
|
3417
|
+
// packages/core/src/reminders/index.ts
|
|
3418
|
+
var createSystemReminderBlock, renderSystemReminderText, renderSystemReminder, systemReminderMessage, appendSystemReminderToToolResult, cloneSystemReminderBlock, isToolResultWithContent;
|
|
3419
|
+
var init_reminders = __esm({
|
|
3420
|
+
"packages/core/src/reminders/index.ts"() {
|
|
3421
|
+
"use strict";
|
|
3422
|
+
createSystemReminderBlock = (input) => ({
|
|
3423
|
+
type: "system_reminder",
|
|
3424
|
+
kind: input.kind,
|
|
3425
|
+
origin: input.origin,
|
|
3426
|
+
text: input.text,
|
|
3427
|
+
visibility: input.visibility,
|
|
3428
|
+
scope: input.scope,
|
|
3429
|
+
...input.data ? { data: { ...input.data } } : {}
|
|
3430
|
+
});
|
|
3431
|
+
renderSystemReminderText = (text) => `<system-reminder>
|
|
3432
|
+
${text}
|
|
3433
|
+
</system-reminder>`;
|
|
3434
|
+
renderSystemReminder = (input) => renderSystemReminderText(typeof input === "string" ? input : input.text);
|
|
3435
|
+
systemReminderMessage = (block, meta) => ({
|
|
3436
|
+
role: "user",
|
|
3437
|
+
content: [cloneSystemReminderBlock(block)],
|
|
3438
|
+
...meta ? { meta: { ...meta } } : {}
|
|
3439
|
+
});
|
|
3440
|
+
appendSystemReminderToToolResult = (message, block) => {
|
|
3441
|
+
for (let i = message.content.length - 1; i >= 0; i -= 1) {
|
|
3442
|
+
const candidate = message.content[i];
|
|
3443
|
+
if (candidate?.type !== "tool_result" || !isToolResultWithContent(candidate.result)) {
|
|
3444
|
+
continue;
|
|
3445
|
+
}
|
|
3446
|
+
const mergedResult = {
|
|
3447
|
+
...candidate.result,
|
|
3448
|
+
content: [...candidate.result.content, cloneSystemReminderBlock(block)]
|
|
3449
|
+
};
|
|
3450
|
+
message.content[i] = {
|
|
3451
|
+
...candidate,
|
|
3452
|
+
result: mergedResult
|
|
3453
|
+
};
|
|
3454
|
+
return true;
|
|
3455
|
+
}
|
|
3456
|
+
return false;
|
|
3457
|
+
};
|
|
3458
|
+
cloneSystemReminderBlock = (block) => ({
|
|
3459
|
+
...block,
|
|
3460
|
+
...block.data ? { data: { ...block.data } } : {}
|
|
3461
|
+
});
|
|
3462
|
+
isToolResultWithContent = (value) => typeof value === "object" && value !== null && "content" in value && Array.isArray(value.content);
|
|
3463
|
+
}
|
|
3464
|
+
});
|
|
3465
|
+
|
|
3422
3466
|
// packages/core/src/provider/pi-ai.ts
|
|
3423
3467
|
import {
|
|
3424
3468
|
getModels,
|
|
3425
3469
|
streamSimple
|
|
3426
3470
|
} from "@mariozechner/pi-ai";
|
|
3427
|
-
var DEFAULT_CUSTOM_MODEL_CONTEXT_WINDOW, DEFAULT_CUSTOM_MODEL_MAX_TOKENS, createPiAiProvider, resolvePiAiModel, toPiContext, toPiMessage, toPiAssistantBlock, fromPiAssistant, fromPiContentBlock, toPiTool, textContent, toolResultText, stringMeta, toPiStopReason, fromPiStopReason, fromPiUsage;
|
|
3471
|
+
var DEFAULT_CUSTOM_MODEL_CONTEXT_WINDOW, DEFAULT_CUSTOM_MODEL_MAX_TOKENS, createPiAiProvider, resolvePiAiModel, toPiContext, toPiMessage, toPiAssistantBlock, fromPiAssistant, fromPiContentBlock, toPiTool, textContent, toolResultText, isSystemReminderContentBlock, stringMeta, toPiStopReason, fromPiStopReason, fromPiUsage;
|
|
3428
3472
|
var init_pi_ai = __esm({
|
|
3429
3473
|
"packages/core/src/provider/pi-ai.ts"() {
|
|
3430
3474
|
"use strict";
|
|
3475
|
+
init_reminders();
|
|
3431
3476
|
DEFAULT_CUSTOM_MODEL_CONTEXT_WINDOW = 2e5;
|
|
3432
3477
|
DEFAULT_CUSTOM_MODEL_MAX_TOKENS = 64e3;
|
|
3433
3478
|
createPiAiProvider = (options) => ({
|
|
@@ -3526,6 +3571,9 @@ var init_pi_ai = __esm({
|
|
|
3526
3571
|
if (block.type === "text") {
|
|
3527
3572
|
return [{ type: "text", text: block.text }];
|
|
3528
3573
|
}
|
|
3574
|
+
if (block.type === "system_reminder") {
|
|
3575
|
+
return [{ type: "text", text: renderSystemReminder(block) }];
|
|
3576
|
+
}
|
|
3529
3577
|
if (block.type === "thinking") {
|
|
3530
3578
|
return [{ type: "thinking", thinking: block.text }];
|
|
3531
3579
|
}
|
|
@@ -3564,16 +3612,33 @@ var init_pi_ai = __esm({
|
|
|
3564
3612
|
description: tool.description,
|
|
3565
3613
|
parameters: tool.parameters
|
|
3566
3614
|
});
|
|
3567
|
-
textContent = (message) => message.content.
|
|
3615
|
+
textContent = (message) => message.content.flatMap((block) => {
|
|
3616
|
+
if (block.type === "text") {
|
|
3617
|
+
return [block.text];
|
|
3618
|
+
}
|
|
3619
|
+
if (block.type === "system_reminder") {
|
|
3620
|
+
return [renderSystemReminder(block)];
|
|
3621
|
+
}
|
|
3622
|
+
return [];
|
|
3623
|
+
}).join("\n");
|
|
3568
3624
|
toolResultText = (result) => {
|
|
3569
3625
|
if (typeof result === "object" && result !== null && "content" in result) {
|
|
3570
3626
|
const content = result.content;
|
|
3571
3627
|
if (Array.isArray(content)) {
|
|
3572
|
-
return content.
|
|
3628
|
+
return content.flatMap((block) => {
|
|
3629
|
+
if (block?.type === "text" && typeof block.text === "string") {
|
|
3630
|
+
return [block.text];
|
|
3631
|
+
}
|
|
3632
|
+
if (isSystemReminderContentBlock(block)) {
|
|
3633
|
+
return [renderSystemReminder(block)];
|
|
3634
|
+
}
|
|
3635
|
+
return [];
|
|
3636
|
+
}).join("\n");
|
|
3573
3637
|
}
|
|
3574
3638
|
}
|
|
3575
3639
|
return JSON.stringify(result);
|
|
3576
3640
|
};
|
|
3641
|
+
isSystemReminderContentBlock = (value) => typeof value === "object" && value !== null && value.type === "system_reminder" && typeof value.text === "string";
|
|
3577
3642
|
stringMeta = (message, key) => {
|
|
3578
3643
|
const value = message.meta?.[key];
|
|
3579
3644
|
return typeof value === "string" ? value : void 0;
|
|
@@ -3855,11 +3920,12 @@ function assertTreeEvent(value) {
|
|
|
3855
3920
|
throw new SessionStoreError("invalid_event", "skill_index_delta is missing delta payload");
|
|
3856
3921
|
}
|
|
3857
3922
|
}
|
|
3858
|
-
var snipUserMessageAlias, SessionStoreError, SessionTree, JsonlSession, sessionFilePath, sessionLogFilePath, sessionArtifactsDirPath, createSession, loadSession, buildContext, hiddenContextEventIds, retainedMessagesBeforeCompact, isRetainedContextStart, parseJsonLine, parseHeader, parseSessionEvent, validateSessionMatch, isConversationEvent, isInstructionSnapshot, isHarnessItem, isCompactEvent, isContextControlEvent, isQueueUpdate, isSessionTitleUpdated, isSkillIndexSnapshot, isSkillIndexDelta, isSkillIndexEntry, appendHarnessItemToContext,
|
|
3923
|
+
var snipUserMessageAlias, SessionStoreError, SessionTree, JsonlSession, sessionFilePath, sessionLogFilePath, sessionArtifactsDirPath, createSession, loadSession, buildContext, hiddenContextEventIds, retainedMessagesBeforeCompact, isRetainedContextStart, parseJsonLine, parseHeader, parseSessionEvent, validateSessionMatch, isConversationEvent, isInstructionSnapshot, isHarnessItem, isCompactEvent, isContextControlEvent, isQueueUpdate, isSessionTitleUpdated, isSkillIndexSnapshot, isSkillIndexDelta, isSkillIndexEntry, appendHarnessItemToContext, compactSummaryMessage, reminderKindFromHarness, reminderVisibilityFromHarness, reminderScopeFromHarness, cloneMessage, isRecord8;
|
|
3859
3924
|
var init_session = __esm({
|
|
3860
3925
|
"packages/core/src/session/index.ts"() {
|
|
3861
3926
|
"use strict";
|
|
3862
3927
|
init_src();
|
|
3928
|
+
init_reminders();
|
|
3863
3929
|
snipUserMessageAlias = (eventId) => `u_${createHash2("sha256").update(eventId).digest("hex").slice(0, 8)}`;
|
|
3864
3930
|
SessionStoreError = class extends Error {
|
|
3865
3931
|
code;
|
|
@@ -4214,65 +4280,74 @@ var init_session = __esm({
|
|
|
4214
4280
|
);
|
|
4215
4281
|
isSkillIndexEntry = (value) => isRecord8(value) && typeof value.name === "string" && typeof value.path === "string" && (value.scope === "user" || value.scope === "project" || value.scope === "extension") && typeof value.description === "string" && typeof value.mtimeMs === "number" && typeof value.size === "number" && typeof value.contentHash === "string" && typeof value.priority === "number";
|
|
4216
4282
|
appendHarnessItemToContext = (messages, event) => {
|
|
4217
|
-
const reminder =
|
|
4283
|
+
const reminder = createSystemReminderBlock({
|
|
4284
|
+
kind: reminderKindFromHarness(event.item.kind),
|
|
4285
|
+
origin: event.item.origin,
|
|
4286
|
+
text: event.item.content,
|
|
4287
|
+
visibility: reminderVisibilityFromHarness(event.item.visibility),
|
|
4288
|
+
scope: reminderScopeFromHarness(event.item.kind),
|
|
4289
|
+
...event.item.data ? { data: event.item.data } : {}
|
|
4290
|
+
});
|
|
4218
4291
|
const last = messages.at(-1);
|
|
4219
|
-
if (last?.role === "tool_result" &&
|
|
4292
|
+
if (last?.role === "tool_result" && appendSystemReminderToToolResult(last, reminder)) {
|
|
4220
4293
|
return;
|
|
4221
4294
|
}
|
|
4222
|
-
messages.push({
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
harnessKind: event.item.kind,
|
|
4228
|
-
harnessOrigin: event.item.origin
|
|
4229
|
-
}
|
|
4230
|
-
});
|
|
4231
|
-
};
|
|
4232
|
-
appendReminderToToolResult = (message, reminder) => {
|
|
4233
|
-
for (let i = message.content.length - 1; i >= 0; i -= 1) {
|
|
4234
|
-
const block = message.content[i];
|
|
4235
|
-
if (block?.type !== "tool_result" || !isToolResultWithContent(block.result)) {
|
|
4236
|
-
continue;
|
|
4237
|
-
}
|
|
4238
|
-
const mergedResult = {
|
|
4239
|
-
...block.result,
|
|
4240
|
-
content: [...block.result.content, { type: "text", text: `
|
|
4241
|
-
|
|
4242
|
-
${reminder}` }]
|
|
4243
|
-
};
|
|
4244
|
-
message.content[i] = {
|
|
4245
|
-
...block,
|
|
4246
|
-
result: mergedResult
|
|
4247
|
-
};
|
|
4248
|
-
return true;
|
|
4249
|
-
}
|
|
4250
|
-
return false;
|
|
4295
|
+
messages.push(systemReminderMessage(reminder, {
|
|
4296
|
+
source: "harness_item",
|
|
4297
|
+
harnessKind: event.item.kind,
|
|
4298
|
+
harnessOrigin: event.item.origin
|
|
4299
|
+
}));
|
|
4251
4300
|
};
|
|
4252
|
-
isToolResultWithContent = (value) => isRecord8(value) && Array.isArray(value.content);
|
|
4253
|
-
renderSystemReminder = (content) => `<system-reminder>
|
|
4254
|
-
${content}
|
|
4255
|
-
</system-reminder>`;
|
|
4256
4301
|
compactSummaryMessage = (event) => ({
|
|
4257
4302
|
role: "user",
|
|
4258
|
-
content: [{
|
|
4259
|
-
|
|
4260
|
-
|
|
4303
|
+
content: [createSystemReminderBlock({
|
|
4304
|
+
kind: "compact_summary",
|
|
4305
|
+
origin: "system",
|
|
4306
|
+
text: [
|
|
4261
4307
|
"Earlier session context has been compacted.",
|
|
4262
4308
|
"",
|
|
4263
4309
|
event.summary.trim(),
|
|
4264
4310
|
"",
|
|
4265
4311
|
"Use this summary as continuity context. Verify current repository facts before acting."
|
|
4266
|
-
].join("\n")
|
|
4267
|
-
|
|
4312
|
+
].join("\n"),
|
|
4313
|
+
visibility: "model",
|
|
4314
|
+
scope: "session"
|
|
4315
|
+
})],
|
|
4268
4316
|
meta: {
|
|
4269
4317
|
source: "compact",
|
|
4270
4318
|
compactedThrough: event.compactedThrough
|
|
4271
4319
|
}
|
|
4272
4320
|
});
|
|
4321
|
+
reminderKindFromHarness = (kind) => {
|
|
4322
|
+
if (kind === "attachment" || kind === "skill_listing" || kind === "skill_delta" || kind === "memory" || kind === "channel_context" || kind === "steer" || kind === "runtime_notice") {
|
|
4323
|
+
return kind;
|
|
4324
|
+
}
|
|
4325
|
+
if (kind === "date_change") {
|
|
4326
|
+
return "time";
|
|
4327
|
+
}
|
|
4328
|
+
return "runtime_notice";
|
|
4329
|
+
};
|
|
4330
|
+
reminderVisibilityFromHarness = (visibility) => {
|
|
4331
|
+
if (visibility === "hidden") {
|
|
4332
|
+
return "model";
|
|
4333
|
+
}
|
|
4334
|
+
return visibility;
|
|
4335
|
+
};
|
|
4336
|
+
reminderScopeFromHarness = (kind) => {
|
|
4337
|
+
if (kind === "steer" || kind === "skill_delta" || kind === "runtime_notice") {
|
|
4338
|
+
return "next_model_call";
|
|
4339
|
+
}
|
|
4340
|
+
if (kind === "channel_context" || kind === "attachment" || kind === "date_change") {
|
|
4341
|
+
return "turn";
|
|
4342
|
+
}
|
|
4343
|
+
return "session";
|
|
4344
|
+
};
|
|
4273
4345
|
cloneMessage = (message) => ({
|
|
4274
4346
|
...message,
|
|
4275
4347
|
content: message.content.map((block) => {
|
|
4348
|
+
if (block.type === "system_reminder") {
|
|
4349
|
+
return cloneSystemReminderBlock(block);
|
|
4350
|
+
}
|
|
4276
4351
|
if (block.type !== "tool_result" || !isRecord8(block.result)) {
|
|
4277
4352
|
return { ...block };
|
|
4278
4353
|
}
|
|
@@ -4532,6 +4607,7 @@ var init_src3 = __esm({
|
|
|
4532
4607
|
init_instructions();
|
|
4533
4608
|
init_memory();
|
|
4534
4609
|
init_pi_ai();
|
|
4610
|
+
init_reminders();
|
|
4535
4611
|
init_runtime();
|
|
4536
4612
|
init_session();
|
|
4537
4613
|
init_skills();
|
|
@@ -5490,20 +5566,22 @@ var init_src4 = __esm({
|
|
|
5490
5566
|
}
|
|
5491
5567
|
async #handleLoadSession(connection, request) {
|
|
5492
5568
|
try {
|
|
5493
|
-
const lane =
|
|
5569
|
+
const lane = this.#sessions.get(request.sessionId);
|
|
5570
|
+
const session = lane?.session ?? await loadSession({ sessionsDir: this.#sessionsDir, sessionId: request.sessionId });
|
|
5494
5571
|
await this.#appendDiagnostic(request.sessionId, "session_loaded", { clientId: connection.clientId });
|
|
5495
5572
|
connection.sessionId = request.sessionId;
|
|
5496
|
-
const persistentEvents = [...
|
|
5573
|
+
const persistentEvents = [...session.tree];
|
|
5497
5574
|
const sessionEvents = this.#events.get(request.sessionId) ?? [];
|
|
5498
5575
|
if (sessionEvents.length === 0 && persistentEvents.length > 0) {
|
|
5499
5576
|
this.#events.set(request.sessionId, persistentEvents);
|
|
5500
5577
|
}
|
|
5578
|
+
this.#seqs.set(request.sessionId, Number(session.currentSeq));
|
|
5501
5579
|
this.#respond(connection, request, {
|
|
5502
5580
|
sessionId: request.sessionId,
|
|
5503
|
-
activeLeafId:
|
|
5504
|
-
currentSeq:
|
|
5581
|
+
activeLeafId: session.activeLeafId,
|
|
5582
|
+
currentSeq: session.currentSeq,
|
|
5505
5583
|
events: persistentEvents,
|
|
5506
|
-
meta:
|
|
5584
|
+
meta: session.header.meta
|
|
5507
5585
|
});
|
|
5508
5586
|
} catch (cause) {
|
|
5509
5587
|
connection.emit({
|
|
@@ -7711,11 +7789,14 @@ var init_src4 = __esm({
|
|
|
7711
7789
|
countContentBlocks = (message, type) => message.content.filter((block) => block.type === type).length;
|
|
7712
7790
|
normalizeContent = (content) => typeof content === "string" ? [{ type: "text", text: content }] : content;
|
|
7713
7791
|
snipUserMessageIdBlock = (userEventId) => ({
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
7792
|
+
...createSystemReminderBlock({
|
|
7793
|
+
kind: "message_ref",
|
|
7794
|
+
origin: "system",
|
|
7795
|
+
text: `snip.userMessageId: ${snipUserMessageAlias(userEventId)}`,
|
|
7796
|
+
visibility: "model",
|
|
7797
|
+
scope: "message",
|
|
7798
|
+
data: { userMessageId: snipUserMessageAlias(userEventId) }
|
|
7799
|
+
})
|
|
7719
7800
|
});
|
|
7720
7801
|
inputText = (message) => message.content.flatMap((block) => block.type === "text" && block.visibility !== "model" ? [block.text] : []).join("\n").trim();
|
|
7721
7802
|
assistantText = (message) => message.content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
|
|
@@ -7733,6 +7814,9 @@ snip.userMessageId: ${snipUserMessageAlias(userEventId)}
|
|
|
7733
7814
|
if (block.type === "tool_result") {
|
|
7734
7815
|
return `[tool_result:${block.toolName}] ${JSON.stringify(block.result)}`;
|
|
7735
7816
|
}
|
|
7817
|
+
if (block.type === "system_reminder") {
|
|
7818
|
+
return `[system_reminder:${block.kind}] ${block.text}`;
|
|
7819
|
+
}
|
|
7736
7820
|
return "";
|
|
7737
7821
|
}).filter(Boolean).join("\n").trim();
|
|
7738
7822
|
return text || "(empty)";
|
|
@@ -9732,7 +9816,7 @@ import { createInterface } from "node:readline/promises";
|
|
|
9732
9816
|
import { homedir as homedir9 } from "node:os";
|
|
9733
9817
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
9734
9818
|
import { basename as basename4, dirname as dirname13, join as join17 } from "node:path";
|
|
9735
|
-
var cliAppName, cliClientDependency, cliDaemonDependency, defaultSessionsDir, defaultStateDir4, runCli, runProject, runLogs, runAttach, attachCacheScope, attachCacheFilePath, attachDiagnosticsFilePath, findAttachDiagnosticsFilePath, stateDirFromSessionsDir, AttachDiagnostics, readAttachCache, writeAttachCache, emptyAttachCacheSnapshot, mergePersistentEvents, highestSeq, highestCachedStreamSeq, updateAttachCacheSnapshot, removeCompletedTransients, isCachedTransientMessage, AsyncInputQueue, parseAttachOptions, parseLogsOptions, runChat, createSigintHandler, loadOrCreateSession, parseChatOptions, requireValue6, promptIfInteractive, writeUsage, writeProjectUsage, writeEventError, writeToolResult, redactDiagnosticFields, formatDiagnosticLine2, formatDiagnosticValue2, AttachEventRenderer, blocksToText, isCliEntrypoint;
|
|
9819
|
+
var cliAppName, cliClientDependency, cliDaemonDependency, defaultSessionsDir, defaultStateDir4, runCli, runProject, runLogs, runAttach, attachCacheScope, attachCacheFilePath, attachDiagnosticsFilePath, findAttachDiagnosticsFilePath, stateDirFromSessionsDir, AttachDiagnostics, readAttachCache, writeAttachCache, emptyAttachCacheSnapshot, mergePersistentEvents, highestSeq, highestCachedStreamSeq, updateAttachCacheSnapshot, removeCompletedTransients, isCachedTransientMessage, AsyncInputQueue, parseAttachOptions, parseLogsOptions, runChat, runHeadless, renderRunEvent, renderRunFinal, writeJsonLine, RunTimeoutError, withRunTimeout, makeRunSummary, writeRunSummary, readRunPrompt, resolveRunConfig, stripTrailingSlashes2, createSigintHandler, loadOrCreateSession, parseChatOptions, parseRunOptions, parseRunOutputFormat, parsePositiveInteger, parseModelSelection, parseRunProviderApi, requireValue6, promptIfInteractive, writeUsage, writeRunUsage, writeProjectUsage, writeEventError, writeToolResult, redactDiagnosticFields, formatDiagnosticLine2, formatDiagnosticValue2, AttachEventRenderer, blocksToText, isCliEntrypoint;
|
|
9736
9820
|
var init_index = __esm({
|
|
9737
9821
|
async "apps/cli/src/index.ts"() {
|
|
9738
9822
|
"use strict";
|
|
@@ -9766,6 +9850,19 @@ var init_index = __esm({
|
|
|
9766
9850
|
const sessionsDir = runOptions.sessionsDir ?? chatOptions.sessionsDir;
|
|
9767
9851
|
return runChat({ ...chatOptions, config: runOptions.config, sessionsDir, stateDir: stateDirFromSessionsDir(sessionsDir) }, io);
|
|
9768
9852
|
}
|
|
9853
|
+
if (command === "run") {
|
|
9854
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
9855
|
+
writeRunUsage(io.output);
|
|
9856
|
+
return 0;
|
|
9857
|
+
}
|
|
9858
|
+
try {
|
|
9859
|
+
return runHeadless(parseRunOptions(rest, runOptions), io);
|
|
9860
|
+
} catch (cause) {
|
|
9861
|
+
io.error.write(`scorel run error: ${cause instanceof Error ? cause.message : String(cause)}
|
|
9862
|
+
`);
|
|
9863
|
+
return 2;
|
|
9864
|
+
}
|
|
9865
|
+
}
|
|
9769
9866
|
if (command === "daemon") {
|
|
9770
9867
|
return runCliDaemon(rest, {
|
|
9771
9868
|
stateDir: stateDirFromSessionsDir(runOptions.sessionsDir),
|
|
@@ -10327,7 +10424,7 @@ var init_index = __esm({
|
|
|
10327
10424
|
process.on("SIGINT", sigintHandler);
|
|
10328
10425
|
try {
|
|
10329
10426
|
await client.connect(options.sessionId);
|
|
10330
|
-
const resumed = await loadOrCreateSession(client, options, project.projectId);
|
|
10427
|
+
const resumed = await loadOrCreateSession(client, options.sessionId, project.projectId);
|
|
10331
10428
|
io.error.write(`scorel chat ${resumed ? "resumed" : "created"} session ${options.sessionId}
|
|
10332
10429
|
`);
|
|
10333
10430
|
const rl = createInterface({ input: io.input, crlfDelay: Infinity });
|
|
@@ -10375,6 +10472,247 @@ var init_index = __esm({
|
|
|
10375
10472
|
await daemon.shutdown();
|
|
10376
10473
|
}
|
|
10377
10474
|
};
|
|
10475
|
+
runHeadless = async (options, io) => {
|
|
10476
|
+
const startedAt = Date.now();
|
|
10477
|
+
let projectId;
|
|
10478
|
+
const textParts = [];
|
|
10479
|
+
const prompt = await readRunPrompt(options, io);
|
|
10480
|
+
const runConfig = resolveRunConfig(options);
|
|
10481
|
+
const configScope = { scorelHomeDir: options.stateDir };
|
|
10482
|
+
const loadProjectConfig = async (project) => runConfig ?? options.config ?? await loadScorelConfig({ cwd: project.workDir, ...configScope });
|
|
10483
|
+
const loadProjectConfigProfile = async (project) => runConfig ?? options.config ?? await loadScorelConfigProfile({ cwd: project.workDir, ...configScope });
|
|
10484
|
+
const daemon = new ScorelHost({
|
|
10485
|
+
sessionsDir: options.sessionsDir,
|
|
10486
|
+
projectsPath: join17(options.stateDir, "projects.json"),
|
|
10487
|
+
deviceId: asDeviceId("device_local"),
|
|
10488
|
+
scorelHomeDir: options.stateDir,
|
|
10489
|
+
loadConfig: async ({ project }) => loadProjectConfig(project),
|
|
10490
|
+
loadConfigProfile: async ({ project }) => loadProjectConfigProfile(project),
|
|
10491
|
+
createRuntime: async ({ sessionId, project, selectedModel, purpose }) => createRealRuntime({
|
|
10492
|
+
cwd: project.workDir,
|
|
10493
|
+
config: await loadProjectConfig(project),
|
|
10494
|
+
sessionsDir: options.sessionsDir,
|
|
10495
|
+
sessionId,
|
|
10496
|
+
modelSelection: selectedModel ? { modelId: selectedModel.modelId, role: selectedModel.role } : void 0,
|
|
10497
|
+
includeTools: purpose === "chat"
|
|
10498
|
+
})
|
|
10499
|
+
});
|
|
10500
|
+
const client = new DaemonClient(createEmbeddedTransport(daemon), {
|
|
10501
|
+
clientId: asClientId("client_cli_run")
|
|
10502
|
+
});
|
|
10503
|
+
let unsubscribe;
|
|
10504
|
+
try {
|
|
10505
|
+
await daemon.start();
|
|
10506
|
+
const project = await daemon.registerProject(options.cwd);
|
|
10507
|
+
projectId = project.projectId;
|
|
10508
|
+
await client.connect(options.sessionId);
|
|
10509
|
+
await loadOrCreateSession(client, options.sessionId, project.projectId, options.modelSelection);
|
|
10510
|
+
unsubscribe = client.subscribe((event) => {
|
|
10511
|
+
if (event.type === "text_delta") {
|
|
10512
|
+
textParts.push(event.delta);
|
|
10513
|
+
}
|
|
10514
|
+
renderRunEvent(options, io, event);
|
|
10515
|
+
});
|
|
10516
|
+
const send = client.sendMessage(prompt, options.modelSelection ? { modelSelection: options.modelSelection } : void 0);
|
|
10517
|
+
const result = options.timeoutMs === void 0 ? await send : await withRunTimeout(send, options.timeoutMs, async () => {
|
|
10518
|
+
await client.cancel().catch(() => void 0);
|
|
10519
|
+
});
|
|
10520
|
+
const summary = makeRunSummary({
|
|
10521
|
+
options,
|
|
10522
|
+
startedAt,
|
|
10523
|
+
projectId,
|
|
10524
|
+
status: "completed",
|
|
10525
|
+
exitReason: "completed",
|
|
10526
|
+
userEventId: String(result.userEventId),
|
|
10527
|
+
assistantEventId: String(result.assistantEventId)
|
|
10528
|
+
});
|
|
10529
|
+
await writeRunSummary(options.summaryPath, summary);
|
|
10530
|
+
renderRunFinal(options, io, summary, textParts.join(""));
|
|
10531
|
+
return 0;
|
|
10532
|
+
} catch (cause) {
|
|
10533
|
+
const isTimeout = cause instanceof RunTimeoutError;
|
|
10534
|
+
const summary = makeRunSummary({
|
|
10535
|
+
options,
|
|
10536
|
+
startedAt,
|
|
10537
|
+
projectId,
|
|
10538
|
+
status: isTimeout ? "timeout" : "error",
|
|
10539
|
+
exitReason: isTimeout ? "timeout" : "error",
|
|
10540
|
+
error: cause instanceof Error ? cause : new Error(String(cause))
|
|
10541
|
+
});
|
|
10542
|
+
await writeRunSummary(options.summaryPath, summary).catch(() => void 0);
|
|
10543
|
+
renderRunFinal(options, io, summary, textParts.join(""));
|
|
10544
|
+
if (!options.quiet && options.outputFormat === "text") {
|
|
10545
|
+
io.error.write(`scorel run error: ${summary.error?.message ?? "unknown error"}
|
|
10546
|
+
`);
|
|
10547
|
+
}
|
|
10548
|
+
return isTimeout ? 124 : 1;
|
|
10549
|
+
} finally {
|
|
10550
|
+
unsubscribe?.();
|
|
10551
|
+
client.disconnect();
|
|
10552
|
+
await daemon.shutdown();
|
|
10553
|
+
}
|
|
10554
|
+
};
|
|
10555
|
+
renderRunEvent = (options, io, event) => {
|
|
10556
|
+
if (options.outputFormat === "none" || options.outputFormat === "json") {
|
|
10557
|
+
return;
|
|
10558
|
+
}
|
|
10559
|
+
if (options.outputFormat === "stream-json") {
|
|
10560
|
+
writeJsonLine(io.output, { type: "event", event });
|
|
10561
|
+
return;
|
|
10562
|
+
}
|
|
10563
|
+
if (event.type === "text_delta") {
|
|
10564
|
+
io.output.write(event.delta);
|
|
10565
|
+
}
|
|
10566
|
+
if (event.type === "tool_result") {
|
|
10567
|
+
writeToolResult(io.output, event);
|
|
10568
|
+
}
|
|
10569
|
+
if (event.type === "error") {
|
|
10570
|
+
writeEventError(io.error, event);
|
|
10571
|
+
}
|
|
10572
|
+
};
|
|
10573
|
+
renderRunFinal = (options, io, summary, text) => {
|
|
10574
|
+
if (options.outputFormat === "none") {
|
|
10575
|
+
return;
|
|
10576
|
+
}
|
|
10577
|
+
if (options.outputFormat === "json") {
|
|
10578
|
+
io.output.write(`${JSON.stringify({ ...summary, result: text })}
|
|
10579
|
+
`);
|
|
10580
|
+
return;
|
|
10581
|
+
}
|
|
10582
|
+
if (options.outputFormat === "stream-json") {
|
|
10583
|
+
writeJsonLine(io.output, { type: "result", summary, result: text });
|
|
10584
|
+
return;
|
|
10585
|
+
}
|
|
10586
|
+
if (!text.endsWith("\n")) {
|
|
10587
|
+
io.output.write("\n");
|
|
10588
|
+
}
|
|
10589
|
+
};
|
|
10590
|
+
writeJsonLine = (output, value) => {
|
|
10591
|
+
output.write(`${JSON.stringify(value)}
|
|
10592
|
+
`);
|
|
10593
|
+
};
|
|
10594
|
+
RunTimeoutError = class extends Error {
|
|
10595
|
+
constructor(timeoutMs) {
|
|
10596
|
+
super(`run timed out after ${timeoutMs}ms`);
|
|
10597
|
+
this.name = "RunTimeoutError";
|
|
10598
|
+
}
|
|
10599
|
+
};
|
|
10600
|
+
withRunTimeout = async (promise, timeoutMs, onTimeout) => {
|
|
10601
|
+
let timeout;
|
|
10602
|
+
try {
|
|
10603
|
+
return await Promise.race([
|
|
10604
|
+
promise,
|
|
10605
|
+
new Promise((_resolve, reject) => {
|
|
10606
|
+
timeout = setTimeout(() => {
|
|
10607
|
+
void onTimeout().finally(() => reject(new RunTimeoutError(timeoutMs)));
|
|
10608
|
+
}, timeoutMs);
|
|
10609
|
+
})
|
|
10610
|
+
]);
|
|
10611
|
+
} finally {
|
|
10612
|
+
if (timeout) {
|
|
10613
|
+
clearTimeout(timeout);
|
|
10614
|
+
}
|
|
10615
|
+
}
|
|
10616
|
+
};
|
|
10617
|
+
makeRunSummary = (input) => ({
|
|
10618
|
+
status: input.status,
|
|
10619
|
+
sessionId: String(input.options.sessionId),
|
|
10620
|
+
...input.projectId ? { projectId: String(input.projectId) } : {},
|
|
10621
|
+
cwd: input.options.cwd,
|
|
10622
|
+
stateDir: input.options.stateDir,
|
|
10623
|
+
sessionsDir: input.options.sessionsDir,
|
|
10624
|
+
sessionJsonl: join17(input.options.sessionsDir, `${input.options.sessionId}.jsonl`),
|
|
10625
|
+
outputFormat: input.options.outputFormat,
|
|
10626
|
+
elapsedMs: Date.now() - input.startedAt,
|
|
10627
|
+
exitReason: input.exitReason,
|
|
10628
|
+
...input.userEventId ? { userEventId: input.userEventId } : {},
|
|
10629
|
+
...input.assistantEventId ? { assistantEventId: input.assistantEventId } : {},
|
|
10630
|
+
...input.error ? { error: { message: input.error.message } } : {}
|
|
10631
|
+
});
|
|
10632
|
+
writeRunSummary = async (path, summary) => {
|
|
10633
|
+
if (!path) {
|
|
10634
|
+
return;
|
|
10635
|
+
}
|
|
10636
|
+
await mkdir8(dirname13(path), { recursive: true });
|
|
10637
|
+
await writeFile8(path, `${JSON.stringify(summary, null, 2)}
|
|
10638
|
+
`);
|
|
10639
|
+
};
|
|
10640
|
+
readRunPrompt = async (options, io) => {
|
|
10641
|
+
if (options.promptSource === "prompt-file") {
|
|
10642
|
+
return (await readFile14(options.promptFile, "utf8")).trim();
|
|
10643
|
+
}
|
|
10644
|
+
if (options.promptSource === "stdin") {
|
|
10645
|
+
const chunks = [];
|
|
10646
|
+
for await (const chunk of io.input) {
|
|
10647
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
|
|
10648
|
+
}
|
|
10649
|
+
return Buffer.concat(chunks).toString("utf8").trim();
|
|
10650
|
+
}
|
|
10651
|
+
return (options.prompt ?? "").trim();
|
|
10652
|
+
};
|
|
10653
|
+
resolveRunConfig = (options) => {
|
|
10654
|
+
const override = options.providerOverride;
|
|
10655
|
+
if (!override || !override.provider && !override.api && !override.baseUrl && !override.apiKey) {
|
|
10656
|
+
return void 0;
|
|
10657
|
+
}
|
|
10658
|
+
if (!override.baseUrl) {
|
|
10659
|
+
throw new Error("--base-url is required when overriding the run provider");
|
|
10660
|
+
}
|
|
10661
|
+
if (!override.apiKey) {
|
|
10662
|
+
throw new Error("--api-key is required when overriding the run provider");
|
|
10663
|
+
}
|
|
10664
|
+
if (!options.modelSelection?.modelId) {
|
|
10665
|
+
throw new Error("--model <model-id> is required when overriding the run provider");
|
|
10666
|
+
}
|
|
10667
|
+
const providerId = "run";
|
|
10668
|
+
const providerModelId = "run_model";
|
|
10669
|
+
const availableModelId = options.modelSelection.modelId;
|
|
10670
|
+
return {
|
|
10671
|
+
providers: {
|
|
10672
|
+
[providerId]: {
|
|
10673
|
+
type: "custom",
|
|
10674
|
+
api: override.api ?? "openai-completions",
|
|
10675
|
+
provider: override.provider ?? "openai",
|
|
10676
|
+
baseUrl: stripTrailingSlashes2(override.baseUrl),
|
|
10677
|
+
apiKey: override.apiKey
|
|
10678
|
+
}
|
|
10679
|
+
},
|
|
10680
|
+
providerModels: {
|
|
10681
|
+
[providerModelId]: {
|
|
10682
|
+
provider: providerId,
|
|
10683
|
+
id: availableModelId,
|
|
10684
|
+
displayName: availableModelId
|
|
10685
|
+
}
|
|
10686
|
+
},
|
|
10687
|
+
models: {
|
|
10688
|
+
[availableModelId]: {
|
|
10689
|
+
model: providerModelId,
|
|
10690
|
+
displayName: availableModelId
|
|
10691
|
+
}
|
|
10692
|
+
},
|
|
10693
|
+
modelProfile: {
|
|
10694
|
+
roles: {
|
|
10695
|
+
primary: availableModelId,
|
|
10696
|
+
standard: availableModelId,
|
|
10697
|
+
auxiliary: availableModelId
|
|
10698
|
+
}
|
|
10699
|
+
},
|
|
10700
|
+
memory: {
|
|
10701
|
+
enabled: false,
|
|
10702
|
+
daily: false,
|
|
10703
|
+
sessionMemory: false,
|
|
10704
|
+
autoDream: false,
|
|
10705
|
+
promoteRoot: false,
|
|
10706
|
+
dreamIdleMinutes: 60,
|
|
10707
|
+
autoCompactThreshold: 0.8
|
|
10708
|
+
},
|
|
10709
|
+
runtime: {
|
|
10710
|
+
tokenSavingRtk: false
|
|
10711
|
+
},
|
|
10712
|
+
extensions: {}
|
|
10713
|
+
};
|
|
10714
|
+
};
|
|
10715
|
+
stripTrailingSlashes2 = (value) => value.replace(/\/+$/, "");
|
|
10378
10716
|
createSigintHandler = (options) => {
|
|
10379
10717
|
return () => {
|
|
10380
10718
|
if (options.isInFlight()) {
|
|
@@ -10385,14 +10723,14 @@ var init_index = __esm({
|
|
|
10385
10723
|
options.exit();
|
|
10386
10724
|
};
|
|
10387
10725
|
};
|
|
10388
|
-
loadOrCreateSession = async (client,
|
|
10726
|
+
loadOrCreateSession = async (client, sessionId, projectId, modelSelection) => {
|
|
10389
10727
|
try {
|
|
10390
|
-
await client.loadSession(
|
|
10728
|
+
await client.loadSession(sessionId);
|
|
10391
10729
|
return true;
|
|
10392
10730
|
} catch {
|
|
10393
10731
|
await client.createSession({
|
|
10394
|
-
sessionId
|
|
10395
|
-
meta: { projectId }
|
|
10732
|
+
sessionId,
|
|
10733
|
+
meta: { projectId, ...modelSelection ? { modelSelection } : {} }
|
|
10396
10734
|
});
|
|
10397
10735
|
return false;
|
|
10398
10736
|
}
|
|
@@ -10417,6 +10755,152 @@ var init_index = __esm({
|
|
|
10417
10755
|
const sessionsDir = defaultSessionsDir();
|
|
10418
10756
|
return { sessionId, sessionsDir, stateDir: stateDirFromSessionsDir(sessionsDir), cwd };
|
|
10419
10757
|
};
|
|
10758
|
+
parseRunOptions = (argv, runOptions) => {
|
|
10759
|
+
const promptSources = [];
|
|
10760
|
+
let sessionId = asSessionId(`ses_run_${Date.now().toString(36)}`);
|
|
10761
|
+
let cwd = process.cwd();
|
|
10762
|
+
let stateDir;
|
|
10763
|
+
let sessionsDir = runOptions.sessionsDir;
|
|
10764
|
+
let timeoutMs;
|
|
10765
|
+
let outputFormat = "text";
|
|
10766
|
+
let summaryPath;
|
|
10767
|
+
let quiet = false;
|
|
10768
|
+
let modelSelection;
|
|
10769
|
+
const providerOverride = {};
|
|
10770
|
+
const positional = [];
|
|
10771
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
10772
|
+
const arg = argv[index];
|
|
10773
|
+
if (arg === "--prompt") {
|
|
10774
|
+
promptSources.push({ promptSource: "prompt", prompt: requireValue6(argv, index, "--prompt") });
|
|
10775
|
+
index += 1;
|
|
10776
|
+
continue;
|
|
10777
|
+
}
|
|
10778
|
+
if (arg === "--prompt-file") {
|
|
10779
|
+
promptSources.push({ promptSource: "prompt-file", promptFile: requireValue6(argv, index, "--prompt-file") });
|
|
10780
|
+
index += 1;
|
|
10781
|
+
continue;
|
|
10782
|
+
}
|
|
10783
|
+
if (arg === "--stdin") {
|
|
10784
|
+
promptSources.push({ promptSource: "stdin" });
|
|
10785
|
+
continue;
|
|
10786
|
+
}
|
|
10787
|
+
if (arg === "--session") {
|
|
10788
|
+
sessionId = asSessionId(requireValue6(argv, index, "--session"));
|
|
10789
|
+
index += 1;
|
|
10790
|
+
continue;
|
|
10791
|
+
}
|
|
10792
|
+
if (arg === "--cwd") {
|
|
10793
|
+
cwd = requireValue6(argv, index, "--cwd");
|
|
10794
|
+
index += 1;
|
|
10795
|
+
continue;
|
|
10796
|
+
}
|
|
10797
|
+
if (arg === "--state-dir") {
|
|
10798
|
+
stateDir = requireValue6(argv, index, "--state-dir");
|
|
10799
|
+
index += 1;
|
|
10800
|
+
continue;
|
|
10801
|
+
}
|
|
10802
|
+
if (arg === "--sessions-dir") {
|
|
10803
|
+
sessionsDir = requireValue6(argv, index, "--sessions-dir");
|
|
10804
|
+
index += 1;
|
|
10805
|
+
continue;
|
|
10806
|
+
}
|
|
10807
|
+
if (arg === "--timeout-ms") {
|
|
10808
|
+
timeoutMs = parsePositiveInteger(requireValue6(argv, index, "--timeout-ms"), "--timeout-ms");
|
|
10809
|
+
index += 1;
|
|
10810
|
+
continue;
|
|
10811
|
+
}
|
|
10812
|
+
if (arg === "--output-format") {
|
|
10813
|
+
outputFormat = parseRunOutputFormat(requireValue6(argv, index, "--output-format"));
|
|
10814
|
+
index += 1;
|
|
10815
|
+
continue;
|
|
10816
|
+
}
|
|
10817
|
+
if (arg === "--summary") {
|
|
10818
|
+
summaryPath = requireValue6(argv, index, "--summary");
|
|
10819
|
+
index += 1;
|
|
10820
|
+
continue;
|
|
10821
|
+
}
|
|
10822
|
+
if (arg === "--quiet") {
|
|
10823
|
+
quiet = true;
|
|
10824
|
+
continue;
|
|
10825
|
+
}
|
|
10826
|
+
if (arg === "--model") {
|
|
10827
|
+
modelSelection = parseModelSelection(requireValue6(argv, index, "--model"));
|
|
10828
|
+
index += 1;
|
|
10829
|
+
continue;
|
|
10830
|
+
}
|
|
10831
|
+
if (arg === "--provider") {
|
|
10832
|
+
providerOverride.provider = requireValue6(argv, index, "--provider");
|
|
10833
|
+
index += 1;
|
|
10834
|
+
continue;
|
|
10835
|
+
}
|
|
10836
|
+
if (arg === "--api" || arg === "--protocol") {
|
|
10837
|
+
providerOverride.api = parseRunProviderApi(requireValue6(argv, index, arg));
|
|
10838
|
+
index += 1;
|
|
10839
|
+
continue;
|
|
10840
|
+
}
|
|
10841
|
+
if (arg === "--base-url" || arg === "--baseurl") {
|
|
10842
|
+
providerOverride.baseUrl = requireValue6(argv, index, arg);
|
|
10843
|
+
index += 1;
|
|
10844
|
+
continue;
|
|
10845
|
+
}
|
|
10846
|
+
if (arg === "--api-key" || arg === "--apikey") {
|
|
10847
|
+
providerOverride.apiKey = requireValue6(argv, index, arg);
|
|
10848
|
+
index += 1;
|
|
10849
|
+
continue;
|
|
10850
|
+
}
|
|
10851
|
+
if (arg.startsWith("-")) {
|
|
10852
|
+
throw new Error(`Unknown run option: ${arg}`);
|
|
10853
|
+
}
|
|
10854
|
+
positional.push(arg);
|
|
10855
|
+
}
|
|
10856
|
+
if (positional.length > 0) {
|
|
10857
|
+
promptSources.unshift({ promptSource: "argument", prompt: positional.join(" ") });
|
|
10858
|
+
}
|
|
10859
|
+
if (promptSources.length !== 1) {
|
|
10860
|
+
throw new Error("scorel run requires exactly one prompt source");
|
|
10861
|
+
}
|
|
10862
|
+
const resolvedStateDir = stateDir ?? stateDirFromSessionsDir(sessionsDir);
|
|
10863
|
+
const resolvedSessionsDir = sessionsDir ?? join17(resolvedStateDir, "sessions");
|
|
10864
|
+
return {
|
|
10865
|
+
...promptSources[0],
|
|
10866
|
+
sessionId,
|
|
10867
|
+
cwd,
|
|
10868
|
+
stateDir: resolvedStateDir,
|
|
10869
|
+
sessionsDir: resolvedSessionsDir,
|
|
10870
|
+
timeoutMs,
|
|
10871
|
+
outputFormat,
|
|
10872
|
+
summaryPath,
|
|
10873
|
+
quiet,
|
|
10874
|
+
modelSelection,
|
|
10875
|
+
providerOverride,
|
|
10876
|
+
config: runOptions.config
|
|
10877
|
+
};
|
|
10878
|
+
};
|
|
10879
|
+
parseRunOutputFormat = (value) => {
|
|
10880
|
+
if (value === "text" || value === "json" || value === "stream-json" || value === "none") {
|
|
10881
|
+
return value;
|
|
10882
|
+
}
|
|
10883
|
+
throw new Error("--output-format must be text, json, stream-json, or none");
|
|
10884
|
+
};
|
|
10885
|
+
parsePositiveInteger = (value, flag) => {
|
|
10886
|
+
const parsed = Number(value);
|
|
10887
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
10888
|
+
throw new Error(`${flag} must be a positive integer`);
|
|
10889
|
+
}
|
|
10890
|
+
return parsed;
|
|
10891
|
+
};
|
|
10892
|
+
parseModelSelection = (value) => {
|
|
10893
|
+
if (value === "primary" || value === "standard" || value === "auxiliary") {
|
|
10894
|
+
return { role: value };
|
|
10895
|
+
}
|
|
10896
|
+
return { modelId: value };
|
|
10897
|
+
};
|
|
10898
|
+
parseRunProviderApi = (value) => {
|
|
10899
|
+
if (value === "openai-completions" || value === "openai-responses" || value === "google-generative-ai" || value === "anthropic-messages") {
|
|
10900
|
+
return value;
|
|
10901
|
+
}
|
|
10902
|
+
throw new Error("--api must be openai-completions, openai-responses, google-generative-ai, or anthropic-messages");
|
|
10903
|
+
};
|
|
10420
10904
|
requireValue6 = (argv, index, flag) => {
|
|
10421
10905
|
const value = argv[index + 1];
|
|
10422
10906
|
if (!value) {
|
|
@@ -10434,6 +10918,12 @@ var init_index = __esm({
|
|
|
10434
10918
|
[
|
|
10435
10919
|
"Usage: scorel chat [--session <id>] [--cwd <dir>]",
|
|
10436
10920
|
" scorel [--session <id>] [--cwd <dir>]",
|
|
10921
|
+
" scorel run [prompt] [--prompt <text> | --prompt-file <path> | --stdin]",
|
|
10922
|
+
" [--cwd <dir>] [--state-dir <dir>] [--sessions-dir <dir>]",
|
|
10923
|
+
" [--session <id>] [--timeout-ms <ms>]",
|
|
10924
|
+
" [--output-format text|json|stream-json|none] [--summary <path>]",
|
|
10925
|
+
" [--provider <name>] [--api|--protocol <protocol>]",
|
|
10926
|
+
" [--base-url|--baseurl <url>] [--api-key|--apikey <key>] [--model <id>]",
|
|
10437
10927
|
" scorel attach --session <id> --remote <ws-url> --token <token>",
|
|
10438
10928
|
" scorel host start [--host <h>] [--port <p>] [--token <t>] [--project <dir>]",
|
|
10439
10929
|
" [--relay <relay-url> | --no-relay] [--replace] [--idle-timeout-ms <ms>]",
|
|
@@ -10456,6 +10946,37 @@ var init_index = __esm({
|
|
|
10456
10946
|
].join("\n") + "\n"
|
|
10457
10947
|
);
|
|
10458
10948
|
};
|
|
10949
|
+
writeRunUsage = (output) => {
|
|
10950
|
+
output.write(
|
|
10951
|
+
[
|
|
10952
|
+
"Usage: scorel run [prompt]",
|
|
10953
|
+
" scorel run --prompt <text>",
|
|
10954
|
+
" scorel run --prompt-file <path>",
|
|
10955
|
+
" scorel run --stdin",
|
|
10956
|
+
"",
|
|
10957
|
+
"Options:",
|
|
10958
|
+
" --cwd <dir>",
|
|
10959
|
+
" --state-dir <dir>",
|
|
10960
|
+
" --sessions-dir <dir>",
|
|
10961
|
+
" --session <id>",
|
|
10962
|
+
" --timeout-ms <ms>",
|
|
10963
|
+
" --output-format text|json|stream-json|none",
|
|
10964
|
+
" --summary <path>",
|
|
10965
|
+
" --quiet",
|
|
10966
|
+
" --model <primary|standard|auxiliary|model-id>",
|
|
10967
|
+
" --provider <name>",
|
|
10968
|
+
" --api, --protocol <openai-completions|openai-responses|google-generative-ai|anthropic-messages>",
|
|
10969
|
+
" --base-url, --baseurl <url>",
|
|
10970
|
+
" --api-key, --apikey <key>",
|
|
10971
|
+
"",
|
|
10972
|
+
"Examples:",
|
|
10973
|
+
' scorel run --prompt "Summarize this project" --output-format json',
|
|
10974
|
+
" scorel run --prompt-file /tmp/instruction.txt --cwd /workspace --state-dir /tmp/scorel-state \\",
|
|
10975
|
+
' --api openai-completions --baseurl http://127.0.0.1:4000/v1 --apikey "$API_KEY" \\',
|
|
10976
|
+
" --model gpt-5.4-mini --output-format none --summary /logs/agent/scorel-summary.json"
|
|
10977
|
+
].join("\n") + "\n"
|
|
10978
|
+
);
|
|
10979
|
+
};
|
|
10459
10980
|
writeProjectUsage = (output) => {
|
|
10460
10981
|
output.write("Usage: scorel project list | add <dir> | remove <project-id>\n");
|
|
10461
10982
|
};
|
|
@@ -10575,7 +11096,18 @@ ${text}
|
|
|
10575
11096
|
this.#atLineStart = text.endsWith("\n");
|
|
10576
11097
|
}
|
|
10577
11098
|
};
|
|
10578
|
-
blocksToText = (blocks) => blocks.
|
|
11099
|
+
blocksToText = (blocks) => blocks.flatMap((block) => {
|
|
11100
|
+
if (block.type === "text") {
|
|
11101
|
+
if (block.visibility === "model") {
|
|
11102
|
+
return [];
|
|
11103
|
+
}
|
|
11104
|
+
return [block.text];
|
|
11105
|
+
}
|
|
11106
|
+
if (block.type === "system_reminder" && block.visibility !== "model") {
|
|
11107
|
+
return [block.text];
|
|
11108
|
+
}
|
|
11109
|
+
return [];
|
|
11110
|
+
}).join("");
|
|
10579
11111
|
isCliEntrypoint = async () => {
|
|
10580
11112
|
if (!process.argv[1]) return false;
|
|
10581
11113
|
const [argvPath, modulePath] = await Promise.all([
|