fuli-context 0.7.6 → 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-sLV9WChi.js → AboutPage-BcZeFcHe.js} +1 -1
- package/dist/web/assets/{ConnectionsPage-BWn4ywGJ.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-CRQWOaos.js → KnowledgeInspector-BqPJH5Rr.js} +1 -1
- package/dist/web/assets/{KnowledgeOrganizerPage-Dfj3vIpU.js → KnowledgeOrganizerPage-CyvRflXM.js} +1 -1
- package/dist/web/assets/KnowledgePage-59eczTqe.js +1 -0
- package/dist/web/assets/{KnowledgeWorkspace-ChEB5Bwk.js → KnowledgeWorkspace-CfIjhOog.js} +1 -1
- package/dist/web/assets/{OverviewPage-Cd66M0RT.js → OverviewPage-Xyfm5xkZ.js} +1 -1
- package/dist/web/assets/{PersonalProfilePage-RCFHL0Wz.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-mstPEjHe.js → PublicProjectsPage-BEZ1YPs3.js} +1 -1
- package/dist/web/assets/{ReviewPage-6Y1SmfZy.js → ReviewPage-CQYGwFBH.js} +1 -1
- package/dist/web/assets/SearchableSelect-D27H0MoP.js +1 -0
- package/dist/web/assets/{SettingsPage--LdTMUm7.js → SettingsPage-BlEZ03Yi.js} +1 -1
- package/dist/web/assets/{WritingTastePage-CIpKswvs.js → WritingTastePage-DvRt_nmP.js} +1 -1
- package/dist/web/assets/catalog-DFvIaHVS.js +1 -0
- package/dist/web/assets/{console-BT1P2Db4.js → console-tOxOl8Vq.js} +1 -1
- package/dist/web/assets/conversation-launcher-settings-DuFSpPAo.js +1 -0
- package/dist/web/assets/{i18n-js6gfc7j.js → i18n-CgBHZthI.js} +3 -3
- package/dist/web/assets/{identity-CfDfanpa.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-DJkLAJsg.js → model-BtnVr7fX.js} +1 -1
- package/dist/web/assets/{useApi-CROJJdhE-BdSti7Y2.js → useApi-CROJJdhE-B6MHm_Av.js} +1 -1
- package/dist/web/assets/{vue-router-Kk67EaCP.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_executor_models.py +35 -7
- package/graph-provider/fuli_graph/project_agent_memory_models.py +79 -0
- package/graph-provider/fuli_graph/project_agent_memory_routes.py +46 -0
- package/graph-provider/fuli_graph/project_agent_models.py +9 -0
- package/graph-provider/fuli_graph/project_agent_recruitment_values.py +48 -0
- package/graph-provider/fuli_graph/project_agent_routes.py +21 -1
- package/graph-provider/fuli_graph/project_agent_task_models.py +217 -29
- package/graph-provider/fuli_graph/runtime.py +37 -1
- package/graph-provider/fuli_graph/store.py +6 -0
- package/graph-provider/fuli_graph/store_project_agent_context.py +65 -0
- package/graph-provider/fuli_graph/store_project_agent_executor_learning.py +175 -11
- package/graph-provider/fuli_graph/store_project_agent_executor_routing.py +33 -10
- package/graph-provider/fuli_graph/store_project_agent_executors.py +181 -14
- package/graph-provider/fuli_graph/store_project_agent_memory.py +174 -0
- package/graph-provider/fuli_graph/store_project_agent_task_activity.py +423 -0
- package/graph-provider/fuli_graph/store_project_agent_task_persistence.py +152 -0
- package/graph-provider/fuli_graph/store_project_agent_task_reads.py +187 -21
- package/graph-provider/fuli_graph/store_project_agent_task_recruitment.py +748 -162
- package/graph-provider/fuli_graph/store_project_agent_task_staffing.py +230 -18
- package/graph-provider/fuli_graph/store_project_agent_tasks.py +261 -468
- package/graph-provider/fuli_graph/store_project_agents.py +214 -46
- package/graph-provider/fuli_graph/store_task_contexts.py +217 -0
- package/graph-provider/fuli_graph/store_transactions.py +40 -0
- package/graph-provider/fuli_graph/task_context_models.py +50 -0
- package/graph-provider/fuli_graph/task_context_routes.py +31 -0
- package/graph-provider/fuli_graph/workflow_observation_models.py +1 -1
- package/graph-provider/pyproject.toml +1 -1
- package/npm-shrinkwrap.json +8 -8
- package/package.json +5 -2
- package/skills/capturing-session-knowledge/SKILL.md +18 -6
- package/src/adaptive-runtime/executor-pool.js +46 -5
- package/src/adaptive-runtime/graph-services.js +10 -3
- package/src/adaptive-runtime/lease-client.js +66 -14
- package/src/adaptive-runtime/runtime-broker.js +24 -9
- package/src/agent-tools/employee-definitions.js +43 -0
- package/src/agent-tools/graph-definitions.js +25 -6
- package/src/agent-tools/graph-handlers.js +11 -0
- package/src/agent-tools/project-agent-definitions.js +35 -4
- package/src/agent-tools/project-agent-memory-definitions.js +36 -0
- package/src/agent-tools.js +6 -2
- package/src/agents/codex/lifecycle-hook.js +107 -0
- package/src/agents/codex/lifecycle-hooks.js +231 -0
- package/src/agents/cursor/lifecycle-hook.js +133 -0
- package/src/agents/cursor/lifecycle-hooks.js +50 -0
- package/src/agents/lifecycle-message.js +19 -0
- package/src/app/agent-request-context.js +23 -0
- package/src/cli/command-registry.js +2 -0
- package/src/cli/employee-command.js +17 -0
- package/src/cli/remote-mcp-command.js +282 -0
- package/src/cli/setup-command.js +5 -0
- package/src/cli.js +10 -0
- package/src/employees/catalog/jefa.json +21 -0
- package/src/employees/install-package.js +77 -0
- package/src/employees/management-policy.js +88 -0
- package/src/employees/manifest.js +53 -0
- package/src/employees/package-registry.js +107 -0
- package/src/employees/project-selection.js +50 -0
- package/src/employees/recruitment.js +199 -0
- package/src/employees/service.js +83 -0
- package/src/employees/task-entry.js +39 -0
- package/src/graphiti/agent-knowledge-workflows.js +135 -25
- package/src/graphiti/federated-application.js +78 -35
- package/src/graphiti/project-agent-control-plane.js +20 -3
- package/src/graphiti/project-agent-mapping.js +155 -5
- package/src/graphiti/project-agent-memory.js +115 -0
- package/src/graphiti/project-agent-task-entry.js +126 -0
- package/src/graphiti/project-agent-workflows.js +30 -14
- package/src/graphiti/provider-client.js +66 -4
- package/src/http/api-router.js +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 +2 -0
- package/src/http/request-policy.js +6 -3
- package/src/http/static-handler.js +4 -3
- package/src/mcp/create-mcp-server.js +98 -37
- package/src/mcp/direct-call.js +38 -0
- package/src/mcp/instructions.js +8 -7
- package/src/mcp/provider-task-context-registry.js +74 -0
- package/src/mcp/remote-http-server.js +761 -0
- package/src/mcp/session-id.js +29 -3
- package/src/mcp/task-context-registry.js +88 -29
- package/src/mcp/tool-annotations.js +10 -2
- package/src/mcp/tool-result.js +8 -3
- package/src/mcp-server.js +20 -8
- package/src/native-runtime/runtime.js +58 -8
- package/src/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-CZ5ziPrD.js +0 -1
- package/dist/web/assets/KnowledgePage-BRYC9S5Y.js +0 -1
- package/dist/web/assets/PersonalProjectsPage-DEh8XWby.js +0 -1
- package/dist/web/assets/ProjectAgentsPage-Crh7PrXa.css +0 -1
- package/dist/web/assets/ProjectAgentsPage-DPnaH-TR.js +0 -11
- package/dist/web/assets/SearchableSelect-D3HM8YF8.js +0 -1
- package/dist/web/assets/conversation-launcher-settings-DrJEotdf.js +0 -1
- package/dist/web/assets/index-BnH5mcZx.css +0 -1
- package/dist/web/assets/index-GqJf1xqg.js +0 -2
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
CallToolRequestSchema,
|
|
4
|
+
ListToolsRequestSchema
|
|
5
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
3
6
|
|
|
4
7
|
import { callAgentTool, listAgentTools } from '../agent-tools.js';
|
|
8
|
+
import { ApplicationError, ApplicationErrorCode } from '../app/application-error.js';
|
|
5
9
|
import { FULI_VERSION } from '../package-metadata.js';
|
|
6
10
|
import { MCP_INSTRUCTIONS } from './instructions.js';
|
|
7
11
|
import { createProjectActionPreviewTokens } from './project-action-preview-tokens.js';
|
|
@@ -24,8 +28,13 @@ import {
|
|
|
24
28
|
} from './session-id.js';
|
|
25
29
|
|
|
26
30
|
const TOOL_RESULT_LIMIT_BYTES = Object.freeze({
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
list_employee_templates: 32 * 1024,
|
|
32
|
+
recruit_employee: 64 * 1024,
|
|
33
|
+
list_employee_tools: 64 * 1024,
|
|
34
|
+
call_employee_tool: 64 * 1024,
|
|
35
|
+
begin_task_context: 64 * 1024,
|
|
36
|
+
checkpoint_task_knowledge: 16 * 1024,
|
|
37
|
+
get_collaboration_preferences: 64 * 1024,
|
|
29
38
|
get_user_taste_skill: 32 * 1024,
|
|
30
39
|
search_knowledge_graph: 32 * 1024,
|
|
31
40
|
search_connected_knowledge: 64 * 1024,
|
|
@@ -38,6 +47,8 @@ const TOOL_RESULT_LIMIT_BYTES = Object.freeze({
|
|
|
38
47
|
get_project_agent: 32 * 1024,
|
|
39
48
|
list_project_agent_assignments: 32 * 1024,
|
|
40
49
|
get_project_agent_context: 64 * 1024,
|
|
50
|
+
get_project_agent_memory: 128 * 1024,
|
|
51
|
+
checkpoint_project_agent_memory: 64 * 1024,
|
|
41
52
|
coordinate_project_agent_task: 256 * 1024,
|
|
42
53
|
acquire_runtime_lease: 4 * 1024,
|
|
43
54
|
refresh_runtime_lease: 4 * 1024,
|
|
@@ -63,33 +74,46 @@ export function createMcpServer(
|
|
|
63
74
|
env = process.env,
|
|
64
75
|
clock = () => new Date(),
|
|
65
76
|
sourceApplication = nativeCodexThreadId(env) ? 'codex' : 'other',
|
|
66
|
-
withRuntimeLease = (_owner, operation) => operation()
|
|
77
|
+
withRuntimeLease = (_owner, operation) => operation(),
|
|
78
|
+
hostSessionId = null,
|
|
79
|
+
instructions = MCP_INSTRUCTIONS,
|
|
80
|
+
toolNames = null,
|
|
81
|
+
prepareToolInput = (_name, input) => input,
|
|
82
|
+
registerResources = true
|
|
67
83
|
} = {}
|
|
68
84
|
) {
|
|
69
85
|
const server = new McpServer(
|
|
70
86
|
{ name: 'fuli', version: FULI_VERSION },
|
|
71
|
-
{ instructions
|
|
87
|
+
{ instructions }
|
|
72
88
|
);
|
|
73
89
|
|
|
74
|
-
const nativeThreadId = nativeCodexThreadId(env);
|
|
75
90
|
const authoritativeSourceApplication = normalizeMcpSourceApplication(
|
|
76
91
|
sourceApplication
|
|
77
92
|
);
|
|
93
|
+
const nativeThreadId = authoritativeSourceApplication === 'codex' ? nativeCodexThreadId(env) : null;
|
|
78
94
|
const tools = createToolMap(
|
|
79
95
|
app,
|
|
80
96
|
createProjectActionPreviewTokens(),
|
|
81
97
|
nativeThreadId,
|
|
82
|
-
mcpHostSessionId(env),
|
|
98
|
+
hostSessionId ?? mcpHostSessionId(authoritativeSourceApplication === 'codex' ? env : {}),
|
|
83
99
|
clock,
|
|
84
100
|
authoritativeSourceApplication,
|
|
85
|
-
withRuntimeLease
|
|
101
|
+
withRuntimeLease,
|
|
102
|
+
toolNames,
|
|
103
|
+
prepareToolInput
|
|
86
104
|
);
|
|
87
105
|
for (const tool of tools.values()) registerTool(server, tool);
|
|
88
|
-
|
|
106
|
+
if (!tools.size) registerEmptyToolList(server);
|
|
107
|
+
if (registerResources) registerFuliContextResources(server, app, { withRuntimeLease });
|
|
89
108
|
registerCallHandler(server, tools);
|
|
90
109
|
return server;
|
|
91
110
|
}
|
|
92
111
|
|
|
112
|
+
function registerEmptyToolList(server) {
|
|
113
|
+
server.server.registerCapabilities({ tools: { listChanged: true } });
|
|
114
|
+
server.server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: [] }));
|
|
115
|
+
}
|
|
116
|
+
|
|
93
117
|
function createToolMap(
|
|
94
118
|
app,
|
|
95
119
|
projectActionPreviews,
|
|
@@ -97,29 +121,52 @@ function createToolMap(
|
|
|
97
121
|
hostSessionId,
|
|
98
122
|
clock,
|
|
99
123
|
sourceApplication,
|
|
100
|
-
withRuntimeLease
|
|
124
|
+
withRuntimeLease,
|
|
125
|
+
toolNames,
|
|
126
|
+
prepareToolInput
|
|
101
127
|
) {
|
|
102
128
|
const commonKnowledgePreviews = createCommonKnowledgePreviewTokens();
|
|
103
|
-
|
|
129
|
+
if (toolNames !== null && !Array.isArray(toolNames)) {
|
|
130
|
+
throw new TypeError('MCP toolNames must be an array or null');
|
|
131
|
+
}
|
|
132
|
+
const definitions = listAgentTools();
|
|
133
|
+
const allowedTools = toolNames === null ? null : new Set(toolNames);
|
|
134
|
+
if (allowedTools) {
|
|
135
|
+
const available = new Set(definitions.map(({ name }) => name));
|
|
136
|
+
const unknown = [...allowedTools].filter((name) => !available.has(name));
|
|
137
|
+
if (unknown.length) {
|
|
138
|
+
throw new TypeError(
|
|
139
|
+
`Unknown MCP tool name${unknown.length === 1 ? '' : 's'}: ${unknown.join(', ')}`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return new Map(definitions
|
|
144
|
+
.filter((definition) => !allowedTools || allowedTools.has(definition.name))
|
|
145
|
+
.map((definition) => [definition.name, {
|
|
104
146
|
definition,
|
|
105
147
|
schema: jsonSchemaToZod(definition.inputSchema),
|
|
106
|
-
invoke: (input) =>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
148
|
+
invoke: (input, requestContext = null) => {
|
|
149
|
+
requestContext?.signal?.throwIfAborted?.();
|
|
150
|
+
return withRuntimeLease(
|
|
151
|
+
`mcp-tool:${definition.name}`,
|
|
152
|
+
() => invokeAgentTool(
|
|
153
|
+
app,
|
|
112
154
|
definition.name,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
155
|
+
normalizeAgentSessionInput(
|
|
156
|
+
definition.name,
|
|
157
|
+
prepareToolInput(definition.name, input),
|
|
158
|
+
nativeThreadId,
|
|
159
|
+
hostSessionId,
|
|
160
|
+
clock,
|
|
161
|
+
sourceApplication
|
|
162
|
+
),
|
|
163
|
+
projectActionPreviews,
|
|
164
|
+
commonKnowledgePreviews,
|
|
165
|
+
requestContext
|
|
118
166
|
),
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
)
|
|
167
|
+
requestContext
|
|
168
|
+
);
|
|
169
|
+
}
|
|
123
170
|
}]));
|
|
124
171
|
}
|
|
125
172
|
|
|
@@ -131,22 +178,35 @@ function registerTool(server, tool) {
|
|
|
131
178
|
inputSchema: schema,
|
|
132
179
|
outputSchema: openObjectSchema(),
|
|
133
180
|
annotations: annotationsFor(definition.name)
|
|
134
|
-
}, (input) => invokeTool(tool, input));
|
|
181
|
+
}, (input, extra) => invokeTool(tool, input, extra));
|
|
135
182
|
}
|
|
136
183
|
|
|
137
184
|
function registerCallHandler(server, tools) {
|
|
138
|
-
server.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
185
|
+
server.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
139
186
|
const tool = tools.get(request.params.name);
|
|
140
|
-
if (!tool)
|
|
187
|
+
if (!tool) {
|
|
188
|
+
return errorToolResult(new ApplicationError(
|
|
189
|
+
ApplicationErrorCode.NOT_FOUND,
|
|
190
|
+
'Unknown Fuli tool'
|
|
191
|
+
));
|
|
192
|
+
}
|
|
141
193
|
const parsed = await tool.schema.safeParseAsync(request.params.arguments ?? {});
|
|
142
|
-
if (!parsed.success)
|
|
143
|
-
|
|
194
|
+
if (!parsed.success) {
|
|
195
|
+
return protocolErrorResult(
|
|
196
|
+
'Input validation error',
|
|
197
|
+
parsed.error.issues.map(({ path, message }) => ({
|
|
198
|
+
field: path.length ? path.join('.') : 'arguments',
|
|
199
|
+
message
|
|
200
|
+
}))
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
return invokeTool(tool, parsed.data, extra);
|
|
144
204
|
});
|
|
145
205
|
}
|
|
146
206
|
|
|
147
|
-
async function invokeTool(tool, input) {
|
|
207
|
+
async function invokeTool(tool, input, requestContext = null) {
|
|
148
208
|
try {
|
|
149
|
-
const value = await tool.invoke(input);
|
|
209
|
+
const value = await tool.invoke(input, requestContext);
|
|
150
210
|
auditLifecycleTool(tool.definition.name);
|
|
151
211
|
const limitBytes = TOOL_RESULT_LIMIT_BYTES[tool.definition.name];
|
|
152
212
|
if (tool.definition.name === 'begin_task_context') {
|
|
@@ -167,10 +227,11 @@ async function invokeAgentTool(
|
|
|
167
227
|
name,
|
|
168
228
|
input,
|
|
169
229
|
projectActionPreviews,
|
|
170
|
-
commonKnowledgePreviews
|
|
230
|
+
commonKnowledgePreviews,
|
|
231
|
+
requestContext = null
|
|
171
232
|
) {
|
|
172
233
|
if (name === 'preview_personal_project_action') {
|
|
173
|
-
const result = await callAgentTool(app, name, input);
|
|
234
|
+
const result = await callAgentTool(app, name, input, requestContext);
|
|
174
235
|
return {
|
|
175
236
|
...result,
|
|
176
237
|
previewToken: projectActionPreviews.issue(input)
|
|
@@ -180,7 +241,7 @@ async function invokeAgentTool(
|
|
|
180
241
|
projectActionPreviews.consume(input.previewToken, input);
|
|
181
242
|
}
|
|
182
243
|
if (name === 'preview_common_knowledge_promotion') {
|
|
183
|
-
const result = await callAgentTool(app, name, input);
|
|
244
|
+
const result = await callAgentTool(app, name, input, requestContext);
|
|
184
245
|
return {
|
|
185
246
|
...result,
|
|
186
247
|
previewToken: commonKnowledgePreviews.issue(input)
|
|
@@ -189,5 +250,5 @@ async function invokeAgentTool(
|
|
|
189
250
|
if (name === 'apply_common_knowledge_promotion') {
|
|
190
251
|
commonKnowledgePreviews.consume(input.previewToken, input);
|
|
191
252
|
}
|
|
192
|
-
return callAgentTool(app, name, input);
|
|
253
|
+
return callAgentTool(app, name, input, requestContext);
|
|
193
254
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { listAgentTools } from '../agent-tools.js';
|
|
2
|
+
import {
|
|
3
|
+
mcpHostSessionId,
|
|
4
|
+
nativeCodexThreadId,
|
|
5
|
+
normalizeAgentSessionInput,
|
|
6
|
+
normalizeMcpSourceApplication
|
|
7
|
+
} from './session-id.js';
|
|
8
|
+
import { jsonSchemaToZod } from './tool-schema.js';
|
|
9
|
+
|
|
10
|
+
export async function prepareDirectAgentToolCall({
|
|
11
|
+
toolName,
|
|
12
|
+
input,
|
|
13
|
+
sourceApplication = 'other',
|
|
14
|
+
env = process.env,
|
|
15
|
+
clock = () => new Date(),
|
|
16
|
+
hostSessionId = null
|
|
17
|
+
}) {
|
|
18
|
+
const definition = listAgentTools().find((item) => item.name === toolName);
|
|
19
|
+
if (!definition) throw new TypeError('Unknown tool');
|
|
20
|
+
const parsed = await jsonSchemaToZod(definition.inputSchema).safeParseAsync(input ?? {});
|
|
21
|
+
if (!parsed.success) throw new TypeError('Input validation error');
|
|
22
|
+
const source = normalizeMcpSourceApplication(sourceApplication);
|
|
23
|
+
const nativeThreadId = source === 'codex' ? nativeCodexThreadId(env) : null;
|
|
24
|
+
const authoritativeHostSessionId = hostSessionId ?? mcpHostSessionId(
|
|
25
|
+
source === 'codex' ? env : {}
|
|
26
|
+
);
|
|
27
|
+
return {
|
|
28
|
+
definition,
|
|
29
|
+
input: normalizeAgentSessionInput(
|
|
30
|
+
toolName,
|
|
31
|
+
parsed.data,
|
|
32
|
+
nativeThreadId,
|
|
33
|
+
authoritativeHostSessionId,
|
|
34
|
+
clock,
|
|
35
|
+
source
|
|
36
|
+
)
|
|
37
|
+
};
|
|
38
|
+
}
|
package/src/mcp/instructions.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export const MCP_INSTRUCTIONS = [
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
"Each user task: begin_task_context hook-provided task context; else before tools/answer call exactly get_collaboration_preferences(projectPath=cwd taskPrompt=current user request); never substitute project action. All effective_preferences: personal-global everywhere; matched project, authorized inheritable parent. get_user_taste_skill never replaces user Skill. Resolve deferred_conflict; never guess personalProjectId. Writes=actual payload; final text=not compliance.",
|
|
3
|
+
"Before asking stable project fact/method: task_knowledge_recall; miss: search_current_project_knowledge with focused action/artifact/target/ID queries, never only the full request. Active child first, then inheritable parent; no local_only/RELATED_TO.",
|
|
4
|
+
"Before saying unknown: search_knowledge_graph; extra projects=exact IDs. all_local_confirmed only after consent; rg only current repo/workspace. monitoring/Git MCP; search_connected_knowledge; agent_decide response-only.",
|
|
5
|
+
"record_decision_trace; errors: record_knowledge_feedback. Batch durable confirmed knowledge: capture_session_knowledge; no secrets. checkpoint_task_knowledge: capture_candidates/retain_nothing; record_knowledge_usage.",
|
|
6
|
+
"coordinate_project_agent_task=isolated context; Fuli never spawns. acquire_runtime_lease; run/report; release_runtime_lease in finally.",
|
|
7
|
+
"project_management_context: actionable work via authorized manager+board; keep chosen specialist; no excluded projects/extra model. Rename: exact current native session, host rename tool, manual-title protection; receipt after actual client result.",
|
|
8
|
+
"Task runs until all workerStatus terminal. executionSummary: one table row/worker: occupation emoji/label, actual executor/sourceApplication, work/status/session/link, source-labelled cumulative tokens. Missing=unknown; no invent/estimate/copy totals. Empty: omit. Configured/allowed/available not evidence.",
|
|
9
|
+
"Terminal-safe Markdown; no HTML. Match=candidate only. If supported: MUST begin sourceMarker.leadMarkdown; append sourceMarker.markdown; otherwise noMatchSourceMarker (empty). Keep unchanged."
|
|
9
10
|
].join(' ');
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
|
|
3
|
+
// The Provider is the sole source of truth. Hooks commonly use separate MCP
|
|
4
|
+
// processes; a process-local cache cannot prove that a task was checkpointed.
|
|
5
|
+
export class ProviderTaskContextRegistry {
|
|
6
|
+
constructor(provider, personalSpaceId) {
|
|
7
|
+
this.provider = provider;
|
|
8
|
+
this.personalSpaceId = personalSpaceId;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async begin(input) {
|
|
12
|
+
return taskRecord(await this.provider.beginTaskContext({
|
|
13
|
+
personal_space_id: this.personalSpaceId,
|
|
14
|
+
personal_project_id: input.personalProjectId ?? null,
|
|
15
|
+
project_agent_id: input.projectAgentId ?? null,
|
|
16
|
+
session_id: input.sessionId,
|
|
17
|
+
source_application: input.sourceApplication ?? 'other',
|
|
18
|
+
source_session_id: input.sourceSessionId ?? null,
|
|
19
|
+
token: `fuli-task-${randomUUID()}`,
|
|
20
|
+
turn_id: input.turnId ?? null,
|
|
21
|
+
memory_revision: input.memoryRevision ?? null
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async context(token, sourceApplication = 'other') {
|
|
26
|
+
return taskRecord(await this.provider.getTaskContext(token, {
|
|
27
|
+
personal_space_id: this.personalSpaceId, source_application: sourceApplication
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
prepare(token, checkpoint, sourceApplication = 'other', agentMemory = null) {
|
|
32
|
+
return this.#write(token, checkpoint, 'prepare', sourceApplication, agentMemory);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
checkpoint(token, checkpoint, sourceApplication = 'other') {
|
|
36
|
+
return this.#write(token, checkpoint, 'complete', sourceApplication);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
verify(sessionId, sourceApplication = 'other') {
|
|
40
|
+
return this.provider.verifyTaskCheckpoint({
|
|
41
|
+
personal_space_id: this.personalSpaceId, session_id: sessionId,
|
|
42
|
+
source_application: sourceApplication
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async #write(token, value, phase, sourceApplication, agentMemory = null) {
|
|
47
|
+
return taskRecord(await this.provider.checkpointTaskContext(token, {
|
|
48
|
+
personal_space_id: this.personalSpaceId, source_application: sourceApplication,
|
|
49
|
+
phase, disposition: value.disposition, reason: value.reason,
|
|
50
|
+
fingerprint: value.fingerprint, capture_status: value.captureStatus ?? null,
|
|
51
|
+
...(agentMemory ? { agent_memory: agentMemory } : {})
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function taskRecord(value) {
|
|
57
|
+
if (typeof value?.token !== 'string' || !value?.session_id) {
|
|
58
|
+
throw new TypeError('Provider did not return a durable task context');
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
token: value.token, sessionId: value.session_id,
|
|
62
|
+
personalProjectId: value.personal_project_id,
|
|
63
|
+
projectAgentId: value.project_agent_id,
|
|
64
|
+
sourceApplication: value.source_application,
|
|
65
|
+
sourceSessionId: value.source_session_id ?? null,
|
|
66
|
+
turnId: value.turn_id ?? null,
|
|
67
|
+
memoryRevision: value.memory_revision,
|
|
68
|
+
agentMemory: value.agent_memory ?? null,
|
|
69
|
+
previousCheckpointMissing: Boolean(value.previous_checkpoint_missing),
|
|
70
|
+
checkpoint: value.checkpoint ? {
|
|
71
|
+
...value.checkpoint, captureStatus: value.checkpoint.capture_status
|
|
72
|
+
} : null
|
|
73
|
+
};
|
|
74
|
+
}
|