fuli-context 0.7.6 → 0.7.8
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/README.md +69 -13
- package/README.zh-CN.md +60 -14
- package/dist/web/assets/{AboutPage-sLV9WChi.js → AboutPage-9CVX91tr.js} +1 -1
- package/dist/web/assets/{ConnectionsPage-BWn4ywGJ.js → ConnectionsPage-CWbCVFdv.js} +1 -1
- package/dist/web/assets/EmployeeRecruitDialog-CQgNpGJ_.js +1 -0
- package/dist/web/assets/EmployeeRecruitDialog-CfFlyKSh.css +1 -0
- package/dist/web/assets/EmployeeWorkbenchPage-CWg4WJhr.css +1 -0
- package/dist/web/assets/EmployeeWorkbenchPage-CwU4qBgD.js +1 -0
- package/dist/web/assets/KnowledgeEditDialog-B6TGAcFH.js +1 -0
- package/dist/web/assets/{KnowledgeEditDialog-DWUV_NPp.css → KnowledgeEditDialog-iv-dgUeD.css} +1 -1
- package/dist/web/assets/{KnowledgeInspector-CRQWOaos.js → KnowledgeInspector-M2pLY0bR.js} +1 -1
- package/dist/web/assets/{KnowledgeOrganizerPage-Dfj3vIpU.js → KnowledgeOrganizerPage-DzeAlk9b.js} +1 -1
- package/dist/web/assets/KnowledgePage-BJu9w0fF.js +1 -0
- package/dist/web/assets/{KnowledgeWorkspace-ChEB5Bwk.js → KnowledgeWorkspace-CCt8rnBb.js} +1 -1
- package/dist/web/assets/{OverviewPage-Cd66M0RT.js → OverviewPage-CZswVqui.js} +1 -1
- package/dist/web/assets/{PersonalProfilePage-RCFHL0Wz.js → PersonalProfilePage-f1nSF6kx.js} +1 -1
- package/dist/web/assets/PersonalProjectsPage-D__eJf0t.js +1 -0
- package/dist/web/assets/ProjectAgentsPage-C3vW6wmk.css +1 -0
- package/dist/web/assets/ProjectAgentsPage-LrwagMGj.js +11 -0
- package/dist/web/assets/{PublicProjectsPage-mstPEjHe.js → PublicProjectsPage-BdC2Qk4n.js} +1 -1
- package/dist/web/assets/{ReviewPage-6Y1SmfZy.js → ReviewPage-Cbgl8_Si.js} +1 -1
- package/dist/web/assets/SearchableSelect-ERm-k4KI.js +1 -0
- package/dist/web/assets/{SettingsPage--LdTMUm7.js → SettingsPage-DWso4x29.js} +1 -1
- package/dist/web/assets/{WritingTastePage-CIpKswvs.js → WritingTastePage-CFpCjmIY.js} +1 -1
- package/dist/web/assets/catalog-WGLn7ERJ.js +1 -0
- package/dist/web/assets/{console-BT1P2Db4.js → console-DQgu0JIA.js} +1 -1
- package/dist/web/assets/conversation-launcher-settings-0KtlG_LV.js +1 -0
- package/dist/web/assets/{i18n-js6gfc7j.js → i18n-ByRiA3pJ.js} +3 -3
- package/dist/web/assets/{identity-CfDfanpa.js → identity-CxdPRMwH.js} +1 -1
- package/dist/web/assets/index-JAZe6lfX.js +2 -0
- package/dist/web/assets/index-wcXzzggp.css +1 -0
- package/dist/web/assets/{model-DJkLAJsg.js → model-Db4-KefQ.js} +1 -1
- package/dist/web/assets/{useApi-CROJJdhE-BdSti7Y2.js → useApi-CROJJdhE-CePMjc08.js} +1 -1
- package/dist/web/assets/{vue-router-Kk67EaCP.js → vue-router-CzX-hn3P.js} +1 -1
- package/dist/web/index.html +7 -6
- package/docs/employee-agents.md +99 -0
- package/docs/project-agent-memory.md +479 -0
- package/graph-provider/fuli_graph/knowledge_audit_models.py +171 -0
- package/graph-provider/fuli_graph/model_base.py +5 -0
- package/graph-provider/fuli_graph/model_validation.py +32 -0
- package/graph-provider/fuli_graph/models.py +26 -170
- package/graph-provider/fuli_graph/project_agent_context_models.py +29 -0
- package/graph-provider/fuli_graph/project_agent_executor_models.py +35 -7
- package/graph-provider/fuli_graph/project_agent_memory_models.py +79 -0
- package/graph-provider/fuli_graph/project_agent_memory_routes.py +46 -0
- package/graph-provider/fuli_graph/project_agent_models.py +9 -0
- package/graph-provider/fuli_graph/project_agent_recruitment_values.py +48 -0
- package/graph-provider/fuli_graph/project_agent_routes.py +21 -1
- package/graph-provider/fuli_graph/project_agent_task_models.py +217 -29
- package/graph-provider/fuli_graph/runtime.py +37 -1
- package/graph-provider/fuli_graph/store.py +6 -0
- package/graph-provider/fuli_graph/store_project_agent_context.py +65 -0
- package/graph-provider/fuli_graph/store_project_agent_executor_learning.py +175 -11
- package/graph-provider/fuli_graph/store_project_agent_executor_routing.py +33 -10
- package/graph-provider/fuli_graph/store_project_agent_executors.py +181 -14
- package/graph-provider/fuli_graph/store_project_agent_memory.py +174 -0
- package/graph-provider/fuli_graph/store_project_agent_task_activity.py +423 -0
- package/graph-provider/fuli_graph/store_project_agent_task_persistence.py +152 -0
- package/graph-provider/fuli_graph/store_project_agent_task_reads.py +187 -21
- package/graph-provider/fuli_graph/store_project_agent_task_recruitment.py +748 -162
- package/graph-provider/fuli_graph/store_project_agent_task_staffing.py +230 -18
- package/graph-provider/fuli_graph/store_project_agent_tasks.py +261 -468
- package/graph-provider/fuli_graph/store_project_agents.py +214 -46
- package/graph-provider/fuli_graph/store_task_contexts.py +217 -0
- package/graph-provider/fuli_graph/store_transactions.py +40 -0
- package/graph-provider/fuli_graph/task_context_models.py +50 -0
- package/graph-provider/fuli_graph/task_context_routes.py +31 -0
- package/graph-provider/fuli_graph/workflow_observation_models.py +1 -1
- package/graph-provider/pyproject.toml +1 -1
- package/npm-shrinkwrap.json +8 -8
- package/package.json +5 -2
- package/skills/capturing-session-knowledge/SKILL.md +18 -6
- package/src/adaptive-runtime/executor-pool.js +46 -5
- package/src/adaptive-runtime/graph-services.js +10 -3
- package/src/adaptive-runtime/lease-client.js +66 -14
- package/src/adaptive-runtime/runtime-broker.js +24 -9
- package/src/agent-tools/employee-definitions.js +43 -0
- package/src/agent-tools/graph-definitions.js +25 -6
- package/src/agent-tools/graph-handlers.js +11 -0
- package/src/agent-tools/project-agent-definitions.js +35 -4
- package/src/agent-tools/project-agent-memory-definitions.js +36 -0
- package/src/agent-tools.js +6 -2
- package/src/agents/codex/lifecycle-hook.js +107 -0
- package/src/agents/codex/lifecycle-hooks.js +231 -0
- package/src/agents/cursor/lifecycle-hook.js +133 -0
- package/src/agents/cursor/lifecycle-hooks.js +50 -0
- package/src/agents/lifecycle-message.js +19 -0
- package/src/app/agent-request-context.js +23 -0
- package/src/cli/command-registry.js +2 -0
- package/src/cli/employee-command.js +17 -0
- package/src/cli/remote-mcp-command.js +282 -0
- package/src/cli/setup-command.js +5 -0
- package/src/cli/update-command.js +6 -43
- package/src/cli.js +10 -0
- package/src/employees/catalog/jefa.json +21 -0
- package/src/employees/install-package.js +77 -0
- package/src/employees/management-policy.js +88 -0
- package/src/employees/manifest.js +53 -0
- package/src/employees/package-registry.js +107 -0
- package/src/employees/project-selection.js +50 -0
- package/src/employees/recruitment.js +199 -0
- package/src/employees/service.js +83 -0
- package/src/employees/task-entry.js +39 -0
- package/src/graphiti/agent-knowledge-workflows.js +135 -25
- package/src/graphiti/federated-application.js +78 -35
- package/src/graphiti/project-agent-control-plane.js +20 -3
- package/src/graphiti/project-agent-mapping.js +155 -5
- package/src/graphiti/project-agent-memory.js +115 -0
- package/src/graphiti/project-agent-task-entry.js +126 -0
- package/src/graphiti/project-agent-workflows.js +30 -14
- package/src/graphiti/provider-client.js +66 -4
- package/src/http/api-router.js +30 -5
- package/src/http/employee-api-router.js +64 -0
- package/src/http/error-mapping.js +4 -0
- package/src/http/graph-api-router.js +2 -0
- package/src/http/request-policy.js +6 -3
- package/src/http/static-handler.js +4 -3
- package/src/mcp/create-mcp-server.js +98 -37
- package/src/mcp/direct-call.js +38 -0
- package/src/mcp/instructions.js +8 -7
- package/src/mcp/provider-task-context-registry.js +74 -0
- package/src/mcp/remote-http-server.js +761 -0
- package/src/mcp/session-id.js +29 -3
- package/src/mcp/task-context-registry.js +88 -29
- package/src/mcp/tool-annotations.js +10 -2
- package/src/mcp/tool-result.js +8 -3
- package/src/mcp-server.js +20 -8
- package/src/native-runtime/runtime.js +58 -8
- package/src/semantic-version.js +42 -0
- package/src/server.js +76 -28
- package/src/setup/agent-installation-status.js +38 -6
- package/src/setup/agents.js +20 -8
- package/src/setup/claude-code-config.js +55 -13
- package/src/setup/codex-bootstrap.js +11 -10
- package/src/setup/codex-config.js +74 -7
- package/src/setup/config-backup.js +18 -2
- package/src/setup/cursor-config.js +22 -5
- package/src/setup/setup.js +30 -22
- package/src/storage/json-file.js +11 -3
- package/src/system/package-version-checker.js +72 -0
- package/src/system/system-service.js +3 -0
- package/dist/web/assets/KnowledgeEditDialog-CZ5ziPrD.js +0 -1
- package/dist/web/assets/KnowledgePage-BRYC9S5Y.js +0 -1
- package/dist/web/assets/PersonalProjectsPage-DEh8XWby.js +0 -1
- package/dist/web/assets/ProjectAgentsPage-Crh7PrXa.css +0 -1
- package/dist/web/assets/ProjectAgentsPage-DPnaH-TR.js +0 -11
- package/dist/web/assets/SearchableSelect-D3HM8YF8.js +0 -1
- package/dist/web/assets/conversation-launcher-settings-DrJEotdf.js +0 -1
- package/dist/web/assets/index-BnH5mcZx.css +0 -1
- package/dist/web/assets/index-GqJf1xqg.js +0 -2
|
@@ -246,6 +246,8 @@ export function providerProjectAgentTaskSubmit(input) {
|
|
|
246
246
|
objective: input.objective,
|
|
247
247
|
work_kind: input.workKind ?? input.work_kind,
|
|
248
248
|
required_capabilities: input.requiredCapabilities ?? input.required_capabilities ?? [],
|
|
249
|
+
executor_capability_hints:
|
|
250
|
+
input.executorCapabilityHints ?? input.executor_capability_hints ?? [],
|
|
249
251
|
duration: input.duration ?? 'ongoing',
|
|
250
252
|
staffing_intent: input.staffingIntent ?? input.staffing_intent ?? 'reuse_preferred',
|
|
251
253
|
lead_agent_id: input.leadAgentId ?? input.lead_agent_id ?? null,
|
|
@@ -293,6 +295,36 @@ export function projectAgentParallelPlan(value = {}) {
|
|
|
293
295
|
};
|
|
294
296
|
}
|
|
295
297
|
|
|
298
|
+
export function providerProjectAgentTokenUsage(value) {
|
|
299
|
+
if (value === undefined || value === null) return value ?? null;
|
|
300
|
+
return {
|
|
301
|
+
source: value.source,
|
|
302
|
+
total_tokens: value.totalTokens ?? value.total_tokens,
|
|
303
|
+
input_tokens: value.inputTokens ?? value.input_tokens ?? null,
|
|
304
|
+
output_tokens: value.outputTokens ?? value.output_tokens ?? null,
|
|
305
|
+
cached_input_tokens: value.cachedInputTokens ?? value.cached_input_tokens ?? null,
|
|
306
|
+
cache_write_input_tokens: value.cacheWriteInputTokens ??
|
|
307
|
+
value.cache_write_input_tokens ?? null,
|
|
308
|
+
reasoning_output_tokens: value.reasoningOutputTokens ??
|
|
309
|
+
value.reasoning_output_tokens ?? null
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export function projectAgentTokenUsage(value) {
|
|
314
|
+
if (value === undefined || value === null) return value ?? null;
|
|
315
|
+
return {
|
|
316
|
+
source: value.source,
|
|
317
|
+
totalTokens: value.total_tokens ?? value.totalTokens,
|
|
318
|
+
inputTokens: value.input_tokens ?? value.inputTokens ?? null,
|
|
319
|
+
outputTokens: value.output_tokens ?? value.outputTokens ?? null,
|
|
320
|
+
cachedInputTokens: value.cached_input_tokens ?? value.cachedInputTokens ?? null,
|
|
321
|
+
cacheWriteInputTokens: value.cache_write_input_tokens ??
|
|
322
|
+
value.cacheWriteInputTokens ?? null,
|
|
323
|
+
reasoningOutputTokens: value.reasoning_output_tokens ??
|
|
324
|
+
value.reasoningOutputTokens ?? null
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
296
328
|
export function providerProjectAgentTaskActivity(input) {
|
|
297
329
|
const result = withoutUndefined({
|
|
298
330
|
personal_space_id: input.personalSpaceId ?? input.personal_space_id,
|
|
@@ -332,6 +364,31 @@ export function providerProjectAgentTaskActivity(input) {
|
|
|
332
364
|
worker_status: input.workerStatus ?? input.worker_status ?? null
|
|
333
365
|
});
|
|
334
366
|
}
|
|
367
|
+
if (hasAny(input, ['tokenUsage', 'token_usage'])) {
|
|
368
|
+
result.token_usage = providerProjectAgentTokenUsage(
|
|
369
|
+
input.tokenUsage ?? input.token_usage
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
if (hasAny(input, ['workerRuntime', 'worker_runtime'])) {
|
|
373
|
+
const runtime = input.workerRuntime ?? input.worker_runtime;
|
|
374
|
+
result.worker_runtime = runtime ? withoutUndefined({
|
|
375
|
+
application: runtime.application,
|
|
376
|
+
session_id: runtime.sessionId ?? runtime.session_id ?? null,
|
|
377
|
+
session_url: runtime.sessionUrl ?? runtime.session_url ?? null
|
|
378
|
+
}) : null;
|
|
379
|
+
}
|
|
380
|
+
copyOptional(
|
|
381
|
+
result,
|
|
382
|
+
'source_session_url',
|
|
383
|
+
input.sourceSessionUrl ?? input.source_session_url ?? null,
|
|
384
|
+
hasAny(input, ['sourceSessionUrl', 'source_session_url'])
|
|
385
|
+
);
|
|
386
|
+
copyOptional(
|
|
387
|
+
result,
|
|
388
|
+
'tools_used',
|
|
389
|
+
input.toolsUsed ?? input.tools_used ?? null,
|
|
390
|
+
hasAny(input, ['toolsUsed', 'tools_used'])
|
|
391
|
+
);
|
|
335
392
|
return result;
|
|
336
393
|
}
|
|
337
394
|
|
|
@@ -344,6 +401,7 @@ export function projectAgentTaskRecord(value = {}) {
|
|
|
344
401
|
objective: value.objective,
|
|
345
402
|
workKind: value.work_kind,
|
|
346
403
|
requiredCapabilities: value.required_capabilities ?? [],
|
|
404
|
+
executorCapabilityHints: value.executor_capability_hints ?? [],
|
|
347
405
|
duration: value.duration,
|
|
348
406
|
staffingIntent: value.staffing_intent,
|
|
349
407
|
status: value.status,
|
|
@@ -411,7 +469,7 @@ export function projectAgentTaskParticipantRecord(value = {}) {
|
|
|
411
469
|
}
|
|
412
470
|
|
|
413
471
|
export function projectAgentTaskEventRecord(value = {}) {
|
|
414
|
-
|
|
472
|
+
const result = {
|
|
415
473
|
eventId: value.event_id,
|
|
416
474
|
taskId: value.task_id,
|
|
417
475
|
agentId: value.agent_id ?? null,
|
|
@@ -439,6 +497,31 @@ export function projectAgentTaskEventRecord(value = {}) {
|
|
|
439
497
|
fallbackUsed: value.fallback_used ?? false,
|
|
440
498
|
createdAt: value.created_at
|
|
441
499
|
};
|
|
500
|
+
copyOptional(
|
|
501
|
+
result,
|
|
502
|
+
'workerRuntime',
|
|
503
|
+
projectAgentWorkerRuntime(value.worker_runtime ?? value.workerRuntime),
|
|
504
|
+
hasAny(value, ['worker_runtime', 'workerRuntime'])
|
|
505
|
+
);
|
|
506
|
+
copyOptional(
|
|
507
|
+
result,
|
|
508
|
+
'sourceSessionUrl',
|
|
509
|
+
value.source_session_url ?? value.sourceSessionUrl ?? null,
|
|
510
|
+
hasAny(value, ['source_session_url', 'sourceSessionUrl'])
|
|
511
|
+
);
|
|
512
|
+
copyOptional(
|
|
513
|
+
result,
|
|
514
|
+
'toolsUsed',
|
|
515
|
+
value.tools_used ?? value.toolsUsed ?? null,
|
|
516
|
+
hasAny(value, ['tools_used', 'toolsUsed'])
|
|
517
|
+
);
|
|
518
|
+
copyOptional(
|
|
519
|
+
result,
|
|
520
|
+
'tokenUsage',
|
|
521
|
+
projectAgentTokenUsage(value.token_usage ?? value.tokenUsage),
|
|
522
|
+
hasAny(value, ['token_usage', 'tokenUsage'])
|
|
523
|
+
);
|
|
524
|
+
return result;
|
|
442
525
|
}
|
|
443
526
|
|
|
444
527
|
export function projectAgentRoutingDecisionRecord(value = {}) {
|
|
@@ -483,6 +566,7 @@ export function projectAgentTaskRouteResult(value = {}) {
|
|
|
483
566
|
task: projectAgentTaskRecord(value.task ?? {}),
|
|
484
567
|
assignedAgent: value.assigned_agent ? projectAgentRecord(value.assigned_agent) : null,
|
|
485
568
|
recruitment: value.recruitment ? projectAgentRecruitmentRecord(value.recruitment) : null,
|
|
569
|
+
recruitments: (value.recruitments ?? []).map(projectAgentRecruitmentRecord),
|
|
486
570
|
decision: value.decision,
|
|
487
571
|
mustDiscloseRecruitment: value.must_disclose_recruitment ?? false,
|
|
488
572
|
clientNotice: value.client_notice ?? null
|
|
@@ -505,6 +589,8 @@ export function projectAgentRecruitmentRecord(value = {}) {
|
|
|
505
589
|
status: value.status,
|
|
506
590
|
confirmationMode: value.confirmation_mode,
|
|
507
591
|
proposedAgentId: value.proposed_agent_id,
|
|
592
|
+
participantRole: value.participant_role ?? 'lead',
|
|
593
|
+
recruitmentSlot: value.recruitment_slot ?? 'lead',
|
|
508
594
|
proposedProfile: value.proposed_profile
|
|
509
595
|
? projectAgentProfileRecord(value.proposed_profile) : null,
|
|
510
596
|
triggerSourceApplication: value.trigger_source_application ?? null,
|
|
@@ -542,10 +628,10 @@ export function projectAgentExecutionSummary(value) {
|
|
|
542
628
|
if (!Array.isArray(value)) return [];
|
|
543
629
|
return value.map((entry = {}) => {
|
|
544
630
|
const actualExecutor = entry.actual_executor_id ?? entry.actual_executor ??
|
|
545
|
-
entry.actualExecutor ??
|
|
631
|
+
entry.actualExecutor ?? null;
|
|
546
632
|
const workSummary = entry.work_summary ?? entry.workSummary ?? entry.summary ?? null;
|
|
547
633
|
const status = entry.status ?? entry.worker_status ?? entry.workerStatus ?? null;
|
|
548
|
-
|
|
634
|
+
const result = {
|
|
549
635
|
agentId: entry.agent_id ?? entry.agentId ?? null,
|
|
550
636
|
agentName: entry.agent_name ?? entry.agentName ?? null,
|
|
551
637
|
occupationEmoji: entry.occupation_emoji ?? entry.occupationEmoji ?? null,
|
|
@@ -563,8 +649,48 @@ export function projectAgentExecutionSummary(value) {
|
|
|
563
649
|
workSummary,
|
|
564
650
|
summary: workSummary,
|
|
565
651
|
status,
|
|
566
|
-
workerStatus: entry.worker_status ?? entry.workerStatus ??
|
|
652
|
+
workerStatus: entry.worker_status ?? entry.workerStatus ?? null
|
|
567
653
|
};
|
|
654
|
+
copyOptional(
|
|
655
|
+
result,
|
|
656
|
+
'workerRuntime',
|
|
657
|
+
projectAgentWorkerRuntime(entry.worker_runtime ?? entry.workerRuntime),
|
|
658
|
+
hasAny(entry, ['worker_runtime', 'workerRuntime'])
|
|
659
|
+
);
|
|
660
|
+
copyOptional(
|
|
661
|
+
result,
|
|
662
|
+
'sourceSessionId',
|
|
663
|
+
entry.source_session_id ?? entry.sourceSessionId ?? null,
|
|
664
|
+
hasAny(entry, ['source_session_id', 'sourceSessionId'])
|
|
665
|
+
);
|
|
666
|
+
copyOptional(
|
|
667
|
+
result,
|
|
668
|
+
'sourceSessionUrl',
|
|
669
|
+
entry.source_session_url ?? entry.sourceSessionUrl ?? null,
|
|
670
|
+
hasAny(entry, ['source_session_url', 'sourceSessionUrl'])
|
|
671
|
+
);
|
|
672
|
+
copyOptional(
|
|
673
|
+
result,
|
|
674
|
+
'toolsUsed',
|
|
675
|
+
entry.tools_used ?? entry.toolsUsed ?? null,
|
|
676
|
+
hasAny(entry, ['tools_used', 'toolsUsed'])
|
|
677
|
+
);
|
|
678
|
+
copyOptional(
|
|
679
|
+
result,
|
|
680
|
+
'tokenUsage',
|
|
681
|
+
projectAgentTokenUsage(entry.token_usage ?? entry.tokenUsage),
|
|
682
|
+
hasAny(entry, ['token_usage', 'tokenUsage'])
|
|
683
|
+
);
|
|
684
|
+
return result;
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
export function projectAgentWorkerRuntime(value) {
|
|
689
|
+
if (!value || typeof value !== 'object') return null;
|
|
690
|
+
return withoutUndefined({
|
|
691
|
+
application: value.application,
|
|
692
|
+
sessionId: value.session_id ?? value.sessionId ?? null,
|
|
693
|
+
sessionUrl: value.session_url ?? value.sessionUrl ?? null
|
|
568
694
|
});
|
|
569
695
|
}
|
|
570
696
|
|
|
@@ -587,12 +713,30 @@ export function projectAgentActivityRecord(value = {}) {
|
|
|
587
713
|
summary: task.summary,
|
|
588
714
|
occurredAt: task.occurred_at,
|
|
589
715
|
sourceApplication: task.source_application ?? null,
|
|
716
|
+
sourceSessionId: task.source_session_id ?? null,
|
|
717
|
+
sourceSessionUrl: task.source_session_url ?? task.sourceSessionUrl ?? null,
|
|
718
|
+
toolsUsed: task.tools_used ?? task.toolsUsed ?? null,
|
|
590
719
|
actualExecutor: task.actual_executor_id ?? task.actual_executor ?? null,
|
|
720
|
+
selectedExecutorId: task.selected_executor_id ?? null,
|
|
721
|
+
executorRuleId: task.executor_rule_id ?? task.rule_id ?? null,
|
|
591
722
|
matchedExecutorRuleId: task.matched_executor_rule_id ?? task.routing_rule_id ?? null,
|
|
592
723
|
executorSelectionReason: task.executor_selection_reason ?? null,
|
|
724
|
+
executorFallbackReason: task.executor_fallback_reason ?? null,
|
|
725
|
+
executorFallbackOutcome: task.executor_fallback_outcome ?? null,
|
|
726
|
+
executorBlockedReason: task.executor_blocked_reason ?? null,
|
|
727
|
+
executorDecision: task.executor_decision ?? null,
|
|
593
728
|
auditId: task.audit_id ?? null,
|
|
594
729
|
actualModelProvider: task.actual_model_provider ?? null,
|
|
595
730
|
actualModel: task.actual_model ?? null,
|
|
731
|
+
workerId: task.worker_id ?? task.workerId ?? null,
|
|
732
|
+
workerLabel: task.worker_label ?? task.workerLabel ?? null,
|
|
733
|
+
workerOccupationEmoji: task.worker_occupation_emoji ??
|
|
734
|
+
task.workerOccupationEmoji ?? null,
|
|
735
|
+
workerStatus: task.worker_status ?? task.workerStatus ?? null,
|
|
736
|
+
tokenUsage: projectAgentTokenUsage(task.token_usage ?? task.tokenUsage),
|
|
737
|
+
...(hasAny(task, ['worker_runtime', 'workerRuntime']) ? {
|
|
738
|
+
workerRuntime: projectAgentWorkerRuntime(task.worker_runtime ?? task.workerRuntime)
|
|
739
|
+
} : {}),
|
|
596
740
|
executionSummary: projectAgentExecutionSummary(
|
|
597
741
|
task.execution_summary ?? task.executionSummary
|
|
598
742
|
),
|
|
@@ -608,7 +752,12 @@ export function projectAgentRecruitmentPolicyRecord(value = {}) {
|
|
|
608
752
|
return {
|
|
609
753
|
personalSpaceId: value.personal_space_id,
|
|
610
754
|
confirmationMode: value.confirmation_mode ?? 'automatic',
|
|
611
|
-
updatedAt: value.updated_at ?? null
|
|
755
|
+
updatedAt: value.updated_at ?? null,
|
|
756
|
+
...(value.policy_status ? {
|
|
757
|
+
policyStatus: value.policy_status,
|
|
758
|
+
appliesToRecruitment: value.applies_to_recruitment,
|
|
759
|
+
warning: value.warning
|
|
760
|
+
} : {})
|
|
612
761
|
};
|
|
613
762
|
}
|
|
614
763
|
|
|
@@ -991,6 +1140,7 @@ export function routingLearningRecord(value = {}) {
|
|
|
991
1140
|
ratingCount: value.rating_count,
|
|
992
1141
|
averageRating: value.average_rating,
|
|
993
1142
|
neutralDueToInsufficientEvidence: value.neutral_due_to_insufficient_evidence,
|
|
1143
|
+
validationWarnings: value.validation_warnings,
|
|
994
1144
|
weightedSuccess: value.weighted_success,
|
|
995
1145
|
weightedFailure: value.weighted_failure,
|
|
996
1146
|
evidenceRefs: value.evidence_refs,
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { ApplicationError, ApplicationErrorCode } from '../app/application-error.js';
|
|
2
|
+
import { detectSensitiveContent } from '../security/sensitive-content.js';
|
|
3
|
+
|
|
4
|
+
export function agentMemoryRecord(value) {
|
|
5
|
+
if (!value || typeof value !== 'object' || Array.isArray(value) ||
|
|
6
|
+
!Number.isInteger(value.revision) || value.revision < 1 ||
|
|
7
|
+
!value.memory || typeof value.memory !== 'object' || Array.isArray(value.memory) ||
|
|
8
|
+
typeof value.memory.summary !== 'string') {
|
|
9
|
+
throw invalidAgentMemoryResponse();
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
checkpointId: value.checkpoint_id,
|
|
13
|
+
personalSpaceId: value.personal_space_id,
|
|
14
|
+
personalProjectId: value.personal_project_id,
|
|
15
|
+
agentId: value.agent_id,
|
|
16
|
+
revision: value.revision,
|
|
17
|
+
memory: {
|
|
18
|
+
summary: value.memory.summary,
|
|
19
|
+
decisions: memoryNotes(value.memory.decisions),
|
|
20
|
+
openThreads: memoryNotes(value.memory.open_threads),
|
|
21
|
+
nextActions: memoryNotes(value.memory.next_actions)
|
|
22
|
+
},
|
|
23
|
+
sourceApplication: value.source_application,
|
|
24
|
+
sourceSessionId: value.source_session_id ?? null,
|
|
25
|
+
taskId: value.task_id ?? null,
|
|
26
|
+
createdAt: value.created_at
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function agentMemoryView(value) {
|
|
31
|
+
if (!value || typeof value !== 'object' || Array.isArray(value) ||
|
|
32
|
+
!Number.isInteger(value.revision) || value.revision < 0 ||
|
|
33
|
+
(value.history !== undefined && value.history !== null && !Array.isArray(value.history))) {
|
|
34
|
+
throw invalidAgentMemoryResponse();
|
|
35
|
+
}
|
|
36
|
+
const current = value.current === undefined || value.current === null
|
|
37
|
+
? null : agentMemoryRecord(value.current);
|
|
38
|
+
const history = (value.history ?? []).map(agentMemoryRecord)
|
|
39
|
+
.filter(record => record.revision !== current?.revision);
|
|
40
|
+
return {
|
|
41
|
+
personalSpaceId: value.personal_space_id,
|
|
42
|
+
personalProjectId: value.personal_project_id,
|
|
43
|
+
agentId: value.agent_id,
|
|
44
|
+
scope: value.scope,
|
|
45
|
+
storage: value.storage,
|
|
46
|
+
authority: value.authority,
|
|
47
|
+
revision: value.revision ?? 0,
|
|
48
|
+
current,
|
|
49
|
+
history
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function getProjectAgentMemory(application, input) {
|
|
54
|
+
await requireAgentMemoryAccess(application, input);
|
|
55
|
+
return agentMemoryView(await application.personal.getProjectAgentMemory(input));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function checkpointProjectAgentMemory(application, input) {
|
|
59
|
+
const prepared = await prepareProjectAgentMemory(application, input);
|
|
60
|
+
if (prepared.status === 'capture_disabled') return prepared;
|
|
61
|
+
const value = await application.personal.writeProjectAgentMemory(prepared.request);
|
|
62
|
+
return { status: 'checkpointed', ...agentMemoryRecord(value) };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Validate and normalize through the same boundary without performing a write.
|
|
66
|
+
// Task checkpoints send this payload to the Provider's atomic prepare operation.
|
|
67
|
+
export async function prepareProjectAgentMemory(application, input) {
|
|
68
|
+
if (detectSensitiveContent(JSON.stringify(input.memory)).restricted) {
|
|
69
|
+
throw new ApplicationError(ApplicationErrorCode.VALIDATION, 'Agent working memory contains credentials');
|
|
70
|
+
}
|
|
71
|
+
await requireAgentMemoryAccess(application, input);
|
|
72
|
+
const policy = application.getCapturePolicy?.() ?? { enabled: true };
|
|
73
|
+
if (!policy.enabled) return { status: 'capture_disabled', capturePolicy: policy };
|
|
74
|
+
return { request: {
|
|
75
|
+
personal_space_id: input.personalSpaceId,
|
|
76
|
+
personal_project_id: input.personalProjectId,
|
|
77
|
+
agent_id: input.agentId,
|
|
78
|
+
expected_revision: input.expectedRevision,
|
|
79
|
+
idempotency_key: input.idempotencyKey,
|
|
80
|
+
memory: {
|
|
81
|
+
summary: input.memory.summary,
|
|
82
|
+
decisions: input.memory.decisions ?? [],
|
|
83
|
+
open_threads: input.memory.openThreads ?? [],
|
|
84
|
+
next_actions: input.memory.nextActions ?? []
|
|
85
|
+
},
|
|
86
|
+
source_application: input.sourceApplication ?? 'other',
|
|
87
|
+
source_session_id: input.sourceSessionId ?? null,
|
|
88
|
+
task_id: input.taskId ?? null
|
|
89
|
+
} };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function requireAgentMemoryAccess(application, input) {
|
|
93
|
+
const agent = await application.getProjectAgent(input);
|
|
94
|
+
if (agent.profile.status !== 'active' || agent.memoryScope !== 'reviewed_agent') {
|
|
95
|
+
throw new ApplicationError(ApplicationErrorCode.VALIDATION, 'An active durable Agent assignment is required for working memory');
|
|
96
|
+
}
|
|
97
|
+
if (!(agent.profile.allowedClients ?? []).includes(input.sourceApplication ?? 'other')) {
|
|
98
|
+
throw new ApplicationError(ApplicationErrorCode.VALIDATION, 'This client is not allowed to load the Agent memory');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function memoryNotes(value) {
|
|
103
|
+
const notes = value ?? [];
|
|
104
|
+
if (!Array.isArray(notes) || notes.some(note => typeof note !== 'string')) {
|
|
105
|
+
throw invalidAgentMemoryResponse();
|
|
106
|
+
}
|
|
107
|
+
return [...notes];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function invalidAgentMemoryResponse() {
|
|
111
|
+
return new ApplicationError(
|
|
112
|
+
ApplicationErrorCode.VALIDATION,
|
|
113
|
+
'Provider returned an invalid Agent memory record'
|
|
114
|
+
);
|
|
115
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { projectAgentRecord } from './project-agent-mapping.js';
|
|
2
|
+
import { agentMemoryView } from './project-agent-memory.js';
|
|
3
|
+
import { planTaskKnowledgeRecall } from './task-knowledge-recall.js';
|
|
4
|
+
|
|
5
|
+
const ENTRY_TOOLS = new Set(['begin_task_context', 'get_collaboration_preferences']);
|
|
6
|
+
|
|
7
|
+
export async function resolveTaskEntryAgent(application, resolution, input) {
|
|
8
|
+
if (!input.agentInvocation || !ENTRY_TOOLS.has(input.agentToolName)) return null;
|
|
9
|
+
if (!resolution.personalProjectId) return { status: 'project_unresolved', worker_started: false };
|
|
10
|
+
try {
|
|
11
|
+
const value = await application.personal.resolveProjectAgentContext({
|
|
12
|
+
personal_space_id: application.config.personal.spaceId,
|
|
13
|
+
personal_project_id: resolution.personalProjectId,
|
|
14
|
+
agent_id: input.projectAgentId ?? null,
|
|
15
|
+
session_id: input.sessionId ?? null,
|
|
16
|
+
turn_id: input.turnId ?? null,
|
|
17
|
+
work_kind: input.workKind ?? taskWorkKind(input.taskPrompt),
|
|
18
|
+
required_capabilities: input.requiredCapabilities ?? [],
|
|
19
|
+
source_application: input.sourceApplication ?? 'other'
|
|
20
|
+
});
|
|
21
|
+
if (!value?.status) throw new Error('Role resolution is unavailable');
|
|
22
|
+
const agent = value.agent ? projectAgentRecord(value.agent) : null;
|
|
23
|
+
const employeeId = /^employee\.([a-z][a-z0-9-]{0,63})$/.exec(agent?.agentId ?? '')?.[1];
|
|
24
|
+
if (employeeId && application.employees) {
|
|
25
|
+
try { await application.employees.authorize({ templateId: employeeId, personalProjectId: resolution.personalProjectId }); }
|
|
26
|
+
catch { return { status: 'agent_unavailable', worker_started: false }; }
|
|
27
|
+
}
|
|
28
|
+
if (agent && (agent.profile.status !== 'active' ||
|
|
29
|
+
!(agent.profile.allowedClients ?? []).includes(input.sourceApplication ?? 'other'))) {
|
|
30
|
+
return { status: 'agent_unavailable', worker_started: false };
|
|
31
|
+
}
|
|
32
|
+
return { ...value, agent, worker_started: false };
|
|
33
|
+
} catch {
|
|
34
|
+
// Preferences remain useful during an older/offline Provider upgrade, but
|
|
35
|
+
// never claim that a role or its private memory was successfully restored.
|
|
36
|
+
return { status: 'unavailable', worker_started: false,
|
|
37
|
+
required_action: 'Role context could not be restored. Check the Provider before claiming continuity.' };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function loadProjectAgentContinuity(application, {
|
|
42
|
+
projectId, agent, sourceApplication = 'other', taskPrompt = null,
|
|
43
|
+
selectionReason = null, matchBasis = [], includeKnowledge = true
|
|
44
|
+
}) {
|
|
45
|
+
const scope = { personalSpaceId: application.config.personal.spaceId,
|
|
46
|
+
personalProjectId: projectId, agentId: agent.agentId };
|
|
47
|
+
const planned = planTaskKnowledgeRecall(taskPrompt);
|
|
48
|
+
const queries = (planned.queries.length ? planned.queries
|
|
49
|
+
: [agent.profile.responsibility || 'project requirements architecture decisions']).slice(0, 2);
|
|
50
|
+
const requests = [
|
|
51
|
+
['memory', agent.memoryScope === 'reviewed_agent'
|
|
52
|
+
? application.personal.getProjectAgentMemory({ ...scope, limit: 1 })
|
|
53
|
+
: Promise.resolve(null)],
|
|
54
|
+
['project', application.personal.getPersonalProject(scope.personalSpaceId, projectId)],
|
|
55
|
+
['tasks', application.personal.listProjectAgentTasks({ ...scope, limit: 4 })],
|
|
56
|
+
['knowledge', includeKnowledge ? Promise.all(queries.map(query => application.searchKnowledge({
|
|
57
|
+
personalSpaceId: scope.personalSpaceId, personalProjectId: projectId,
|
|
58
|
+
projectAgentId: agent.agentId, query, limit: 4, includePending: false,
|
|
59
|
+
agentInvocation: true, agentToolName: 'automatic_project_agent_context'
|
|
60
|
+
}))) : Promise.resolve([])]
|
|
61
|
+
];
|
|
62
|
+
const results = await Promise.allSettled(requests.map(([, promise]) => promise));
|
|
63
|
+
const data = {};
|
|
64
|
+
const unavailable = [];
|
|
65
|
+
results.forEach((result, index) => {
|
|
66
|
+
const key = requests[index][0];
|
|
67
|
+
if (result.status === 'fulfilled') data[key] = result.value;
|
|
68
|
+
else unavailable.push(key);
|
|
69
|
+
});
|
|
70
|
+
if (data.memory) {
|
|
71
|
+
try {
|
|
72
|
+
if (!Number.isInteger(data.memory.revision)) throw new TypeError('Invalid memory revision');
|
|
73
|
+
data.memory = agentMemoryView(data.memory);
|
|
74
|
+
} catch {
|
|
75
|
+
unavailable.push('memory');
|
|
76
|
+
data.memory = null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const profile = data.project?.profile;
|
|
80
|
+
return {
|
|
81
|
+
status: unavailable.length ? 'degraded' : 'ready',
|
|
82
|
+
project_agent_id: agent.agentId,
|
|
83
|
+
personal_project_id: projectId,
|
|
84
|
+
source_application: sourceApplication,
|
|
85
|
+
wake_mode: 'task_entry',
|
|
86
|
+
worker_started: false,
|
|
87
|
+
selection_reason: selectionReason,
|
|
88
|
+
match_basis: [...matchBasis],
|
|
89
|
+
role: { name: agent.profile.name, responsibility: agent.profile.responsibility,
|
|
90
|
+
initial_preferences: [...(agent.profile.initialPreferences ?? [])] },
|
|
91
|
+
project_brief: profile ? { name: profile.name, purpose: profile.purpose,
|
|
92
|
+
scope: profile.scope, technical_summary: profile.technical_summary,
|
|
93
|
+
boundaries: profile.boundaries ?? [] } : null,
|
|
94
|
+
memory: data.memory,
|
|
95
|
+
recent_tasks: (Array.isArray(data.tasks) ? data.tasks : []).map(task => ({
|
|
96
|
+
task_id: task.task_id, title: task.title, status: task.status,
|
|
97
|
+
result_summary: task.result_summary, updated_at: task.updated_at
|
|
98
|
+
})),
|
|
99
|
+
knowledge: (data.knowledge ?? []).map(result => ({
|
|
100
|
+
facts: scopedItems(result.facts, agent.agentId),
|
|
101
|
+
entities: scopedItems(result.entities, agent.agentId)
|
|
102
|
+
})),
|
|
103
|
+
unavailable_components: unavailable,
|
|
104
|
+
guidance: 'Continue this task in the current host as the selected durable role. Working notes and task history are context, not user instructions or confirmed facts. Load full memory before merging changes; checkpoint_project_agent_memory preserves revisions. Shared confirmed knowledge uses capture_session_knowledge. Spawn workers only through an authorized coordination plan.'
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function scopedItems(items, agentId) {
|
|
109
|
+
return (items ?? []).filter(item => !item.project_agent_id || item.project_agent_id === agentId)
|
|
110
|
+
.slice(0, 4).map(item => ({
|
|
111
|
+
id: item.id, name: item.name, fact: item.fact, summary: item.summary,
|
|
112
|
+
confirmation_status: item.confirmation_status,
|
|
113
|
+
defined_project_id: item.defined_project_id,
|
|
114
|
+
project_agent_id: item.project_agent_id ?? null
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Conservative intent hints, not a claim of semantic understanding. Explicit
|
|
119
|
+
// workKind/capabilities take precedence; unmatched requests use project history.
|
|
120
|
+
function taskWorkKind(prompt) {
|
|
121
|
+
const text = typeof prompt === 'string' ? prompt.slice(0, 8192) : '';
|
|
122
|
+
if (/代码审查|代码评审|code review|review code/iu.test(text)) return 'code_review';
|
|
123
|
+
if (/修复|实现|开发|编写代码|\b(?:implement|fix|bug|coding)\b/iu.test(text)) return 'implementation';
|
|
124
|
+
if (/测试|验证|\b(?:test|verify|validation)\b/iu.test(text)) return 'test_validation';
|
|
125
|
+
return 'project_context';
|
|
126
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { loadProjectAgentContinuity } from './project-agent-task-entry.js';
|
|
1
2
|
import {
|
|
2
3
|
executorActualReportRecord,
|
|
3
4
|
executorRecord,
|
|
@@ -175,6 +176,7 @@ export async function coordinateProjectAgentTask(
|
|
|
175
176
|
objective: input.objective,
|
|
176
177
|
workKind: input.workKind,
|
|
177
178
|
requiredCapabilities: input.requiredCapabilities,
|
|
179
|
+
executorCapabilityHints: input.executorCapabilityHints,
|
|
178
180
|
duration: input.duration,
|
|
179
181
|
staffingIntent: input.staffingIntent,
|
|
180
182
|
leadAgentId: input.leadAgentId,
|
|
@@ -213,13 +215,11 @@ export async function coordinateProjectAgentTask(
|
|
|
213
215
|
workerPlan.length > 0 && contextsReady;
|
|
214
216
|
|
|
215
217
|
return {
|
|
216
|
-
status:
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
? 'blocked'
|
|
222
|
-
: 'context_unavailable',
|
|
218
|
+
status: coordinatedTaskStatus(
|
|
219
|
+
route.task.status,
|
|
220
|
+
hostExecutionRequired,
|
|
221
|
+
workerPlan.length
|
|
222
|
+
),
|
|
223
223
|
personal_space_id: application.config.personal.spaceId,
|
|
224
224
|
personal_project_id: projectId,
|
|
225
225
|
project_resolution: projectResolution,
|
|
@@ -252,7 +252,10 @@ export async function viewProjectAgentTask(application, input) {
|
|
|
252
252
|
const value = await application.personal.viewProjectAgentTask(
|
|
253
253
|
input.personalSpaceId,
|
|
254
254
|
input.taskId,
|
|
255
|
-
{
|
|
255
|
+
{
|
|
256
|
+
personalProjectId: input.personalProjectId ?? null,
|
|
257
|
+
includeEvents: input.includeEvents ?? true
|
|
258
|
+
}
|
|
256
259
|
);
|
|
257
260
|
return projectAgentTaskRecord(value.task ?? value);
|
|
258
261
|
}
|
|
@@ -267,6 +270,7 @@ export async function recordProjectAgentTaskActivity(application, input) {
|
|
|
267
270
|
export async function viewProjectAgentActivity(application, input) {
|
|
268
271
|
const value = await application.personal.listProjectAgentActivity({
|
|
269
272
|
personalSpaceId: input.personalSpaceId,
|
|
273
|
+
personalProjectId: input.personalProjectId ?? null,
|
|
270
274
|
agentId: input.agentId,
|
|
271
275
|
fromDate: input.fromDate ?? null,
|
|
272
276
|
toDate: input.toDate ?? null
|
|
@@ -497,8 +501,6 @@ export async function getProjectAgentContext(
|
|
|
497
501
|
personal_project_id: projectId,
|
|
498
502
|
project_agent_id: agentId,
|
|
499
503
|
project_resolution: projectResolution,
|
|
500
|
-
agent,
|
|
501
|
-
executionSummary: agent.executionSummary ?? [],
|
|
502
504
|
required_action: 'Choose an active project Agent or reactivate this Agent before use.'
|
|
503
505
|
};
|
|
504
506
|
}
|
|
@@ -510,8 +512,6 @@ export async function getProjectAgentContext(
|
|
|
510
512
|
project_agent_id: agentId,
|
|
511
513
|
project_resolution: projectResolution,
|
|
512
514
|
source_application: sourceApplication,
|
|
513
|
-
agent,
|
|
514
|
-
executionSummary: agent.executionSummary ?? [],
|
|
515
515
|
required_action: (
|
|
516
516
|
'Use a client in this Agent\'s allow-list or update the Agent profile '
|
|
517
517
|
+ 'before loading its context.'
|
|
@@ -519,10 +519,11 @@ export async function getProjectAgentContext(
|
|
|
519
519
|
};
|
|
520
520
|
}
|
|
521
521
|
|
|
522
|
-
const [preferences, results] = await Promise.all([
|
|
522
|
+
const [preferences, results, continuity] = await Promise.all([
|
|
523
523
|
application.getCollaborationPreferences({
|
|
524
524
|
personalProjectId: projectId,
|
|
525
525
|
projectAgentId: agentId,
|
|
526
|
+
sourceApplication,
|
|
526
527
|
agentInvocation: true,
|
|
527
528
|
agentToolName: 'get_project_agent_context'
|
|
528
529
|
}),
|
|
@@ -535,7 +536,10 @@ export async function getProjectAgentContext(
|
|
|
535
536
|
includePending,
|
|
536
537
|
agentInvocation: true,
|
|
537
538
|
agentToolName: 'get_project_agent_context'
|
|
538
|
-
})))
|
|
539
|
+
}))),
|
|
540
|
+
loadProjectAgentContinuity(application, {
|
|
541
|
+
projectId, agent, sourceApplication, includeKnowledge: false
|
|
542
|
+
})
|
|
539
543
|
]);
|
|
540
544
|
|
|
541
545
|
return {
|
|
@@ -555,6 +559,11 @@ export async function getProjectAgentContext(
|
|
|
555
559
|
deferred_conflicts: preferences.deferred_conflicts,
|
|
556
560
|
active_conflicts: preferences.active_conflicts,
|
|
557
561
|
knowledge_results: results,
|
|
562
|
+
working_memory: continuity.memory,
|
|
563
|
+
project_brief: continuity.project_brief,
|
|
564
|
+
recent_tasks: continuity.recent_tasks,
|
|
565
|
+
continuity_status: continuity.status,
|
|
566
|
+
unavailable_components: continuity.unavailable_components,
|
|
558
567
|
scope_policy: {
|
|
559
568
|
includes_personal_global_preferences: true,
|
|
560
569
|
includes_project_preferences_and_shared_knowledge: true,
|
|
@@ -566,6 +575,13 @@ export async function getProjectAgentContext(
|
|
|
566
575
|
};
|
|
567
576
|
}
|
|
568
577
|
|
|
578
|
+
function coordinatedTaskStatus(taskStatus, hostExecutionRequired, participantCount) {
|
|
579
|
+
if (hostExecutionRequired) return 'ready_for_host_execution';
|
|
580
|
+
if (taskStatus === 'queued' && participantCount === 0) return 'staffing_unavailable';
|
|
581
|
+
if (taskStatus === 'queued' || !taskStatus) return 'context_unavailable';
|
|
582
|
+
return taskStatus;
|
|
583
|
+
}
|
|
584
|
+
|
|
569
585
|
function asList(value, keys = []) {
|
|
570
586
|
if (Array.isArray(value)) return value;
|
|
571
587
|
if (!value || typeof value !== 'object') return [];
|