用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/trycompai/comp --skill trigger-realtime命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | trigger-realtime |
| description | How to use realtime in your Trigger.dev tasks and your frontend |
Source Cursor rule: .cursor/rules/trigger.realtime.mdc.
Original file scope: **/trigger/**/*.ts.
Original Cursor alwaysApply: false.
Real-time monitoring and updates for runs
Realtime allows you to:
import { auth } from "@trigger.dev/sdk";
// Read-only token for specific runs
const publicToken = await auth.createPublicToken({
scopes: {
read: {
runs: ["run_123", "run_456"],
tasks: ["my-task-1", "my-task-2"],
},
},
expirationTime: "1h", // Default: 15 minutes
});
// Single-use token for triggering tasks
const triggerToken = await auth.createTriggerPublicToken("my-task", {
expirationTime: "30m",
});
import { runs, tasks } from "@trigger.dev/sdk";
// Trigger and subscribe
const handle = await tasks.trigger("my-task", { data: "value" });
// Subscribe to specific run
for await (const run of runs.subscribeToRun<typeof myTask>(handle.id)) {
console.log(`Status: ${run.status}, Progress: ${run.metadata?.progress}`);
if (run.status === "COMPLETED") break;
}
// Subscribe to runs with tag
for await (const run of runs.subscribeToRunsWithTag("user-123")) {
console.log(`Tagged run ${run.id}: ${run.status}`);
}
// Subscribe to batch
for await (const run of runs.subscribeToBatch(batchId)) {
console.log(`Batch run ${run.id}: ${run.status}`);
}
import { task, metadata } from "@trigger.dev/sdk";
// Task that streams data
export type STREAMS = {
openai: OpenAI.ChatCompletionChunk;
};
export const streamingTask = task({
id: "streaming-task",
run: async (payload) => {
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: payload.prompt }],
stream: true,
});
// Register stream
const stream = await metadata.stream("openai", completion);
let text = "";
for await (const chunk of stream) {
text += chunk.choices[0]?.delta?.content || "";
}
return { text };
},
});
// Subscribe to streams
for await ( part runs.(runId).<>()) {
(part.) {
:
.(, part..);
;
:
.(, part.);
;
}
}
bun add @trigger.dev/react-hooks
"use client";
import { useTaskTrigger, useRealtimeTaskTrigger } from "@trigger.dev/react-hooks";
import type { myTask } from "../trigger/tasks";
function TriggerComponent({ accessToken }: { accessToken: string }) {
// Basic trigger
const { submit, handle, isLoading } = useTaskTrigger<typeof myTask>("my-task", {
accessToken,
});
// Trigger with realtime updates
const {
submit: realtimeSubmit,
run,
isLoading: isRealtimeLoading,
} = useRealtimeTaskTrigger<typeof myTask>("my-task", { accessToken });
return (
<div>
<button onClick={() => submit({ data: "value" })} disabled={isLoading}>
Trigger Task
</button>
<button onClick={() => realtimeSubmit({ data: "realtime" })} disabled={isRealtimeLoading}>
Trigger with Realtime
</button>
{run && <div>Status: {run.status}</div>}
</div>
);
}
"use client";
import { useRealtimeRun, useRealtimeRunsWithTag } from "@trigger.dev/react-hooks";
import type { myTask } from "../trigger/tasks";
function SubscribeComponent({ runId, accessToken }: { runId: string; accessToken: string }) {
// Subscribe to specific run
const { run, error } = useRealtimeRun<typeof myTask>(runId, {
accessToken,
onComplete: (run) => {
console.log("Task completed:", run.output);
},
});
// Subscribe to tagged runs
const { runs } = useRealtimeRunsWithTag("user-123", { accessToken });
if (error) return <div>Error: {error.message}</div>;
if (!run) return <div>Loading...</div>;
return (
<div>
<div>Status: {run.status}</div>
<div>Progress: {run.metadata?.progress || 0}%</div>
{run.output && Result: {JSON.stringify(run.output)}}
Tagged Runs:
{runs.map((r) => (
{r.id}: {r.status}
))}
);
}
"use client";
import { useRealtimeRunWithStreams } from "@trigger.dev/react-hooks";
import type { streamingTask, STREAMS } from "../trigger/tasks";
function StreamComponent({ runId, accessToken }: { runId: string; accessToken: string }) {
const { run, streams } = useRealtimeRunWithStreams<typeof streamingTask, STREAMS>(runId, {
accessToken,
});
const text = streams.openai
.filter((chunk) => chunk.choices[0]?.delta?.content)
.map((chunk) => chunk.choices[0].delta.content)
.join("");
return (
<div>
<div>Status: {run?.status}</div>
<div>Streamed Text: {text}</div>
</div>
);
}
"use client";
import { useWaitToken } from "@trigger.dev/react-hooks";
function WaitTokenComponent({ tokenId, accessToken }: { tokenId: string; accessToken: string }) {
const { complete } = useWaitToken(tokenId, { accessToken });
return <button onClick={() => complete({ approved: true })}>Approve Task</button>;
}
"use client";
import { useRun } from "@trigger.dev/react-hooks";
import type { myTask } from "../trigger/tasks";
function SWRComponent({ runId, accessToken }: { runId: string; accessToken: string }) {
const { run, error, isLoading } = useRun<typeof myTask>(runId, {
accessToken,
refreshInterval: 0, // Disable polling (recommended)
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>Run: {run?.status}</div>;
}
Key properties available in run subscriptions:
id: Unique run identifierstatus: QUEUED, EXECUTING, COMPLETED, FAILED, CANCELED, etc.payload: Task input data (typed)output: Task result (typed, when completed)metadata: Real-time updatable datacreatedAt, updatedAt: TimestampscostInCents: Execution cost