@yeaft/webchat-agent 1.0.558 → 1.0.560
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/local-runtime/version.json +1 -1
- package/local-runtime/web/app.bundle.js +22 -12
- package/local-runtime/web/app.bundle.js.gz +0 -0
- package/local-runtime/web/index.html +2 -2
- package/local-runtime/web/style.bundle.css +1 -1
- package/local-runtime/web/style.bundle.css.gz +0 -0
- package/package.json +1 -1
- package/yeaft/work-center/bridge.js +1 -0
- package/yeaft/work-center/controller.js +8 -3
- package/yeaft/work-center/store.js +71 -10
|
Binary file
|
package/package.json
CHANGED
|
@@ -254,6 +254,7 @@ export async function handleWorkCenterRequest(msg) {
|
|
|
254
254
|
op,
|
|
255
255
|
ok: false,
|
|
256
256
|
error: err?.message || String(err),
|
|
257
|
+
...(err?.code === 'WORK_CENTER_INPUT_STALE' ? { errorCode: err.code } : {}),
|
|
257
258
|
_requestUserId: msg._requestUserId || null,
|
|
258
259
|
});
|
|
259
260
|
}
|
|
@@ -251,11 +251,14 @@ export class WorkflowController {
|
|
|
251
251
|
throw new Error('actionId, revision, and generation are required for Action input');
|
|
252
252
|
}
|
|
253
253
|
const graphMode = workItem.workflowSnapshot?.executionMode === 'graph';
|
|
254
|
+
const concurrentMode = graphMode || workItem.coordinationMode === 'dynamic';
|
|
254
255
|
const targetMatches = targetAction?.workItemId === id
|
|
255
256
|
&& targetAction.generation === expectedGeneration
|
|
256
|
-
&& (
|
|
257
|
+
&& (concurrentMode || workItem.currentActionId === input.actionId);
|
|
257
258
|
if (!targetMatches || workItem.revision !== input.revision) {
|
|
258
|
-
|
|
259
|
+
const error = new Error('Action changed before input was applied; refresh and try again');
|
|
260
|
+
error.code = 'WORK_CENTER_INPUT_STALE';
|
|
261
|
+
throw error;
|
|
259
262
|
}
|
|
260
263
|
if (['ready', 'running'].includes(targetAction.status)) {
|
|
261
264
|
if (targetAction.status === 'running' && addedAttachmentCount > 0) {
|
|
@@ -269,7 +272,9 @@ export class WorkflowController {
|
|
|
269
272
|
}, input.attachments, input.addedAttachments, input.clientMessageId, quote);
|
|
270
273
|
}
|
|
271
274
|
if (!['waiting', 'failed'].includes(targetAction.status)) {
|
|
272
|
-
|
|
275
|
+
const error = new Error(`Action in ${targetAction.status} cannot accept input`);
|
|
276
|
+
error.code = 'WORK_CENTER_INPUT_STALE';
|
|
277
|
+
throw error;
|
|
273
278
|
}
|
|
274
279
|
return this.retry(id, {
|
|
275
280
|
answer: text,
|
|
@@ -1944,7 +1944,9 @@ export class WorkItemStore {
|
|
|
1944
1944
|
? ['ready', 'running', 'waiting', 'needs_attention']
|
|
1945
1945
|
: ['ready', 'running'];
|
|
1946
1946
|
if (!inputStatuses.includes(workItem.status)) {
|
|
1947
|
-
|
|
1947
|
+
const error = new Error(`WorkItem in ${workItem.status} cannot accept Action input`);
|
|
1948
|
+
error.code = 'WORK_CENTER_INPUT_STALE';
|
|
1949
|
+
throw error;
|
|
1948
1950
|
}
|
|
1949
1951
|
const action = this.getAction(expected.actionId);
|
|
1950
1952
|
const actionMatches = action?.workItemId === id
|
|
@@ -1956,7 +1958,9 @@ export class WorkItemStore {
|
|
|
1956
1958
|
|| (activeRun?.status === 'running' && activeRun.acceptingInput !== false
|
|
1957
1959
|
&& runMatchesActionIdentity(activeRun, action));
|
|
1958
1960
|
if (!actionMatches || !runMatches || workItem.revision !== expected.revision) {
|
|
1959
|
-
|
|
1961
|
+
const error = new Error('Action changed before input was applied; refresh and try again');
|
|
1962
|
+
error.code = 'WORK_CENTER_INPUT_STALE';
|
|
1963
|
+
throw error;
|
|
1960
1964
|
}
|
|
1961
1965
|
const projectedAttachments = (Array.isArray(addedAttachments) ? addedAttachments : []).map(attachment => ({
|
|
1962
1966
|
id: attachment.id,
|
|
@@ -1998,7 +2002,7 @@ export class WorkItemStore {
|
|
|
1998
2002
|
const changedAction = this.db.prepare(`UPDATE actions SET context = ?, instruction = ?, attempt = 0,
|
|
1999
2003
|
generation = generation + 1, spec_hash = ?, identity_history = ?, result_run_id = NULL,
|
|
2000
2004
|
workspace = NULL, updated_at = ? WHERE id = ? AND status = 'ready' AND current_run_id IS NULL
|
|
2001
|
-
AND generation = ? AND spec_hash = ?`).run(
|
|
2005
|
+
AND generation = ? AND spec_hash = ? AND contract_revision = ?`).run(
|
|
2002
2006
|
stringify(context),
|
|
2003
2007
|
nextAction.instruction,
|
|
2004
2008
|
nextAction.specHash,
|
|
@@ -2007,9 +2011,12 @@ export class WorkItemStore {
|
|
|
2007
2011
|
action.id,
|
|
2008
2012
|
action.generation,
|
|
2009
2013
|
action.specHash,
|
|
2014
|
+
action.contractRevision,
|
|
2010
2015
|
);
|
|
2011
2016
|
if (Number(changedAction.changes) !== 1) {
|
|
2012
|
-
|
|
2017
|
+
const error = new Error('Action changed before input was applied; refresh and try again');
|
|
2018
|
+
error.code = 'WORK_CENTER_INPUT_STALE';
|
|
2019
|
+
throw error;
|
|
2013
2020
|
}
|
|
2014
2021
|
this.#supersedePendingActionInputs(
|
|
2015
2022
|
[action],
|
|
@@ -4536,12 +4543,15 @@ export class WorkItemStore {
|
|
|
4536
4543
|
}
|
|
4537
4544
|
const workItem = this.getWorkItem(id);
|
|
4538
4545
|
if (!workItem) return null;
|
|
4546
|
+
const dynamicMode = isDynamicWorkItem(workItem);
|
|
4539
4547
|
const graphMode = usesLegacyGraph(workItem);
|
|
4540
|
-
const retryableWorkItemStatuses = graphMode
|
|
4548
|
+
const retryableWorkItemStatuses = graphMode || dynamicMode
|
|
4541
4549
|
? ['ready', 'running', 'waiting', 'needs_attention']
|
|
4542
4550
|
: ['waiting', 'needs_attention'];
|
|
4543
4551
|
if (!retryableWorkItemStatuses.includes(workItem.status)) {
|
|
4544
|
-
|
|
4552
|
+
const error = new Error(`WorkItem in ${workItem.status} does not need retry`);
|
|
4553
|
+
error.code = 'WORK_CENTER_INPUT_STALE';
|
|
4554
|
+
throw error;
|
|
4545
4555
|
}
|
|
4546
4556
|
let previous = workItem.currentActionId ? this.getAction(workItem.currentActionId) : null;
|
|
4547
4557
|
if (options.expected) {
|
|
@@ -4553,10 +4563,12 @@ export class WorkItemStore {
|
|
|
4553
4563
|
const hasExpectedGeneration = Number.isInteger(expectedGeneration) && expectedGeneration > 0;
|
|
4554
4564
|
const expectedMatches = expectedAction?.workItemId === id
|
|
4555
4565
|
&& allowedExpectedStatuses.includes(expectedAction.status)
|
|
4556
|
-
&& (graphMode || workItem.currentActionId === options.expected.actionId)
|
|
4557
|
-
&& (hasExpectedGeneration ? expectedAction.generation === expectedGeneration : !graphMode);
|
|
4566
|
+
&& (graphMode || dynamicMode || workItem.currentActionId === options.expected.actionId)
|
|
4567
|
+
&& (hasExpectedGeneration ? expectedAction.generation === expectedGeneration : !(graphMode || dynamicMode));
|
|
4558
4568
|
if (!expectedMatches || workItem.revision !== options.expected.revision) {
|
|
4559
|
-
|
|
4569
|
+
const error = new Error('Action changed before input was applied; refresh and try again');
|
|
4570
|
+
error.code = 'WORK_CENTER_INPUT_STALE';
|
|
4571
|
+
throw error;
|
|
4560
4572
|
}
|
|
4561
4573
|
previous = expectedAction;
|
|
4562
4574
|
}
|
|
@@ -4565,7 +4577,7 @@ export class WorkItemStore {
|
|
|
4565
4577
|
AND status != 'running' ORDER BY ended_at DESC, started_at DESC LIMIT 1`).get(id, previous.id))
|
|
4566
4578
|
: null;
|
|
4567
4579
|
const now = this.now();
|
|
4568
|
-
const revision = options.expected ? workItem.revision + 1 : workItem.revision;
|
|
4580
|
+
const revision = options.expected && !dynamicMode ? workItem.revision + 1 : workItem.revision;
|
|
4569
4581
|
const replacement = {
|
|
4570
4582
|
...makeAction(workItem, previous, previousRun),
|
|
4571
4583
|
contractRevision: previous?.contractRevision ?? workItem.revision,
|
|
@@ -4573,6 +4585,55 @@ export class WorkItemStore {
|
|
|
4573
4585
|
const inputEvent = options.inputEvent && typeof options.inputEvent === 'object'
|
|
4574
4586
|
? options.inputEvent
|
|
4575
4587
|
: null;
|
|
4588
|
+
if (dynamicMode) {
|
|
4589
|
+
if (!previous) throw new Error('Dynamic WorkItem retry target is missing');
|
|
4590
|
+
const candidate = {
|
|
4591
|
+
...previous,
|
|
4592
|
+
...replacement,
|
|
4593
|
+
id: previous.id,
|
|
4594
|
+
generation: previous.generation + 1,
|
|
4595
|
+
attempt: 0,
|
|
4596
|
+
currentRunId: null,
|
|
4597
|
+
resultRunId: null,
|
|
4598
|
+
workspace: null,
|
|
4599
|
+
};
|
|
4600
|
+
candidate.instruction = canonicalActionInstruction(workItem, candidate, candidate.context);
|
|
4601
|
+
candidate.specHash = actionSpecHash(candidate);
|
|
4602
|
+
const changed = this.db.prepare(`UPDATE actions SET status = 'ready', attempt = 0,
|
|
4603
|
+
current_run_id = NULL, context = ?, instruction = ?, generation = generation + 1,
|
|
4604
|
+
spec_hash = ?, identity_history = ?, result_run_id = NULL, workspace = NULL, updated_at = ?
|
|
4605
|
+
WHERE id = ? AND work_item_id = ? AND status IN ('waiting', 'failed')
|
|
4606
|
+
AND current_run_id IS NULL AND generation = ? AND spec_hash = ? AND contract_revision = ?`).run(
|
|
4607
|
+
stringify(candidate.context), candidate.instruction, candidate.specHash,
|
|
4608
|
+
stringify(actionIdentityHistory(previous, candidate.generation, candidate.specHash)),
|
|
4609
|
+
now, previous.id, id, previous.generation, previous.specHash, previous.contractRevision,
|
|
4610
|
+
);
|
|
4611
|
+
if (Number(changed.changes) !== 1) {
|
|
4612
|
+
const error = new Error('Action changed before input was applied; refresh and try again');
|
|
4613
|
+
error.code = 'WORK_CENTER_INPUT_STALE';
|
|
4614
|
+
throw error;
|
|
4615
|
+
}
|
|
4616
|
+
const changedWorkItem = this.db.prepare(`UPDATE work_items SET attachments = ?, updated_at = ?
|
|
4617
|
+
WHERE id = ? AND revision = ? AND status NOT IN ('done', 'cancelled')`).run(
|
|
4618
|
+
stringify(Array.isArray(options.attachments) ? options.attachments : workItem.attachments),
|
|
4619
|
+
now, id, workItem.revision,
|
|
4620
|
+
);
|
|
4621
|
+
if (Number(changedWorkItem.changes) !== 1) {
|
|
4622
|
+
const error = new Error('Action changed before input was applied; refresh and try again');
|
|
4623
|
+
error.code = 'WORK_CENTER_INPUT_STALE';
|
|
4624
|
+
throw error;
|
|
4625
|
+
}
|
|
4626
|
+
const action = this.getAction(previous.id);
|
|
4627
|
+
if (inputEvent) {
|
|
4628
|
+
this.appendEvent(id, 'action.input_added', inputEvent, {
|
|
4629
|
+
actionId: action.id,
|
|
4630
|
+
actionGeneration: action.generation,
|
|
4631
|
+
});
|
|
4632
|
+
} else {
|
|
4633
|
+
this.appendEvent(id, 'work_item.retried', {}, { actionId: action.id });
|
|
4634
|
+
}
|
|
4635
|
+
return this.getWorkItemDetail(id);
|
|
4636
|
+
}
|
|
4576
4637
|
if (graphMode) {
|
|
4577
4638
|
if (!previous) throw new Error('WorkItem graph retry target is missing');
|
|
4578
4639
|
const action = this.#resetGraphFromStage(
|