@troykelly/openclaw-projects 0.0.30 → 0.0.32

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 (55) hide show
  1. package/dist/register-openclaw.d.ts.map +1 -1
  2. package/dist/register-openclaw.js +230 -8
  3. package/dist/register-openclaw.js.map +1 -1
  4. package/dist/services/api-source-service.d.ts +181 -0
  5. package/dist/services/api-source-service.d.ts.map +1 -0
  6. package/dist/services/api-source-service.js +120 -0
  7. package/dist/services/api-source-service.js.map +1 -0
  8. package/dist/tools/api-credential-manage.d.ts +83 -0
  9. package/dist/tools/api-credential-manage.d.ts.map +1 -0
  10. package/dist/tools/api-credential-manage.js +71 -0
  11. package/dist/tools/api-credential-manage.js.map +1 -0
  12. package/dist/tools/api-get.d.ts +47 -0
  13. package/dist/tools/api-get.d.ts.map +1 -0
  14. package/dist/tools/api-get.js +41 -0
  15. package/dist/tools/api-get.js.map +1 -0
  16. package/dist/tools/api-list.d.ts +54 -0
  17. package/dist/tools/api-list.d.ts.map +1 -0
  18. package/dist/tools/api-list.js +46 -0
  19. package/dist/tools/api-list.js.map +1 -0
  20. package/dist/tools/api-onboard.d.ts +134 -0
  21. package/dist/tools/api-onboard.d.ts.map +1 -0
  22. package/dist/tools/api-onboard.js +109 -0
  23. package/dist/tools/api-onboard.js.map +1 -0
  24. package/dist/tools/api-recall.d.ts +69 -0
  25. package/dist/tools/api-recall.d.ts.map +1 -0
  26. package/dist/tools/api-recall.js +101 -0
  27. package/dist/tools/api-recall.js.map +1 -0
  28. package/dist/tools/api-refresh.d.ts +50 -0
  29. package/dist/tools/api-refresh.d.ts.map +1 -0
  30. package/dist/tools/api-refresh.js +55 -0
  31. package/dist/tools/api-refresh.js.map +1 -0
  32. package/dist/tools/api-remove.d.ts +46 -0
  33. package/dist/tools/api-remove.d.ts.map +1 -0
  34. package/dist/tools/api-remove.js +45 -0
  35. package/dist/tools/api-remove.js.map +1 -0
  36. package/dist/tools/api-restore.d.ts +45 -0
  37. package/dist/tools/api-restore.d.ts.map +1 -0
  38. package/dist/tools/api-restore.js +41 -0
  39. package/dist/tools/api-restore.js.map +1 -0
  40. package/dist/tools/api-update.d.ts +57 -0
  41. package/dist/tools/api-update.d.ts.map +1 -0
  42. package/dist/tools/api-update.js +46 -0
  43. package/dist/tools/api-update.js.map +1 -0
  44. package/dist/tools/context-search.d.ts +2 -0
  45. package/dist/tools/context-search.d.ts.map +1 -1
  46. package/dist/tools/context-search.js +5 -1
  47. package/dist/tools/context-search.js.map +1 -1
  48. package/dist/tools/index.d.ts +9 -0
  49. package/dist/tools/index.d.ts.map +1 -1
  50. package/dist/tools/index.js +10 -0
  51. package/dist/tools/index.js.map +1 -1
  52. package/dist/types/openclaw-api.d.ts +1 -0
  53. package/dist/types/openclaw-api.d.ts.map +1 -1
  54. package/openclaw.plugin.json +1 -1
  55. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"register-openclaw.d.ts","sourceRoot":"","sources":["../src/register-openclaw.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,KAAK,YAAY,EAA2G,MAAM,aAAa,CAAC;AAKzJ,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAgBxD,OAAO,KAAK,EAEV,UAAU,EAQV,iBAAiB,EAGlB,MAAM,yBAAyB,CAAC;AAajC,8CAA8C;AAC9C,UAAU,WAAW;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,uGAAuG;IACvG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4GAA4G;IAC5G,iBAAiB,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACzD,oEAAoE;IACpE,eAAe,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,sBAAsB,EAAE,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,eAAe,EAAE,OAAO,CAAC;IACzB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA08CD;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA6C9E;AAwrED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,iBAi4B9B,CAAC;AAEF,yDAAyD;AACzD,eAAe,gBAAgB,CAAC;AAEhC,2CAA2C;AAC3C,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCnB,CAAC"}
1
+ {"version":3,"file":"register-openclaw.d.ts","sourceRoot":"","sources":["../src/register-openclaw.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,KAAK,YAAY,EAA2G,MAAM,aAAa,CAAC;AAKzJ,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAyBxD,OAAO,KAAK,EAEV,UAAU,EAQV,iBAAiB,EAGlB,MAAM,yBAAyB,CAAC;AAajC,8CAA8C;AAC9C,UAAU,WAAW;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,uGAAuG;IACvG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4GAA4G;IAC5G,iBAAiB,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACzD,oEAAoE;IACpE,eAAe,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,sBAAsB,EAAE,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,eAAe,EAAE,OAAO,CAAC;IACzB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAwjDD;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA6C9E;AA0uED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,iBAq9B9B,CAAC;AAEF,yDAAyD;AACzD,eAAe,gBAAgB,CAAC;AAEhC,2CAA2C;AAC3C,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCnB,CAAC"}
@@ -16,7 +16,7 @@ import { createGatewayMethods, registerGatewayRpcMethods } from './gateway/rpc-m
16
16
  import { createAutoCaptureHook, createGraphAwareRecallHook } from './hooks.js';
17
17
  import { createLogger } from './logger.js';
18
18
  import { createNotificationService } from './services/notification-service.js';
19
- import { createContextSearchTool, createLinksQueryTool, createLinksRemoveTool, createLinksSetTool, createProjectSearchTool, createSkillStoreAggregateTool, createSkillStoreCollectionsTool, createSkillStoreDeleteTool, createSkillStoreGetTool, createSkillStoreListTool, createSkillStorePutTool, createSkillStoreSearchTool, } from './tools/index.js';
19
+ import { createContextSearchTool, createLinksQueryTool, createLinksRemoveTool, createLinksSetTool, createProjectSearchTool, createSkillStoreAggregateTool, createSkillStoreCollectionsTool, createSkillStoreDeleteTool, createSkillStoreGetTool, createSkillStoreListTool, createSkillStorePutTool, createSkillStoreSearchTool, createApiOnboardTool, createApiRecallTool, createApiGetTool, createApiListTool, createApiUpdateTool, createApiCredentialManageTool, createApiRefreshTool, createApiRemoveTool, createApiRestoreTool, } from './tools/index.js';
20
20
  import { autoLinkInboundMessage } from './utils/auto-linker.js';
21
21
  import { blendScores, computeGeoScore, haversineDistanceKm } from './utils/geo.js';
22
22
  import { createBoundaryMarkers, detectInjectionPatternsAsync, sanitizeMessageForContext, sanitizeMetadataField, wrapExternalMessage, } from './utils/injection-protection.js';
@@ -219,8 +219,7 @@ const memoryForgetSchema = {
219
219
  properties: {
220
220
  memory_id: {
221
221
  type: 'string',
222
- description: 'ID of the memory to forget',
223
- format: 'uuid',
222
+ description: 'ID of the memory to forget (full UUID)',
224
223
  },
225
224
  query: {
226
225
  type: 'string',
@@ -1439,6 +1438,107 @@ const namespaceRevokeSchema = {
1439
1438
  },
1440
1439
  required: ['namespace', 'grant_id'],
1441
1440
  };
1441
+ // ── API Onboarding tool schemas (#1784, #1785, #1786) ─────────────────────
1442
+ const apiOnboardSchema = {
1443
+ type: 'object',
1444
+ properties: {
1445
+ spec_url: { type: 'string', description: 'URL to fetch the OpenAPI spec from.', format: 'uri' },
1446
+ spec_content: { type: 'string', description: 'Inline OpenAPI spec content (JSON or YAML).' },
1447
+ name: { type: 'string', description: 'Human-readable name for the API.', maxLength: 200 },
1448
+ description: { type: 'string', description: 'Description of the API.', maxLength: 2000 },
1449
+ tags: { type: 'array', description: 'Tags to categorise the API.', items: { type: 'string' } },
1450
+ credentials: {
1451
+ type: 'array',
1452
+ description: 'Credentials for authenticating API calls.',
1453
+ items: {
1454
+ type: 'object',
1455
+ properties: {
1456
+ header_name: { type: 'string' },
1457
+ header_prefix: { type: 'string' },
1458
+ resolve_strategy: { type: 'string', enum: ['literal', 'env', 'file', 'command'] },
1459
+ resolve_reference: { type: 'string' },
1460
+ purpose: { type: 'string', enum: ['api_call', 'spec_fetch'] },
1461
+ },
1462
+ required: ['header_name', 'resolve_strategy', 'resolve_reference'],
1463
+ },
1464
+ },
1465
+ spec_auth_headers: { type: 'object', description: 'Headers for fetching the spec URL (if auth-protected).', additionalProperties: { type: 'string' } },
1466
+ },
1467
+ required: [],
1468
+ };
1469
+ const apiRecallSchema = {
1470
+ type: 'object',
1471
+ properties: {
1472
+ query: { type: 'string', description: 'Natural-language search query for API capabilities.', minLength: 1, maxLength: 1000 },
1473
+ limit: { type: 'integer', description: 'Maximum results to return.', minimum: 1, maximum: 50, default: 10 },
1474
+ memory_kind: { type: 'string', description: 'Filter by memory kind.', enum: ['overview', 'tag_group', 'operation'] },
1475
+ api_source_id: { type: 'string', description: 'Filter to a specific API source.', format: 'uuid' },
1476
+ tags: { type: 'array', description: 'Filter by tags.', items: { type: 'string' } },
1477
+ },
1478
+ required: ['query'],
1479
+ };
1480
+ const apiGetSchema = {
1481
+ type: 'object',
1482
+ properties: {
1483
+ id: { type: 'string', description: 'UUID of the API source.', format: 'uuid' },
1484
+ },
1485
+ required: ['id'],
1486
+ };
1487
+ const apiListSchema = {
1488
+ type: 'object',
1489
+ properties: {
1490
+ limit: { type: 'integer', description: 'Maximum results.', minimum: 1, maximum: 100 },
1491
+ offset: { type: 'integer', description: 'Pagination offset.', minimum: 0 },
1492
+ status: { type: 'string', description: 'Filter by status.', enum: ['active', 'error', 'disabled'] },
1493
+ },
1494
+ required: [],
1495
+ };
1496
+ const apiUpdateSchema = {
1497
+ type: 'object',
1498
+ properties: {
1499
+ id: { type: 'string', description: 'UUID of the API source to update.', format: 'uuid' },
1500
+ name: { type: 'string', description: 'New name.', maxLength: 200 },
1501
+ description: { type: 'string', description: 'New description.', maxLength: 2000 },
1502
+ tags: { type: 'array', description: 'New tags.', items: { type: 'string' } },
1503
+ status: { type: 'string', description: 'New status.', enum: ['active', 'error', 'disabled'] },
1504
+ },
1505
+ required: ['id'],
1506
+ };
1507
+ const apiCredentialManageSchema = {
1508
+ type: 'object',
1509
+ properties: {
1510
+ api_source_id: { type: 'string', description: 'UUID of the API source.', format: 'uuid' },
1511
+ action: { type: 'string', description: 'Action to perform.', enum: ['add', 'update', 'remove'] },
1512
+ credential_id: { type: 'string', description: 'UUID of the credential (for update/remove).', format: 'uuid' },
1513
+ header_name: { type: 'string', description: 'HTTP header name (e.g. Authorization).' },
1514
+ header_prefix: { type: 'string', description: 'Header value prefix (e.g. Bearer).' },
1515
+ resolve_strategy: { type: 'string', description: 'How to resolve the credential.', enum: ['literal', 'env', 'file', 'command'] },
1516
+ resolve_reference: { type: 'string', description: 'Credential value or reference.' },
1517
+ purpose: { type: 'string', description: 'Credential purpose.', enum: ['api_call', 'spec_fetch'] },
1518
+ },
1519
+ required: ['api_source_id', 'action'],
1520
+ };
1521
+ const apiRefreshSchema = {
1522
+ type: 'object',
1523
+ properties: {
1524
+ id: { type: 'string', description: 'UUID of the API source to refresh.', format: 'uuid' },
1525
+ },
1526
+ required: ['id'],
1527
+ };
1528
+ const apiRemoveSchema = {
1529
+ type: 'object',
1530
+ properties: {
1531
+ id: { type: 'string', description: 'UUID of the API source to soft-delete.', format: 'uuid' },
1532
+ },
1533
+ required: ['id'],
1534
+ };
1535
+ const apiRestoreSchema = {
1536
+ type: 'object',
1537
+ properties: {
1538
+ id: { type: 'string', description: 'UUID of the API source to restore.', format: 'uuid' },
1539
+ },
1540
+ required: ['id'],
1541
+ };
1442
1542
  /**
1443
1543
  * Async namespace discovery — fetches accessible namespaces from the API
1444
1544
  * and updates state.resolvedNamespace.recall in-place (Issue #1537).
@@ -1490,10 +1590,11 @@ function createToolHandlers(state) {
1490
1590
  const { config, logger, apiClient } = state;
1491
1591
  // Issue #1644: Read user_id from mutable state on every call.
1492
1592
  const getAgentId = () => state.agentId;
1493
- /** Read user_id from mutable state on every call (Issue #1644) */
1593
+ /** Read user_id and namespace from mutable state on every call (Issue #1644, #1797) */
1494
1594
  const reqOpts = () => ({
1495
1595
  user_id: state.agentId,
1496
1596
  user_email: state.agentEmail,
1597
+ namespace: state.resolvedNamespace.default,
1497
1598
  });
1498
1599
  /**
1499
1600
  * Request options with namespace header for by-ID operations (#1760).
@@ -1694,7 +1795,7 @@ function createToolHandlers(state) {
1694
1795
  };
1695
1796
  }
1696
1797
  // Multiple matches or low confidence → return candidates, don't delete
1697
- const list = matches.map((m) => `- [${m.id.slice(0, 8)}] ${m.content.slice(0, 60)}${m.content.length > 60 ? '...' : ''}`).join('\n');
1798
+ const list = matches.map((m) => `- [${m.id}] ${m.content.slice(0, 60)}${m.content.length > 60 ? '...' : ''}`).join('\n');
1698
1799
  return {
1699
1800
  success: true,
1700
1801
  data: {
@@ -1945,7 +2046,8 @@ function createToolHandlers(state) {
1945
2046
  return tool.execute(params);
1946
2047
  },
1947
2048
  async context_search(params) {
1948
- const tool = createContextSearchTool({ client: apiClient, logger, config, user_id: getAgentId() });
2049
+ const contextNs = getRecallNamespaces(params);
2050
+ const tool = createContextSearchTool({ client: apiClient, logger, config, user_id: getAgentId(), namespaces: contextNs.length > 0 ? contextNs : undefined });
1949
2051
  return tool.execute(params);
1950
2052
  },
1951
2053
  async contact_search(params) {
@@ -1981,7 +2083,8 @@ function createToolHandlers(state) {
1981
2083
  return { success: false, error: response.error.message };
1982
2084
  }
1983
2085
  const contact = response.data;
1984
- const lines = [`Contact: ${contact.name}`];
2086
+ const contactName = contact.display_name || [contact.given_name, contact.family_name].filter(Boolean).join(' ') || 'Unknown';
2087
+ const lines = [`Contact: ${contactName}`];
1985
2088
  if (contact.email)
1986
2089
  lines.push(`Email: ${contact.email}`);
1987
2090
  if (contact.phone)
@@ -3184,7 +3287,7 @@ function createToolHandlers(state) {
3184
3287
  if (members.length === 0) {
3185
3288
  return { success: true, data: { content: `Namespace **${namespace}** has no members.`, details: response.data } };
3186
3289
  }
3187
- const content = [`**${namespace}** — ${member_count} member(s):`, ...members.map((m) => `- ${m.email} (${m.role}${m.is_default ? ', default' : ''})`)].join('\n');
3290
+ const content = [`**${namespace}** — ${member_count} member(s):`, ...members.map((m) => `- ${m.email} (${m.access}${m.is_home ? ', home' : ''})`)].join('\n');
3188
3291
  return { success: true, data: { content, details: response.data } };
3189
3292
  }
3190
3293
  catch (error) {
@@ -3206,6 +3309,43 @@ function createToolHandlers(state) {
3206
3309
  return { success: false, error: 'Failed to revoke namespace access' };
3207
3310
  }
3208
3311
  },
3312
+ // ── API Onboarding tools (#1784, #1785, #1786) ──────────────────────
3313
+ async api_onboard(params) {
3314
+ const tool = createApiOnboardTool({ client: apiClient, logger, config, user_id: getAgentId() });
3315
+ return tool.execute(params);
3316
+ },
3317
+ async api_recall(params) {
3318
+ const tool = createApiRecallTool({ client: apiClient, logger, config, user_id: getAgentId() });
3319
+ return tool.execute(params);
3320
+ },
3321
+ async api_get(params) {
3322
+ const tool = createApiGetTool({ client: apiClient, logger, config, user_id: getAgentId() });
3323
+ return tool.execute(params);
3324
+ },
3325
+ async api_list(params) {
3326
+ const tool = createApiListTool({ client: apiClient, logger, config, user_id: getAgentId() });
3327
+ return tool.execute(params);
3328
+ },
3329
+ async api_update(params) {
3330
+ const tool = createApiUpdateTool({ client: apiClient, logger, config, user_id: getAgentId() });
3331
+ return tool.execute(params);
3332
+ },
3333
+ async api_credential_manage(params) {
3334
+ const tool = createApiCredentialManageTool({ client: apiClient, logger, config, user_id: getAgentId() });
3335
+ return tool.execute(params);
3336
+ },
3337
+ async api_refresh(params) {
3338
+ const tool = createApiRefreshTool({ client: apiClient, logger, config, user_id: getAgentId() });
3339
+ return tool.execute(params);
3340
+ },
3341
+ async api_remove(params) {
3342
+ const tool = createApiRemoveTool({ client: apiClient, logger, config, user_id: getAgentId() });
3343
+ return tool.execute(params);
3344
+ },
3345
+ async api_restore(params) {
3346
+ const tool = createApiRestoreTool({ client: apiClient, logger, config, user_id: getAgentId() });
3347
+ return tool.execute(params);
3348
+ },
3209
3349
  };
3210
3350
  }
3211
3351
  /**
@@ -3766,6 +3906,88 @@ export const registerOpenClaw = (api) => {
3766
3906
  return toAgentToolResult(result);
3767
3907
  },
3768
3908
  },
3909
+ // ── API Onboarding tools (#1784, #1785, #1786) ──────────────────────
3910
+ {
3911
+ name: 'api_onboard',
3912
+ description: 'Onboard a new API by providing its OpenAPI spec URL or inline content. Parses the spec into searchable memories and optionally stores credentials.',
3913
+ parameters: withNamespace(apiOnboardSchema),
3914
+ execute: async (_toolCallId, params, _signal, _onUpdate) => {
3915
+ const result = await handlers.api_onboard(params);
3916
+ return toAgentToolResult(result);
3917
+ },
3918
+ },
3919
+ {
3920
+ name: 'api_recall',
3921
+ description: 'Search onboarded API memories to find endpoints, operations, and capabilities. Returns operation details including method, path, parameters, and credentials.',
3922
+ parameters: withNamespaces(apiRecallSchema),
3923
+ execute: async (_toolCallId, params, _signal, _onUpdate) => {
3924
+ const result = await handlers.api_recall(params);
3925
+ return toAgentToolResult(result);
3926
+ },
3927
+ },
3928
+ {
3929
+ name: 'api_get',
3930
+ description: 'Get details about a specific onboarded API source including its status, spec version, and tags.',
3931
+ parameters: apiGetSchema,
3932
+ execute: async (_toolCallId, params, _signal, _onUpdate) => {
3933
+ const result = await handlers.api_get(params);
3934
+ return toAgentToolResult(result);
3935
+ },
3936
+ },
3937
+ {
3938
+ name: 'api_list',
3939
+ description: 'List all onboarded API sources. Optionally filter by status (active, error, disabled).',
3940
+ parameters: apiListSchema,
3941
+ execute: async (_toolCallId, params, _signal, _onUpdate) => {
3942
+ const result = await handlers.api_list(params);
3943
+ return toAgentToolResult(result);
3944
+ },
3945
+ },
3946
+ {
3947
+ name: 'api_update',
3948
+ description: 'Update an onboarded API source. Change its name, description, tags, or status.',
3949
+ parameters: apiUpdateSchema,
3950
+ execute: async (_toolCallId, params, _signal, _onUpdate) => {
3951
+ const result = await handlers.api_update(params);
3952
+ return toAgentToolResult(result);
3953
+ },
3954
+ },
3955
+ {
3956
+ name: 'api_credential_manage',
3957
+ description: 'Manage credentials for an onboarded API source: add, update, or remove authentication headers.',
3958
+ parameters: apiCredentialManageSchema,
3959
+ execute: async (_toolCallId, params, _signal, _onUpdate) => {
3960
+ const result = await handlers.api_credential_manage(params);
3961
+ return toAgentToolResult(result);
3962
+ },
3963
+ },
3964
+ {
3965
+ name: 'api_refresh',
3966
+ description: 'Refresh an API source by re-fetching its OpenAPI spec and updating memories. Returns a diff summary.',
3967
+ parameters: apiRefreshSchema,
3968
+ execute: async (_toolCallId, params, _signal, _onUpdate) => {
3969
+ const result = await handlers.api_refresh(params);
3970
+ return toAgentToolResult(result);
3971
+ },
3972
+ },
3973
+ {
3974
+ name: 'api_remove',
3975
+ description: 'Soft-delete an onboarded API source. Can be restored later with api_restore.',
3976
+ parameters: apiRemoveSchema,
3977
+ execute: async (_toolCallId, params, _signal, _onUpdate) => {
3978
+ const result = await handlers.api_remove(params);
3979
+ return toAgentToolResult(result);
3980
+ },
3981
+ },
3982
+ {
3983
+ name: 'api_restore',
3984
+ description: 'Restore a previously soft-deleted API source.',
3985
+ parameters: apiRestoreSchema,
3986
+ execute: async (_toolCallId, params, _signal, _onUpdate) => {
3987
+ const result = await handlers.api_restore(params);
3988
+ return toAgentToolResult(result);
3989
+ },
3990
+ },
3769
3991
  ];
3770
3992
  for (const tool of tools) {
3771
3993
  api.registerTool(tool);