panal-mcp 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fetch-result.d.ts +15 -2
- package/dist/fetch-result.js +15 -7
- package/dist/server.js +10 -1
- package/package.json +1 -1
package/dist/fetch-result.d.ts
CHANGED
|
@@ -52,8 +52,21 @@ export declare function pushBrief(botUrl: string, taskId: bigint, brief: string,
|
|
|
52
52
|
* «no hay tope» es volver a averiguarlo pagando.
|
|
53
53
|
*/
|
|
54
54
|
export declare function parseMaxBriefChars(card: unknown): number | null;
|
|
55
|
-
export
|
|
55
|
+
export interface LimitesDelAgente {
|
|
56
|
+
/**
|
|
57
|
+
* Si contestó ALGO, aunque fuera un error.
|
|
58
|
+
*
|
|
59
|
+
* Un 404 en `/agent.json` cuenta como alcanzable: hay agentes que no sirven
|
|
60
|
+
* tarjeta y su `POST /brief` funciona igual. Lo que descalifica es que no
|
|
61
|
+
* conteste nadie —DNS que no resuelve, conexión rechazada, timeout— o que la
|
|
62
|
+
* URL no pase el guard, porque entonces el encargo tampoco va a llegar.
|
|
63
|
+
*
|
|
64
|
+
* `null` = no se preguntó (el agente no publica endpoint, que es un modo
|
|
65
|
+
* soportado: el encargo se le hace llegar por otro canal).
|
|
66
|
+
*/
|
|
67
|
+
alcanzable: boolean | null;
|
|
56
68
|
maxBriefChars: number | null;
|
|
57
|
-
}
|
|
69
|
+
}
|
|
70
|
+
export declare function fetchAgentLimits(botUrl: string): Promise<LimitesDelAgente>;
|
|
58
71
|
/** Descarga acotada: se corta en cuanto se pasa del tope. */
|
|
59
72
|
export declare function fetchResultText(botUrl: string, taskId: bigint, client: string, signature: string, expira: number): Promise<string>;
|
package/dist/fetch-result.js
CHANGED
|
@@ -110,27 +110,35 @@ export function parseMaxBriefChars(card) {
|
|
|
110
110
|
return typeof max === 'number' && Number.isInteger(max) && max > 0 ? max : null;
|
|
111
111
|
}
|
|
112
112
|
export async function fetchAgentLimits(botUrl) {
|
|
113
|
-
const desconocido = { maxBriefChars: null };
|
|
114
113
|
let url;
|
|
115
114
|
try {
|
|
116
115
|
const base = await assertPublicUrl(botUrl);
|
|
117
116
|
url = new URL('/agent.json', base);
|
|
118
117
|
}
|
|
119
118
|
catch {
|
|
120
|
-
|
|
119
|
+
// El guard rechaza la URL: a esa dirección no se le puede entregar nada, ni
|
|
120
|
+
// ahora ni al contratar. Es inalcanzable, no «no lo sé».
|
|
121
|
+
return { alcanzable: false, maxBriefChars: null };
|
|
121
122
|
}
|
|
122
123
|
const controller = new AbortController();
|
|
123
124
|
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
124
125
|
try {
|
|
125
126
|
const res = await fetch(url, { signal: controller.signal, redirect: 'error' });
|
|
127
|
+
// A partir de aquí YA contestó, y eso no se revoca: una tarjeta ilegible o
|
|
128
|
+
// un 500 dejan el tope sin saber, pero el agente sigue siendo contratable.
|
|
129
|
+
// Meter el parseo en el catch de la red convertiría un JSON roto en «este
|
|
130
|
+
// agente no existe», que es una acusación distinta y falsa.
|
|
126
131
|
if (!res.ok)
|
|
127
|
-
return
|
|
128
|
-
|
|
132
|
+
return { alcanzable: true, maxBriefChars: null };
|
|
133
|
+
try {
|
|
134
|
+
return { alcanzable: true, maxBriefChars: parseMaxBriefChars(await res.json()) };
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return { alcanzable: true, maxBriefChars: null };
|
|
138
|
+
}
|
|
129
139
|
}
|
|
130
140
|
catch {
|
|
131
|
-
|
|
132
|
-
// límite sin comprobar. Fallar aquí seria peor que el problema.
|
|
133
|
-
return desconocido;
|
|
141
|
+
return { alcanzable: false, maxBriefChars: null };
|
|
134
142
|
}
|
|
135
143
|
finally {
|
|
136
144
|
clearTimeout(timer);
|
package/dist/server.js
CHANGED
|
@@ -405,7 +405,16 @@ const WRITE_TOOLS = [
|
|
|
405
405
|
// tarea. Aquí no cuesta nada y evita dejar dinero atrapado hasta que
|
|
406
406
|
// vence el plazo.
|
|
407
407
|
if (agent.metadata.botUrl) {
|
|
408
|
-
const { maxBriefChars } = await fetchAgentLimits(agent.metadata.botUrl);
|
|
408
|
+
const { alcanzable, maxBriefChars } = await fetchAgentLimits(agent.metadata.botUrl);
|
|
409
|
+
// Que el endpoint no conteste descalifica el encargo entero: el brief se
|
|
410
|
+
// entrega DESPUÉS de crear la tarea, así que contratar ahora dejaría el
|
|
411
|
+
// pago bloqueado en una tarea que nadie puede empezar. Aquí no cuesta
|
|
412
|
+
// nada y basta con reintentar cuando el agente vuelva.
|
|
413
|
+
if (alcanzable === false) {
|
|
414
|
+
return (`${agent.metadata.name || address} publishes ${agent.metadata.botUrl} but nothing answers there, ` +
|
|
415
|
+
`so the job could not be delivered even after paying. Nothing was quoted and nothing was spent. ` +
|
|
416
|
+
`Try again when the agent is back up.`);
|
|
417
|
+
}
|
|
409
418
|
if (maxBriefChars !== null && brief.length > maxBriefChars) {
|
|
410
419
|
return (`That job does not fit: ${agent.metadata.name || address} accepts ${maxBriefChars} characters ` +
|
|
411
420
|
`and this brief is ${brief.length}. Nothing was quoted and nothing was spent. ` +
|