hoi4-agent-tools 3.0.9 → 3.2.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/CHANGELOG.md +32 -1
- package/README.md +10 -2
- package/dist/bin/stdio.js +23 -12
- package/dist/hoi4_agent_tools/core/analysis-checkpoints.js +82 -0
- package/dist/hoi4_agent_tools/core/analysis-evidence.js +9 -0
- package/dist/hoi4_agent_tools/core/analysis-job-operations.js +38 -0
- package/dist/hoi4_agent_tools/core/artifact-resource.js +173 -0
- package/dist/hoi4_agent_tools/core/artifacts.js +84 -2
- package/dist/hoi4_agent_tools/core/condition-evaluator.js +16 -0
- package/dist/hoi4_agent_tools/core/dependency-pages.js +216 -0
- package/dist/hoi4_agent_tools/core/dependency-walk.js +266 -0
- package/dist/hoi4_agent_tools/core/domain-validation.js +188 -0
- package/dist/hoi4_agent_tools/core/engine.js +48 -5
- package/dist/hoi4_agent_tools/core/helper-expansion.js +186 -0
- package/dist/hoi4_agent_tools/core/impact-comparison.js +49 -0
- package/dist/hoi4_agent_tools/core/impact-graph.js +301 -0
- package/dist/hoi4_agent_tools/core/impact-semantic.js +256 -0
- package/dist/hoi4_agent_tools/core/index-segments.js +137 -0
- package/dist/hoi4_agent_tools/core/index.js +47 -4
- package/dist/hoi4_agent_tools/core/job-controls.js +109 -0
- package/dist/hoi4_agent_tools/core/job-executor.js +190 -0
- package/dist/hoi4_agent_tools/core/job-service.js +112 -0
- package/dist/hoi4_agent_tools/core/job-store.js +641 -0
- package/dist/hoi4_agent_tools/core/job-transactions.js +126 -0
- package/dist/hoi4_agent_tools/core/job-worker-host.js +202 -0
- package/dist/hoi4_agent_tools/core/job-worker.js +64 -0
- package/dist/hoi4_agent_tools/core/operation-context.js +31 -0
- package/dist/hoi4_agent_tools/core/operation-result.js +412 -0
- package/dist/hoi4_agent_tools/core/operation-tasks.js +387 -0
- package/dist/hoi4_agent_tools/core/persistent-analysis-cache.js +383 -0
- package/dist/hoi4_agent_tools/core/result.js +1 -0
- package/dist/hoi4_agent_tools/core/scanner.js +15 -75
- package/dist/hoi4_agent_tools/core/semantic-dependencies.js +233 -0
- package/dist/hoi4_agent_tools/core/shared-request-capacity.js +43 -11
- package/dist/hoi4_agent_tools/core/source/cache.js +107 -0
- package/dist/hoi4_agent_tools/core/source/parser.js +11 -1
- package/dist/hoi4_agent_tools/core/source-overlay.js +125 -0
- package/dist/hoi4_agent_tools/core/transaction-execution.js +134 -0
- package/dist/hoi4_agent_tools/core/transactions.js +80 -27
- package/dist/hoi4_agent_tools/decision/ai.js +104 -0
- package/dist/hoi4_agent_tools/decision/comparison.js +106 -0
- package/dist/hoi4_agent_tools/decision/cost.js +177 -0
- package/dist/hoi4_agent_tools/decision/evaluation.js +256 -0
- package/dist/hoi4_agent_tools/decision/lifecycle.js +114 -0
- package/dist/hoi4_agent_tools/decision/service.js +172 -0
- package/dist/hoi4_agent_tools/decision/source-inventory.js +182 -0
- package/dist/hoi4_agent_tools/event/graph.js +214 -290
- package/dist/hoi4_agent_tools/event/helper-expansion.js +33 -0
- package/dist/hoi4_agent_tools/event/job-operations.js +51 -0
- package/dist/hoi4_agent_tools/event/operations.js +179 -0
- package/dist/hoi4_agent_tools/event/service.js +67 -15
- package/dist/hoi4_agent_tools/event/source-analysis.js +5 -4
- package/dist/hoi4_agent_tools/focus/job-operations.js +77 -0
- package/dist/hoi4_agent_tools/focus/tool-operations.js +669 -0
- package/dist/hoi4_agent_tools/focus/tool-support.js +123 -0
- package/dist/hoi4_agent_tools/gui/job-operations.js +81 -0
- package/dist/hoi4_agent_tools/gui/tool-operations.js +270 -0
- package/dist/hoi4_agent_tools/impact/scenario-suites.js +74 -0
- package/dist/hoi4_agent_tools/impact/service.js +127 -0
- package/dist/hoi4_agent_tools/map/job-operations.js +76 -0
- package/dist/hoi4_agent_tools/map/tool-operations.js +493 -0
- package/dist/hoi4_agent_tools/mcp/prompts/probability.js +25 -0
- package/dist/hoi4_agent_tools/mcp/prompts/register-modern.js +29 -0
- package/dist/hoi4_agent_tools/mcp/resources/register-modern.js +34 -0
- package/dist/hoi4_agent_tools/mcp/resources/register.js +4 -150
- package/dist/hoi4_agent_tools/mcp/server/base-tools.js +3 -219
- package/dist/hoi4_agent_tools/mcp/server/create-modern-operations.js +188 -0
- package/dist/hoi4_agent_tools/mcp/server/create.js +18 -6
- package/dist/hoi4_agent_tools/mcp/server/instructions.js +2 -0
- package/dist/hoi4_agent_tools/mcp/server/job-task-store.js +67 -0
- package/dist/hoi4_agent_tools/mcp/server/legacy-task-tools.js +20 -0
- package/dist/hoi4_agent_tools/mcp/server/modern-tasks.js +168 -0
- package/dist/hoi4_agent_tools/mcp/server/progress.js +17 -15
- package/dist/hoi4_agent_tools/mcp/server/request-lifecycle.js +45 -0
- package/dist/hoi4_agent_tools/mcp/server/result.js +2 -412
- package/dist/hoi4_agent_tools/mcp/server/task-request-context.js +9 -0
- package/dist/hoi4_agent_tools/mcp/server/task-tool-catalog.js +16 -0
- package/dist/hoi4_agent_tools/mcp/server/task-tool-definition.js +1 -0
- package/dist/hoi4_agent_tools/mcp/server/transaction-execution.js +1 -123
- package/dist/hoi4_agent_tools/mcp/tools/analysis.js +65 -0
- package/dist/hoi4_agent_tools/mcp/tools/chaosx.js +38 -21
- package/dist/hoi4_agent_tools/mcp/tools/event.js +24 -315
- package/dist/hoi4_agent_tools/mcp/tools/focus.js +34 -1039
- package/dist/hoi4_agent_tools/mcp/tools/gui.js +19 -504
- package/dist/hoi4_agent_tools/mcp/tools/job.js +46 -0
- package/dist/hoi4_agent_tools/mcp/tools/map.js +21 -600
- package/dist/hoi4_agent_tools/mcp/tools/probability.js +39 -463
- package/dist/hoi4_agent_tools/mcp/tools/technology.js +40 -304
- package/dist/hoi4_agent_tools/mcp/transports/http.js +58 -1
- package/dist/hoi4_agent_tools/mcp/transports/modern-task-routing.js +109 -0
- package/dist/hoi4_agent_tools/mcp/transports/negotiated-stdio.js +121 -0
- package/dist/hoi4_agent_tools/probability/job-operations.js +58 -0
- package/dist/hoi4_agent_tools/probability/operations.js +183 -0
- package/dist/hoi4_agent_tools/probability/service.js +24 -3
- package/dist/hoi4_agent_tools/schemas/analysis.js +228 -0
- package/dist/hoi4_agent_tools/schemas/common.js +2 -0
- package/dist/hoi4_agent_tools/schemas/event.js +72 -1
- package/dist/hoi4_agent_tools/schemas/focus-requests.js +189 -0
- package/dist/hoi4_agent_tools/schemas/gui-requests.js +193 -0
- package/dist/hoi4_agent_tools/schemas/helper-expansion.js +58 -0
- package/dist/hoi4_agent_tools/schemas/map-requests.js +85 -0
- package/dist/hoi4_agent_tools/schemas/probability-requests.js +168 -0
- package/dist/hoi4_agent_tools/schemas/technology.js +90 -1
- package/dist/hoi4_agent_tools/schemas/transaction.js +1 -0
- package/dist/hoi4_agent_tools/technology/graph.js +83 -78
- package/dist/hoi4_agent_tools/technology/helper-expansion.js +33 -0
- package/dist/hoi4_agent_tools/technology/job-operations.js +60 -0
- package/dist/hoi4_agent_tools/technology/operations.js +125 -0
- package/dist/hoi4_agent_tools/technology/service.js +89 -15
- package/dist/hoi4_agent_tools/technology/source-analysis.js +2 -1
- package/dist/hoi4_agent_tools/version.js +1 -1
- package/docs/README.md +3 -0
- package/docs/analysis.md +100 -0
- package/docs/development.md +2 -0
- package/docs/events.md +7 -2
- package/docs/helper-expansion.md +78 -0
- package/docs/http.md +2 -0
- package/docs/jobs.md +86 -0
- package/docs/technology.md +6 -2
- package/package.json +15 -6
- package/schemas/configuration.schema.json +1 -1
- package/schemas/continuous-focus-palette.schema.json +1 -1
- package/schemas/custom-weighted-pool.schema.json +1 -1
- package/schemas/decision-inspect-input.schema.json +290 -0
- package/schemas/event-feature-manifest.schema.json +1 -1
- package/schemas/focus-plan.schema.json +1 -1
- package/schemas/focus-planning-sidecar.schema.json +1 -1
- package/schemas/gui-animation-source.schema.json +1 -1
- package/schemas/gui-helper.schema.json +1 -1
- package/schemas/gui-scenario.schema.json +1 -1
- package/schemas/helper-expansion-request.schema.json +44 -0
- package/schemas/helper-expansion-summary.schema.json +70 -0
- package/schemas/impact-inspect-input.schema.json +203 -0
- package/schemas/map-operation.schema.json +1 -1
- package/schemas/operation-result.schema.json +1 -1
- package/schemas/probability-analysis-result.schema.json +1 -1
- package/schemas/probability-compare-input.schema.json +1 -1
- package/schemas/probability-evaluate-input.schema.json +1 -1
- package/schemas/probability-inspect-input.schema.json +1 -1
- package/schemas/probability-render-input.schema.json +1 -1
- package/schemas/probability-scenario-set.schema.json +1 -1
- package/schemas/probability-sequence-input.schema.json +1 -1
- package/schemas/probability-simulate-input.schema.json +1 -1
- package/schemas/probability-sweep-input.schema.json +1 -1
- package/server.json +3 -3
|
@@ -333,24 +333,17 @@ async function resolveGuiRevision(engine, context, studio, cache, workspaceId, s
|
|
|
333
333
|
filesScanned: Object.keys(sourceHashes).sort(compareCodeUnits),
|
|
334
334
|
};
|
|
335
335
|
}
|
|
336
|
-
export function
|
|
336
|
+
export function createChaosxToolOperations(engine, context) {
|
|
337
337
|
const guiStudio = new ScriptedGuiStudio(engine);
|
|
338
338
|
const guiRevisionCache = new Map();
|
|
339
339
|
const guiCacheLifetime = new IdleCacheLifetime(() => {
|
|
340
340
|
guiStudio.clearCaches();
|
|
341
341
|
guiRevisionCache.clear();
|
|
342
342
|
});
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
description: 'Private ChaosX cache-coherency endpoint. Computes exact scripted-GUI source revisions without rendering PNG artifacts.',
|
|
346
|
-
inputSchema: chaosxVisualRevisionInput,
|
|
347
|
-
outputSchema: chaosxVisualRevisionOutput,
|
|
348
|
-
annotations: readOnly,
|
|
349
|
-
}, async (input, extra) => {
|
|
350
|
-
const workspaceId = await resolveServerWorkspaceId(engine, context, input.workspaceId, extra.signal);
|
|
343
|
+
const visualCall = async (input, progress) => {
|
|
344
|
+
const workspaceId = await resolveServerWorkspaceId(engine, context, input.workspaceId, progress.signal);
|
|
351
345
|
const releaseCaches = guiCacheLifetime.begin();
|
|
352
346
|
try {
|
|
353
|
-
const progress = progressReporter(extra);
|
|
354
347
|
await progress.report(0, 2, 'Checking ChaosX scripted-GUI sources');
|
|
355
348
|
const resolvedGuiRevisions = [];
|
|
356
349
|
for (const selector of input.guiWindows)
|
|
@@ -381,17 +374,10 @@ export function registerChaosxTools(server, engine, context) {
|
|
|
381
374
|
finally {
|
|
382
375
|
releaseCaches();
|
|
383
376
|
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
description: 'Private ChaosX Discord integration endpoint. Returns country flags and leader portraits to accompany a focus-tree raster; it is not intended for coding-agent workflows.',
|
|
388
|
-
inputSchema: chaosxCountryAssetsInput,
|
|
389
|
-
outputSchema: chaosxCountryAssetsOutput,
|
|
390
|
-
annotations: artifactProducing,
|
|
391
|
-
}, async (input, extra) => {
|
|
392
|
-
const workspaceId = await resolveServerWorkspaceId(engine, context, input.workspaceId, extra.signal);
|
|
377
|
+
};
|
|
378
|
+
const countryCall = async (input, progress) => {
|
|
379
|
+
const workspaceId = await resolveServerWorkspaceId(engine, context, input.workspaceId, progress.signal);
|
|
393
380
|
try {
|
|
394
|
-
const progress = progressReporter(extra);
|
|
395
381
|
await progress.report(0, 3, 'Resolving ChaosX country assets');
|
|
396
382
|
const discoveryWorkspace = engine.resolver.get(workspaceId, context.principal);
|
|
397
383
|
const snapshot = await engine.scan(workspaceId, { patterns: countryAssetDiscoveryPatterns(discoveryWorkspace) }, context.principal, progress.signal);
|
|
@@ -488,5 +474,36 @@ export function registerChaosxTools(server, engine, context) {
|
|
|
488
474
|
catch (error) {
|
|
489
475
|
return errorResult(error, workspaceId);
|
|
490
476
|
}
|
|
491
|
-
}
|
|
477
|
+
};
|
|
478
|
+
return {
|
|
479
|
+
visual: {
|
|
480
|
+
definition: {
|
|
481
|
+
name: 'chaosx.visual_revision',
|
|
482
|
+
title: 'Check ChaosX visual revisions',
|
|
483
|
+
description: 'Private ChaosX cache-coherency endpoint. Computes exact scripted-GUI source revisions without rendering PNG artifacts.',
|
|
484
|
+
inputSchema: chaosxVisualRevisionInput,
|
|
485
|
+
outputSchema: chaosxVisualRevisionOutput,
|
|
486
|
+
annotations: readOnly,
|
|
487
|
+
},
|
|
488
|
+
call: visualCall,
|
|
489
|
+
},
|
|
490
|
+
country: {
|
|
491
|
+
definition: {
|
|
492
|
+
name: 'chaosx.focus_country_assets',
|
|
493
|
+
title: 'Render ChaosX focus country assets',
|
|
494
|
+
description: 'Private ChaosX Discord integration endpoint. Returns country flags and leader portraits to accompany a focus-tree raster; it is not intended for coding-agent workflows.',
|
|
495
|
+
inputSchema: chaosxCountryAssetsInput,
|
|
496
|
+
outputSchema: chaosxCountryAssetsOutput,
|
|
497
|
+
annotations: artifactProducing,
|
|
498
|
+
},
|
|
499
|
+
call: countryCall,
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
export function registerChaosxTools(server, engine, context) {
|
|
504
|
+
const operations = createChaosxToolOperations(engine, context);
|
|
505
|
+
const { name: visualName, ...visualDefinition } = operations.visual.definition;
|
|
506
|
+
const { name: countryName, ...countryDefinition } = operations.country.definition;
|
|
507
|
+
server.registerTool(visualName, visualDefinition, (input, extra) => operations.visual.call(input, progressReporter(extra)));
|
|
508
|
+
server.registerTool(countryName, countryDefinition, (input, extra) => operations.country.call(input, progressReporter(extra)));
|
|
492
509
|
}
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
+
import { registerLegacyTaskTools } from '../server/legacy-task-tools.js';
|
|
1
2
|
import { z } from 'zod/v4';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { IdleCacheLifetime } from '../../core/idle-cache-lifetime.js';
|
|
5
|
-
import { emptyServiceResult } from '../../core/result.js';
|
|
6
|
-
import { EventChainViewer, eventDiagnostics, } from '../../event/service.js';
|
|
7
|
-
import { eventDirectionSchema, eventGraphReferenceSchema, eventImpactSubjectSchema, eventInspectModeSchema, eventProposedSourceSchema, eventRenderViewSchema, eventSelectorSchema, eventStateSubjectSchema, } from '../../schemas/event.js';
|
|
8
|
-
import { workspaceIdSchema } from '../../schemas/common.js';
|
|
3
|
+
import { helperExpansionRequestSchema, helperExpansionSummarySchema, } from '../../schemas/helper-expansion.js';
|
|
4
|
+
import { eventDirectionSchema, eventGraphReferenceSchema, eventImpactSubjectSchema, eventInspectModeSchema, eventProposedSourceSchema, eventRenderViewSchema, eventSelectorSchema, eventInspectRequestSchema, eventRenderRequestSchema, eventCompareRequestSchema, validateEventCompareRequest, validateEventInspectRequest, eventStateSubjectSchema, } from '../../schemas/event.js';
|
|
9
5
|
import { compactValidatedInputSchema } from '../server/context-schemas.js';
|
|
10
6
|
import { nonNegativeIntegerSchema, sha256Schema } from '../server/output-schemas.js';
|
|
11
|
-
import {
|
|
12
|
-
import { errorResult, setInlineFilesScanned, strictOperationResultSchema, toolResult, } from '../server/result.js';
|
|
13
|
-
import { resolveServerWorkspaceId } from '../server/base-tools.js';
|
|
7
|
+
import { strictOperationResultSchema } from '../server/result.js';
|
|
14
8
|
const nestedSelectorSchema = compactValidatedInputSchema(eventSelectorSchema, 'Event selector; see docs/events.md.');
|
|
15
9
|
const nestedStateSubjectSchema = compactValidatedInputSchema(eventStateSubjectSchema, 'State kind and name.');
|
|
16
10
|
const nestedImpactSubjectSchema = compactValidatedInputSchema(eventImpactSubjectSchema, 'Impact kind and name.');
|
|
@@ -18,73 +12,31 @@ const nestedGraphReferenceSchema = compactValidatedInputSchema(eventGraphReferen
|
|
|
18
12
|
const nestedProposedSourceSchema = compactValidatedInputSchema(eventProposedSourceSchema, 'In-memory source overlay; never written.');
|
|
19
13
|
const eventInspectInputSchema = z
|
|
20
14
|
.object({
|
|
21
|
-
|
|
22
|
-
mode: eventInspectModeSchema,
|
|
15
|
+
...eventInspectRequestSchema.shape,
|
|
23
16
|
selector: nestedSelectorSchema.optional(),
|
|
24
17
|
from: nestedSelectorSchema.optional(),
|
|
25
18
|
to: nestedSelectorSchema.optional(),
|
|
26
|
-
direction: eventDirectionSchema.optional(),
|
|
27
|
-
maxDepth: z.number().int().min(1).max(64).optional(),
|
|
28
|
-
maxNodes: z.number().int().min(1).max(5_000).optional(),
|
|
29
|
-
maxEdges: z.number().int().min(1).max(20_000).optional(),
|
|
30
|
-
expandHelpers: z.boolean().optional(),
|
|
31
19
|
stateSubject: nestedStateSubjectSchema.optional(),
|
|
32
20
|
impactSubject: nestedImpactSubjectSchema.optional(),
|
|
33
|
-
|
|
21
|
+
helperExpansion: compactValidatedInputSchema(helperExpansionRequestSchema, 'Bounded helper paths; opaque continuationUri resumes the same source and roots. See docs/events.md.').optional(),
|
|
34
22
|
})
|
|
35
23
|
.strict()
|
|
36
|
-
.superRefine(
|
|
37
|
-
if (value.mode === 'trace' && value.selector === undefined) {
|
|
38
|
-
context.addIssue({ code: 'custom', path: ['selector'], message: 'Trace requires selector' });
|
|
39
|
-
}
|
|
40
|
-
if (value.mode === 'explain_path' && (value.from === undefined || value.to === undefined)) {
|
|
41
|
-
context.addIssue({
|
|
42
|
-
code: 'custom',
|
|
43
|
-
path: value.from === undefined ? ['from'] : ['to'],
|
|
44
|
-
message: 'Path explanation requires from and to',
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
if (value.mode === 'impact' && value.impactSubject === undefined) {
|
|
48
|
-
context.addIssue({
|
|
49
|
-
code: 'custom',
|
|
50
|
-
path: ['impactSubject'],
|
|
51
|
-
message: 'Impact analysis requires impactSubject',
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
});
|
|
24
|
+
.superRefine(validateEventInspectRequest);
|
|
55
25
|
const eventRenderInputSchema = z
|
|
56
26
|
.object({
|
|
57
|
-
|
|
58
|
-
view: eventRenderViewSchema,
|
|
27
|
+
...eventRenderRequestSchema.shape,
|
|
59
28
|
selector: nestedSelectorSchema.optional(),
|
|
60
|
-
direction: eventDirectionSchema.optional(),
|
|
61
|
-
maxDepth: z.number().int().min(1).max(64).optional(),
|
|
62
|
-
maxNodes: z.number().int().min(1).max(240).optional(),
|
|
63
|
-
expandHelpers: z.boolean().optional(),
|
|
64
|
-
includeHtml: z.boolean().optional(),
|
|
65
|
-
refresh: z.boolean().optional(),
|
|
66
29
|
})
|
|
67
30
|
.strict();
|
|
68
31
|
const eventCompareInputSchema = z
|
|
69
32
|
.object({
|
|
70
|
-
|
|
33
|
+
...eventCompareRequestSchema.shape,
|
|
71
34
|
before: nestedGraphReferenceSchema.optional(),
|
|
72
35
|
after: nestedGraphReferenceSchema.optional(),
|
|
73
36
|
proposedSources: z.array(nestedProposedSourceSchema).min(1).max(64).optional(),
|
|
74
|
-
render: z.boolean().optional(),
|
|
75
|
-
maxRenderNodes: z.number().int().min(1).max(240).optional(),
|
|
76
|
-
refresh: z.boolean().optional(),
|
|
77
37
|
})
|
|
78
38
|
.strict()
|
|
79
|
-
.superRefine(
|
|
80
|
-
if (value.after !== undefined && value.proposedSources !== undefined) {
|
|
81
|
-
context.addIssue({
|
|
82
|
-
code: 'custom',
|
|
83
|
-
path: ['after'],
|
|
84
|
-
message: 'after and proposedSources are mutually exclusive',
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
});
|
|
39
|
+
.superRefine(validateEventCompareRequest);
|
|
88
40
|
const eventGraphCountsSchema = z
|
|
89
41
|
.object({
|
|
90
42
|
events: nonNegativeIntegerSchema,
|
|
@@ -128,6 +80,7 @@ const eventInspectOutputSchema = strictOperationResultSchema(z
|
|
|
128
80
|
revision: sha256Schema,
|
|
129
81
|
graphHash: sha256Schema,
|
|
130
82
|
counts: eventGraphCountsSchema,
|
|
83
|
+
helperExpansion: helperExpansionSummarySchema.optional(),
|
|
131
84
|
boundary: inspectBoundarySchema,
|
|
132
85
|
})
|
|
133
86
|
.strict());
|
|
@@ -206,276 +159,32 @@ const readOnlyEventTool = {
|
|
|
206
159
|
idempotentHint: true,
|
|
207
160
|
openWorldHint: false,
|
|
208
161
|
};
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
events: graph.statistics.eventCount,
|
|
213
|
-
options: graph.statistics.optionCount,
|
|
214
|
-
entries: graph.statistics.entryCount,
|
|
215
|
-
helpers: graph.statistics.helperCount,
|
|
216
|
-
unresolvedNodes: graph.statistics.unresolvedNodeCount,
|
|
217
|
-
terminals: graph.statistics.terminalCount,
|
|
218
|
-
edges: graph.statistics.edgeCount,
|
|
219
|
-
derivedEdges: graph.statistics.derivedEdgeCount,
|
|
220
|
-
stateAccesses: graph.statistics.stateAccessCount,
|
|
221
|
-
issues: graph.statistics.issueCount,
|
|
222
|
-
diagnostics: diagnostics.length,
|
|
223
|
-
blockingDiagnostics: diagnostics.filter(({ severity }) => severity === 'error' || severity === 'blocker').length,
|
|
224
|
-
skippedSources: graph.skippedSourceCount,
|
|
225
|
-
artifacts,
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
function graphValidation(graph) {
|
|
229
|
-
const counts = graphCounts(graph, 0);
|
|
230
|
-
const focused = graph.analysisMode === 'focused';
|
|
231
|
-
return {
|
|
232
|
-
passed: graph.complete && counts.blockingDiagnostics === 0,
|
|
233
|
-
checks: [
|
|
234
|
-
{
|
|
235
|
-
id: 'event-analysis',
|
|
236
|
-
passed: graph.complete && counts.blockingDiagnostics === 0,
|
|
237
|
-
message: focused
|
|
238
|
-
? 'Large workspace analysis deferred workspace-wide helper projections and lifecycle passes; direct evidence is linked'
|
|
239
|
-
: graph.complete
|
|
240
|
-
? `${counts.blockingDiagnostics} blocking event-chain diagnostics; full evidence is linked`
|
|
241
|
-
: `${graph.skippedSourceCount} event-analysis source(s) were skipped; full evidence is linked`,
|
|
242
|
-
},
|
|
243
|
-
],
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
function inspectRequest(input, context, signal) {
|
|
247
|
-
return {
|
|
248
|
-
workspaceId: input.workspaceId,
|
|
249
|
-
mode: input.mode,
|
|
250
|
-
...(input.selector === undefined
|
|
251
|
-
? {}
|
|
252
|
-
: { selector: input.selector }),
|
|
253
|
-
...(input.from === undefined
|
|
254
|
-
? {}
|
|
255
|
-
: { from: input.from }),
|
|
256
|
-
...(input.to === undefined ? {} : { to: input.to }),
|
|
257
|
-
...(input.direction === undefined ? {} : { direction: input.direction }),
|
|
258
|
-
...(input.maxDepth === undefined ? {} : { maxDepth: input.maxDepth }),
|
|
259
|
-
...(input.maxNodes === undefined ? {} : { maxNodes: input.maxNodes }),
|
|
260
|
-
...(input.maxEdges === undefined ? {} : { maxEdges: input.maxEdges }),
|
|
261
|
-
...(input.expandHelpers === undefined ? {} : { expandHelpers: input.expandHelpers }),
|
|
262
|
-
...(input.stateSubject === undefined ? {} : { stateSubject: input.stateSubject }),
|
|
263
|
-
...(input.impactSubject === undefined ? {} : { impactSubject: input.impactSubject }),
|
|
264
|
-
...(input.refresh === undefined ? {} : { refresh: input.refresh }),
|
|
265
|
-
...(context.principal === undefined ? {} : { principal: context.principal }),
|
|
266
|
-
signal,
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
function renderRequest(input, context, signal) {
|
|
270
|
-
return {
|
|
271
|
-
workspaceId: input.workspaceId,
|
|
272
|
-
view: input.view,
|
|
273
|
-
...(input.selector === undefined
|
|
274
|
-
? {}
|
|
275
|
-
: { selector: input.selector }),
|
|
276
|
-
...(input.direction === undefined ? {} : { direction: input.direction }),
|
|
277
|
-
...(input.maxDepth === undefined ? {} : { maxDepth: input.maxDepth }),
|
|
278
|
-
...(input.maxNodes === undefined ? {} : { maxNodes: input.maxNodes }),
|
|
279
|
-
...(input.expandHelpers === undefined ? {} : { expandHelpers: input.expandHelpers }),
|
|
280
|
-
...(input.includeHtml === undefined ? {} : { includeHtml: input.includeHtml }),
|
|
281
|
-
...(input.refresh === undefined ? {} : { refresh: input.refresh }),
|
|
282
|
-
...(context.principal === undefined ? {} : { principal: context.principal }),
|
|
283
|
-
signal,
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
function compareRequest(input, context, signal) {
|
|
287
|
-
return {
|
|
288
|
-
workspaceId: input.workspaceId,
|
|
289
|
-
...(input.before === undefined
|
|
290
|
-
? {}
|
|
291
|
-
: { before: input.before }),
|
|
292
|
-
...(input.after === undefined
|
|
293
|
-
? {}
|
|
294
|
-
: { after: input.after }),
|
|
295
|
-
...(input.proposedSources === undefined
|
|
296
|
-
? {}
|
|
297
|
-
: {
|
|
298
|
-
proposedSources: input.proposedSources,
|
|
299
|
-
}),
|
|
300
|
-
...(input.render === undefined ? {} : { render: input.render }),
|
|
301
|
-
...(input.maxRenderNodes === undefined ? {} : { maxRenderNodes: input.maxRenderNodes }),
|
|
302
|
-
...(input.refresh === undefined ? {} : { refresh: input.refresh }),
|
|
303
|
-
...(context.principal === undefined ? {} : { principal: context.principal }),
|
|
304
|
-
signal,
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
export function registerEventTools(server, engine, context) {
|
|
308
|
-
const viewer = new EventChainViewer(engine);
|
|
309
|
-
const cacheLifetime = new IdleCacheLifetime(() => viewer.clearCaches());
|
|
310
|
-
server.registerTool('hoi4.event_inspect', {
|
|
162
|
+
export const eventTaskTools = [
|
|
163
|
+
{
|
|
164
|
+
name: 'hoi4.event_inspect',
|
|
311
165
|
title: 'Inspect event chains',
|
|
312
166
|
description: 'Scan, find roots, trace, explain paths, inspect state flow, lint, or assess impact. Full source-linked reports are resources.',
|
|
313
167
|
inputSchema: eventInspectInputSchema,
|
|
314
168
|
outputSchema: eventInspectOutputSchema,
|
|
315
169
|
annotations: readOnlyEventTool,
|
|
316
|
-
},
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
try {
|
|
320
|
-
const progress = progressReporter(extra);
|
|
321
|
-
await progress.report(0, 3, 'Analyzing event chain');
|
|
322
|
-
const inspected = await viewer.inspect(inspectRequest({ ...input, workspaceId }, context, progress.signal));
|
|
323
|
-
await progress.report(2, 3, 'Linking complete event analysis');
|
|
324
|
-
const result = emptyServiceResult(workspaceId, {
|
|
325
|
-
mode: inspected.mode,
|
|
326
|
-
analysisMode: inspected.graph.analysisMode ?? 'full',
|
|
327
|
-
revision: inspected.graph.revision,
|
|
328
|
-
graphHash: inspected.graphHash,
|
|
329
|
-
counts: graphCounts(inspected.graph, inspected.artifacts.length),
|
|
330
|
-
boundary: {
|
|
331
|
-
direction: input.direction ?? 'both',
|
|
332
|
-
maxDepth: input.maxDepth ?? 8,
|
|
333
|
-
maxNodes: input.maxNodes ?? 500,
|
|
334
|
-
maxEdges: input.maxEdges ?? 2_000,
|
|
335
|
-
expandHelpers: input.expandHelpers ?? (input.mode === 'explain_path' ? true : false),
|
|
336
|
-
refresh: input.refresh ?? input.mode === 'scan',
|
|
337
|
-
},
|
|
338
|
-
});
|
|
339
|
-
result.code = inspected.graph.complete ? 'EVENT_INSPECTED' : 'EVENT_INSPECTED_PARTIAL';
|
|
340
|
-
setInlineFilesScanned(result, inspected.graph.filesScanned);
|
|
341
|
-
result.artifacts = inspected.artifacts.map(publicArtifactLink);
|
|
342
|
-
result.validation = graphValidation(inspected.graph);
|
|
343
|
-
await progress.report(3, 3, 'Event inspection complete');
|
|
344
|
-
return toolResult(result);
|
|
345
|
-
}
|
|
346
|
-
catch (error) {
|
|
347
|
-
return errorResult(error, workspaceId);
|
|
348
|
-
}
|
|
349
|
-
finally {
|
|
350
|
-
releaseCaches();
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
server.registerTool('hoi4.event_render', {
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: 'hoi4.event_render',
|
|
354
173
|
title: 'Render event chains',
|
|
355
174
|
description: 'Render deterministic JSON, SVG, PNG, and optional HTML for an event-chain view. Complete artifacts retain source links.',
|
|
356
175
|
inputSchema: eventRenderInputSchema,
|
|
357
176
|
outputSchema: eventRenderOutputSchema,
|
|
358
177
|
annotations: readOnlyEventTool,
|
|
359
|
-
},
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
try {
|
|
363
|
-
const progress = progressReporter(extra);
|
|
364
|
-
await progress.report(0, 3, 'Rendering event-chain view');
|
|
365
|
-
const rendered = await viewer.renderAndStore(renderRequest({ ...input, workspaceId }, context, progress.signal));
|
|
366
|
-
await progress.report(2, 3, 'Linking complete event renders');
|
|
367
|
-
const result = emptyServiceResult(workspaceId, {
|
|
368
|
-
view: rendered.render.view,
|
|
369
|
-
analysisMode: rendered.graph.analysisMode ?? 'full',
|
|
370
|
-
revision: rendered.graph.revision,
|
|
371
|
-
graphHash: rendered.graphHash,
|
|
372
|
-
layoutHash: rendered.render.layout.layoutHash,
|
|
373
|
-
hashes: rendered.render.hashes,
|
|
374
|
-
counts: {
|
|
375
|
-
...graphCounts(rendered.graph, rendered.artifacts.length),
|
|
376
|
-
selectedNodes: rendered.render.selectedNodeIds.length,
|
|
377
|
-
omittedNodes: rendered.render.omittedNodeCount,
|
|
378
|
-
branchRenders: rendered.branches.length,
|
|
379
|
-
},
|
|
380
|
-
boundary: {
|
|
381
|
-
direction: input.direction ?? 'both',
|
|
382
|
-
maxDepth: input.maxDepth ?? 4,
|
|
383
|
-
maxNodes: input.maxNodes ?? 120,
|
|
384
|
-
expandHelpers: input.expandHelpers ?? false,
|
|
385
|
-
includeHtml: input.includeHtml ?? false,
|
|
386
|
-
refresh: input.refresh ?? false,
|
|
387
|
-
},
|
|
388
|
-
});
|
|
389
|
-
result.code = rendered.graph.complete ? 'EVENT_RENDERED' : 'EVENT_RENDERED_PARTIAL';
|
|
390
|
-
setInlineFilesScanned(result, rendered.graph.filesScanned);
|
|
391
|
-
result.artifacts = rendered.artifacts.map(publicArtifactLink);
|
|
392
|
-
result.validation = graphValidation(rendered.graph);
|
|
393
|
-
await progress.report(3, 3, 'Event render complete');
|
|
394
|
-
return toolResult(result);
|
|
395
|
-
}
|
|
396
|
-
catch (error) {
|
|
397
|
-
return errorResult(error, workspaceId);
|
|
398
|
-
}
|
|
399
|
-
finally {
|
|
400
|
-
releaseCaches();
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
server.registerTool('hoi4.event_compare', {
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: 'hoi4.event_compare',
|
|
404
181
|
title: 'Compare event chains',
|
|
405
182
|
description: 'Compare cached, artifact-backed, current, or in-memory proposed event graphs without writing source. Full changes are resources.',
|
|
406
183
|
inputSchema: eventCompareInputSchema,
|
|
407
184
|
outputSchema: eventCompareOutputSchema,
|
|
408
185
|
annotations: readOnlyEventTool,
|
|
409
|
-
},
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
const progress = progressReporter(extra);
|
|
414
|
-
await progress.report(0, 3, 'Comparing event-chain graphs');
|
|
415
|
-
const compared = await viewer.compareAndStore(compareRequest({ ...input, workspaceId }, context, progress.signal));
|
|
416
|
-
await progress.report(2, 3, 'Linking complete event comparison');
|
|
417
|
-
const { comparison } = compared;
|
|
418
|
-
const result = emptyServiceResult(workspaceId, {
|
|
419
|
-
beforeRevision: comparison.beforeRevision,
|
|
420
|
-
afterRevision: comparison.afterRevision,
|
|
421
|
-
beforeGraphHash: comparison.beforeGraphHash,
|
|
422
|
-
afterGraphHash: comparison.afterGraphHash,
|
|
423
|
-
...(compared.render === undefined ? {} : { renderHashes: compared.render.hashes }),
|
|
424
|
-
counts: {
|
|
425
|
-
changes: comparison.changes.length,
|
|
426
|
-
addedNodes: comparison.addedNodeIds.length,
|
|
427
|
-
removedNodes: comparison.removedNodeIds.length,
|
|
428
|
-
changedNodes: comparison.changedNodeIds.length,
|
|
429
|
-
addedEdges: comparison.addedEdgeIds.length,
|
|
430
|
-
removedEdges: comparison.removedEdgeIds.length,
|
|
431
|
-
changedEdges: comparison.changedEdgeIds.length,
|
|
432
|
-
addedStateAccesses: comparison.addedStateAccessIds.length,
|
|
433
|
-
removedStateAccesses: comparison.removedStateAccessIds.length,
|
|
434
|
-
changedStateAccesses: comparison.changedStateAccessIds.length,
|
|
435
|
-
addedStateLinks: comparison.addedStateLinkIds.length,
|
|
436
|
-
removedStateLinks: comparison.removedStateLinkIds.length,
|
|
437
|
-
changedStateLinks: comparison.changedStateLinkIds.length,
|
|
438
|
-
addedDiagnostics: comparison.addedIssueIds.length,
|
|
439
|
-
resolvedDiagnostics: comparison.resolvedIssueIds.length,
|
|
440
|
-
addedUnresolved: comparison.addedUnresolvedIds.length,
|
|
441
|
-
resolvedUnresolved: comparison.resolvedUnresolvedIds.length,
|
|
442
|
-
disconnectedRoots: comparison.newlyDisconnectedRootIds.length,
|
|
443
|
-
disconnectedBranches: comparison.newlyDisconnectedBranchIds.length,
|
|
444
|
-
disconnectedTerminals: comparison.newlyDisconnectedTerminalIds.length,
|
|
445
|
-
beforeSkippedSources: compared.before.skippedSourceCount,
|
|
446
|
-
afterSkippedSources: compared.after.skippedSourceCount,
|
|
447
|
-
artifacts: compared.artifacts.length,
|
|
448
|
-
},
|
|
449
|
-
boundary: {
|
|
450
|
-
proposedSources: input.proposedSources?.length ?? 0,
|
|
451
|
-
render: input.render ?? true,
|
|
452
|
-
maxRenderNodes: input.maxRenderNodes ?? 120,
|
|
453
|
-
refresh: compared.refresh,
|
|
454
|
-
},
|
|
455
|
-
});
|
|
456
|
-
result.code =
|
|
457
|
-
compared.before.complete && compared.after.complete
|
|
458
|
-
? 'EVENT_COMPARED'
|
|
459
|
-
: 'EVENT_COMPARED_PARTIAL';
|
|
460
|
-
setInlineFilesScanned(result, [...new Set([...compared.before.filesScanned, ...compared.after.filesScanned])].sort(compareCodeUnits));
|
|
461
|
-
result.artifacts = compared.artifacts.map(publicArtifactLink);
|
|
462
|
-
const beforeValidation = graphValidation(compared.before);
|
|
463
|
-
const afterValidation = graphValidation(compared.after);
|
|
464
|
-
result.validation = {
|
|
465
|
-
passed: beforeValidation.passed && afterValidation.passed,
|
|
466
|
-
checks: [...beforeValidation.checks, ...afterValidation.checks].map((check, index) => ({
|
|
467
|
-
...check,
|
|
468
|
-
id: `${index === 0 ? 'before' : 'after'}-${check.id}`,
|
|
469
|
-
})),
|
|
470
|
-
};
|
|
471
|
-
await progress.report(3, 3, 'Event comparison complete');
|
|
472
|
-
return toolResult(result);
|
|
473
|
-
}
|
|
474
|
-
catch (error) {
|
|
475
|
-
return errorResult(error, workspaceId);
|
|
476
|
-
}
|
|
477
|
-
finally {
|
|
478
|
-
releaseCaches();
|
|
479
|
-
}
|
|
480
|
-
});
|
|
186
|
+
},
|
|
187
|
+
];
|
|
188
|
+
export function registerEventTools(server) {
|
|
189
|
+
registerLegacyTaskTools(server, eventTaskTools);
|
|
481
190
|
}
|