@portel/photon 1.33.0 → 1.33.2

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 (65) hide show
  1. package/README.md +43 -6
  2. package/dist/auth/mcp-jwt.d.ts +59 -0
  3. package/dist/auth/mcp-jwt.d.ts.map +1 -0
  4. package/dist/auth/mcp-jwt.js +177 -0
  5. package/dist/auth/mcp-jwt.js.map +1 -0
  6. package/dist/auto-ui/beam.d.ts +1 -0
  7. package/dist/auto-ui/beam.d.ts.map +1 -1
  8. package/dist/auto-ui/beam.js +35 -1
  9. package/dist/auto-ui/beam.js.map +1 -1
  10. package/dist/auto-ui/frontend/pure-view.html +5 -2
  11. package/dist/auto-ui/playground-html.d.ts.map +1 -1
  12. package/dist/auto-ui/playground-html.js +28 -38
  13. package/dist/auto-ui/playground-html.js.map +1 -1
  14. package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
  15. package/dist/auto-ui/streamable-http-transport.js +62 -11
  16. package/dist/auto-ui/streamable-http-transport.js.map +1 -1
  17. package/dist/beam.bundle.js +25 -17
  18. package/dist/beam.bundle.js.map +2 -2
  19. package/dist/capability-negotiator.d.ts +11 -0
  20. package/dist/capability-negotiator.d.ts.map +1 -1
  21. package/dist/capability-negotiator.js +20 -0
  22. package/dist/capability-negotiator.js.map +1 -1
  23. package/dist/cli/commands/auth.d.ts +15 -0
  24. package/dist/cli/commands/auth.d.ts.map +1 -0
  25. package/dist/cli/commands/auth.js +105 -0
  26. package/dist/cli/commands/auth.js.map +1 -0
  27. package/dist/cli/commands/host.d.ts.map +1 -1
  28. package/dist/cli/commands/host.js +9 -0
  29. package/dist/cli/commands/host.js.map +1 -1
  30. package/dist/cli/commands/run.d.ts.map +1 -1
  31. package/dist/cli/commands/run.js +3 -0
  32. package/dist/cli/commands/run.js.map +1 -1
  33. package/dist/cli/index.d.ts.map +1 -1
  34. package/dist/cli/index.js +6 -0
  35. package/dist/cli/index.js.map +1 -1
  36. package/dist/daemon/worker-dep-proxy.d.ts +17 -0
  37. package/dist/daemon/worker-dep-proxy.d.ts.map +1 -0
  38. package/dist/daemon/worker-dep-proxy.js +92 -0
  39. package/dist/daemon/worker-dep-proxy.js.map +1 -0
  40. package/dist/daemon/worker-host.js +8 -28
  41. package/dist/daemon/worker-host.js.map +1 -1
  42. package/dist/deploy/cloudflare.d.ts +2 -0
  43. package/dist/deploy/cloudflare.d.ts.map +1 -1
  44. package/dist/deploy/cloudflare.js +135 -13
  45. package/dist/deploy/cloudflare.js.map +1 -1
  46. package/dist/editor-support/docblock-tag-catalog.d.ts.map +1 -1
  47. package/dist/editor-support/docblock-tag-catalog.js +6 -0
  48. package/dist/editor-support/docblock-tag-catalog.js.map +1 -1
  49. package/dist/loader.d.ts +3 -0
  50. package/dist/loader.d.ts.map +1 -1
  51. package/dist/loader.js +49 -0
  52. package/dist/loader.js.map +1 -1
  53. package/dist/photon-doc-extractor.d.ts +1 -0
  54. package/dist/photon-doc-extractor.d.ts.map +1 -1
  55. package/dist/photon-doc-extractor.js +13 -0
  56. package/dist/photon-doc-extractor.js.map +1 -1
  57. package/dist/resource-server.d.ts +15 -0
  58. package/dist/resource-server.d.ts.map +1 -1
  59. package/dist/resource-server.js +86 -5
  60. package/dist/resource-server.js.map +1 -1
  61. package/dist/server.d.ts.map +1 -1
  62. package/dist/server.js +168 -176
  63. package/dist/server.js.map +1 -1
  64. package/package.json +1 -1
  65. package/templates/cloudflare/worker.ts.template +340 -55
@@ -148,6 +148,33 @@ function decodeJWTCaller(authHeader) {
148
148
  return undefined;
149
149
  }
150
150
  }
151
+ function isOpenAIAppSession(session) {
152
+ const name = session.clientInfo?.name?.toLowerCase();
153
+ return name === 'chatgpt' || !!name?.includes('openai');
154
+ }
155
+ function namespacedToolName(serverName, methodName) {
156
+ return `${serverName}.${methodName}`;
157
+ }
158
+ function toolNameForSession(session, photonName, methodName) {
159
+ return isOpenAIAppSession(session) ? methodName : namespacedToolName(photonName, methodName);
160
+ }
161
+ function splitNamespacedToolName(name) {
162
+ const dotIndex = name.indexOf('.');
163
+ if (dotIndex !== -1) {
164
+ return {
165
+ serverName: name.slice(0, dotIndex),
166
+ methodName: name.slice(dotIndex + 1),
167
+ };
168
+ }
169
+ const slashIndex = name.indexOf('/');
170
+ if (slashIndex !== -1) {
171
+ return {
172
+ serverName: name.slice(0, slashIndex),
173
+ methodName: name.slice(slashIndex + 1),
174
+ };
175
+ }
176
+ return null;
177
+ }
151
178
  // ════════════════════════════════════════════════════════════════════════════════
152
179
  // SESSION MANAGEMENT
153
180
  // ════════════════════════════════════════════════════════════════════════════════
@@ -1150,7 +1177,7 @@ const handlers = {
1150
1177
  : undefined;
1151
1178
  const meta = buildToolMCPMeta(method, { uiResourceUri });
1152
1179
  tools.push({
1153
- name: `${photon.name}/${method.name}`,
1180
+ name: toolNameForSession(session, photon.name, method.name),
1154
1181
  description: method.description || `Execute ${method.name}`,
1155
1182
  inputSchema: method.params || { type: 'object', properties: {} },
1156
1183
  'x-photon-id': photon.id, // Unique ID (hash of path) for subscriptions
@@ -1186,7 +1213,7 @@ const handlers = {
1186
1213
  if (!photon.configured || !photon.stateful)
1187
1214
  continue;
1188
1215
  tools.push({
1189
- name: `${photon.name}/_use`,
1216
+ name: namespacedToolName(photon.name, '_use'),
1190
1217
  description: `Switch to a named instance of ${photon.name}. Omit name to select interactively.`,
1191
1218
  inputSchema: {
1192
1219
  type: 'object',
@@ -1201,21 +1228,21 @@ const handlers = {
1201
1228
  'x-photon-internal': true,
1202
1229
  });
1203
1230
  tools.push({
1204
- name: `${photon.name}/_instances`,
1231
+ name: namespacedToolName(photon.name, '_instances'),
1205
1232
  description: `List all available instances of ${photon.name}.`,
1206
1233
  inputSchema: { type: 'object', properties: {} },
1207
1234
  'x-photon-id': photon.id,
1208
1235
  'x-photon-internal': true,
1209
1236
  });
1210
1237
  tools.push({
1211
- name: `${photon.name}/_undo`,
1238
+ name: namespacedToolName(photon.name, '_undo'),
1212
1239
  description: `Undo the last state mutation on ${photon.name}. Reverts the most recent change.`,
1213
1240
  inputSchema: { type: 'object', properties: {} },
1214
1241
  'x-photon-id': photon.id,
1215
1242
  'x-photon-internal': true,
1216
1243
  });
1217
1244
  tools.push({
1218
- name: `${photon.name}/_redo`,
1245
+ name: namespacedToolName(photon.name, '_redo'),
1219
1246
  description: `Redo the last undone mutation on ${photon.name}. Re-applies a previously undone change.`,
1220
1247
  inputSchema: { type: 'object', properties: {} },
1221
1248
  'x-photon-id': photon.id,
@@ -1230,7 +1257,7 @@ const handlers = {
1230
1257
  for (const method of mcp.methods) {
1231
1258
  const meta = buildToolMCPMeta(method, { uiResourceUri: method.linkedUi });
1232
1259
  tools.push({
1233
- name: `${mcp.name}/${method.name}`,
1260
+ name: namespacedToolName(mcp.name, method.name),
1234
1261
  description: method.description || `Execute ${method.name}`,
1235
1262
  inputSchema: method.params || { type: 'object', properties: {} },
1236
1263
  'x-external-mcp': true, // Marker for frontend to identify external MCPs
@@ -1542,9 +1569,31 @@ const handlers = {
1542
1569
  if (name === 'beam/studio-parse') {
1543
1570
  return handleBeamStudioParse(req, args || {});
1544
1571
  }
1545
- // Parse tool name: server-name/method-name or namespace:server-name/method-name
1546
- const slashIndex = name.indexOf('/');
1547
- if (slashIndex === -1) {
1572
+ // Parse tool name: server-name.method-name.
1573
+ // ChatGPT/OpenAI app sessions receive slashless names in tools/list because
1574
+ // their connector layer treats slash-qualified names as app resource paths.
1575
+ let serverName;
1576
+ let methodName;
1577
+ const namespacedName = splitNamespacedToolName(name);
1578
+ if (!namespacedName && isOpenAIAppSession(session)) {
1579
+ const matches = ctx.photons.filter((photon) => photon.configured && photon.methods?.some((method) => method.name === name));
1580
+ if (matches.length === 1) {
1581
+ const photon = matches[0];
1582
+ serverName = photon.name;
1583
+ methodName = name;
1584
+ }
1585
+ else {
1586
+ return {
1587
+ jsonrpc: '2.0',
1588
+ id: req.id,
1589
+ result: {
1590
+ content: [{ type: 'text', text: `Invalid tool name: ${name}` }],
1591
+ isError: true,
1592
+ },
1593
+ };
1594
+ }
1595
+ }
1596
+ else if (!namespacedName) {
1548
1597
  return {
1549
1598
  jsonrpc: '2.0',
1550
1599
  id: req.id,
@@ -1554,8 +1603,10 @@ const handlers = {
1554
1603
  },
1555
1604
  };
1556
1605
  }
1557
- const serverName = name.slice(0, slashIndex);
1558
- const methodName = name.slice(slashIndex + 1);
1606
+ else {
1607
+ serverName = namespacedName.serverName;
1608
+ methodName = namespacedName.methodName;
1609
+ }
1559
1610
  // Per-photon auth check: if this photon requires auth but caller is anonymous, reject
1560
1611
  const targetPhoton = ctx.photons.find((p) => p.name === serverName);
1561
1612
  // Claim-code scope enforcement: filtering tools/list alone is not a