KS
Killer-Skills

effect-patterns-scheduling-periodic-tasks — how to use effect-patterns-scheduling-periodic-tasks how to use effect-patterns-scheduling-periodic-tasks, effect-patterns-scheduling-periodic-tasks alternative, effect-patterns-scheduling-periodic-tasks setup guide, what is effect-patterns-scheduling-periodic-tasks, effect-patterns-scheduling-periodic-tasks vs NixOS, effect-patterns-scheduling-periodic-tasks install

v1.0.0
GitHub

About this Skill

Ideal for Effect-TS Agents requiring efficient scheduling of periodic tasks and best practices implementation. effect-patterns-scheduling-periodic-tasks is a NixOS Module for isolated worktree containers, providing patterns for scheduling periodic tasks.

Features

Provides 3 curated Effect-TS patterns for scheduling periodic tasks
Includes Scheduling Pattern 4: Debounce and Throttle Execution for critical task management
Supports isolated worktree containers in NixOS
Offers best practices in Effect-TS applications
Includes real-world patterns and solutions for periodic task scheduling

# Core Topics

scotttrinh scotttrinh
[0]
[0]
Updated: 3/6/2026

Quality Score

Top 5%
39
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add scotttrinh/nook/effect-patterns-scheduling-periodic-tasks

Agent Capability Analysis

The effect-patterns-scheduling-periodic-tasks MCP Server by scotttrinh is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for how to use effect-patterns-scheduling-periodic-tasks, effect-patterns-scheduling-periodic-tasks alternative, effect-patterns-scheduling-periodic-tasks setup guide.

Ideal Agent Persona

Ideal for Effect-TS Agents requiring efficient scheduling of periodic tasks and best practices implementation.

Core Value

Empowers agents to utilize curated Effect-TS patterns for scheduling periodic tasks, including debounce and throttle execution, enhancing their ability to manage tasks effectively using Effect-TS applications and real-world patterns.

Capabilities Granted for effect-patterns-scheduling-periodic-tasks MCP Server

Scheduling recurring tasks with precision
Implementing best practices in Effect-TS applications
Optimizing task execution frequency with debounce and throttle techniques

! Prerequisites & Limits

  • Requires understanding of Effect-TS patterns and applications
  • Limited to scheduling periodic tasks
Project
SKILL.md
19.6 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

Effect-TS Patterns: Scheduling Periodic Tasks

This skill provides 3 curated Effect-TS patterns for scheduling periodic tasks. Use this skill when working on tasks related to:

  • scheduling periodic tasks
  • Best practices in Effect-TS applications
  • Real-world patterns and solutions

🟡 Intermediate Patterns

Scheduling Pattern 4: Debounce and Throttle Execution

Rule: Use debounce to wait for silence before executing, and throttle to limit execution frequency, both critical for handling rapid events.

Good Example:

This example demonstrates debouncing and throttling for common scenarios.

typescript
1import { Effect, Schedule, Ref } from "effect"; 2 3interface SearchQuery { 4 readonly query: string; 5 readonly timestamp: Date; 6} 7 8// Simulate API search 9const performSearch = (query: string): Effect.Effect<string[]> => 10 Effect.gen(function* () { 11 yield* Effect.log(`[API] Searching for: "${query}"`); 12 13 yield* Effect.sleep("100 millis"); // Simulate API delay 14 15 return [ 16 `Result 1 for ${query}`, 17 `Result 2 for ${query}`, 18 `Result 3 for ${query}`, 19 ]; 20 }); 21 22// Main: demonstrate debounce and throttle 23const program = Effect.gen(function* () { 24 console.log(`\n[DEBOUNCE/THROTTLE] Handling rapid events\n`); 25 26 // Example 1: Debounce search input 27 console.log(`[1] Debounced search (wait for silence):\n`); 28 29 const searchQueries = ["h", "he", "hel", "hell", "hello"]; 30 31 const debouncedSearches = yield* Ref.make<Effect.Effect<string[]>[]>([]); 32 33 for (const query of searchQueries) { 34 yield* Effect.log(`[INPUT] User typed: "${query}"`); 35 36 // In real app, this would be debounced 37 yield* Effect.sleep("150 millis"); // User typing 38 } 39 40 // After user stops, execute search 41 yield* Effect.log(`[DEBOUNCE] User silent for 200ms, executing search`); 42 43 const searchResults = yield* performSearch("hello"); 44 45 yield* Effect.log(`[RESULTS] ${searchResults.length} results found\n`); 46 47 // Example 2: Throttle scroll events 48 console.log(`[2] Throttled scroll handler (max 10/sec):\n`); 49 50 const scrollEventCount = yield* Ref.make(0); 51 const updateCount = yield* Ref.make(0); 52 53 // Simulate 100 rapid scroll events 54 for (let i = 0; i < 100; i++) { 55 yield* Ref.update(scrollEventCount, (c) => c + 1); 56 57 // In real app, scroll handler would be throttled 58 if (i % 10 === 0) { 59 // Simulate throttled update (max 10 per second) 60 yield* Ref.update(updateCount, (c) => c + 1); 61 } 62 } 63 64 const events = yield* Ref.get(scrollEventCount); 65 const updates = yield* Ref.get(updateCount); 66 67 yield* Effect.log( 68 `[THROTTLE] ${events} scroll events → ${updates} updates (${(updates / events * 100).toFixed(1)}% update rate)\n` 69 ); 70 71 // Example 3: Deduplication 72 console.log(`[3] Deduplicating rapid events:\n`); 73 74 const userClicks = ["click", "click", "click", "dblclick", "click"]; 75 76 const lastClick = yield* Ref.make<string | null>(null); 77 const clickCount = yield* Ref.make(0); 78 79 for (const click of userClicks) { 80 const prev = yield* Ref.get(lastClick); 81 82 if (click !== prev) { 83 yield* Effect.log(`[CLICK] Processing: ${click}`); 84 yield* Ref.update(clickCount, (c) => c + 1); 85 yield* Ref.set(lastClick, click); 86 } else { 87 yield* Effect.log(`[CLICK] Duplicate: ${click} (skipped)`); 88 } 89 } 90 91 const processed = yield* Ref.get(clickCount); 92 93 yield* Effect.log( 94 `\n[DEDUPE] ${userClicks.length} clicks → ${processed} processed\n` 95 ); 96 97 // Example 4: Exponential backoff on repeated errors 98 console.log(`[4] Throttled retry on errors:\n`); 99 100 let retryCount = 0; 101 102 const operation = Effect.gen(function* () { 103 retryCount++; 104 105 if (retryCount < 3) { 106 yield* Effect.fail(new Error("Still failing")); 107 } 108 109 yield* Effect.log(`[SUCCESS] Succeeded on attempt ${retryCount}`); 110 111 return "done"; 112 }).pipe( 113 Effect.retry( 114 Schedule.exponential("100 millis").pipe( 115 Schedule.upTo("1 second"), 116 Schedule.recurs(5) 117 ) 118 ) 119 ); 120 121 yield* operation; 122}); 123 124Effect.runPromise(program);

Rationale:

Debounce and throttle manage rapid events:

  • Debounce: Wait for silence (delay after last event), then execute once
  • Throttle: Execute at most once per interval
  • Deduplication: Skip duplicate events
  • Rate limiting: Limit events per second

Pattern: Schedule.debounce(duration) or Schedule.throttle(maxEvents, duration)


Rapid events without debounce/throttle cause problems:

Debounce example: Search input

  • User types "hello" character by character
  • Without debounce: 5 API calls (one per character)
  • With debounce: 1 API call after user stops typing

Throttle example: Scroll events

  • Scroll fires 100+ times per second
  • Without throttle: Updates lag, GC pressure
  • With throttle: Update max 60 times per second

Real-world issues:

  • API overload: Search queries hammer backend
  • Rendering lag: Too many DOM updates
  • Resource exhaustion: Event handlers never catch up

Debounce/throttle enable:

  • Efficiency: Fewer operations
  • Responsiveness: UI stays smooth
  • Resource safety: Prevent exhaustion
  • Sanity: Predictable execution


Scheduling Pattern 3: Schedule Tasks with Cron Expressions

Rule: Use cron expressions to schedule periodic tasks at specific calendar times, enabling flexible scheduling beyond simple fixed intervals.

Good Example:

This example demonstrates scheduling a daily report generation using cron, with timezone support.

typescript
1import { Effect, Schedule, Console } from "effect"; 2import { DateTime } from "luxon"; // For timezone handling 3 4interface ReportConfig { 5 readonly cronExpression: string; 6 readonly timezone?: string; 7 readonly jobName: string; 8} 9 10interface ScheduledReport { 11 readonly timestamp: Date; 12 readonly jobName: string; 13 readonly result: string; 14} 15 16// Simple cron parser (in production, use a library like cron-parser) 17const parseCronExpression = ( 18 expression: string 19): { 20 minute: number[]; 21 hour: number[]; 22 dayOfMonth: number[]; 23 month: number[]; 24 dayOfWeek: number[]; 25} => { 26 const parts = expression.split(" "); 27 28 const parseField = (field: string, max: number): number[] => { 29 if (field === "*") { 30 return Array.from({ length: max + 1 }, (_, i) => i); 31 } 32 33 if (field.includes(",")) { 34 return field.split(",").flatMap((part) => parseField(part, max)); 35 } 36 37 if (field.includes("-")) { 38 const [start, end] = field.split("-").map(Number); 39 return Array.from({ length: end - start + 1 }, (_, i) => start + i); 40 } 41 42 return [Number(field)]; 43 }; 44 45 return { 46 minute: parseField(parts[0], 59), 47 hour: parseField(parts[1], 23), 48 dayOfMonth: parseField(parts[2], 31), 49 month: parseField(parts[3], 12), 50 dayOfWeek: parseField(parts[4], 6), 51 }; 52}; 53 54// Check if current time matches cron expression 55const shouldRunNow = (parsed: ReturnType<typeof parseCronExpression>): boolean => { 56 const now = new Date(); 57 58 return ( 59 parsed.minute.includes(now.getUTCMinutes()) && 60 parsed.hour.includes(now.getUTCHours()) && 61 parsed.dayOfMonth.includes(now.getUTCDate()) && 62 parsed.month.includes(now.getUTCMonth() + 1) && 63 parsed.dayOfWeek.includes(now.getUTCDay()) 64 ); 65}; 66 67// Generate a report 68const generateReport = (jobName: string): Effect.Effect<ScheduledReport> => 69 Effect.gen(function* () { 70 yield* Console.log(`[REPORT] Generating ${jobName}...`); 71 72 // Simulate report generation 73 yield* Effect.sleep("100 millis"); 74 75 return { 76 timestamp: new Date(), 77 jobName, 78 result: `Report generated at ${new Date().toISOString()}`, 79 }; 80 }); 81 82// Schedule with cron expression 83const scheduleWithCron = (config: ReportConfig) => 84 Effect.gen(function* () { 85 const parsed = parseCronExpression(config.cronExpression); 86 87 yield* Console.log( 88 `[SCHEDULER] Scheduling job: ${config.jobName}` 89 ); 90 yield* Console.log(`[SCHEDULER] Cron: ${config.cronExpression}`); 91 yield* Console.log(`[SCHEDULER] Timezone: ${config.timezone || "UTC"}\n`); 92 93 // Create schedule that checks every minute 94 const schedule = Schedule.fixed("1 minute").pipe( 95 Schedule.untilInputEffect((report: ScheduledReport) => 96 Effect.gen(function* () { 97 const isPastTime = shouldRunNow(parsed); 98 99 if (isPastTime) { 100 yield* Console.log( 101 `[SCHEDULED] ✓ Running at ${report.timestamp.toISOString()}` 102 ); 103 return true; // Stop scheduling 104 } 105 106 return false; // Continue scheduling 107 }) 108 ) 109 ); 110 111 // Generate report with cron schedule 112 yield* generateReport(config.jobName).pipe( 113 Effect.repeat(schedule) 114 ); 115 }); 116 117// Demonstrate multiple cron schedules 118const program = Effect.gen(function* () { 119 console.log( 120 `\n[START] Scheduling multiple jobs with cron expressions\n` 121 ); 122 123 // Schedule examples (note: in real app, these would run at actual times) 124 const jobs = [ 125 { 126 cronExpression: "0 9 * * 1-5", // 9 AM weekdays 127 jobName: "Daily Standup Report", 128 timezone: "America/New_York", 129 }, 130 { 131 cronExpression: "0 0 * * *", // Midnight daily 132 jobName: "Nightly Backup", 133 timezone: "UTC", 134 }, 135 { 136 cronExpression: "0 0 1 * *", // Midnight on 1st of month 137 jobName: "Monthly Summary", 138 timezone: "Europe/London", 139 }, 140 ]; 141 142 yield* Console.log("[JOBS] Scheduled:"); 143 jobs.forEach((job) => { 144 console.log( 145 ` - ${job.jobName}: ${job.cronExpression} (${job.timezone})` 146 ); 147 }); 148}); 149 150Effect.runPromise(program);

Rationale:

Use cron expressions for scheduling that aligns with business calendars:

  • Hourly backups: 0 * * * * (at :00 every hour)
  • Daily reports: 0 9 * * 1-5 (9 AM weekdays)
  • Monthly cleanup: 0 0 1 * * (midnight on 1st of month)
  • Business hours: 0 9-17 * * 1-5 (9 AM-5 PM, Mon-Fri)

Format: minute hour day month weekday


Fixed intervals don't align with business needs:

Fixed interval (every 24 hours):

  • If task takes 2 hours, next run is 26 hours later
  • Drifts over time
  • No alignment with calendar
  • Fails during daylight saving time changes

Cron expressions:

  • Specific calendar times (e.g., always 9 AM)
  • Independent of execution duration
  • Aligns with business hours
  • Natural DST handling (clock adjusts, cron resyncs)
  • Human-readable vs. milliseconds

Real-world example: Daily report at 9 AM

  • Fixed interval: Scheduled at 9:00, takes 1 hour → next at 10:00 → drift until 5 PM
  • Cron 0 9 * * *: Always runs at 9:00 regardless of duration or previous delays


🟠 Advanced Patterns

Scheduling Pattern 5: Advanced Retry Chains and Circuit Breakers

Rule: Use retry chains with circuit breakers to handle complex failure scenarios, detect cascade failures early, and prevent resource exhaustion.

Good Example:

This example demonstrates circuit breaker and fallback chain patterns.

typescript
1import { Effect, Schedule, Ref, Data } from "effect"; 2 3// Error classification 4class RetryableError extends Data.TaggedError("RetryableError")<{ 5 message: string; 6 code: string; 7}> {} 8 9class NonRetryableError extends Data.TaggedError("NonRetryableError")<{ 10 message: string; 11 code: string; 12}> {} 13 14class CircuitBreakerOpenError extends Data.TaggedError("CircuitBreakerOpenError")<{ 15 message: string; 16}> {} 17 18// Circuit breaker state 19interface CircuitBreakerState { 20 status: "closed" | "open" | "half-open"; 21 failureCount: number; 22 lastFailureTime: Date | null; 23 successCount: number; 24} 25 26// Create circuit breaker 27const createCircuitBreaker = (config: { 28 failureThreshold: number; 29 resetTimeoutMs: number; 30 halfOpenRequests: number; 31}) => 32 Effect.gen(function* () { 33 const state = yield* Ref.make<CircuitBreakerState>({ 34 status: "closed", 35 failureCount: 0, 36 lastFailureTime: null, 37 successCount: 0, 38 }); 39 40 const recordSuccess = Effect.gen(function* () { 41 yield* Ref.modify(state, (s) => { 42 if (s.status === "half-open") { 43 return [ 44 undefined, 45 { 46 ...s, 47 successCount: s.successCount + 1, 48 status: s.successCount + 1 >= config.halfOpenRequests 49 ? "closed" 50 : "half-open", 51 failureCount: 0, 52 }, 53 ]; 54 } 55 return [undefined, s]; 56 }); 57 }); 58 59 const recordFailure = Effect.gen(function* () { 60 yield* Ref.modify(state, (s) => { 61 const newFailureCount = s.failureCount + 1; 62 const newStatus = newFailureCount >= config.failureThreshold 63 ? "open" 64 : s.status; 65 66 return [ 67 undefined, 68 { 69 ...s, 70 failureCount: newFailureCount, 71 lastFailureTime: new Date(), 72 status: newStatus, 73 }, 74 ]; 75 }); 76 }); 77 78 const canExecute = Effect.gen(function* () { 79 const current = yield* Ref.get(state); 80 81 if (current.status === "closed") { 82 return true; 83 } 84 85 if (current.status === "open") { 86 const timeSinceFailure = Date.now() - (current.lastFailureTime?.getTime() ?? 0); 87 88 if (timeSinceFailure > config.resetTimeoutMs) { 89 yield* Ref.modify(state, (s) => [ 90 undefined, 91 { 92 ...s, 93 status: "half-open", 94 failureCount: 0, 95 successCount: 0, 96 }, 97 ]); 98 return true; 99 } 100 101 return false; 102 } 103 104 // half-open: allow limited requests 105 return true; 106 }); 107 108 return { recordSuccess, recordFailure, canExecute, state }; 109 }); 110 111// Main example 112const program = Effect.gen(function* () { 113 console.log(`\n[ADVANCED RETRY] Circuit breaker and fallback chains\n`); 114 115 // Create circuit breaker 116 const cb = yield* createCircuitBreaker({ 117 failureThreshold: 3, 118 resetTimeoutMs: 1000, 119 halfOpenRequests: 2, 120 }); 121 122 // Example 1: Circuit breaker in action 123 console.log(`[1] Circuit breaker state transitions:\n`); 124 125 let requestCount = 0; 126 127 const callWithCircuitBreaker = (shouldFail: boolean) => 128 Effect.gen(function* () { 129 const canExecute = yield* cb.canExecute; 130 131 if (!canExecute) { 132 yield* Effect.fail( 133 new CircuitBreakerOpenError({ 134 message: "Circuit breaker is open", 135 }) 136 ); 137 } 138 139 requestCount++; 140 141 if (shouldFail) { 142 yield* cb.recordFailure; 143 yield* Effect.log( 144 `[REQUEST ${requestCount}] FAILED (Circuit: ${(yield* Ref.get(cb.state)).status})` 145 ); 146 yield* Effect.fail( 147 new RetryableError({ 148 message: "Service error", 149 code: "500", 150 }) 151 ); 152 } else { 153 yield* cb.recordSuccess; 154 yield* Effect.log( 155 `[REQUEST ${requestCount}] SUCCESS (Circuit: ${(yield* Ref.get(cb.state)).status})` 156 ); 157 return "success"; 158 } 159 }); 160 161 // Simulate failures then recovery 162 const failSequence = [true, true, true, false, false, false]; 163 164 for (const shouldFail of failSequence) { 165 yield* callWithCircuitBreaker(shouldFail).pipe( 166 Effect.catchAll((error) => 167 Effect.gen(function* () { 168 if (error._tag === "CircuitBreakerOpenError") { 169 yield* Effect.log( 170 `[REQUEST ${requestCount + 1}] REJECTED (Circuit open)` 171 ); 172 } else { 173 yield* Effect.log( 174 `[REQUEST ${requestCount + 1}] ERROR caught` 175 ); 176 } 177 }) 178 ) 179 ); 180 181 // Add delay between requests 182 yield* Effect.sleep("100 millis"); 183 } 184 185 // Example 2: Fallback chain 186 console.log(`\n[2] Fallback chain (primary → secondary → cache):\n`); 187 188 const endpoints = { 189 primary: "https://api.primary.com/data", 190 secondary: "https://api.secondary.com/data", 191 cache: "cached-data", 192 }; 193 194 const callEndpoint = (name: string, shouldFail: boolean) => 195 Effect.gen(function* () { 196 yield* Effect.log(`[CALL] Trying ${name}`); 197 198 if (shouldFail) { 199 yield* Effect.sleep("50 millis"); 200 yield* Effect.fail( 201 new RetryableError({ 202 message: `${name} failed`, 203 code: "500", 204 }) 205 ); 206 } 207 208 yield* Effect.sleep("50 millis"); 209 return `data-from-${name}`; 210 }); 211 212 const fallbackChain = callEndpoint("primary", true).pipe( 213 Effect.orElse(() => callEndpoint("secondary", false)), 214 Effect.orElse(() => { 215 yield* Effect.log(`[FALLBACK] Using cached data`); 216 return Effect.succeed(endpoints.cache); 217 }) 218 ); 219 220 const result = yield* fallbackChain; 221 222 yield* Effect.log(`[RESULT] Got: ${result}\n`); 223 224 // Example 3: Error-specific retry strategy 225 console.log(`[3] Error classification and adaptive retry:\n`); 226 227 const classifyError = (code: string) => { 228 if (["502", "503", "504"].includes(code)) { 229 return "retryable-service-error"; 230 } 231 if (["408", "429"].includes(code)) { 232 return "retryable-rate-limit"; 233 } 234 if (["404", "401", "403"].includes(code)) { 235 return "non-retryable"; 236 } 237 if (code === "timeout") { 238 return "retryable-network"; 239 } 240 return "unknown"; 241 }; 242 243 const errorCodes = ["500", "404", "429", "503", "timeout"]; 244 245 for (const code of errorCodes) { 246 const classification = classifyError(code); 247 const shouldRetry = !classification.startsWith("non-retryable"); 248 249 yield* Effect.log( 250 `[ERROR ${code}] → ${classification} (Retry: ${shouldRetry})` 251 ); 252 } 253 254 // Example 4: Bulkhead pattern 255 console.log(`\n[4] Bulkhead isolation (limit concurrency per endpoint):\n`); 256 257 const bulkheads = { 258 "primary-api": { maxConcurrent: 5, currentCount: 0 }, 259 "secondary-api": { maxConcurrent: 3, currentCount: 0 }, 260 }; 261 262 const acquirePermit = (endpoint: string) => 263 Effect.gen(function* () { 264 const bulkhead = bulkheads[endpoint as keyof typeof bulkheads]; 265 266 if (!bulkhead) { 267 return false; 268 } 269 270 if (bulkhead.currentCount < bulkhead.maxConcurrent) { 271 bulkhead.currentCount++; 272 return true; 273 } 274 275 yield* Effect.log( 276 `[BULKHEAD] ${endpoint} at capacity (${bulkhead.currentCount}/${bulkhead.maxConcurrent})` 277 ); 278 279 return false; 280 }); 281 282 // Simulate requests 283 for (let i = 0; i < 10; i++) { 284 const endpoint = i < 6 ? "primary-api" : "secondary-api"; 285 const acquired = yield* acquirePermit(endpoint); 286 287 if (acquired) { 288 yield* Effect.log( 289 `[REQUEST] Acquired permit for ${endpoint}` 290 ); 291 } 292 } 293}); 294 295Effect.runPromise(program);

Rationale:

Advanced retry strategies handle multiple failure types:

  • Circuit breaker: Stop retrying when error rate is high
  • Bulkhead: Limit concurrency per operation
  • Fallback chain: Try multiple approaches in order
  • Adaptive retry: Adjust strategy based on failure pattern
  • Health checks: Verify recovery before resuming

Pattern: Combine Schedule.retry, Ref state, and error classification


Simple retry fails in production:

Scenario 1: Cascade Failure

  • Service A calls Service B (down)
  • Retries pile up, consuming resources
  • A gets overloaded trying to recover B
  • System collapses

Scenario 2: Mixed Failures

  • 404 (not found) - retrying won't help
  • 500 (server error) - retrying might help
  • Network timeout - retrying might help
  • Same retry strategy for all = inefficient

Scenario 3: Thundering Herd

  • 10,000 clients all retrying at once
  • Server recovers, gets hammered again
  • Needs coordinated backoff + jitter

Solutions:

Circuit breaker:

  • Monitor error rate
  • Stop requests when high
  • Resume gradually
  • Prevent cascade failures

Fallback chain:

  • Try primary endpoint
  • Try secondary endpoint
  • Use cache
  • Return degraded result

Adaptive retry:

  • Classify error type
  • Use appropriate strategy
  • Skip unretryable errors
  • Adjust backoff dynamically


Related Skills

Looking for an alternative to effect-patterns-scheduling-periodic-tasks or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication