import { AgentTool } from './tool.js'; /** * 재귀 하강 파서. 문법은 이게 전부다. * * ``` * expr := term (('+' | '-') term)* * term := factor (('*' | '/' | '%') factor)* * factor := ('-' | '+') factor | '(' expr ')' | number * ``` */ export declare function evaluateExpression(expression: string): number; /** * 계산기 도구. 소형 모델이 확실히 못하는 일이라 도구로 메울 값어치가 있다. * * ```ts * new Agent({ instruction: '...', tools: [calculator()] }) * ``` * * `%`는 백분율이 아니라 **나머지**다. 설명에 명시해 두어 모델이 헷갈리지 않게 한다. * 도구 호출은 왕복 한 번이므로 `2+2` 같은 것에는 오히려 손해다. 설명을 좁게 써서 * 모델이 남용하지 않도록 유도한다. */ export declare function calculator(): AgentTool<{ expression: string; }>; export interface PageToolsOptions { /** * 읽을 범위. 기본은 `document.body`. * * 페이지 전체를 읽으면 내비게이션과 푸터까지 딸려와 좁은 창을 낭비한다. * 본문 컨테이너를 지정하는 편이 거의 항상 낫다. 예: `() => document.querySelector('main')` */ root?: () => Element | null; /** 한 번에 돌려줄 최대 글자 수. 기본 2000자. */ maxChars?: number; /** * 주소에 쿼리 문자열을 포함할지. 기본 false. * * 쿼리에 세션 토큰이나 개인정보가 실리는 경우가 흔해서 기본으로는 뺀다. * 모델이 로컬에서 돌더라도 대화 기록은 저장될 수 있다. */ includeQuery?: boolean; } /** * 지금 열려 있는 페이지를 읽는 도구들. * * **서버 LLM이 구조적으로 못 하는 일이다.** 사용자 화면 안에 있는 것은 브라우저 안에서 * 도는 모델만 볼 수 있다. 웹 검색이 "밖에서 정보를 가져오는" 것이라면 이쪽은 * "이미 눈앞에 있는 것을 읽는" 것이고, 키도 서버도 필요 없다. * * ```ts * new Agent({ * instruction: '이 페이지에 대해 답하는 도우미. 모르면 도구로 읽어라.', * tools: pageTools({ root: () => document.querySelector('article') }), * }) * ``` * * 두 도구 모두 **인자가 없다.** 인자를 받으면 모델이 JSON 문자열을 만들어야 하고 * 거기서 실패율이 오른다. 인자 없는 도구는 이름만 고르면 되므로 가장 안정적이다. */ export declare function pageTools(options?: PageToolsOptions): Array;