8000 fix: 웹 읽기 접수 상태의 캐시된 링크 재사용 방지 by hmmhmmhm · Pull Request #349 · hmmhmmhm/daiso-mcp · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/service-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ README 하단에 있던 기능, REST API, 개발, 아키텍처 설명을 분리

모든 후속 웹 GET도 `/browse/`를 사용하세요. 자동 HTML이며 쿼리 문자열이나 format 지정은 필요 없습니다. 상품 검색 결과의 실제 ID로 재고를 조회하고 검색 성공만으로 매장 재고를 단정하지 않습니다. 이미지는 응답 imageUrl과 카드의 원본 Markdown만 사용하고 이미지 검색으로 대체하지 않습니다.

현재 안내는 [버전 안내](https://mcp.aka.page/guide/2026-10-27.3), 다음 버전도 따라가려면 [항상 최신 안내](https://mcp.aka.page/guide/latest)를 여세요. 이 상세 레퍼런스를 끝까지 읽기 전에 첫 조회를 실행하세요.
현재 안내는 [버전 안내](https://mcp.aka.page/guide/latest), 다음 버전도 따라가려면 [항상 최신 안내](https://mcp.aka.page/guide/latest)를 여세요. 이 상세 레퍼런스를 끝까지 읽기 전에 첫 조회를 실행하세요.

이미 연결된 MCP 도구가 있는 환경만 `search_products`에 `service=daiso`, `query=수납박스`를 전달합니다. 서버는 https://mcp.aka.page 이며 Streamable HTTP, 인증 없음입니다. 실제로 실행한 도구·URL·오류만 보고하고 실행하지 않은 요청의 성공·실패를 만들지 않습니다.

Expand Down
7 changes: 7 additions & 0 deletions experiments/web-read-lab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,10 @@ received는 Worker 도착, prepared는 응답 생성 완료입니다. prepared
User-Agent는 chatgpt-user/oai-searchbot/browser/other로만 분류하며 인증된 신원이나 클라이언트 원본을 증명하지 않습니다. IP·쿠키·토큰·전체 UA·자유 쿼리는 저장하지 않습니다. 공개 관측 기록은 최대128개/24시간이며 많은 요청이 들어오면 앞 기록이 사라질 수 있습니다. 관측 URL에 개인정보를 넣지 마세요.

새 링크 하나가 실패했다는 사실만으로 JSON·한글·크기 등이 원인이라고 결론 내리지 않습니다. 기준 HTML도 실패하면 그 실행에서는 내용별 한계를 비교할 수 없습니다. 검색 사본 갱신은 보장하지 않습니다.


## 최초 지연·결과 저장·접수 비교

새 실행번호에서 `delay5`(매번5초), `cold5`(처음5초 뒤 결과 저장), `start5`(즉시 pending 접수), `result5`(저장 상태 읽기)를 비교합니다. 최초 cold5 연결이 끊겨도 같은 실행의 Durable Object 알람이 고정 가상 결과를 완성합니다. 완료 결과의 resultId와 completedAt은24시간 동안 유지하고 이후 정리합니다. HTML은 no-store이며 서버의 저장 결과와 웹 도구 사본 재사용은 구분합니다. pending/not-found에는 수량이 없습니다.

접수·결과 응답에는 같은 작업의 새로운 실제 결과 확인 링크와 완성 resultUrl을 제공합니다. 이전 pending 주소를 반복하지 말고 새 링크를 최대3번 선택합니다. 반복 후에도 pending이면 미확인으로 보고합니다. 실제 ChatGPT에서 원본 도착·requestId·jobId·resultId를 대조하고, 일반 HTTP 성공만으로 웹 도구 성공을 판정하지 않습니다. 관측 조회는 예열하지 않지만 결과 URL을 미리 여는 것은 표본을 오염시키므로 하지 않습니다.
4 changes: 3 additions & 1 deletion experiments/web-read-lab/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,11 @@ export default {
const result = await job.fetch(new Request(`https://job/${test}`));
const state = await result.json();
const { quantity: _quantity, ...metadata } = data;
const resultUrl = new URL(`/run/${run}/result5`, url.origin);
resultUrl.searchParams.set('attempt', requestId);
status = result.status;
body = html(
`<p>가상 작업 실험. pending은 조회 완료나 재고가 아닙니다.</p><pre>${JSON.stringify({ ...metadata, job: state }, null, 2)}</pre><p><a href="/run/${run}/result5">결과 확인</a></p><p>결과가 pending이면 잠시 후 같은 실제 링크를 한 번만 다시 확인하세요.</p>`,
`<p>가상 작업 실험. pending은 조회 완료나 재고가 아닙니다.</p><pre>${JSON.stringify({ ...metadata, resultUrl: resultUrl.href, job: state }, null, 2)}</pre><p><a href="${resultUrl.href}">결과 확인</a> · <code>${resultUrl.href}</code></p><p>결과가 pending이면 이 응답의 새 결과 확인 링크를 선택하세요. 이전 주소를 반복하지 마세요. 최대3번 확인하고 계속 pending이면 미확인으로 보고하세요.</p>`,
);
} else if (isComposer) {
headers.set('X-Robots-Tag', 'noindex');
Expand Down
7 changes: 6 additions & 1 deletion tests/scripts/web-read-lab-jobs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ describe('웹 읽기 저장 결과와 접수 실험', () => {
const body = await first.text();
expect(body).toContain('pending');
expect(body).not.toContain('quantity');
expect(body).toContain('href="/run/staged/result5"');
expect(body).toMatch(/href="https:\/\/lab.example\/run\/staged\/result5\?attempt=/);
const next = body.match(/href="([^"]+)">결과 확인/)![1];
const pendingBody = await (await get(new URL(next).pathname + new URL(next).search)).text();
expect(pendingBody).toContain('pending');
expect(pendingBody.match(/href="([^"]+)">결과 확인/)![1]).not.toBe(next);
expect(body).toContain('resultUrl');
expect(await (await get('/run/staged/result5')).text()).toContain('pending');
await vi.advanceTimersByTimeAsync(5000);
await env.PROBE_LOG.get('job-staged').alarm();
Expand Down
Loading
0