fuli-context 0.7.4-beta.2 → 0.7.5

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.
Files changed (133) hide show
  1. package/README.md +93 -7
  2. package/README.zh-CN.md +84 -7
  3. package/compose.graphiti.yml +6 -6
  4. package/dist/web/assets/AboutPage-ByCUor-j.js +1 -0
  5. package/dist/web/assets/ConnectionsPage-DkdkZ40Q.js +1 -0
  6. package/dist/web/assets/KnowledgeEditDialog-DSe3Gwep.js +1 -0
  7. package/dist/web/assets/KnowledgeInspector-CYAjAb9J.js +1 -0
  8. package/dist/web/assets/KnowledgeOrganizerPage-CV4F54R_.js +1 -0
  9. package/dist/web/assets/KnowledgePage-vYYXipOi.js +1 -0
  10. package/dist/web/assets/KnowledgeWorkspace-z4u5mXOG.js +4 -0
  11. package/dist/web/assets/OverviewPage-BWOfeS6k.js +1 -0
  12. package/dist/web/assets/PersonalProfilePage-c3w4-h7a.js +1 -0
  13. package/dist/web/assets/PersonalProjectsPage-B7AlLEwf.js +1 -0
  14. package/dist/web/assets/ProjectAgentsPage-CgftpIPB.css +1 -0
  15. package/dist/web/assets/ProjectAgentsPage-DTHcL_ox.js +11 -0
  16. package/dist/web/assets/PublicProjectsPage-DdH0oGB3.js +1 -0
  17. package/dist/web/assets/ReviewPage-BYIpcIHG.js +1 -0
  18. package/dist/web/assets/SearchableSelect-Dz13ClQb.js +1 -0
  19. package/dist/web/assets/SettingsPage-2VkbXgZi.js +1 -0
  20. package/dist/web/assets/SettingsPage-CwZp2ka4.css +1 -0
  21. package/dist/web/assets/WritingTastePage-BOPQZuva.js +1 -0
  22. package/dist/web/assets/{console-DMvHxKf9.js → console-BlAhujsH.js} +1 -1
  23. package/dist/web/assets/{conversation-launcher-settings-Dnlcw7Rj.js → conversation-launcher-settings-DTYxiLJt.js} +1 -1
  24. package/dist/web/assets/i18n-Ci3heuiL.js +9 -0
  25. package/dist/web/assets/{identity-C9mLdR8L.js → identity-4_-v6cB7.js} +1 -1
  26. package/dist/web/assets/index-BnH5mcZx.css +1 -0
  27. package/dist/web/assets/index-C67Q0JY2.js +2 -0
  28. package/dist/web/assets/{model-CsYAR8O3.js → model-yG0YqUyZ.js} +1 -1
  29. package/dist/web/assets/{useApi-CROJJdhE-BLQiPVw0.js → useApi-CROJJdhE-twhdZArA.js} +1 -1
  30. package/dist/web/assets/vue-router-C-wot_Di.js +1 -0
  31. package/dist/web/index.html +6 -6
  32. package/docs/public-personal-architecture.md +73 -0
  33. package/graph-provider/fuli_graph/app.py +8 -0
  34. package/graph-provider/fuli_graph/collaboration_context.py +69 -6
  35. package/graph-provider/fuli_graph/knowledge_search.py +84 -5
  36. package/graph-provider/fuli_graph/model_validation.py +134 -0
  37. package/graph-provider/fuli_graph/models.py +24 -5
  38. package/graph-provider/fuli_graph/project_agent_access.py +54 -0
  39. package/graph-provider/fuli_graph/project_agent_executor_models.py +635 -0
  40. package/graph-provider/fuli_graph/project_agent_models.py +278 -0
  41. package/graph-provider/fuli_graph/project_agent_routes.py +597 -0
  42. package/graph-provider/fuli_graph/project_agent_task_models.py +542 -0
  43. package/graph-provider/fuli_graph/runtime.py +259 -0
  44. package/graph-provider/fuli_graph/search_projection.py +3 -0
  45. package/graph-provider/fuli_graph/store.py +6 -0
  46. package/graph-provider/fuli_graph/store_knowledge.py +62 -9
  47. package/graph-provider/fuli_graph/store_project_agent_executor_learning.py +756 -0
  48. package/graph-provider/fuli_graph/store_project_agent_executor_routing.py +601 -0
  49. package/graph-provider/fuli_graph/store_project_agent_executors.py +1087 -0
  50. package/graph-provider/fuli_graph/store_project_agent_task_reads.py +458 -0
  51. package/graph-provider/fuli_graph/store_project_agent_task_recruitment.py +699 -0
  52. package/graph-provider/fuli_graph/store_project_agent_task_staffing.py +409 -0
  53. package/graph-provider/fuli_graph/store_project_agent_tasks.py +1144 -0
  54. package/graph-provider/fuli_graph/store_project_agents.py +965 -0
  55. package/graph-provider/pyproject.toml +2 -1
  56. package/npm-shrinkwrap.json +2 -2
  57. package/package.json +2 -1
  58. package/skills/capturing-session-knowledge/SKILL.md +43 -2
  59. package/src/adaptive-runtime/executor-pool.js +127 -0
  60. package/src/adaptive-runtime/graph-services.js +166 -0
  61. package/src/adaptive-runtime/lease-client.js +335 -0
  62. package/src/adaptive-runtime/runtime-broker.js +318 -0
  63. package/src/adaptive-runtime/settings.js +111 -0
  64. package/src/adaptive-runtime/state.js +74 -0
  65. package/src/agent-tools/graph-definitions.js +396 -0
  66. package/src/agent-tools/graph-handlers.js +61 -0
  67. package/src/agent-tools/project-agent-definitions.js +307 -0
  68. package/src/backup/graph-backup.js +289 -0
  69. package/src/backup/identity-reconciliation.js +208 -0
  70. package/src/backup/runtime-adapters.js +269 -0
  71. package/src/cli/command-registry.js +7 -2
  72. package/src/cli/graph-data-command.js +112 -0
  73. package/src/cli/local-runtime-command.js +16 -2
  74. package/src/cli/setup-command.js +19 -3
  75. package/src/cli/update-command.js +4 -0
  76. package/src/cli/workspace-connection-command.js +333 -0
  77. package/src/cli.js +11 -0
  78. package/src/graphiti/collaboration-preference-projection.js +29 -1
  79. package/src/graphiti/collaboration-preference-workflow.js +121 -0
  80. package/src/graphiti/federated-application.js +74 -112
  81. package/src/graphiti/knowledge-provider-mapping.js +7 -1
  82. package/src/graphiti/project-agent-control-plane.js +263 -0
  83. package/src/graphiti/project-agent-mapping.js +1003 -0
  84. package/src/graphiti/project-agent-workflows.js +557 -0
  85. package/src/graphiti/provider-client.js +270 -1
  86. package/src/graphiti/runtime-config.js +6 -1
  87. package/src/graphiti/workspace-provider-client.js +403 -0
  88. package/src/http/api-router.js +63 -9
  89. package/src/http/graph-api-router.js +278 -0
  90. package/src/local-runtime/lifecycle.js +46 -10
  91. package/src/mcp/context-resources.js +15 -6
  92. package/src/mcp/create-mcp-server.js +51 -16
  93. package/src/mcp/instructions.js +7 -5
  94. package/src/mcp/runtime.js +17 -5
  95. package/src/mcp/session-id.js +38 -1
  96. package/src/mcp/tool-annotations.js +69 -0
  97. package/src/mcp-server.js +23 -6
  98. package/src/native-runtime/runtime.js +717 -0
  99. package/src/server.js +6 -2
  100. package/src/setup/agent-installation-status.js +7 -1
  101. package/src/setup/agents.js +3 -1
  102. package/src/setup/claude-code-config.js +3 -1
  103. package/src/setup/codex-bootstrap.js +11 -10
  104. package/src/setup/codex-config.js +7 -1
  105. package/src/setup/cursor-config.js +3 -1
  106. package/src/setup/graph-runtime.js +158 -13
  107. package/src/setup/neo4j-memory-profile.js +43 -0
  108. package/src/setup/options.js +38 -2
  109. package/src/setup/paths.js +14 -0
  110. package/src/setup/setup.js +37 -1
  111. package/src/system/resource-monitor.js +181 -16
  112. package/src/system/runtime-settings.js +10 -1
  113. package/src/system/system-service.js +27 -2
  114. package/dist/web/assets/AboutPage-CftRexSY.js +0 -1
  115. package/dist/web/assets/ConnectionsPage-D5J91x6d.js +0 -1
  116. package/dist/web/assets/KnowledgeEditDialog-wotVahvr.js +0 -1
  117. package/dist/web/assets/KnowledgeInspector-BzkW0mVs.js +0 -1
  118. package/dist/web/assets/KnowledgeOrganizerPage-BebUDiHt.js +0 -1
  119. package/dist/web/assets/KnowledgePage-OUT07aKH.js +0 -1
  120. package/dist/web/assets/KnowledgeWorkspace-1pHJ0MNZ.js +0 -4
  121. package/dist/web/assets/OverviewPage-CHE6XhdS.js +0 -1
  122. package/dist/web/assets/PersonalProfilePage-CXXiabUy.js +0 -1
  123. package/dist/web/assets/PersonalProjectsPage-d2wYGW8n.js +0 -1
  124. package/dist/web/assets/PublicProjectsPage-hxLShtnZ.js +0 -1
  125. package/dist/web/assets/ReviewPage-DUeyu7E8.js +0 -1
  126. package/dist/web/assets/SearchableSelect-C5RiB5F8.js +0 -1
  127. package/dist/web/assets/SettingsPage-BMuASSzQ.js +0 -1
  128. package/dist/web/assets/SettingsPage-CAfz4qiV.css +0 -1
  129. package/dist/web/assets/WritingTastePage-B9BCYIwQ.js +0 -1
  130. package/dist/web/assets/i18n-CWfd8Dtt.js +0 -5
  131. package/dist/web/assets/index-X2j29j8i.css +0 -1
  132. package/dist/web/assets/index-nP5p5OaY.js +0 -2
  133. package/dist/web/assets/vue-router-DN8x6iY1.js +0 -1
@@ -1,6 +1,10 @@
1
1
  import { dirname } from 'node:path';
2
2
 
3
3
  import { GraphitiProviderClient } from './provider-client.js';
4
+ import {
5
+ aggregatePublicCapabilities,
6
+ createWorkspaceProvider
7
+ } from './workspace-provider-client.js';
4
8
  import {
5
9
  canonicalProviderUrl,
6
10
  readGraphRuntimeConfig
@@ -24,17 +28,12 @@ import {
24
28
  createFuliSourceMarker,
25
29
  sourceConsoleUrl
26
30
  } from './source-marker.js';
27
- import {
28
- recallTaskKnowledge,
29
- TASK_KNOWLEDGE_RETRIEVAL_GUIDANCE
30
- } from './task-knowledge-recall.js';
31
31
  import { resolvePersonalProjectPath } from './project-path-context.js';
32
32
  import { mergeExternalKnowledgeProjection } from '../external-knowledge/graph-projection.js';
33
33
  import { TaskContextRegistry } from '../mcp/task-context-registry.js';
34
34
  import { attachExternalKnowledgeRuntime } from '../external-knowledge/runtime.js';
35
35
  import { resolveSetupPaths } from '../setup/paths.js';
36
36
  import {
37
- agentProjectResolution,
38
37
  beginTaskContext as beginTaskContextWorkflow,
39
38
  checkpointTaskKnowledge as checkpointTaskKnowledgeWorkflow,
40
39
  discoverCommonKnowledgeCandidates as discoverCommonKnowledgeCandidatesWorkflow,
@@ -56,6 +55,10 @@ import {
56
55
  providerEpisode
57
56
  } from './knowledge-provider-mapping.js';
58
57
  import { providerProjectProfile } from './project-profile-mapping.js';
58
+ import {
59
+ ProjectAgentControlPlaneApplication,
60
+ projectAgentControlPlaneHooks
61
+ } from './project-agent-control-plane.js';
59
62
  import {
60
63
  finishKnowledgeReview as finishKnowledgeReviewWorkflow,
61
64
  listKnowledgeReviewCandidates as listKnowledgeReviewCandidatesWorkflow,
@@ -73,10 +76,8 @@ import {
73
76
  relatedProjectGuidance
74
77
  } from './related-project-suggestions.js';
75
78
  import {
76
- agentCollaborationPreference,
77
- agentDeferredPreferenceConflict,
78
- deferredPreferenceConflicts
79
- } from './collaboration-preference-projection.js';
79
+ getCollaborationPreferences as getCollaborationPreferencesWorkflow
80
+ } from './collaboration-preference-workflow.js';
80
81
  import { buildUserTasteSkill } from './user-taste-skill.js';
81
82
  import { getWritingTasteProfile as getWritingTasteProfileWorkflow } from './writing-taste-profile-workflow.js';
82
83
  import {
@@ -129,7 +130,7 @@ function providerRequestTimeoutFromEnv(env) {
129
130
  return parsed;
130
131
  }
131
132
 
132
- export class FederatedGraphApplication {
133
+ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplication {
133
134
  constructor(config, {
134
135
  fetchImpl = globalThis.fetch,
135
136
  capturePolicyStore = new CapturePolicyStore(),
@@ -139,6 +140,7 @@ export class FederatedGraphApplication {
139
140
  taskContextRegistry = new TaskContextRegistry(),
140
141
  providerRequestTimeoutMs = undefined
141
142
  } = {}) {
143
+ super();
142
144
  this.graphiti = true;
143
145
  this.config = config;
144
146
  this.capturePolicyStore = capturePolicyStore;
@@ -153,20 +155,12 @@ export class FederatedGraphApplication {
153
155
  fetchImpl,
154
156
  requestTimeoutMs: providerRequestTimeoutMs
155
157
  });
156
- this.workspaces = new Map(
157
- config.workspaces.map((workspace) => {
158
- const url = canonicalProviderUrl(workspace.providerUrl);
159
- return [url, {
160
- ...workspace,
161
- client: new GraphitiProviderClient({
162
- baseUrl: url,
163
- accessToken: workspace.accessToken,
164
- fetchImpl,
165
- requestTimeoutMs: providerRequestTimeoutMs
166
- })
167
- }];
168
- })
169
- );
158
+ this.workspaces = new Map(config.workspaces.map((workspace) => {
159
+ const provider = createWorkspaceProvider(workspace, {
160
+ fetchImpl, requestTimeoutMs: providerRequestTimeoutMs
161
+ });
162
+ return [provider.providerUrl, provider];
163
+ }));
170
164
  }
171
165
 
172
166
  async beginTaskContext(input) {
@@ -207,10 +201,17 @@ export class FederatedGraphApplication {
207
201
  const result = await this.personal.commit({
208
202
  space_id: input.spaceId,
209
203
  personal_project_id: input.personalProjectId ?? null,
204
+ project_agent_id: input.projectAgentId ?? null,
210
205
  episode
211
206
  });
212
207
  return { route: 'personal', ...result };
213
208
  }
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
+ }
214
215
  if (episode.sensitivity !== 'normal') {
215
216
  throw new ApplicationError(
216
217
  ApplicationErrorCode.VALIDATION,
@@ -253,6 +254,7 @@ export class FederatedGraphApplication {
253
254
 
254
255
  async getCollaborationPreferences({
255
256
  personalProjectId = null,
257
+ projectAgentId = null,
256
258
  projectPath = null,
257
259
  taskPrompt = null,
258
260
  limit = 100,
@@ -263,80 +265,18 @@ export class FederatedGraphApplication {
263
265
  personalProjectId,
264
266
  projectPath
265
267
  });
266
- const resolvedProjectId = projectResolution.personalProjectId;
267
- const [result, queuedConflicts] = await Promise.all([
268
- this.personal.collaborationPreferences(
269
- this.config.personal.spaceId,
270
- resolvedProjectId,
271
- limit
272
- ),
273
- this.personal.listPreferenceConflicts(
274
- this.config.personal.spaceId,
275
- 'ai_pending',
276
- limit
277
- )
278
- ]);
279
- const deferredConflicts = deferredPreferenceConflicts(
280
- result,
281
- queuedConflicts
268
+ return getCollaborationPreferencesWorkflow(
269
+ this,
270
+ projectResolution,
271
+ {
272
+ projectAgentId,
273
+ taskPrompt,
274
+ limit,
275
+ agentInvocation,
276
+ agentToolName
277
+ },
278
+ (items, toolName) => this.#recordAgentViews(items, toolName)
282
279
  );
283
- const taskKnowledgeRecall = taskPrompt === null
284
- ? null
285
- : await recallTaskKnowledge(this, projectResolution, taskPrompt);
286
- if (agentInvocation) {
287
- const items = [
288
- ...(result.global_preferences ?? []),
289
- ...(result.project_preferences ?? [])
290
- ];
291
- await this.#recordAgentViews(items.map(({ id, item_kind: itemKind }) => ({
292
- item_id: id,
293
- item_kind: itemKind
294
- })), agentToolName);
295
- }
296
- const applicationGuidance = {
297
- apply: 'effective_preferences',
298
- global_scope: 'Apply personal-global preferences in every user task.',
299
- project_scope: resolvedProjectId
300
- ? `Also apply preferences scoped to ${resolvedProjectId} and confirmed ancestor preferences whose descendants or selected-projects mode explicitly reaches it.`
301
- : 'No exact personal project matched; do not apply project-scoped preferences.',
302
- inheritance: 'Project preference inheritance follows only PART_OF or USES_KNOWLEDGE_FROM for at most two hops. Preserve inherited_from_project_id, scope_path, and scope_distance. An exact item wins only after confirmation authority is compared; weight never expands scope or resolves a conflict.',
303
- related_projects: 'RELATED_TO preferences never auto-apply. Use structured related-project suggestions to ask before a one-time read-only expansion.',
304
- conflicts: 'Do not apply entries listed in conflicts until the user resolves them.',
305
- deferred_conflicts: 'If the current task would use a deferred_conflict, call resolve_deferred_preference_conflict before applying either side. Ignore unrelated deferred conflicts. The resolution must preserve the AI audit marker.',
306
- authority: 'Human or authoritative-source confirmed preferences outrank agent-confirmed preferences. Agent-confirmed preferences are usable but lower priority and remain explicitly marked.',
307
- pending: 'Pending preferences are available only through on-demand knowledge search; invalid and unrelated-project preferences are excluded. Automatic preference injection never counts as usage evidence.',
308
- knowledge_retrieval: TASK_KNOWLEDGE_RETRIEVAL_GUIDANCE
309
- };
310
- if (!agentInvocation) {
311
- return {
312
- ...result,
313
- deferred_conflicts: deferredConflicts,
314
- application_guidance: applicationGuidance,
315
- project_resolution: agentProjectResolution(projectResolution),
316
- ...(taskKnowledgeRecall ? { task_knowledge_recall: taskKnowledgeRecall } : {})
317
- };
318
- }
319
- return {
320
- effective_preferences: (result.effective_preferences ?? [])
321
- .map(agentCollaborationPreference),
322
- deferred_conflicts: deferredConflicts.map(agentDeferredPreferenceConflict),
323
- application_guidance: applicationGuidance,
324
- ...(taskKnowledgeRecall ? { task_knowledge_recall: taskKnowledgeRecall } : {}),
325
- context: {
326
- personal_space_id: result.personal_space_id,
327
- personal_project_id: result.personal_project_id,
328
- global_preference_count: (result.global_preferences ?? []).length,
329
- project_preference_count: (result.project_preferences ?? []).length,
330
- inherited_project_preference_count: (result.project_preferences ?? [])
331
- .filter(({ inherited_from_project_id: projectId }) => Boolean(projectId))
332
- .length,
333
- conflict_count: (result.conflicts ?? []).length,
334
- ai_deferred_conflict_count: deferredConflicts.length,
335
- overridden_global_count: (result.overridden_global_ids ?? []).length,
336
- source_truncated: result.truncated === true,
337
- project_resolution: agentProjectResolution(projectResolution)
338
- }
339
- };
340
280
  }
341
281
 
342
282
  async getUserTasteSkill({
@@ -419,6 +359,7 @@ export class FederatedGraphApplication {
419
359
  query,
420
360
  projectIds = [],
421
361
  personalProjectId = null,
362
+ projectAgentId = null,
422
363
  contextPersonalProjectIds = [],
423
364
  personalProjectScope = 'bounded',
424
365
  limit = 12,
@@ -433,6 +374,11 @@ export class FederatedGraphApplication {
433
374
  if (!['bounded', 'all_local_confirmed'].includes(personalProjectScope)) {
434
375
  throw new TypeError('Unknown personal project search scope');
435
376
  }
377
+ if (projectAgentId && (!personalProjectId || personalProjectScope !== 'bounded')) {
378
+ throw new TypeError(
379
+ 'Project Agent search requires one bounded active personal project'
380
+ );
381
+ }
436
382
  const subscriptions = projectIds.length
437
383
  ? await this.personal.listSubscriptions(personalSpaceId)
438
384
  : [];
@@ -451,21 +397,25 @@ export class FederatedGraphApplication {
451
397
  )
452
398
  : personalContextProjectIds(personalProjectId, contextPersonalProjectIds);
453
399
  const personalSearches = personalProjectSearchBatches(selectedPersonalProjectIds)
454
- .map((personalProjectIds, index) => this.personal.search({
400
+ .map((personalProjectIds, index) => {
401
+ const activePersonalProjectId = (
402
+ personalProjectScope === 'bounded' &&
403
+ personalProjectId &&
404
+ personalProjectIds.includes(personalProjectId)
405
+ ) ? personalProjectId : null;
406
+ return this.personal.search({
455
407
  space_ids: [personalSpaceId],
456
408
  query,
457
409
  limit,
458
410
  include_historical: includeHistorical,
459
411
  include_exploratory: includePending,
460
412
  personal_project_ids: personalProjectIds,
461
- active_personal_project_id: (
462
- personalProjectScope === 'bounded' &&
463
- personalProjectId &&
464
- personalProjectIds.includes(personalProjectId)
465
- ) ? personalProjectId : null,
413
+ active_personal_project_id: activePersonalProjectId,
414
+ project_agent_id: activePersonalProjectId ? projectAgentId : null,
466
415
  inherit_project_knowledge: personalProjectScope === 'bounded',
467
416
  include_personal_global: index === 0
468
- }));
417
+ });
418
+ });
469
419
  const grouped = groupSubscriptions(selectedSubscriptions);
470
420
  const workspaceSearches = [...grouped.entries()].map(([providerUrl, items]) => {
471
421
  const projectIdsForProvider = items.map(({ project_id: projectId }) => projectId);
@@ -553,6 +503,7 @@ export class FederatedGraphApplication {
553
503
  entities,
554
504
  personalGlobalIncluded: true,
555
505
  personalProjectScope,
506
+ projectAgentId,
556
507
  searchedPersonalProjectIds: selectedPersonalProjectIds,
557
508
  requestedProjectIds,
558
509
  searchedProjectIds,
@@ -1159,10 +1110,17 @@ export class FederatedGraphApplication {
1159
1110
  try {
1160
1111
  return {
1161
1112
  providerUrl: workspace.providerUrl,
1113
+ protocol: workspace.protocol,
1114
+ capabilities: workspace.capabilities,
1162
1115
  ...(await workspace.client.health())
1163
1116
  };
1164
1117
  } catch {
1165
- return { providerUrl: workspace.providerUrl, status: 'unavailable' };
1118
+ return {
1119
+ providerUrl: workspace.providerUrl,
1120
+ protocol: workspace.protocol,
1121
+ capabilities: workspace.capabilities,
1122
+ status: 'unavailable'
1123
+ };
1166
1124
  }
1167
1125
  })
1168
1126
  ]);
@@ -1200,13 +1158,9 @@ export class FederatedGraphApplication {
1200
1158
  capturePolicy: this.getCapturePolicy(),
1201
1159
  agentAccessPolicy: this.getAgentAccessPolicy(),
1202
1160
  publicProvider: { configured, status: publicStatus },
1203
- capabilities: {
1204
- browsePublicProjects: connected,
1205
- publishProject: connected,
1206
- submitKnowledge: connected,
1207
- subscribeProject: connected,
1208
- reviewProposals: connected && spaces.projects.some(({ role }) => role === 'maintainer')
1209
- }
1161
+ capabilities: aggregatePublicCapabilities(
1162
+ this.workspaces, providers.workspaces, spaces.projects
1163
+ )
1210
1164
  };
1211
1165
  }
1212
1166
 
@@ -1233,6 +1187,14 @@ export class FederatedGraphApplication {
1233
1187
  }
1234
1188
  }
1235
1189
 
1190
+ [projectAgentControlPlaneHooks.assertActivePersonalSpace](personalSpaceId) {
1191
+ this.#assertActivePersonalSpace(personalSpaceId);
1192
+ }
1193
+
1194
+ async [projectAgentControlPlaneHooks.resolvePreferenceProject](input) {
1195
+ return this.#resolvePreferenceProject(input);
1196
+ }
1197
+
1236
1198
  #workspace(providerUrl) {
1237
1199
  const requested = providerUrl
1238
1200
  ? canonicalProviderUrl(providerUrl)
@@ -71,7 +71,8 @@ function assertReasoningSummaries(items, collectionName) {
71
71
  }
72
72
 
73
73
  export function assertPublicKnowledgeEligible(episode) {
74
- const blocked = [...episode.entities, ...episode.relationships].find((item) =>
74
+ const items = [...episode.entities, ...episode.relationships];
75
+ const blocked = items.find((item) =>
75
76
  item.profile_aspect ||
76
77
  item.confirmation_status !== 'confirmed' ||
77
78
  !item.confirmation_basis?.confirmed_by ||
@@ -83,6 +84,11 @@ export function assertPublicKnowledgeEligible(episode) {
83
84
  'Only knowledge with an auditable confirmation can enter public review'
84
85
  );
85
86
  }
87
+ if (items.some((item) => (item.origin_quadrant ?? 'known_known') !== 'known_known')) {
88
+ throw new TypeError(
89
+ 'Only knowledge originally captured as known-known can enter public review'
90
+ );
91
+ }
86
92
  }
87
93
 
88
94
  export function providerConfirmationBasis(basis) {
@@ -0,0 +1,263 @@
1
+ import { agentProjectResolution } from './agent-knowledge-workflows.js';
2
+ import {
3
+ authorizeExecutor as authorizeExecutorWorkflow,
4
+ cleanupProjectAgentTestRoles as cleanupProjectAgentTestRolesWorkflow,
5
+ coordinateProjectAgentTask as coordinateProjectAgentTaskWorkflow,
6
+ createProjectAgentAssignment as createProjectAgentAssignmentWorkflow,
7
+ decideProjectAgentRecruitment as decideProjectAgentRecruitmentWorkflow,
8
+ deleteExecutor as deleteExecutorWorkflow,
9
+ deleteExecutorRoutingRule as deleteExecutorRoutingRuleWorkflow,
10
+ deleteProjectAgent as deleteProjectAgentWorkflow,
11
+ endProjectAgentAssignment as endProjectAgentAssignmentWorkflow,
12
+ getExecutor as getExecutorWorkflow,
13
+ getExecutorRoutingRule as getExecutorRoutingRuleWorkflow,
14
+ getProjectAgent as getProjectAgentWorkflow,
15
+ getProjectAgentContext as getProjectAgentContextWorkflow,
16
+ getProjectAgentRecruitmentPolicy as getProjectAgentRecruitmentPolicyWorkflow,
17
+ ignoreProjectAgentRoutingLearning as ignoreProjectAgentRoutingLearningWorkflow,
18
+ listCurrentProjectAgents as listCurrentProjectAgentsWorkflow,
19
+ listExecutorRoutingRules as listExecutorRoutingRulesWorkflow,
20
+ listExecutors as listExecutorsWorkflow,
21
+ listProjectAgentAssignments as listProjectAgentAssignmentsWorkflow,
22
+ listProjectAgentRecruitments as listProjectAgentRecruitmentsWorkflow,
23
+ listProjectAgentRoutingLearning as listProjectAgentRoutingLearningWorkflow,
24
+ listProjectAgentTasks as listProjectAgentTasksWorkflow,
25
+ listProjectAgents as listProjectAgentsWorkflow,
26
+ preflightExecutor as preflightExecutorWorkflow,
27
+ recordProjectAgentExecutorActual as recordProjectAgentExecutorActualWorkflow,
28
+ recordProjectAgentTaskActivity as recordProjectAgentTaskActivityWorkflow,
29
+ recordProjectAgentTaskOutcome as recordProjectAgentTaskOutcomeWorkflow,
30
+ replaceProjectAgentAssignment as replaceProjectAgentAssignmentWorkflow,
31
+ reportExecutorHealth as reportExecutorHealthWorkflow,
32
+ resetProjectAgentRoutingLearning as resetProjectAgentRoutingLearningWorkflow,
33
+ submitProjectAgentTask as submitProjectAgentTaskWorkflow,
34
+ updateExecutorRoutingRule as updateExecutorRoutingRuleWorkflow,
35
+ updateProjectAgentRecruitmentPolicy as updateProjectAgentRecruitmentPolicyWorkflow,
36
+ upsertExecutor as upsertExecutorWorkflow,
37
+ upsertExecutorRoutingRule as upsertExecutorRoutingRuleWorkflow,
38
+ upsertProjectAgent as upsertProjectAgentWorkflow,
39
+ viewProjectAgentActivity as viewProjectAgentActivityWorkflow,
40
+ viewProjectAgentTask as viewProjectAgentTaskWorkflow
41
+ } from './project-agent-workflows.js';
42
+
43
+ export const projectAgentControlPlaneHooks = Object.freeze({
44
+ assertActivePersonalSpace: Symbol('assertActivePersonalSpace'),
45
+ resolvePreferenceProject: Symbol('resolvePreferenceProject')
46
+ });
47
+
48
+ export class ProjectAgentControlPlaneApplication {
49
+ async upsertProjectAgent(input) {
50
+ this.#assertSpace(input.personalSpaceId);
51
+ return upsertProjectAgentWorkflow(this, input);
52
+ }
53
+
54
+ async listProjectAgents(input) {
55
+ this.#assertSpace(input.personalSpaceId);
56
+ return listProjectAgentsWorkflow(this, input);
57
+ }
58
+
59
+ async listCurrentProjectAgents(input) {
60
+ const resolution = await this.#resolveProject(input.projectPath);
61
+ return listCurrentProjectAgentsWorkflow(
62
+ this,
63
+ agentProjectResolution(resolution),
64
+ input
65
+ );
66
+ }
67
+
68
+ async getProjectAgent(input) {
69
+ this.#assertSpace(input.personalSpaceId);
70
+ return getProjectAgentWorkflow(this, input);
71
+ }
72
+
73
+ async deleteProjectAgent(input) {
74
+ this.#assertSpace(input.personalSpaceId);
75
+ return deleteProjectAgentWorkflow(this, input);
76
+ }
77
+
78
+ async cleanupProjectAgentTestRoles(input) {
79
+ this.#assertSpace(input.personalSpaceId);
80
+ return cleanupProjectAgentTestRolesWorkflow(this, input);
81
+ }
82
+
83
+ async createProjectAgentAssignment(input) {
84
+ this.#assertSpace(input.personalSpaceId);
85
+ return createProjectAgentAssignmentWorkflow(this, input);
86
+ }
87
+
88
+ async listProjectAgentAssignments(input) {
89
+ this.#assertSpace(input.personalSpaceId);
90
+ return listProjectAgentAssignmentsWorkflow(this, input);
91
+ }
92
+
93
+ async endProjectAgentAssignment(input) {
94
+ this.#assertSpace(input.personalSpaceId);
95
+ return endProjectAgentAssignmentWorkflow(this, input);
96
+ }
97
+
98
+ async replaceProjectAgentAssignment(input) {
99
+ this.#assertSpace(input.personalSpaceId);
100
+ return replaceProjectAgentAssignmentWorkflow(this, input);
101
+ }
102
+
103
+ async submitProjectAgentTask(input) {
104
+ this.#assertSpace(input.personalSpaceId);
105
+ return submitProjectAgentTaskWorkflow(this, input);
106
+ }
107
+
108
+ async coordinateProjectAgentTask(input) {
109
+ const resolution = await this.#resolveProject(input.projectPath);
110
+ return coordinateProjectAgentTaskWorkflow(
111
+ this,
112
+ agentProjectResolution(resolution),
113
+ input
114
+ );
115
+ }
116
+
117
+ async listProjectAgentTasks(input) {
118
+ this.#assertSpace(input.personalSpaceId);
119
+ return listProjectAgentTasksWorkflow(this, input);
120
+ }
121
+
122
+ async viewProjectAgentTask(input) {
123
+ this.#assertSpace(input.personalSpaceId);
124
+ return viewProjectAgentTaskWorkflow(this, input);
125
+ }
126
+
127
+ async recordProjectAgentTaskActivity(input) {
128
+ this.#assertSpace(input.personalSpaceId);
129
+ return recordProjectAgentTaskActivityWorkflow(this, input);
130
+ }
131
+
132
+ async viewProjectAgentActivity(input) {
133
+ this.#assertSpace(input.personalSpaceId);
134
+ return viewProjectAgentActivityWorkflow(this, input);
135
+ }
136
+
137
+ async getProjectAgentRecruitmentPolicy(input) {
138
+ this.#assertSpace(input.personalSpaceId);
139
+ return getProjectAgentRecruitmentPolicyWorkflow(this, input);
140
+ }
141
+
142
+ async updateProjectAgentRecruitmentPolicy(input) {
143
+ this.#assertSpace(input.personalSpaceId);
144
+ return updateProjectAgentRecruitmentPolicyWorkflow(this, input);
145
+ }
146
+
147
+ async listProjectAgentRecruitments(input) {
148
+ this.#assertSpace(input.personalSpaceId);
149
+ return listProjectAgentRecruitmentsWorkflow(this, input);
150
+ }
151
+
152
+ async decideProjectAgentRecruitment(input) {
153
+ this.#assertSpace(input.personalSpaceId);
154
+ return decideProjectAgentRecruitmentWorkflow(this, input);
155
+ }
156
+
157
+ async upsertExecutor(input) {
158
+ this.#assertSpace(input.personalSpaceId);
159
+ return upsertExecutorWorkflow(this, input);
160
+ }
161
+
162
+ async listExecutors(input) {
163
+ this.#assertSpace(input.personalSpaceId);
164
+ return listExecutorsWorkflow(this, input);
165
+ }
166
+
167
+ async getExecutor(input) {
168
+ this.#assertSpace(input.personalSpaceId);
169
+ return getExecutorWorkflow(this, input);
170
+ }
171
+
172
+ async deleteExecutor(input) {
173
+ this.#assertSpace(input.personalSpaceId);
174
+ return deleteExecutorWorkflow(this, input);
175
+ }
176
+
177
+ async preflightExecutor(input) {
178
+ this.#assertSpace(input.personalSpaceId);
179
+ return preflightExecutorWorkflow(this, input);
180
+ }
181
+
182
+ async authorizeExecutor(input) {
183
+ this.#assertSpace(input.personalSpaceId);
184
+ return authorizeExecutorWorkflow(this, input);
185
+ }
186
+
187
+ async reportExecutorHealth(input) {
188
+ this.#assertSpace(input.personalSpaceId);
189
+ return reportExecutorHealthWorkflow(this, input);
190
+ }
191
+
192
+ async recordProjectAgentExecutorActual(input) {
193
+ this.#assertSpace(input.personalSpaceId);
194
+ return recordProjectAgentExecutorActualWorkflow(this, input);
195
+ }
196
+
197
+ async upsertExecutorRoutingRule(input) {
198
+ this.#assertSpace(input.personalSpaceId);
199
+ return upsertExecutorRoutingRuleWorkflow(this, input);
200
+ }
201
+
202
+ async updateExecutorRoutingRule(input) {
203
+ this.#assertSpace(input.personalSpaceId);
204
+ return updateExecutorRoutingRuleWorkflow(this, input);
205
+ }
206
+
207
+ async listExecutorRoutingRules(input) {
208
+ this.#assertSpace(input.personalSpaceId);
209
+ return listExecutorRoutingRulesWorkflow(this, input);
210
+ }
211
+
212
+ async getExecutorRoutingRule(input) {
213
+ this.#assertSpace(input.personalSpaceId);
214
+ return getExecutorRoutingRuleWorkflow(this, input);
215
+ }
216
+
217
+ async deleteExecutorRoutingRule(input) {
218
+ this.#assertSpace(input.personalSpaceId);
219
+ return deleteExecutorRoutingRuleWorkflow(this, input);
220
+ }
221
+
222
+ async recordProjectAgentTaskOutcome(input) {
223
+ this.#assertSpace(input.personalSpaceId);
224
+ return recordProjectAgentTaskOutcomeWorkflow(this, input);
225
+ }
226
+
227
+ async listProjectAgentRoutingLearning(input) {
228
+ this.#assertSpace(input.personalSpaceId);
229
+ return listProjectAgentRoutingLearningWorkflow(this, input);
230
+ }
231
+
232
+ async ignoreProjectAgentRoutingLearning(input) {
233
+ this.#assertSpace(input.personalSpaceId);
234
+ return ignoreProjectAgentRoutingLearningWorkflow(this, input);
235
+ }
236
+
237
+ async resetProjectAgentRoutingLearning(input) {
238
+ this.#assertSpace(input.personalSpaceId);
239
+ return resetProjectAgentRoutingLearningWorkflow(this, input);
240
+ }
241
+
242
+ async getProjectAgentContext(input) {
243
+ const resolution = await this.#resolveProject(input.projectPath);
244
+ return getProjectAgentContextWorkflow(
245
+ this,
246
+ agentProjectResolution(resolution),
247
+ input
248
+ );
249
+ }
250
+
251
+ #assertSpace(personalSpaceId) {
252
+ this[projectAgentControlPlaneHooks.assertActivePersonalSpace](
253
+ personalSpaceId
254
+ );
255
+ }
256
+
257
+ #resolveProject(projectPath) {
258
+ return this[projectAgentControlPlaneHooks.resolvePreferenceProject]({
259
+ personalProjectId: null,
260
+ projectPath
261
+ });
262
+ }
263
+ }