fuli-context 0.7.5 → 0.7.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/README.md +69 -13
- package/README.zh-CN.md +60 -14
- package/dist/web/assets/{AboutPage-ByCUor-j.js → AboutPage-BcZeFcHe.js} +1 -1
- package/dist/web/assets/{ConnectionsPage-DkdkZ40Q.js → ConnectionsPage-xAQYl1SQ.js} +1 -1
- package/dist/web/assets/EmployeeRecruitDialog-CbPAmhy7.js +1 -0
- package/dist/web/assets/EmployeeRecruitDialog-CfFlyKSh.css +1 -0
- package/dist/web/assets/EmployeeWorkbenchPage-BQvTLoc8.css +1 -0
- package/dist/web/assets/EmployeeWorkbenchPage-DF3EL0Ui.js +1 -0
- package/dist/web/assets/KnowledgeEditDialog-UnnBDt0I.js +1 -0
- package/dist/web/assets/{KnowledgeEditDialog-DWUV_NPp.css → KnowledgeEditDialog-iv-dgUeD.css} +1 -1
- package/dist/web/assets/{KnowledgeInspector-CYAjAb9J.js → KnowledgeInspector-BqPJH5Rr.js} +1 -1
- package/dist/web/assets/{KnowledgeOrganizerPage-CV4F54R_.js → KnowledgeOrganizerPage-CyvRflXM.js} +1 -1
- package/dist/web/assets/KnowledgePage-59eczTqe.js +1 -0
- package/dist/web/assets/{KnowledgeWorkspace-z4u5mXOG.js → KnowledgeWorkspace-CfIjhOog.js} +1 -1
- package/dist/web/assets/{OverviewPage-BWOfeS6k.js → OverviewPage-Xyfm5xkZ.js} +1 -1
- package/dist/web/assets/{PersonalProfilePage-c3w4-h7a.js → PersonalProfilePage-DB9mByB3.js} +1 -1
- package/dist/web/assets/PersonalProjectsPage-_-YXVi5O.js +1 -0
- package/dist/web/assets/ProjectAgentsPage-C3vW6wmk.css +1 -0
- package/dist/web/assets/ProjectAgentsPage-DeeQByPX.js +11 -0
- package/dist/web/assets/{PublicProjectsPage-DdH0oGB3.js → PublicProjectsPage-BEZ1YPs3.js} +1 -1
- package/dist/web/assets/{ReviewPage-BYIpcIHG.js → ReviewPage-CQYGwFBH.js} +1 -1
- package/dist/web/assets/SearchableSelect-D27H0MoP.js +1 -0
- package/dist/web/assets/{SettingsPage-2VkbXgZi.js → SettingsPage-BlEZ03Yi.js} +1 -1
- package/dist/web/assets/{WritingTastePage-BOPQZuva.js → WritingTastePage-DvRt_nmP.js} +1 -1
- package/dist/web/assets/catalog-DFvIaHVS.js +1 -0
- package/dist/web/assets/{console-BlAhujsH.js → console-tOxOl8Vq.js} +1 -1
- package/dist/web/assets/conversation-launcher-settings-DuFSpPAo.js +1 -0
- package/dist/web/assets/{i18n-Ci3heuiL.js → i18n-CgBHZthI.js} +3 -3
- package/dist/web/assets/{identity-4_-v6cB7.js → identity-CFo_Uw1H.js} +1 -1
- package/dist/web/assets/index-CJc5ppXH.css +1 -0
- package/dist/web/assets/index-yCi3cz2l.js +2 -0
- package/dist/web/assets/{model-yG0YqUyZ.js → model-BtnVr7fX.js} +1 -1
- package/dist/web/assets/{useApi-CROJJdhE-twhdZArA.js → useApi-CROJJdhE-B6MHm_Av.js} +1 -1
- package/dist/web/assets/{vue-router-C-wot_Di.js → vue-router-CzHm-y-x.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_coordination_models.py +22 -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 +50 -1
- package/graph-provider/fuli_graph/project_agent_task_models.py +220 -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_coordination_policy.py +122 -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 +756 -164
- package/graph-provider/fuli_graph/store_project_agent_task_staffing.py +396 -7
- package/graph-provider/fuli_graph/store_project_agent_tasks.py +265 -465
- 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 +48 -6
- package/src/agent-tools/graph-handlers.js +15 -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.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 +32 -3
- package/src/graphiti/project-agent-mapping.js +175 -4
- 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 +49 -14
- package/src/graphiti/provider-client.js +78 -4
- package/src/http/api-router.js +25 -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 +14 -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 +12 -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/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/dist/web/assets/KnowledgeEditDialog-DSe3Gwep.js +0 -1
- package/dist/web/assets/KnowledgePage-vYYXipOi.js +0 -1
- package/dist/web/assets/PersonalProjectsPage-B7AlLEwf.js +0 -1
- package/dist/web/assets/ProjectAgentsPage-CgftpIPB.css +0 -1
- package/dist/web/assets/ProjectAgentsPage-DTHcL_ox.js +0 -11
- package/dist/web/assets/SearchableSelect-Dz13ClQb.js +0 -1
- package/dist/web/assets/conversation-launcher-settings-DTYxiLJt.js +0 -1
- package/dist/web/assets/index-BnH5mcZx.css +0 -1
- package/dist/web/assets/index-C67Q0JY2.js +0 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { dirname } from 'node:path';
|
|
2
|
+
import { createEmployeeService } from '../employees/service.js';
|
|
2
3
|
|
|
3
4
|
import { GraphitiProviderClient } from './provider-client.js';
|
|
4
5
|
import {
|
|
@@ -30,7 +31,7 @@ import {
|
|
|
30
31
|
} from './source-marker.js';
|
|
31
32
|
import { resolvePersonalProjectPath } from './project-path-context.js';
|
|
32
33
|
import { mergeExternalKnowledgeProjection } from '../external-knowledge/graph-projection.js';
|
|
33
|
-
import {
|
|
34
|
+
import { ProviderTaskContextRegistry } from '../mcp/provider-task-context-registry.js';
|
|
34
35
|
import { attachExternalKnowledgeRuntime } from '../external-knowledge/runtime.js';
|
|
35
36
|
import { resolveSetupPaths } from '../setup/paths.js';
|
|
36
37
|
import {
|
|
@@ -79,6 +80,7 @@ import {
|
|
|
79
80
|
getCollaborationPreferences as getCollaborationPreferencesWorkflow
|
|
80
81
|
} from './collaboration-preference-workflow.js';
|
|
81
82
|
import { buildUserTasteSkill } from './user-taste-skill.js';
|
|
83
|
+
import { resolveTaskEntryAgent, loadProjectAgentContinuity } from './project-agent-task-entry.js';
|
|
82
84
|
import { getWritingTasteProfile as getWritingTasteProfileWorkflow } from './writing-taste-profile-workflow.js';
|
|
83
85
|
import {
|
|
84
86
|
groupSubscriptions,
|
|
@@ -114,6 +116,7 @@ export function openFederatedGraphApplication({
|
|
|
114
116
|
env,
|
|
115
117
|
fetchImpl
|
|
116
118
|
});
|
|
119
|
+
app.employees = createEmployeeService({ app, runtimeConfigPath });
|
|
117
120
|
}
|
|
118
121
|
return app;
|
|
119
122
|
}
|
|
@@ -137,7 +140,7 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
137
140
|
agentAccessPolicyStore = new AgentAccessPolicyStore(),
|
|
138
141
|
consoleUrl = sourceConsoleUrl(null),
|
|
139
142
|
projectPathResolver = resolvePersonalProjectPath,
|
|
140
|
-
taskContextRegistry =
|
|
143
|
+
taskContextRegistry = null,
|
|
141
144
|
providerRequestTimeoutMs = undefined
|
|
142
145
|
} = {}) {
|
|
143
146
|
super();
|
|
@@ -147,7 +150,6 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
147
150
|
this.agentAccessPolicyStore = agentAccessPolicyStore;
|
|
148
151
|
this.consoleUrl = consoleUrl;
|
|
149
152
|
this.projectPathResolver = projectPathResolver;
|
|
150
|
-
this.taskContextRegistry = taskContextRegistry;
|
|
151
153
|
this.personal = new GraphitiProviderClient({
|
|
152
154
|
baseUrl: config.personal.providerUrl,
|
|
153
155
|
accessToken: config.personal.accessToken,
|
|
@@ -155,6 +157,9 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
155
157
|
fetchImpl,
|
|
156
158
|
requestTimeoutMs: providerRequestTimeoutMs
|
|
157
159
|
});
|
|
160
|
+
this.taskContextRegistry = taskContextRegistry ?? new ProviderTaskContextRegistry(
|
|
161
|
+
this.personal, config.personal.spaceId
|
|
162
|
+
);
|
|
158
163
|
this.workspaces = new Map(config.workspaces.map((workspace) => {
|
|
159
164
|
const provider = createWorkspaceProvider(workspace, {
|
|
160
165
|
fetchImpl, requestTimeoutMs: providerRequestTimeoutMs
|
|
@@ -171,8 +176,8 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
171
176
|
return checkpointTaskKnowledgeWorkflow(this, input);
|
|
172
177
|
}
|
|
173
178
|
|
|
174
|
-
verifyTaskCheckpoint({ sessionId }) {
|
|
175
|
-
return this.taskContextRegistry.verify(sessionId);
|
|
179
|
+
verifyTaskCheckpoint({ sessionId, sourceApplication = 'other' }) {
|
|
180
|
+
return this.taskContextRegistry.verify(sessionId, sourceApplication);
|
|
176
181
|
}
|
|
177
182
|
|
|
178
183
|
async recordDecisionTrace(input) {
|
|
@@ -180,6 +185,10 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
180
185
|
return recordDecisionTraceWorkflow(this, input);
|
|
181
186
|
}
|
|
182
187
|
|
|
188
|
+
validateCaptureSessionKnowledge(input) {
|
|
189
|
+
if (this.getCapturePolicy().enabled) this.#prepareKnowledgeCapture(input);
|
|
190
|
+
}
|
|
191
|
+
|
|
183
192
|
async captureSessionKnowledge(input) {
|
|
184
193
|
const capturePolicy = this.getCapturePolicy();
|
|
185
194
|
if (!capturePolicy.enabled) {
|
|
@@ -189,15 +198,8 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
189
198
|
capturePolicy
|
|
190
199
|
};
|
|
191
200
|
}
|
|
192
|
-
|
|
193
|
-
const episode = providerEpisode(input);
|
|
201
|
+
const { episode, workspace } = this.#prepareKnowledgeCapture(input);
|
|
194
202
|
if (input.targetKind === 'personal') {
|
|
195
|
-
if (input.spaceId !== this.config.personal.spaceId) {
|
|
196
|
-
throw new ApplicationError(
|
|
197
|
-
ApplicationErrorCode.VALIDATION,
|
|
198
|
-
'Personal capture target must be the active personal space'
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
203
|
const result = await this.personal.commit({
|
|
202
204
|
space_id: input.spaceId,
|
|
203
205
|
personal_project_id: input.personalProjectId ?? null,
|
|
@@ -206,20 +208,6 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
206
208
|
});
|
|
207
209
|
return { route: 'personal', ...result };
|
|
208
210
|
}
|
|
209
|
-
if (input.projectAgentId) {
|
|
210
|
-
throw new ApplicationError(
|
|
211
|
-
ApplicationErrorCode.VALIDATION,
|
|
212
|
-
'Project Agent knowledge can only be captured in the personal graph'
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
if (episode.sensitivity !== 'normal') {
|
|
216
|
-
throw new ApplicationError(
|
|
217
|
-
ApplicationErrorCode.VALIDATION,
|
|
218
|
-
'Private or restricted knowledge cannot enter a team-shared project queue. Use targetKind "personal" with personalProjectId to keep it in the personal graph'
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
assertPublicKnowledgeEligible(episode);
|
|
222
|
-
const workspace = this.#workspace(input.providerUrl);
|
|
223
211
|
const draft = await this.personal.createPublicationDraft({
|
|
224
212
|
personal_space_id: this.config.personal.spaceId,
|
|
225
213
|
target_project_id: input.spaceId,
|
|
@@ -257,19 +245,33 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
257
245
|
projectAgentId = null,
|
|
258
246
|
projectPath = null,
|
|
259
247
|
taskPrompt = null,
|
|
248
|
+
sourceApplication = 'other',
|
|
249
|
+
sourceSessionId = null,
|
|
250
|
+
sessionId = null,
|
|
251
|
+
turnId = null,
|
|
252
|
+
workKind = null,
|
|
253
|
+
requiredCapabilities = [],
|
|
260
254
|
limit = 100,
|
|
261
255
|
agentInvocation = false,
|
|
262
256
|
agentToolName = 'get_collaboration_preferences'
|
|
263
257
|
} = {}) {
|
|
264
|
-
const projectResolution = await this.#resolvePreferenceProject({
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
258
|
+
const projectResolution = await this.#resolvePreferenceProject({ personalProjectId, projectPath });
|
|
259
|
+
const selection = projectPath === null && !personalProjectId && !projectAgentId
|
|
260
|
+
? null
|
|
261
|
+
: await resolveTaskEntryAgent(
|
|
262
|
+
this, projectResolution, { projectAgentId, taskPrompt, sourceApplication,
|
|
263
|
+
sessionId: agentToolName === 'get_collaboration_preferences'
|
|
264
|
+
? sessionId ?? sourceSessionId : turnId ? sessionId : null,
|
|
265
|
+
turnId: agentToolName === 'begin_task_context' ? turnId : null,
|
|
266
|
+
workKind, requiredCapabilities, agentInvocation, agentToolName }
|
|
267
|
+
);
|
|
268
|
+
// A rejected explicit role must not leak its private preferences via fallback.
|
|
269
|
+
const selectedAgentId = selection ? selection.agent?.agentId ?? null : projectAgentId;
|
|
270
|
+
const preferences = await getCollaborationPreferencesWorkflow(
|
|
269
271
|
this,
|
|
270
272
|
projectResolution,
|
|
271
273
|
{
|
|
272
|
-
projectAgentId,
|
|
274
|
+
projectAgentId: selectedAgentId,
|
|
273
275
|
taskPrompt,
|
|
274
276
|
limit,
|
|
275
277
|
agentInvocation,
|
|
@@ -277,6 +279,19 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
277
279
|
},
|
|
278
280
|
(items, toolName) => this.#recordAgentViews(items, toolName)
|
|
279
281
|
);
|
|
282
|
+
const management = this.employees && agentInvocation &&
|
|
283
|
+
['begin_task_context', 'get_collaboration_preferences'].includes(agentToolName)
|
|
284
|
+
? await this.employees.taskEntry({ personalProjectId: projectResolution.personalProjectId,
|
|
285
|
+
sourceApplication, sourceSessionId, sessionId })
|
|
286
|
+
: null;
|
|
287
|
+
const managedPreferences = management ? { ...preferences, project_management_context: management } : preferences;
|
|
288
|
+
if (!selection) return managedPreferences;
|
|
289
|
+
const context = selection.agent ? await loadProjectAgentContinuity(this, {
|
|
290
|
+
projectId: projectResolution.personalProjectId, agent: selection.agent,
|
|
291
|
+
sourceApplication, taskPrompt, selectionReason: selection.reason,
|
|
292
|
+
matchBasis: selection.match_basis
|
|
293
|
+
}) : selection;
|
|
294
|
+
return { ...managedPreferences, project_agent_context: context };
|
|
280
295
|
}
|
|
281
296
|
|
|
282
297
|
async getUserTasteSkill({
|
|
@@ -518,7 +533,7 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
518
533
|
|
|
519
534
|
async searchCurrentProjectKnowledge(input) {
|
|
520
535
|
const resolution = await this.#resolvePreferenceProject({
|
|
521
|
-
personalProjectId: null,
|
|
536
|
+
personalProjectId: input.personalProjectId ?? null,
|
|
522
537
|
projectPath: input.projectPath
|
|
523
538
|
});
|
|
524
539
|
return searchCurrentProjectKnowledgeWorkflow(this, resolution, input);
|
|
@@ -1164,7 +1179,7 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
1164
1179
|
};
|
|
1165
1180
|
}
|
|
1166
1181
|
|
|
1167
|
-
close() {}
|
|
1182
|
+
close() { return this.employees?.close(); }
|
|
1168
1183
|
|
|
1169
1184
|
async #recordAgentViews(items, toolName) {
|
|
1170
1185
|
const unique = new Map(items.map((item) => [
|
|
@@ -1195,6 +1210,34 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
|
|
|
1195
1210
|
return this.#resolvePreferenceProject(input);
|
|
1196
1211
|
}
|
|
1197
1212
|
|
|
1213
|
+
#prepareKnowledgeCapture(input) {
|
|
1214
|
+
assertNoCredentials(input);
|
|
1215
|
+
const episode = providerEpisode(input);
|
|
1216
|
+
if (input.targetKind === 'personal') {
|
|
1217
|
+
if (input.spaceId !== this.config.personal.spaceId) {
|
|
1218
|
+
throw new ApplicationError(
|
|
1219
|
+
ApplicationErrorCode.VALIDATION,
|
|
1220
|
+
'Personal capture target must be the active personal space'
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
return { episode };
|
|
1224
|
+
}
|
|
1225
|
+
if (input.projectAgentId) {
|
|
1226
|
+
throw new ApplicationError(
|
|
1227
|
+
ApplicationErrorCode.VALIDATION,
|
|
1228
|
+
'Project Agent knowledge can only be captured in the personal graph'
|
|
1229
|
+
);
|
|
1230
|
+
}
|
|
1231
|
+
if (episode.sensitivity !== 'normal') {
|
|
1232
|
+
throw new ApplicationError(
|
|
1233
|
+
ApplicationErrorCode.VALIDATION,
|
|
1234
|
+
'Private or restricted knowledge cannot enter a team-shared project queue. Use targetKind "personal" with personalProjectId to keep it in the personal graph'
|
|
1235
|
+
);
|
|
1236
|
+
}
|
|
1237
|
+
assertPublicKnowledgeEligible(episode);
|
|
1238
|
+
return { episode, workspace: this.#workspace(input.providerUrl) };
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1198
1241
|
#workspace(providerUrl) {
|
|
1199
1242
|
const requested = providerUrl
|
|
1200
1243
|
? canonicalProviderUrl(providerUrl)
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { agentProjectResolution } from './agent-knowledge-workflows.js';
|
|
2
|
+
import {
|
|
3
|
+
getProjectAgentMemory,
|
|
4
|
+
checkpointProjectAgentMemory
|
|
5
|
+
} from './project-agent-memory.js';
|
|
2
6
|
import {
|
|
3
7
|
authorizeExecutor as authorizeExecutorWorkflow,
|
|
4
8
|
cleanupProjectAgentTestRoles as cleanupProjectAgentTestRolesWorkflow,
|
|
@@ -13,6 +17,7 @@ import {
|
|
|
13
17
|
getExecutorRoutingRule as getExecutorRoutingRuleWorkflow,
|
|
14
18
|
getProjectAgent as getProjectAgentWorkflow,
|
|
15
19
|
getProjectAgentContext as getProjectAgentContextWorkflow,
|
|
20
|
+
getProjectAgentCoordinationPolicy as getProjectAgentCoordinationPolicyWorkflow,
|
|
16
21
|
getProjectAgentRecruitmentPolicy as getProjectAgentRecruitmentPolicyWorkflow,
|
|
17
22
|
ignoreProjectAgentRoutingLearning as ignoreProjectAgentRoutingLearningWorkflow,
|
|
18
23
|
listCurrentProjectAgents as listCurrentProjectAgentsWorkflow,
|
|
@@ -32,6 +37,7 @@ import {
|
|
|
32
37
|
resetProjectAgentRoutingLearning as resetProjectAgentRoutingLearningWorkflow,
|
|
33
38
|
submitProjectAgentTask as submitProjectAgentTaskWorkflow,
|
|
34
39
|
updateExecutorRoutingRule as updateExecutorRoutingRuleWorkflow,
|
|
40
|
+
updateProjectAgentCoordinationPolicy as updateProjectAgentCoordinationPolicyWorkflow,
|
|
35
41
|
updateProjectAgentRecruitmentPolicy as updateProjectAgentRecruitmentPolicyWorkflow,
|
|
36
42
|
upsertExecutor as upsertExecutorWorkflow,
|
|
37
43
|
upsertExecutorRoutingRule as upsertExecutorRoutingRuleWorkflow,
|
|
@@ -46,6 +52,16 @@ export const projectAgentControlPlaneHooks = Object.freeze({
|
|
|
46
52
|
});
|
|
47
53
|
|
|
48
54
|
export class ProjectAgentControlPlaneApplication {
|
|
55
|
+
async getProjectAgentMemory(input) {
|
|
56
|
+
this.#assertSpace(input.personalSpaceId);
|
|
57
|
+
return getProjectAgentMemory(this, input);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async checkpointProjectAgentMemory(input) {
|
|
61
|
+
this.#assertSpace(input.personalSpaceId);
|
|
62
|
+
return checkpointProjectAgentMemory(this, input);
|
|
63
|
+
}
|
|
64
|
+
|
|
49
65
|
async upsertProjectAgent(input) {
|
|
50
66
|
this.#assertSpace(input.personalSpaceId);
|
|
51
67
|
return upsertProjectAgentWorkflow(this, input);
|
|
@@ -134,6 +150,16 @@ export class ProjectAgentControlPlaneApplication {
|
|
|
134
150
|
return viewProjectAgentActivityWorkflow(this, input);
|
|
135
151
|
}
|
|
136
152
|
|
|
153
|
+
async getProjectAgentCoordinationPolicy(input) {
|
|
154
|
+
this.#assertSpace(input.personalSpaceId);
|
|
155
|
+
return getProjectAgentCoordinationPolicyWorkflow(this, input);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async updateProjectAgentCoordinationPolicy(input) {
|
|
159
|
+
this.#assertSpace(input.personalSpaceId);
|
|
160
|
+
return updateProjectAgentCoordinationPolicyWorkflow(this, input);
|
|
161
|
+
}
|
|
162
|
+
|
|
137
163
|
async getProjectAgentRecruitmentPolicy(input) {
|
|
138
164
|
this.#assertSpace(input.personalSpaceId);
|
|
139
165
|
return getProjectAgentRecruitmentPolicyWorkflow(this, input);
|
|
@@ -240,7 +266,10 @@ export class ProjectAgentControlPlaneApplication {
|
|
|
240
266
|
}
|
|
241
267
|
|
|
242
268
|
async getProjectAgentContext(input) {
|
|
243
|
-
const resolution = await this.#resolveProject(
|
|
269
|
+
const resolution = await this.#resolveProject(
|
|
270
|
+
input.projectPath,
|
|
271
|
+
input.personalProjectId ?? null
|
|
272
|
+
);
|
|
244
273
|
return getProjectAgentContextWorkflow(
|
|
245
274
|
this,
|
|
246
275
|
agentProjectResolution(resolution),
|
|
@@ -254,9 +283,9 @@ export class ProjectAgentControlPlaneApplication {
|
|
|
254
283
|
);
|
|
255
284
|
}
|
|
256
285
|
|
|
257
|
-
#resolveProject(projectPath) {
|
|
286
|
+
#resolveProject(projectPath, personalProjectId = null) {
|
|
258
287
|
return this[projectAgentControlPlaneHooks.resolvePreferenceProject]({
|
|
259
|
-
personalProjectId
|
|
288
|
+
personalProjectId,
|
|
260
289
|
projectPath
|
|
261
290
|
});
|
|
262
291
|
}
|
|
@@ -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,10 +752,36 @@ export function projectAgentRecruitmentPolicyRecord(value = {}) {
|
|
|
608
752
|
return {
|
|
609
753
|
personalSpaceId: value.personal_space_id,
|
|
610
754
|
confirmationMode: value.confirmation_mode ?? 'automatic',
|
|
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
|
+
} : {})
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
export function projectAgentCoordinationPolicyRecord(value = {}) {
|
|
765
|
+
return {
|
|
766
|
+
personalSpaceId: value.personal_space_id,
|
|
767
|
+
personalProjectId: value.personal_project_id,
|
|
768
|
+
askBeforeRecruitment: value.ask_before_recruitment ?? true,
|
|
769
|
+
autoReusePreviousAgent: value.auto_reuse_previous_agent ?? true,
|
|
611
770
|
updatedAt: value.updated_at ?? null
|
|
612
771
|
};
|
|
613
772
|
}
|
|
614
773
|
|
|
774
|
+
export function providerProjectAgentCoordinationPolicy(input) {
|
|
775
|
+
return {
|
|
776
|
+
personal_space_id: input.personalSpaceId ?? input.personal_space_id,
|
|
777
|
+
personal_project_id: input.personalProjectId ?? input.personal_project_id,
|
|
778
|
+
ask_before_recruitment:
|
|
779
|
+
input.askBeforeRecruitment ?? input.ask_before_recruitment ?? true,
|
|
780
|
+
auto_reuse_previous_agent:
|
|
781
|
+
input.autoReusePreviousAgent ?? input.auto_reuse_previous_agent ?? true
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
|
|
615
785
|
export function providerProjectAgentRecruitmentDecision(input) {
|
|
616
786
|
return {
|
|
617
787
|
personal_space_id: input.personalSpaceId ?? input.personal_space_id,
|
|
@@ -970,6 +1140,7 @@ export function routingLearningRecord(value = {}) {
|
|
|
970
1140
|
ratingCount: value.rating_count,
|
|
971
1141
|
averageRating: value.average_rating,
|
|
972
1142
|
neutralDueToInsufficientEvidence: value.neutral_due_to_insufficient_evidence,
|
|
1143
|
+
validationWarnings: value.validation_warnings,
|
|
973
1144
|
weightedSuccess: value.weighted_success,
|
|
974
1145
|
weightedFailure: value.weighted_failure,
|
|
975
1146
|
evidenceRefs: value.evidence_refs,
|