unreal-engine-mcp-server 0.5.0 → 0.5.1

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 (139) hide show
  1. package/.env.example +1 -1
  2. package/.github/release-drafter-config.yml +51 -0
  3. package/.github/workflows/greetings.yml +5 -1
  4. package/.github/workflows/labeler.yml +2 -1
  5. package/.github/workflows/publish-mcp.yml +1 -0
  6. package/.github/workflows/release-drafter.yml +1 -1
  7. package/.github/workflows/release.yml +3 -3
  8. package/CHANGELOG.md +71 -0
  9. package/CONTRIBUTING.md +1 -1
  10. package/GEMINI.md +115 -0
  11. package/Public/Plugin_setup_guide.mp4 +0 -0
  12. package/README.md +166 -200
  13. package/dist/config.d.ts +0 -1
  14. package/dist/config.js +0 -1
  15. package/dist/constants.d.ts +4 -0
  16. package/dist/constants.js +4 -0
  17. package/dist/graphql/loaders.d.ts +64 -0
  18. package/dist/graphql/loaders.js +117 -0
  19. package/dist/graphql/resolvers.d.ts +3 -3
  20. package/dist/graphql/resolvers.js +33 -30
  21. package/dist/graphql/server.js +3 -1
  22. package/dist/graphql/types.d.ts +2 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.js +13 -2
  25. package/dist/server-setup.d.ts +0 -1
  26. package/dist/server-setup.js +0 -40
  27. package/dist/tools/actors.d.ts +40 -24
  28. package/dist/tools/actors.js +8 -2
  29. package/dist/tools/assets.d.ts +19 -71
  30. package/dist/tools/assets.js +28 -22
  31. package/dist/tools/base-tool.d.ts +4 -4
  32. package/dist/tools/base-tool.js +1 -1
  33. package/dist/tools/blueprint.d.ts +33 -61
  34. package/dist/tools/consolidated-tool-handlers.js +96 -110
  35. package/dist/tools/dynamic-handler-registry.d.ts +11 -9
  36. package/dist/tools/dynamic-handler-registry.js +17 -95
  37. package/dist/tools/editor.d.ts +19 -193
  38. package/dist/tools/editor.js +8 -0
  39. package/dist/tools/environment.d.ts +8 -14
  40. package/dist/tools/foliage.d.ts +18 -143
  41. package/dist/tools/foliage.js +4 -2
  42. package/dist/tools/handlers/actor-handlers.js +0 -5
  43. package/dist/tools/handlers/asset-handlers.js +454 -454
  44. package/dist/tools/landscape.d.ts +16 -116
  45. package/dist/tools/landscape.js +7 -3
  46. package/dist/tools/level.d.ts +22 -103
  47. package/dist/tools/level.js +24 -16
  48. package/dist/tools/lighting.js +5 -1
  49. package/dist/tools/materials.js +5 -1
  50. package/dist/tools/niagara.js +37 -2
  51. package/dist/tools/performance.d.ts +0 -1
  52. package/dist/tools/performance.js +0 -1
  53. package/dist/tools/physics.js +5 -1
  54. package/dist/tools/sequence.d.ts +24 -24
  55. package/dist/tools/sequence.js +13 -0
  56. package/dist/tools/ui.d.ts +0 -2
  57. package/dist/types/automation-responses.d.ts +115 -0
  58. package/dist/types/automation-responses.js +2 -0
  59. package/dist/types/responses.d.ts +249 -0
  60. package/dist/types/responses.js +2 -0
  61. package/dist/types/tool-interfaces.d.ts +135 -135
  62. package/dist/utils/command-validator.js +3 -2
  63. package/dist/utils/path-security.d.ts +2 -0
  64. package/dist/utils/path-security.js +24 -0
  65. package/dist/utils/response-factory.d.ts +4 -4
  66. package/dist/utils/response-factory.js +15 -21
  67. package/docs/Migration-Guide-v0.5.0.md +1 -9
  68. package/docs/testing-guide.md +2 -2
  69. package/package.json +12 -6
  70. package/scripts/run-all-tests.mjs +25 -20
  71. package/server.json +3 -2
  72. package/src/config.ts +1 -1
  73. package/src/constants.ts +7 -0
  74. package/src/graphql/loaders.ts +244 -0
  75. package/src/graphql/resolvers.ts +47 -49
  76. package/src/graphql/server.ts +3 -1
  77. package/src/graphql/types.ts +3 -0
  78. package/src/index.ts +15 -2
  79. package/src/resources/assets.ts +5 -4
  80. package/src/server-setup.ts +3 -37
  81. package/src/tools/actors.ts +36 -28
  82. package/src/tools/animation.ts +1 -0
  83. package/src/tools/assets.ts +74 -63
  84. package/src/tools/base-tool.ts +3 -3
  85. package/src/tools/blueprint.ts +59 -59
  86. package/src/tools/consolidated-tool-handlers.ts +129 -150
  87. package/src/tools/dynamic-handler-registry.ts +22 -140
  88. package/src/tools/editor.ts +39 -26
  89. package/src/tools/environment.ts +21 -27
  90. package/src/tools/foliage.ts +28 -25
  91. package/src/tools/handlers/actor-handlers.ts +2 -8
  92. package/src/tools/handlers/asset-handlers.ts +484 -484
  93. package/src/tools/handlers/sequence-handlers.ts +1 -1
  94. package/src/tools/landscape.ts +34 -28
  95. package/src/tools/level.ts +96 -76
  96. package/src/tools/lighting.ts +6 -1
  97. package/src/tools/materials.ts +8 -2
  98. package/src/tools/niagara.ts +44 -2
  99. package/src/tools/performance.ts +1 -2
  100. package/src/tools/physics.ts +7 -1
  101. package/src/tools/sequence.ts +41 -25
  102. package/src/tools/ui.ts +0 -2
  103. package/src/types/automation-responses.ts +119 -0
  104. package/src/types/responses.ts +355 -0
  105. package/src/types/tool-interfaces.ts +135 -135
  106. package/src/utils/command-validator.ts +3 -2
  107. package/src/utils/normalize.test.ts +162 -0
  108. package/src/utils/path-security.ts +43 -0
  109. package/src/utils/response-factory.ts +29 -24
  110. package/src/utils/safe-json.test.ts +90 -0
  111. package/src/utils/validation.test.ts +184 -0
  112. package/tests/test-animation.mjs +358 -33
  113. package/tests/test-asset-graph.mjs +311 -0
  114. package/tests/test-audio.mjs +314 -116
  115. package/tests/test-behavior-tree.mjs +327 -144
  116. package/tests/test-blueprint-graph.mjs +343 -12
  117. package/tests/test-control-editor.mjs +85 -53
  118. package/tests/test-graphql.mjs +58 -8
  119. package/tests/test-input.mjs +349 -0
  120. package/tests/test-inspect.mjs +291 -61
  121. package/tests/test-landscape.mjs +304 -48
  122. package/tests/test-lighting.mjs +428 -0
  123. package/tests/test-manage-level.mjs +70 -51
  124. package/tests/test-performance.mjs +539 -0
  125. package/tests/test-sequence.mjs +82 -46
  126. package/tests/test-system.mjs +72 -33
  127. package/tests/test-wasm.mjs +98 -8
  128. package/vitest.config.ts +35 -0
  129. package/.github/release-drafter.yml +0 -148
  130. package/dist/prompts/index.d.ts +0 -21
  131. package/dist/prompts/index.js +0 -217
  132. package/dist/tools/blueprint/helpers.d.ts +0 -29
  133. package/dist/tools/blueprint/helpers.js +0 -182
  134. package/src/prompts/index.ts +0 -249
  135. package/src/tools/blueprint/helpers.ts +0 -189
  136. package/tests/test-blueprint-events.mjs +0 -35
  137. package/tests/test-extra-tools.mjs +0 -38
  138. package/tests/test-render.mjs +0 -33
  139. package/tests/test-search-assets.mjs +0 -66
@@ -0,0 +1,117 @@
1
+ import DataLoader from 'dataloader';
2
+ import { Logger } from '../utils/logger.js';
3
+ const log = new Logger('GraphQL:Loaders');
4
+ export function createLoaders(automationBridge) {
5
+ return {
6
+ actorLoader: new DataLoader(async (names) => {
7
+ log.debug(`Batching actor fetch for ${names.length} actors`);
8
+ try {
9
+ const result = await automationBridge.sendAutomationRequest('control_actor', {
10
+ action: 'batch_get',
11
+ actorNames: [...names]
12
+ });
13
+ if (result.success && result.actors) {
14
+ return names.map(name => result.actors?.find(a => a.name === name || a.label === name) ?? null);
15
+ }
16
+ }
17
+ catch {
18
+ log.debug('Batch fetch not supported, falling back to individual fetches');
19
+ }
20
+ const results = await Promise.all(names.map(async (name) => {
21
+ try {
22
+ const result = await automationBridge.sendAutomationRequest('control_actor', {
23
+ action: 'find_by_name',
24
+ actorName: name
25
+ });
26
+ return result.success ? (result.actor ?? null) : null;
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }));
32
+ return results;
33
+ }, {
34
+ cache: true,
35
+ maxBatchSize: 50
36
+ }),
37
+ assetLoader: new DataLoader(async (paths) => {
38
+ log.debug(`Batching asset fetch for ${paths.length} assets`);
39
+ try {
40
+ const result = await automationBridge.sendAutomationRequest('manage_asset', {
41
+ action: 'batch_get',
42
+ assetPaths: [...paths]
43
+ });
44
+ if (result.success && result.assets) {
45
+ return paths.map(path => result.assets?.find(a => a.path === path) ?? null);
46
+ }
47
+ }
48
+ catch {
49
+ log.debug('Batch asset fetch not supported');
50
+ }
51
+ const results = await Promise.all(paths.map(async (path) => {
52
+ try {
53
+ const result = await automationBridge.sendAutomationRequest('manage_asset', {
54
+ action: 'exists',
55
+ assetPath: path
56
+ });
57
+ if (result.success && result.exists) {
58
+ return result.asset ?? { name: path.split('/').pop() || '', path };
59
+ }
60
+ return null;
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ }));
66
+ return results;
67
+ }, {
68
+ cache: true,
69
+ maxBatchSize: 100
70
+ }),
71
+ blueprintLoader: new DataLoader(async (paths) => {
72
+ log.debug(`Batching blueprint fetch for ${paths.length} blueprints`);
73
+ const results = await Promise.all(paths.map(async (path) => {
74
+ try {
75
+ const result = await automationBridge.sendAutomationRequest('manage_blueprint', {
76
+ action: 'get_blueprint',
77
+ blueprintPath: path
78
+ });
79
+ return result.success ? (result.blueprint ?? null) : null;
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }));
85
+ return results;
86
+ }, {
87
+ cache: true,
88
+ maxBatchSize: 20
89
+ }),
90
+ actorComponentsLoader: new DataLoader(async (actorNames) => {
91
+ log.debug(`Batching component fetch for ${actorNames.length} actors`);
92
+ const results = await Promise.all(actorNames.map(async (actorName) => {
93
+ try {
94
+ const result = await automationBridge.sendAutomationRequest('control_actor', {
95
+ action: 'get_components',
96
+ actorName
97
+ });
98
+ return result.success ? (result.components ?? null) : null;
99
+ }
100
+ catch {
101
+ return null;
102
+ }
103
+ }));
104
+ return results;
105
+ }, {
106
+ cache: true,
107
+ maxBatchSize: 30
108
+ })
109
+ };
110
+ }
111
+ export function clearLoaders(loaders) {
112
+ loaders.actorLoader.clearAll();
113
+ loaders.assetLoader.clearAll();
114
+ loaders.blueprintLoader.clearAll();
115
+ loaders.actorComponentsLoader.clearAll();
116
+ }
117
+ //# sourceMappingURL=loaders.js.map
@@ -100,7 +100,7 @@ export declare const resolvers: {
100
100
  }>;
101
101
  asset: (_: any, { path }: {
102
102
  path: string;
103
- }, context: GraphQLContext) => Promise<{} | null>;
103
+ }, context: GraphQLContext) => Promise<import("./loaders.js").Asset | null>;
104
104
  actors: (_: any, args: any, context: GraphQLContext) => Promise<{
105
105
  edges: {
106
106
  node: Actor;
@@ -116,7 +116,7 @@ export declare const resolvers: {
116
116
  }>;
117
117
  actor: (_: any, { name }: {
118
118
  name: string;
119
- }, context: GraphQLContext) => Promise<Actor | null>;
119
+ }, context: GraphQLContext) => Promise<import("./loaders.js").Actor | null>;
120
120
  blueprints: (_: any, args: any, context: GraphQLContext) => Promise<{
121
121
  edges: {
122
122
  node: Blueprint;
@@ -141,7 +141,7 @@ export declare const resolvers: {
141
141
  }>;
142
142
  blueprint: (_: any, { path }: {
143
143
  path: string;
144
- }, context: GraphQLContext) => Promise<Blueprint | null>;
144
+ }, context: GraphQLContext) => Promise<import("./loaders.js").Blueprint | null>;
145
145
  levels: (_: any, __: any, context: GraphQLContext) => Promise<any>;
146
146
  currentLevel: (_: any, __: any, context: GraphQLContext) => Promise<{} | null>;
147
147
  materials: (_: any, args: any, context: GraphQLContext) => Promise<{
@@ -87,6 +87,24 @@ export const scalarResolvers = {
87
87
  }
88
88
  }
89
89
  };
90
+ import { Logger } from '../utils/logger.js';
91
+ const log = new Logger('GraphQL:Resolvers');
92
+ class GraphQLResolverError extends Error {
93
+ extensions;
94
+ constructor(message, code = 'UNREAL_ENGINE_ERROR', originalError) {
95
+ super(message);
96
+ this.name = 'GraphQLResolverError';
97
+ this.extensions = {
98
+ code,
99
+ originalError: originalError?.message
100
+ };
101
+ }
102
+ }
103
+ function createResolverError(operation, error) {
104
+ const message = error instanceof Error ? error.message : String(error);
105
+ log.error(`${operation} failed:`, message);
106
+ return new GraphQLResolverError(`${operation} failed: ${message}`, 'UNREAL_ENGINE_ERROR', error instanceof Error ? error : undefined);
107
+ }
90
108
  function logAutomationFailure(source, response) {
91
109
  try {
92
110
  if (!response || response.success !== false) {
@@ -96,7 +114,7 @@ function logAutomationFailure(source, response) {
96
114
  if (errorText.length === 0) {
97
115
  return;
98
116
  }
99
- console.error(`[GraphQL] ${source} automation failure:`, errorText);
117
+ log.error(`${source} automation failure:`, errorText);
100
118
  }
101
119
  catch {
102
120
  }
@@ -111,7 +129,7 @@ async function getActorProperties(bridge, actorName) {
111
129
  return result.success ? result.value || {} : {};
112
130
  }
113
131
  catch (error) {
114
- console.error('Failed to get actor properties:', error);
132
+ log.error('Failed to get actor properties:', error);
115
133
  return {};
116
134
  }
117
135
  }
@@ -129,12 +147,12 @@ async function listAssets(automationBridge, filter, pagination) {
129
147
  };
130
148
  }
131
149
  logAutomationFailure('list_assets', response);
132
- console.error('Failed to list assets:', response);
150
+ log.warn('Failed to list assets - returning empty set');
133
151
  return { assets: [], totalCount: 0 };
134
152
  }
135
153
  catch (error) {
136
- console.error('Failed to list assets:', error);
137
- return { assets: [], totalCount: 0 };
154
+ log.error('Failed to list assets:', error);
155
+ throw createResolverError('listAssets', error);
138
156
  }
139
157
  }
140
158
  async function listActors(automationBridge, filter) {
@@ -156,22 +174,6 @@ async function listActors(automationBridge, filter) {
156
174
  return { actors: [] };
157
175
  }
158
176
  }
159
- async function getBlueprint(automationBridge, blueprintPath) {
160
- try {
161
- const response = await automationBridge.sendAutomationRequest('get_blueprint', {
162
- blueprintPath
163
- }, { timeoutMs: 30000 });
164
- if (response.success && response.result) {
165
- return response.result;
166
- }
167
- logAutomationFailure('get_blueprint', response);
168
- return null;
169
- }
170
- catch (error) {
171
- console.error('Failed to get blueprint:', error);
172
- return null;
173
- }
174
- }
175
177
  export const resolvers = {
176
178
  Query: {
177
179
  assets: async (_, args, context) => {
@@ -194,11 +196,10 @@ export const resolvers = {
194
196
  },
195
197
  asset: async (_, { path }, context) => {
196
198
  try {
197
- const response = await context.automationBridge.sendAutomationRequest('get_asset', { assetPath: path }, { timeoutMs: 10000 });
198
- if (response.success && response.result) {
199
- return response.result;
199
+ if (!context.loaders) {
200
+ throw new Error('Loaders not initialized');
200
201
  }
201
- return null;
202
+ return await context.loaders.assetLoader.load(path);
202
203
  }
203
204
  catch (error) {
204
205
  console.error('Failed to get asset:', error);
@@ -228,11 +229,10 @@ export const resolvers = {
228
229
  },
229
230
  actor: async (_, { name }, context) => {
230
231
  try {
231
- const actors = await listActors(context.automationBridge, { tag: name });
232
- if (actors.actors.length > 0) {
233
- return actors.actors[0];
232
+ if (!context.loaders) {
233
+ throw new Error('Loaders not initialized');
234
234
  }
235
- return null;
235
+ return await context.loaders.actorLoader.load(name);
236
236
  }
237
237
  catch (error) {
238
238
  console.error('Failed to get actor:', error);
@@ -279,7 +279,10 @@ export const resolvers = {
279
279
  }
280
280
  },
281
281
  blueprint: async (_, { path }, context) => {
282
- return await getBlueprint(context.automationBridge, path);
282
+ if (!context.loaders) {
283
+ throw new Error('Loaders not initialized');
284
+ }
285
+ return await context.loaders.blueprintLoader.load(path);
283
286
  },
284
287
  levels: async (_, __, context) => {
285
288
  try {
@@ -2,6 +2,7 @@ import { createYoga } from 'graphql-yoga';
2
2
  import { createServer } from 'http';
3
3
  import { Logger } from '../utils/logger.js';
4
4
  import { createGraphQLSchema } from './schema.js';
5
+ import { createLoaders } from './loaders.js';
5
6
  export class GraphQLServer {
6
7
  log = new Logger('GraphQLServer');
7
8
  server = null;
@@ -40,7 +41,8 @@ export class GraphQLServer {
40
41
  },
41
42
  context: () => ({
42
43
  bridge: this.bridge,
43
- automationBridge: this.automationBridge
44
+ automationBridge: this.automationBridge,
45
+ loaders: createLoaders(this.automationBridge)
44
46
  }),
45
47
  logging: {
46
48
  debug: (...args) => this.log.debug('[GraphQL]', ...args),
@@ -1,7 +1,9 @@
1
1
  import type { UnrealBridge } from '../unreal-bridge.js';
2
2
  import { AutomationBridge } from '../automation/index.js';
3
+ import type { GraphQLLoaders } from './loaders.js';
3
4
  export interface GraphQLContext {
4
5
  bridge: UnrealBridge;
5
6
  automationBridge: AutomationBridge;
7
+ loaders?: GraphQLLoaders;
6
8
  }
7
9
  //# sourceMappingURL=types.d.ts.map
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import { UnrealBridge } from './unreal-bridge.js';
3
3
  import { AutomationBridge } from './automation/index.js';
4
4
  import { z } from 'zod';
5
+ import { GraphQLServer } from './graphql/server.js';
5
6
  export declare function createServer(): {
6
7
  server: Server<{
7
8
  method: string;
@@ -39,6 +40,7 @@ export declare function createServer(): {
39
40
  }>;
40
41
  bridge: UnrealBridge;
41
42
  automationBridge: AutomationBridge;
43
+ graphqlServer: GraphQLServer;
42
44
  };
43
45
  export declare const configSchema: z.ZodObject<{
44
46
  logLevel: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ import { HealthMonitor } from './services/health-monitor.js';
12
12
  import { ServerSetup } from './server-setup.js';
13
13
  import { startMetricsServer } from './services/metrics-server.js';
14
14
  import { config } from './config.js';
15
+ import { GraphQLServer } from './graphql/server.js';
15
16
  const require = createRequire(import.meta.url);
16
17
  const packageInfo = (() => {
17
18
  try {
@@ -81,6 +82,10 @@ export function createServer() {
81
82
  log.error('Automation bridge error', error);
82
83
  });
83
84
  startMetricsServer({ healthMonitor, automationBridge, logger: log });
85
+ const graphqlServer = new GraphQLServer(bridge, automationBridge);
86
+ graphqlServer.start().catch((error) => {
87
+ log.warn('GraphQL server failed to start:', error);
88
+ });
84
89
  log.debug('Initializing WebAssembly integration...');
85
90
  initializeWASM().then(() => {
86
91
  log.info('✅ WebAssembly integration initialized (JSON parsing and math operations)');
@@ -109,7 +114,7 @@ export function createServer() {
109
114
  });
110
115
  const serverSetup = new ServerSetup(server, bridge, automationBridge, log, healthMonitor);
111
116
  serverSetup.setup();
112
- return { server, bridge, automationBridge };
117
+ return { server, bridge, automationBridge, graphqlServer };
113
118
  }
114
119
  export const configSchema = z.object({
115
120
  logLevel: z.enum(['debug', 'info', 'warn', 'error']).optional().default('info').describe('Runtime log level'),
@@ -131,7 +136,7 @@ export default function createServerDefault({ config } = {}) {
131
136
  return server;
132
137
  }
133
138
  export async function startStdioServer() {
134
- const { server, automationBridge } = createServer();
139
+ const { server, automationBridge, graphqlServer } = createServer();
135
140
  const transport = new StdioServerTransport();
136
141
  let shuttingDown = false;
137
142
  const handleShutdown = async (signal) => {
@@ -147,6 +152,12 @@ export async function startStdioServer() {
147
152
  catch (error) {
148
153
  log.warn('Failed to stop automation bridge cleanly', error);
149
154
  }
155
+ try {
156
+ await graphqlServer.stop();
157
+ }
158
+ catch (error) {
159
+ log.warn('Failed to stop GraphQL server cleanly', error);
160
+ }
150
161
  try {
151
162
  if (typeof server.close === 'function') {
152
163
  await server.close();
@@ -16,6 +16,5 @@ export declare class ServerSetup {
16
16
  setup(): Promise<void>;
17
17
  private validateEnvironment;
18
18
  private ensureConnectedOnDemand;
19
- private registerPrompts;
20
19
  }
21
20
  //# sourceMappingURL=server-setup.d.ts.map
@@ -1,5 +1,3 @@
1
- import { ListPromptsRequestSchema, GetPromptRequestSchema } from '@modelcontextprotocol/sdk/types.js';
2
- import { prompts } from './prompts/index.js';
3
1
  import { AssetResources } from './resources/assets.js';
4
2
  import { ActorResources } from './resources/actors.js';
5
3
  import { LevelResources } from './resources/levels.js';
@@ -32,7 +30,6 @@ export class ServerSetup {
32
30
  resourceRegistry.register();
33
31
  const toolRegistry = new ToolRegistry(this.server, this.bridge, this.automationBridge, this.logger, this.healthMonitor, this.assetResources, this.actorResources, this.levelResources, ensureConnected);
34
32
  toolRegistry.register();
35
- this.registerPrompts();
36
33
  }
37
34
  validateEnvironment() {
38
35
  const projectPath = process.env.UE_PROJECT_PATH;
@@ -70,42 +67,5 @@ export class ServerSetup {
70
67
  }
71
68
  return ok;
72
69
  }
73
- registerPrompts() {
74
- this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
75
- return {
76
- prompts: prompts.map(p => ({
77
- name: p.name,
78
- description: p.description,
79
- arguments: Object.entries(p.arguments || {}).map(([name, schema]) => {
80
- const meta = {};
81
- if (schema.type)
82
- meta.type = schema.type;
83
- if (schema.enum)
84
- meta.enum = schema.enum;
85
- if (schema.default !== undefined)
86
- meta.default = schema.default;
87
- return {
88
- name,
89
- description: schema.description,
90
- required: schema.required ?? false,
91
- ...(Object.keys(meta).length ? { _meta: meta } : {})
92
- };
93
- })
94
- }))
95
- };
96
- });
97
- this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
98
- const prompt = prompts.find(p => p.name === request.params.name);
99
- if (!prompt) {
100
- throw new Error(`Unknown prompt: ${request.params.name}`);
101
- }
102
- const args = (request.params.arguments || {});
103
- const messages = prompt.build(args);
104
- return {
105
- description: prompt.description,
106
- messages
107
- };
108
- });
109
- }
110
70
  }
111
71
  //# sourceMappingURL=server-setup.js.map
@@ -22,7 +22,7 @@ export declare class ActorTools extends BaseTool implements IActorTools {
22
22
  delete(params: {
23
23
  actorName?: string;
24
24
  actorNames?: string[];
25
- }): Promise<any>;
25
+ }): Promise<StandardActionResponse<any>>;
26
26
  applyForce(params: {
27
27
  actorName: string;
28
28
  force: {
@@ -30,7 +30,7 @@ export declare class ActorTools extends BaseTool implements IActorTools {
30
30
  y: number;
31
31
  z: number;
32
32
  };
33
- }): Promise<any>;
33
+ }): Promise<StandardActionResponse<any>>;
34
34
  private resolveActorClass;
35
35
  spawnBlueprint(params: {
36
36
  blueprintPath: string;
@@ -45,7 +45,7 @@ export declare class ActorTools extends BaseTool implements IActorTools {
45
45
  yaw: number;
46
46
  roll: number;
47
47
  };
48
- }): Promise<any>;
48
+ }): Promise<StandardActionResponse<any>>;
49
49
  setTransform(params: {
50
50
  actorName: string;
51
51
  location?: {
@@ -63,26 +63,30 @@ export declare class ActorTools extends BaseTool implements IActorTools {
63
63
  y: number;
64
64
  z: number;
65
65
  };
66
- }): Promise<any>;
67
- getTransform(actorName: string): Promise<any>;
66
+ }): Promise<StandardActionResponse<any>>;
67
+ getTransform(actorName: string): Promise<StandardActionResponse<any>>;
68
68
  setVisibility(params: {
69
69
  actorName: string;
70
70
  visible: boolean;
71
- }): Promise<any>;
71
+ }): Promise<StandardActionResponse<any>>;
72
72
  addComponent(params: {
73
73
  actorName: string;
74
74
  componentType: string;
75
75
  componentName?: string;
76
76
  properties?: Record<string, unknown>;
77
- }): Promise<any>;
77
+ }): Promise<StandardActionResponse<any>>;
78
78
  setComponentProperties(params: {
79
79
  actorName: string;
80
80
  componentName: string;
81
81
  properties: Record<string, unknown>;
82
- }): Promise<any>;
82
+ }): Promise<StandardActionResponse<any>>;
83
83
  getComponents(actorName: string): Promise<{
84
84
  success: boolean;
85
- error: any;
85
+ error: string | {
86
+ [key: string]: unknown;
87
+ code?: string;
88
+ message: string;
89
+ };
86
90
  message?: undefined;
87
91
  components?: undefined;
88
92
  count?: undefined;
@@ -101,45 +105,49 @@ export declare class ActorTools extends BaseTool implements IActorTools {
101
105
  y: number;
102
106
  z: number;
103
107
  };
104
- }): Promise<any>;
108
+ }): Promise<StandardActionResponse<any>>;
105
109
  addTag(params: {
106
110
  actorName: string;
107
111
  tag: string;
108
- }): Promise<any>;
112
+ }): Promise<StandardActionResponse<any>>;
109
113
  removeTag(params: {
110
114
  actorName: string;
111
115
  tag: string;
112
- }): Promise<any>;
116
+ }): Promise<StandardActionResponse<any>>;
113
117
  findByTag(params: {
114
118
  tag: string;
115
119
  matchType?: string;
116
- }): Promise<any>;
117
- findByName(name: string): Promise<any>;
118
- detach(actorName: string): Promise<any>;
120
+ }): Promise<StandardActionResponse<any>>;
121
+ findByName(name: string): Promise<StandardActionResponse<any>>;
122
+ detach(actorName: string): Promise<StandardActionResponse<any>>;
119
123
  attach(params: {
120
124
  childActor: string;
121
125
  parentActor: string;
122
- }): Promise<any>;
123
- deleteByTag(tag: string): Promise<any>;
126
+ }): Promise<StandardActionResponse<any>>;
127
+ deleteByTag(tag: string): Promise<StandardActionResponse<any>>;
124
128
  setBlueprintVariables(params: {
125
129
  actorName: string;
126
130
  variables: Record<string, unknown>;
127
- }): Promise<any>;
131
+ }): Promise<StandardActionResponse<any>>;
128
132
  createSnapshot(params: {
129
133
  actorName: string;
130
134
  snapshotName: string;
131
- }): Promise<any>;
135
+ }): Promise<StandardActionResponse<any>>;
132
136
  restoreSnapshot(params: {
133
137
  actorName: string;
134
138
  snapshotName: string;
135
- }): Promise<any>;
139
+ }): Promise<StandardActionResponse<any>>;
136
140
  exportActor(params: {
137
141
  actorName: string;
138
142
  destinationPath?: string;
139
- }): Promise<any>;
143
+ }): Promise<StandardActionResponse<any>>;
140
144
  getBoundingBox(actorName: string): Promise<{
141
145
  success: boolean;
142
- error: any;
146
+ error: string | {
147
+ [key: string]: unknown;
148
+ code?: string;
149
+ message: string;
150
+ };
143
151
  message?: undefined;
144
152
  boundingBox?: undefined;
145
153
  } | {
@@ -150,7 +158,11 @@ export declare class ActorTools extends BaseTool implements IActorTools {
150
158
  }>;
151
159
  getMetadata(actorName: string): Promise<{
152
160
  success: boolean;
153
- error: any;
161
+ error: string | {
162
+ [key: string]: unknown;
163
+ code?: string;
164
+ message: string;
165
+ };
154
166
  message?: undefined;
155
167
  metadata?: undefined;
156
168
  } | {
@@ -163,7 +175,11 @@ export declare class ActorTools extends BaseTool implements IActorTools {
163
175
  filter?: string;
164
176
  }): Promise<{
165
177
  success: boolean;
166
- error: any;
178
+ error: string | {
179
+ [key: string]: unknown;
180
+ code?: string;
181
+ message: string;
182
+ };
167
183
  message?: undefined;
168
184
  actors?: undefined;
169
185
  count?: undefined;
@@ -1,5 +1,6 @@
1
1
  import { ensureRotation, ensureVector3 } from '../utils/validation.js';
2
2
  import { BaseTool } from './base-tool.js';
3
+ import { wasmIntegration } from '../wasm/index.js';
3
4
  export class ActorTools extends BaseTool {
4
5
  constructor(bridge) {
5
6
  super(bridge);
@@ -38,7 +39,9 @@ export class ActorTools extends BaseTool {
38
39
  meshPath: params.meshPath
39
40
  }, timeoutMs ? { timeoutMs } : undefined);
40
41
  if (!response || !response.success) {
41
- throw new Error(response?.error || response?.message || 'Failed to spawn actor');
42
+ const error = response?.error;
43
+ const errorMsg = typeof error === 'string' ? error : error?.message || response?.message || 'Failed to spawn actor';
44
+ throw new Error(errorMsg);
42
45
  }
43
46
  const data = response.data || {};
44
47
  const result = {
@@ -292,7 +295,10 @@ export class ActorTools extends BaseTool {
292
295
  }
293
296
  if (params.offset) {
294
297
  const offs = ensureVector3(params.offset, 'duplicate offset');
295
- payload.offset = { x: offs[0], y: offs[1], z: offs[2] };
298
+ const origin = [0, 0, 0];
299
+ const calculatedOffset = wasmIntegration.vectorAdd(origin, offs);
300
+ console.error('[WASM] Using vectorAdd for duplicate offset calculation');
301
+ payload.offset = { x: calculatedOffset[0], y: calculatedOffset[1], z: calculatedOffset[2] };
296
302
  }
297
303
  return this.sendRequest('duplicate', payload, 'control_actor');
298
304
  }