signalloomai 0.1.0

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/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # Signal Loom AI — LangChain Integration
2
+
3
+ <p align="center">
4
+ <strong>LoomLens AI</strong> — Token cost estimation for AI pipelines.<br>
5
+ Compare GPT-4o, Claude Sonnet 4, Gemini 2.5, DeepSeek, and more. Before you run.
6
+ </p>
7
+
8
+ <p align="center">
9
+ <a href="https://signalloomai.com">Website</a> ·
10
+ <a href="https://signalloomai.com/docs">API Docs</a> ·
11
+ <a href="https://signalloomai.com/prompt-integrity.html">Prompt Integrity</a>
12
+ </p>
13
+
14
+ ---
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ npm install signalloomai
20
+ ```
21
+
22
+ Requires Node.js 18+.
23
+
24
+ ---
25
+
26
+ ## Quick Start
27
+
28
+ ```typescript
29
+ import { LoomLensTool } from 'signalloomai';
30
+
31
+ // Initialize with your API key
32
+ const tool = new LoomLensTool({ apiKey: process.env.SIGNALLOOM_API_KEY });
33
+
34
+ // Get a cost estimate
35
+ const result = await tool.estimate({
36
+ job_description: 'Customer support agent with 5 sub-agents handling billing and shipping',
37
+ num_agents: 5,
38
+ estimated_runtime_minutes: 20,
39
+ complexity: 'standard',
40
+ target_models: [
41
+ 'openai/gpt-4o',
42
+ 'anthropic/claude-sonnet-4-20250514',
43
+ 'google/gemini-2.5-flash',
44
+ ],
45
+ });
46
+
47
+ console.log(`Cheapest model: ${result.cheapest_model}`);
48
+ console.log(`Savings vs most expensive: $${result.savings_vs_expensive}`);
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Use with LangChain Agents
54
+
55
+ ```typescript
56
+ import { LoomLensTool } from 'signalloomai';
57
+ import { ChatOpenAI } from '@langchain/openai';
58
+ import { createReactAgent } from 'langchain-agents';
59
+
60
+ // Initialize
61
+ const loomLensTool = new LoomLensTool({ apiKey: process.env.SIGNALLOOM_API_KEY });
62
+ const llm = new ChatOpenAI({ modelName: 'gpt-4o', temperature: 0 });
63
+
64
+ // Create agent with LoomLens as a tool
65
+ const agent = createReactAgent({
66
+ llm,
67
+ tools: [loomLensTool.toLangChainTool()],
68
+ });
69
+
70
+ // Run
71
+ const response = await agent.invoke({
72
+ input: 'Compare the cost of running a 10-agent research pipeline on GPT-4o vs Claude Sonnet 4',
73
+ });
74
+ ```
75
+
76
+ ---
77
+
78
+ ## API Key
79
+
80
+ Get your API key at **[signalloomai.com](https://signalloomai.com)**.
81
+
82
+ Set it as an environment variable:
83
+
84
+ ```bash
85
+ export SIGNALLOOM_API_KEY=sk_...
86
+ ```
87
+
88
+ Or pass it directly:
89
+
90
+ ```typescript
91
+ const tool = new LoomLensTool({ apiKey: 'sk_your_key_here' });
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Prompt Integrity
97
+
98
+ **LoomLens AI does NOT log prompts or job descriptions.**
99
+
100
+ We estimate cost based on token counts and model pricing — not by reading your content. See our full [Prompt Integrity Policy](https://signalloomai.com/prompt-integrity.html).
101
+
102
+ ---
103
+
104
+ ## Available Models
105
+
106
+ | Provider | Model |
107
+ |----------|-------|
108
+ | OpenAI | `gpt-4o`, `gpt-4o-mini` |
109
+ | Anthropic | `claude-sonnet-4-20250514`, `claude-opus-4-6` |
110
+ | Google | `gemini-2.5-flash`, `gemini-2.5-pro` |
111
+ | DeepSeek | `deepseek-chat-v3` |
112
+ | xAI | `grok-3` |
113
+ | MiniMax | `MiniMax-M2.7` |
114
+
115
+ ---
116
+
117
+ ## License
118
+
119
+ MIT · [signalloomai.com/terms.html](https://signalloomai.com/terms.html)
package/dist/index.cjs ADDED
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ LoomLensTool: () => LoomLensTool,
24
+ SIGNALLOOM_PACKAGE_INFO: () => SIGNALLOOM_PACKAGE_INFO,
25
+ createLoomLensTool: () => createLoomLensTool
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+ var import_tools = require("@langchain/core/tools");
29
+ var BASE_URL = "https://api.signalloomai.com";
30
+ var TOOL_NAME = "loomlens_ai_estimate";
31
+ var TOOL_DESCRIPTION = `
32
+ **LoomLens AI \u2014 Token Cost Estimator**
33
+
34
+ Use this tool to compare AI pipeline costs across different models BEFORE you run them.
35
+ No more billing surprises. Estimate your cost per job across GPT-4o, Claude Sonnet 4,
36
+ Claude Opus 4, Gemini 2.5 Flash, DeepSeek Chat v3, Grok 3, and more.
37
+
38
+ Input:
39
+ - job_description: What the pipeline does (natural language)
40
+ - target_models: List of model IDs to compare
41
+ - num_agents: Number of concurrent agents (default: 1)
42
+ - estimated_runtime_minutes: Expected runtime in minutes (default: 5)
43
+ - complexity: trivial | simple | standard | complex | extreme (default: standard)
44
+
45
+ Output:
46
+ - Cost estimate (low/mid/high) for each model
47
+ - Cheapest model recommendation
48
+ - Potential savings vs most expensive option
49
+
50
+ **Prompt Integrity: This tool does NOT log prompts or job descriptions.**
51
+ See: https://signalloomai.com/prompt-integrity.html
52
+
53
+ Available models:
54
+ - openai/gpt-4o
55
+ - openai/gpt-4o-mini
56
+ - anthropic/claude-sonnet-4-20250514
57
+ - anthropic/claude-opus-4-6
58
+ - google/gemini-2.5-flash
59
+ - google/gemini-2.5-pro
60
+ - deepseek/deepseek-chat-v3
61
+ - xai/grok-3
62
+ - minimax/MiniMax-M2.7
63
+ `.trim();
64
+ var LoomLensTool = class {
65
+ constructor(config = {}) {
66
+ this.name = TOOL_NAME;
67
+ this.description = TOOL_DESCRIPTION;
68
+ this.apiKey = config.apiKey || process.env.SIGNALLOOM_API_KEY || process.env.SIGNALLOOM_API_KEY || "";
69
+ this.baseUrl = config.baseUrl || BASE_URL;
70
+ if (!this.apiKey) {
71
+ console.warn(
72
+ "[LoomLensTool] No API key provided. Set SIGNALLOOM_API_KEY env var or pass apiKey."
73
+ );
74
+ }
75
+ }
76
+ /**
77
+ * Estimate token cost for an AI pipeline.
78
+ */
79
+ async estimate(input) {
80
+ if (!this.apiKey) {
81
+ throw new Error(
82
+ "Signal Loom API key required. Set SIGNALLOOM_API_KEY env var or pass apiKey."
83
+ );
84
+ }
85
+ const payload = {
86
+ job_description: input.job_description,
87
+ num_agents: input.num_agents ?? 1,
88
+ estimated_runtime_minutes: input.estimated_runtime_minutes ?? 5,
89
+ complexity: input.complexity ?? "standard",
90
+ target_models: input.target_models,
91
+ include_postmortem: input.include_postmortem ?? false
92
+ };
93
+ const response = await fetch(`${this.baseUrl}/v1/estimate`, {
94
+ method: "POST",
95
+ headers: {
96
+ "Content-Type": "application/json",
97
+ Authorization: `Bearer ${this.apiKey}`
98
+ },
99
+ body: JSON.stringify(payload)
100
+ });
101
+ if (!response.ok) {
102
+ const error = await response.json().catch(() => ({ detail: response.statusText }));
103
+ throw new Error(`LoomLens API error ${response.status}: ${error?.detail ?? response.statusText}`);
104
+ }
105
+ return response.json();
106
+ }
107
+ /**
108
+ * Estimate and return a human-readable summary string.
109
+ */
110
+ async estimateSummary(input) {
111
+ const result = await this.estimate(input);
112
+ const { cheapest_model, most_expensive_model, savings_vs_expensive, models, billing } = result;
113
+ const lines = [
114
+ `## LoomLens AI Estimate`,
115
+ ``,
116
+ `**Cheapest:** ${cheapest_model}`,
117
+ `**Most expensive:** ${most_expensive_model}`,
118
+ `**Savings (cheapest vs most expensive):** $${savings_vs_expensive.toFixed(6)} per job`,
119
+ ``,
120
+ `### Cost Comparison`,
121
+ ``,
122
+ ...models.map(
123
+ (m) => ` ${m.model}: **$${m.estimated_cost_mid.toFixed(6)}/job** (range: $${m.estimated_cost_low.toFixed(6)}\u2013$${m.estimated_cost_high.toFixed(6)})${m.model === cheapest_model ? " \u2190 CHEAPEST" : ""}${m.model === most_expensive_model ? " \u2190 MOST EXPENSIVE" : ""}`
124
+ ),
125
+ ``,
126
+ `**Estimate call cost:** $${billing.call_cost_usd.toFixed(6)}`,
127
+ `**Quota remaining:** ${billing.remaining_this_month} calls this month`,
128
+ ``,
129
+ `*Powered by LoomLens AI \u2014 https://signalloomai.com/token-estimator.html*`
130
+ ];
131
+ return lines.join("\n");
132
+ }
133
+ /**
134
+ * Return a LangChain-compatible BaseTool instance.
135
+ *
136
+ * Requires langchain as a peer dependency.
137
+ */
138
+ toLangChainTool() {
139
+ const self = this;
140
+ const ToolClass = import_tools.Tool;
141
+ return new ToolClass({
142
+ name: self.name,
143
+ description: self.description,
144
+ returnDirect: false,
145
+ async call(input) {
146
+ let parsed;
147
+ if (typeof input === "string") {
148
+ try {
149
+ parsed = JSON.parse(input);
150
+ } catch {
151
+ throw new Error(
152
+ `LoomLensTool requires JSON input. Received: ${input.slice(0, 100)}`
153
+ );
154
+ }
155
+ } else {
156
+ parsed = input;
157
+ }
158
+ if (!parsed.job_description || !parsed.target_models?.length) {
159
+ throw new Error(
160
+ "LoomLensTool requires job_description and target_models. Example: { job_description: 'Research agent', target_models: ['openai/gpt-4o'] }"
161
+ );
162
+ }
163
+ return self.estimateSummary(parsed);
164
+ }
165
+ });
166
+ }
167
+ };
168
+ function createLoomLensTool(config) {
169
+ return new LoomLensTool(config);
170
+ }
171
+ var SIGNALLOOM_PACKAGE_INFO = {
172
+ name: "signalloomai",
173
+ version: "1.0.0",
174
+ homepage: "https://signalloomai.com",
175
+ docs: "https://signalloomai.com/docs",
176
+ promptIntegrity: "https://signalloomai.com/prompt-integrity.html"
177
+ /** Prompt: This tool does NOT log prompts or job descriptions. */
178
+ };
179
+ // Annotate the CommonJS export names for ESM import in node:
180
+ 0 && (module.exports = {
181
+ LoomLensTool,
182
+ SIGNALLOOM_PACKAGE_INFO,
183
+ createLoomLensTool
184
+ });
@@ -0,0 +1,95 @@
1
+ import { Tool } from '@langchain/core/tools';
2
+
3
+ /**
4
+ * Signal Loom AI — LangChain Tool Wrapper
5
+ * ========================================
6
+ * Exposes LoomLens AI as a LangChain-compatible tool.
7
+ *
8
+ * Install:
9
+ * npm install signalloomai
10
+ *
11
+ * Usage:
12
+ * import { LoomLensTool } from 'signalloomai';
13
+ *
14
+ * const tool = new LoomLensTool({ apiKey: 'sk_...' });
15
+ *
16
+ * // Use as a LangChain tool
17
+ * const model = new ChatOpenAI({ modelName: 'gpt-4o' });
18
+ * const agent = createReactAgent({ llm: model, tools: [tool.toLangChainTool()] });
19
+ *
20
+ * const result = await agent.invoke({
21
+ * input: 'Compare the cost of running a 5-agent pipeline on GPT-4o vs Claude Sonnet 4'
22
+ * });
23
+ *
24
+ * Docs: https://signalloomai.com/docs
25
+ * Prompt Integrity: https://signalloomai.com/prompt-integrity.html
26
+ */
27
+
28
+ interface LoomLensEstimateInput {
29
+ /** Natural language description of the AI pipeline job */
30
+ job_description: string;
31
+ /** List of model IDs to compare */
32
+ target_models: string[];
33
+ /** Number of concurrent agents (default: 1) */
34
+ num_agents?: number;
35
+ /** Estimated runtime in minutes (default: 5.0) */
36
+ estimated_runtime_minutes?: number;
37
+ /** Task complexity (default: 'standard') */
38
+ complexity?: "trivial" | "simple" | "standard" | "complex" | "extreme";
39
+ /** Include detailed cost breakdown (default: false) */
40
+ include_postmortem?: boolean;
41
+ }
42
+ interface LoomLensEstimateResult {
43
+ cheapest_model: string;
44
+ most_expensive_model: string;
45
+ savings_vs_expensive: number;
46
+ models: Array<{
47
+ model: string;
48
+ estimated_cost_mid: number;
49
+ estimated_cost_low: number;
50
+ estimated_cost_high: number;
51
+ }>;
52
+ billing: {
53
+ tier: string;
54
+ call_cost_usd: number;
55
+ used_this_month: number;
56
+ remaining_this_month: number;
57
+ };
58
+ }
59
+ interface LoomLensToolConfig {
60
+ /** Your Signal Loom API key. Falls back to SIGNALLOOM_API_KEY env var. */
61
+ apiKey?: string;
62
+ /** API base URL. Defaults to production. */
63
+ baseUrl?: string;
64
+ }
65
+ declare class LoomLensTool {
66
+ apiKey: string;
67
+ baseUrl: string;
68
+ readonly name = "loomlens_ai_estimate";
69
+ readonly description: string;
70
+ constructor(config?: LoomLensToolConfig);
71
+ /**
72
+ * Estimate token cost for an AI pipeline.
73
+ */
74
+ estimate(input: LoomLensEstimateInput): Promise<LoomLensEstimateResult>;
75
+ /**
76
+ * Estimate and return a human-readable summary string.
77
+ */
78
+ estimateSummary(input: LoomLensEstimateInput): Promise<string>;
79
+ /**
80
+ * Return a LangChain-compatible BaseTool instance.
81
+ *
82
+ * Requires langchain as a peer dependency.
83
+ */
84
+ toLangChainTool(): Tool;
85
+ }
86
+ declare function createLoomLensTool(config?: LoomLensToolConfig): LoomLensTool;
87
+ declare const SIGNALLOOM_PACKAGE_INFO: {
88
+ name: string;
89
+ version: string;
90
+ homepage: string;
91
+ docs: string;
92
+ promptIntegrity: string;
93
+ };
94
+
95
+ export { type LoomLensEstimateInput, type LoomLensEstimateResult, LoomLensTool, type LoomLensToolConfig, SIGNALLOOM_PACKAGE_INFO, createLoomLensTool };
@@ -0,0 +1,95 @@
1
+ import { Tool } from '@langchain/core/tools';
2
+
3
+ /**
4
+ * Signal Loom AI — LangChain Tool Wrapper
5
+ * ========================================
6
+ * Exposes LoomLens AI as a LangChain-compatible tool.
7
+ *
8
+ * Install:
9
+ * npm install signalloomai
10
+ *
11
+ * Usage:
12
+ * import { LoomLensTool } from 'signalloomai';
13
+ *
14
+ * const tool = new LoomLensTool({ apiKey: 'sk_...' });
15
+ *
16
+ * // Use as a LangChain tool
17
+ * const model = new ChatOpenAI({ modelName: 'gpt-4o' });
18
+ * const agent = createReactAgent({ llm: model, tools: [tool.toLangChainTool()] });
19
+ *
20
+ * const result = await agent.invoke({
21
+ * input: 'Compare the cost of running a 5-agent pipeline on GPT-4o vs Claude Sonnet 4'
22
+ * });
23
+ *
24
+ * Docs: https://signalloomai.com/docs
25
+ * Prompt Integrity: https://signalloomai.com/prompt-integrity.html
26
+ */
27
+
28
+ interface LoomLensEstimateInput {
29
+ /** Natural language description of the AI pipeline job */
30
+ job_description: string;
31
+ /** List of model IDs to compare */
32
+ target_models: string[];
33
+ /** Number of concurrent agents (default: 1) */
34
+ num_agents?: number;
35
+ /** Estimated runtime in minutes (default: 5.0) */
36
+ estimated_runtime_minutes?: number;
37
+ /** Task complexity (default: 'standard') */
38
+ complexity?: "trivial" | "simple" | "standard" | "complex" | "extreme";
39
+ /** Include detailed cost breakdown (default: false) */
40
+ include_postmortem?: boolean;
41
+ }
42
+ interface LoomLensEstimateResult {
43
+ cheapest_model: string;
44
+ most_expensive_model: string;
45
+ savings_vs_expensive: number;
46
+ models: Array<{
47
+ model: string;
48
+ estimated_cost_mid: number;
49
+ estimated_cost_low: number;
50
+ estimated_cost_high: number;
51
+ }>;
52
+ billing: {
53
+ tier: string;
54
+ call_cost_usd: number;
55
+ used_this_month: number;
56
+ remaining_this_month: number;
57
+ };
58
+ }
59
+ interface LoomLensToolConfig {
60
+ /** Your Signal Loom API key. Falls back to SIGNALLOOM_API_KEY env var. */
61
+ apiKey?: string;
62
+ /** API base URL. Defaults to production. */
63
+ baseUrl?: string;
64
+ }
65
+ declare class LoomLensTool {
66
+ apiKey: string;
67
+ baseUrl: string;
68
+ readonly name = "loomlens_ai_estimate";
69
+ readonly description: string;
70
+ constructor(config?: LoomLensToolConfig);
71
+ /**
72
+ * Estimate token cost for an AI pipeline.
73
+ */
74
+ estimate(input: LoomLensEstimateInput): Promise<LoomLensEstimateResult>;
75
+ /**
76
+ * Estimate and return a human-readable summary string.
77
+ */
78
+ estimateSummary(input: LoomLensEstimateInput): Promise<string>;
79
+ /**
80
+ * Return a LangChain-compatible BaseTool instance.
81
+ *
82
+ * Requires langchain as a peer dependency.
83
+ */
84
+ toLangChainTool(): Tool;
85
+ }
86
+ declare function createLoomLensTool(config?: LoomLensToolConfig): LoomLensTool;
87
+ declare const SIGNALLOOM_PACKAGE_INFO: {
88
+ name: string;
89
+ version: string;
90
+ homepage: string;
91
+ docs: string;
92
+ promptIntegrity: string;
93
+ };
94
+
95
+ export { type LoomLensEstimateInput, type LoomLensEstimateResult, LoomLensTool, type LoomLensToolConfig, SIGNALLOOM_PACKAGE_INFO, createLoomLensTool };
package/dist/index.js ADDED
@@ -0,0 +1,157 @@
1
+ // src/index.ts
2
+ import { Tool } from "@langchain/core/tools";
3
+ var BASE_URL = "https://api.signalloomai.com";
4
+ var TOOL_NAME = "loomlens_ai_estimate";
5
+ var TOOL_DESCRIPTION = `
6
+ **LoomLens AI \u2014 Token Cost Estimator**
7
+
8
+ Use this tool to compare AI pipeline costs across different models BEFORE you run them.
9
+ No more billing surprises. Estimate your cost per job across GPT-4o, Claude Sonnet 4,
10
+ Claude Opus 4, Gemini 2.5 Flash, DeepSeek Chat v3, Grok 3, and more.
11
+
12
+ Input:
13
+ - job_description: What the pipeline does (natural language)
14
+ - target_models: List of model IDs to compare
15
+ - num_agents: Number of concurrent agents (default: 1)
16
+ - estimated_runtime_minutes: Expected runtime in minutes (default: 5)
17
+ - complexity: trivial | simple | standard | complex | extreme (default: standard)
18
+
19
+ Output:
20
+ - Cost estimate (low/mid/high) for each model
21
+ - Cheapest model recommendation
22
+ - Potential savings vs most expensive option
23
+
24
+ **Prompt Integrity: This tool does NOT log prompts or job descriptions.**
25
+ See: https://signalloomai.com/prompt-integrity.html
26
+
27
+ Available models:
28
+ - openai/gpt-4o
29
+ - openai/gpt-4o-mini
30
+ - anthropic/claude-sonnet-4-20250514
31
+ - anthropic/claude-opus-4-6
32
+ - google/gemini-2.5-flash
33
+ - google/gemini-2.5-pro
34
+ - deepseek/deepseek-chat-v3
35
+ - xai/grok-3
36
+ - minimax/MiniMax-M2.7
37
+ `.trim();
38
+ var LoomLensTool = class {
39
+ constructor(config = {}) {
40
+ this.name = TOOL_NAME;
41
+ this.description = TOOL_DESCRIPTION;
42
+ this.apiKey = config.apiKey || process.env.SIGNALLOOM_API_KEY || process.env.SIGNALLOOM_API_KEY || "";
43
+ this.baseUrl = config.baseUrl || BASE_URL;
44
+ if (!this.apiKey) {
45
+ console.warn(
46
+ "[LoomLensTool] No API key provided. Set SIGNALLOOM_API_KEY env var or pass apiKey."
47
+ );
48
+ }
49
+ }
50
+ /**
51
+ * Estimate token cost for an AI pipeline.
52
+ */
53
+ async estimate(input) {
54
+ if (!this.apiKey) {
55
+ throw new Error(
56
+ "Signal Loom API key required. Set SIGNALLOOM_API_KEY env var or pass apiKey."
57
+ );
58
+ }
59
+ const payload = {
60
+ job_description: input.job_description,
61
+ num_agents: input.num_agents ?? 1,
62
+ estimated_runtime_minutes: input.estimated_runtime_minutes ?? 5,
63
+ complexity: input.complexity ?? "standard",
64
+ target_models: input.target_models,
65
+ include_postmortem: input.include_postmortem ?? false
66
+ };
67
+ const response = await fetch(`${this.baseUrl}/v1/estimate`, {
68
+ method: "POST",
69
+ headers: {
70
+ "Content-Type": "application/json",
71
+ Authorization: `Bearer ${this.apiKey}`
72
+ },
73
+ body: JSON.stringify(payload)
74
+ });
75
+ if (!response.ok) {
76
+ const error = await response.json().catch(() => ({ detail: response.statusText }));
77
+ throw new Error(`LoomLens API error ${response.status}: ${error?.detail ?? response.statusText}`);
78
+ }
79
+ return response.json();
80
+ }
81
+ /**
82
+ * Estimate and return a human-readable summary string.
83
+ */
84
+ async estimateSummary(input) {
85
+ const result = await this.estimate(input);
86
+ const { cheapest_model, most_expensive_model, savings_vs_expensive, models, billing } = result;
87
+ const lines = [
88
+ `## LoomLens AI Estimate`,
89
+ ``,
90
+ `**Cheapest:** ${cheapest_model}`,
91
+ `**Most expensive:** ${most_expensive_model}`,
92
+ `**Savings (cheapest vs most expensive):** $${savings_vs_expensive.toFixed(6)} per job`,
93
+ ``,
94
+ `### Cost Comparison`,
95
+ ``,
96
+ ...models.map(
97
+ (m) => ` ${m.model}: **$${m.estimated_cost_mid.toFixed(6)}/job** (range: $${m.estimated_cost_low.toFixed(6)}\u2013$${m.estimated_cost_high.toFixed(6)})${m.model === cheapest_model ? " \u2190 CHEAPEST" : ""}${m.model === most_expensive_model ? " \u2190 MOST EXPENSIVE" : ""}`
98
+ ),
99
+ ``,
100
+ `**Estimate call cost:** $${billing.call_cost_usd.toFixed(6)}`,
101
+ `**Quota remaining:** ${billing.remaining_this_month} calls this month`,
102
+ ``,
103
+ `*Powered by LoomLens AI \u2014 https://signalloomai.com/token-estimator.html*`
104
+ ];
105
+ return lines.join("\n");
106
+ }
107
+ /**
108
+ * Return a LangChain-compatible BaseTool instance.
109
+ *
110
+ * Requires langchain as a peer dependency.
111
+ */
112
+ toLangChainTool() {
113
+ const self = this;
114
+ const ToolClass = Tool;
115
+ return new ToolClass({
116
+ name: self.name,
117
+ description: self.description,
118
+ returnDirect: false,
119
+ async call(input) {
120
+ let parsed;
121
+ if (typeof input === "string") {
122
+ try {
123
+ parsed = JSON.parse(input);
124
+ } catch {
125
+ throw new Error(
126
+ `LoomLensTool requires JSON input. Received: ${input.slice(0, 100)}`
127
+ );
128
+ }
129
+ } else {
130
+ parsed = input;
131
+ }
132
+ if (!parsed.job_description || !parsed.target_models?.length) {
133
+ throw new Error(
134
+ "LoomLensTool requires job_description and target_models. Example: { job_description: 'Research agent', target_models: ['openai/gpt-4o'] }"
135
+ );
136
+ }
137
+ return self.estimateSummary(parsed);
138
+ }
139
+ });
140
+ }
141
+ };
142
+ function createLoomLensTool(config) {
143
+ return new LoomLensTool(config);
144
+ }
145
+ var SIGNALLOOM_PACKAGE_INFO = {
146
+ name: "signalloomai",
147
+ version: "1.0.0",
148
+ homepage: "https://signalloomai.com",
149
+ docs: "https://signalloomai.com/docs",
150
+ promptIntegrity: "https://signalloomai.com/prompt-integrity.html"
151
+ /** Prompt: This tool does NOT log prompts or job descriptions. */
152
+ };
153
+ export {
154
+ LoomLensTool,
155
+ SIGNALLOOM_PACKAGE_INFO,
156
+ createLoomLensTool
157
+ };
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "signalloomai",
3
+ "version": "0.1.0",
4
+ "description": "Signal Loom AI — LangChain tool wrapper for LoomLens AI token cost estimation",
5
+ "license": "MIT",
6
+ "homepage": "https://signalloomai.com",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/signalloom/signalloomai"
10
+ },
11
+ "keywords": [
12
+ "langchain",
13
+ "llm",
14
+ "token",
15
+ "cost",
16
+ "estimation",
17
+ "ai-agent",
18
+ "ai-tools",
19
+ "gpt-4o",
20
+ "claude",
21
+ "gemini",
22
+ "openai",
23
+ "anthropic",
24
+ "ai-pipeline"
25
+ ],
26
+ "type": "module",
27
+ "main": "./dist/index.cjs",
28
+ "module": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js",
34
+ "require": "./dist/index.cjs"
35
+ }
36
+ },
37
+ "files": [
38
+ "dist"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
42
+ "prepublishOnly": "npm run build"
43
+ },
44
+ "peerDependencies": {
45
+ "langchain": ">=0.1.0"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^20.0.0",
49
+ "tsup": "^8.0.0",
50
+ "typescript": "^5.0.0"
51
+ },
52
+ "dependencies": {
53
+ "@langchain/core": ">=0.1.0"
54
+ }
55
+ }