fuli-context 0.3.0 → 0.5.0
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.en.md +336 -0
- package/README.md +220 -174
- package/dist/web/assets/ConnectionsPage-CCKWm-6p.js +1 -0
- package/dist/web/assets/KnowledgeInspector-BZkB2wJn.js +1 -0
- package/dist/web/assets/KnowledgeInspector-CrGYxEob.css +1 -0
- package/dist/web/assets/KnowledgeOrganizerPage-CZAF_OlN.css +1 -0
- package/dist/web/assets/KnowledgeOrganizerPage-DlvcLwlL.js +1 -0
- package/dist/web/assets/KnowledgePage-CNQXd15y.js +1 -0
- package/dist/web/assets/KnowledgeWorkspace-CXPE4GCD.js +4 -0
- package/dist/web/assets/OverviewPage-ul7g7HXh.js +1 -0
- package/dist/web/assets/PersonalProfilePage-CC40Pw2L.js +1 -0
- package/dist/web/assets/PersonalProfilePage-S8ZcG2LU.css +1 -0
- package/dist/web/assets/PersonalProjectsPage-CPIEcShD.js +1 -0
- package/dist/web/assets/PublicProjectsPage-C700sR7z.js +1 -0
- package/dist/web/assets/ReviewPage-7MDDUDgA.js +1 -0
- package/dist/web/assets/console-B_Ena2DS.js +5 -0
- package/dist/web/assets/identity-CjBwYSMX.js +1 -0
- package/dist/web/assets/{index-Devf7glZ.css → index-CpLDx3of.css} +1 -1
- package/dist/web/assets/index-DAzeFJSc.js +2 -0
- package/dist/web/assets/model-C-5RVIJ2.js +1 -0
- package/dist/web/assets/{paths-B790iniO.js → paths-BkULqmGI.js} +1 -1
- package/dist/web/assets/{vue-router-BYTAoWT3.js → vue-router-DnD3hUm7.js} +1 -1
- package/dist/web/index.html +5 -6
- package/graph-provider/fuli_graph/app.py +48 -0
- package/graph-provider/fuli_graph/common_knowledge.py +443 -0
- package/graph-provider/fuli_graph/common_knowledge_models.py +54 -0
- package/graph-provider/fuli_graph/graph_models.py +9 -0
- package/graph-provider/fuli_graph/graph_query.py +25 -0
- package/graph-provider/fuli_graph/knowledge_audit.py +211 -0
- package/graph-provider/fuli_graph/knowledge_feedback_models.py +69 -0
- package/graph-provider/fuli_graph/knowledge_management.py +37 -0
- package/graph-provider/fuli_graph/knowledge_search.py +24 -2
- package/graph-provider/fuli_graph/models.py +69 -0
- package/graph-provider/fuli_graph/search_projection.py +59 -0
- package/graph-provider/fuli_graph/store_knowledge.py +2 -0
- package/graph-provider/pyproject.toml +1 -1
- package/npm-shrinkwrap.json +97 -2
- package/package.json +3 -1
- package/skills/capturing-session-knowledge/SKILL.md +83 -13
- package/src/agent-tools/graph-definitions.js +181 -13
- package/src/agent-tools/graph-handlers.js +19 -0
- package/src/cli/command-registry.js +3 -58
- package/src/cli/local-runtime-command.js +16 -2
- package/src/cli/local-runtime-options.js +6 -2
- package/src/cli.js +2 -37
- package/src/graphiti/agent-knowledge-workflows.js +543 -0
- package/src/graphiti/federated-application.js +85 -104
- package/src/graphiti/knowledge-provider-mapping.js +91 -0
- package/src/graphiti/provider-client.js +15 -0
- package/src/graphiti/source-uri.js +29 -0
- package/src/http/request-policy.js +37 -2
- package/src/local-runtime/lifecycle.js +11 -1
- package/src/mcp/common-knowledge-preview-tokens.js +67 -0
- package/src/mcp/create-mcp-server.js +43 -7
- package/src/mcp/instructions.js +6 -7
- package/src/mcp/lifecycle-audit.js +27 -0
- package/src/mcp/task-context-registry.js +93 -0
- package/src/mcp/tool-annotations.js +16 -1
- package/src/mcp/tool-result.js +24 -0
- package/src/runtime-options.js +7 -8
- package/src/server/lan-access.js +52 -0
- package/src/server.js +67 -8
- package/src/setup/agent-installation-status.js +14 -2
- package/src/setup/agents.js +12 -1
- package/src/setup/claude-code-config.js +194 -0
- package/src/setup/config-backup.js +20 -5
- package/src/setup/graph-runtime.js +78 -9
- package/dist/web/assets/ConnectionsPage-CY6H_mJJ.js +0 -1
- package/dist/web/assets/KnowledgeInspector-BSpz5Sfm.js +0 -1
- package/dist/web/assets/KnowledgeInspector-CHbB_0rC.css +0 -1
- package/dist/web/assets/KnowledgeOrganizerPage-BlEvhPrv.css +0 -1
- package/dist/web/assets/KnowledgeOrganizerPage-CvjGPlUc.js +0 -1
- package/dist/web/assets/KnowledgePage-Khuo3cNs.js +0 -1
- package/dist/web/assets/KnowledgeWorkspace-DVZusvem.js +0 -4
- package/dist/web/assets/OverviewPage-DC4C4Fhn.js +0 -1
- package/dist/web/assets/PersonalProfilePage-CSV9Mtgz.js +0 -1
- package/dist/web/assets/PersonalProfilePage-CVJ3TcRi.css +0 -1
- package/dist/web/assets/PersonalProjectsPage-A50EaseQ.js +0 -1
- package/dist/web/assets/PublicProjectsPage-BAdO_bae.js +0 -1
- package/dist/web/assets/ReviewPage-Dztk2jDG.js +0 -1
- package/dist/web/assets/console-tbvTUi6p.js +0 -1
- package/dist/web/assets/identity-B3s5CXhv.js +0 -1
- package/dist/web/assets/index-DwUDhQKc.js +0 -6
- package/dist/web/assets/model-DVT8sjy9.js +0 -1
- package/dist/web/assets/runtime-dom.esm-bundler-DttsK21F.js +0 -1
- package/src/cli/commands/candidates.js +0 -17
- package/src/cli/commands/ingestion.js +0 -32
- package/src/cli/commands/reads.js +0 -50
- package/src/cli/commands/spaces.js +0 -20
- package/src/cli/invocation.js +0 -47
- package/src/cli/migrate-command.js +0 -71
- package/src/cli/migration-destination.js +0 -117
- package/src/storage/import-json.js +0 -70
- package/src/storage/legacy-record-validation.js +0 -152
- package/src/storage/legacy-snapshot-validation.js +0 -32
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
1
3
|
from graphiti_core.edges import EntityEdge
|
|
2
4
|
|
|
3
5
|
from .models import (
|
|
@@ -35,6 +37,9 @@ async def read_edge_epistemic_metadata(store, edge_ids: list[str]) -> dict[str,
|
|
|
35
37
|
'''
|
|
36
38
|
MATCH ()-[edge:RELATES_TO]->()
|
|
37
39
|
WHERE edge.uuid IN $edge_ids
|
|
40
|
+
OPTIONAL MATCH (episode:Episodic)
|
|
41
|
+
WHERE episode.uuid IN coalesce(edge.episodes, [])
|
|
42
|
+
WITH edge, collect(DISTINCT episode) AS episodes
|
|
38
43
|
RETURN edge.uuid AS id,
|
|
39
44
|
coalesce(edge.fuli_origin_quadrant, 'known_known') AS origin_quadrant,
|
|
40
45
|
coalesce(edge.fuli_current_quadrant, 'known_known') AS current_quadrant,
|
|
@@ -68,6 +73,19 @@ async def read_edge_epistemic_metadata(store, edge_ids: list[str]) -> dict[str,
|
|
|
68
73
|
,coalesce(edge.fuli_distinct_task_count, 0)
|
|
69
74
|
AS distinct_task_count
|
|
70
75
|
,edge.fuli_last_used_at AS last_used_at
|
|
76
|
+
,coalesce(edge.fuli_negative_evidence_count, 0)
|
|
77
|
+
AS negative_evidence_count
|
|
78
|
+
,coalesce(edge.fuli_requires_attention, false)
|
|
79
|
+
AS requires_attention
|
|
80
|
+
,edge.fuli_last_feedback_kind AS last_feedback_kind
|
|
81
|
+
,edge.fuli_last_feedback_at AS last_feedback_at
|
|
82
|
+
,[episode IN episodes
|
|
83
|
+
WHERE episode.fuli_source_uri IS NOT NULL |
|
|
84
|
+
{
|
|
85
|
+
uri: episode.fuli_source_uri,
|
|
86
|
+
reference_time: episode.valid_at,
|
|
87
|
+
created_at: episode.created_at
|
|
88
|
+
}] AS source_references
|
|
71
89
|
''',
|
|
72
90
|
edge_ids=edge_ids,
|
|
73
91
|
routing_='r',
|
|
@@ -140,12 +158,53 @@ def fact_result(
|
|
|
140
158
|
qualified_use_count=int(metadata.get('qualified_use_count') or 0),
|
|
141
159
|
distinct_task_count=int(metadata.get('distinct_task_count') or 0),
|
|
142
160
|
last_used_at=_native_datetime(metadata.get('last_used_at')),
|
|
161
|
+
negative_evidence_count=int(
|
|
162
|
+
metadata.get('negative_evidence_count') or 0
|
|
163
|
+
),
|
|
164
|
+
requires_attention=metadata.get('requires_attention') is True,
|
|
165
|
+
last_feedback_kind=metadata.get('last_feedback_kind'),
|
|
166
|
+
last_feedback_at=_native_datetime(metadata.get('last_feedback_at')),
|
|
143
167
|
scope_distance=int(metadata.get('scope_distance') or 0),
|
|
144
168
|
inherited_from_project_id=metadata.get('inherited_from_project_id'),
|
|
145
169
|
scope_path=metadata.get('scope_path') or [],
|
|
170
|
+
source_uris=source_uris_from_references(
|
|
171
|
+
metadata.get('source_references')
|
|
172
|
+
),
|
|
146
173
|
)
|
|
147
174
|
|
|
148
175
|
|
|
176
|
+
def source_uris_from_references(references, limit: int = 20) -> list[str]:
|
|
177
|
+
ranked = sorted(
|
|
178
|
+
(
|
|
179
|
+
(reference, index)
|
|
180
|
+
for index, reference in enumerate(references or [])
|
|
181
|
+
if isinstance(reference, dict) and reference.get('uri')
|
|
182
|
+
),
|
|
183
|
+
key=lambda item: (
|
|
184
|
+
_source_reference_timestamp(item[0]),
|
|
185
|
+
-item[1],
|
|
186
|
+
),
|
|
187
|
+
reverse=True,
|
|
188
|
+
)
|
|
189
|
+
result = []
|
|
190
|
+
for reference, _ in ranked:
|
|
191
|
+
uri = reference['uri']
|
|
192
|
+
if uri in result:
|
|
193
|
+
continue
|
|
194
|
+
result.append(uri)
|
|
195
|
+
if len(result) == limit:
|
|
196
|
+
break
|
|
197
|
+
return result
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _source_reference_timestamp(reference: dict) -> float:
|
|
201
|
+
for field in ('reference_time', 'created_at'):
|
|
202
|
+
value = _native_datetime(reference.get(field))
|
|
203
|
+
if isinstance(value, datetime):
|
|
204
|
+
return value.timestamp()
|
|
205
|
+
return 0.0
|
|
206
|
+
|
|
207
|
+
|
|
149
208
|
def _confirmation_basis(value) -> ConfirmationBasis | None:
|
|
150
209
|
data = json_object(value)
|
|
151
210
|
if not data:
|
|
@@ -268,6 +268,7 @@ class StoreKnowledge:
|
|
|
268
268
|
entity_edges: $relationship_ids,
|
|
269
269
|
fuli_session_id: $session_id,
|
|
270
270
|
fuli_source_kind: $source_kind,
|
|
271
|
+
fuli_source_uri: $source_uri,
|
|
271
272
|
fuli_source_application: $source_application,
|
|
272
273
|
fuli_source_turn_id: $source_turn_id,
|
|
273
274
|
fuli_source_excerpt: $source_excerpt,
|
|
@@ -391,6 +392,7 @@ class StoreKnowledge:
|
|
|
391
392
|
relationship_ids=relationship_ids,
|
|
392
393
|
session_id=episode.session_id,
|
|
393
394
|
source_kind=episode.source_kind,
|
|
395
|
+
source_uri=episode.source_uri,
|
|
394
396
|
source_application=episode.source_application,
|
|
395
397
|
source_turn_id=episode.source_turn_id,
|
|
396
398
|
source_excerpt=episode.source_excerpt,
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fuli-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "fuli-context",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.5.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@hono/node-server": "2.0.12",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"vite": "^8.1.5",
|
|
35
35
|
"vitest": "^4.1.10",
|
|
36
36
|
"vue": "^3.5.40",
|
|
37
|
+
"vue-i18n": "^11.4.8",
|
|
37
38
|
"vue-router": "^5.2.0",
|
|
38
39
|
"vue-tsc": "^3.3.8"
|
|
39
40
|
},
|
|
@@ -427,6 +428,71 @@
|
|
|
427
428
|
"hono": "^4"
|
|
428
429
|
}
|
|
429
430
|
},
|
|
431
|
+
"node_modules/@intlify/core-base": {
|
|
432
|
+
"version": "11.4.8",
|
|
433
|
+
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.4.8.tgz",
|
|
434
|
+
"integrity": "sha512-A+Q7SKm5oEcy1E/cghqd7n/St4XjTqLhiiyDuieNcMrJcrHlkY5n0jp7Q9dD3txvVHzvsmBVV5M9wD5/s1zfzw==",
|
|
435
|
+
"dev": true,
|
|
436
|
+
"license": "MIT",
|
|
437
|
+
"dependencies": {
|
|
438
|
+
"@intlify/devtools-types": "11.4.8",
|
|
439
|
+
"@intlify/message-compiler": "11.4.8",
|
|
440
|
+
"@intlify/shared": "11.4.8"
|
|
441
|
+
},
|
|
442
|
+
"engines": {
|
|
443
|
+
"node": ">= 22"
|
|
444
|
+
},
|
|
445
|
+
"funding": {
|
|
446
|
+
"url": "https://github.com/sponsors/kazupon"
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
"node_modules/@intlify/devtools-types": {
|
|
450
|
+
"version": "11.4.8",
|
|
451
|
+
"resolved": "https://registry.npmjs.org/@intlify/devtools-types/-/devtools-types-11.4.8.tgz",
|
|
452
|
+
"integrity": "sha512-MGpID+rlfzGUbNcnC20bm5NMSBHPrvx0atLTfv9dftn3kjXw1hGKDcIcwrO99tSrZEc2i+hczRL7ks8qXsHPkQ==",
|
|
453
|
+
"dev": true,
|
|
454
|
+
"license": "MIT",
|
|
455
|
+
"dependencies": {
|
|
456
|
+
"@intlify/core-base": "11.4.8",
|
|
457
|
+
"@intlify/shared": "11.4.8"
|
|
458
|
+
},
|
|
459
|
+
"engines": {
|
|
460
|
+
"node": ">= 22"
|
|
461
|
+
},
|
|
462
|
+
"funding": {
|
|
463
|
+
"url": "https://github.com/sponsors/kazupon"
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
"node_modules/@intlify/message-compiler": {
|
|
467
|
+
"version": "11.4.8",
|
|
468
|
+
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.4.8.tgz",
|
|
469
|
+
"integrity": "sha512-vbzk17dYwduYiv52EK61+FDCyhfVg1uPUtPmiD/d45W99uJIcXywrweOBcHv7n9/iEqmXiMGT52bgJbZDQqK3w==",
|
|
470
|
+
"dev": true,
|
|
471
|
+
"license": "MIT",
|
|
472
|
+
"dependencies": {
|
|
473
|
+
"@intlify/shared": "11.4.8",
|
|
474
|
+
"source-map-js": "^1.0.2"
|
|
475
|
+
},
|
|
476
|
+
"engines": {
|
|
477
|
+
"node": ">= 22"
|
|
478
|
+
},
|
|
479
|
+
"funding": {
|
|
480
|
+
"url": "https://github.com/sponsors/kazupon"
|
|
481
|
+
}
|
|
482
|
+
},
|
|
483
|
+
"node_modules/@intlify/shared": {
|
|
484
|
+
"version": "11.4.8",
|
|
485
|
+
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.4.8.tgz",
|
|
486
|
+
"integrity": "sha512-XbRgrv+XEuvDr7UCY55oibVrh+o4u+A0VB6nSL0F5Z8LcZxE/8j573LYG6bCrOigIcHdGpSNI7Rh5UpC5/B/eg==",
|
|
487
|
+
"dev": true,
|
|
488
|
+
"license": "MIT",
|
|
489
|
+
"engines": {
|
|
490
|
+
"node": ">= 22"
|
|
491
|
+
},
|
|
492
|
+
"funding": {
|
|
493
|
+
"url": "https://github.com/sponsors/kazupon"
|
|
494
|
+
}
|
|
495
|
+
},
|
|
430
496
|
"node_modules/@isaacs/cliui": {
|
|
431
497
|
"version": "8.0.2",
|
|
432
498
|
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
|
@@ -5731,6 +5797,35 @@
|
|
|
5731
5797
|
"dev": true,
|
|
5732
5798
|
"license": "MIT"
|
|
5733
5799
|
},
|
|
5800
|
+
"node_modules/vue-i18n": {
|
|
5801
|
+
"version": "11.4.8",
|
|
5802
|
+
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.4.8.tgz",
|
|
5803
|
+
"integrity": "sha512-0ULeHP6Z9CGvAm67S77ZEp41cfGXIREGL8qfhos2BMgcQQewtQcDKuojt6jjasAD/S8GwfTp2ySPmDSpwvrCMQ==",
|
|
5804
|
+
"dev": true,
|
|
5805
|
+
"license": "MIT",
|
|
5806
|
+
"dependencies": {
|
|
5807
|
+
"@intlify/core-base": "11.4.8",
|
|
5808
|
+
"@intlify/devtools-types": "11.4.8",
|
|
5809
|
+
"@intlify/shared": "11.4.8",
|
|
5810
|
+
"@vue/devtools-api": "^6.5.0"
|
|
5811
|
+
},
|
|
5812
|
+
"engines": {
|
|
5813
|
+
"node": ">= 22"
|
|
5814
|
+
},
|
|
5815
|
+
"funding": {
|
|
5816
|
+
"url": "https://github.com/sponsors/kazupon"
|
|
5817
|
+
},
|
|
5818
|
+
"peerDependencies": {
|
|
5819
|
+
"vue": "^3.0.0"
|
|
5820
|
+
}
|
|
5821
|
+
},
|
|
5822
|
+
"node_modules/vue-i18n/node_modules/@vue/devtools-api": {
|
|
5823
|
+
"version": "6.6.4",
|
|
5824
|
+
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
|
|
5825
|
+
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
|
|
5826
|
+
"dev": true,
|
|
5827
|
+
"license": "MIT"
|
|
5828
|
+
},
|
|
5734
5829
|
"node_modules/vue-router": {
|
|
5735
5830
|
"version": "5.2.0",
|
|
5736
5831
|
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.2.0.tgz",
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fuli-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Local-first context graph for AI agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
|
+
"README.en.md",
|
|
7
8
|
"npm-shrinkwrap.json",
|
|
8
9
|
"src/",
|
|
9
10
|
"dist/web/",
|
|
@@ -86,6 +87,7 @@
|
|
|
86
87
|
"vite": "^8.1.5",
|
|
87
88
|
"vitest": "^4.1.10",
|
|
88
89
|
"vue": "^3.5.40",
|
|
90
|
+
"vue-i18n": "^11.4.8",
|
|
89
91
|
"vue-router": "^5.2.0",
|
|
90
92
|
"vue-tsc": "^3.3.8"
|
|
91
93
|
},
|
|
@@ -7,12 +7,19 @@ description: Use when Fuli tools are available and a task may depend on remember
|
|
|
7
7
|
|
|
8
8
|
Accumulate reusable knowledge without interrupting the user's normal work. Keep an internal session buffer and flush focused batches at a natural task boundary or before the session ends.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Establish Task Context
|
|
11
11
|
|
|
12
|
-
At the start of every user task,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
At the start of every user task, first use the lifecycle context supplied by the host when one
|
|
13
|
+
exists. A Claude Code `UserPromptSubmit` hook calls `begin_task_context`, which already loads
|
|
14
|
+
collaboration preferences and resolves the exact local personal project from the current working
|
|
15
|
+
directory. Apply that returned context and retain its opaque task token for the final checkpoint;
|
|
16
|
+
do not redundantly call `get_collaboration_preferences`.
|
|
17
|
+
|
|
18
|
+
When the host has not supplied lifecycle context, call exactly
|
|
19
|
+
`get_collaboration_preferences` before any other tool or answer. Pass `projectPath` as the current
|
|
20
|
+
working directory. This is the prompt-only fallback for Agents without an equivalent lifecycle
|
|
21
|
+
hook. Fuli uses the path only for this local MCP call, never stores or returns it, and resolves the
|
|
22
|
+
exact local personal project itself. Do not infer or guess `personalProjectId` in the Agent.
|
|
16
23
|
|
|
17
24
|
Apply only `effective_preferences`. Personal-global preferences apply in every user task;
|
|
18
25
|
project-scoped preferences layer on only for the exact selected project. Do not apply items
|
|
@@ -30,7 +37,13 @@ Mentioning a preference only in the final answer is not compliance.
|
|
|
30
37
|
|
|
31
38
|
## Retrieve Context
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
For facts about the current local project, call `search_current_project_knowledge` with the
|
|
41
|
+
current working directory. It resolves the exact active project without requiring the Agent to
|
|
42
|
+
copy an ID, searches that child project first, and then includes only inheritable knowledge from
|
|
43
|
+
authorized parents or shared-source projects. Use `search_knowledge_graph` for personal-global
|
|
44
|
+
context, explicitly named extra projects, subscribed public projects, or advanced scoped queries.
|
|
45
|
+
|
|
46
|
+
Search when prior durable context can materially improve the task.
|
|
34
47
|
Before saying that a stable fact is unknown or asking the user to provide it again, search
|
|
35
48
|
Fuli if it may have been learned earlier. Strong triggers include URLs, deployment routes,
|
|
36
49
|
requirements, terminology, architecture, prior decisions, runbooks, rationale, and remembered
|
|
@@ -75,11 +88,13 @@ IDs; never search every personal project, every subscription, or the whole graph
|
|
|
75
88
|
Use the current repository, the user's wording, and `list_knowledge_spaces` to resolve scope.
|
|
76
89
|
Ask if the active project remains ambiguous.
|
|
77
90
|
|
|
78
|
-
The active project may also retrieve only knowledge explicitly marked inheritable from
|
|
79
|
-
reached through outgoing `PART_OF` or `USES_KNOWLEDGE_FROM` relations.
|
|
80
|
-
project-
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
The active child project may also retrieve only knowledge explicitly marked inheritable from
|
|
92
|
+
projects reached through its outgoing `PART_OF` or `USES_KNOWLEDGE_FROM` relations. This means
|
|
93
|
+
project-specific PRDs, configuration IDs, and debugging notes remain in the child, while a parent
|
|
94
|
+
may own shared run, validation, and test runbooks. Search the child first, then authorized parents.
|
|
95
|
+
Never inherit project-scoped personal preferences, never traverse `RELATED_TO`, stop after two
|
|
96
|
+
hops, and retain the returned scope path. Exact active-project knowledge with the same stable key
|
|
97
|
+
overrides an inherited item.
|
|
83
98
|
|
|
84
99
|
After a retrieved personal item materially affects the final answer or a completed action, call
|
|
85
100
|
`record_knowledge_usage` once for that task and item with `cited` or `applied`. Do not record
|
|
@@ -96,6 +111,27 @@ do not calculate, override, or claim the promotion themselves.
|
|
|
96
111
|
|
|
97
112
|
For “why was this code written?” questions, use stored evidence relationships and a separately configured Git MCP together. Never invent a commit, PRD link, or missing history. For “what errors happened today?” questions, obtain current data from a monitoring/log MCP; use Fuli only for runbooks, architecture, prior causes, and other durable context.
|
|
98
113
|
|
|
114
|
+
## Preserve Online Sources For Knowledge Refresh
|
|
115
|
+
|
|
116
|
+
When the user provides an online project or document link and the current Agent has a connector
|
|
117
|
+
or tool that can read it:
|
|
118
|
+
|
|
119
|
+
1. Read the current source with the Agent's available capability. Fuli does not implement or
|
|
120
|
+
pretend to provide source-specific reading.
|
|
121
|
+
2. Distill only durable knowledge, then pass the exact stable original HTTP(S) link as
|
|
122
|
+
`sourceUri` to `capture_session_knowledge`. Do not substitute a temporary download URL,
|
|
123
|
+
fabricate a link, or put credentials in the URI.
|
|
124
|
+
3. Route confidential or internal sources to personal knowledge with `private` or `restricted`
|
|
125
|
+
sensitivity. The runtime may retain the source URI; never copy a real internal URI into Git
|
|
126
|
+
project files, fixtures, examples, logs, or public project evidence.
|
|
127
|
+
4. When the user later asks to refresh the knowledge, search the relevant scope, use the returned
|
|
128
|
+
`source_uris` from supporting facts or entities, re-read the source with the current Agent,
|
|
129
|
+
and revise or supersede the corresponding Fuli knowledge while preserving history.
|
|
130
|
+
|
|
131
|
+
This workflow refreshes knowledge stored in Fuli. It does not imply or require writing back to
|
|
132
|
+
the original online document. If the current Agent cannot read the source, report that limitation
|
|
133
|
+
and never invent source-derived knowledge.
|
|
134
|
+
|
|
99
135
|
Every `search_knowledge_graph` response provides two terminal-safe Markdown choices:
|
|
100
136
|
`sourceMarker` for returned items that support the answer, and `noMatchSourceMarker`
|
|
101
137
|
for a search with no supporting result. A tool-labelled match that is irrelevant to
|
|
@@ -111,6 +147,10 @@ omit, or wrap markers in HTML. A capture or write result is not a read citation.
|
|
|
111
147
|
|
|
112
148
|
## Decide What Persists
|
|
113
149
|
|
|
150
|
+
Evaluate every completed task for reusable value, but do not force every collaboration to become
|
|
151
|
+
knowledge. `retain_nothing` is the correct result for temporary output, already-known material,
|
|
152
|
+
unsupported inference, or a task with no durable value.
|
|
153
|
+
|
|
114
154
|
Capture confirmed, stable information:
|
|
115
155
|
|
|
116
156
|
- Personal: the user's enduring preferences, boundaries, habits, and working methods. Project-specific personal rules must explicitly link to that project instead of becoming global defaults.
|
|
@@ -118,6 +158,17 @@ Capture confirmed, stable information:
|
|
|
118
158
|
|
|
119
159
|
Do not capture credentials, tokens, cookies, private keys, raw transcripts, temporary logs, command output, speculative conclusions, or disposable implementation details. Treat a correction as a replacement, not an additional conflicting fact.
|
|
120
160
|
|
|
161
|
+
For a confirmed project decision, prefer `record_decision_trace` over a flat note. Preserve the
|
|
162
|
+
selected option, materially considered rejected options, the human/source-confirmed rationale,
|
|
163
|
+
and any validation evidence. The rationale must explain the tradeoff rather than merely repeat
|
|
164
|
+
the selected option.
|
|
165
|
+
|
|
166
|
+
When retained knowledge is later rejected, contradicted, found outdated, or fails validation,
|
|
167
|
+
call `record_knowledge_feedback` with a concise reason and available evidence. Negative evidence
|
|
168
|
+
lowers ranking and marks the item for attention without deleting its history. Agent-only feedback
|
|
169
|
+
must not demote human/source-confirmed knowledge; authoritative contradiction may require review
|
|
170
|
+
or demotion under the Provider policy.
|
|
171
|
+
|
|
121
172
|
## Classify Knowledge State
|
|
122
173
|
|
|
123
174
|
Every entity and relationship needs an `originQuadrant`, `confirmationBasis`, and
|
|
@@ -195,6 +246,21 @@ global decision without hiding unrelated preferences.
|
|
|
195
246
|
- Never auto-approve a project Proposal.
|
|
196
247
|
- If ownership is genuinely ambiguous and changes who can see the knowledge, ask one concise question instead of guessing.
|
|
197
248
|
|
|
249
|
+
## Converge Shared Child Knowledge
|
|
250
|
+
|
|
251
|
+
When multiple direct children of one parent independently contain substantially equivalent
|
|
252
|
+
runbooks, conventions, or architecture facts, call `discover_common_knowledge_candidates`.
|
|
253
|
+
Discovery is read-only and must compare child-local knowledge with inheritance disabled so a
|
|
254
|
+
parent item cannot manufacture its own promotion candidate.
|
|
255
|
+
|
|
256
|
+
Never promote automatically. Preview a candidate with
|
|
257
|
+
`preview_common_knowledge_promotion`, show the proposed parent ownership, descendants inheritance
|
|
258
|
+
mode, selected duplicates, and scope rationale, then require a human confirmation reason. Apply
|
|
259
|
+
with `apply_common_knowledge_promotion` only using the one-time intent-bound preview token. The
|
|
260
|
+
Provider must atomically create or move the canonical parent item, mark descendants inheritance,
|
|
261
|
+
supersede child duplicates, and record the promotion audit. Child-specific exceptions stay in
|
|
262
|
+
their child projects.
|
|
263
|
+
|
|
198
264
|
## Resolve Or Create The Local Project
|
|
199
265
|
|
|
200
266
|
Before the first project-scoped capture in a repository:
|
|
@@ -214,7 +280,7 @@ Use `capture_session_knowledge` with a small, coherent batch:
|
|
|
214
280
|
1. List spaces when the target IDs are not already known.
|
|
215
281
|
2. Summarize the durable facts; do not submit the entire source document or conversation.
|
|
216
282
|
3. Create stable entity keys, typed entities, and explicit uppercase relationships. When relevant, model `GitCommit`, `CodeSymbol`, `PRDSection`, `Runbook`, and `Incident` entities and connect them with relationships such as `IMPLEMENTED_IN`, `DEFINED_BY`, `MOTIVATED_BY`, `APPLIES_TO`, and `INVESTIGATED_WITH`.
|
|
217
|
-
4. Include source kind, source application, a non-sensitive source description, reference time, session ID, and a retry-safe idempotency key. When available, include a stable source turn ID and only the smallest relevant excerpt needed to understand the evidence; never include a full transcript.
|
|
283
|
+
4. Include source kind, source application, a non-sensitive source description, reference time, session ID, and a retry-safe idempotency key. When an online source was actually read, also include its exact stable `sourceUri`. When available, include a stable source turn ID and only the smallest relevant excerpt needed to understand the evidence; never include a full transcript.
|
|
218
284
|
5. Use `supersedes` when replacing a known relationship and set confidence below `1` only when the source itself expresses uncertainty.
|
|
219
285
|
6. Flush silently at the boundary. Continue the user's task without narrating routine capture.
|
|
220
286
|
|
|
@@ -222,6 +288,10 @@ If `capture_session_knowledge` or automatic project creation returns `capture_di
|
|
|
222
288
|
user has disabled automatic capture. Do not retry, do not create a fallback record elsewhere,
|
|
223
289
|
and do not describe the skipped batch as stored. Existing knowledge may still be queried.
|
|
224
290
|
|
|
225
|
-
Before sending the final response, perform one checkpoint
|
|
291
|
+
Before sending the final response, perform one checkpoint. For a hook-managed task, call
|
|
292
|
+
`checkpoint_task_knowledge` exactly once with either `capture_candidates` and the bounded durable
|
|
293
|
+
batch, or `retain_nothing`. For a prompt-only Agent, either flush the durable batch directly or
|
|
294
|
+
determine that the turn produced no reusable knowledge. Do not finish a reusable project decision
|
|
295
|
+
with an unflushed batch.
|
|
226
296
|
|
|
227
297
|
Only notify the user when capture fails, conflicts with existing knowledge, or requires an ownership decision. If project knowledge was proposed successfully, do not interrupt merely to announce the pending review item.
|