@linkegringo/mcp 1.0.9 → 1.0.10
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/index.d.ts +2 -9
- package/dist/index.js +194 -122
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -392,8 +392,7 @@ declare function handleGetPendingJob(input?: GetPendingJobInput): Promise<{
|
|
|
392
392
|
}[];
|
|
393
393
|
structuredData: {
|
|
394
394
|
jobFound: boolean;
|
|
395
|
-
|
|
396
|
-
job?: undefined;
|
|
395
|
+
job: BridgeJob<any, any>;
|
|
397
396
|
};
|
|
398
397
|
} | {
|
|
399
398
|
content: {
|
|
@@ -402,13 +401,7 @@ declare function handleGetPendingJob(input?: GetPendingJobInput): Promise<{
|
|
|
402
401
|
}[];
|
|
403
402
|
structuredData: {
|
|
404
403
|
jobFound: boolean;
|
|
405
|
-
|
|
406
|
-
id: string;
|
|
407
|
-
type: JobType;
|
|
408
|
-
payload: any;
|
|
409
|
-
createdAt: number;
|
|
410
|
-
};
|
|
411
|
-
pendingCount?: undefined;
|
|
404
|
+
pendingCount: number;
|
|
412
405
|
};
|
|
413
406
|
}>;
|
|
414
407
|
|
package/dist/index.js
CHANGED
|
@@ -172,9 +172,9 @@ var DEFAULT_BRIDGE_URL = process.env.LINKEGRINGO_BRIDGE_URL || (process.env.NODE
|
|
|
172
172
|
async function getRemoteOrLocalPendingJob(jobId, bridgeUrl = DEFAULT_BRIDGE_URL) {
|
|
173
173
|
if (bridgeUrl) {
|
|
174
174
|
try {
|
|
175
|
-
const url = jobId ? `${bridgeUrl}/api/jobs
|
|
175
|
+
const url = jobId ? `${bridgeUrl}/api/jobs/${encodeURIComponent(jobId)}` : `${bridgeUrl}/api/jobs/pending`;
|
|
176
176
|
const controller = new AbortController();
|
|
177
|
-
const timer = setTimeout(() => controller.abort(),
|
|
177
|
+
const timer = setTimeout(() => controller.abort(), 15e3);
|
|
178
178
|
const res = await fetch(url, { signal: controller.signal });
|
|
179
179
|
clearTimeout(timer);
|
|
180
180
|
if (res.ok) {
|
|
@@ -192,7 +192,7 @@ async function completeRemoteOrLocalJob(jobId, result, bridgeUrl = DEFAULT_BRIDG
|
|
|
192
192
|
if (bridgeUrl) {
|
|
193
193
|
try {
|
|
194
194
|
const controller = new AbortController();
|
|
195
|
-
const timer = setTimeout(() => controller.abort(),
|
|
195
|
+
const timer = setTimeout(() => controller.abort(), 15e3);
|
|
196
196
|
const res = await fetch(`${bridgeUrl}/api/jobs/${encodeURIComponent(jobId)}/complete`, {
|
|
197
197
|
method: "POST",
|
|
198
198
|
headers: { "Content-Type": "application/json" },
|
|
@@ -1256,26 +1256,10 @@ ${proposals.map(
|
|
|
1256
1256
|
|
|
1257
1257
|
// src/tools/get-pending-job.ts
|
|
1258
1258
|
import { z as z11 } from "zod";
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
const job = await getRemoteOrLocalPendingJob(input.jobId);
|
|
1264
|
-
if (!job) {
|
|
1265
|
-
return {
|
|
1266
|
-
content: [
|
|
1267
|
-
{
|
|
1268
|
-
type: "text",
|
|
1269
|
-
text: "Nenhum job pendente no momento na interface web do LinkeGringo."
|
|
1270
|
-
}
|
|
1271
|
-
],
|
|
1272
|
-
structuredData: {
|
|
1273
|
-
jobFound: false,
|
|
1274
|
-
pendingCount: bridgeJobStore.getPendingCount()
|
|
1275
|
-
}
|
|
1276
|
-
};
|
|
1277
|
-
}
|
|
1278
|
-
bridgeJobStore.markProcessing(job.id);
|
|
1259
|
+
|
|
1260
|
+
// src/tools/format-job.ts
|
|
1261
|
+
function formatJobResponse(job) {
|
|
1262
|
+
let instructions = "";
|
|
1279
1263
|
let details = "";
|
|
1280
1264
|
if (job.type === "parse_and_diagnose") {
|
|
1281
1265
|
const p = job.payload || {};
|
|
@@ -1284,53 +1268,210 @@ async function handleGetPendingJob(input = {}) {
|
|
|
1284
1268
|
- **Cargo Almejado**: ${p.targetRole || "N\xE3o especificado"}
|
|
1285
1269
|
- **Possui PDF Base64**: ${Boolean(p.pdfBase64)} (${p.pdfBase64 ? Math.round(p.pdfBase64.length / 1024) + " KB base64" : "N/A"})
|
|
1286
1270
|
- **Possui Texto**: ${Boolean(p.pdfText)}
|
|
1271
|
+
`.trim();
|
|
1272
|
+
instructions = `
|
|
1273
|
+
### \u26A0\uFE0F DIRETRIZES OBRIGAT\xD3RIAS PARA O AGENTE DE IA:
|
|
1274
|
+
1. **Zero Scripts**: N\xC3O execute scripts Python/Node no disco. N\xC3O salve arquivos no sistema de arquivos. N\xC3O inspecione arquivos locais de c\xF3digo.
|
|
1275
|
+
2. **Processamento Multimodal**: Analise o PDF/dados recebidos diretamente no seu racioc\xEDnio em 1 \xFAnico turno.
|
|
1276
|
+
3. **Submiss\xE3o Imediata**: Chame a ferramenta \`submit_job_result\` com o JSON estruturado no campo \`result\`.
|
|
1277
|
+
|
|
1278
|
+
### \u{1F4CB} Estrutura JSON Exata para \`submit_job_result\`:
|
|
1279
|
+
\`\`\`json
|
|
1280
|
+
{
|
|
1281
|
+
"jobId": "${job.id}",
|
|
1282
|
+
"result": {
|
|
1283
|
+
"profile": {
|
|
1284
|
+
"firstName": "Nome",
|
|
1285
|
+
"lastName": "Sobrenome",
|
|
1286
|
+
"headline": "Role Anchor | Core Techs | Scale/Impact | US Remote",
|
|
1287
|
+
"location": "Cidade, Pa\xEDs",
|
|
1288
|
+
"summary": "Resumo profissional com foco em impacto t\xE9cnico...",
|
|
1289
|
+
"experiences": [
|
|
1290
|
+
{
|
|
1291
|
+
"title": "Senior Software Engineer",
|
|
1292
|
+
"companyName": "Nome da Empresa",
|
|
1293
|
+
"workplaceType": "remote",
|
|
1294
|
+
"location": "Local",
|
|
1295
|
+
"current": true,
|
|
1296
|
+
"startDate": { "year": 2022, "month": 1 },
|
|
1297
|
+
"endDate": undefined,
|
|
1298
|
+
"description": "Responsabilidades e impacto..."
|
|
1299
|
+
}
|
|
1300
|
+
],
|
|
1301
|
+
"education": [
|
|
1302
|
+
{
|
|
1303
|
+
"schoolName": "Universidade",
|
|
1304
|
+
"degreeName": "Bacharelado",
|
|
1305
|
+
"fieldOfStudy": "Ci\xEAncia da Computa\xE7\xE3o"
|
|
1306
|
+
}
|
|
1307
|
+
],
|
|
1308
|
+
"skills": [
|
|
1309
|
+
{ "name": "Node.js" },
|
|
1310
|
+
{ "name": "TypeScript" }
|
|
1311
|
+
],
|
|
1312
|
+
"languages": [
|
|
1313
|
+
{ "name": "English", "proficiency": "professional" }
|
|
1314
|
+
]
|
|
1315
|
+
},
|
|
1316
|
+
"review": {
|
|
1317
|
+
"targetMarket": "United States Remote",
|
|
1318
|
+
"language": "en",
|
|
1319
|
+
"overallScore": 82,
|
|
1320
|
+
"scores": {
|
|
1321
|
+
"searchRelevance": 85,
|
|
1322
|
+
"humanVoice": 80,
|
|
1323
|
+
"credibility": 80,
|
|
1324
|
+
"positioningClarity": 85,
|
|
1325
|
+
"evidenceCoverage": 80
|
|
1326
|
+
},
|
|
1327
|
+
"scoreExplanations": {
|
|
1328
|
+
"searchRelevance": "Avalia\xE7\xE3o de indexa\xE7\xE3o ATS...",
|
|
1329
|
+
"humanVoice": "Tom profissional e aut\xEAntico...",
|
|
1330
|
+
"credibility": "Evid\xEAncias t\xE9cnicas e consist\xEAncia...",
|
|
1331
|
+
"positioningClarity": "Clareza do papel s\xEAnior...",
|
|
1332
|
+
"evidenceCoverage": "Densidade de m\xE9tricas quantific\xE1veis..."
|
|
1333
|
+
},
|
|
1334
|
+
"executiveSummary": "Resumo executivo do diagn\xF3stico e posicionamento para vagas nos EUA...",
|
|
1335
|
+
"profileDirection": {
|
|
1336
|
+
"positioning": "Senior Full-Stack Engineer",
|
|
1337
|
+
"primaryRole": "${p.targetRole || "Senior Full-Stack Engineer"}",
|
|
1338
|
+
"openToWorkTitles": [
|
|
1339
|
+
"Senior Full Stack Engineer",
|
|
1340
|
+
"Senior Backend Engineer",
|
|
1341
|
+
"Staff Software Engineer",
|
|
1342
|
+
"Lead Software Engineer",
|
|
1343
|
+
"Full Stack Developer"
|
|
1344
|
+
],
|
|
1345
|
+
"rationale": "Justificativa do posicionamento estrat\xE9gico para o mercado americano..."
|
|
1346
|
+
},
|
|
1347
|
+
"triageBottlenecks": [
|
|
1348
|
+
"Gargalo 1: Descri\xE7\xF5es de cargos com poucos bullets quantific\xE1veis",
|
|
1349
|
+
"Gargalo 2: Headline precisa de palavras-chave de indexa\xE7\xE3o booleana"
|
|
1350
|
+
],
|
|
1351
|
+
"critique": [
|
|
1352
|
+
{
|
|
1353
|
+
"section": "Headline",
|
|
1354
|
+
"assessment": "Avalia\xE7\xE3o da headline atual",
|
|
1355
|
+
"strengths": ["Clareza do cargo principal"],
|
|
1356
|
+
"issues": ["Falta men\xE7\xE3o a escala e especializa\xE7\xE3o"],
|
|
1357
|
+
"severity": "medium"
|
|
1358
|
+
}
|
|
1359
|
+
]
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
\`\`\`
|
|
1287
1364
|
`.trim();
|
|
1288
1365
|
} else if (job.type === "generate_interview") {
|
|
1366
|
+
const p = job.payload || {};
|
|
1289
1367
|
details = `
|
|
1290
1368
|
- **Tipo de A\xE7\xE3o**: Gera\xE7\xE3o de Perguntas de Entrevista T\xE9cnica
|
|
1291
|
-
- **Candidato**: ${
|
|
1292
|
-
- **Cargo Almejado**: ${
|
|
1369
|
+
- **Candidato**: ${p.profile?.firstName || ""} ${p.profile?.lastName || ""}
|
|
1370
|
+
- **Cargo Almejado**: ${p.objective?.primaryRole || "N\xE3o informado"}
|
|
1371
|
+
`.trim();
|
|
1372
|
+
instructions = `
|
|
1373
|
+
### \u26A0\uFE0F DIRETRIZES OBRIGAT\xD3RIAS PARA O AGENTE DE IA:
|
|
1374
|
+
1. Gere perguntas t\xE9cnicas focando nos gargalos e lacunas identificados no perfil.
|
|
1375
|
+
2. N\xC3O execute scripts nem inspecione arquivos.
|
|
1376
|
+
3. Chame a ferramenta \`submit_job_result\` com a estrutura:
|
|
1377
|
+
|
|
1378
|
+
\`\`\`json
|
|
1379
|
+
{
|
|
1380
|
+
"jobId": "${job.id}",
|
|
1381
|
+
"result": {
|
|
1382
|
+
"questions": [
|
|
1383
|
+
{
|
|
1384
|
+
"id": "q1",
|
|
1385
|
+
"category": "scale",
|
|
1386
|
+
"question": "Texto claro da pergunta para investigar o escopo e impacto...",
|
|
1387
|
+
"rationale": "Por que esta pergunta \xE9 importante para o recrutador gringo...",
|
|
1388
|
+
"targetSignal": "M\xE9tricas de escala, throughput ou lat\xEAncia que queremos capturar"
|
|
1389
|
+
}
|
|
1390
|
+
]
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
\`\`\`
|
|
1293
1394
|
`.trim();
|
|
1294
1395
|
} else if (job.type === "generate_rewritten_profile") {
|
|
1396
|
+
const p = job.payload || {};
|
|
1295
1397
|
details = `
|
|
1296
|
-
- **Tipo de A\xE7\xE3o**: Reescrita
|
|
1297
|
-
- **Candidato**: ${
|
|
1298
|
-
- **Fatos Confirmados**: ${
|
|
1398
|
+
- **Tipo de A\xE7\xE3o**: Reescrita Completa de Perfil com Bullets Google XYZ
|
|
1399
|
+
- **Candidato**: ${p.profile?.firstName || ""} ${p.profile?.lastName || ""}
|
|
1400
|
+
- **Fatos Confirmados**: ${p.confirmedFacts?.length || 0}
|
|
1401
|
+
`.trim();
|
|
1402
|
+
instructions = `
|
|
1403
|
+
### \u26A0\uFE0F DIRETRIZES OBRIGAT\xD3RIAS PARA O AGENTE DE IA:
|
|
1404
|
+
1. Reescreva o perfil aplicando a f\xF3rmula Google XYZ (*Accomplished [X], measured by [Y], by doing [Z]*) e Headline $\\le$ 160 caracteres.
|
|
1405
|
+
2. N\xC3O execute scripts nem inspecione arquivos.
|
|
1406
|
+
3. Chame a ferramenta \`submit_job_result\` com a estrutura:
|
|
1407
|
+
|
|
1408
|
+
\`\`\`json
|
|
1409
|
+
{
|
|
1410
|
+
"jobId": "${job.id}",
|
|
1411
|
+
"result": {
|
|
1412
|
+
"rewritten": {
|
|
1413
|
+
"headline": "Role Anchor | 3-4 Core Techs | Scale/Impact | US Remote",
|
|
1414
|
+
"summary": "Resumo About reformulado com gancho forte nos primeiros 250 caracteres...",
|
|
1415
|
+
"experiences": [
|
|
1416
|
+
{
|
|
1417
|
+
"title": "Senior Software Engineer",
|
|
1418
|
+
"companyName": "Nome da Empresa",
|
|
1419
|
+
"workplaceType": "remote",
|
|
1420
|
+
"location": "Local",
|
|
1421
|
+
"current": true,
|
|
1422
|
+
"startDate": { "year": 2022, "month": 1 },
|
|
1423
|
+
"endDate": undefined,
|
|
1424
|
+
"description": "Accomplished [X], measured by [Y], by doing [Z]...\\nAccomplished [X], measured by [Y], by doing [Z]..."
|
|
1425
|
+
}
|
|
1426
|
+
]
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
\`\`\`
|
|
1299
1431
|
`.trim();
|
|
1300
1432
|
}
|
|
1301
1433
|
return {
|
|
1302
1434
|
content: [
|
|
1303
1435
|
{
|
|
1304
1436
|
type: "text",
|
|
1305
|
-
text:
|
|
1306
|
-
# \u{1F4E5} Job da Interface Web Encontrado!
|
|
1307
|
-
|
|
1308
|
-
- **Job ID**: \`${job.id}\`
|
|
1309
|
-
- **Tipo**: \`${job.type}\`
|
|
1310
|
-
- **Criado em**: ${new Date(job.createdAt).toLocaleTimeString()}
|
|
1437
|
+
text: `\u{1F680} **NOVO JOB RECEBIDO DO LINKEGRINGO**: \`${job.id}\`
|
|
1311
1438
|
|
|
1312
1439
|
${details}
|
|
1313
1440
|
|
|
1314
|
-
|
|
1315
|
-
\u{1F4A1} **Instru\xE7\xF5es para o Agente de IA**:
|
|
1316
|
-
1. Processe a intelig\xEAncia requerida para este job com base nas diretrizes do LinkeGringo.
|
|
1317
|
-
2. Ao concluir, chame a ferramenta \`submit_job_result\` passando \`jobId: "${job.id}"\` e o JSON estruturado no campo \`result\`.
|
|
1318
|
-
3. A interface web em \`localhost:5173\` atualizar\xE1 a tela no mesmo instante!
|
|
1319
|
-
`.trim()
|
|
1441
|
+
${instructions}`
|
|
1320
1442
|
}
|
|
1321
1443
|
],
|
|
1322
1444
|
structuredData: {
|
|
1323
1445
|
jobFound: true,
|
|
1324
|
-
job
|
|
1325
|
-
id: job.id,
|
|
1326
|
-
type: job.type,
|
|
1327
|
-
payload: job.payload,
|
|
1328
|
-
createdAt: job.createdAt
|
|
1329
|
-
}
|
|
1446
|
+
job
|
|
1330
1447
|
}
|
|
1331
1448
|
};
|
|
1332
1449
|
}
|
|
1333
1450
|
|
|
1451
|
+
// src/tools/get-pending-job.ts
|
|
1452
|
+
var getPendingJobInputSchema = z11.object({
|
|
1453
|
+
jobId: z11.string().optional().describe("ID espec\xEDfico do job a ser buscado (opcional. Se omitido, pega o pr\xF3ximo da fila)")
|
|
1454
|
+
});
|
|
1455
|
+
async function handleGetPendingJob(input = {}) {
|
|
1456
|
+
const job = await getRemoteOrLocalPendingJob(input.jobId);
|
|
1457
|
+
if (!job) {
|
|
1458
|
+
return {
|
|
1459
|
+
content: [
|
|
1460
|
+
{
|
|
1461
|
+
type: "text",
|
|
1462
|
+
text: "Nenhum job pendente no momento na interface web do LinkeGringo."
|
|
1463
|
+
}
|
|
1464
|
+
],
|
|
1465
|
+
structuredData: {
|
|
1466
|
+
jobFound: false,
|
|
1467
|
+
pendingCount: bridgeJobStore.getPendingCount()
|
|
1468
|
+
}
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1471
|
+
bridgeJobStore.markProcessing(job.id);
|
|
1472
|
+
return formatJobResponse(job);
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1334
1475
|
// src/tools/submit-job-result.ts
|
|
1335
1476
|
import { z as z12 } from "zod";
|
|
1336
1477
|
var submitJobResultInputSchema = z12.object({
|
|
@@ -1501,76 +1642,6 @@ async function waitForNextJob(bridgeUrl, timeoutMs) {
|
|
|
1501
1642
|
}
|
|
1502
1643
|
});
|
|
1503
1644
|
}
|
|
1504
|
-
function formatJobResponse(job) {
|
|
1505
|
-
let instructions = "";
|
|
1506
|
-
let details = "";
|
|
1507
|
-
if (job.type === "parse_and_diagnose") {
|
|
1508
|
-
const p = job.payload || {};
|
|
1509
|
-
details = `
|
|
1510
|
-
- **Tipo de A\xE7\xE3o**: Extra\xE7\xE3o Multimodal e Diagn\xF3stico de Perfil (parseAndDiagnose)
|
|
1511
|
-
- **Cargo Almejado**: ${p.targetRole || "N\xE3o especificado"}
|
|
1512
|
-
- **Possui PDF Base64**: ${Boolean(p.pdfBase64)} (${p.pdfBase64 ? Math.round(p.pdfBase64.length / 1024) + " KB" : "N/A"})
|
|
1513
|
-
- **Possui Texto**: ${Boolean(p.pdfText)}
|
|
1514
|
-
`.trim();
|
|
1515
|
-
instructions = `
|
|
1516
|
-
### Pr\xF3ximos Passos Obrigat\xF3rios:
|
|
1517
|
-
1. Extraia e analise o perfil estruturado (\`Profile\`) e o diagn\xF3stico (\`ProfileReview\`) com notas (0-100), gargalos de triagem de recrutadores e lacunas de stack.
|
|
1518
|
-
2. Envie o resultado de volta para o navegador chamando a tool \`submit_job_result\`:
|
|
1519
|
-
\`\`\`json
|
|
1520
|
-
{
|
|
1521
|
-
"jobId": "${job.id}",
|
|
1522
|
-
"result": {
|
|
1523
|
-
"profile": { ... },
|
|
1524
|
-
"review": { ... }
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
\`\`\`
|
|
1528
|
-
3. Ap\xF3s enviar o resultado, execute a tool \`watch_linkegringo\` novamente para aguardar a pr\xF3xima a\xE7\xE3o do usu\xE1rio (entrevista t\xE9cnica ou reescrita).
|
|
1529
|
-
`.trim();
|
|
1530
|
-
} else if (job.type === "generate_interview") {
|
|
1531
|
-
const p = job.payload || {};
|
|
1532
|
-
details = `
|
|
1533
|
-
- **Tipo de A\xE7\xE3o**: Gera\xE7\xE3o de Perguntas de Entrevista T\xE9cnica
|
|
1534
|
-
- **Candidato**: ${p.profile?.name || "N\xE3o informado"}
|
|
1535
|
-
- **Cargo Almejado**: ${p.objective?.primaryRole || "N\xE3o informado"}
|
|
1536
|
-
`.trim();
|
|
1537
|
-
instructions = `
|
|
1538
|
-
### Pr\xF3ximos Passos Obrigat\xF3rios:
|
|
1539
|
-
1. Gere as perguntas t\xE9cnicas focando nos gargalos e lacunas identificados.
|
|
1540
|
-
2. Envie o resultado chamando \`submit_job_result({ jobId: "${job.id}", result: { questions: [...] } })\`.
|
|
1541
|
-
3. Rearme a escuta chamando \`watch_linkegringo\` para aguardar as respostas do candidato.
|
|
1542
|
-
`.trim();
|
|
1543
|
-
} else if (job.type === "generate_rewritten_profile") {
|
|
1544
|
-
const p = job.payload || {};
|
|
1545
|
-
details = `
|
|
1546
|
-
- **Tipo de A\xE7\xE3o**: Reescrita Completa de Perfil com Bullets Google XYZ
|
|
1547
|
-
- **Candidato**: ${p.profile?.name || "N\xE3o informado"}
|
|
1548
|
-
- **Fatos Confirmados na Entrevista**: ${p.confirmedFacts?.length || 0}
|
|
1549
|
-
`.trim();
|
|
1550
|
-
instructions = `
|
|
1551
|
-
### Pr\xF3ximos Passos Obrigat\xF3rios:
|
|
1552
|
-
1. Reescreva o perfil aplicando a f\xF3rmula Google XYZ (Accomplished [X], measured by [Y], by doing [Z]) e Headline $\\le$ 160 caracteres.
|
|
1553
|
-
2. Envie o resultado chamando \`submit_job_result({ jobId: "${job.id}", result: { rewritten: { ... } } })\`.
|
|
1554
|
-
3. Rearme a escuta chamando \`watch_linkegringo\`.
|
|
1555
|
-
`.trim();
|
|
1556
|
-
}
|
|
1557
|
-
return {
|
|
1558
|
-
content: [
|
|
1559
|
-
{
|
|
1560
|
-
type: "text",
|
|
1561
|
-
text: `\u{1F680} **NOVO JOB RECEBIDO DO LINKEGRINGO**: \`${job.id}\`
|
|
1562
|
-
|
|
1563
|
-
${details}
|
|
1564
|
-
|
|
1565
|
-
${instructions}`
|
|
1566
|
-
}
|
|
1567
|
-
],
|
|
1568
|
-
structuredData: {
|
|
1569
|
-
jobFound: true,
|
|
1570
|
-
job
|
|
1571
|
-
}
|
|
1572
|
-
};
|
|
1573
|
-
}
|
|
1574
1645
|
async function handleWatchLinkeGringo(input = {}) {
|
|
1575
1646
|
const timeoutSeconds = Math.min(Math.max(input.timeoutSeconds ?? 60, 0.1), 300);
|
|
1576
1647
|
const timeoutMs = timeoutSeconds * 1e3;
|
|
@@ -1653,7 +1724,7 @@ function createLinkeGringoMcpServer() {
|
|
|
1653
1724
|
server.registerTool(
|
|
1654
1725
|
"get_pending_job",
|
|
1655
1726
|
{
|
|
1656
|
-
description: "
|
|
1727
|
+
description: "Obt\xE9m os dados completos de um job pelo ID (ou o pr\xF3ximo da fila). Use APENAS quando for notificado de um job espec\xEDfico (ex: por watcher em background). N\xC3O use esta ferramenta para iniciar escuta ou checar jobs antes de iniciar o watch.",
|
|
1657
1728
|
inputSchema: getPendingJobInputSchema.shape
|
|
1658
1729
|
},
|
|
1659
1730
|
async (args) => {
|
|
@@ -1663,7 +1734,7 @@ function createLinkeGringoMcpServer() {
|
|
|
1663
1734
|
server.registerTool(
|
|
1664
1735
|
"submit_job_result",
|
|
1665
1736
|
{
|
|
1666
|
-
description: "Envia o resultado
|
|
1737
|
+
description: "Envia o resultado estruturado do processamento de um job de volta para o navegador do LinkeGringo, desbloqueando a tela do usu\xE1rio instantaneamente. Sempre chame esta ferramenta imediatamente ap\xF3s processar um job recebido por watch_linkegringo ou get_pending_job.",
|
|
1667
1738
|
inputSchema: submitJobResultInputSchema.shape
|
|
1668
1739
|
},
|
|
1669
1740
|
async (args) => {
|
|
@@ -1673,7 +1744,7 @@ function createLinkeGringoMcpServer() {
|
|
|
1673
1744
|
server.registerTool(
|
|
1674
1745
|
"watch_linkegringo",
|
|
1675
1746
|
{
|
|
1676
|
-
description:
|
|
1747
|
+
description: 'Inicia a escuta ativa (watch) por jobs enviados pela interface web do LinkeGringo (http://127.0.0.1:5174). Use esta ferramenta SEMPRE que o usu\xE1rio disser "iniciar watch", "escutar", "conectar ao LinkeGringo" ou similar. N\xC3O chame get_pending_job antes desta ferramenta. Bloqueia aguardando e retorna o job assim que ele for submetido no navegador.',
|
|
1677
1748
|
inputSchema: watchLinkeGringoInputSchema.shape
|
|
1678
1749
|
},
|
|
1679
1750
|
async (args) => {
|
|
@@ -2204,16 +2275,17 @@ function startBridgeWatcher(options = {}) {
|
|
|
2204
2275
|
console.log(
|
|
2205
2276
|
`[LinkeGringo Watcher] \u{1F7E2} Conectado ao bridge (${bridgeUrl}). Watcher ativo: ${payload.watcherId} (Jobs pendentes: ${payload.pendingCount})`
|
|
2206
2277
|
);
|
|
2207
|
-
if (
|
|
2278
|
+
if (payload.pendingCount > 0 && options.once) {
|
|
2208
2279
|
console.log(
|
|
2209
|
-
`[LinkeGringo Watcher] \u{1F680} JOB DETECTADO NA FILA (${payload.pendingCount} pendente(s)).
|
|
2280
|
+
`[LinkeGringo Watcher] \u{1F680} JOB DETECTADO NA FILA (${payload.pendingCount} pendente(s)). Chame get_pending_job para processar e submit_job_result para responder.`
|
|
2210
2281
|
);
|
|
2211
2282
|
setTimeout(() => process.exit(0), 50);
|
|
2212
2283
|
}
|
|
2213
2284
|
} else if (payload.type === "job_created") {
|
|
2214
2285
|
console.log(
|
|
2215
2286
|
`
|
|
2216
|
-
[LinkeGringo Watcher] \u{1F680} NOVO JOB DETECTADO: ${payload.job.id} | Tipo: ${payload.job.type}
|
|
2287
|
+
[LinkeGringo Watcher] \u{1F680} NOVO JOB DETECTADO: ${payload.job.id} | Tipo: ${payload.job.type}
|
|
2288
|
+
[LinkeGringo Watcher] \u{1F449} Chame get_pending_job({ jobId: '${payload.job.id}' }) e envie o resultado direto com submit_job_result.`
|
|
2217
2289
|
);
|
|
2218
2290
|
options.onJob?.(payload.job);
|
|
2219
2291
|
if (options.once) {
|