Persist workflow archive bridge state
This commit is contained in:
+3
-1
@@ -718,12 +718,13 @@ Automation execution-layer PXX remains closed and its known scope stays frozen.
|
||||
- Latest O2 validation passed: 74 focused archive/API/static/operator tests, 732 full unit tests, 73 script static checks, `node --check src/web/app.js`, live deploy completed, remote ops smoke passed 9 checks, and remote O2 smoke confirmed persisted digest/workflow baselines, long-range trend stories, and deployed `Save Baseline` / `Save Workflow Baseline` UI strings on the live host.
|
||||
- Latest B7 validation passed: 74 focused archive/API/static/operator tests, 732 full unit tests, 73 script static checks, `node --check src/web/app.js`, live deploy completed, remote ops smoke passed 9 checks, and remote B7 smoke confirmed persisted archive defaults, cross-profile preset retrieval, and deployed `Save Digest Defaults` / `Use Saved Digest Defaults` / `Save Workflow Defaults` / `Use Saved Workflow Defaults` UI strings on the live host.
|
||||
- Latest E12 validation passed: 16 focused external-context/static tests, 732 full unit tests, 73 script static checks, `node --check src/web/app.js`, live deploy completed, remote ops smoke passed 9 checks, and remote E12 smoke confirmed screenshot readiness summary, capture-surface screenshot status fields, and deployed `Open Screenshot Surface` UI strings on the live host.
|
||||
- Latest W9 validation passed: 74 focused workflow bridge/API/static/operator tests, 732 full unit tests, 73 script static checks, `node --check src/web/app.js`, live deploy completed, remote ops smoke passed 9 checks, and remote W9 smoke confirmed persisted workflow bridge state, persisted handoff/bundle starters, and deployed `Persist Bridge State` plus `bridge persistence` cockpit summary on the live host.
|
||||
- Refreshed `docs/AI_ICT_??????????????????????2026-05-14_v1.md` after closing Phases A-E; the active remaining mainline backlog is now archive long-range trend deepening, archive deep-retrieval deepening, external context deep visual evidence extensions, and workflow archive deep bridge extensions.
|
||||
- Real-live order submission remains intentionally disabled because the OKX order adapter is still not a real-live submitter.
|
||||
|
||||
## Exact Next Step
|
||||
|
||||
Use `docs/AI_ICT_???????????????????2026-05-14_v1.md` as the completed enhancement record for Phases A-E. The active backlog source is now `docs/AI_ICT_??????????????????????2026-05-14_v1.md`. `B5 archive keyword search / export starter slice`, `W7 workflow archive replay / handoff / export bridge starter slice`, `E10 external context visual evidence / provider health starter slice`, `O1 archive long-range trend / baseline pin starter slice`, `B6 archive deep retrieval / structured export follow-up starter slice`, `E11 external context deep visual evidence / capture surface follow-up starter slice`, `W8 workflow archive deep bridge extension starter slice`, `O2 archive long-range trend deepening / baseline persistence starter slice`, `B7 archive deep retrieval deepening / preset persistence starter slice`, and `E12 external context visual evidence extension / screenshot readiness starter slice` are now closed. Start from `W9 workflow archive deep bridge extension / bundle export persistence slice`, keep work on the analysis-assistant mainline only, and continue treating real-trading scope as deferred. PXX remains closed and you still must not create P25/P26 automatically or enable real trading.
|
||||
Use `docs/AI_ICT_???????????????????2026-05-14_v1.md` as the completed enhancement record for Phases A-E. The active backlog source is now `docs/AI_ICT_??????????????????????2026-05-14_v1.md`. `B5 archive keyword search / export starter slice`, `W7 workflow archive replay / handoff / export bridge starter slice`, `E10 external context visual evidence / provider health starter slice`, `O1 archive long-range trend / baseline pin starter slice`, `B6 archive deep retrieval / structured export follow-up starter slice`, `E11 external context deep visual evidence / capture surface follow-up starter slice`, `W8 workflow archive deep bridge extension starter slice`, `O2 archive long-range trend deepening / baseline persistence starter slice`, `B7 archive deep retrieval deepening / preset persistence starter slice`, `E12 external context visual evidence extension / screenshot readiness starter slice`, and `W9 workflow archive deep bridge extension / bundle export persistence slice` are now closed. Start from `O3 archive long-range trend unification / operator overview slice`, keep work on the analysis-assistant mainline only, and continue treating real-trading scope as deferred. PXX remains closed and you still must not create P25/P26 automatically or enable real trading.
|
||||
|
||||
## Validation Commands Used Recently
|
||||
|
||||
@@ -781,3 +782,4 @@ D:\ai-exchange\.venv\Scripts\python.exe scripts\run_automation_execution_closure
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -113,7 +113,8 @@
|
||||
- [x] O2 archive long-range trend deepening / baseline persistence starter slice
|
||||
- [x] B7 archive deep retrieval deepening / preset persistence starter slice
|
||||
- [x] E12 external context visual evidence extension / screenshot readiness starter slice
|
||||
- [ ] W9 workflow archive deep bridge extension / bundle export persistence slice
|
||||
- [x] W9 workflow archive deep bridge extension / bundle export persistence slice
|
||||
- [ ] O3 archive long-range trend unification / operator overview slice
|
||||
|
||||
- [x] A1 independent preferences surface / dedicated settings section
|
||||
- [x] A2 preference profile create / duplicate / rename / delete
|
||||
|
||||
@@ -145,6 +145,16 @@
|
||||
- 下一刀最小闭环切片改为:
|
||||
- `W9 workflow archive deep bridge extension / bundle export persistence slice`
|
||||
|
||||
## 11. 2026-05-15 W9 Addendum
|
||||
|
||||
- `W9 workflow archive deep bridge extension / bundle export persistence slice` 已完成。
|
||||
- 当前已具备:
|
||||
- persisted workflow bridge state
|
||||
- handoff / replay / artifact bundle starter persistence
|
||||
- workflow bridge persistence summary in cockpit
|
||||
- 下一刀最小闭环切片改为:
|
||||
- `O3 archive long-range trend unification / operator overview slice`
|
||||
|
||||
- A-E 璁″垝宸茬粡鍏ㄩ儴瀹屾垚锛屼笉璇ュ啀浣滀负涓?backlog 閲嶅鎺ㄨ繘銆?- 褰撳墠鐪熸鏈畬鎴愮殑锛屽凡缁忎粠鈥滃熀纭€浜у搧鍖栤€濆垏鎹㈠埌鈥渁rchive 娣卞寲銆乪xternal evidence 寮哄寲銆佽繍钀ラ暱鏈熻鍥锯€濊繖涓€绾с€?- 鐪熷疄浜ゆ槗銆乴ive adapter銆佷笅鍗曟潈闄愮浉鍏冲唴瀹圭户缁繚鎸佸欢鏈燂紝涓嶅簲娣峰洖褰撳墠鍒嗘瀽鍔╂墜涓荤嚎銆?
|
||||
|
||||
|
||||
|
||||
@@ -321,6 +321,7 @@ class DecisionAssistantSummaryService:
|
||||
)
|
||||
digest_archive_compare = _build_decision_assistant_digest_archive_compare(refreshed_digest_history)
|
||||
workflow_archive_compare = _build_decision_assistant_workflow_archive_compare(refreshed_workflow_history)
|
||||
workflow_bridge_persistence_summary = _decision_assistant_workflow_bridge_state(persisted_digest_preference)
|
||||
summary["digest_history_archive"] = digest_history_archive
|
||||
summary["digest_archive_compare"] = digest_archive_compare
|
||||
summary["digest_persistence_status"] = persistence_result.get("status")
|
||||
@@ -329,6 +330,7 @@ class DecisionAssistantSummaryService:
|
||||
summary["workflow_archive_operations_summary"] = workflow_history_archive.get("operations_summary")
|
||||
summary["workflow_archive_multi_day_drift_review"] = workflow_history_archive.get("multi_day_drift_review")
|
||||
summary["workflow_archive_bridge_summary"] = workflow_history_archive.get("bridge_summary")
|
||||
summary["workflow_archive_bridge_persistence_summary"] = workflow_bridge_persistence_summary
|
||||
summary["workflow_persistence_status"] = workflow_persistence_result.get("status")
|
||||
digest_surface = dict(summary.get("digest_surface") or {})
|
||||
digest_surface["digest_history_archive"] = digest_history_archive
|
||||
@@ -345,6 +347,7 @@ class DecisionAssistantSummaryService:
|
||||
workflow_artifact_summary["workflow_archive_operations_summary"] = workflow_history_archive.get("operations_summary")
|
||||
workflow_artifact_summary["workflow_archive_multi_day_drift_review"] = workflow_history_archive.get("multi_day_drift_review")
|
||||
workflow_artifact_summary["workflow_archive_bridge_summary"] = workflow_history_archive.get("bridge_summary")
|
||||
workflow_artifact_summary["workflow_archive_bridge_persistence_summary"] = workflow_bridge_persistence_summary
|
||||
workflow_artifact_summary["workflow_persistence_status"] = workflow_persistence_result.get("status")
|
||||
summary["workflow_artifact_summary"] = workflow_artifact_summary
|
||||
return summary
|
||||
@@ -702,6 +705,19 @@ def _decision_assistant_archive_defaults(persisted_digest_preference: dict) -> d
|
||||
}
|
||||
|
||||
|
||||
def _decision_assistant_workflow_bridge_state(persisted_digest_preference: dict) -> dict:
|
||||
payload = _decision_assistant_preference_payload(persisted_digest_preference)
|
||||
state = dict(payload.get("workflow_bridge_state") or {})
|
||||
return {
|
||||
"status": "persisted" if state else "idle",
|
||||
"updated_ts": state.get("updated_ts"),
|
||||
"query_context": dict(state.get("query_context") or {}),
|
||||
"handoff_packet_starter": dict(state.get("handoff_packet_starter") or {}),
|
||||
"replay_note_bridge_summary": dict(state.get("replay_note_bridge_summary") or {}),
|
||||
"artifact_bundle_summary": dict(state.get("artifact_bundle_summary") or {}),
|
||||
}
|
||||
|
||||
|
||||
def _decision_assistant_importance_template_thresholds(*, persisted_digest_preference: dict) -> dict:
|
||||
payload = _decision_assistant_preference_payload(persisted_digest_preference)
|
||||
thresholds = dict(payload.get("importance_templates") or {})
|
||||
|
||||
@@ -245,6 +245,47 @@ async function persistAssistantArchiveBaselinesServer({ profileKey, digestSnapsh
|
||||
});
|
||||
}
|
||||
|
||||
async function persistWorkflowArchiveBridgeStateServer({ summary, exportPayload, profileKey }) {
|
||||
const digestSurface = summary?.digest_surface || {};
|
||||
const digestProfile = digestSurface.digest_preference_profile || {};
|
||||
const saved = await persistAssistantDigestPreferenceServer({
|
||||
profileKey: profileKey || assistantDigestProfileKey || 'local_operator',
|
||||
digestMode: assistantPreferenceDraft?.digest_mode || digestProfile.persisted_digest_mode || 'all_reminders',
|
||||
preferredHistoryKind: assistantPreferenceDraft?.preferred_history_kind === 'all'
|
||||
? null
|
||||
: (assistantPreferenceDraft?.preferred_history_kind || digestProfile.preferred_history_kind || null),
|
||||
importanceThreshold: assistantPreferenceDraft?.importance_threshold || digestProfile.importance_threshold || 70,
|
||||
payload: {
|
||||
profile_label: assistantPreferenceDraft?.profile_label || digestProfile.profile_label || profileKey || 'local_operator',
|
||||
history_window_hours: assistantPreferenceDraft?.history_window_hours || digestProfile.history_window_hours || 24,
|
||||
importance_templates: { ...((assistantPreferenceDraft && assistantPreferenceDraft.importance_templates) || {}) },
|
||||
archive_defaults: { ...((assistantPreferenceDraft && assistantPreferenceDraft.archive_defaults) || digestProfile.archive_defaults || {}) },
|
||||
workflow_bridge_state: {
|
||||
handoff_packet_starter: exportPayload?.handoff_packet_starter || {},
|
||||
replay_note_bridge_summary: exportPayload?.replay_note_bridge_summary || {},
|
||||
artifact_bundle_summary: exportPayload?.artifact_bundle_summary || {},
|
||||
query_context: {
|
||||
profile_key: assistantWorkflowArchiveState.profile_key || profileKey || assistantDigestProfileKey || 'local_operator',
|
||||
profile_scope: assistantWorkflowArchiveState.profile_scope || 'selected_profile',
|
||||
query_preset: assistantWorkflowArchiveState.query_preset || '',
|
||||
current_session: assistantWorkflowArchiveState.current_session || '',
|
||||
next_phase: assistantWorkflowArchiveState.next_phase || '',
|
||||
next_artifact_kind: assistantWorkflowArchiveState.next_artifact_kind || '',
|
||||
query_text: assistantWorkflowArchiveState.query_text || '',
|
||||
},
|
||||
updated_ts: new Date().toISOString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
if (saved) {
|
||||
assistantPreferenceDraft = {
|
||||
...(assistantPreferenceDraft || {}),
|
||||
archive_defaults: { ...((assistantPreferenceDraft && assistantPreferenceDraft.archive_defaults) || digestProfile.archive_defaults || {}) },
|
||||
};
|
||||
}
|
||||
return saved;
|
||||
}
|
||||
|
||||
function loadAssistantScanHandoffMarker() {
|
||||
try {
|
||||
const raw = window.localStorage?.getItem('assistantScanHandoffMarker');
|
||||
@@ -1011,6 +1052,9 @@ function renderDecisionAssistant(summary) {
|
||||
|| summary.workflow_artifact_summary?.workflow_archive_bridge_summary
|
||||
|| summary.workflow_archive_bridge_summary
|
||||
|| null;
|
||||
const workflowArchiveBridgePersistenceSummary = summary.workflow_artifact_summary?.workflow_archive_bridge_persistence_summary
|
||||
|| summary.workflow_archive_bridge_persistence_summary
|
||||
|| null;
|
||||
const workflowArchiveDailyGroups = workflowArchiveData?.daily_groups || [];
|
||||
const workflowArchiveSessionGroups = workflowArchiveData?.session_groups || [];
|
||||
const workflowArchiveBridgeContext = assistantWorkflowArchiveBridgeContext;
|
||||
@@ -2641,6 +2685,19 @@ function renderDecisionAssistant(summary) {
|
||||
])
|
||||
);
|
||||
}
|
||||
if (workflowArchiveBridgePersistenceSummary) {
|
||||
decisionAssistantPanel.appendChild(
|
||||
buildInfoGrid([
|
||||
['bridge persistence', workflowArchiveBridgePersistenceSummary.status || 'idle'],
|
||||
['bridge saved at', formatTimestamp(workflowArchiveBridgePersistenceSummary.updated_ts)],
|
||||
['bridge saved preset', workflowArchiveBridgePersistenceSummary.query_context?.query_preset || 'custom'],
|
||||
['bridge saved scope', workflowArchiveBridgePersistenceSummary.query_context?.profile_scope || 'selected_profile'],
|
||||
['bridge saved handoff', workflowArchiveBridgePersistenceSummary.handoff_packet_starter?.headline || 'n/a'],
|
||||
['bridge saved replay', workflowArchiveBridgePersistenceSummary.replay_note_bridge_summary?.note_title || 'n/a'],
|
||||
['bridge saved bundle', workflowArchiveBridgePersistenceSummary.artifact_bundle_summary?.starter_export_prompt || 'n/a'],
|
||||
])
|
||||
);
|
||||
}
|
||||
if (workflowArchiveBridgeContext) {
|
||||
decisionAssistantPanel.appendChild(
|
||||
buildActionBar([
|
||||
@@ -3129,6 +3186,36 @@ function renderDecisionAssistant(summary) {
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Persist Bridge State',
|
||||
onClick: async () => {
|
||||
const exportPayload = await fetchJson(`/trading/workflow-archive/export?${queryString({
|
||||
instrument_id: Number(instrumentIdInput.value || 1),
|
||||
profile_key: assistantWorkflowArchiveState.profile_key || selectedProfileKey,
|
||||
profile_scope: assistantWorkflowArchiveState.profile_scope || 'selected_profile',
|
||||
query_preset: assistantWorkflowArchiveState.query_preset || '',
|
||||
current_session: assistantWorkflowArchiveState.current_session || '',
|
||||
next_phase: assistantWorkflowArchiveState.next_phase || '',
|
||||
next_artifact_kind: assistantWorkflowArchiveState.next_artifact_kind || '',
|
||||
query_text: assistantWorkflowArchiveState.query_text || '',
|
||||
created_after: assistantWorkflowArchiveState.created_after || '',
|
||||
created_before: assistantWorkflowArchiveState.created_before || '',
|
||||
limit: Math.max(Number(assistantWorkflowArchiveState.limit || 12), Number(workflowArchiveData?.items?.length || 0)),
|
||||
left_id: assistantWorkflowArchiveState.selected_left_id,
|
||||
right_id: assistantWorkflowArchiveState.selected_right_id,
|
||||
})}`);
|
||||
const saved = await persistWorkflowArchiveBridgeStateServer({
|
||||
summary,
|
||||
exportPayload,
|
||||
profileKey: assistantWorkflowArchiveState.profile_key || selectedProfileKey,
|
||||
});
|
||||
if (!saved) {
|
||||
showErrorPanel('workflow_bridge_state_persist_failed');
|
||||
return;
|
||||
}
|
||||
await refreshDashboard();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Export Artifact Bundle',
|
||||
onClick: async () => {
|
||||
|
||||
@@ -186,6 +186,8 @@ class ApiStaticServerTests(unittest.TestCase):
|
||||
"Prefill Compare Replay Note",
|
||||
"Export Handoff Starter",
|
||||
"Export Artifact Bundle",
|
||||
"Persist Bridge State",
|
||||
"bridge persistence",
|
||||
):
|
||||
self.assertIn(expected, app_js)
|
||||
|
||||
|
||||
@@ -194,6 +194,7 @@ class OperatorWorkspaceServiceTests(unittest.TestCase):
|
||||
self.assertIn("workflow_archive_operations_summary", summary["workflow_artifact_summary"])
|
||||
self.assertIn("workflow_archive_multi_day_drift_review", summary["workflow_artifact_summary"])
|
||||
self.assertIn("workflow_archive_bridge_summary", summary["workflow_artifact_summary"])
|
||||
self.assertIn("workflow_archive_bridge_persistence_summary", summary["workflow_artifact_summary"])
|
||||
self.assertIn("workflow_persistence_status", summary["workflow_artifact_summary"])
|
||||
self.assertEqual(summary["workflow_artifact_summary"]["workflow_archive_operations_summary"]["status"], "active")
|
||||
self.assertEqual(
|
||||
@@ -201,6 +202,7 @@ class OperatorWorkspaceServiceTests(unittest.TestCase):
|
||||
"insufficient_history",
|
||||
)
|
||||
self.assertEqual(summary["workflow_artifact_summary"]["workflow_archive_bridge_summary"]["status"], "active")
|
||||
self.assertEqual(summary["workflow_artifact_summary"]["workflow_archive_bridge_persistence_summary"]["status"], "persisted")
|
||||
self.assertIn("long_range_trend_summary", summary["workflow_artifact_summary"]["workflow_history_archive"])
|
||||
self.assertIn("baseline_pin_summary", summary["workflow_artifact_summary"]["workflow_history_archive"])
|
||||
self.assertEqual(summary["workflow_artifact_summary"]["workflow_history_archive"]["long_range_trend_summary"]["status"], "active")
|
||||
@@ -979,6 +981,13 @@ class _DecisionAssistantRepo:
|
||||
"workflow_snapshot_id": 10,
|
||||
"updated_ts": "2026-05-12T02:04:00+00:00",
|
||||
},
|
||||
"workflow_bridge_state": {
|
||||
"handoff_packet_starter": {"headline": "Saved handoff starter"},
|
||||
"replay_note_bridge_summary": {"note_title": "Saved replay note"},
|
||||
"artifact_bundle_summary": {"starter_export_prompt": "Saved artifact bundle"},
|
||||
"query_context": {"profile_scope": "selected_profile", "query_preset": "intraday_recent"},
|
||||
"updated_ts": "2026-05-12T02:04:30+00:00",
|
||||
},
|
||||
},
|
||||
"updated_ts": "2026-05-12T02:05:00+00:00",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user