@penkit/ai
v1.1.0
Published
PenKit AI layer: gesture intent recognition, shape assist, natural-language tool control. Heuristic offline, LLM-pluggable.
Readme
@penkit/ai
PenKit product AI helper 패키지다. deterministic gesture intent, stroke-to-shape recognition, natural-language tool control, LLM provider interface를 제공한다.
npm install @penkit/ai @penkit/coreheuristic은 offline으로 동작한다. host는 model-backed upgrade가 필요할 때 LLM provider를 추가할 수 있다. 설계 원칙은 AI-powered, never AI-dependent다.
LLM Agent Quick Start
- heuristic API를 먼저 사용한다. synchronous, deterministic이며 network/API key가 필요 없다.
- 이 helper를
@penkit/engine또는@penkit/sdk에 주입한다. engine은@penkit/ai를 직접 import하지 않는다. - 실제 모델을 붙인다면 host code에서
LLMProvider를 구현하고LLMToolController에 넘긴다. - fallback behavior를 유지한다. drawing, erasing, shape creation이 model response에 의존하게 만들지 않는다.
import {
HeuristicNaturalLanguageController,
recognizeShape,
} from "@penkit/ai";
import { createNoteToolset, PenEngine } from "@penkit/engine";
const engine = new PenEngine({
adapter,
tools: createNoteToolset({ recognize: recognizeShape }),
});
const nl = new HeuristicNaturalLanguageController();
const command = nl.interpret("빨간 형광펜으로");
if (command.tool) engine.setTool(command.tool);
if (command.style) engine.setStyle(command.style);주요 모듈
Gesture Intent
HeuristicGestureRecognizer는 raw gesture signal을 host-neutral intent로 바꾼다. host가 어떤 command를 실행할지 결정한다.
import { HeuristicGestureRecognizer } from "@penkit/ai";
const recognizer = new HeuristicGestureRecognizer();
const intent = recognizer.recognize({
tapCount: 2,
isDragging: true,
durationMs: 120,
pointerType: "pen",
barrelButton: false,
});
if (intent.kind === "pointer-temporary") {
engine.setTool("pointer");
}기본 rule:
- double tap + drag ->
pointer-temporary - barrel button + drag ->
erase - long press + drag ->
lasso-select - 그 외 ->
none
Stroke-to-Shape Assist
recognizeShape(points)는 raw point를 분류하고 ShapeGuess를 반환한다.
import { recognizeShape } from "@penkit/ai";
const guess = recognizeShape(rawPoints);
if (guess.kind === "rectangle" && guess.confidence >= 0.55) {
// rough stroke를 host나 engine tool에서 clean rectangle로 교체한다.
}현재 heuristic class:
linerectangleellipsetrianglefreeform
arrow는 type system에 있지만 model-backed class로 예약되어 있다. heuristic recognizer는 freehand arrow recognition을 claim하지 않는다.
Natural-Language Tool Control
HeuristicNaturalLanguageController는 한국어와 영어 keyword를 중립 ToolCommand로 파싱한다.
import { HeuristicNaturalLanguageController } from "@penkit/ai";
const controller = new HeuristicNaturalLanguageController();
controller.interpret("빨간 형광펜으로");
// { tool: "highlighter", style: { color: "#ef4444" } }
controller.interpret("use a thick blue pen");
// { tool: "pen", style: { color: "#3b82f6", baseWidth: 8 } }host는 command를 받아 적용한다.
const command = controller.interpret(input.value);
if (command.tool) engine.setTool(command.tool);
if (command.style) engine.setStyle(command.style);LLMProvider and LLMToolController
LLMToolController는 host가 제공한 LLMProvider를 호출하고, provider 실패나 invalid JSON 반환 시 heuristic controller로 fallback한다.
import { LLMToolController } from "@penkit/ai";
import type { LLMCompletionRequest, LLMProvider } from "@penkit/ai";
class HostLLMProvider implements LLMProvider {
readonly name = "host";
async complete(req: LLMCompletionRequest): Promise<string> {
const result = await hostAiClient.complete({
system: req.system,
prompt: req.prompt,
});
return result.text;
}
}
const controller = new LLMToolController(new HostLLMProvider());
const command = await controller.interpret("make the next strokes a thin green marker");provider output은 다음 JSON shape여야 한다.
{
"tool": "pen",
"style": {
"color": "#22c55e",
"baseWidth": 1
}
}MockLLMProvider는 test와 demo용이다.
Integration Notes
- 이 패키지는
@penkit/core에만 의존한다. - engine은 recognizer function을 주입받아 AI optional 상태를 유지한다.
- 테스트에는 heuristic path를 사용한다. deterministic/offline이다.
- model-backed behavior는 contract가 아니라 enhancement로 다룬다.
- production provider를 연결할 때는 host에서 model output을 검증하고 제한한다.
하지 말 것
- 실제 OpenAI/Anthropic/on-device provider가 bundled되어 있다고 말하지 않는다.
- model response를 기다리느라 drawing input을 막지 않는다.
- host privacy policy와 user consent 없이 raw document data를 외부 모델에 보내지 않는다.
- heuristic shape recognizer를 handwriting OCR, math, diagram graph extraction 용도로 의존하지 않는다.
