Skip to content
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

feat: add subscribers to kit #61

Merged
merged 1 commit into from
Feb 18, 2025
Merged
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: 5 additions & 0 deletions apps/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"clean-react": "rm -rf node_modules/react; rm -rf node_modules/react-dom"
},
"dependencies": {
"@ai-sdk/openai": "^1.1.12",
"@browserbasehq/sdk": "^2.3.0",
"@bubba/notifications": "workspace:*",
"@date-fns/tz": "^1.2.0",
Expand All @@ -19,10 +20,14 @@
"@prisma/instrumentation": "^6.3.1",
"@tanstack/react-query": "^5.66.0",
"@tanstack/react-table": "^8.21.2",
"@tiptap/pm": "^2.11.5",
"@tiptap/react": "^2.11.5",
"@tiptap/starter-kit": "^2.11.5",
"@trigger.dev/react-hooks": "3.3.16",
"@trigger.dev/sdk": "3.3.16",
"@uploadthing/react": "^7.2.0",
"@upstash/ratelimit": "^2.0.5",
"ai": "^4.1.41",
"argon2": "^0.41.1",
"bun": "^1.2.2",
"crypto": "^1.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default async function Layout({
}

return (
<div className="max-w-[1200px] space-y-4">
<div className="max-w-[1200px] mx-auto">
<main className="h-[calc(100vh-4rem-4rem)]">{children}</main>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import Tiptap from "@/components/editor/editor";
import { Button } from "@bubba/ui/button";
import { Separator } from "@bubba/ui/separator";
import { useAction } from "next-safe-action/hooks";
Expand All @@ -18,6 +19,9 @@ export default function PolicyPage() {
onSuccess: () => {
toast.success("Policy published successfully");
},
onError: () => {
toast.error("Failed to publish policy, please try again.");
},
},
);

Expand All @@ -44,7 +48,7 @@ export default function PolicyPage() {
<div className="flex-1">
<div className="min-h-0 h-auto">
<div className="relative min-h-[calc(100vh-250px)] w-full mx-auto border border-border bg-background">
Editor
<Tiptap content={content} />
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default async function Layout({
const t = await getI18n();

return (
<div className="max-w-[1200px]">
<div className="max-w-[1200px] mx-auto">
<Suspense fallback={<div>Loading...</div>}>
<SecondaryMenu
items={[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default async function Layout({
const t = await getI18n();

return (
<div className="max-w-[800px] mx-auto">
<div className="max-w-[1200px] mx-auto">
<Suspense fallback={<div>Loading...</div>}>
<SecondaryMenu
items={[
Expand Down
17 changes: 17 additions & 0 deletions apps/app/src/app/api/chat/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { openai } from "@ai-sdk/openai";
import { convertToCoreMessages, streamText } from "ai";

export const maxDuration = 30;

export async function POST(req: Request) {
const { messages } = await req.json();

Comment on lines +6 to +8
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for request body parsing.

The current implementation lacks error handling for JSON parsing and message validation.

 export async function POST(req: Request) {
+  try {
   const { messages } = await req.json();
+    if (!messages || !Array.isArray(messages)) {
+      return new Response(
+        JSON.stringify({ error: "Invalid messages format" }),
+        { status: 400 }
+      );
+    }
+  } catch (error) {
+    return new Response(
+      JSON.stringify({ error: "Invalid JSON payload" }),
+      { status: 400 }
+    );
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function POST(req: Request) {
const { messages } = await req.json();
export async function POST(req: Request) {
try {
const { messages } = await req.json();
if (!messages || !Array.isArray(messages)) {
return new Response(
JSON.stringify({ error: "Invalid messages format" }),
{ status: 400 }
);
}
} catch (error) {
return new Response(
JSON.stringify({ error: "Invalid JSON payload" }),
{ status: 400 }
);
}
}

const result = await streamText({
model: openai("gpt-4o-mini"),
system:
"You generate markdown documents for users. Unless specified, this is a draft. Keep things shortish. Do not add any supplementary text, as everything you say will be placed into a document. If you're confused however, it's okay to ask a user for info. Responses must be either a chat response, or a document. Don't add bold styling to headings.",
messages: convertToCoreMessages(messages),
});
Comment on lines +9 to +14
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Extract system prompt to a configuration file.

The system prompt is hardcoded and quite long. Consider extracting it to a separate configuration file for better maintainability.

Additionally, verify if "gpt-4o-mini" is the correct model name as it seems unusual.


🌐 Web query:

What are the available OpenAI GPT-4 model names?

💡 Result:

OpenAI's GPT-4 family includes multiple model variants with distinct capabilities and naming conventions. Here's a breakdown of available models based on current documentation:

Latest GA Models

  1. GPT-4o (gpt-4o)

    • Versions: 2024-11-20, 2024-08-06, 2024-05-13
    • Multimodal (text + image input)
    • 128K token context window
    • Enhanced non-English language support
    • Structured outputs & parallel function calling[1][4]
  2. GPT-4 Turbo with Vision (gpt-4, version turbo-2024-04-09)

    • Replaces previous preview models (vision-preview, 1106-Preview)
    • 128K context window
    • Image/text input capabilities[1][2][5]
  3. GPT-4o mini (gpt-4o-mini)

    • Version: 2024-07-18
    • Cost-effective alternative to GPT 3.5 Turbo series
    • Supports text/image processing[1][4]

Older GA Models

  1. Base GPT-4 (gpt‑4)

    • Versions: 0613 (8K context), 0314 (legacy)
    • Core text processing capabilities[1][6]
  2. GPT‑4‑32k

    • Version: 0613 (32K context)
    • Extended context variant[1][6]

Specialized Variants

  1. GPT‑Turbo Realtime Beta

    • Models: gpt‑4o‑realtime‑preview, gpt‑4o‑mini‑realtime‑preview
    • Real-time audio/text interaction via WebRTC/WebSocket[4]
  2. Vision-Capable Models

    • Requires specific deployment configurations in Azure[1]

Key distinctions:

Feature GPT‑Turbo Original GPT‑4
Context Window 128K 8K/32K
Training Data Up to Dec 2023 Up to Sep 2021
Multimodal Input Yes Limited[1][2][5]

Older versions like 0314 are being phased out[1][6], while preview models (0125-Preview) are being replaced by stable releases[1]. Model names typically follow gpt‑{version}‑{release_date} patterns[7].

Citations:


Action: Extract Hardcoded System Prompt & Confirm "gpt-4o-mini" Is Valid

  • The system prompt in apps/app/src/app/api/chat/route.ts (lines 9-14) is currently hardcoded. For better maintainability, extract this prompt into a separate configuration file (e.g., config/prompts.ts).
  • The model name "gpt-4o-mini" has been verified against current OpenAI GPT-4 model documentation and is valid.


return result.toDataStreamResponse();
}
17 changes: 17 additions & 0 deletions apps/app/src/components/editor/actions/ai.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use server";

import { openai } from "@ai-sdk/openai";
import { type CoreMessage, streamText } from "ai";
import { createStreamableValue } from "ai/rsc";

// Send messages to AI and stream a result back
export async function continueConversation(messages: CoreMessage[]) {
const result = await streamText({
model: openai("gpt-4o-mini"),
messages,
});

const stream = createStreamableValue(result.textStream);
return stream.value;
}

22 changes: 22 additions & 0 deletions apps/app/src/components/editor/editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"use client";

import { EditorContent, type JSONContent, useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import { useEffect, useState } from "react";

const Tiptap = ({ content }: { content: JSONContent }) => {
const [editorState, setEditorState] = useState<JSONContent | null>(null);

const editor = useEditor({
extensions: [StarterKit],
content: content,
});

useEffect(() => {
setEditorState(JSON.parse(editor?.getText() || "{}"));
}, [editor]);
Comment on lines +15 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Use the built-in method to obtain the editor’s content as JSON.

editor.getText() returns plain text, which wouldn't be valid JSON to parse. Instead, consider using editor?.getJSON() to retrieve the editor’s state safely and accurately.

useEffect(() => {
-  setEditorState(JSON.parse(editor?.getText() || "{}"));
+  if (editor) {
+    setEditorState(editor.getJSON());
+  }
}, [editor]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
setEditorState(JSON.parse(editor?.getText() || "{}"));
}, [editor]);
useEffect(() => {
if (editor) {
setEditorState(editor.getJSON());
}
}, [editor]);


return <EditorContent editor={editor} />;
};

export default Tiptap;
2 changes: 1 addition & 1 deletion apps/app/src/components/google-sign-in.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function GoogleSignIn() {
return (
<Button
onClick={handleSignIn}
className="flex h-[40px] w-full space-x-2 bg-primary px-6 py-4 font-medium text-secondary active:scale-[0.98]"
className="flex h-[40px] w-full space-x-2 px-6 py-4 font-medium active:scale-[0.98]"
>
{isLoading ? (
<Loader2 className="h-4 w-4 animate-spin" />
Expand Down
70 changes: 35 additions & 35 deletions apps/web/src/app/actions/waitlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,53 @@ import ky from "ky";
import { createSafeActionClient } from "next-safe-action";
import { waitlistSchema } from "./schema";

interface ZapSubscriberPayload {
email_address: string;
referrer: string;
}

export const joinWaitlist = createSafeActionClient()
.schema(waitlistSchema)
.action(async ({ parsedInput }) => {
const kitPayload: ZapSubscriberPayload = {
email_address: parsedInput.email,
referrer: typeof window !== 'undefined' ? window.location.href : 'https://trycomp.ai',
};
Comment on lines +19 to +22
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove duplicated code and fix server-side window check.

The code has the following issues:

  1. The window check is server-side but window is only available client-side.
  2. The payload creation is duplicated.

Apply this diff to fix the issues:

+const getReferrer = () => {
+  return 'https://trycomp.ai';
+};

-    const kitPayload: ZapSubscriberPayload = {
-      email_address: parsedInput.email,
-      referrer: typeof window !== 'undefined' ? window.location.href : 'https://trycomp.ai',
-    };
+    const payload: ZapSubscriberPayload = {
+      email_address: parsedInput.email,
+      referrer: getReferrer(),
+    };

-      const zapPayload: ZapSubscriberPayload = {
-        email_address: parsedInput.email,
-        referrer: typeof window !== 'undefined' ? window.location.href : 'https://trycomp.ai',
-      };
-
       await ky.post(
         process.env.ZAP_WEBHOOK_URL as string,
         {
           headers: {
             "Content-Type": "application/json",
             Accept: "application/json",
           },
-          json: kitPayload,
+          json: payload,
         }
       );

Also applies to: 36-39


if (!resend) {
throw new Error("Resend not initialized - missing API key");
}

const audience = await resend.contacts.list({
audienceId: process.env.RESEND_AUDIENCE_ID!,
});

const isInAudience = audience.data?.data?.some(
(contact: { email: string }) => contact.email === parsedInput.email,
);

if (!isInAudience) {
await resend.contacts.create({
email: parsedInput.email,
firstName:
parsedInput.email.charAt(0).toUpperCase() +
parsedInput.email.split("@")[0].slice(1),
audienceId: process.env.RESEND_AUDIENCE_ID as string,
if (process.env.DISCORD_WEBHOOK_URL) {
await ky.post(process.env.DISCORD_WEBHOOK_URL as string, {
json: {
content: `New waitlist signup: ${parsedInput.email}`,
},
});

await tasks.trigger<typeof introductionEmailTask>(
"introduction-email",
}
Comment on lines +28 to +34
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling and consistent headers.

The webhook calls lack error handling and have inconsistent header usage.

Apply this diff to improve error handling and header consistency:

+    const headers = {
+      "Content-Type": "application/json",
+      Accept: "application/json",
+    };

     if (process.env.DISCORD_WEBHOOK_URL) {
-      await ky.post(process.env.DISCORD_WEBHOOK_URL as string, {
-        json: {
-          content: `New waitlist signup: ${parsedInput.email}`,
-        },
-      });
+      try {
+        await ky.post(process.env.DISCORD_WEBHOOK_URL as string, {
+          headers,
+          json: {
+            content: `New waitlist signup: ${parsedInput.email}`,
+          },
+        });
+      } catch (error) {
+        console.error('Failed to send Discord notification:', error);
+        // Continue execution as this is non-critical
+      }
     }
     if (process.env.ZAP_WEBHOOK_URL) {
-      const zapPayload: ZapSubscriberPayload = {
-        email_address: parsedInput.email,
-        referrer: typeof window !== 'undefined' ? window.location.href : 'https://trycomp.ai',
-      };
-
-      await ky.post(
-        process.env.ZAP_WEBHOOK_URL as string,
-        {
-          headers: {
-            "Content-Type": "application/json",
-            Accept: "application/json",
-          },
-          json: kitPayload,
-        }
-      );
+      try {
+        await ky.post(
+          process.env.ZAP_WEBHOOK_URL as string,
+          {
+            headers,
+            json: payload,
+          }
+        );
+      } catch (error) {
+        console.error('Failed to send Zapier notification:', error);
+        throw new Error('Failed to add subscriber');
+      }
     }

Also applies to: 35-51

if (process.env.ZAP_WEBHOOK_URL) {
const zapPayload: ZapSubscriberPayload = {
email_address: parsedInput.email,
referrer: typeof window !== 'undefined' ? window.location.href : 'https://trycomp.ai',
};

await ky.post(
process.env.ZAP_WEBHOOK_URL as string,
{
email: parsedInput.email,
},
);

if (process.env.DISCORD_WEBHOOK_URL) {
await ky.post(process.env.DISCORD_WEBHOOK_URL as string, {
json: {
content: `New waitlist signup: ${parsedInput.email}`,
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
});
}

await ServerAnalytics.track(parsedInput.email, "waitlist_signup", {
channel: "web",
email: parsedInput.email,
});
} else {
throw new Error("Email already in audience");
json: kitPayload,
}
);
}

await ServerAnalytics.track(parsedInput.email, "waitlist_signup", {
channel: "web",
email: parsedInput.email,
});

return {
success: true,
};
Expand Down
29 changes: 29 additions & 0 deletions bun.lock
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"name": "comp.ai",
"version": "0.1.0",
"dependencies": {
"@ai-sdk/openai": "^1.1.12",
"@browserbasehq/sdk": "^2.3.0",
"@bubba/notifications": "workspace:*",
"@date-fns/tz": "^1.2.0",
Expand All @@ -29,10 +30,14 @@
"@prisma/instrumentation": "^6.3.1",
"@tanstack/react-query": "^5.66.0",
"@tanstack/react-table": "^8.21.2",
"@tiptap/pm": "^2.11.5",
"@tiptap/react": "^2.11.5",
"@tiptap/starter-kit": "^2.11.5",
"@trigger.dev/react-hooks": "3.3.16",
"@trigger.dev/sdk": "3.3.16",
"@uploadthing/react": "^7.2.0",
"@upstash/ratelimit": "^2.0.5",
"ai": "^4.1.41",
"argon2": "^0.41.1",
"bun": "^1.2.2",
"crypto": "^1.0.1",
Expand Down Expand Up @@ -3185,6 +3190,10 @@

"cmdk/react-dom": ["[email protected]", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" }, "peerDependencies": { "react": "^18.2.0" } }, "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g=="],

"comp.ai/@ai-sdk/openai": ["@ai-sdk/[email protected]", "", { "dependencies": { "@ai-sdk/provider": "1.0.7", "@ai-sdk/provider-utils": "2.1.8" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-lh3zN4J/XEqkjpZAOBajSttF1Nl2qV/7WxRbORn+4jZmQkmzWQbsEUpgQ6ME+heyRvnsRCNq3fkMGehWWxWuXg=="],

"comp.ai/ai": ["[email protected]", "", { "dependencies": { "@ai-sdk/provider": "1.0.7", "@ai-sdk/provider-utils": "2.1.8", "@ai-sdk/react": "1.1.16", "@ai-sdk/ui-utils": "1.1.14", "@opentelemetry/api": "1.9.0", "jsondiffpatch": "0.6.0" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "zod": "^3.0.0" }, "optionalPeers": ["react", "zod"] }, "sha512-qQ5eVm5ivTij0/auLaoggfW3Y+IgWL0uNCCH79P8eUODeJTTqCRvB0B3iz9xl9b4uqOPcgZCVELgLfVODnCJ9g=="],

"condense-newlines/kind-of": ["[email protected]", "", { "dependencies": { "is-buffer": "^1.1.5" } }, "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ=="],

"data-urls/whatwg-url": ["[email protected]", "", { "dependencies": { "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" } }, "sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ=="],
Expand Down Expand Up @@ -3453,6 +3462,18 @@

"cmdk/react-dom/scheduler": ["[email protected]", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],

"comp.ai/@ai-sdk/openai/@ai-sdk/provider": ["@ai-sdk/[email protected]", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-q1PJEZ0qD9rVR+8JFEd01/QM++csMT5UVwYXSN2u54BrVw/D8TZLTeg2FEfKK00DgAx0UtWd8XOhhwITP9BT5g=="],

"comp.ai/@ai-sdk/openai/@ai-sdk/provider-utils": ["@ai-sdk/[email protected]", "", { "dependencies": { "@ai-sdk/provider": "1.0.7", "eventsource-parser": "^3.0.0", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, "peerDependencies": { "zod": "^3.0.0" }, "optionalPeers": ["zod"] }, "sha512-1j9niMUAFlCBdYRYJr1yoB5kwZcRFBVuBiL1hhrf0ONFNrDiJYA6F+gROOuP16NHhezMfTo60+GeeV1xprHFjg=="],

"comp.ai/ai/@ai-sdk/provider": ["@ai-sdk/[email protected]", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-q1PJEZ0qD9rVR+8JFEd01/QM++csMT5UVwYXSN2u54BrVw/D8TZLTeg2FEfKK00DgAx0UtWd8XOhhwITP9BT5g=="],

"comp.ai/ai/@ai-sdk/provider-utils": ["@ai-sdk/[email protected]", "", { "dependencies": { "@ai-sdk/provider": "1.0.7", "eventsource-parser": "^3.0.0", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, "peerDependencies": { "zod": "^3.0.0" }, "optionalPeers": ["zod"] }, "sha512-1j9niMUAFlCBdYRYJr1yoB5kwZcRFBVuBiL1hhrf0ONFNrDiJYA6F+gROOuP16NHhezMfTo60+GeeV1xprHFjg=="],

"comp.ai/ai/@ai-sdk/react": ["@ai-sdk/[email protected]", "", { "dependencies": { "@ai-sdk/provider-utils": "2.1.8", "@ai-sdk/ui-utils": "1.1.14", "swr": "^2.2.5", "throttleit": "2.1.0" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "zod": "^3.0.0" }, "optionalPeers": ["react", "zod"] }, "sha512-4Jx1piCte2+YoDd6ZdwM0Mw29046edw7MMNICImCPv2s7sfwFwe4c1t8waA4PYRefuETmzheqjh80kafQYJf8g=="],

"comp.ai/ai/@ai-sdk/ui-utils": ["@ai-sdk/[email protected]", "", { "dependencies": { "@ai-sdk/provider": "1.0.7", "@ai-sdk/provider-utils": "2.1.8", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.0.0" }, "optionalPeers": ["zod"] }, "sha512-JQXcnPRnDfeH1l503s/8+SxJdmgyUKC3QvKjOpTV6Z/LyRWJZrruBoZnVB1OrL9o/WHEguC+rD+p9udv281KzQ=="],

"data-urls/whatwg-url/tr46": ["[email protected]", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g=="],

"express/debug/ms": ["[email protected]", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
Expand Down Expand Up @@ -3535,6 +3556,14 @@

"cmdk/@radix-ui/react-dialog/@radix-ui/react-use-controllable-state/@radix-ui/react-use-callback-ref": ["@radix-ui/[email protected]", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg=="],

"comp.ai/@ai-sdk/openai/@ai-sdk/provider-utils/eventsource-parser": ["[email protected]", "", {}, "sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA=="],

"comp.ai/@ai-sdk/openai/@ai-sdk/provider-utils/nanoid": ["[email protected]", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],

"comp.ai/ai/@ai-sdk/provider-utils/eventsource-parser": ["[email protected]", "", {}, "sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA=="],

"comp.ai/ai/@ai-sdk/provider-utils/nanoid": ["[email protected]", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],

"languine/@trigger.dev/sdk/@trigger.dev/core/@opentelemetry/instrumentation": ["@opentelemetry/[email protected]", "", { "dependencies": { "@opentelemetry/api-logs": "0.52.1", "@types/shimmer": "^1.0.2", "import-in-the-middle": "^1.8.1", "require-in-the-middle": "^7.1.1", "semver": "^7.5.2", "shimmer": "^1.2.1" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw=="],

"languine/@trigger.dev/sdk/@trigger.dev/core/eventsource-parser": ["[email protected]", "", {}, "sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA=="],
Expand Down
Loading