@hunterzhu/pulse-runtime 0.1.5 → 0.1.7
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/context/builder.d.ts +6 -1
- package/dist/context/builder.js +37 -4
- package/dist/core/inbox.d.ts +6 -0
- package/dist/core/inbox.js +31 -7
- package/dist/core/mutations.d.ts +5 -1
- package/dist/core/mutations.js +5 -1
- package/dist/core/types.d.ts +26 -1
- package/dist/core/types.js +1 -1
- package/dist/dsl/program.d.ts +4 -1
- package/dist/dsl/program.js +147 -24
- package/dist/dsl/session.d.ts +7 -0
- package/dist/dsl/session.js +37 -10
- package/dist/dsl/templates.d.ts +2 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/scheduler/human-arbitration.d.ts +59 -0
- package/dist/scheduler/human-arbitration.js +62 -0
- package/dist/scheduler/runtime.d.ts +51 -3
- package/dist/scheduler/runtime.js +445 -40
- package/dist/scheduler/worker.d.ts +2 -0
- package/dist/scheduler/worker.js +24 -4
- package/dist/storage/session.d.ts +2 -1
- package/dist/storage/session.js +14 -0
- package/dist/transitions/validate.js +14 -4
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MutationLog } from '../storage/mutation-log.js';
|
|
2
2
|
import { PriorityInheritance, ReadyQueue, type RuntimeClock } from './index.js';
|
|
3
|
-
import type { EffectRecord, EffectSubmission, EffectState, JsonValue, LaneRecord, LaneStepOutput, Outcome, ResumeInput, RuntimeState, RuntimeError, ForkAffinityMode, PrivacyLabel, PrivacyTaint, ProvenanceRef, ResumePoint, ResultRecord } from '../core/types.js';
|
|
3
|
+
import type { EffectRecord, EffectSubmission, EffectState, JsonValue, LaneRecord, LaneStepOutput, Outcome, ResumeInput, RuntimeState, RuntimeError, ForkAffinityMode, PrivacyLabel, PrivacyTaint, ProvenanceRef, ResumePoint, ResultRecord, HumanInputRecord } from '../core/types.js';
|
|
4
4
|
import { QuarantineScope } from '../lifecycle/scopes.js';
|
|
5
5
|
import { PulseSession } from '../dsl/session.js';
|
|
6
6
|
import type { ProgramRef } from '../dsl/templates.js';
|
|
@@ -18,10 +18,12 @@ import { type ArtifactPublication } from '../storage/artifacts.js';
|
|
|
18
18
|
import { type FindingPublication } from '../storage/findings.js';
|
|
19
19
|
import { RuntimeToolRegistry } from '../tools/registry.js';
|
|
20
20
|
import { type SchedulerDecisionConfig } from './decision.js';
|
|
21
|
+
import { type HumanArbitrationConfig } from './human-arbitration.js';
|
|
21
22
|
export interface LaneStepContext {
|
|
22
23
|
lane: Readonly<LaneRecord>;
|
|
23
24
|
state: Readonly<RuntimeState>;
|
|
24
25
|
resumeInput?: ResumeInput;
|
|
26
|
+
humanInputs?: readonly HumanInputRecord[];
|
|
25
27
|
now: number;
|
|
26
28
|
observe?: (event: {
|
|
27
29
|
type: 'progress' | 'chunk' | 'trace' | 'warning' | 'diagnostic';
|
|
@@ -83,6 +85,12 @@ export type HostCommand = {
|
|
|
83
85
|
agentId: string;
|
|
84
86
|
effectId: string;
|
|
85
87
|
value: JsonValue;
|
|
88
|
+
} | {
|
|
89
|
+
type: 'human_input';
|
|
90
|
+
agentId: string;
|
|
91
|
+
inputId: string;
|
|
92
|
+
value: JsonValue;
|
|
93
|
+
targetEffectId?: string;
|
|
86
94
|
} | {
|
|
87
95
|
type: 'cancel';
|
|
88
96
|
agentId: string;
|
|
@@ -132,7 +140,12 @@ interface SchedulerDecisionFact {
|
|
|
132
140
|
orderedLaneIds: string[];
|
|
133
141
|
modelId: string;
|
|
134
142
|
}
|
|
135
|
-
|
|
143
|
+
interface HumanArbitrationFact {
|
|
144
|
+
[key: string]: JsonValue;
|
|
145
|
+
type: 'human_arbitration';
|
|
146
|
+
decision: JsonValue;
|
|
147
|
+
}
|
|
148
|
+
type RuntimeFact = HostCommand | EffectCompletionFact | LLMPreparationFact | EffectReconcileFact | SchedulerDecisionFact | HumanArbitrationFact;
|
|
136
149
|
export interface RuntimeConfig {
|
|
137
150
|
maxLaneStepsPerTick?: number;
|
|
138
151
|
maxTickMs?: number;
|
|
@@ -187,6 +200,8 @@ export interface RuntimeConfig {
|
|
|
187
200
|
persistenceExpectedDigest?: string;
|
|
188
201
|
budget?: RuntimeBudgetConfig;
|
|
189
202
|
schedulerDecision?: SchedulerDecisionConfig;
|
|
203
|
+
/** Optional model used for ordinary Human messages after deterministic control rules. */
|
|
204
|
+
humanArbitration?: HumanArbitrationConfig;
|
|
190
205
|
}
|
|
191
206
|
export interface RuntimeBudgetConfig {
|
|
192
207
|
maxTotalAttempts?: number;
|
|
@@ -263,6 +278,13 @@ export declare class PulseRuntime {
|
|
|
263
278
|
private readonly auditLogPrivacy;
|
|
264
279
|
private readonly persistenceBackend;
|
|
265
280
|
private readonly sessionStore;
|
|
281
|
+
/**
|
|
282
|
+
* The file session store is synchronous by design, so avoid rewriting an
|
|
283
|
+
* unchanged warm-start snapshot on every scheduler tick. Without this
|
|
284
|
+
* guard an idle run can spend its whole event loop serializing and fsyncing
|
|
285
|
+
* the same snapshot, starving effect dispatch and human input handling.
|
|
286
|
+
*/
|
|
287
|
+
private readonly sessionStoreDigests;
|
|
266
288
|
private readonly enforcingRecoveryPrograms;
|
|
267
289
|
private readonly toolVersions;
|
|
268
290
|
private readonly recoveryCompatibility;
|
|
@@ -305,6 +327,7 @@ export declare class PulseRuntime {
|
|
|
305
327
|
private factInboxDedupeArchive;
|
|
306
328
|
private readonly customExecutor;
|
|
307
329
|
private readonly builtinHumanEffects;
|
|
330
|
+
private humanInputProgram;
|
|
308
331
|
private enqueueSeq;
|
|
309
332
|
private readonly maxSteps;
|
|
310
333
|
private readonly maxTickMs;
|
|
@@ -317,6 +340,10 @@ export declare class PulseRuntime {
|
|
|
317
340
|
private readonly maxPreparedLLMs;
|
|
318
341
|
private readonly effectSubmissionPreparer;
|
|
319
342
|
private readonly schedulerDecisionCoordinator;
|
|
343
|
+
private readonly humanArbitrationCoordinator;
|
|
344
|
+
private readonly humanArbitrationModelId;
|
|
345
|
+
private humanArbitrationRequestSeq;
|
|
346
|
+
private readonly humanArbitrationRequests;
|
|
320
347
|
private readonly schedulerDecisionConfig;
|
|
321
348
|
private readonly schedulerDecisionModelId;
|
|
322
349
|
private readonly schedulerDecisionMaxReorderDistance;
|
|
@@ -331,16 +358,34 @@ export declare class PulseRuntime {
|
|
|
331
358
|
private readonly sessionId;
|
|
332
359
|
private hostCommandSeq;
|
|
333
360
|
private factWaiters;
|
|
361
|
+
private activityWaiters;
|
|
334
362
|
private wakeScheduled;
|
|
363
|
+
/**
|
|
364
|
+
* A lock grant can happen synchronously while an effect completion is being
|
|
365
|
+
* applied inside tick(). scheduleWake() intentionally avoids re-entering the
|
|
366
|
+
* drain in that case, so remember forced wake requests and service them once
|
|
367
|
+
* the current drain has finished.
|
|
368
|
+
*/
|
|
369
|
+
private wakeAfterDrain;
|
|
335
370
|
private inDrain;
|
|
336
371
|
private wakeError;
|
|
337
372
|
private tickBudget;
|
|
338
373
|
static restore(backend: RuntimePersistenceBackend, config?: Omit<RuntimeConfig, 'persistence'>): Promise<PulseRuntime>;
|
|
339
374
|
constructor(config?: RuntimeConfig);
|
|
340
375
|
register(program: LaneProgram): void;
|
|
376
|
+
/** Register the program used for urgent, concurrent human interactions. */
|
|
377
|
+
setHumanInputProgram(program: LaneProgram): void;
|
|
341
378
|
createAgent(request: AgentCreateRequest): AgentHandle;
|
|
342
379
|
createAgent(goal: string, program: LaneProgram, agentId?: string): AgentHandle;
|
|
343
380
|
start(agentId: string): PulseSession;
|
|
381
|
+
/** Accept external human input without waiting for the current Effect to settle. */
|
|
382
|
+
submitHumanInput(agentId: string, inputId: string, value: JsonValue, targetEffectId?: string): boolean;
|
|
383
|
+
humanInputsFor(agentId: string): HumanInputRecord[];
|
|
384
|
+
private humanArbitrationRequest;
|
|
385
|
+
private ownsAgentForRuntime;
|
|
386
|
+
private commitHumanInputDecision;
|
|
387
|
+
private applyHumanArbitrationDecision;
|
|
388
|
+
private requestHumanArbitration;
|
|
344
389
|
requestCancel(agentId: string, reason?: string): void;
|
|
345
390
|
setLanePriority(laneId: string, priority: number): void;
|
|
346
391
|
effectHandle(effectId: string): EffectHandle;
|
|
@@ -369,7 +414,7 @@ export declare class PulseRuntime {
|
|
|
369
414
|
private executeRegisteredEffect;
|
|
370
415
|
private journalEffect;
|
|
371
416
|
private enqueueFact;
|
|
372
|
-
enqueueHostCommand(command: HostCommand):
|
|
417
|
+
enqueueHostCommand(command: HostCommand): boolean;
|
|
373
418
|
private enqueueEffectCompletion;
|
|
374
419
|
private enqueueLLMPreparation;
|
|
375
420
|
private enqueueEffectReconcile;
|
|
@@ -417,6 +462,9 @@ export declare class PulseRuntime {
|
|
|
417
462
|
private hasPendingTickCleanup;
|
|
418
463
|
private hasPendingHostInteraction;
|
|
419
464
|
private waitForFact;
|
|
465
|
+
/** Wait for a state or observation change without polling the event loop. */
|
|
466
|
+
waitForActivity(timeoutMs?: number): Promise<void>;
|
|
467
|
+
private notifyActivity;
|
|
420
468
|
private completeFinishedChildAgents;
|
|
421
469
|
completeEffect(effectId: string, execution: EffectExecution, status?: 'succeeded' | 'failed' | 'cancelled', error?: RuntimeError, additionalMutations?: Mutation[]): boolean;
|
|
422
470
|
markRemoteUnknown(effectId: string, sideEffectState: 'none' | 'applied' | 'known' | 'unknown'): void;
|