@framers/agentos-ext-vision-pipeline 0.1.0 → 0.2.1

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/SKILL.md CHANGED
@@ -8,13 +8,24 @@ tools_required: [vision-pipeline]
8
8
 
9
9
  # Vision & OCR
10
10
 
11
- Extract text from images, documents, and handwritten notes using a progressive 3-tier pipeline: local OCR (PaddleOCR) -> local vision models (TrOCR, Florence-2) -> cloud vision (GPT-4o, Claude).
11
+ Extract text from images, documents, and handwritten notes with a progressive 3-tier pipeline: local OCR (PaddleOCR or Tesseract), then local vision models (TrOCR, Florence-2), then cloud vision.
12
12
 
13
- ## Capabilities
14
- - **Printed text OCR**: Extract text from documents, receipts, screenshots
15
- - **Handwriting recognition**: Read handwritten notes and forms via TrOCR
16
- - **Document layout**: Understand tables, figures, headings via Florence-2
17
- - **Image embeddings**: Generate CLIP vectors for semantic image search
13
+ ## Tool
14
+ **vision-pipeline** takes `imageUrl`, `mode` and `maxTier`. `imageUrl` is a `data:image/...` URL or an http(s) URL on a public host: local file paths and addresses on this machine or a private network are refused, so a model cannot send the machine's files, or what its network serves, to a cloud model. With AgentOS 0.13.16 or later, the tool fetches an http(s) image through `imageToBuffer`'s untrusted mode and hands the pipeline the bytes: every address the host resolves to is checked when the connection is made, each redirect is checked the same way, and the fetch stops at 50 MiB and 30 seconds. With an older AgentOS the check reads the URL's host as written, so the address a public name resolves to and a redirect's target are not checked.
15
+
16
+ | mode | what it returns | lowest maxTier |
17
+ |------|-----------------|----------------|
18
+ | `auto` (default) | the pipeline's best text | 1 |
19
+ | `ocr` | printed text | 1 |
20
+ | `handwriting` | handwritten text (TrOCR) | 2 |
21
+ | `layout` | document text and structure (Florence-2) | 2 |
22
+ | `embed` | a CLIP embedding vector | 2 |
23
+ | `describe` | what the image shows (cloud vision) | 3 |
24
+
25
+ `maxTier` 1 runs local OCR alone, 2 adds the local vision models, 3 (default) may use cloud vision.
26
+
27
+ ## Setup
28
+ The local tiers use the optional packages AgentOS finds installed: `ppu-paddle-ocr` or `tesseract.js` for OCR, and `@huggingface/transformers` for handwriting, layout and embeddings. With an OpenAI key in the pack option `openaiApiKey` or the secret `openai.apiKey`, the cloud tier uses OpenAI with that key. Without one, it uses the first provider whose key is in the environment: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GOOGLE_API_KEY` (or `GEMINI_API_KEY`), `OPENROUTER_API_KEY`. `describe` and the cloud tier need `@framers/agentos` 0.12.14 or later: earlier releases send the image to the cloud model as text, and read the key from the environment only.
18
29
 
19
30
  ## Example
20
31
  "Read the text from this receipt"
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @fileoverview Vision & OCR Pipeline Extension Pack: the vision-pipeline tool
3
+ * on AgentOS's `createVisionPipeline`.
4
+ *
5
+ * Pipeline tiers:
6
+ * Tier 1 (local, fast): PaddleOCR or Tesseract for printed text
7
+ * Tier 2 (local, medium): TrOCR for handwriting, Florence-2 for layout, CLIP embeddings
8
+ * Tier 3 (cloud, slow): a vision model of the provider whose key is set
9
+ *
10
+ * The local tiers need their optional packages (ppu-paddle-ocr or tesseract.js,
11
+ * and @huggingface/transformers); AgentOS uses the ones it finds installed.
12
+ * The cloud tier reads OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY (or
13
+ * GEMINI_API_KEY) or OPENROUTER_API_KEY from the environment.
14
+ *
15
+ * @module @framers/agentos-ext-vision-pipeline
16
+ */
17
+ /** What the extension manager passes the pack factory. */
18
+ export interface ExtensionContext {
19
+ /** `priority` of the tool descriptor (default 45); `openaiApiKey` for the cloud tier. */
20
+ options?: {
21
+ priority?: number;
22
+ openaiApiKey?: string;
23
+ } & Record<string, unknown>;
24
+ /** Reads a secret, such as `openai.apiKey`. */
25
+ getSecret?: (key: string) => string | undefined;
26
+ logger?: {
27
+ info: (msg: string) => void;
28
+ warn?: (msg: string) => void;
29
+ };
30
+ }
31
+ /** The pack the factory returns: one `vision-pipeline` tool descriptor. */
32
+ export interface ExtensionPack {
33
+ name: string;
34
+ version: string;
35
+ descriptors: Array<{
36
+ id: string;
37
+ kind: string;
38
+ priority?: number;
39
+ payload: unknown;
40
+ requiredSecrets?: Array<{
41
+ id: string;
42
+ optional?: boolean;
43
+ }>;
44
+ }>;
45
+ onActivate?: () => Promise<void>;
46
+ onDeactivate?: () => Promise<void>;
47
+ }
48
+ /**
49
+ * Create the Vision & OCR Pipeline extension pack.
50
+ *
51
+ * The pack builds a pipeline per strategy the first time a call needs it:
52
+ * building one probes for the optional OCR and model packages, which loading
53
+ * the pack does not do. A build that fails is tried again on the next call.
54
+ */
55
+ export declare function createExtensionPack(context?: ExtensionContext): ExtensionPack;
56
+ export { VisionPipelineTool, imageInput } from './tools/visionPipeline.js';
57
+ export type { VisionPipelineInput, VisionPipelineOutput, VisionMode } from './tools/visionPipeline.js';
58
+ export default createExtensionPack;
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;GAeG;AAQH,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,yFAAyF;IACzF,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjF,+CAA+C;IAC/C,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAChD,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CACxE;AAED,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,KAAK,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,eAAe,CAAC,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;KAC7D,CAAC,CAAC;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,gBAAqB,GAAG,aAAa,CAiEjF;AAED,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC3E,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvG,eAAe,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,99 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @fileoverview Vision & OCR Pipeline Extension Pack: the vision-pipeline tool
4
+ * on AgentOS's `createVisionPipeline`.
5
+ *
6
+ * Pipeline tiers:
7
+ * Tier 1 (local, fast): PaddleOCR or Tesseract for printed text
8
+ * Tier 2 (local, medium): TrOCR for handwriting, Florence-2 for layout, CLIP embeddings
9
+ * Tier 3 (cloud, slow): a vision model of the provider whose key is set
10
+ *
11
+ * The local tiers need their optional packages (ppu-paddle-ocr or tesseract.js,
12
+ * and @huggingface/transformers); AgentOS uses the ones it finds installed.
13
+ * The cloud tier reads OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY (or
14
+ * GEMINI_API_KEY) or OPENROUTER_API_KEY from the environment.
15
+ *
16
+ * @module @framers/agentos-ext-vision-pipeline
17
+ */
18
+ import { createRequire } from 'node:module';
19
+ import { createVisionPipeline } from '@framers/agentos';
20
+ import { VisionPipelineTool } from './tools/visionPipeline.js';
21
+ const { version } = createRequire(import.meta.url)('../package.json');
22
+ /**
23
+ * Create the Vision & OCR Pipeline extension pack.
24
+ *
25
+ * The pack builds a pipeline per strategy the first time a call needs it:
26
+ * building one probes for the optional OCR and model packages, which loading
27
+ * the pack does not do. A build that fails is tried again on the next call.
28
+ */
29
+ export function createExtensionPack(context = {}) {
30
+ // An OpenAI key from the options or the secrets makes OpenAI the cloud tier's
31
+ // provider, with that key. Without one, AgentOS detects the provider and its
32
+ // key from the environment. AgentOS releases whose VisionPipelineConfig has
33
+ // no cloudApiKey ignore it and read OPENAI_API_KEY.
34
+ const firstKey = (...values) => values.map((value) => (typeof value === 'string' ? value.trim() : '')).find(Boolean) || undefined;
35
+ const openaiKey = firstKey(context.options?.openaiApiKey, context.getSecret?.('openai.apiKey'));
36
+ const cloud = openaiKey ? { cloudProvider: 'openai', cloudApiKey: openaiKey } : {};
37
+ const pipelines = new Map();
38
+ // Set while the pack is deactivated: a call then gets no new pipeline,
39
+ // which deactivation would not dispose of.
40
+ let deactivated = false;
41
+ const pipelineFor = (strategy) => {
42
+ if (deactivated)
43
+ return Promise.reject(new Error('The Vision & OCR Pipeline pack is deactivated.'));
44
+ let pipeline = pipelines.get(strategy);
45
+ if (!pipeline) {
46
+ pipeline = createVisionPipeline({ strategy, ...cloud });
47
+ pipelines.set(strategy, pipeline);
48
+ const built = pipeline;
49
+ built.catch(() => {
50
+ if (pipelines.get(strategy) === built)
51
+ pipelines.delete(strategy);
52
+ });
53
+ }
54
+ return pipeline;
55
+ };
56
+ const tool = new VisionPipelineTool(pipelineFor);
57
+ return {
58
+ name: '@framers/agentos-ext-vision-pipeline',
59
+ version,
60
+ descriptors: [
61
+ {
62
+ id: tool.name,
63
+ kind: 'tool',
64
+ priority: context.options?.priority ?? 45,
65
+ payload: tool,
66
+ requiredSecrets: [{ id: 'openai.apiKey', optional: true }],
67
+ },
68
+ ],
69
+ onActivate: async () => {
70
+ deactivated = false;
71
+ context.logger?.info('Vision & OCR Pipeline Extension activated');
72
+ },
73
+ onDeactivate: async () => {
74
+ deactivated = true;
75
+ const built = [...pipelines.values()];
76
+ pipelines.clear();
77
+ for (const pipeline of built) {
78
+ let instance;
79
+ try {
80
+ instance = await pipeline;
81
+ }
82
+ catch {
83
+ continue; // A pipeline that failed to build has nothing to release.
84
+ }
85
+ try {
86
+ await instance.dispose();
87
+ }
88
+ catch (error) {
89
+ const log = context.logger?.warn ?? context.logger?.info;
90
+ log?.call(context.logger, `Vision & OCR Pipeline: disposing of a pipeline failed: ${error instanceof Error ? error.message : String(error)}`);
91
+ }
92
+ }
93
+ context.logger?.info('Vision & OCR Pipeline Extension deactivated');
94
+ },
95
+ };
96
+ }
97
+ export { VisionPipelineTool, imageInput } from './tools/visionPipeline.js';
98
+ export default createExtensionPack;
99
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAuB,MAAM,2BAA2B,CAAC;AAEpF,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC;AA0BtE;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAA4B,EAAE;IAChE,8EAA8E;IAC9E,6EAA6E;IAC7E,4EAA4E;IAC5E,oDAAoD;IACpD,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAiB,EAAE,EAAE,CACxC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC;IACpG,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAChG,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAgC,CAAC;IAC1D,uEAAuE;IACvE,2CAA2C;IAC3C,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,MAAM,WAAW,GAAG,CAAC,QAAwB,EAAE,EAAE;QAC/C,IAAI,WAAW;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC,CAAC;QACpG,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,oBAAoB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;YACxD,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAClC,MAAM,KAAK,GAAG,QAAQ,CAAC;YACvB,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;gBACf,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK;oBAAE,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACpE,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAEjD,OAAO;QACL,IAAI,EAAE,sCAAsC;QAC5C,OAAO;QACP,WAAW,EAAE;YACX;gBACE,EAAE,EAAE,IAAI,CAAC,IAAI;gBACb,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,IAAI,EAAE;gBACzC,OAAO,EAAE,IAAI;gBACb,eAAe,EAAE,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;aAC3D;SACF;QACD,UAAU,EAAE,KAAK,IAAI,EAAE;YACrB,WAAW,GAAG,KAAK,CAAC;YACpB,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACpE,CAAC;QACD,YAAY,EAAE,KAAK,IAAI,EAAE;YACvB,WAAW,GAAG,IAAI,CAAC;YACnB,MAAM,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;YACtC,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;gBAC7B,IAAI,QAAQ,CAAC;gBACb,IAAI,CAAC;oBACH,QAAQ,GAAG,MAAM,QAAQ,CAAC;gBAC5B,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS,CAAC,0DAA0D;gBACtE,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;gBAC3B,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC;oBACzD,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,0DAA0D,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAChJ,CAAC;YACH,CAAC;YACD,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,6CAA6C,CAAC,CAAC;QACtE,CAAC;KACF,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE3E,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * @fileoverview The vision-pipeline tool: OCR, handwriting, document layout,
3
+ * image description and CLIP embeddings through an AgentOS VisionPipeline.
4
+ */
5
+ import type { ITool, JSONSchemaObject, ToolExecutionContext, ToolExecutionResult } from '@framers/agentos';
6
+ /** What the tool reads from an image; see {@link VisionPipelineTool}. */
7
+ export type VisionMode = 'ocr' | 'handwriting' | 'layout' | 'describe' | 'embed' | 'auto';
8
+ /** The vision-pipeline tool's input. */
9
+ export interface VisionPipelineInput {
10
+ /** The image: a data:image URL, or an http(s) URL on a public host. */
11
+ imageUrl: string;
12
+ /** What to read (default `auto`). */
13
+ mode?: VisionMode;
14
+ /** The highest tier to use: 1 local OCR, 2 local vision models, 3 cloud vision (default). */
15
+ maxTier?: 1 | 2 | 3;
16
+ }
17
+ /** The vision-pipeline tool's output: the text found, or for `embed` the vector. */
18
+ export interface VisionPipelineOutput {
19
+ mode: VisionMode;
20
+ text?: string;
21
+ confidence?: number;
22
+ category?: string;
23
+ /** The pipeline tiers that produced the result. */
24
+ tiers?: string[];
25
+ /** How many text regions the winning tier located. */
26
+ regions?: number;
27
+ durationMs?: number;
28
+ /** For embed: the CLIP vector. */
29
+ embedding?: number[];
30
+ dimensions?: number;
31
+ }
32
+ /** The pipeline strategy a call runs under: tier 3 may reach cloud vision, tiers 1 and 2 stay local. */
33
+ export type VisionStrategy = 'progressive' | 'local-only';
34
+ /** Returns the pipeline for a strategy, made on first use. */
35
+ export type PipelineFor = (strategy: VisionStrategy) => Promise<{
36
+ process(image: Buffer | string, options?: {
37
+ forceCategory?: string;
38
+ tiers?: string[];
39
+ }): Promise<any>;
40
+ embed(image: Buffer | string): Promise<number[]>;
41
+ }>;
42
+ /**
43
+ * Whether a URL's host is this machine or off the public internet: `localhost`
44
+ * names, and the IPv4 and IPv6 literals above. The URL parser has already
45
+ * written other IPv4 spellings (`0x7f000001`, `127.1`) as dotted numbers. An
46
+ * IPv6 literal that cannot be read is treated as not public. The check reads
47
+ * the host as written: the address a name resolves to, and the target of a
48
+ * redirect, are not checked here.
49
+ */
50
+ export declare function isPrivateHost(hostname: string): boolean;
51
+ /**
52
+ * The image as the pipeline takes it: a data URL decoded to its bytes, an
53
+ * http(s) URL whose host is not this machine or a private network as is, or
54
+ * `undefined` for anything else. AgentOS also reads local file paths and
55
+ * fetches any URL, but a tool the model calls must not send the machine's
56
+ * files, or what its network serves, to a cloud vision model.
57
+ */
58
+ export declare function imageInput(value: unknown): Buffer | string | undefined;
59
+ /**
60
+ * The image as the tool hands it to the pipeline. A Buffer goes on as it is. An
61
+ * http(s) URL is fetched here through AgentOS's `imageToBuffer` with
62
+ * `untrusted: true`, which connects only to public network addresses (every
63
+ * address the host resolves to, and every redirect, is checked) and stops at
64
+ * 50 MiB and 30 seconds; the bytes go on. With an AgentOS without that mode
65
+ * (it has no `isPublicNetworkAddress` export) the pipeline gets the URL,
66
+ * already checked against the host as written.
67
+ */
68
+ export declare function loadImage(image: Buffer | string): Promise<Buffer | string>;
69
+ /** The vision-pipeline tool, on an AgentOS `VisionPipeline` per strategy. */
70
+ export declare class VisionPipelineTool implements ITool<VisionPipelineInput, VisionPipelineOutput> {
71
+ private readonly pipelineFor;
72
+ readonly id = "tool.vision-pipeline";
73
+ readonly name = "vision-pipeline";
74
+ readonly displayName = "Vision & OCR Pipeline";
75
+ readonly description: string;
76
+ readonly category = "media";
77
+ readonly hasSideEffects = false;
78
+ readonly inputSchema: JSONSchemaObject;
79
+ constructor(pipelineFor: PipelineFor);
80
+ execute(args: VisionPipelineInput, _context?: ToolExecutionContext): Promise<ToolExecutionResult<VisionPipelineOutput>>;
81
+ }
82
+ //# sourceMappingURL=visionPipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visionPipeline.d.ts","sourceRoot":"","sources":["../../src/tools/visionPipeline.ts"],"names":[],"mappings":"AACA;;;GAGG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE3G,yEAAyE;AACzE,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1F,wCAAwC;AACxC,MAAM,WAAW,mBAAmB;IAClC,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CACrB;AAED,oFAAoF;AACpF,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wGAAwG;AACxG,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,YAAY,CAAC;AAE1D,8DAA8D;AAC9D,MAAM,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC;IAC9D,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACtG,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAClD,CAAC,CAAC;AA+EH;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQvD;AAiCD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAetE;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAIhF;AAED,6EAA6E;AAC7E,qBAAa,kBAAmB,YAAW,KAAK,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;IA8B7E,OAAO,CAAC,QAAQ,CAAC,WAAW;IA7BxC,QAAQ,CAAC,EAAE,0BAA0B;IACrC,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,WAAW,2BAA2B;IAC/C,QAAQ,CAAC,WAAW,SAE8F;IAClH,QAAQ,CAAC,QAAQ,WAAW;IAC5B,QAAQ,CAAC,cAAc,SAAS;IAEhC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAkBpC;gBAE2B,WAAW,EAAE,WAAW;IAE/C,OAAO,CAAC,IAAI,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CAmD9H"}
@@ -0,0 +1,264 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * @fileoverview The vision-pipeline tool: OCR, handwriting, document layout,
4
+ * image description and CLIP embeddings through an AgentOS VisionPipeline.
5
+ */
6
+ import * as agentos from '@framers/agentos';
7
+ /**
8
+ * The lowest tier each mode needs: 1 is local OCR, 2 local vision models
9
+ * (TrOCR, Florence-2, CLIP), 3 cloud vision.
10
+ */
11
+ const TIER_NEEDED = {
12
+ auto: 1,
13
+ ocr: 1,
14
+ handwriting: 2,
15
+ layout: 2,
16
+ embed: 2,
17
+ describe: 3,
18
+ };
19
+ /**
20
+ * Whether an IPv4 address, as its four numbers, is off the public internet:
21
+ * "this network", private, carrier-grade NAT, loopback, link-local (cloud
22
+ * metadata services answer at 169.254.169.254), the IETF protocol block, the
23
+ * documentation and benchmarking ranges, multicast, reserved and broadcast.
24
+ */
25
+ function isNonPublicIPv4([a, b, c]) {
26
+ return (a === 0 ||
27
+ a === 10 ||
28
+ a === 127 ||
29
+ (a === 100 && b >= 64 && b <= 127) ||
30
+ (a === 169 && b === 254) ||
31
+ (a === 172 && b >= 16 && b <= 31) ||
32
+ (a === 192 && b === 0 && (c === 0 || c === 2)) ||
33
+ (a === 192 && b === 168) ||
34
+ (a === 198 && (b === 18 || b === 19)) ||
35
+ (a === 198 && b === 51 && c === 100) ||
36
+ (a === 203 && b === 0 && c === 113) ||
37
+ a >= 224);
38
+ }
39
+ /** The eight 16-bit groups of an IPv6 address, or `undefined` when the text is not one. */
40
+ function ipv6Groups(address) {
41
+ let text = address;
42
+ // A trailing dotted IPv4 (::ffff:1.2.3.4) is two groups.
43
+ const dotted = /^(.*:)(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(text);
44
+ if (dotted) {
45
+ const [w, x, y, z] = dotted.slice(2).map(Number);
46
+ if ([w, x, y, z].some((n) => n > 255))
47
+ return undefined;
48
+ text = `${dotted[1]}${((w << 8) | x).toString(16)}:${((y << 8) | z).toString(16)}`;
49
+ }
50
+ const halves = text.split('::');
51
+ if (halves.length > 2)
52
+ return undefined;
53
+ const head = halves[0] ? halves[0].split(':') : [];
54
+ const tail = halves.length === 2 && halves[1] ? halves[1].split(':') : [];
55
+ const fill = halves.length === 2 ? 8 - head.length - tail.length : 0;
56
+ if (halves.length === 2 ? fill < 1 : head.length !== 8)
57
+ return undefined;
58
+ const groups = [...head, ...Array(fill).fill('0'), ...tail];
59
+ if (!groups.every((group) => /^[0-9a-f]{1,4}$/.test(group)))
60
+ return undefined;
61
+ return groups.map((group) => parseInt(group, 16));
62
+ }
63
+ /**
64
+ * Whether an IPv6 address is off the public internet, the IPv4 address it
65
+ * carries included: unspecified, loopback, IPv4-compatible and IPv4-mapped,
66
+ * NAT64 (64:ff9b::/96 and 64:ff9b:1::/48), 6to4 (2002::/16), discard
67
+ * (100::/64), documentation (2001:db8::/32), unique local, link-local,
68
+ * site-local and multicast.
69
+ */
70
+ function isNonPublicIPv6(groups) {
71
+ const carried = (high, low) => isNonPublicIPv4([high >> 8, high & 255, low >> 8, low & 255]);
72
+ const [g0, g1, g2, g3, g4, g5, g6, g7] = groups;
73
+ const zeros = (from, to) => groups.slice(from, to).every((group) => group === 0);
74
+ if (zeros(0, 6))
75
+ return (g6 === 0 && g7 <= 1) || carried(g6, g7);
76
+ if (zeros(0, 5) && g5 === 0xffff)
77
+ return carried(g6, g7);
78
+ if (g0 === 0x64 && g1 === 0xff9b)
79
+ return g2 === 1 || !zeros(2, 6) || carried(g6, g7);
80
+ if (g0 === 0x2002)
81
+ return carried(g1, g2);
82
+ if (g0 === 0x100 && zeros(1, 4))
83
+ return true;
84
+ if (g0 === 0x2001 && g1 === 0xdb8)
85
+ return true;
86
+ return (g0 & 0xfe00) === 0xfc00 || (g0 & 0xffc0) === 0xfe80 || (g0 & 0xffc0) === 0xfec0 || (g0 & 0xff00) === 0xff00;
87
+ }
88
+ /**
89
+ * Whether a URL's host is this machine or off the public internet: `localhost`
90
+ * names, and the IPv4 and IPv6 literals above. The URL parser has already
91
+ * written other IPv4 spellings (`0x7f000001`, `127.1`) as dotted numbers. An
92
+ * IPv6 literal that cannot be read is treated as not public. The check reads
93
+ * the host as written: the address a name resolves to, and the target of a
94
+ * redirect, are not checked here.
95
+ */
96
+ export function isPrivateHost(hostname) {
97
+ const host = hostname.toLowerCase().replace(/^\[|\]$/g, '').replace(/\.$/, '');
98
+ if (host === 'localhost' || host.endsWith('.localhost'))
99
+ return true;
100
+ const v4 = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
101
+ if (v4)
102
+ return isNonPublicIPv4(v4.slice(1).map(Number));
103
+ if (!host.includes(':'))
104
+ return false;
105
+ const groups = ipv6Groups(host);
106
+ return groups === undefined || isNonPublicIPv6(groups);
107
+ }
108
+ /** The value of an ASCII hex digit, or -1. */
109
+ function hexValue(byte) {
110
+ if (byte >= 0x30 && byte <= 0x39)
111
+ return byte - 0x30;
112
+ if (byte >= 0x41 && byte <= 0x46)
113
+ return byte - 0x37;
114
+ if (byte >= 0x61 && byte <= 0x66)
115
+ return byte - 0x57;
116
+ return -1;
117
+ }
118
+ /**
119
+ * The bytes of a percent-encoded data URL payload: each `%XX` is one byte,
120
+ * any other character its UTF-8 bytes. A `%` that starts no valid escape is
121
+ * kept as it is, so the decoding never throws. One pass over two buffers.
122
+ */
123
+ function percentDecode(payload) {
124
+ const text = Buffer.from(payload, 'utf8');
125
+ const out = Buffer.allocUnsafe(text.length);
126
+ let length = 0;
127
+ for (let i = 0; i < text.length; i += 1) {
128
+ const high = text[i] === 0x25 && i + 2 < text.length ? hexValue(text[i + 1]) : -1;
129
+ const low = high >= 0 ? hexValue(text[i + 2]) : -1;
130
+ if (low >= 0) {
131
+ out[length] = high * 16 + low;
132
+ i += 2;
133
+ }
134
+ else {
135
+ out[length] = text[i];
136
+ }
137
+ length += 1;
138
+ }
139
+ return out.subarray(0, length);
140
+ }
141
+ /**
142
+ * The image as the pipeline takes it: a data URL decoded to its bytes, an
143
+ * http(s) URL whose host is not this machine or a private network as is, or
144
+ * `undefined` for anything else. AgentOS also reads local file paths and
145
+ * fetches any URL, but a tool the model calls must not send the machine's
146
+ * files, or what its network serves, to a cloud vision model.
147
+ */
148
+ export function imageInput(value) {
149
+ if (typeof value !== 'string')
150
+ return undefined;
151
+ const source = value.trim();
152
+ if (/^https?:\/\//i.test(source)) {
153
+ let url;
154
+ try {
155
+ url = new URL(source);
156
+ }
157
+ catch {
158
+ return undefined;
159
+ }
160
+ return isPrivateHost(url.hostname) ? undefined : source;
161
+ }
162
+ const data = /^data:image\/[^,]*?(;base64)?,(.*)$/is.exec(source);
163
+ if (!data)
164
+ return undefined;
165
+ return data[1] ? Buffer.from(data[2], 'base64') : percentDecode(data[2]);
166
+ }
167
+ /**
168
+ * The image as the tool hands it to the pipeline. A Buffer goes on as it is. An
169
+ * http(s) URL is fetched here through AgentOS's `imageToBuffer` with
170
+ * `untrusted: true`, which connects only to public network addresses (every
171
+ * address the host resolves to, and every redirect, is checked) and stops at
172
+ * 50 MiB and 30 seconds; the bytes go on. With an AgentOS without that mode
173
+ * (it has no `isPublicNetworkAddress` export) the pipeline gets the URL,
174
+ * already checked against the host as written.
175
+ */
176
+ export async function loadImage(image) {
177
+ const { imageToBuffer, isPublicNetworkAddress } = agentos;
178
+ if (typeof image !== 'string' || typeof isPublicNetworkAddress !== 'function')
179
+ return image;
180
+ return imageToBuffer(image, { untrusted: true });
181
+ }
182
+ /** The vision-pipeline tool, on an AgentOS `VisionPipeline` per strategy. */
183
+ export class VisionPipelineTool {
184
+ pipelineFor;
185
+ id = 'tool.vision-pipeline';
186
+ name = 'vision-pipeline';
187
+ displayName = 'Vision & OCR Pipeline';
188
+ description = 'Read and understand an image: printed text (ocr), handwriting, document layout, a description of the image, ' +
189
+ 'or a CLIP embedding vector. Local OCR runs first; local vision models and cloud vision run as maxTier allows.';
190
+ category = 'media';
191
+ hasSideEffects = false;
192
+ inputSchema = {
193
+ type: 'object',
194
+ properties: {
195
+ imageUrl: { type: 'string', description: 'The image: an http(s) URL or a data:image URL.' },
196
+ mode: {
197
+ type: 'string',
198
+ enum: ['ocr', 'handwriting', 'layout', 'describe', 'embed', 'auto'],
199
+ description: 'ocr for printed text, handwriting, layout for document structure, describe for what the image shows, ' +
200
+ 'embed for a CLIP vector, or auto (default) to let the pipeline decide.',
201
+ },
202
+ maxTier: {
203
+ type: 'number',
204
+ enum: [1, 2, 3],
205
+ description: 'The highest tier to use: 1 local OCR only, 2 local vision models, 3 cloud vision (default).',
206
+ },
207
+ },
208
+ required: ['imageUrl'],
209
+ };
210
+ constructor(pipelineFor) {
211
+ this.pipelineFor = pipelineFor;
212
+ }
213
+ async execute(args, _context) {
214
+ const image = imageInput(args.imageUrl);
215
+ if (image === undefined) {
216
+ return {
217
+ success: false,
218
+ error: 'imageUrl must be a data:image URL or an http(s) URL on a public host: local file paths are not read, nor local or private network addresses.',
219
+ };
220
+ }
221
+ const mode = args.mode ?? 'auto';
222
+ if (typeof mode !== 'string' || !Object.hasOwn(TIER_NEEDED, mode)) {
223
+ return { success: false, error: `mode must be one of ${Object.keys(TIER_NEEDED).join(', ')}.` };
224
+ }
225
+ const maxTier = args.maxTier === 1 || args.maxTier === 2 ? args.maxTier : 3;
226
+ if (TIER_NEEDED[mode] > maxTier) {
227
+ return { success: false, error: `${mode} needs maxTier ${TIER_NEEDED[mode]} or higher; this call allows ${maxTier}.` };
228
+ }
229
+ try {
230
+ const input = await loadImage(image);
231
+ const pipeline = await this.pipelineFor(maxTier === 3 ? 'progressive' : 'local-only');
232
+ if (mode === 'embed') {
233
+ const embedding = await pipeline.embed(input);
234
+ return { success: true, output: { mode, embedding, dimensions: embedding.length } };
235
+ }
236
+ const options = maxTier === 1 || mode === 'ocr'
237
+ ? { tiers: ['ocr'] }
238
+ : mode === 'handwriting'
239
+ ? { forceCategory: 'handwritten' }
240
+ : mode === 'layout'
241
+ ? { forceCategory: 'document-layout' }
242
+ : mode === 'describe'
243
+ ? { tiers: ['cloud-vision'] }
244
+ : undefined;
245
+ const result = await pipeline.process(input, options);
246
+ return {
247
+ success: true,
248
+ output: {
249
+ mode,
250
+ text: result.text,
251
+ confidence: result.confidence,
252
+ category: result.category,
253
+ tiers: result.tiers,
254
+ regions: result.regions?.length ?? 0,
255
+ durationMs: result.durationMs,
256
+ },
257
+ };
258
+ }
259
+ catch (error) {
260
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
261
+ }
262
+ }
263
+ }
264
+ //# sourceMappingURL=visionPipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visionPipeline.js","sourceRoot":"","sources":["../../src/tools/visionPipeline.ts"],"names":[],"mappings":"AAAA,cAAc;AACd;;;GAGG;AAEH,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAyC5C;;;GAGG;AACH,MAAM,WAAW,GAAkC;IACjD,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,CAAC;IACN,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;CACZ,CAAC;AAEF;;;;;GAKG;AACH,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAW;IAC1C,OAAO,CACL,CAAC,KAAK,CAAC;QACP,CAAC,KAAK,EAAE;QACR,CAAC,KAAK,GAAG;QACT,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC;QAClC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;QACxB,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACjC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;QACxB,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACrC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC;QACpC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC;QACnC,CAAC,IAAI,GAAG,CACT,CAAC;AACJ,CAAC;AAED,2FAA2F;AAC3F,SAAS,UAAU,CAAC,OAAe;IACjC,IAAI,IAAI,GAAG,OAAO,CAAC;IACnB,yDAAyD;IACzD,MAAM,MAAM,GAAG,mDAAmD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9E,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QACxD,IAAI,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;IACrF,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzE,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9E,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,MAAgB;IACvC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,GAAW,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;IAC7G,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC;IAChD,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAU,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;IACjG,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjE,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM;QAAE,OAAO,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACzD,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,MAAM;QAAE,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACrF,IAAI,EAAE,KAAK,MAAM;QAAE,OAAO,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,EAAE,KAAK,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,EAAE,KAAK,MAAM,IAAI,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,KAAK,MAAM,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,KAAK,MAAM,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,KAAK,MAAM,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,KAAK,MAAM,CAAC;AACtH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC/E,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IACrE,MAAM,EAAE,GAAG,8CAA8C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrE,IAAI,EAAE;QAAE,OAAO,eAAe,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,MAAM,KAAK,SAAS,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;AACzD,CAAC;AAED,8CAA8C;AAC9C,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,IAAI,GAAG,IAAI,CAAC;IACrD,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,IAAI,GAAG,IAAI,CAAC;IACrD,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,IAAI,GAAG,IAAI,CAAC;IACrD,OAAO,CAAC,CAAC,CAAC;AACZ,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClF,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC;YAC9B,CAAC,IAAI,CAAC,CAAC;QACT,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,MAAM,IAAI,CAAC,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1D,CAAC;IACD,MAAM,IAAI,GAAG,uCAAuC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClE,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAsB;IACpD,MAAM,EAAE,aAAa,EAAE,sBAAsB,EAAE,GAAG,OAAO,CAAC;IAC1D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,sBAAsB,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAC5F,OAAO,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,6EAA6E;AAC7E,MAAM,OAAO,kBAAkB;IA8BA;IA7BpB,EAAE,GAAG,sBAAsB,CAAC;IAC5B,IAAI,GAAG,iBAAiB,CAAC;IACzB,WAAW,GAAG,uBAAuB,CAAC;IACtC,WAAW,GAClB,8GAA8G;QAC9G,+GAA+G,CAAC;IACzG,QAAQ,GAAG,OAAO,CAAC;IACnB,cAAc,GAAG,KAAK,CAAC;IAEvB,WAAW,GAAqB;QACvC,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gDAAgD,EAAE;YAC3F,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC;gBACnE,WAAW,EACT,uGAAuG;oBACvG,wEAAwE;aAC3E;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBACf,WAAW,EAAE,6FAA6F;aAC3G;SACF;QACD,QAAQ,EAAE,CAAC,UAAU,CAAC;KACvB,CAAC;IAEF,YAA6B,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAAG,CAAC;IAEzD,KAAK,CAAC,OAAO,CAAC,IAAyB,EAAE,QAA+B;QACtE,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,8IAA8I;aACtJ,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAe,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC;QAC7C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC;YAClE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAClG,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,OAAO,EAAE,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,kBAAkB,WAAW,CAAC,IAAI,CAAC,gCAAgC,OAAO,GAAG,EAAE,CAAC;QACzH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;YACrC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;YACtF,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC9C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YACtF,CAAC;YACD,MAAM,OAAO,GACX,OAAO,KAAK,CAAC,IAAI,IAAI,KAAK,KAAK;gBAC7B,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE;gBACpB,CAAC,CAAC,IAAI,KAAK,aAAa;oBACtB,CAAC,CAAC,EAAE,aAAa,EAAE,aAAa,EAAE;oBAClC,CAAC,CAAC,IAAI,KAAK,QAAQ;wBACjB,CAAC,CAAC,EAAE,aAAa,EAAE,iBAAiB,EAAE;wBACtC,CAAC,CAAC,IAAI,KAAK,UAAU;4BACnB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,cAAc,CAAC,EAAE;4BAC7B,CAAC,CAAC,SAAS,CAAC;YACtB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACtD,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE;oBACN,IAAI;oBACJ,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,UAAU,EAAE,MAAM,CAAC,UAAU;oBAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;oBACpC,UAAU,EAAE,MAAM,CAAC,UAAU;iBAC9B;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3F,CAAC;IACH,CAAC;CACF"}
package/manifest.json CHANGED
@@ -2,16 +2,16 @@
2
2
  "$schema": "https://agentos.sh/schemas/extension-manifest-v1.json",
3
3
  "id": "com.framers.tools.vision-pipeline",
4
4
  "name": "Vision & OCR Pipeline",
5
- "version": "0.1.0",
5
+ "version": "0.2.1",
6
6
  "description": "Progressive vision pipeline with PaddleOCR, TrOCR, Florence-2, CLIP, and cloud vision (GPT-4o, Claude).",
7
7
  "author": {
8
8
  "name": "Frame.dev",
9
9
  "email": "support@frame.dev",
10
- "url": "https://github.com/framersai"
10
+ "url": "https://github.com/framerslab"
11
11
  },
12
12
  "license": "MIT",
13
13
  "keywords": ["vision", "ocr", "paddle", "trocr", "florence", "clip", "document-ai"],
14
- "agentosVersion": "^2.0.0",
14
+ "agentosVersion": ">=0.10.40",
15
15
  "categories": ["tool", "media"],
16
16
  "platforms": [],
17
17
  "sdk": "none",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@framers/agentos-ext-vision-pipeline",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Vision & OCR pipeline extension for AgentOS — PaddleOCR, TrOCR, Florence-2, CLIP, and cloud vision",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -38,26 +38,35 @@
38
38
  "license": "MIT",
39
39
  "repository": {
40
40
  "type": "git",
41
- "url": "https://github.com/framersai/agentos-extensions.git",
41
+ "url": "git+https://github.com/framerslab/agentos-extensions.git",
42
42
  "directory": "registry/curated/tools/vision-pipeline"
43
43
  },
44
44
  "publishConfig": {
45
45
  "access": "public"
46
46
  },
47
47
  "peerDependencies": {
48
- "@framers/agentos": "^0.5.2"
48
+ "@framers/agentos": ">=0.10.40"
49
49
  },
50
50
  "devDependencies": {
51
- "@framers/agentos": "^0.5.2",
51
+ "@framers/agentos": "^0.12.8",
52
52
  "@types/node": "^20.12.12",
53
53
  "rimraf": "^5.0.7",
54
54
  "typescript": "^5.4.5",
55
- "vitest": "^1.6.0"
55
+ "vitest": "^3.2.7"
56
56
  },
57
+ "homepage": "https://github.com/framerslab/agentos-extensions/tree/master/registry/curated/tools/vision-pipeline#readme",
58
+ "bugs": {
59
+ "url": "https://github.com/framerslab/agentos-extensions/issues"
60
+ },
61
+ "files": [
62
+ "dist",
63
+ "manifest.json",
64
+ "SKILL.md"
65
+ ],
57
66
  "scripts": {
58
67
  "build": "tsc",
59
68
  "dev": "tsc --watch",
60
- "test": "vitest run",
69
+ "test": "vitest run --passWithNoTests",
61
70
  "test:watch": "vitest",
62
71
  "clean": "rimraf dist"
63
72
  }
package/src/index.ts DELETED
@@ -1,116 +0,0 @@
1
- // @ts-nocheck
2
- /**
3
- * @fileoverview Vision & OCR Pipeline Extension Pack — progressive multi-tier
4
- * vision pipeline as an agent tool.
5
- *
6
- * This is a minimal stub pack. The actual vision pipeline implementation is
7
- * provided by the core AgentOS vision module; this extension pack registers
8
- * the tool descriptor so the agent can discover and invoke it.
9
- *
10
- * Pipeline tiers:
11
- * Tier 1 (local, fast): PaddleOCR for printed text
12
- * Tier 2 (local, medium): TrOCR for handwriting, Florence-2 for layout
13
- * Tier 3 (cloud, slow): GPT-4o / Claude vision for complex understanding
14
- *
15
- * CLIP embeddings are generated alongside any tier for semantic image search.
16
- *
17
- * @module @framers/agentos-ext-vision-pipeline
18
- */
19
-
20
- /* ------------------------------------------------------------------ */
21
- /* Extension pack types */
22
- /* ------------------------------------------------------------------ */
23
-
24
- export interface ExtensionContext {
25
- options?: Record<string, unknown>;
26
- secrets?: Record<string, string>;
27
- getSecret?: (key: string) => string | undefined;
28
- logger?: { info: (msg: string) => void };
29
- }
30
-
31
- export interface ExtensionPack {
32
- name: string;
33
- version: string;
34
- descriptors: Array<{
35
- id: string;
36
- kind: string;
37
- priority?: number;
38
- payload: unknown;
39
- requiredSecrets?: Array<{ id: string; optional?: boolean }>;
40
- }>;
41
- onActivate?: () => Promise<void>;
42
- onDeactivate?: () => Promise<void>;
43
- }
44
-
45
- /* ------------------------------------------------------------------ */
46
- /* Stub tool definition */
47
- /* ------------------------------------------------------------------ */
48
-
49
- /**
50
- * Stub tool for the vision & OCR pipeline.
51
- * Implementation is resolved at runtime by the AgentOS vision module.
52
- */
53
- const visionPipelineTool = {
54
- name: 'vision-pipeline',
55
- description:
56
- 'Extract text, understand layout, and generate embeddings from images using a progressive pipeline: PaddleOCR -> TrOCR/Florence-2 -> GPT-4o/Claude vision.',
57
- parameters: {
58
- type: 'object' as const,
59
- properties: {
60
- imageUrl: {
61
- type: 'string',
62
- description: 'URL or local path of the image to analyze',
63
- },
64
- mode: {
65
- type: 'string',
66
- enum: ['ocr', 'handwriting', 'layout', 'describe', 'embed', 'auto'],
67
- description:
68
- 'Analysis mode — "ocr" for printed text, "handwriting" for handwritten text, "layout" for document structure, "describe" for general image understanding, "embed" for CLIP vector, "auto" to let the pipeline decide (default: auto)',
69
- },
70
- maxTier: {
71
- type: 'number',
72
- enum: [1, 2, 3],
73
- description:
74
- 'Maximum pipeline tier to use — 1 (local OCR only), 2 (local vision models), 3 (cloud vision). Default: 3',
75
- },
76
- language: {
77
- type: 'string',
78
- description: 'Language hint for OCR (e.g. "en", "zh", "ja"). Default: "en"',
79
- },
80
- },
81
- required: ['imageUrl'],
82
- },
83
- execute: async () => {
84
- throw new Error('vision-pipeline stub — wire to VisionPipelineService at runtime.');
85
- },
86
- };
87
-
88
- /* ------------------------------------------------------------------ */
89
- /* Factory */
90
- /* ------------------------------------------------------------------ */
91
-
92
- /**
93
- * Create the Vision & OCR Pipeline extension pack.
94
- *
95
- * Registers the vision-pipeline tool. Actual implementation is provided
96
- * by the core AgentOS vision module and wired at runtime.
97
- */
98
- export function createExtensionPack(context: ExtensionContext): ExtensionPack {
99
- return {
100
- name: '@framers/agentos-ext-vision-pipeline',
101
- version: '0.1.0',
102
- descriptors: [
103
- {
104
- id: visionPipelineTool.name,
105
- kind: 'tool' as const,
106
- priority: 45,
107
- payload: visionPipelineTool,
108
- requiredSecrets: [{ id: 'openai.apiKey', optional: true }],
109
- },
110
- ],
111
- onActivate: async () => context.logger?.info('Vision & OCR Pipeline Extension activated'),
112
- onDeactivate: async () => context.logger?.info('Vision & OCR Pipeline Extension deactivated'),
113
- };
114
- }
115
-
116
- export default createExtensionPack;