# dsh-fal-imagegen **언어:** [English](README.md) · [中文](README.zh.md) · [Español](README.es.md) · [العربية](README.ar.md) · [Français](README.fr.md) · [日本語](README.ja.md) · **한국어** DeepSeek Harness(DSH)용 [fal.ai](https://fal.ai) 네이티브 이미지 생성 플러그인: FAL_KEY와 기본값을 설정하는 이중 언어 설정 카드와, fal 프로토콜을 처음부터 끝까지 직접 사용하는 에이전트 도구 — OpenAI 호환 게이트웨이를 거치지 않습니다. ## 기능 - **네이티브 fal 프로토콜** — `Authorization: Key :` 헤더로 `POST https://queue.fal.run/`, 큐 티켓(`status_url` → `response_url`)을 폴링하여 `{ images: [{ url, width, height }] }`를 소비합니다. - **기본 비동기 생성** — `fal_generate_image`가 작업을 fal 큐에 제출하고 즉시 `task_id`를 반환합니다. 백그라운드 수집기가 완료까지 처리하며, `fal_get_image_task`로 진행 상황을 확인하고 완성된 이미지를 받을 수 있습니다(쿼리당 최대 120초 대기). 예전처럼 동기적으로 기다리려면 `wait=true`를 전달하세요. - **DSH 언어를 따르는 설정 카드** — 설정 → 플러그인의 "fal 生図"/"fal imagegen": 마스터 스위치, FAL_KEY, 기본 텍스트→이미지/이미지→이미지 엔드포인트, 기본 크기, 품질, 출력 형식, 타임아웃, 출력 폴더, 시스템 프롬프트 공지 스위치. 카드는 내장 플러그인 카드와 동일한 모양과 동작(접기, 미저장 태그, 필드별 초기화, 저장/취소)을 따르며, 카드 문구는 DSH 자체 언어(설정 → 일반 → 언어)를 따릅니다: DSH가 중국어면 중국어, 그 외의 모든 언어면 영어 — 일치하는 언어가 없으면 영어를 기본값으로 사용합니다. 별도 전환 버튼은 없습니다. 항상 주변 UI의 일부로 읽힙니다. - **에이전트 도구**: | 도구 | 용도 | | --- | --- | | `fal_generate_image` | 텍스트→이미지, 기본 비동기: `prompt` / `model` / `size` / `quality` / `count` / `wait` → `task_id` 반환 | | `fal_get_image_task` | 백그라운드 작업 조회: 진행, 대기, 완성 이미지(`task_id` 또는 fal `request_id`로 지정. 둘 다 생략하면 최근 작업 목록) | | `fal_edit_image` | 이미지→이미지, 동기 처리: `prompt` + 소스(첨부 참조 또는 디스크의 `image_path`) | | `fal_list_image_models` | 내장 별칭, 현재 기본값, 출력 폴더 목록 | - **재사용 가능한 결과물** — 모든 이미지는 대화에 첨부되고(도구 호출 옆에 표시) **그리고** `/fal-imagegen` 아래 디스크에 저장됩니다. 반환된 `path`는 `fal_edit_image`의 `image_path`에 곧바로 넣을 수 있습니다. - **검증된 모델 별칭** — 모든 내장 별칭은 fal 공식 엔드포인트 스키마로 검증했습니다. "/"를 포함한 미지의 slug는 그대로 전달되며, 텍스트→이미지 slug를 편집에 쓰면 깨진 요청 대신 명확하게 거부합니다. ## 비동기 생성 흐름 `fal_generate_image`는 더 이상 에이전트 턴을 fal 큐에 묶어두지 않습니다: 1. 도구가 작업을 큐에 제출하고, fal이 수락하는 즉시 `{ status: "queued", task_id, request_id, message, next_action, images: [] }`를 응답합니다. 2. 분리된 수집기가 큐를 폴링하고 이미지를 다운로드해 첨부로 저장하고 출력 폴더로 복사합니다 — 모두 백그라운드에서. 3. `fal_get_image_task`(`task_id` 필수, 또는 fal의 `request_id`)는 `queued / running / completed / failed`를 보고합니다. `wait_seconds`(0–120)를 주면 그 시간만큼 블로킹하고, `completed`가 되면 결과에 `attachment_id` + 로컬 `path`가 담긴 전체 `images[]`가 포함되며 도구 호출 옆에 이미지가 렌더링됩니다. 4. id를 생략하면 최근 작업 목록(`task_id`, 상태, 모델, 이미지 수)을 표시합니다. 참고: 작업 기록은 현재 호스트 프로세스에 보관됩니다(약 6시간, 최신 64개). 백그라운드 대기가 타임아웃된 작업은 다음 조회에서 자동으로 재시도됩니다. `fal_edit_image`는 그 결과가 보통 다음 단계의 입력으로 쓰이기 때문에 동기 방식 그대로 유지합니다. ## 모델 별칭 | 별칭 | 텍스트→이미지 엔드포인트 | 이미지→이미지 엔드포인트 | 크기 파라미터 | quality | | --- | --- | --- | --- | --- | | `gpt-image-2.5-flare`(기본값. `gpt-image-2.5` / `gpt-image-2.5-flash`도 허용) | `openai/gpt-image-2.5/flare/text-to-image` | `openai/gpt-image-2.5/flare/edit` | `image_size` | 지원 | | `gpt-image-2.5-sunburst` | `openai/gpt-image-2.5/sunburst/text-to-image` | `openai/gpt-image-2.5/sunburst/edit` | `image_size` | 지원 | | `gpt-image-2` | `openai/gpt-image-2` | `openai/gpt-image-2/edit` | `image_size` | 지원 | | `gpt-image-1.5` | `fal-ai/gpt-image-1.5` | `fal-ai/gpt-image-1.5/edit` | `image_size` | 지원 | | `nano-banana-2` | `fal-ai/nano-banana-2` | `fal-ai/nano-banana-2/edit` | `aspect_ratio` | 생략 | | `gemini-25-flash-image` | `fal-ai/gemini-25-flash-image` | `fal-ai/gemini-25-flash-image/edit` | `aspect_ratio` | 생략 | | `flux-2-flash` | `fal-ai/flux-2/flash` | `fal-ai/flux-2/flash/edit` | `image_size` | 생략 | ## 설정 | 필드 | 기본값 | 의미 | | --- | --- | --- | | `enabled` | `true` | 마스터 스위치(도구 + 프롬프트 공지) | | `falKey` | 빈 값 | FAL_KEY(`key_id:key_secret` 형식. fal.ai → Keys 페이지에서 전체 문자열 복사) | | `defaultTextToImageModel` | `openai/gpt-image-2.5/flare/text-to-image` | 기본 텍스트→이미지 엔드포인트 | | `defaultImageToImageModel` | `openai/gpt-image-2.5/flare/edit` | 기본 이미지→이미지 엔드포인트 | | `defaultImageSize` | `1:1` | `1:1 / 4:3 / 3:4 / 3:2 / 2:3 / 16:9 / 9:16 / 21:9`, `WxH` 픽셀 지정, 또는 `auto` | | `quality` | `high` | `auto / low / medium / high / xhigh / max`(지원하지 않는 엔드포인트는 자동 생략) | | `outputFormat` | `png` | `png / jpeg / webp` | | `timeoutSeconds` | `300` | 요청 1회 총 예산(제출 + 대기 + 수신) | | `saveDir` | 빈 값 | 출력 폴더. 빈 값 = `/fal-imagegen` | | `announceToAgent` | `true` | 에이전트 시스템 프롬프트에 플러그인 공지 여부 | 설정 카드는 `~/.dsh/settings.yaml`의 `dsh-fal-imagegen:` 섹션과 동일한 설정을 읽고 씁니다. FAL_KEY는 비밀번호 필드입니다: 비워 두면 현재 키가 유지됩니다(키는 모든 네트워크 뷰에서 마스킹됩니다). ## 설치 ### npm(권장) `dsh-fal-imagegen@0.2.0`이 게시되어 있습니다: ```sh # CLI 관리 프로필(web / headless / 커스텀): dsh plugin --profile web add dsh-fal-imagegen # 설치 후 해당 프로세스 재시작 ``` **desktop 프로필**은 DSH Desktop 앱이 독점 관리합니다(`dsh plugin --profile desktop`은 거부됨): 설정 → 플러그인 → 마켓에서 설치하거나, `~/.dsh/profiles/desktop/package.json`에 수동 등록(의존성 + `dsh.profile.bundles`에 `dsh-fal-imagegen` 추가)한 뒤 DSH Desktop을 완전히 재시작하세요. 설치 후 설정 → 플러그인 → 插件配置 의 "fal 生図" 카드에서 FAL_KEY를 입력하거나 `~/.dsh/settings.yaml`의 `dsh-fal-imagegen:` 섹션에 작성합니다. ### git에서(대체 경로) ```sh dsh plugin --profile web add github:Enchanted0911/dsh-fal-imagegen ``` ### 소스에서 ```sh git clone https://github.com/Enchanted0911/dsh-fal-imagegen # 프로필에 link: 하세요(의존성 + dsh.profile.bundles 항목) → DSH Desktop 재시작 ``` 런타임 패키지(`@deepseek-ai/dsh-tools`, `dsh-attachment`, `dsh-settings`, `schemastery`)는 하니스에서 제공됩니다. 소스 트리의 `node_modules/`는 오프라인 테스트를 하니스 밖에서 돌리기 위해서만 존재합니다. ## 개발 오프라인 테스트(키 없음, 네트워크 없음): ```sh node tests/fal-manifest-test.mjs # 매니페스트 계약: patch 행, exports, dsh.client, wrapper id node tests/fal-client-test.mjs # 브라우저 절반: 슬롯 등록, 카드 상태, 저장 ops, 언어 전환 node tests/fal-settings-roundtrip-test.mjs # 양쪽 접합: 카드 쓰기 → 호스트 읽기, 리셋, 토글 node tests/fal-schema-test.mjs # 도구 파라미터·출력 스키마 node tests/fal-tasks-test.mjs # 비동기 경로: 제출 → 백그라운드 완료 → 조회(가짜 fal 큐 사용) ``` 실제 호출 테스트(fal 크레딧 소모): ```sh FAL_KEY=':' node tests/fal-host-test.mjs # 호스트 시뮬레이션: 생성 + 편집 + 첨부/저장 + 실패 경로 FAL_KEY=':' node tests/fal-smoke.mjs # fal 클라이언트만(1회 생성) ``` 링크 설치에서 코드 변경 반영: 브라우저 절반(`lib/client.js`)은 페이지 새로고침으로 반영됩니다. 호스트 절반 코드와 `package.json` 매니페스트 변경은 DSH Desktop 재시작이 필요합니다. ## 마켓플레이스 카탈로그 소스 DSH 커뮤니티 마켓에는 기본 소스가 없습니다. 이 저장소는 `catalog/`(데이터 소스는 `catalog/entry.mjs`)에 v1 계약을 따르는 카탈로그 소스를 포함합니다. Cloudflare Pages 형태를 배포하고 설정 → 플러그인 → 마켓 → 소스에 매니페스트 URL을 등록하세요: ```sh npx wrangler pages deploy catalog/pages --project-name dsh-fal-imagegen-catalog # 그런 다음 https://dsh-fal-imagegen-catalog.pages.dev/catalog-source.json을 소스로 추가 ``` ## 알려진 제한 사항 - `aspect_ratio`만 문서화된 엔드포인트(nano-banana / gemini)에서는 명시적 픽셀 크기가 `auto`로 강등됩니다. - 생성은 fal 크레딧을 소모하며 이미지 콘텐츠는 fal 호스팅 모델이 만듭니다.