agentlas 1.0.57 → 1.0.59
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.
|
@@ -167,7 +167,28 @@ function listGraphs(ctx) {
|
|
|
167
167
|
* 판단은 노드마다 둘 중 하나다 — "이미 일어났다(--done)" / "확실히 안 일어났다(--not-done)".
|
|
168
168
|
* 아무 것도 주지 않으면 무엇을 정해야 하는지 보여 주기만 한다. 실행 중에 묻지 않는다.
|
|
169
169
|
*/
|
|
170
|
-
|
|
170
|
+
/**
|
|
171
|
+
* 엔진을 손에 넣는다 — 캐시에 없으면 **받는다**.
|
|
172
|
+
*
|
|
173
|
+
* ★엔진이 필요한 명령은 전부 이 길을 지나야 한다. 실측 2026-08-20: `graph run` 은 이걸
|
|
174
|
+
* 고쳤는데, 바로 뒤에 만든 `graph reconcile` 이 동기 로더만 불러 같은 병을 반복했다 —
|
|
175
|
+
* 새로 설치한 사람에게는 "이 엔진에는 재조정 기능이 없습니다" 로 보인다(사실은 엔진이
|
|
176
|
+
* 아직 없는 것이다). 한 곳으로 모아 다음 명령이 또 빠뜨리지 않게 한다.
|
|
177
|
+
*/
|
|
178
|
+
async function acquireCore(ctx) {
|
|
179
|
+
const desktopCore = require("../core/desktop-core.cjs");
|
|
180
|
+
let core = ctx.desktopCore || desktopCore.loadDesktopCore();
|
|
181
|
+
if (!core || core.error || typeof core.runGraph !== "function") {
|
|
182
|
+
try {
|
|
183
|
+
core = await desktopCore.loadDesktopCoreAsync({ onNotice: (message) => ctx.err(message) });
|
|
184
|
+
} catch {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return core && !core.error ? core : null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function reconcileGraph(ctx, needle, flags, en) {
|
|
171
192
|
const rows = graphRows(ctx, ctx.db());
|
|
172
193
|
const row = findGraph(rows, needle);
|
|
173
194
|
if (row?.ambiguous) { reportAmbiguous(ctx, needle, row.ambiguous, en); return 1; }
|
|
@@ -175,7 +196,7 @@ function reconcileGraph(ctx, needle, flags, en) {
|
|
|
175
196
|
ctx.err(en ? `No graph matches "${needle}".` : `"${needle}"와 맞는 그래프가 없습니다.`);
|
|
176
197
|
return 1;
|
|
177
198
|
}
|
|
178
|
-
const core =
|
|
199
|
+
const core = await acquireCore(ctx);
|
|
179
200
|
const reconciliation = core && core.graphReconciliation;
|
|
180
201
|
if (!reconciliation || typeof reconciliation.get !== "function") {
|
|
181
202
|
ctx.err(en
|
|
@@ -183,6 +204,35 @@ function reconcileGraph(ctx, needle, flags, en) {
|
|
|
183
204
|
: "이 엔진에는 재조정 기능이 없습니다. CLI를 업데이트한 뒤(`npm i -g agentlas@latest`) 다시 시도하세요.");
|
|
184
205
|
return 1;
|
|
185
206
|
}
|
|
207
|
+
// 그래프를 고친 뒤에는 옛 좌표가 그 그래프의 것이 아니라 재조정도 거절된다. 그 상태는
|
|
208
|
+
// 실행도 재조정도 안 되는 잠김이므로, 사람이 스스로 나갈 문을 둔다.
|
|
209
|
+
if (flags && flags['start-over']) {
|
|
210
|
+
if (typeof reconciliation.forgetStale !== 'function') {
|
|
211
|
+
ctx.err(en ? 'This engine build cannot do that. Update the CLI and try again.' : '이 엔진에는 그 기능이 없습니다. CLI를 업데이트한 뒤 다시 시도하세요.');
|
|
212
|
+
return 1;
|
|
213
|
+
}
|
|
214
|
+
const graph = parseGraph(row);
|
|
215
|
+
const automation = core.getAutomation ? core.getAutomation(row.id) : null;
|
|
216
|
+
const digest = core.graphExecutionDigest && automation && graph
|
|
217
|
+
? core.graphExecutionDigest(automation, graph)
|
|
218
|
+
: null;
|
|
219
|
+
if (!digest) {
|
|
220
|
+
ctx.err(en ? 'Could not compute the current graph identity.' : '지금 그래프의 신원을 계산하지 못했습니다.');
|
|
221
|
+
return 1;
|
|
222
|
+
}
|
|
223
|
+
const outcome = reconciliation.forgetStale(row.id, digest);
|
|
224
|
+
if (!outcome.forgot) {
|
|
225
|
+
ctx.err(en
|
|
226
|
+
? `Nothing to forget (${outcome.reason}). If the graph has not changed, decide each step instead.`
|
|
227
|
+
: `잊을 것이 없습니다(${outcome.reason}). 그래프가 그대로라면, 단계마다 정하는 쪽이 맞습니다.`);
|
|
228
|
+
return 1;
|
|
229
|
+
}
|
|
230
|
+
ctx.out(en
|
|
231
|
+
? 'The earlier run is forgotten. Note: whatever it already did can happen again on the next run.'
|
|
232
|
+
: '이전 실행을 잊었습니다. 그 실행이 이미 한 일은 다음 실행에서 다시 일어날 수 있습니다.');
|
|
233
|
+
return 0;
|
|
234
|
+
}
|
|
235
|
+
|
|
186
236
|
const view = reconciliation.get(row.id);
|
|
187
237
|
if (!view) {
|
|
188
238
|
ctx.out(en
|
|
@@ -606,7 +656,7 @@ async function runGraph(ctx, needle, flags) {
|
|
|
606
656
|
// 시작 값이 필요한 그래프는 값 없이 요청하지 않는다. 값 없이 보내면 빈 채로 실행돼,
|
|
607
657
|
// 사용자가 요청한 적 없는 내용이 만들어진다.
|
|
608
658
|
const requirement = graphInputRequirement(graph, en);
|
|
609
|
-
if (requirement && !flags.input) {
|
|
659
|
+
if (requirement && !flags.inputProvided && !flags.input) {
|
|
610
660
|
ctx.err(en
|
|
611
661
|
? `"${row.name}" starts from a value you provide — ${requirement.label}.`
|
|
612
662
|
: `"${row.name}"은(는) 시작할 때 값을 받습니다 — ${requirement.label}.`);
|
|
@@ -626,7 +676,7 @@ async function runGraph(ctx, needle, flags) {
|
|
|
626
676
|
createdBy: row.created_by || "terminal",
|
|
627
677
|
graph,
|
|
628
678
|
};
|
|
629
|
-
const initialVars = requirement && flags.input ? { [requirement.varName]: flags.input } : {};
|
|
679
|
+
const initialVars = requirement && (flags.inputProvided || flags.input) ? { [requirement.varName]: flags.input } : {};
|
|
630
680
|
|
|
631
681
|
/*
|
|
632
682
|
* ★데몬 우선 (Phase 3). 데몬이 떠 있으면 이 터미널은 코어를 **로드하지 않는다** —
|
|
@@ -668,19 +718,10 @@ async function runGraph(ctx, needle, flags) {
|
|
|
668
718
|
*
|
|
669
719
|
* 받는 동안은 조용하지 않다(onNotice) — 12MB 를 말없이 끌어오지 않는다.
|
|
670
720
|
*/
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
} catch (fetchError) {
|
|
676
|
-
ctx.err(JSON.stringify({
|
|
677
|
-
ok: false,
|
|
678
|
-
error: `graph-execution engine could not be fetched: ${fetchError instanceof Error ? fetchError.message : String(fetchError)}`,
|
|
679
|
-
}, null, 2));
|
|
680
|
-
return 1;
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
if (!core || core.error || typeof core.runGraph !== "function") {
|
|
721
|
+
// ★엔진을 얻는 법을 아는 곳은 acquireCore 하나뿐이다 — 둘이면 다음에 만드는 명령이
|
|
722
|
+
// 또 한쪽만 보고 캐시에서 끝난다(실측 2026-08-20: reconcile 이 정확히 그랬다).
|
|
723
|
+
let core = await acquireCore(ctx);
|
|
724
|
+
if (!core || typeof core.runGraph !== "function") {
|
|
684
725
|
const cause = core?.error instanceof Error ? core.error.message : "vendored Desktop Core is unavailable";
|
|
685
726
|
ctx.err(JSON.stringify({ ok: false, error: cause }, null, 2));
|
|
686
727
|
return 1;
|
|
@@ -1257,8 +1298,11 @@ async function run(ctx, args = []) {
|
|
|
1257
1298
|
for (let i = 0; i < args.length; i += 1) {
|
|
1258
1299
|
const arg = args[i];
|
|
1259
1300
|
if (arg === "-y" || arg === "--yes") { flags.yes = true; continue; }
|
|
1260
|
-
if (arg === "--
|
|
1261
|
-
|
|
1301
|
+
if (arg === "--start-over") { flags["start-over"] = true; continue; }
|
|
1302
|
+
// ★"안 줬다"와 "빈 값을 줬다"는 다르다. 그래프가 "비워 두면 최신 값을 씁니다"라고
|
|
1303
|
+
// 안내해도, 빈 문자열을 못 줘서 그 선택지를 고를 수 없었다(실측 2026-08-20).
|
|
1304
|
+
if (arg === "--input" || arg === "-i") { flags.input = String(args[i + 1] ?? "").trim(); flags.inputProvided = true; i += 1; continue; }
|
|
1305
|
+
if (arg.startsWith("--input=")) { flags.input = arg.slice("--input=".length).trim(); flags.inputProvided = true; continue; }
|
|
1262
1306
|
// ★--name 도 값을 하나 받는 플래그다. 걷어내지 않으면 그 값이 파일 경로에 붙어
|
|
1263
1307
|
// "그런 파일 없음"으로 죽는다 — `graph help`가 문법으로 광고하는 옵션인데
|
|
1264
1308
|
// 실제로는 한 번도 동작한 적이 없었다(실사용 실측 2026-08-06).
|
|
@@ -1320,7 +1364,7 @@ async function run(ctx, args = []) {
|
|
|
1320
1364
|
: "사용법: agentlas graph reconcile \"<이름>\" [--done <노드>] [--not-done <노드>] [--output <노드>=<값>]");
|
|
1321
1365
|
return 1;
|
|
1322
1366
|
}
|
|
1323
|
-
return reconcileGraph(ctx, target, flags, en);
|
|
1367
|
+
return await reconcileGraph(ctx, target, flags, en);
|
|
1324
1368
|
}
|
|
1325
1369
|
if (sub === "export") {
|
|
1326
1370
|
if (!target) {
|
|
@@ -231,6 +231,12 @@ function loadDesktopCore(options = {}) {
|
|
|
231
231
|
initStore: req("store/db").initStore,
|
|
232
232
|
getDb: req("store/db").getDb,
|
|
233
233
|
runGraph: kernel.runGraph,
|
|
234
|
+
getAutomation: req("store/automations").getAutomation,
|
|
235
|
+
// shared/ 는 electron/ 밖이라 req 로 못 닿는다 — 직접 해석한다.
|
|
236
|
+
graphExecutionDigest: (() => {
|
|
237
|
+
try { return require(path.join(root, "shared", "graph-execution-digest.js")).graphExecutionDigest; }
|
|
238
|
+
catch { return null; }
|
|
239
|
+
})(),
|
|
234
240
|
graphFailureOf: kernel.graphFailureOf,
|
|
235
241
|
planGraphLoops: kernel.planGraphLoops,
|
|
236
242
|
/*
|
|
@@ -246,6 +252,7 @@ function loadDesktopCore(options = {}) {
|
|
|
246
252
|
return {
|
|
247
253
|
get: mod.getAutomationGraphReconciliation,
|
|
248
254
|
apply: mod.reconcileAutomationGraph,
|
|
255
|
+
forgetStale: mod.forgetStaleGraphCheckpoint,
|
|
249
256
|
};
|
|
250
257
|
} catch {
|
|
251
258
|
return null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
3
|
-
"url": "https://github.com/agentlas-ai/agentlas-terminal/releases/download/desktop-core-
|
|
4
|
-
"sha256": "
|
|
5
|
-
"sizeBytes":
|
|
6
|
-
"writtenAt": "2026-08-
|
|
2
|
+
"version": "11",
|
|
3
|
+
"url": "https://github.com/agentlas-ai/agentlas-terminal/releases/download/desktop-core-v11/desktop-core.tar.gz",
|
|
4
|
+
"sha256": "c68cddd2cd4ee6978903a7a1bea39fbdce218c1dcbaa74165231ea99bbd1999e",
|
|
5
|
+
"sizeBytes": 12557470,
|
|
6
|
+
"writtenAt": "2026-08-19T22:35:51.167Z"
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentlas",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.59",
|
|
4
4
|
"description": "Agentlas project terminal — run project controllers and task-scoped agent teams from the terminal. Standalone: no desktop app process required.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agentlas": "bin/agentlas.cjs"
|