mppx 0.2.6 → 0.3.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.
@@ -1 +1 @@
1
- {"version":3,"file":"Proxy.d.ts","sourceRoot":"","sources":["../../src/proxy/Proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAA;AAKtC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC,kFAAkF;AAClF,MAAM,MAAM,KAAK,GAAG;IAClB,sFAAsF;IACtF,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC9C,uFAAuF;IACvF,QAAQ,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI,CAAA;CACxE,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CAsFnD;AAED,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC;IAC9B,KAAY,MAAM,GAAG;QACnB,sEAAsE;QACtE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC7B,0DAA0D;QAC1D,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAChC,qEAAqE;QACrE,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,GAAG,SAAS,CAAA;QAC3C,qEAAqE;QACrE,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,CAAA;QAC3B,8DAA8D;QAC9D,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC3B,CAAA;CACF"}
1
+ {"version":3,"file":"Proxy.d.ts","sourceRoot":"","sources":["../../src/proxy/Proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAA;AAKtC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC,kFAAkF;AAClF,MAAM,MAAM,KAAK,GAAG;IAClB,sFAAsF;IACtF,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC9C,uFAAuF;IACvF,QAAQ,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI,CAAA;CACxE,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CA6HnD;AAED,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC;IAC9B,KAAY,MAAM,GAAG;QACnB,sEAAsE;QACtE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC7B,0DAA0D;QAC1D,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAChC,qEAAqE;QACrE,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,GAAG,SAAS,CAAA;QAC3C,qEAAqE;QACrE,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,CAAA;QAC3B,8DAA8D;QAC9D,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC3B,CAAA;CACF"}
@@ -48,17 +48,44 @@ export function create(config) {
48
48
  return new Response(Service.toLlmsTxt(config.services, {
49
49
  title: config.title,
50
50
  description: config.description,
51
- }), {
52
- headers: { 'Content-Type': 'text/plain; charset=utf-8' },
53
- });
54
- if (request.method === 'GET' && (pathname === '/services' || pathname === '/services/'))
51
+ }), { headers: { 'Content-Type': 'text/plain; charset=utf-8' } });
52
+ if (request.method === 'GET' && pathname === '/discover.md')
53
+ return new Response(Service.toLlmsTxt(config.services, {
54
+ title: config.title,
55
+ description: config.description,
56
+ }), { headers: { 'Content-Type': 'text/plain; charset=utf-8' } });
57
+ if (request.method === 'GET' && (pathname === '/discover' || pathname === '/discover/')) {
58
+ if (wantsMarkdown(request))
59
+ return new Response(Service.toLlmsTxt(config.services, {
60
+ title: config.title,
61
+ description: config.description,
62
+ }), { headers: { 'Content-Type': 'text/plain; charset=utf-8' } });
55
63
  return Response.json(config.services.map(Service.serialize));
64
+ }
65
+ if (request.method === 'GET' &&
66
+ (pathname === '/discover/all' || pathname === '/discover/all/')) {
67
+ if (wantsMarkdown(request))
68
+ return new Response(Service.toServicesMarkdown(config.services), {
69
+ headers: { 'Content-Type': 'text/markdown; charset=utf-8' },
70
+ });
71
+ return Response.json(config.services.map(Service.serialize));
72
+ }
73
+ if (request.method === 'GET' && pathname === '/discover/all.md')
74
+ return new Response(Service.toServicesMarkdown(config.services), {
75
+ headers: { 'Content-Type': 'text/markdown; charset=utf-8' },
76
+ });
56
77
  {
57
- const match = pathname.match(/^\/services\/([^/]+)\/?$/);
78
+ // List service
79
+ const match = pathname.match(/^\/discover\/([^/]+)\.md$/) ?? pathname.match(/^\/discover\/([^/]+)\/?$/);
58
80
  if (request.method === 'GET' && match) {
59
81
  const service = config.services.find((s) => s.id === match[1]);
60
82
  if (!service)
61
83
  return new Response('Not Found', { status: 404 });
84
+ const wantsText = pathname.endsWith('.md') || wantsMarkdown(request);
85
+ if (wantsText)
86
+ return new Response(Service.toMarkdown(service), {
87
+ headers: { 'Content-Type': 'text/markdown; charset=utf-8' },
88
+ });
62
89
  return Response.json(Service.serialize(service));
63
90
  }
64
91
  }
@@ -126,4 +153,43 @@ async function proxyUpstream(options) {
126
153
  upstreamRes = await service.rewriteResponse(upstreamRes, ctx);
127
154
  return upstreamRes;
128
155
  }
156
+ const aiUserAgents = [
157
+ 'GPTBot',
158
+ 'OAI-SearchBot',
159
+ 'ChatGPT-User',
160
+ 'anthropic-ai',
161
+ 'ClaudeBot',
162
+ 'claude-web',
163
+ 'PerplexityBot',
164
+ 'Perplexity-User',
165
+ 'Google-Extended',
166
+ 'Googlebot',
167
+ 'Bingbot',
168
+ 'Amazonbot',
169
+ 'Applebot',
170
+ 'Applebot-Extended',
171
+ 'FacebookBot',
172
+ 'meta-externalagent',
173
+ 'Bytespider',
174
+ 'DuckAssistBot',
175
+ 'cohere-ai',
176
+ 'AI2Bot',
177
+ 'CCBot',
178
+ 'Diffbot',
179
+ 'YouBot',
180
+ 'MistralAI-User',
181
+ 'GoogleAgent-Mariner',
182
+ ];
183
+ const terminalUserAgents = ['curl', 'Wget', 'HTTPie', 'httpie-go', 'mppx', 'presto', 'xh'];
184
+ function wantsMarkdown(request) {
185
+ const accept = request.headers.get('accept');
186
+ if (accept && (accept.includes('text/markdown') || accept.includes('text/plain')))
187
+ return true;
188
+ const ua = request.headers.get('user-agent') ?? '';
189
+ if (aiUserAgents.some((agent) => ua.includes(agent)))
190
+ return true;
191
+ if (terminalUserAgents.some((agent) => ua.includes(agent)))
192
+ return true;
193
+ return false;
194
+ }
129
195
  //# sourceMappingURL=Proxy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Proxy.js","sourceRoot":"","sources":["../../src/proxy/Proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Proxy.js","sourceRoot":"","sources":["../../src/proxy/Proxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAA;AAC/C,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAA;AAChD,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAA;AAC5C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAUvC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,MAAM,CAAC,MAAqB;IAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAA;IAElD,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACxB,MAAM,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE;YACxC,KAAK,EAAE,SAAS;YAChB,mBAAmB,EAAE,KAAK;YAC1B,iBAAiB,EAAE,KAAK;SACzB,CAAC,CAAA;QACF,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAU,CAAA;IAC/C,CAAC,CAAC,CACH,CAAA;IAED,KAAK,UAAU,MAAM,CAAC,OAA2B;QAC/C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAEhC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;QAErD,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QAEhE,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,QAAQ,KAAK,WAAW;YACtD,OAAO,IAAI,QAAQ,CACjB,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE;gBACjC,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;aAChC,CAAC,EACF,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,EAAE,CAC7D,CAAA;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,QAAQ,KAAK,cAAc;YACzD,OAAO,IAAI,QAAQ,CACjB,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE;gBACjC,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;aAChC,CAAC,EACF,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,EAAE,CAC7D,CAAA;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,YAAY,CAAC,EAAE,CAAC;YACxF,IAAI,aAAa,CAAC,OAAO,CAAC;gBACxB,OAAO,IAAI,QAAQ,CACjB,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE;oBACjC,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;iBAChC,CAAC,EACF,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,EAAE,CAC7D,CAAA;YACH,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;QAC9D,CAAC;QAED,IACE,OAAO,CAAC,MAAM,KAAK,KAAK;YACxB,CAAC,QAAQ,KAAK,eAAe,IAAI,QAAQ,KAAK,gBAAgB,CAAC,EAC/D,CAAC;YACD,IAAI,aAAa,CAAC,OAAO,CAAC;gBACxB,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;oBAC/D,OAAO,EAAE,EAAE,cAAc,EAAE,8BAA8B,EAAE;iBAC5D,CAAC,CAAA;YACJ,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;QAC9D,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,QAAQ,KAAK,kBAAkB;YAC7D,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;gBAC/D,OAAO,EAAE,EAAE,cAAc,EAAE,8BAA8B,EAAE;aAC5D,CAAC,CAAA;QAEJ,CAAC;YACC,eAAe;YACf,MAAM,KAAK,GACT,QAAQ,CAAC,KAAK,CAAC,2BAA2B,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;YAC3F,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,KAAK,EAAE,CAAC;gBACtC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;gBAC9D,IAAI,CAAC,OAAO;oBAAE,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;gBAC/D,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,CAAA;gBACpE,IAAI,SAAS;oBACX,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;wBAC/C,OAAO,EAAE,EAAE,cAAc,EAAE,8BAA8B,EAAE;qBAC5D,CAAC,CAAA;gBACJ,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;YAClD,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QACpC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QAE9D,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,CAAA;QAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACrC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QAE7D,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;QAEhC,MAAM,OAAO,GACX,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC;YACzD,sEAAsE;YACtE,qEAAqE;YACrE,oEAAoE;YACpE,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;gBAChE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC;gBAC/C,CAAC,CAAC,IAAI,CAAC,CAAA;QACX,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QAE/D,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAyB,CAAA;QAClD,MAAM,GAAG,GAAoB,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAA;QAE/D,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,aAAa,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAA;QAE7E,MAAM,OAAO,GAAG,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAA;QACxE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;QACrC,IAAI,MAAM,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,MAAM,CAAC,SAAS,CAAA;QAElD,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;QAC5C,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC;YACtC,OAAO;YACP,OAAO;YACP,GAAG,EAAE,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE;YAC3B,KAAK;SACN,CAAC,CAAA;QACF,OAAO,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAA;IACxC,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC;KACzC,CAAA;AACH,CAAC;AA0BD,gBAAgB;AAChB,KAAK,UAAU,aAAa,CAAC,OAA8B;IACzD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;IAChD,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAA;IAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAE9C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAA;IAC3C,MAAM,OAAO,GAAG,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,CAAA;IAErD,MAAM,IAAI,GAAsC;QAC9C,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO;QACP,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAA;IAED,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,IAAI,WAAW,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAA;IAE7F,IAAI,OAAO,CAAC,cAAc;QAAE,WAAW,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,WAAW,EAAE,GAAG,CAAC,CAAA;IAExF,IAAI,WAAW,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,CAAA;IAE1C,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAA;IAEhD,IAAI,OAAO,CAAC,eAAe;QAAE,WAAW,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,WAAW,EAAE,GAAG,CAAC,CAAA;IAE1F,OAAO,WAAW,CAAA;AACpB,CAAC;AAED,MAAM,YAAY,GAAG;IACnB,QAAQ;IACR,eAAe;IACf,cAAc;IACd,cAAc;IACd,WAAW;IACX,YAAY;IACZ,eAAe;IACf,iBAAiB;IACjB,iBAAiB;IACjB,WAAW;IACX,SAAS;IACT,WAAW;IACX,UAAU;IACV,mBAAmB;IACnB,aAAa;IACb,oBAAoB;IACpB,YAAY;IACZ,eAAe;IACf,WAAW;IACX,QAAQ;IACR,OAAO;IACP,SAAS;IACT,QAAQ;IACR,gBAAgB;IAChB,qBAAqB;CACtB,CAAA;AAED,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;AAE1F,SAAS,aAAa,CAAC,OAA2B;IAChD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC5C,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAC9F,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAA;IAClD,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IACjE,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IACvE,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -100,7 +100,6 @@ export declare namespace from {
100
100
  export { from as custom };
101
101
  /** Serializes a service for discovery responses. */
102
102
  export declare function serialize(s: Service): {
103
- baseUrl: string;
104
103
  description: string | undefined;
105
104
  id: string;
106
105
  docsLlmsUrl: string | undefined;
@@ -118,6 +117,10 @@ export declare function toLlmsTxt(services: Service[], options?: {
118
117
  title?: string | undefined;
119
118
  description?: string | undefined;
120
119
  }): string;
120
+ /** Renders a full markdown listing of all services with their routes. */
121
+ export declare function toServicesMarkdown(services: Service[]): string;
122
+ /** Renders a markdown string for a single service. */
123
+ export declare function toMarkdown(s: Service): string;
121
124
  /** Extracts per-endpoint options from an endpoint definition. */
122
125
  export declare function getOptions(endpoint: Endpoint): EndpointOptions | undefined;
123
126
  //# sourceMappingURL=Service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Service.d.ts","sourceRoot":"","sources":["../../src/proxy/Service.ts"],"names":[],"mappings":"AAEA,6FAA6F;AAC7F,MAAM,MAAM,OAAO,GAAG;IACpB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAA;IACf,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,gFAAgF;IAChF,EAAE,EAAE,MAAM,CAAA;IACV,gIAAgI;IAChI,WAAW,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,KAAK,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;IAC3F,qFAAqF;IACrF,cAAc,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAA;IACzF,2EAA2E;IAC3E,eAAe,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,SAAS,CAAA;IAC7F,kDAAkD;IAClD,MAAM,EAAE,WAAW,CAAA;IACnB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3B,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG;IAAE,GAAG,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAAG,IAAI,CAAA;AAE9F,+DAA+D;AAC/D,MAAM,MAAM,WAAW,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,GACzF,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAA;AAE/B,0EAA0E;AAC1E,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAED,mEAAmE;AACnE,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;AAErE,6FAA6F;AAC7F,MAAM,MAAM,YAAY,GACpB;IAAE,SAAS,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GACpC;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,KAAK,QAAQ,CAAA;CAAE,CAAA;AAE5E,sGAAsG;AACtG,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;CACrB,GAAG,eAAe,CAAA;AAEnB,MAAM,MAAM,IAAI,CACd,OAAO,SAAS;IACd,MAAM,EAAE,MAAM,CAAA;CACf,IACC;IACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;CACvC,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;AAE3B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAkBzF;AAED,MAAM,CAAC,OAAO,WAAW,IAAI,CAAC;IAC5B,KAAY,MAAM,CAAC,OAAO,GAAG,OAAO,IAAI;QACtC,wCAAwC;QACxC,OAAO,EAAE,MAAM,CAAA;QACf,gEAAgE;QAChE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC3B,wCAAwC;QACxC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAChC,wCAAwC;QACxC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;QAC5C,6HAA6H;QAC7H,WAAW,CAAC,EACR,MAAM,GACN,CAAC,CAAC,OAAO,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE,KAAK,MAAM,GAAG,SAAS,CAAC,GACjE,SAAS,CAAA;QACb,yFAAyF;QACzF,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAA;QACnE,0FAA0F;QAC1F,cAAc,CAAC,EACX,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GACpF,SAAS,CAAA;QACb,qDAAqD;QACrD,MAAM,EAAE,WAAW,CAAA;QACnB,4CAA4C;QAC5C,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC3B,CAAA;CACF;AAED,OAAO,EAAE,IAAI,IAAI,MAAM,EAAE,CAAA;AAiCzB,oDAAoD;AACpD,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;EAmBnC;AAED,kEAAkE;AAClE,wBAAgB,SAAS,CACvB,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACzE,MAAM,CAqDR;AAED,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,eAAe,GAAG,SAAS,CAI1E"}
1
+ {"version":3,"file":"Service.d.ts","sourceRoot":"","sources":["../../src/proxy/Service.ts"],"names":[],"mappings":"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"}
@@ -66,18 +66,18 @@ function resolveRewriteRequest(config) {
66
66
  /** Serializes a service for discovery responses. */
67
67
  export function serialize(s) {
68
68
  return {
69
- baseUrl: s.baseUrl,
70
69
  description: s.description,
71
70
  id: s.id,
72
71
  docsLlmsUrl: s.docsLlmsUrl?.({}),
73
72
  routes: Object.entries(s.routes).map(([pattern, endpoint]) => {
74
73
  const tokens = pattern.trim().split(/\s+/);
75
74
  const hasMethod = tokens.length >= 2;
75
+ const path = hasMethod ? tokens.slice(1).join(' ') : tokens[0];
76
76
  return {
77
77
  docsLlmsUrl: s.docsLlmsUrl?.({ route: pattern }),
78
78
  method: hasMethod ? tokens[0] : undefined,
79
- path: hasMethod ? tokens.slice(1).join(' ') : tokens[0],
80
- pattern,
79
+ path: `/${s.id}${path}`,
80
+ pattern: hasMethod ? `${tokens[0]} /${s.id}${path}` : `/${s.id}${path}`,
81
81
  payment: endpoint ? resolvePayment(endpoint) : null,
82
82
  };
83
83
  }),
@@ -91,56 +91,71 @@ export function toLlmsTxt(services, options) {
91
91
  '',
92
92
  `> ${options?.description ?? 'Paid API proxy powered by [Machine Payments Protocol](https://mpp.tempo.xyz).'}`,
93
93
  '',
94
- 'For machine-readable service data, use `GET /services` (JSON).',
95
- '',
96
94
  ];
97
95
  if (services.length === 0)
98
96
  return lines.join('\n');
99
97
  lines.push('## Services', '');
100
98
  for (const s of services) {
101
- const serialized = serialize(s);
102
- const free = serialized.routes.filter((r) => r.payment === null).length;
103
- const paid = serialized.routes.length - free;
104
- const parts = [paid && `${paid} paid`, free && `${free} free`].filter(Boolean).join(', ');
105
99
  const label = s.title ?? s.id;
106
- const desc = s.description ? `: ${s.description} (${parts})` : `: ${parts}`;
107
- lines.push(`- [${label}](${s.baseUrl})${desc}`);
100
+ const desc = s.description ? `: ${s.description}` : '';
101
+ lines.push(`- [${label}](/discover/${s.id}.md)${desc}`);
108
102
  }
103
+ lines.push('', '[See all service definitions](/discover/all.md)');
104
+ return lines.join('\n');
105
+ }
106
+ /** Renders a full markdown listing of all services with their routes. */
107
+ export function toServicesMarkdown(services) {
108
+ const lines = ['# Services', ''];
109
+ if (services.length === 0)
110
+ return lines.join('\n');
109
111
  for (const s of services) {
110
- const serialized = serialize(s);
111
- const docsLlmsUrl = s.docsLlmsUrl?.({});
112
- lines.push('', `## ${s.title ?? s.id}`, '');
112
+ lines.push(`## [${s.title ?? s.id}](/discover/${s.id}.md)`, '');
113
113
  if (s.description)
114
114
  lines.push(s.description, '');
115
- if (docsLlmsUrl)
116
- lines.push(`Documentation: ${docsLlmsUrl}`, '');
117
- for (const route of serialized.routes) {
118
- const p = route.payment;
119
- const desc = p?.description ? ` - ${p.description}` : '';
120
- lines.push(`- \`${route.pattern}\`${desc}`);
121
- if (!p) {
122
- lines.push(` - Type: free`);
123
- }
124
- else {
125
- lines.push(` - Type: ${p.intent}`);
126
- if (p.amount) {
127
- const perUnit = p.unitType ? `/${p.unitType}` : '';
128
- if (p.decimals !== undefined) {
129
- const price = Number(p.amount) / 10 ** Number(p.decimals);
130
- lines.push(` - Price: ${price}${perUnit} (${p.amount} units, ${p.decimals} decimals)`);
131
- }
132
- else {
133
- lines.push(` - Units: ${p.amount}${perUnit}`);
134
- }
115
+ pushRoutes(lines, s);
116
+ }
117
+ return lines.join('\n');
118
+ }
119
+ /** Renders a markdown string for a single service. */
120
+ export function toMarkdown(s) {
121
+ const docsLlmsUrl = s.docsLlmsUrl?.({});
122
+ const lines = [`# ${s.title ?? s.id}`, ''];
123
+ if (docsLlmsUrl)
124
+ lines.push(`> Documentation: ${docsLlmsUrl}`, '');
125
+ if (s.description)
126
+ lines.push(s.description, '');
127
+ pushRoutes(lines, s, '##');
128
+ return lines.join('\n');
129
+ }
130
+ function pushRoutes(lines, s, heading = '###') {
131
+ lines.push(`${heading} Routes`, '');
132
+ const serialized = serialize(s);
133
+ for (const route of serialized.routes) {
134
+ const p = route.payment;
135
+ const desc = p?.description ? `: ${p.description}` : '';
136
+ lines.push(`- \`${route.pattern}\`${desc}`);
137
+ if (!p) {
138
+ lines.push(' - Type: free');
139
+ }
140
+ else {
141
+ lines.push(` - Type: ${p.intent}`);
142
+ if (p.amount) {
143
+ const perUnit = p.unitType ? `/${p.unitType}` : '';
144
+ if (p.decimals !== undefined) {
145
+ const price = Number(p.amount) / 10 ** Number(p.decimals);
146
+ lines.push(` - Price: ${price}${perUnit} (${p.amount} units, ${p.decimals} decimals)`);
147
+ }
148
+ else {
149
+ lines.push(` - Units: ${p.amount}${perUnit}`);
135
150
  }
136
- if (p.currency)
137
- lines.push(` - Currency: ${p.currency}`);
138
151
  }
139
- if (route.docsLlmsUrl)
140
- lines.push(` - Docs: ${route.docsLlmsUrl}`);
152
+ if (p.currency)
153
+ lines.push(` - Currency: ${p.currency}`);
141
154
  }
155
+ if (route.docsLlmsUrl)
156
+ lines.push(` - Docs: ${route.docsLlmsUrl}`);
157
+ lines.push('');
142
158
  }
143
- return lines.join('\n');
144
159
  }
145
160
  /** Extracts per-endpoint options from an endpoint definition. */
146
161
  export function getOptions(endpoint) {
@@ -1 +1 @@
1
- {"version":3,"file":"Service.js","sourceRoot":"","sources":["../../src/proxy/Service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,CAAA;AA+D1B;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,IAAI,CAAoB,EAAU,EAAE,MAA4B;IAC9E,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAA;IACvD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,EAAE;QACF,WAAW,EAAE,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC;QAC/C,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,cAAc,EAAE,MAAM,CAAC,cAAc;YACnC,CAAC,CAAC,iBAAiB;gBACjB,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;oBACjB,GAAG,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;oBACvC,OAAQ,MAAM,CAAC,cAA6C,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;gBACxE,CAAC;gBACH,CAAC,CAAE,MAAM,CAAC,cAA4C;YACxD,CAAC,CAAC,iBAAiB;KACtB,CAAA;AACH,CAAC;AA8BD,OAAO,EAAE,IAAI,IAAI,MAAM,EAAE,CAAA;AAEzB,SAAS,qBAAqB,CAC5B,MAAmB;IAEnB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;QAC5B,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAClB,MAAM,OAAO,GAAG,GAA2B,CAAA;YAC3C,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAA;YAClC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAA;QACf,CAAC,CAAA;IACH,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;QAC5B,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAClB,MAAM,OAAO,GAAG,GAA2B,CAAA;YAC3C,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,OAAO,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC,CAAA;YACtE,OAAO,GAAG,CAAA;QACZ,CAAC,CAAA;IACH,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;QAC9B,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAClB,MAAM,OAAO,GAAG,GAA2B,CAAA;YAC3C,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAA;YACpC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;gBAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YAC3E,OAAO,GAAG,CAAA;QACZ,CAAC,CAAA;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,SAAS,CAAC,CAAU;IAClC,OAAO;QACL,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QAChC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE;YAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAA;YACpC,OAAO;gBACL,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;gBAChD,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;gBACzC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACvD,OAAO;gBACP,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI;aACpD,CAAA;QACH,CAAC,CAAC;QACF,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAA;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,SAAS,CACvB,QAAmB,EACnB,OAA0E;IAE1E,MAAM,KAAK,GAAa;QACtB,KAAK,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE;QACpC,EAAE;QACF,KAAK,OAAO,EAAE,WAAW,IAAI,+EAA+E,EAAE;QAC9G,EAAE;QACF,gEAAgE;QAChE,EAAE;KACH,CAAA;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAElD,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;IAC7B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;QAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,MAAM,CAAA;QACvE,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAA;QAC5C,MAAM,KAAK,GAAG,CAAC,IAAI,IAAI,GAAG,IAAI,OAAO,EAAE,IAAI,IAAI,GAAG,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzF,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAA;QAC7B,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAA;QAC3E,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC,CAAA;IACjD,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;QAC/B,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;QACvC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAC3C,IAAI,CAAC,CAAC,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QAChD,IAAI,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,WAAW,EAAE,EAAE,EAAE,CAAC,CAAA;QAChE,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACtC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAyC,CAAA;YACzD,MAAM,IAAI,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;YACxD,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC,CAAA;YAC3C,IAAI,CAAC,CAAC,EAAE,CAAC;gBACP,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;YAC9B,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,EAAE,CAAC,CAAA;gBACnC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;oBACb,MAAM,OAAO,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;oBAClD,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;wBAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;wBACzD,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,GAAG,OAAO,KAAK,CAAC,CAAC,MAAM,WAAW,CAAC,CAAC,QAAQ,YAAY,CAAC,CAAA;oBACzF,CAAC;yBAAM,CAAC;wBACN,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,OAAO,EAAE,CAAC,CAAA;oBAChD,CAAC;gBACH,CAAC;gBACD,IAAI,CAAC,CAAC,QAAQ;oBAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;YAC3D,CAAC;YACD,IAAI,KAAK,CAAC,WAAW;gBAAE,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;QACrE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,UAAU,CAAC,QAAkB;IAC3C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,SAAS,IAAI,QAAQ;QAC5E,OAAO,QAAQ,CAAC,OAAO,CAAA;IACzB,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,cAAc,CAAC,QAAkB;IACxC,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAClC,MAAM,OAAO,GAAG,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAA;IACxE,IAAI,CAAC,CAAC,WAAW,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,CAAA;IACxC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC,SAAoC,CAAA;IAChG,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE;QACnB,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ;YACtE,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;QACvD,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC,CAAC,EAAE,CAAA;IACJ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAA;AACnF,CAAC;AAED,SAAS,cAAc,CACrB,KAA6F;IAE7F,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAC5B,IAAI,OAAO,KAAK,KAAK,UAAU;QAAE,OAAO,KAAK,CAAA;IAC7C,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;AACnD,CAAC"}
1
+ {"version":3,"file":"Service.js","sourceRoot":"","sources":["../../src/proxy/Service.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,7 @@ export function openai(config) {
22
22
  description: 'Chat completions, embeddings, image generation, and audio transcription.',
23
23
  docsLlmsUrl: ({ route }) => route
24
24
  ? `https://context7.com/websites/platform_openai/llms.txt?topic=${encodeURIComponent(route)}`
25
- : undefined,
25
+ : 'https://context7.com/websites/platform_openai/llms.txt',
26
26
  rewriteRequest(request, ctx) {
27
27
  const apiKey = ctx.apiKey ?? config.apiKey;
28
28
  request.headers.set('Authorization', `Bearer ${apiKey}`);
@@ -1 +1 @@
1
- {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/proxy/services/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AAExC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,MAAM,CAAC,MAAqB;IAC1C,OAAO,OAAO,CAAC,IAAI,CAAgB,QAAQ,EAAE;QAC3C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,wBAAwB;QACnD,WAAW,EAAE,0EAA0E;QACvF,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CACzB,KAAK;YACH,CAAC,CAAC,gEAAgE,kBAAkB,CAAC,KAAK,CAAC,EAAE;YAC7F,CAAC,CAAC,SAAS;QACf,cAAc,CAAC,OAAO,EAAE,GAAG;YACzB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAA;YAC1C,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,MAAM,EAAE,CAAC,CAAA;YACxD,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/proxy/services/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AAExC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,MAAM,CAAC,MAAqB;IAC1C,OAAO,OAAO,CAAC,IAAI,CAAgB,QAAQ,EAAE;QAC3C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,wBAAwB;QACnD,WAAW,EAAE,0EAA0E;QACvF,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CACzB,KAAK;YACH,CAAC,CAAC,gEAAgE,kBAAkB,CAAC,KAAK,CAAC,EAAE;YAC7F,CAAC,CAAC,wDAAwD;QAC9D,cAAc,CAAC,OAAO,EAAE,GAAG;YACzB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAA;YAC1C,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,MAAM,EAAE,CAAC,CAAA;YACxD,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAA;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mppx",
3
3
  "type": "module",
4
- "version": "0.2.6",
4
+ "version": "0.3.2",
5
5
  "main": "./dist/index.js",
6
6
  "license": "MIT",
7
7
  "files": [
@@ -61,7 +61,7 @@ function createUpstream(handler: (req: Request) => Response | Promise<Response>)
61
61
  }
62
62
 
63
63
  describe('create', () => {
64
- test('behavior: GET /services returns service discovery', async () => {
64
+ test('behavior: GET /discover/all returns service discovery JSON', async () => {
65
65
  const proxy = ApiProxy.create({
66
66
  services: [
67
67
  Service.from('api', {
@@ -80,24 +80,23 @@ describe('create', () => {
80
80
  })
81
81
  proxyServer = await Http.createServer(proxy.listener)
82
82
 
83
- const res = await fetch(`${proxyServer.url}/services`)
83
+ const res = await fetch(`${proxyServer.url}/discover/all`)
84
84
  expect(res.status).toBe(200)
85
85
  expect(await res.json()).toMatchInlineSnapshot(`
86
86
  [
87
87
  {
88
- "baseUrl": "https://api.example.com",
89
88
  "id": "api",
90
89
  "routes": [
91
90
  {
92
91
  "method": "GET",
93
- "path": "/v1/models",
94
- "pattern": "GET /v1/models",
92
+ "path": "/api/v1/models",
93
+ "pattern": "GET /api/v1/models",
95
94
  "payment": null,
96
95
  },
97
96
  {
98
97
  "method": "POST",
99
- "path": "/v1/generate",
100
- "pattern": "POST /v1/generate",
98
+ "path": "/api/v1/generate",
99
+ "pattern": "POST /api/v1/generate",
101
100
  "payment": {
102
101
  "amount": "1000000",
103
102
  "currency": "0x20c0000000000000000000000000000000000001",
@@ -110,8 +109,8 @@ describe('create', () => {
110
109
  },
111
110
  {
112
111
  "method": "POST",
113
- "path": "/v1/stream",
114
- "pattern": "POST /v1/stream",
112
+ "path": "/api/v1/stream",
113
+ "pattern": "POST /api/v1/stream",
115
114
  "payment": {
116
115
  "amount": "1000000",
117
116
  "currency": "0x20c0000000000000000000000000000000000001",
@@ -129,7 +128,25 @@ describe('create', () => {
129
128
  `)
130
129
  })
131
130
 
132
- test('behavior: GET /llms.txt returns markdown', async () => {
131
+ test('behavior: GET /discover returns JSON by default', async () => {
132
+ const proxy = ApiProxy.create({
133
+ services: [
134
+ Service.from('api', {
135
+ baseUrl: 'https://api.example.com',
136
+ routes: {
137
+ 'GET /v1/models': true,
138
+ },
139
+ }),
140
+ ],
141
+ })
142
+ proxyServer = await Http.createServer(proxy.listener)
143
+
144
+ const res = await fetch(`${proxyServer.url}/discover`)
145
+ expect(res.status).toBe(200)
146
+ expect(res.headers.get('content-type')).toMatchInlineSnapshot(`"application/json"`)
147
+ })
148
+
149
+ test('behavior: GET /discover returns llms.txt for markdown clients', async () => {
133
150
  const proxy = ApiProxy.create({
134
151
  title: 'My AI Gateway',
135
152
  description: 'A paid proxy for LLM and AI services.',
@@ -165,7 +182,9 @@ describe('create', () => {
165
182
  })
166
183
  proxyServer = await Http.createServer(proxy.listener)
167
184
 
168
- const res = await fetch(`${proxyServer.url}/llms.txt`)
185
+ const res = await fetch(`${proxyServer.url}/discover`, {
186
+ headers: { Accept: 'text/plain' },
187
+ })
169
188
  expect(res.status).toBe(200)
170
189
  expect(res.headers.get('content-type')).toBe('text/plain; charset=utf-8')
171
190
  expect(await res.text()).toMatchInlineSnapshot(`
@@ -173,44 +192,16 @@ describe('create', () => {
173
192
 
174
193
  > A paid proxy for LLM and AI services.
175
194
 
176
- For machine-readable service data, use \`GET /services\` (JSON).
177
-
178
195
  ## Services
179
196
 
180
- - [OpenAI](https://api.openai.com): Chat completions, embeddings, image generation, and audio transcription. (2 paid)
181
- - [Anthropic](https://api.anthropic.com): Claude language models for messages and completions. (2 paid)
182
-
183
- ## OpenAI
184
-
185
- Chat completions, embeddings, image generation, and audio transcription.
186
-
187
- - \`POST /v1/chat/completions\` - Chat completion
188
- - Type: charge
189
- - Price: 0.05 (50000 units, 6 decimals)
190
- - Currency: 0x20c0000000000000000000000000000000000001
191
- - Docs: https://context7.com/websites/platform_openai/llms.txt?topic=POST%20%2Fv1%2Fchat%2Fcompletions
192
- - \`POST /v1/embeddings\` - Generate embeddings
193
- - Type: charge
194
- - Price: 0.01 (10000 units, 6 decimals)
195
- - Currency: 0x20c0000000000000000000000000000000000001
196
- - Docs: https://context7.com/websites/platform_openai/llms.txt?topic=POST%20%2Fv1%2Fembeddings
197
-
198
- ## Anthropic
199
-
200
- Claude language models for messages and completions.
197
+ - [OpenAI](/discover/openai.md): Chat completions, embeddings, image generation, and audio transcription.
198
+ - [Anthropic](/discover/anthropic.md): Claude language models for messages and completions.
201
199
 
202
- - \`POST /v1/messages\` - Send message
203
- - Type: charge
204
- - Price: 0.03 (30000 units, 6 decimals)
205
- - Currency: 0x20c0000000000000000000000000000000000001
206
- - \`POST /v1/messages/stream\` - Stream message
207
- - Type: session
208
- - Price: 0.01/token (10000 units, 6 decimals)
209
- - Currency: 0x20c0000000000000000000000000000000000001"
200
+ [See all service definitions](/discover/all.md)"
210
201
  `)
211
202
  })
212
203
 
213
- test('behavior: GET /services/:id returns single service', async () => {
204
+ test('behavior: GET /discover/:id returns single service', async () => {
214
205
  const proxy = ApiProxy.create({
215
206
  services: [
216
207
  Service.from('api', {
@@ -224,23 +215,22 @@ describe('create', () => {
224
215
  })
225
216
  proxyServer = await Http.createServer(proxy.listener)
226
217
 
227
- const res = await fetch(`${proxyServer.url}/services/api`)
218
+ const res = await fetch(`${proxyServer.url}/discover/api`)
228
219
  expect(res.status).toBe(200)
229
220
  expect(await res.json()).toMatchInlineSnapshot(`
230
221
  {
231
- "baseUrl": "https://api.example.com",
232
222
  "id": "api",
233
223
  "routes": [
234
224
  {
235
225
  "method": "GET",
236
- "path": "/v1/models",
237
- "pattern": "GET /v1/models",
226
+ "path": "/api/v1/models",
227
+ "pattern": "GET /api/v1/models",
238
228
  "payment": null,
239
229
  },
240
230
  {
241
231
  "method": "POST",
242
- "path": "/v1/generate",
243
- "pattern": "POST /v1/generate",
232
+ "path": "/api/v1/generate",
233
+ "pattern": "POST /api/v1/generate",
244
234
  "payment": {
245
235
  "amount": "1000000",
246
236
  "currency": "0x20c0000000000000000000000000000000000001",
@@ -256,10 +246,173 @@ describe('create', () => {
256
246
  `)
257
247
  })
258
248
 
259
- test('behavior: GET /services/:id returns 404 for unknown', async () => {
249
+ test('behavior: GET /discover/all.md returns full markdown with routes', async () => {
250
+ const proxy = ApiProxy.create({
251
+ services: [
252
+ openai({
253
+ apiKey: 'sk-test',
254
+ routes: {
255
+ 'POST /v1/chat/completions': mppx_server.charge({
256
+ amount: '0.05',
257
+ description: 'Chat completion',
258
+ }),
259
+ 'GET /v1/models': true,
260
+ },
261
+ }),
262
+ anthropic({
263
+ apiKey: 'sk-ant-test',
264
+ routes: {
265
+ 'POST /v1/messages': mppx_server.charge({
266
+ amount: '0.03',
267
+ description: 'Send message',
268
+ }),
269
+ },
270
+ }),
271
+ ],
272
+ })
273
+ proxyServer = await Http.createServer(proxy.listener)
274
+
275
+ const res = await fetch(`${proxyServer.url}/discover/all.md`)
276
+ expect(res.status).toBe(200)
277
+ expect(res.headers.get('content-type')).toBe('text/markdown; charset=utf-8')
278
+ expect(await res.text()).toMatchInlineSnapshot(`
279
+ "# Services
280
+
281
+ ## [OpenAI](/discover/openai.md)
282
+
283
+ Chat completions, embeddings, image generation, and audio transcription.
284
+
285
+ ### Routes
286
+
287
+ - \`POST /openai/v1/chat/completions\`: Chat completion
288
+ - Type: charge
289
+ - Price: 0.05 (50000 units, 6 decimals)
290
+ - Currency: 0x20c0000000000000000000000000000000000001
291
+ - Docs: https://context7.com/websites/platform_openai/llms.txt?topic=POST%20%2Fv1%2Fchat%2Fcompletions
292
+
293
+ - \`GET /openai/v1/models\`
294
+ - Type: free
295
+ - Docs: https://context7.com/websites/platform_openai/llms.txt?topic=GET%20%2Fv1%2Fmodels
296
+
297
+ ## [Anthropic](/discover/anthropic.md)
298
+
299
+ Claude language models for messages and completions.
300
+
301
+ ### Routes
302
+
303
+ - \`POST /anthropic/v1/messages\`: Send message
304
+ - Type: charge
305
+ - Price: 0.03 (30000 units, 6 decimals)
306
+ - Currency: 0x20c0000000000000000000000000000000000001
307
+ "
308
+ `)
309
+ })
310
+
311
+ test('behavior: GET /discover/:id.md returns markdown', async () => {
312
+ const proxy = ApiProxy.create({
313
+ services: [
314
+ openai({
315
+ apiKey: 'sk-test',
316
+ routes: {
317
+ 'POST /v1/chat/completions': mppx_server.charge({
318
+ amount: '0.05',
319
+ description: 'Chat completion',
320
+ }),
321
+ 'GET /v1/models': true,
322
+ },
323
+ }),
324
+ anthropic({
325
+ apiKey: 'sk-ant-test',
326
+ routes: {
327
+ 'POST /v1/messages': mppx_server.charge({ amount: '0.03' }),
328
+ },
329
+ }),
330
+ ],
331
+ })
332
+ proxyServer = await Http.createServer(proxy.listener)
333
+
334
+ const res = await fetch(`${proxyServer.url}/discover/openai.md`)
335
+ expect(res.status).toBe(200)
336
+ expect(res.headers.get('content-type')).toBe('text/markdown; charset=utf-8')
337
+ expect(await res.text()).toMatchInlineSnapshot(`
338
+ "# OpenAI
339
+
340
+ > Documentation: https://context7.com/websites/platform_openai/llms.txt
341
+
342
+ Chat completions, embeddings, image generation, and audio transcription.
343
+
344
+ ## Routes
345
+
346
+ - \`POST /openai/v1/chat/completions\`: Chat completion
347
+ - Type: charge
348
+ - Price: 0.05 (50000 units, 6 decimals)
349
+ - Currency: 0x20c0000000000000000000000000000000000001
350
+ - Docs: https://context7.com/websites/platform_openai/llms.txt?topic=POST%20%2Fv1%2Fchat%2Fcompletions
351
+
352
+ - \`GET /openai/v1/models\`
353
+ - Type: free
354
+ - Docs: https://context7.com/websites/platform_openai/llms.txt?topic=GET%20%2Fv1%2Fmodels
355
+ "
356
+ `)
357
+ })
358
+
359
+ test('behavior: GET /discover/:id with Accept: text/markdown returns markdown', async () => {
360
+ const proxy = ApiProxy.create({
361
+ services: [
362
+ openai({
363
+ apiKey: 'sk-test',
364
+ routes: { 'GET /v1/models': true },
365
+ }),
366
+ anthropic({
367
+ apiKey: 'sk-ant-test',
368
+ routes: {
369
+ 'POST /v1/messages': mppx_server.charge({ amount: '0.03' }),
370
+ },
371
+ }),
372
+ ],
373
+ })
374
+ proxyServer = await Http.createServer(proxy.listener)
375
+
376
+ const res = await fetch(`${proxyServer.url}/discover/anthropic`, {
377
+ headers: { Accept: 'text/markdown' },
378
+ })
379
+ expect(res.status).toBe(200)
380
+ expect(res.headers.get('content-type')).toBe('text/markdown; charset=utf-8')
381
+ })
382
+
383
+ test('behavior: GET /discover/:id without Accept returns JSON', async () => {
384
+ const proxy = ApiProxy.create({
385
+ services: [
386
+ openai({
387
+ apiKey: 'sk-test',
388
+ routes: { 'GET /v1/models': true },
389
+ }),
390
+ anthropic({
391
+ apiKey: 'sk-ant-test',
392
+ routes: {
393
+ 'POST /v1/messages': mppx_server.charge({ amount: '0.03' }),
394
+ },
395
+ }),
396
+ ],
397
+ })
398
+ proxyServer = await Http.createServer(proxy.listener)
399
+
400
+ const res = await fetch(`${proxyServer.url}/discover/openai`)
401
+ expect(res.status).toBe(200)
402
+ expect(res.headers.get('content-type')).toMatchInlineSnapshot(`"application/json"`)
403
+ })
404
+
405
+ test('behavior: GET /discover/:id.md returns 404 for unknown', async () => {
406
+ const proxy = ApiProxy.create({ services: [] })
407
+ proxyServer = await Http.createServer(proxy.listener)
408
+ const res = await fetch(`${proxyServer.url}/discover/unknown.md`)
409
+ expect(res.status).toBe(404)
410
+ })
411
+
412
+ test('behavior: GET /discover/:id returns 404 for unknown', async () => {
260
413
  const proxy = ApiProxy.create({ services: [] })
261
414
  proxyServer = await Http.createServer(proxy.listener)
262
- const res = await fetch(`${proxyServer.url}/services/unknown`)
415
+ const res = await fetch(`${proxyServer.url}/discover/unknown`)
263
416
  expect(res.status).toBe(404)
264
417
  })
265
418
 
@@ -66,19 +66,58 @@ export function create(config: create.Config): Proxy {
66
66
  title: config.title,
67
67
  description: config.description,
68
68
  }),
69
- {
70
- headers: { 'Content-Type': 'text/plain; charset=utf-8' },
71
- },
69
+ { headers: { 'Content-Type': 'text/plain; charset=utf-8' } },
72
70
  )
73
71
 
74
- if (request.method === 'GET' && (pathname === '/services' || pathname === '/services/'))
72
+ if (request.method === 'GET' && pathname === '/discover.md')
73
+ return new Response(
74
+ Service.toLlmsTxt(config.services, {
75
+ title: config.title,
76
+ description: config.description,
77
+ }),
78
+ { headers: { 'Content-Type': 'text/plain; charset=utf-8' } },
79
+ )
80
+
81
+ if (request.method === 'GET' && (pathname === '/discover' || pathname === '/discover/')) {
82
+ if (wantsMarkdown(request))
83
+ return new Response(
84
+ Service.toLlmsTxt(config.services, {
85
+ title: config.title,
86
+ description: config.description,
87
+ }),
88
+ { headers: { 'Content-Type': 'text/plain; charset=utf-8' } },
89
+ )
75
90
  return Response.json(config.services.map(Service.serialize))
91
+ }
92
+
93
+ if (
94
+ request.method === 'GET' &&
95
+ (pathname === '/discover/all' || pathname === '/discover/all/')
96
+ ) {
97
+ if (wantsMarkdown(request))
98
+ return new Response(Service.toServicesMarkdown(config.services), {
99
+ headers: { 'Content-Type': 'text/markdown; charset=utf-8' },
100
+ })
101
+ return Response.json(config.services.map(Service.serialize))
102
+ }
103
+
104
+ if (request.method === 'GET' && pathname === '/discover/all.md')
105
+ return new Response(Service.toServicesMarkdown(config.services), {
106
+ headers: { 'Content-Type': 'text/markdown; charset=utf-8' },
107
+ })
76
108
 
77
109
  {
78
- const match = pathname.match(/^\/services\/([^/]+)\/?$/)
110
+ // List service
111
+ const match =
112
+ pathname.match(/^\/discover\/([^/]+)\.md$/) ?? pathname.match(/^\/discover\/([^/]+)\/?$/)
79
113
  if (request.method === 'GET' && match) {
80
114
  const service = config.services.find((s) => s.id === match[1])
81
115
  if (!service) return new Response('Not Found', { status: 404 })
116
+ const wantsText = pathname.endsWith('.md') || wantsMarkdown(request)
117
+ if (wantsText)
118
+ return new Response(Service.toMarkdown(service), {
119
+ headers: { 'Content-Type': 'text/markdown; charset=utf-8' },
120
+ })
82
121
  return Response.json(Service.serialize(service))
83
122
  }
84
123
  }
@@ -183,3 +222,42 @@ async function proxyUpstream(options: proxyUpstream.Options): Promise<Response>
183
222
 
184
223
  return upstreamRes
185
224
  }
225
+
226
+ const aiUserAgents = [
227
+ 'GPTBot',
228
+ 'OAI-SearchBot',
229
+ 'ChatGPT-User',
230
+ 'anthropic-ai',
231
+ 'ClaudeBot',
232
+ 'claude-web',
233
+ 'PerplexityBot',
234
+ 'Perplexity-User',
235
+ 'Google-Extended',
236
+ 'Googlebot',
237
+ 'Bingbot',
238
+ 'Amazonbot',
239
+ 'Applebot',
240
+ 'Applebot-Extended',
241
+ 'FacebookBot',
242
+ 'meta-externalagent',
243
+ 'Bytespider',
244
+ 'DuckAssistBot',
245
+ 'cohere-ai',
246
+ 'AI2Bot',
247
+ 'CCBot',
248
+ 'Diffbot',
249
+ 'YouBot',
250
+ 'MistralAI-User',
251
+ 'GoogleAgent-Mariner',
252
+ ]
253
+
254
+ const terminalUserAgents = ['curl', 'Wget', 'HTTPie', 'httpie-go', 'mppx', 'presto', 'xh']
255
+
256
+ function wantsMarkdown(request: globalThis.Request): boolean {
257
+ const accept = request.headers.get('accept')
258
+ if (accept && (accept.includes('text/markdown') || accept.includes('text/plain'))) return true
259
+ const ua = request.headers.get('user-agent') ?? ''
260
+ if (aiUserAgents.some((agent) => ua.includes(agent))) return true
261
+ if (terminalUserAgents.some((agent) => ua.includes(agent))) return true
262
+ return false
263
+ }
@@ -160,18 +160,18 @@ function resolveRewriteRequest(
160
160
  /** Serializes a service for discovery responses. */
161
161
  export function serialize(s: Service) {
162
162
  return {
163
- baseUrl: s.baseUrl,
164
163
  description: s.description,
165
164
  id: s.id,
166
165
  docsLlmsUrl: s.docsLlmsUrl?.({}),
167
166
  routes: Object.entries(s.routes).map(([pattern, endpoint]) => {
168
167
  const tokens = pattern.trim().split(/\s+/)
169
168
  const hasMethod = tokens.length >= 2
169
+ const path = hasMethod ? tokens.slice(1).join(' ') : tokens[0]
170
170
  return {
171
171
  docsLlmsUrl: s.docsLlmsUrl?.({ route: pattern }),
172
172
  method: hasMethod ? tokens[0] : undefined,
173
- path: hasMethod ? tokens.slice(1).join(' ') : tokens[0],
174
- pattern,
173
+ path: `/${s.id}${path}`,
174
+ pattern: hasMethod ? `${tokens[0]} /${s.id}${path}` : `/${s.id}${path}`,
175
175
  payment: endpoint ? resolvePayment(endpoint) : null,
176
176
  }
177
177
  }),
@@ -189,53 +189,71 @@ export function toLlmsTxt(
189
189
  '',
190
190
  `> ${options?.description ?? 'Paid API proxy powered by [Machine Payments Protocol](https://mpp.tempo.xyz).'}`,
191
191
  '',
192
- 'For machine-readable service data, use `GET /services` (JSON).',
193
- '',
194
192
  ]
195
193
 
196
194
  if (services.length === 0) return lines.join('\n')
197
195
 
198
196
  lines.push('## Services', '')
199
197
  for (const s of services) {
200
- const serialized = serialize(s)
201
- const free = serialized.routes.filter((r) => r.payment === null).length
202
- const paid = serialized.routes.length - free
203
- const parts = [paid && `${paid} paid`, free && `${free} free`].filter(Boolean).join(', ')
204
198
  const label = s.title ?? s.id
205
- const desc = s.description ? `: ${s.description} (${parts})` : `: ${parts}`
206
- lines.push(`- [${label}](${s.baseUrl})${desc}`)
199
+ const desc = s.description ? `: ${s.description}` : ''
200
+ lines.push(`- [${label}](/discover/${s.id}.md)${desc}`)
207
201
  }
202
+ lines.push('', '[See all service definitions](/discover/all.md)')
203
+
204
+ return lines.join('\n')
205
+ }
206
+
207
+ /** Renders a full markdown listing of all services with their routes. */
208
+ export function toServicesMarkdown(services: Service[]): string {
209
+ const lines: string[] = ['# Services', '']
210
+
211
+ if (services.length === 0) return lines.join('\n')
208
212
 
209
213
  for (const s of services) {
210
- const serialized = serialize(s)
211
- const docsLlmsUrl = s.docsLlmsUrl?.({})
212
- lines.push('', `## ${s.title ?? s.id}`, '')
214
+ lines.push(`## [${s.title ?? s.id}](/discover/${s.id}.md)`, '')
213
215
  if (s.description) lines.push(s.description, '')
214
- if (docsLlmsUrl) lines.push(`Documentation: ${docsLlmsUrl}`, '')
215
- for (const route of serialized.routes) {
216
- const p = route.payment as Record<string, unknown> | null
217
- const desc = p?.description ? ` - ${p.description}` : ''
218
- lines.push(`- \`${route.pattern}\`${desc}`)
219
- if (!p) {
220
- lines.push(` - Type: free`)
221
- } else {
222
- lines.push(` - Type: ${p.intent}`)
223
- if (p.amount) {
224
- const perUnit = p.unitType ? `/${p.unitType}` : ''
225
- if (p.decimals !== undefined) {
226
- const price = Number(p.amount) / 10 ** Number(p.decimals)
227
- lines.push(` - Price: ${price}${perUnit} (${p.amount} units, ${p.decimals} decimals)`)
228
- } else {
229
- lines.push(` - Units: ${p.amount}${perUnit}`)
230
- }
216
+ pushRoutes(lines, s)
217
+ }
218
+
219
+ return lines.join('\n')
220
+ }
221
+
222
+ /** Renders a markdown string for a single service. */
223
+ export function toMarkdown(s: Service): string {
224
+ const docsLlmsUrl = s.docsLlmsUrl?.({})
225
+ const lines: string[] = [`# ${s.title ?? s.id}`, '']
226
+ if (docsLlmsUrl) lines.push(`> Documentation: ${docsLlmsUrl}`, '')
227
+ if (s.description) lines.push(s.description, '')
228
+ pushRoutes(lines, s, '##')
229
+ return lines.join('\n')
230
+ }
231
+
232
+ function pushRoutes(lines: string[], s: Service, heading: '##' | '###' = '###') {
233
+ lines.push(`${heading} Routes`, '')
234
+ const serialized = serialize(s)
235
+ for (const route of serialized.routes) {
236
+ const p = route.payment as Record<string, unknown> | null
237
+ const desc = p?.description ? `: ${p.description}` : ''
238
+ lines.push(`- \`${route.pattern}\`${desc}`)
239
+ if (!p) {
240
+ lines.push(' - Type: free')
241
+ } else {
242
+ lines.push(` - Type: ${p.intent}`)
243
+ if (p.amount) {
244
+ const perUnit = p.unitType ? `/${p.unitType}` : ''
245
+ if (p.decimals !== undefined) {
246
+ const price = Number(p.amount) / 10 ** Number(p.decimals)
247
+ lines.push(` - Price: ${price}${perUnit} (${p.amount} units, ${p.decimals} decimals)`)
248
+ } else {
249
+ lines.push(` - Units: ${p.amount}${perUnit}`)
231
250
  }
232
- if (p.currency) lines.push(` - Currency: ${p.currency}`)
233
251
  }
234
- if (route.docsLlmsUrl) lines.push(` - Docs: ${route.docsLlmsUrl}`)
252
+ if (p.currency) lines.push(` - Currency: ${p.currency}`)
235
253
  }
254
+ if (route.docsLlmsUrl) lines.push(` - Docs: ${route.docsLlmsUrl}`)
255
+ lines.push('')
236
256
  }
237
-
238
- return lines.join('\n')
239
257
  }
240
258
 
241
259
  /** Extracts per-endpoint options from an endpoint definition. */
@@ -24,7 +24,7 @@ export function openai(config: openai.Config) {
24
24
  docsLlmsUrl: ({ route }) =>
25
25
  route
26
26
  ? `https://context7.com/websites/platform_openai/llms.txt?topic=${encodeURIComponent(route)}`
27
- : undefined,
27
+ : 'https://context7.com/websites/platform_openai/llms.txt',
28
28
  rewriteRequest(request, ctx) {
29
29
  const apiKey = ctx.apiKey ?? config.apiKey
30
30
  request.headers.set('Authorization', `Bearer ${apiKey}`)