Skip to content

Initialize Cannoli Server package #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
node_modules/
node_modules
dist
.turbo
.tsup

main.js
fileGen.js
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ data.json

.turbo
dist
.tsup
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v20.17.0
v23
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"tabWidth": 2,
"useTabs": false,
"semi": true
}
33 changes: 18 additions & 15 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"editor.defaultFormatter": "vscode.typescript-language-features",
"editor.formatOnSave": true,
"prettier.enable": false,
"[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"search.exclude": {
// Avoid polluting search results with lockfile content
"pnpm-lock.yaml": true,
"dist": true,
"node_modules": true
},
// Ensure VSCode uses pnpm instead of npm
"npm.packageManager": "pnpm",
"typescript.tsdk": "node_modules/typescript/lib",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"prettier.enable": true,
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"search.exclude": {
// Avoid polluting search results with lockfile content
"pnpm-lock.yaml": true,
"dist": true,
"node_modules": true
},
// Ensure VSCode uses pnpm instead of npm
"npm.packageManager": "pnpm",
"[markdown]": {
"editor.defaultFormatter": "DavidAnson.vscode-markdownlint"
}
}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ Cannolis can be run in several ways:

- Click the Cannoli ribbon icon

- If you're on a canvas file, it will be run as a cannoli
- If you're on a note with a "cannoli" property, the canvas file in that property will be run as a cannoli
- If you're on a canvas file, it will be run as a cannoli
- If you're on a note with a "cannoli" property, the canvas file in that property will be run as a cannoli

- Run the "Start/Stop cannoli" command in the command palette (functions the same as the ribbon icon)
- If a canvas file name ends with ".cno", it will have its own run command in the command palette
- Make an audio recording on a note with a "cannoli" property
- That recording will be (1) transcribed using Whisper, (2) replace the reference, and (3) trigger the cannoli defined in the property.
- That recording will be (1) transcribed using Whisper, (2) replace the reference, and (3) trigger the cannoli defined in the property.

## AI providers

Expand Down
65 changes: 33 additions & 32 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
{
"name": "cannoli",
"version": "2.0.0",
"description": "",
"scripts": {
"typecheck": "turbo run typecheck",
"build": "turbo run build",
"dev": "turbo run dev",
"release-plugin": "turbo run release --filter cannoli-plugin",
"build-college": "turbo run build-college --filter cannoli-plugin",
"clean": "rimraf main.js packages/**/node_modules packages/**/dist packages/**/.turbo .turbo node_modules",
"release-core": "pnpm run build && pnpm --filter cannoli-core publish --no-git-check --access public",
"format": "prettier --write '**/*.{js,ts,md}'",
"check": "prettier --check '**/*.{js,ts,md}'"
},
"engines": {
"node": ">=18",
"pnpm": ">=9"
},
"keywords": [],
"author": "",
"license": "MIT",
"private": true,
"dependencies": {
"rimraf": "^5.0.7",
"turbo": "1.13.3"
},
"packageManager": "[email protected]+sha512.9df9cf27c91715646c7d675d1c9c8e41f6fce88246f1318c1aa6a1ed1aeb3c4f032fcdf4ba63cc69c4fe6d634279176b5358727d8f2cc1e65b65f43ce2f8bfb0",
"devDependencies": {
"eslint-config-prettier": "10.1.1",
"eslint-plugin-prettier": "5.2.6",
"prettier": "3.5.3"
}
"name": "cannoli",
"version": "2.0.0",
"description": "",
"scripts": {
"typecheck": "turbo run typecheck",
"build": "turbo run build",
"dev": "turbo run dev",
"release-plugin": "turbo run release --filter cannoli-plugin",
"build-college": "turbo run build-college --filter cannoli-plugin",
"clean": "rimraf main.js packages/**/node_modules packages/**/dist packages/**/.turbo .turbo node_modules",
"release-core": "pnpm run build && pnpm --filter cannoli-core publish --no-git-check --access public",
"format": "eslint --fix '**/*.{js,ts}' && prettier --write '**/*.{js,ts}'",
"check": "eslint '**/*.{js,ts}' && prettier --check '**/*.{js,ts}'"
},
"engines": {
"node": ">=18",
"pnpm": ">=9"
},
"keywords": [],
"author": "",
"license": "MIT",
"private": true,
"dependencies": {
"rimraf": "^5.0.7",
"turbo": "1.13.3"
},
"packageManager": "[email protected]+sha512.9df9cf27c91715646c7d675d1c9c8e41f6fce88246f1318c1aa6a1ed1aeb3c4f032fcdf4ba63cc69c4fe6d634279176b5358727d8f2cc1e65b65f43ce2f8bfb0",
"devDependencies": {
"eslint-config-prettier": "10.1.1",
"eslint-plugin-prettier": "5.2.6",
"prettier": "3.5.3",
"typescript": "^5.8.3"
}
}
128 changes: 67 additions & 61 deletions packages/cannoli-core/package.json
Original file line number Diff line number Diff line change
@@ -1,63 +1,69 @@
{
"name": "@deablabs/cannoli-core",
"version": "0.2.0",
"description": "This package is in heavy development and is not ready for production use.\nJoin our Discord server to get involved in the development process: https://discord.gg/wzayNxpxvR",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"files": [
"dist/**/*",
"package.json"
],
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./package.json": "./package.json"
},
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts --treeshake --clean",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
"typecheck": "tsc --noEmit"
},
"keywords": [],
"author": "",
"license": "MIT",
"devDependencies": {
"@types/js-yaml": "^4.0.6",
"@types/node": "^16.11.6",
"@types/uuid": "^9.0.2",
"@typescript-eslint/eslint-plugin": "^7.7.1",
"@typescript-eslint/parser": "^7.7.1",
"builtin-modules": "3.3.0",
"eslint": "^8.57.0",
"typescript": "^5.3.3"
},
"dependencies": {
"@arizeai/openinference-instrumentation-langchain": "0.2.0",
"@arizeai/openinference-semantic-conventions": "0.10.0",
"@langchain/anthropic": "0.2.1",
"@langchain/community": "0.2.12",
"@langchain/core": "0.2.7",
"@langchain/google-genai": "0.0.19",
"@langchain/groq": "0.0.12",
"@langchain/openai": "0.1.3",
"@opentelemetry/exporter-trace-otlp-proto": "0.53.0",
"@opentelemetry/instrumentation": "0.53.0",
"@opentelemetry/resources": "1.26.0",
"@opentelemetry/sdk-trace-web": "1.26.0",
"js-yaml": "^4.1.0",
"langchain": "0.2.5",
"nanoid": "5.0.7",
"openai": "^4.52.0",
"p-limit": "^4.0.0",
"remeda": "1.61.0",
"tiny-invariant": "^1.3.1",
"tslib": "2.4.0",
"tsup": "^8.0.2",
"web-instrumentation-langchain": "workspace:*",
"zod": "3.23.8"
}
"name": "@deablabs/cannoli-core",
"version": "0.2.0",
"description": "This package is in heavy development and is not ready for production use.\nJoin our Discord server to get involved in the development process: https://discord.gg/wzayNxpxvR",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"files": [
"dist/**/*",
"package.json"
],
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./package.json": "./package.json"
},
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts --treeshake --clean",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
"typecheck": "tsc --noEmit"
},
"keywords": [],
"author": "",
"license": "MIT",
"devDependencies": {
"@types/js-yaml": "^4.0.6",
"@types/node": "^22.14.0",
"@types/uuid": "^9.0.2",
"@typescript-eslint/eslint-plugin": "^7.7.1",
"@typescript-eslint/parser": "^7.7.1",
"builtin-modules": "3.3.0",
"eslint": "^8.57.0",
"typescript": "^5.8.3"
},
"dependencies": {
"@arizeai/openinference-semantic-conventions": "1.1.0",
"@deablabs/cannoli-server": "workspace:*",
"@langchain/anthropic": "0.3.17",
"@langchain/community": "0.3.40",
"@langchain/core": "0.3.44",
"@langchain/google-genai": "0.2.3",
"@langchain/groq": "0.2.2",
"@langchain/langgraph": "0.2.64",
"@langchain/mcp-adapters": "0.4.2",
"@langchain/ollama": "0.2.0",
"@langchain/openai": "0.5.5",
"@modelcontextprotocol/sdk": "1.9.0",
"@opentelemetry/exporter-trace-otlp-proto": "0.53.0",
"@opentelemetry/instrumentation": "0.53.0",
"@opentelemetry/resources": "1.26.0",
"@opentelemetry/sdk-trace-web": "1.26.0",
"hono": "4.7.6",
"js-yaml": "^4.1.0",
"langchain": "0.3.21",
"nanoid": "5.0.7",
"openai": "^4.52.0",
"p-limit": "^4.0.0",
"prebuilt": "link:@langchain/langgraph/prebuilt",
"remeda": "1.61.0",
"tiny-invariant": "^1.3.1",
"tslib": "2.4.0",
"tsup": "^8.4.0",
"web-instrumentation-langchain": "workspace:*",
"zod": "3.23.8"
}
}
117 changes: 61 additions & 56 deletions packages/cannoli-core/src/actions/dalleGenerate.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,68 @@
import { Action } from "../run";

export const dalleGenerate: Action = {
name: "dalle",
function: async ({
prompt,
OPENAI_API_KEY,
model = "dall-e-3",
size = "1024x1024",
}: {
prompt: string;
OPENAI_API_KEY: string;
model?: string;
size?: string;
}) => {
try {
const response = await fetch(
"https://api.openai.com/v1/images/generations",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${OPENAI_API_KEY}`,
},
body: JSON.stringify({
model: model,
prompt: prompt,
n: 1,
size: size,
}),
},
);
name: "dalle",
function: async (_args) => {
const {
prompt,
OPENAI_API_KEY,
model = "dall-e-3",
size = "1024x1024",
} = _args as {
prompt: string;
OPENAI_API_KEY: string;
model?: string;
size?: string;
};
try {
const response = await fetch(
"https://api.openai.com/v1/images/generations",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${OPENAI_API_KEY}`,
},
body: JSON.stringify({
model: model,
prompt: prompt,
n: 1,
size: size,
}),
},
);

const data = await response.json();
const data = await response.json();

if (!response.ok) {
throw new Error(data.error?.message || "Unknown error");
}
if (!response.ok) {
throw new Error(data.error?.message || "Unknown error");
}

return `![${data.data?.[0]?.revised_prompt}](${data.data?.[0]?.url})`;
} catch (error) {
return new Error(`Error: ${error.message}`);
}
},
argInfo: {
prompt: {
category: "arg",
},
model: {
category: "arg",
},
size: {
category: "arg",
},
OPENAI_API_KEY: {
category: "secret",
},
},
importInfo: {
name: "dalleGenerate",
path: "npm:@deablabs/cannoli-core",
},
return `![${data.data?.[0]?.revised_prompt}](${data.data?.[0]?.url})`;
} catch (error) {
if (error instanceof Error) {
return new Error(`Error: ${error.message}`);
} else {
return new Error(`Error: ${error}`);
}
}
},
argInfo: {
prompt: {
category: "arg",
},
model: {
category: "arg",
},
size: {
category: "arg",
},
OPENAI_API_KEY: {
category: "secret",
},
},
importInfo: {
name: "dalleGenerate",
path: "npm:@deablabs/cannoli-core",
},
};
Loading