@pqpo/pragma 0.1.0-next.14 → 0.1.0-next.15
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/dist/cli.js +158 -20
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -35515,6 +35515,25 @@ var init_output = __esm({
|
|
|
35515
35515
|
}
|
|
35516
35516
|
});
|
|
35517
35517
|
|
|
35518
|
+
// packages/core/dist/execution/human-interaction-checkpoint.js
|
|
35519
|
+
function isHumanInteractionCheckpointError(error53) {
|
|
35520
|
+
return error53 instanceof HumanInteractionCheckpointError;
|
|
35521
|
+
}
|
|
35522
|
+
var HumanInteractionCheckpointError;
|
|
35523
|
+
var init_human_interaction_checkpoint = __esm({
|
|
35524
|
+
"packages/core/dist/execution/human-interaction-checkpoint.js"() {
|
|
35525
|
+
"use strict";
|
|
35526
|
+
HumanInteractionCheckpointError = class extends Error {
|
|
35527
|
+
executionId;
|
|
35528
|
+
constructor(executionId) {
|
|
35529
|
+
super(`Execution checkpointed while waiting for human input: ${executionId}`);
|
|
35530
|
+
this.executionId = executionId;
|
|
35531
|
+
this.name = "HumanInteractionCheckpointError";
|
|
35532
|
+
}
|
|
35533
|
+
};
|
|
35534
|
+
}
|
|
35535
|
+
});
|
|
35536
|
+
|
|
35518
35537
|
// packages/core/dist/execution/expert-orchestrator.js
|
|
35519
35538
|
import { createHash as createHash6, randomUUID as randomUUID11 } from "node:crypto";
|
|
35520
35539
|
function collectDescendantInvocationIds(invocations, ownerInvocationId) {
|
|
@@ -35679,6 +35698,7 @@ var init_expert_orchestrator = __esm({
|
|
|
35679
35698
|
init_invocation_service();
|
|
35680
35699
|
init_context_resolution_service();
|
|
35681
35700
|
init_context_id_resolver();
|
|
35701
|
+
init_human_interaction_checkpoint();
|
|
35682
35702
|
MAX_EXPERT_MESSAGE_CHARACTERS = 1e5;
|
|
35683
35703
|
MAX_PENDING_EXPERT_MESSAGES = 128;
|
|
35684
35704
|
MAX_PENDING_EXPERT_MESSAGE_BYTES = 1024 * 1024;
|
|
@@ -36401,6 +36421,7 @@ var init_expert_orchestrator = __esm({
|
|
|
36401
36421
|
}
|
|
36402
36422
|
}
|
|
36403
36423
|
async executeActiveJob(options2) {
|
|
36424
|
+
let checkpointed = false;
|
|
36404
36425
|
try {
|
|
36405
36426
|
await this.options.store.commit({
|
|
36406
36427
|
commitId: `agent-activated:${options2.invocation.invocationId}:${randomUUID11()}`,
|
|
@@ -36427,15 +36448,19 @@ var init_expert_orchestrator = __esm({
|
|
|
36427
36448
|
prompt: options2.prompt,
|
|
36428
36449
|
permit: options2.permit
|
|
36429
36450
|
});
|
|
36430
|
-
} catch {
|
|
36431
|
-
|
|
36432
|
-
|
|
36433
|
-
|
|
36451
|
+
} catch (error53) {
|
|
36452
|
+
if (isHumanInteractionCheckpointError(error53)) {
|
|
36453
|
+
checkpointed = true;
|
|
36454
|
+
} else {
|
|
36455
|
+
const current = await this.options.store.getInvocation(this.options.executionId, options2.invocation.invocationId);
|
|
36456
|
+
if (current !== void 0 && !isTerminalExecutionStatus(current.status)) {
|
|
36457
|
+
await this.failUnrecoverableJob(current, "Expert task failed before reaching a terminal state.");
|
|
36458
|
+
}
|
|
36434
36459
|
}
|
|
36435
36460
|
} finally {
|
|
36436
36461
|
try {
|
|
36437
36462
|
const currentAgent = await this.options.store.getAgent(this.options.executionId, options2.agentId);
|
|
36438
|
-
if (currentAgent?.activeInvocationId === options2.invocation.invocationId) {
|
|
36463
|
+
if (!checkpointed && currentAgent?.activeInvocationId === options2.invocation.invocationId) {
|
|
36439
36464
|
await this.options.store.commit({
|
|
36440
36465
|
commitId: `agent-idle:${options2.invocation.invocationId}`,
|
|
36441
36466
|
executionId: this.options.executionId,
|
|
@@ -37218,9 +37243,6 @@ var init_expert_prompt = __esm({
|
|
|
37218
37243
|
|
|
37219
37244
|
// packages/core/dist/execution/expert-runner.js
|
|
37220
37245
|
import { createHash as createHash7, randomUUID as randomUUID12 } from "node:crypto";
|
|
37221
|
-
function isHumanInteractionCheckpointError(error53) {
|
|
37222
|
-
return error53 instanceof HumanInteractionCheckpointError;
|
|
37223
|
-
}
|
|
37224
37246
|
async function listPendingHumanInteractionIds(store, executionId) {
|
|
37225
37247
|
return (await readPendingHumanInteractions(store, executionId)).map((interaction) => interaction.interactionId);
|
|
37226
37248
|
}
|
|
@@ -38325,7 +38347,7 @@ async function validateDelegatedRuntimeRouting(options2, delegation, parentRunti
|
|
|
38325
38347
|
function sameRuntimeBinding2(left, right) {
|
|
38326
38348
|
return left.runtimeId === right.runtimeId && left.revision === right.revision && left.fingerprint === right.fingerprint;
|
|
38327
38349
|
}
|
|
38328
|
-
var AUTOMATIC_EXPERT_WAIT_TIMEOUT_MS,
|
|
38350
|
+
var AUTOMATIC_EXPERT_WAIT_TIMEOUT_MS, ExecutionController;
|
|
38329
38351
|
var init_expert_runner = __esm({
|
|
38330
38352
|
"packages/core/dist/execution/expert-runner.js"() {
|
|
38331
38353
|
"use strict";
|
|
@@ -38355,15 +38377,9 @@ var init_expert_runner = __esm({
|
|
|
38355
38377
|
init_runtime_session_pool();
|
|
38356
38378
|
init_context_output_service();
|
|
38357
38379
|
init_expert_prompt();
|
|
38380
|
+
init_human_interaction_checkpoint();
|
|
38381
|
+
init_human_interaction_checkpoint();
|
|
38358
38382
|
AUTOMATIC_EXPERT_WAIT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
38359
|
-
HumanInteractionCheckpointError = class extends Error {
|
|
38360
|
-
executionId;
|
|
38361
|
-
constructor(executionId) {
|
|
38362
|
-
super(`Execution checkpointed while waiting for human input: ${executionId}`);
|
|
38363
|
-
this.executionId = executionId;
|
|
38364
|
-
this.name = "HumanInteractionCheckpointError";
|
|
38365
|
-
}
|
|
38366
|
-
};
|
|
38367
38383
|
ExecutionController = class {
|
|
38368
38384
|
executionId;
|
|
38369
38385
|
store;
|
|
@@ -38459,7 +38475,7 @@ var init_expert_runner = __esm({
|
|
|
38459
38475
|
signal.abort(checkpoint);
|
|
38460
38476
|
const submission = this.activeRuntimeSubmissions.get(invocationId);
|
|
38461
38477
|
if (submission !== void 0) {
|
|
38462
|
-
runtimeStops.push(
|
|
38478
|
+
runtimeStops.push((async () => await submission.handle.cancel())());
|
|
38463
38479
|
}
|
|
38464
38480
|
}
|
|
38465
38481
|
for (const interaction of pending)
|
|
@@ -39245,6 +39261,57 @@ var init_expert_session = __esm({
|
|
|
39245
39261
|
throw error53;
|
|
39246
39262
|
}
|
|
39247
39263
|
}
|
|
39264
|
+
async recoverClosedSession(expert, request2) {
|
|
39265
|
+
const existing = this.active.get(request2.sessionId);
|
|
39266
|
+
if (existing !== void 0)
|
|
39267
|
+
return existing;
|
|
39268
|
+
if (request2.reason.trim() === "") {
|
|
39269
|
+
throw new Error("Closed ExpertSession recovery requires a reason.");
|
|
39270
|
+
}
|
|
39271
|
+
const record2 = await this.dependencies.sessions.get(request2.sessionId);
|
|
39272
|
+
if (record2 === void 0)
|
|
39273
|
+
throw new Error(`ExpertSession not found: ${request2.sessionId}`);
|
|
39274
|
+
if (record2.status !== "closed") {
|
|
39275
|
+
throw new Error(`ExpertSession is not closed: ${request2.sessionId}`);
|
|
39276
|
+
}
|
|
39277
|
+
const currentFingerprint = fingerprintExpertExecutionDefinition(expert);
|
|
39278
|
+
const definitionMatches = record2.expertId === expert.id && record2.definitionFingerprint === currentFingerprint;
|
|
39279
|
+
const rootExpert = isExpertTeam(expert) ? expert.coordinator : expert;
|
|
39280
|
+
const migration = definitionMatches ? void 0 : validateDefinitionMigration(record2, expert, currentFingerprint, request2);
|
|
39281
|
+
if (!definitionMatches && migration === void 0) {
|
|
39282
|
+
throw new ExpertDefinitionMismatchError(request2.sessionId);
|
|
39283
|
+
}
|
|
39284
|
+
const claimId = randomUUID13();
|
|
39285
|
+
const recovered = await this.dependencies.sessions.recoverClosed({
|
|
39286
|
+
sessionId: request2.sessionId,
|
|
39287
|
+
expectedUpdatedAt: record2.updatedAt,
|
|
39288
|
+
claimId,
|
|
39289
|
+
leaseMs: EXPERT_SESSION_LEASE_MS,
|
|
39290
|
+
reason: request2.reason
|
|
39291
|
+
});
|
|
39292
|
+
if (recovered === void 0) {
|
|
39293
|
+
throw new Error(`ExpertSession recovery conflict: ${request2.sessionId}`);
|
|
39294
|
+
}
|
|
39295
|
+
try {
|
|
39296
|
+
if (migration !== void 0) {
|
|
39297
|
+
await this.migrateSessionDefinition({
|
|
39298
|
+
sessionId: request2.sessionId,
|
|
39299
|
+
expertId: expert.id,
|
|
39300
|
+
rootExpertId: rootExpert.id,
|
|
39301
|
+
definitionFingerprint: currentFingerprint,
|
|
39302
|
+
previousExpertId: migration.previousExpertId,
|
|
39303
|
+
previousRootExpertId: migration.previousRootExpertId,
|
|
39304
|
+
reason: migration.reason
|
|
39305
|
+
});
|
|
39306
|
+
}
|
|
39307
|
+
const session = this.createActiveSession(expert, request2.sessionId, true, claimId);
|
|
39308
|
+
this.active.set(request2.sessionId, session);
|
|
39309
|
+
return session;
|
|
39310
|
+
} catch (error53) {
|
|
39311
|
+
await this.dependencies.sessions.releaseLease(request2.sessionId, claimId);
|
|
39312
|
+
throw error53;
|
|
39313
|
+
}
|
|
39314
|
+
}
|
|
39248
39315
|
async migrateSessionDefinition(options2) {
|
|
39249
39316
|
return await this.dependencies.sessions.transact(options2.sessionId, async ({ session, prompts }) => {
|
|
39250
39317
|
const rootContext = session.contexts[session.rootContextId];
|
|
@@ -41277,6 +41344,76 @@ function createFileExpertSessionStore(options2) {
|
|
|
41277
41344
|
return parsed.data;
|
|
41278
41345
|
});
|
|
41279
41346
|
},
|
|
41347
|
+
async recoverClosed(input2) {
|
|
41348
|
+
return await withFileLock(paths.expertSessionLock(input2.sessionId), async () => {
|
|
41349
|
+
await prepareExpertSession(paths, options2.executions, input2.sessionId);
|
|
41350
|
+
const session = ExpertSessionRecordSchema.parse(await requireJson(paths.expertSessionState(input2.sessionId), input2.sessionId));
|
|
41351
|
+
if (session.status !== "closed" || session.updatedAt !== input2.expectedUpdatedAt) {
|
|
41352
|
+
return void 0;
|
|
41353
|
+
}
|
|
41354
|
+
if (session.activeExecutionId !== void 0) {
|
|
41355
|
+
throw new Error(`Closed ExpertSession has an active Execution: ${input2.sessionId}`);
|
|
41356
|
+
}
|
|
41357
|
+
const prompts = PromptRequestSchema.array().parse(await readJson(paths.expertSessionPrompts(input2.sessionId)) ?? []);
|
|
41358
|
+
if (prompts.some((prompt) => prompt.status === "queued" || prompt.status === "running")) {
|
|
41359
|
+
throw new Error(`Closed ExpertSession has pending prompts: ${input2.sessionId}`);
|
|
41360
|
+
}
|
|
41361
|
+
for (const executionId of session.executionIds) {
|
|
41362
|
+
const execution = await options2.executions.get(executionId);
|
|
41363
|
+
if (execution !== void 0 && !isTerminalExecutionStatus(execution.status)) {
|
|
41364
|
+
throw new Error(`Closed ExpertSession has a non-terminal Execution: ${input2.sessionId}`);
|
|
41365
|
+
}
|
|
41366
|
+
}
|
|
41367
|
+
const existingValue = await readJson(paths.expertSessionLease(input2.sessionId));
|
|
41368
|
+
const existing = existingValue === void 0 ? void 0 : ExpertSessionLeaseSchema.parse(existingValue);
|
|
41369
|
+
if (existing !== void 0 && existing.claimId !== input2.claimId && Date.parse(existing.expiresAt) > Date.now() && (existing.processId === void 0 || isProcessAlive2(existing.processId))) {
|
|
41370
|
+
return void 0;
|
|
41371
|
+
}
|
|
41372
|
+
const rootContext = session.contexts[session.rootContextId];
|
|
41373
|
+
if (rootContext === void 0)
|
|
41374
|
+
throw new Error("ExpertSession root Context is missing.");
|
|
41375
|
+
const reopenedRoot = {
|
|
41376
|
+
...rootContext,
|
|
41377
|
+
lifecycle: "open",
|
|
41378
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
41379
|
+
};
|
|
41380
|
+
delete reopenedRoot.closedAt;
|
|
41381
|
+
const recovered = ExpertSessionRecordSchema.parse({
|
|
41382
|
+
...session,
|
|
41383
|
+
status: "open",
|
|
41384
|
+
contexts: { ...session.contexts, [session.rootContextId]: reopenedRoot },
|
|
41385
|
+
updatedAt: reopenedRoot.updatedAt
|
|
41386
|
+
});
|
|
41387
|
+
const events = ExpertSessionEventSchema.array().parse(await readJson(paths.expertSessionEvents(input2.sessionId)) ?? []);
|
|
41388
|
+
const journal = ExpertSessionTransactionJournalV10Schema.parse({
|
|
41389
|
+
schemaVersion: "pragma.expert-session-transaction/v10",
|
|
41390
|
+
session: recovered,
|
|
41391
|
+
prompts,
|
|
41392
|
+
events: materializeSessionEvents(input2.sessionId, events, [
|
|
41393
|
+
{
|
|
41394
|
+
eventId: `context-recovered:${session.rootContextId}:${recovered.updatedAt}`,
|
|
41395
|
+
type: "context.recovered",
|
|
41396
|
+
data: { contextId: session.rootContextId, reason: input2.reason },
|
|
41397
|
+
occurredAt: recovered.updatedAt
|
|
41398
|
+
},
|
|
41399
|
+
{
|
|
41400
|
+
eventId: `session-recovered:${recovered.updatedAt}`,
|
|
41401
|
+
type: "session.recovered",
|
|
41402
|
+
data: { reason: input2.reason },
|
|
41403
|
+
occurredAt: recovered.updatedAt
|
|
41404
|
+
}
|
|
41405
|
+
])
|
|
41406
|
+
});
|
|
41407
|
+
await writeJson(paths.expertSessionTransaction(input2.sessionId), journal);
|
|
41408
|
+
await applyTransaction2(paths, options2.executions, input2.sessionId, journal);
|
|
41409
|
+
await writeJson(paths.expertSessionLease(input2.sessionId), {
|
|
41410
|
+
claimId: input2.claimId,
|
|
41411
|
+
processId: process.pid,
|
|
41412
|
+
expiresAt: new Date(Date.now() + input2.leaseMs).toISOString()
|
|
41413
|
+
});
|
|
41414
|
+
return recovered;
|
|
41415
|
+
});
|
|
41416
|
+
},
|
|
41280
41417
|
async transact(sessionId, action) {
|
|
41281
41418
|
return await withFileLock(paths.expertSessionLock(sessionId), async () => {
|
|
41282
41419
|
await prepareExpertSession(paths, options2.executions, sessionId);
|
|
@@ -41622,7 +41759,8 @@ function createPragma(options2) {
|
|
|
41622
41759
|
return {
|
|
41623
41760
|
experts: {
|
|
41624
41761
|
createSession: async (expert, request2) => await experts.createSession(expert, request2),
|
|
41625
|
-
resumeSession: async (expert, request2) => await experts.resumeSession(expert, request2)
|
|
41762
|
+
resumeSession: async (expert, request2) => await experts.resumeSession(expert, request2),
|
|
41763
|
+
recoverClosedSession: async (expert, request2) => await experts.recoverClosedSession(expert, request2)
|
|
41626
41764
|
},
|
|
41627
41765
|
flows: {
|
|
41628
41766
|
start: async (flow, request2) => await flows.start(flow, request2),
|
|
@@ -424490,7 +424628,7 @@ init_dist13();
|
|
|
424490
424628
|
init_integration();
|
|
424491
424629
|
|
|
424492
424630
|
// apps/cli/src/version.ts
|
|
424493
|
-
var CLI_VERSION = false ? "0.0.0" : "0.1.0-next.
|
|
424631
|
+
var CLI_VERSION = false ? "0.0.0" : "0.1.0-next.15";
|
|
424494
424632
|
|
|
424495
424633
|
// apps/cli/src/composition/default.ts
|
|
424496
424634
|
function createCliLocalHost(input2 = {}) {
|