en
Feedback
ToCode

ToCode

Open in Telegram

ื˜ื™ืคื™ื ืงืฆืจื™ื ืœืžืชื›ื ืชื™ื ืžืืช ื™ื ื•ืŸ ืคืจืง

Show more
1 420
Subscribers
No data24 hours
+27 days
-230 days
Posts Archive
ToCode
1 420
๐Ÿ“Œ ื™ื•ืชืจ ืžื”ื™ืจ ืœื ืื•ืžืจ ื™ื•ืชืจ ืคืฉื•ื˜ ื—ื‘ืจ ืžืงืฉื” - "ืœื›ืชื•ื‘ ืงื•ื“ ื”ื™ื•ื ื–ื” ืžืฉืขืžื. ืืชื” ืจืง ืžื‘ืงืฉ ืžืฉื”ื• ืžื” AI ื•ื™ืฉ ืœืš ืืช ื”ืงื•ื“. ืขื‘ื•ื“ื” ืฉืคืขื ืœืงื—ื” ื–ืžืŸ ื•ื—ืฉื™ื‘ื” ื”ื™ื•ื ืขื•ืฉื™ื ื›ืœืื—ืจ ื™ื“. ื–ื” ืœื ืžืขื ื™ื™ืŸ". ืื– ืฉืืœืชื™ ื‘ื—ื–ืจื” - "ื ื• ืื– ืžื” ื›ืชื‘ืช ืžืขื ื™ื™ืŸ ืขื ื” AI"?. ืฉืชื™ืงื”. ื™ื•ืชืจ ืงืœ ืœืจื›ื‘ ืขืœ ืื•ืคื ื™ื™ื ืžืืฉืจ ืœื ื”ื•ื’ ื‘ืื•ื˜ื•, ืืคื™ืœื• ืฉื”ืื•ื˜ื• ื ื•ืกืข ื™ื•ืชืจ ืžื”ืจ ื•ืืคื™ืœื• ืฉื‘ืื•ื˜ื• ืœื ืžื–ื™ืขื™ื. ื›ืฉืžืฉื”ื• ืžื”ื™ืจ ื™ื•ืชืจ ืœื ืื•ืžืจ ืฉื”ื•ื ืคืฉื•ื˜ ื™ื•ืชืจ. ื‘ืจื•ืจ ืฉืืคืฉืจ ืœื›ืชื•ื‘ ื”ื™ื•ื ื‘ืฉืขืชื™ื™ื POC ืฉืคืขื ื”ื™ื” ื“ื•ืจืฉ ื›ืกืฃ ื–ืžืŸ ื•ืžืคืชื—ื™ื. ื‘ืจื•ืจ ืฉืžืคืชื—ื™ื ืžื ื•ืกื™ื ืžืฆืœื™ื—ื™ื ืœื›ืชื•ื‘ ื”ื™ื•ื ืขื AI ืงื•ื“ ื‘ืžื”ื™ืจื•ืช ื’ื‘ื•ื”ื” ืžืฉืžืขื•ืชื™ืช ืžืžื” ืฉื›ืชื‘ื ื• ืœืคื ื™ ืฉื ื”. ืื‘ืœ ืฉื•ื•ื” ืœื”ื›ื™ืจ ื’ื ืฉ 50-70% ืžื”ืขื•ื‘ื“ื™ื ื‘ื—ื‘ืจื•ืช ืœื ืžื ืฆืœื™ื ืืช ืชืงืฆื™ื‘ ื”ื˜ื•ืงื ื™ื ืฉืœื”ื. ืœื ืžืฉืชืžืฉื™ื ื‘ืกื•ื›ื ื™ ืงื™ื“ื•ื“ ื›ื“ื™ ืœื”ืชืงื“ื ื‘ืžื”ื™ืจื•ืช ืฉื”ืžื ื”ืœื™ื ืฉืœื”ื ืจื•ืฆื™ื ืฉื”ื ื™ืชืงื“ืžื•. ื”ื ืื•ืœื™ ื ื•ืกืขื™ื ื‘ืื•ื˜ื• ืื‘ืœ ืขื“ื™ื™ืŸ ื‘ืžื”ื™ืจื•ืช 15 ืงืž"ืฉ. ื”ื ืœื ืขื•ืฉื™ื ืืช ื–ื” ื›ื™ ื”ื ืขืฆืœื ื™ื ืื• ื›ื™ ื”ื ืœื ืจื•ืฆื™ื ืœืขื‘ื•ื“. ื ืกื™ืขื” ื‘ืžื”ื™ืจื•ืช ื’ื‘ื•ื”ื” ื“ื•ืจืฉืช ืžื™ื•ืžื ื•ืช ืฉื•ื ื” ืžื ืกื™ืขื” ื‘ืžื”ื™ืจื•ืช ื ืžื•ื›ื”. ืžืคืชื—ื™ื ืจื‘ื™ื ื”ื™ื•ื ืžืกืชื›ืœื™ื ืขืœ "ืžื”ืคื›ืช ื” AI" ื•ื‘ืืžืช ืœื ืžื‘ื™ื ื™ื ืžื” ืจื•ืฆื™ื ืžื”ื. ื”ื ืžืฉืชืžืฉื™ื ื‘ AI ื›ื“ื™ ืœื›ืชื•ื‘ ืงื•ื“ ืื‘ืœ ื”ืงื•ื“ ืœื ื ื›ืชื‘ ื›ืœ ื›ืš ื”ืจื‘ื” ื™ื•ืชืจ ืžื”ืจ. ื›ืฉื™ื•ืฆืื™ื ืžืขื•ืœื ื” POC ื”ื ืžื’ืœื™ื ืฉื”ื ืžืฉืงื™ืขื™ื ื”ืจื‘ื” ื™ื•ืชืจ ื–ืžืŸ ื‘ Code Review, ื‘ืชื™ืงื•ื ื™ื. "ื”ื•ื ื”ืชื—ื™ืœ ืœืขืฉื•ืช ื‘ืœืื’ืŸ ื•ืœืขื‘ื•ื“ ื‘ืœื•ืคื™ื. ืžื–ืœ ืฉืชืคืกืชื™ ืื•ืชื• ื‘ื–ืžืŸ ื•ืขืฆืจืชื™ ืื•ืชื•". ื”ืืชื’ืจ ื”ื•ื ืฉื”ืจืฃ ืขื•ืœื”. ื—ื‘ืจื•ืช ื”ื™ื•ื ืžืฆืคื•ืช ืžืขื•ื‘ื“ื™ื ืœื™ื™ืฆืจ ืงื•ื“ ื‘ืžื”ื™ืจื•ืช ืฉืœ ืžื›ื•ื ื™ืช. ื”ืกื™ืคื•ืจ ื”ื•ื ืœื ืื ืžืฉืชืžืฉื™ื ื‘ AI ืืœื ืื™ืš ืžืฉืชืžืฉื™ื ื‘ื•. ื”ืจื‘ื” ืžื”ื‘ืขื™ื•ืช ืฉืœ ืืชืžื•ืœ ื ืคืชืจื•. ื”ืจื‘ื” ื‘ืขื™ื•ืช ื—ื“ืฉื•ืช ื ื•ืฆืจื•. ื”ื™ื•ื ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœืขืœื•ืช ืจืžื”.

ToCode
1 420
from repid import Job, Queue

from app_repid import app, QUEUE


async def main():
    if len(sys.argv) < 2:
        print("Usage: python dispatcher_repid.py <max_posts>")
        sys.exit(1)

    max_posts = int(sys.argv[1])
    pages_needed = math.ceil(max_posts / 10)

    print(f"Downloading up to {max_posts} posts across {pages_needed} index page(s)")

    async with app.magic(auto_disconnect=True):
        # Declare the queue so jobs can be enqueued before any worker starts.
        await Queue(QUEUE).declare()

        for page_num in range(1, pages_needed + 1):
            # Each page has 10 posts; the last page may have fewer
            already_allocated = (page_num - 1) * 10
            posts_limit = min(10, max_posts - already_allocated)

            await Job(
                name="download_index_page",
                queue=QUEUE,
                args={"page_num": page_num, "posts_limit": posts_limit},
                retries=3,
            ).enqueue()
            print(f"  Dispatched page {page_num} (limit={posts_limit})")

    print("All index pages dispatched. Workers will now process the jobs.")


if __name__ == "__main__":
    asyncio.run(main())
โœ ืกื™ื›ื•ื - ืžื” ืžื•ืฆืœื— ื‘ื“ื•ื’ืžื”. ืžื” ืขื•ื“ ืฆืจื™ืš ืœืฉืคืจ. ื”ืงื•ื“ ืžืจืื” ืื™ืš ืœื”ื•ืจื™ื“ ื‘ืžืงื‘ื™ืœ ืคื•ืกื˜ื™ื ืžื”ื‘ืœื•ื’. ื”ืงื•ื“ ืžืงื‘ืœ ืžืกืคืจ ืคื•ืกื˜ื™ื ืœื”ื•ืจื“ื”, ืžื—ืฉื‘ ื›ืžื” ื“ืคื™ื ืฆืจื™ืš ืœืฉืžื•ืจ ื•ืื– ืžื•ืฆื™ื ืžืฉื™ืžื•ืช ื‘ืžืงื‘ื™ืœ: 1. ืžืฉื™ืžื” ืœื›ืœ ื“ืฃ ืฉืฆืจื™ืš ืœื”ื•ืจื™ื“. 2. ื‘ื–ืžืŸ ืฉื“ืคื™ ื”ืื™ื ื“ืงืก ื™ื•ืจื“ื™ื, ื›ืœ ื“ืฃ ืฉืกื™ื™ื ื™ื•ืฆืจ ืžืฉื™ืžื•ืช ื—ื“ืฉื•ืช ืœื”ื•ืจื“ืช ื”ืคื•ืกื˜ื™ื ืฉื”ื•ืคื™ืขื• ื‘ื•. ื”ื›ืœ ืืกื™ื ื›ืจื•ื ื™ ื•ื”ื›ืœ ืžื•ื’ื‘ืœ ื‘ืขื“ 10 ืžืฉื™ืžื•ืช ืœืคื•ืขืœ ื•ืฉื ื™ ืคื•ืขืœื™ื, ืกืš ื”ื›ืœ ืขื“ 20 ื”ื•ืจื“ื•ืช ื‘ืžืงื‘ื™ืœ ืžื”ืืชืจ. ื”ื“ื•ื’ืžื” ืœื ื›ื•ืœืœืช Type Safety ืขืœ ื”ืžืฉื™ืžื•ืช ืขืฆืžืŸ. ืœืจืคื™ื“ ื™ืฉ ืื™ื ื˜ื’ืจืฆื™ื” ืขื pydantic ืื‘ืœ ืขื“ื™ื™ืŸ ืœื ื ื™ืกื™ืชื™ ืื•ืชื” ืื– ื–ื” ื™ื”ื™ื” ื ื•ืฉื ืœืคื•ืกื˜ ื”ืžืฉืš.

ToCode
1 420
def to_markdown_url(post_url: str) -> str:
    """Convert a blog post URL to its markdown version by stripping
    the query string and appending .md."""
    base = post_url.split("?")[0]
    return f"{base}.md"


def extract_post_urls(soup: BeautifulSoup, limit: int):
    """
    Generator that yields up to `limit` unique blog post URLs
    from a blog index page BeautifulSoup parse tree.

    Blog post URLs are like /blog/<date-slug>?page=1
    Index page is /blog?page=N (no trailing slash) โ€” excluded by startswith.
    """
    seen = set()
    count = 0
    for a_tag in soup.select("a[href]"):
        href = a_tag["href"]
        if href.startswith("/blog/") and href != "/blog/":
            full_url = f"https://www.tocode.co.il{href}"
            if full_url not in seen:
                seen.add(full_url)
                yield full_url
                count += 1
                if count >= limit:
                    return


@router.actor(queue=QUEUE)
async def download_index_page(page_num: int, posts_limit: int) -> dict:
    """
    Download a blog index page, extract post links, and enqueue a
    download_post job for each post found.

    posts_limit: how many posts to download from this page (max 10).
    """
    url = f"{BASE_URL}?page={page_num}"
    resp = await client.get(url)
    resp.raise_for_status()

    soup = BeautifulSoup(resp.text, "html.parser")

    for post_url in extract_post_urls(soup, posts_limit):
        md_url = to_markdown_url(post_url)
        # The worker holds the active (magic) connection, so jobs enqueued
        # from inside an actor reuse it automatically.
        await Job(
            name="download_post",
            queue=QUEUE,
            args={"md_url": md_url},
            retries=3,
        ).enqueue()

    return {"page": page_num}


@router.actor(queue=QUEUE)
async def download_post(md_url: str) -> dict:
    """
    Download a single blog post markdown file and save it to the data folder.
    The URL is already the .md version (converted by the dispatcher).
    """
    resp = await client.get(md_url)
    resp.raise_for_status()

    # Derive filename from the URL slug: /blog/slug.md โ†’ slug
    slug = md_url.rstrip("/").split("/")[-1].removesuffix(".md")
    filename = f"{slug}.md"
    filepath = os.path.join(DATA_DIR, filename)

    os.makedirs(DATA_DIR, exist_ok=True)
    with open(filepath, "w", encoding="utf-8") as f:
        f.write(resp.text)

    return {"file": filename, "size_bytes": len(resp.text)}
ื›ืœ ืคื•ื ืงืฆื™ื” ืฉืžืกื•ืžืช ื‘ืชื•ืจ actor ืžื’ื“ื™ืจื” ืžืฉื™ืžื”. ืืฆืœื ื• ื‘ืชื•ื›ื ื™ืช ืืœื” ื”ืคื•ื ืงืฆื™ื•ืช download_index_page ื• download_post. ืžืฉื™ืžื•ืช ืžื•ื’ื“ืจื•ืช ืขืœ ื” Router ื•ื–ื›ืจื• ืฉื›ืœ Worker ืžืงื‘ืœ ื‘ื™ืฆื™ืจื” ืืช ื” Router-ื™ื ืœืงื—ืช ืžื”ื ืžืฉื™ืžื•ืช:
worker = Worker(routers=[router], tasks_limit=10)
ื”ืžืฉื™ืžื•ืช ืขืฆืžืŸ ื”ืŸ ืคืฉื•ื˜ ืงื•ื“ ืฉืžื•ืจื™ื“ ื“ืฃ ืื™ื ื“ืงืก (ืจืฉื™ืžื” ืฉืœ ืคื•ืกื˜ื™ื) ืื• ืคื•ืกื˜ ืกืคืฆื™ืคื™ ื•ืžื” ืฉื—ืฉื•ื‘ ืœื’ื‘ื™ื”ืŸ ืฉื™ื”ื™ื• ืคื•ื ืงืฆื™ื•ืช ืืกื™ื ื›ืจื•ื ื™ื•ืช. ืžืขื ื™ื™ืŸ ืœืฉื™ื ืœื‘ ื‘ืงื•ื“ ื”ืžืฉื™ืžื” ืฉืžื•ืจื™ื“ื” ืืช ื“ืฃ ื”ืื™ื ื“ืงืก ืื™ืš ื”ื™ื ืžื™ื™ืฆืจืช ืžืฉื™ืžื•ืช ื—ื“ืฉื•ืช ื›ื“ื™ ืœื”ื•ืจื™ื“ ืืช ื”ืคื•ืกื˜ื™ื:
    for post_url in extract_post_urls(soup, posts_limit):
        md_url = to_markdown_url(post_url)
        # The worker holds the active (magic) connection, so jobs enqueued
        # from inside an actor reuse it automatically.
        await Job(
            name="download_post",
            queue=QUEUE,
            args={"md_url": md_url},
            retries=3,
        ).enqueue()

    return {"page": page_num}
โœ ืฉื™ื’ื•ืจ ื”ืžืฉื™ืžื•ืช ื”ื—ืœืง ื”ืื—ืจื•ืŸ ืฉืœ ื”ืžืขืจื›ืช ื”ื•ื ื”ืงื•ื ื˜ื™ื™ื ืจ ืฉืžืฉื’ืจ ืืช ื”ืžืฉื™ืžื•ืช. ืœืžืขืฉื” ื”ืžืฉื™ืžื” ื”ื™ื—ื™ื“ื” ืฉืื ื—ื ื• ืฆืจื™ื›ื™ื ืœื”ืคืขื™ืœ ื”ื™ื ื”ื•ืจื“ืช ื“ืฃ ื”ืื™ื ื“ืงืก ื›ื™ ื”ืคื•ื ืงืฆื™ื” ืฉืœื• ื›ื‘ืจ ืžืคืขื™ืœื” ืืช ืžืฉื™ืžืช ื”ื•ืจื“ืช ื”ืคื•ืกื˜ื™ื ื›ืžื• ืฉืงื•ื“ื ืจืื™ื ื•. ื–ื” ื”ืงื•ื“ ืฉืœ dispatcher_repid.py ืฉืžืชื—ื™ืœ ื”ื•ืจื“ื” ืฉืœ ื“ืคื™ ื”ืื™ื ื“ืงืก ื‘ืžืงื‘ื™ืœ:
"""
Dispatcher (repid version): calculates how many blog index pages are needed
and enqueues download_index_page jobs via repid.

Usage:
    uv run python dispatcher_repid.py <max_posts>

Example:
    uv run python dispatcher_repid.py 25   # downloads up to 25 posts
"""

import asyncio
import math
import sys

ToCode
1 420
๐Ÿ“Œ ื“ื•ื’ืžืช Repid - ื”ื•ืจื“ืช ื”ืคื•ืกื˜ื™ื ืžื”ื‘ืœื•ื’ ื‘ืžืงื‘ื™ืœ ืจืคื™ื“ ื”ื™ื ืกืคืจื™ื™ืช ืคื™ื™ืชื•ืŸ ืœื”ืจืฆืช ืžืฉื™ืžื•ืช ื‘ืžืงื‘ื™ืœ. ื”ื™ื ื“ื•ืžื” ืœ Celery ืื‘ืœ ืคื•ืคื•ืœืจื™ืช ืคื—ื•ืช ื•ืืกื™ื ื›ืจื•ื ื™ืช, ื•ื“ื•ืžื” ืœ dramatiq ื”ืคืขื ืืกื™ื ื›ืจื•ื ื™ืช ื›ืžื•ื”, ื—ื“ืฉื” ื™ื•ืชืจ ื•ืคื—ื•ืช ืคื•ืคื•ืœืจื™ืช. ื”ืชื›ื•ื ื•ืช ื”ื˜ื•ื‘ื•ืช ืฉืœ Repid ื›ื•ืœืœื•ืช: 1. ืžืฉื™ืžื•ืช ืืกื™ื ื›ืจื•ื ื™ื•ืช (ื›ืžื•ื‘ืŸ, ื‘ืฉื‘ื™ืœ ื–ื” ื‘ืื ื•). 2. ืชืžื™ื›ื” ื˜ื•ื‘ื” ื‘ื‘ื“ื™ืงื•ืช ืขื ืจื›ื™ื‘ TestClient. 3. ืชื™ืขื•ื“ ื™ื“ื™ื“ื•ืชื™ ืœืกื•ื›ื ื™ื ืขื ืงื‘ืฆื™ llms.txt ื• llms-full.txt. 4. ื—ื™ื‘ื•ืจ ืžื•ื‘ื ื” ืœ pydantic ื‘ืฉื‘ื™ืœ ื”ื’ื“ืจืช ื˜ื™ืคื•ืกื™ื. ื“ื•ื’ืžื”? ื‘ื˜ื— ื‘ื•ืื• ื ื›ืชื•ื‘ ืชื•ื›ื ื™ืช ืคื™ื™ืชื•ืŸ ืฉืชืฉืžื•ืจ ืคื•ืกื˜ื™ื ืžื”ื‘ืœื•ื’ ื”ื–ื” ืœืงืจื™ืื” ืื•ืคืœื™ื™ืŸ. โœ ืžื‘ื ื” ื”ืžืขืจื›ืช docker-compose.yml ืชื—ื ื” ืจืืฉื•ื ื” ื”ื™ื ืžื‘ื ื” ื”ืžืขืจื›ืช. ืžืื—ืจ ื•ืจืคื™ื“ ื”ื•ื ืžืขืจื›ืช ืœื”ืจืฆืช ืžืฉื™ืžื•ืช ื‘ืฆื•ืจื” ืžื‘ื•ื–ืจืช ืืฉืชืžืฉ ื‘ docker-compose.yml ื›ื“ื™ ืœื™ื™ืฆืจ ืžืกืคืจ ืงื•ื ื˜ื™ื™ื ืจื™ื. ื–ื” ื”ืงื•ื‘ืฅ:
services:
  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5

  worker-1:
    image: ghcr.io/astral-sh/uv:python3.14-bookworm
    working_dir: /app
    depends_on:
      redis:
        condition: service_healthy
    command: sh -c "uv sync --frozen --no-dev && uv run python worker_repid.py"
    volumes:
      - .:/app
      - ./data:/app/data
      - /app/.venv
    environment:
      - REPID_REDIS_URL=redis://redis:6379/0

  worker-2:
    image: ghcr.io/astral-sh/uv:python3.14-bookworm
    working_dir: /app
    depends_on:
      redis:
        condition: service_healthy
    command: sh -c "uv sync --frozen --no-dev && uv run python worker_repid.py"
    volumes:
      - .:/app
      - ./data:/app/data
      - /app/.venv
    environment:
      - REPID_REDIS_URL=redis://redis:6379/0

  dispatcher:
    image: ghcr.io/astral-sh/uv:python3.14-bookworm
    working_dir: /app
    depends_on:
      redis:
        condition: service_healthy
    command: sh -c "uv sync --frozen --no-dev && uv run python dispatcher_repid.py ${MAX_POSTS:-10}"
    volumes:
      - .:/app
      - ./data:/app/data
      - /app/.venv
    environment:
      - REPID_REDIS_URL=redis://redis:6379/0
    profiles:
      - dispatch
ืžืชืื ื”ืขื‘ื•ื“ื” ื”ื•ื ืจื“ื™ืก ื‘ืงื•ื ื˜ื™ื™ื ืจ ื”ืจืืฉื•ืŸ. ืงื•ื ื˜ื™ื™ื ืจื™ื 2 ื• 3 ื”ื ื”ืคื•ืขืœื™ื ื•ืงื•ื ื˜ื™ื™ื ืจ ืจื‘ื™ืขื™ ืฉื•ืœื— ืืช ื”ืžืฉื™ืžื•ืช ื”ืžืชื•ื–ืžื ื•ืช. โœ ืงื•ื“ ื”ืคื•ืขืœื™ื ื”ืกืงืจื™ืคื˜ ืฉืœ ื”ืคื•ืขืœื™ื ืžืžืฉ ืคืฉื•ื˜:
import asyncio

from repid import Worker

from app_repid import app, router, QUEUE


async def run_worker():
    async with app.magic(auto_disconnect=True):
        # auto_declare=True (default) makes the worker declare the queue
        # before it starts consuming.
        # tasks_limit caps how many actor coroutines run concurrently on this
        # worker's event loop -> at most 10 concurrent downloads per worker.
        worker = Worker(routers=[router], tasks_limit=10)
        await worker.run()


if __name__ == "__main__":
    asyncio.run(run_worker())
ื”ื•ื ืžืจื™ืฅ ืคื•ื ืงืฆื™ื” ืฉืœ ืจืคื™ื“ ื•ืžื’ื“ื™ืจ ื”ื’ื‘ืœื” ืฉืœ 10 ืžืฉื™ืžื•ืช ื‘ืžืงื‘ื™ืœ. ืงื•ื“ ื”ืžืฉื™ืžื” ืขืฆืžื” ืžื•ื’ื“ืจ ื‘ืงื•ื‘ืฅ app_repid.py ื‘ืื•ืชื” ืชื™ืงื™ื”. ื–ื” ืชื•ื›ืŸ ื”ืงื•ื‘ืฅ:
"""
Repid application: defines the broker connection, the router and the
two actors (download_index_page, download_post).

This module is imported by both the worker (worker_repid.py) and the
dispatcher (dispatcher_repid.py). The actors are the repid equivalent of
the Celery tasks in tasks.py.
"""

import os
import httpx
from bs4 import BeautifulSoup
from repid import Repid, Connection, RedisMessageBroker, Job, Router

BROKER_URL = os.environ.get("REPID_REDIS_URL", "redis://localhost:6379/0")

# A single Repid app wraps the connection to the message broker (Redis).
# Entering `app.magic()` makes this connection the implicit one used by
# Job().enqueue(), Queue().declare() and the Worker.
app = Repid(Connection(RedisMessageBroker(BROKER_URL)))

# Shared async HTTP client. Because the actors `await` it, many downloads can
# be in flight on the worker's event loop at once (up to the worker's
# tasks_limit). follow_redirects mirrors requests' default behavior.
client = httpx.AsyncClient(timeout=30, follow_redirects=True)

router = Router()

QUEUE = "crawler"
BASE_URL = "https://www.tocode.co.il/blog"
DATA_DIR = "/app/data"

ToCode
1 420
๐Ÿ“Œ ืžื•ืชืจ ืœื”ืชื—ืจื˜? ื›ืœื™ ื”ืคื™ืชื•ื— ืฉืื ื—ื ื• ืฆืจื™ื›ื™ื ืืชืžื•ืœ ื›ื“ื™ ืœืฉืœื‘ Agents ื‘ืฆื•ื•ืช ืฉื™ืœื•ื‘ AI Agents ื‘ืฆื•ื•ืช ืคื™ืชื•ื— ืžื•ื‘ื™ืœ ื™ื—ื“ ืขื ื”ืฉื™ืคื•ืจ ื‘ืžื”ื™ืจื•ืช ื”ืคื™ืชื•ื— ื’ื ืืชื’ืจื™ื ื—ื“ืฉื™ื ื•ื‘ืžื™ื•ื—ื“ ื”ืจื‘ื” ืžืื•ื“ ืขื‘ื•ื“ืช Review ื• Refactor. ื ื›ื•ืŸ ืœื”ื™ื•ื ืื ื™ ืžืงื‘ืœ ืงื•ื“ ืฉื›ืชื‘ AI Agent ืจืง ื‘ื ื™ืกื™ื•ืŸ ื”ืฉื ื™ ืื• ื”ืฉืœื™ืฉื™ ืœืžื™ืžื•ืฉ. ื”ื‘ืขื™ื” ื”ื™ื ืฉืœื ืชืžื™ื“ ืื ื—ื ื• ืžืฆืœื™ื—ื™ื ืœืขืฆื•ืจ ืืช ืจืฆืฃ ื”ืคื™ืชื•ื— ื‘ืฉื‘ื™ืœ Code Review. ื‘ืžื™ื•ื—ื“ ื›ืฉื™ืฉ ืขื•ื“ ืื ืฉื™ื ืฉืžืขื•ืจื‘ื™ื ื‘ืคื™ืชื•ื— ื•ื‘ืจืื™ื™ื” ืœืขืชื™ื“ ืžื” ืฉื”ื•ืœืš ืœืงืจื•ืช ื–ื” ืฉืื ืฉื™ ืžื•ืฆืจ ืื• ืื ืฉื™ื ื˜ื›ื ื™ื™ื ื™ื›ืชื‘ื• ืื™ืคื™ื•ื ื™ื ื•ืžืคืชื—ื™ื ื™ืฆื˜ืจื›ื• ืœื”ื’ื™ืข ืœืงื•ื“ ื‘ื”ืžืฉืš ื›ื“ื™ ืœื‘ืฆืข Code Review ื•ืœืฉืคืจ. ื•ืœืชื”ืœื™ืš ื”ื–ื” ืื ื—ื ื• ืœื ืขืจื•ื›ื™ื. ื”ื ื” ื›ืžื” ื‘ืขื™ื•ืช ื•ืจืขื™ื•ื ื•ืช ืœื›ืœื™ื ืขืชื™ื“ื™ื™ื ืžื‘ื•ืกืกื™ AI ืฉืื•ืœื™ ื™ืขื–ืจื•: 1. ื’ื™ื˜ - ื’ื™ื˜ ืœื ืื•ื”ื‘ ืฉืื ื—ื ื• ืžื›ื ื™ืกื™ื ืฉื™ื ื•ื™ ืื—ืจื™ ืฉื™ืฉ ืงื•ืžื™ื˜ื™ื ื—ื“ืฉื™ื ืฉื”ืชื‘ืกืกื• ืขืœ ืงื•ื“ ืฉื›ื‘ืจ ื ื“ื—ืฃ ืœืจื™ืคื•. ื‘ืขื•ืœื ืžืฉื•ืœื‘ AI ืื ื—ื ื• ื ืจืฆื” ื›ืœื™ ื ื™ื”ื•ืœ ื’ืจืกืื•ืช ืฉืžืืคืฉืจ ืœื™ ืœืฉื ื•ืช ืืช ื”ื”ื™ืกื˜ื•ืจื™ื” ื•ื ืขื–ืจ ื‘ AI ื›ื“ื™ ืœื™ื™ืฆืจ ืžื—ื“ืฉ ืืช ื›ืœ ื”ืงื•ื“ ืฉืžื’ื™ืข ืื—ืจื™. 2. ื‘ืกื™ืกื™ ื ืชื•ื ื™ื - ืžืคืชื—ื•ืช ื–ืจื™ื ื• Sequence-ื™ื ื‘ื‘ืกื™ืกื™ ื ืชื•ื ื™ื ืžื‘ื™ื ื™ื ืœืžืฆื‘ ืฉืงืฉื” ืœื™ ืžืื•ื“ ืœืฉื ื•ืช ื”ื™ืกื˜ื•ืจื™ื” ืื—ืจื™ ืฉื”ื™ื ืงืจืชื”. ื‘ืขืชื™ื“ ืื ื—ื ื• ื ืฆื˜ืจืš ืœืžืฆื•ื ื“ืจืš ืœื”ื•ืฆื™ื "ืขื ืฃ" ืžื’ืจืกื” ื™ืฉื ื” ืฉืœ ื‘ืกื™ืก ื”ื ืชื•ื ื™ื ื•ืœื”ืœื‘ื™ืฉ ืืช ื”ื ืชื•ื ื™ื ื”ื—ื“ืฉื™ื ืขืœ ื”ืฉื™ื ื•ื™ ืฉื ื‘ืฆืข ื‘ื”ื™ืกื˜ื•ืจื™ื”. 3. ืชืฉืชื™ื•ืช - ืฉื™ื ื•ื™ ื—ื™ื‘ื•ืจื™ ืชืฉืชื™ืช ืขื ื›ืœื™ื ื›ืžื• ืื ืกื™ื‘ืœ ืื• ื˜ืจืคื•ืจื ื”ื™ื•ื ืžื›ืจื™ื— ืื•ืชื ื• ืœื‘ืฆืข ืžื™ื’ืจืฆื™ื” ื™ื“ื ื™ืช ืฉืœ ื”ื ืชื•ื ื™ื. ืื ืกื•ื›ืŸ ืžื—ืœื™ื˜ ืœื”ืฉืชืžืฉ ื‘ืžื•ื ื’ื• ื•ืื ื™ ืžื’ืœื” ืืช ื–ื” ืื—ืจื™ ืฉื‘ืกื™ืก ื”ื ืชื•ื ื™ื ื”ื—ื“ืฉ ื‘ืื•ื•ื™ืจ ืื ื™ ืฆืจื™ืš ืœื”ื™ื•ืช ืžืกื•ื’ืœ ืœืฉื ื•ืช ืืช ื”ื”ื—ืœื˜ื” ื•ืกื•ื›ืŸ ืื—ืจื™ ื™ื“ืข ืœื”ืขื‘ื™ืจ ืืช ื”ื ืชื•ื ื™ื ืฉื›ื‘ืจ ื ื•ืฆืจื• ืœืืจื›ื™ื˜ืงื˜ื•ืจื” ื”ื—ื“ืฉื”. ื”ืžืฉืžืขื•ืช ืฉืœ ืœื”ื•ืฆื™ื ืืช ื”ืžืคืชื—ื™ื ืžื”ืœื•ืค ื•ืœื•ื•ืชืจ ืขืœ ืฆื•ื•ืืจ ื”ื‘ืงื‘ื•ืง ืฉืœ Code Reviews ื”ื™ื ื”ื™ื›ื•ืœืช ืœื”ืชื—ืจื˜ ื•ืœืชืงืŸ ื˜ืขื•ื™ื•ืช ืฉืœ ืกื•ื›ื ื™ื. ื’ื™ื˜ ื”ื•ืžืฆื ื‘ืžืงืจื” ื‘ 2005. ื”ืขื ืŸ ืฉืœ AWS ื”ื•ืงื ื‘ 2002. ื˜ืจืคื•ืจื ื‘ 2014. ืื™ืŸ ืกื™ื‘ื” ืœื”ื ื™ื— ืฉื”ื›ืœื™ื ื”ืืœื” ื™ื™ืฉืืจื• ืื™ืชื ื• ืœืขื“.

ToCode
1 420
4. ืชืจื’ื•ื ื”ืžื™ืœื™ื - ืœื ื”ืชื™ื—ืกืชื™ ื‘ืคืจื•ืžืคื˜ ื‘ื›ืœืœ ืœืฉืืœื” ืื™ืš ืœืชืจื’ื ืืช ื”ืžื™ืœื™ื ื”ื‘ื•ื“ื“ื•ืช ื•ืœื›ืŸ ืงืœื•ื“ ื™ืฆืจ ืžื ื’ื ื•ืŸ ื‘ื–ื‘ื–ื ื™ ืฉืคื•ื ื” ืœ LLM ื›ื“ื™ ืœืชืจื’ื ื›ืœ ืžื™ืœื” ื‘ื ืคืจื“. ืฉื™ืคื•ืจ ื”ื›ืจื—ื™ ื”ื™ื” ืœืงื‘ืฅ ืžื™ืœื™ื ื™ื—ื“ ื‘ืฉื‘ื™ืœ ื”ืชืจื’ื•ื. ืžื” ื ืฉืืจ? ืœื”ื›ื ื™ืก ืชื›ื ื™ื ื‘ืขื•ื“ ืฉืคื•ืช ื•ืœืจืื•ืช ืื ืคืœืืฉ ืขื•ืžื“ ื‘ื–ื”, ืœื•ื•ื“ื ืฉืงืจื™ื•ืงื™ ืœื ืฉื•ื‘ืจ ืืช ื”ืฆืคื™ื™ื” ืžืžื•ื‘ื™ื™ืœ. ืจื•ืฆื™ื ืœืจืื•ืช ืืช ื”ืงืจื™ื•ืงื™ ื‘ืคืขื•ืœื”? ื”ื ื” ืฉื™ืจ ืจืืฉื•ืŸ ืฉื”ืขืœื™ืชื™ ืื™ืชื•: https://langlets.app/courses/860/lessons/kissy-face-and-red-hearts

ToCode
1 420
๐Ÿ“Œ ื ื™ืชื•ื— ืคืจื•ืžืคื˜ - ืžืฆื‘ ืงืจื™ื•ืงื™ ืœืคื ื™ ื—ืฆื™ ืฉื ื” ื“ื ืฉื™ ื”ืฆื™ืข ืฉืื•ืกื™ืฃ ืœ langlets ืžืฆื‘ ืงืจื™ื•ืงื™ ืฉืžื“ื’ื™ืฉ ืืช ื”ืžื™ืœื” ื”ื ื•ื›ื—ื™ืช ื›ืฉืžื ื’ื ื™ื ืฉื™ืจ. ื‘ืื•ืชื• ื–ืžืŸ ืœื ื”ืืžื ืชื™ ืฉื–ื” ืืคืฉืจื™ - ืžื•ื“ืœ AI ืฉื™ื•ื“ืข ืœืžืฆื•ื ื–ืžืŸ ืœื›ืœ ืžื™ืœื”? ื”ื ื‘ืงื•ืฉื™ ืžืฆืœื™ื—ื™ื ืœื™ืฆื•ืจ ืœื™ ื”ืชืืžื” ื‘ืจื–ื•ืœื•ืฆื™ื” ืฉืœ ืžืฉืคื˜ื™ื. ื—ืฆื™ ืฉื ื” ืขื‘ืจื” ื• Gemini 3.5 Flash ืขื•ืžื“ ื‘ืžืฉื™ืžื” ื‘ืฆื•ืจื” ืžืจืฉื™ืžื”. ืื—ืจื™ ืฉืจืื™ืชื™ ืืช ื”ืชื•ืฆืื•ืช ื”ืœื›ืชื™ ืœืฉื ื•ืช ืืช ื”ืงื•ื“, ืื• ื™ื•ืชืจ ื ื›ื•ืŸ ื ืชืชื™ ืœืงืœื•ื“ ืœืฉื ื•ืช. ืื ื™ ืจื•ืฆื” ืœื”ืฆื™ื’ ื›ืืŸ ืืช ื”ืคืจื•ืžืคื˜ ื•ืœื“ื‘ืจ ืขืœ ื”ืฉื™ืงื•ืœื™ื ื‘ื›ืชื™ื‘ืชื• ื•ื’ื ืœืกื›ื ืžื” ืขื‘ื“ ื•ืžื” ืขื•ื“ ื”ื™ื” ืฆืจื™ืš ืœื”ื•ืกื™ืฃ. โœ ืœืคื ื™ ื”ื›ืœ ื”ืคืจื•ืžืคื˜ ื”ืชื—ืœืชื™ ืขื ื”ืคืจื•ืžืคื˜ ื”ื–ื” ื›ืงืœื˜ ืœืžืฆื‘ ืชื›ื ื•ืŸ (ืขื“ ื›ื“ื™ ื”ืงื˜ืขื™ื ื”ื˜ื›ื ื™ื™ื ืฉืื ื™ ืžืฆืžืฆื ืคื” ื›ื“ื™ ืœืžืงื“ ืืช ื”ืคืจื•ืžืคื˜):
Switch to per word timing maintaining backward compatibility

Step 1 - Create Song Pipeline
Refactor the extract lyrics prompt to the following version:

[...]

each "word" in the output should create a token translation
Then create_token_translations step doesn't have to do language alignment, it should just translate each "word". Still give the LLM the full phrase for context though.

Step 2 - Schema
Add timestamp to token_translation

Step 3 - UI
Show karaoke style word highlight marking current token when playing in the video players

Step 4 - Verification and format
Use the existing apt_word_timing.json output with song URL as the result of extract youtube lyrics
https://www.youtube.com/watch?v=ekr2nIex040

Run the pipeline steps AFTER extract youtube lyrics to create the rest of the data and save it to a JSON file. I'll then manually import that JSON file to check the result. Create a reusable script so we can repeat our testing

Step 5 - Backward Compatibility
The video players should support 2 cases:

token_translations with timestamps (new functionality) - use karaoke style word highlight
token_trnslations without timestamps (existing data) - continue to use phrase level highlight
Pass a boolean value from rails video activity params to indicate if it should use the new or old style
ืžืฆื‘ ืกื•ื›ืŸ ืฉืืœ ืื•ืชื™ ื›ืžื” ืฉืืœื•ืช ื”ื‘ื”ืจื”, ื™ืฆืจ ืชื•ื›ื ื™ืช ื•ืื– ืžืฆื‘ ืื•ื˜ื•ืžื˜ื™ ืžื™ืžืฉ ืื•ืชื” ื•ื”ืกืจื˜ ื”ืจืืฉื•ืŸ ื ืคืชื— ื‘ืžืฆื‘ ืงืจื™ื•ืงื™ ื›ืš ืฉื›ืžืขื˜ ืืคืฉืจ ืœืกืžืŸ ื”ืฆืœื—ื”. โœ ืžื” ื˜ื•ื‘ ื‘ืคืจื•ืžืคื˜ ืืœื” ื”ื ืงื•ื“ื•ืช ื”ื—ื–ืงื•ืช ืฉืœ ื”ืคืจื•ืžืคื˜: 1. ื”ืฆื’ืช ื”ื”ืฉืคืขื” - ื‘ืจื•ืจ ืขืœ ืื™ื–ื” ื—ืœืงื™ื ื‘ืงื•ื“ ื”ืฉื™ื ื•ื™ ืžืฉืคื™ืข. ื”ื—ืœืงื™ื ื”ืขื™ืงืจื™ื™ื ื”ื ื”ืฉื™ื ื•ื™ ื‘ืžื ื’ื ื•ืŸ ืชืžืœื•ืœ ื”ืกืจื˜ ื•ื”ืฉื™ื ื•ื™ ื‘ืžื ื’ื ื•ืŸ ืชืจื’ื•ื ื”ืžื™ืœื™ื. 2. ืฉื™ื ื•ื™ื™ื ื‘ืกื›ื™ืžื” - ืฉื™ื ื•ื™ื™ื ื‘ืžื•ื“ืœ ื•ืื™ืš ืฉืฉื•ืžืจื™ื ืืช ื”ืžื™ื“ืข ืžื•ืคื™ืขื™ื ื‘ืฆื•ืจื” ืžืคื•ืจืฉืช ื•ืขื•ื–ืจื™ื ืœืžืงื“ ืืช ืงืœื•ื“. ื‘ืžืงืจื” ืฉืœื ื• ื™ืฉ ืชื•ืกืคืช ืฉืœ ืขืžื•ื“ื” ืื—ืช ืœื˜ื‘ืœืช token_translations. 3. ืžืžืฉืง ืžืฉืชืžืฉ - ืฉื™ืžื•ืฉ ื‘ื‘ื™ื˜ื•ื™ Karaoke Style ืžื‘ื”ื™ืจ ื‘ื“ื™ื•ืง ืื™ืš ื“ื‘ืจื™ื ืฆืจื™ื›ื™ื ืœื”ื™ืจืื•ืช, ื‘ืœื™ ืœื”ื›ื ืก ืœืคืจื˜ื™ื ื”ื˜ื›ื ื™ื™ื ืฉืœ ืื™ืš ื–ื” ื™ืžื•ืžืฉ. ืื™ืŸ ืฉื•ื ื“ื‘ืจ ืžื™ื•ื—ื“ ื‘ืงืจื™ื•ืงื™ ื‘ืืคืœื™ืงืฆื™ื” ื–ื• ื‘ื”ืฉื•ื•ืื” ืœืžืฆื‘ ืงืจื™ื•ืงื™ ื‘ื›ืœ ืžืงื•ื ืื—ืจ ื•ืœื›ืŸ ืื™ืŸ ืฆื•ืจืš ืœื”ืจื—ื™ื‘ ืขืœ ื–ื”. 4. ืื™ืš ืœื•ื•ื“ื ื”ืฆืœื—ื” - ื”ื‘ืœื•ืง ื”ืื—ืจื•ืŸ Verification and format ื›ื•ืœืœ ืฆื™ืจื•ืฃ ืงื•ื‘ืฅ ืฉืžืจืื” ืืช ื”ืคื•ืจืžื˜ ื”ืžื“ื•ื™ืง ืฉืœ ื”ื ืชื•ื ื™ื ืขื•ื–ืจ ืœืงืœื•ื“ ืœื”ื‘ื™ืŸ ืฉื”ื•ื ื™ืฆืจ ืžืฉื”ื• ืฉืขื•ื‘ื“. 5. ืžืชืืจ ืืช ื”"ืžื”" ื•ืœื ืืช ื”"ืื™ืš" - ืžื” ืฉื”ื›ื™ ืื”ื‘ืชื™ ื‘ืคืจื•ืžืคื˜. ื”ื•ื ืžืชืืจ ืžื” ื”ืžืขืจื›ืช ืฆืจื™ื›ื” ืœื”ื™ื•ืช ืื—ืจื™ ื”ืฉื™ื ื•ื™ ืื‘ืœ ืœื ื ื›ื ืก ืœืงื•ื“ ืขืฆืžื• ืฉืฆืจื™ืš ืœื”ื™ื•ืช ืฉื. ื–ืืช ืขืœื™ื™ืช ื”ืžื“ืจื’ื” ื‘ืื‘ืกื˜ืจืงืฆื™ื” ืฉืื ื—ื ื• ืฆืจื™ื›ื™ื ืœืืžืฅ. โœ ืžื” ืœื ื˜ื•ื‘ ื‘ืคืจื•ืžืคื˜ ื”ื ืงื•ื“ื•ืช ืฉืงืœื•ื“ ืคืกืคืก ื‘ืžื™ืžื•ืฉ ื”ื™ื• ืžืื•ื“ ืกืคืฆื™ืคื™ื•ืช ืœ Codebase. ืกื•ืคืจ ื”ื’ื™ื•ื ื™ ื•ืžื–ื›ื™ืจ ืœืžื” ื—ืฉื•ื‘ ืœืฉืžื•ืจ ืงื‘ืฆื™ ืชื™ืขื•ื“ ืฉืžืชืืจื™ื ืืช ื”ืงื•ื“ ื•ืžื—ื“ื“ื™ื ื ืงื•ื“ื•ืช ืฉืœื ื• ืื•ืœื™ ื ืจืื•ืช ื‘ืจื•ืจื•ืช ืžืืœื™ื”ืŸ: 1. ืœืžืจื•ืช ืฉื‘ื™ืงืฉืชื™ ืจืง ืชื•ืกืคืช ืฉืœ ืขืžื•ื“ื” ืื—ืช, ืงืœื•ื“ ื”ื•ืกื™ืฃ ืฉืชื™ ืขืžื•ื“ื•ืช "ื–ืžืŸ ื”ืชื—ืœื”" ื•"ื–ืžืŸ ืกื™ื•ื", ืœื”ืชืื™ื ืœืžืงื•ืžื•ืช ืื—ืจื™ื ื‘ืงื•ื“. 2. ืžื ื’ื ื•ืŸ ื–ื™ื”ื•ื™ ื”ืžื™ืœื” ื”ื ื•ื›ื—ื™ืช ืœืงืจื™ื•ืงื™ ืžืื•ื“ ื‘ื–ื‘ื–ื ื™. ื–ื” ื”ืงื•ื“ ืฉืงืœื•ื“ ื™ืฆืจ:
  updateWordHighlight(currentTime) {
    if (!this.tokenSpans) {
      this.tokenSpans = Array.from(this.element.querySelectorAll('[data-token-start]'));
    }

    for (const span of this.tokenSpans) {
      const start = Number(span.dataset.tokenStart);
      const end = Number(span.dataset.tokenEnd);
      span.classList.toggle('s-token-active', currentTime >= start && currentTime <= end);
    }
  }
3. ืงืœื•ื“ ื‘ื—ืจ ืœื”ืฆื™ื’ ื‘ืกื’ื ื•ืŸ ืงืจื™ื•ืงื™ ืชื•ื›ืŸ ืื ืœื—ืœืง ืžื”ืžื™ืœื™ื ื™ืฉ ืชื•ื•ื™ืช ื–ืžืŸ. ืื‘ืœ ื”ืืžืช ื”ื™ื ืฉืื ืจืง ืœื—ืœืง ืงื˜ืŸ ืžื”ืžื™ืœื™ื ื™ืฉ ืชื•ื•ื™ืช ื–ืžืŸ ืขื“ื™ืฃ ืœื•ื•ืชืจ ืขืœ ืžืฆื‘ ืงืจื™ื•ืงื™. ื”ืกื™ื‘ื” ื”ื™ื ืฉืœื ื”ืชื™ื—ืกืชื™ ื‘ืคืจื•ืžืคื˜ ืœืžืฆื‘ื™ื ื‘ื”ื ื™ืฉ ืžื™ื“ืข ืจืง ืขืœ ื—ืœืง ืžื”ืžื™ืœื™ื.

ToCode
1 420
๐Ÿ“Œ ื›ืคืœ ืงื•ื“ ื•ืื‘ืกื˜ืจืงืฆื™ื” ืœื ื ื›ื•ื ื” ื‘ืžืืžืจ ื‘ื ื•ืฉื ืื‘ืกื˜ืจืงืฆื™ื•ืช ื‘ืชืงื•ืคื” ืฉืžืคืชื—ื™ื ืขื•ื“ ื›ืชื‘ื• ืงื•ื“ ืกื ื“ื™ ืžืฅ ืžืชืืจืช ืืช ื”ืชืจื—ื™ืฉ ื”ื ืคื•ืฅ ื”ื‘ื: 1. ืžืคืชื— A ืจื•ืื” ืืช ืื•ืชื• ืงื•ื“ ืžื•ืคื™ืข ื‘ืฉื ื™ ืžืงื•ืžื•ืช. ืžื•ืฆื™ื ืœืคื•ื ืงืฆื™ื” ืžืฉื•ืชืคืช ื•ืฉืžื— ืขืœ ื”ื—ืกื›ื•ืŸ ื‘ืงื•ื“. 2. ื”ื–ืžืŸ ืขื•ื‘ืจ ื•ื ื›ื ืกืช ื“ืจื™ืฉื” ื—ื“ืฉื” ืœืžืขืจื›ืช. 3. ืžืคืชื— B ืžื–ื”ื” ืฉื”ืงื•ื“ ื›ืžืขื˜ ืžืชืื™ื ืœื“ืจื™ืฉื” ื”ื—ื“ืฉื” ืื– ื”ื•ื ืจืง ืžื•ืกื™ืฃ ืคืจืžื˜ืจ ืœืคื•ื ืงืฆื™ื” ื”ืžืฉื•ืชืคืช ื•ืขื•ื“ if ืงื˜ืŸ ื•ื”ื›ืœ ืžืกืชื“ืจ. 4. ื”ื–ืžืŸ ืžืžืฉื™ืš ืœืขื‘ื•ืจ, ืžืคืชื—ื™ื ื ื•ืกืคื™ื ืžืจื—ื™ื‘ื™ื ืืช ื”ืงื•ื“ ื”ืžืฉื•ืชืฃ, ื•ืžื” ืฉืคืขื ื”ื™ื” ืื‘ืกื˜ืจืงืฆื™ื” ื™ืคื” ื”ืคืš ืœืขืจื™ืžื” ืœื ื‘ืจื•ืจื” ืฉืœ ืชื ืื™ื ื•ื—ืจื™ื’ื™ื. ื”ืžืกืงื ื” ืฉืœ ืกื ื“ื™ ื”ื™ืชื” ืฉื”ืื‘ืกื˜ืจืงืฆื™ื” ื”ืœื ื ื›ื•ื ื” ื™ืงืจื” ื‘ื”ืจื‘ื” ืžืงื•ื“ ืžืฉื•ื›ืคืœ ื›ื™ื•ื•ืŸ ืฉืขืœื•ืช ื”ืคื™ืชื•ื— ืฉืœื” ื›ื•ืœืœืช ืืช ื›ืœ ื”ืชื—ื–ื•ืงื” ืฉืœ ืงื˜ืขื™ ื”ืงื•ื“ ื”ืžื—ื•ื‘ืจื™ื. ื”ืื‘ืกื˜ืจืงืฆื™ื” ื”ืœื ื ื›ื•ื ื” ื™ื—ื“ ืขื ืื™ื ืจืฆื™ื” ื”ื›ื ื™ืกื” ืื•ืชื ื• ืœื‘ืจื•ืš ืฉืืฃ ืื—ื“ ื›ื‘ืจ ืœื ื™ื•ื“ืข ืื™ืš ืœืฆืืช ืžืžื ื•. ืื’ื‘ ื”ืชืจื—ื™ืฉ ื”ืžืงื•ืจื™ ืžืžื ื• ืžืคืชื— A ื ื™ืกื” ืœื”ืชื’ื•ื ืŸ ื”ื™ื”: 1. ื”ื–ืžืŸ ืขื•ื‘ืจ ื•ื ื›ื ืกืช ื“ืจื™ืฉื” ื—ื“ืฉื” ืœืžืขืจื›ืช. 2. ืžืคืชื— B ืžืชืงืŸ ืืช ื”ืงื•ื“ ื‘ืžืงื•ื ืื—ื“ ื•ืฉื•ื›ื— ืฉื”ืงื•ื“ ืžืฉื•ื›ืคืœ ื•ืžื•ืคื™ืข ื‘ืžืงื•ื ื ื•ืกืฃ ื‘ืžืขืจื›ืช. 3. ืžืฉืชืžืฉื™ื ื›ื•ืขืกื™ื ื›ื™ ืขื›ืฉื™ื• ื›ืคืชื•ืจ ืื—ื“ ืžืชื ื”ื’ ื ื›ื•ืŸ ื•ืฉื ื™ ืขื“ื™ื™ืŸ ืฉื‘ื•ืจ. ืขืฉืจ ืฉื ื™ื ืื—ืจื™ ื”ืžืืžืจ ืฉืœ ืกื ื“ื™ ืžืฅ ื•ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœื”ื•ืกื™ืฃ ืฉื™ืงื•ืœ ื—ื“ืฉ ืœืžืขืจื›ืช. ืื™ื–ื” ืžื”ืชืจื—ื™ืฉื™ื ื™ื•ืชืจ ืžื˜ืจื™ื“ ืื•ืชื ื• ื›ืฉ AI ื›ื•ืชื‘ ืืช ื”ืงื•ื“. ื”ื ื” ืžื” ืฉืื ื—ื ื• ื™ื•ื“ืขื™ื: 1. ืกื•ื›ื ื™ ืงื™ื“ื•ื“ ืœื ืื•ื”ื‘ื™ื ืœื™ืฆื•ืจ ืื‘ืกื˜ืจืงืฆื™ื•ืช ื—ื“ืฉื•ืช ืื• ืœืฉื‘ื•ืจ ืื‘ืกื˜ืจืงืฆื™ื•ืช ืงื™ื™ืžื•ืช. ื‘ 2026 ืกื•ื›ืŸ ืงื™ื“ื•ื“ ื”ื•ืœืš ืœื”ืชื ื”ื’ ื‘ื“ื™ื•ืง ื›ืžื• ืžืคืชื— B ื‘ื“ื•ื’ืžื” ื”ืจืืฉื•ื ื” ื•ื™ืขืžื™ืก ืขื•ื“ ื”ืชื ื”ื’ื•ืช ืขืœ ื”ืžืขืจื›ืช ื”ืงื™ื™ืžืช. ืื•ืœื™ ื‘ืขืชื™ื“ ื–ื” ื™ืฉืชื ื”. 2. ืกื•ื›ื ื™ ืงื™ื“ื•ื“ ืฆืจื™ื›ื™ื ืขื–ืจื” ื‘ืฉื‘ื™ืœ ืœืžืฆื•ื ืืช ื›ืœ ื”ืžืงื•ืžื•ืช ืฉืžืฉืคื™ืขื™ื ืขืœ ืคืขื•ืœื” ืžืกื•ื™ืžืช. ืื ื™ืฉ ืœื™ ื‘ืžืขืจื›ืช ืฉืชื™ ืงื•ืžืคื•ื ื ื˜ื•ืช ืฉืœ ื ื’ืŸ ื•ื™ื“ืื• ื•ื‘ื™ืงืฉืชื™ ืฉื™ื ื•ื™ ื‘ื ื’ืŸ ืกื•ื›ื ื™ ืงื™ื“ื•ื“ ื‘ืกื‘ื™ืจื•ืช ื’ื‘ื•ื”ื” ื™ืชืงื ื• ืจืง ืืช ืื—ื“ ืžื”ื ื’ื ื™ื. ื•ืืช ื›ืœ ื–ื” ืฆืจื™ืš ืœื”ื›ืคื™ืœ ืคื™ 10 ื›ื™ ืกื•ื›ื ื™ ืงื™ื“ื•ื“ ื›ื•ืชื‘ื™ื ื”ืจื‘ื” ื™ื•ืชืจ ืงื•ื“ ื”ืจื‘ื” ื™ื•ืชืจ ืžื”ืจ ืžื‘ื ื™ ืื“ื. ืื– ื”ืื ื›ืคืœ ืงื•ื“ ืขื“ื™ื™ืŸ ื™ื•ืชืจ ื–ื•ืœ? ื˜ื•ื‘ ื‘ืฉื‘ื™ืœ ืœืขื ื•ืช ืฆืจื™ืš ืงื•ื“ื ืœื”ื‘ื™ืŸ ืื™ืš ื‘ื›ืœืœ ืื ื—ื ื• ืžืชืžื•ื“ื“ื™ื ืขื ืฉื ื™ ื”ืžืฆื‘ื™ื ื‘ืขื•ืœื ืฉืœ ืกื•ื›ื ื™ ืงื™ื“ื•ื“: 1. ืืช ื”ืชืจื—ื™ืฉ ื”ืจืืฉื•ืŸ ืื ื—ื ื• ื ื–ื”ื” ืจืง ืื ื ืงืจื ืืช ื”ืงื•ื“ ืฉ AI ืžื™ื™ืฆืจ ื•ืจืง ืื ื ื”ื™ื” ืจื’ื™ืฉื™ื ืœืจืื•ืช ืื‘ืกื˜ืจืงืฆื™ื” ืœื ื ื›ื•ื ื” ืฉื”ื•ืœื›ืช ื•ืžืกืชื‘ื›ืช. ืชืงืœื” ืคื•ื ืงืฆื™ื•ื ืืœื™ืช ืชืงืจื” ื›ื ืจืื” ืจืง ื›ืฉื›ื‘ืจ ื™ื”ื™ื” ืžืื•ื—ืจ ืžื“ื™ ื•ื”ืงื•ื“ ื™ื”ื™ื” ืžืกื•ื‘ืš ืžื“ื™ ื‘ืฉื‘ื™ืœ ืœืชืงืŸ. ื›ืฉื›ื‘ืจ ื ืจืื” ืืช ื”ื‘ืขื™ื” ื ืฆื˜ืจืš ืœืืจื’ืŸ ืžื—ื“ืฉ ืืช ื”ืงื•ื“ ื•ื‘ื–ื” AI ืœื ืžืžืฉ ื™ื•ื›ืœ ืœืขื–ื•ืจ ื›ื™ ื ื›ื•ืŸ ืœื”ื™ื•ื ืงืฉื” ืžืื•ื“ ืœ AI ืœืจืื•ืช ืื‘ืกื˜ืจืงืฆื™ื” ืœื ื ื›ื•ื ื” ื•ืœื“ืžื™ื™ืŸ ื“ืจืš ื™ื•ืชืจ ื˜ื•ื‘ื” ืœืืจื’ืŸ ืืช ื”ืงื•ื“. 2. ื‘ืชืจื—ื™ืฉ ื”ืฉื ื™ ื”ืงื•ื“ ื”ื›ืคื•ืœ ื™ืขื•ื“ื“ ืืช ื” AI ืœื™ืฆื•ืจ ืขื•ื“ ื›ืคื™ืœื•ื™ื•ืช, ื›ื™ ื›ืš ื”ืžืขืจื›ืช ื‘ื ื•ื™ื”. ืื ื—ื ื• ื ื‘ื™ืŸ ืฉื™ืฉ ื›ืคื™ืœื•ืช ืจืง ื›ืฉื ืงืจื ืืช ื”ืงื•ื“. ืžืฆื“ ืฉื ื™ ืคื” ื™ืฉ ืกื™ื›ื•ื™ ื™ื•ืชืจ ื˜ื•ื‘ ืฉืžืฉื”ื• ืคื•ื ืงืฆื™ื•ื ืืœื™ืช ื™ื™ืฉื‘ืจ ื›ื™ AI ืชื™ืงืŸ ืื• ืขื“ื›ืŸ ืžืฉื”ื• ืจืง ื‘ืžืงื•ื ืื—ื“ ื•ืœื ื‘ื›ืœ ื”ืžื•ืคืขื™ื ืฉืœ ื”ืงื•ื“ ื”ื›ืคื•ืœ ื•ืื– ืžืคืชื—ื™ื ืื ื•ืฉื™ื™ื ื™ื™ื›ื ืกื• ืœืชืžื•ื ื”. ื›ืฉื›ื‘ืจ ื™ืฉ ื›ืคืœ ืงื•ื“ ืœ AI ื“ื™ ืงืœ ืœื™ืฆื•ืจ ืื‘ืกื˜ืจืงืฆื™ื” ืฉืžืชืื™ืžื” ืœืงื•ื“ ื”ื›ืคื•ืœ ื”ื ื•ื›ื—ื™ (ื‘ื ื™ื’ื•ื“ ืœืฉื™ื ื•ื™ ืื‘ืกื˜ืจืงืฆื™ื” ืฉืขื“ื™ื™ืŸ ืœื ืขื•ื‘ื“ ื˜ื•ื‘) ื•ืœื›ืŸ ื‘ื›ืœ ื ืงื•ื“ื” ื™ื”ื™ื” ืงืœ ืœืขื‘ื•ืจ ืžืงื•ื“ ืžืฉื•ื›ืคืœ ืœืงื•ื“ ืžืฉื•ืชืฃ. ืžื™ ืฉื™ืจืฆื” ืœื”ืžืฉื™ืš ืœืขื‘ื•ื“ ืขื ื”ืงื•ื“ ื”ืžืฉื•ื›ืคืœ ืœืื•ืจืš ื–ืžืŸ ื™ื•ื›ืœ ืœื”ื•ืกื™ืฃ ืงื•ื‘ืฅ ืชื™ืขื•ื“ ืฉืžืกื‘ื™ืจ ืื™ืคื” ื›ืœ ื”ืžืงื•ืžื•ืช ืฉื”ืงื•ื“ ื”ื›ืคื•ืœ ืžื•ืคื™ืข. ืœื“ื•ื’ืžื” ื‘ langlets ื™ืฉ ืœื™ ืฉื ื™ ื ื’ื ื™ ื•ื™ื“ืื• ื•ืžืกืคืจ layouts ืœื›ืœ ื ื’ืŸ. ื—ืœืง ืžื”ืงื•ื“ ืžืฉื•ืชืฃ ื•ื—ืœืง ืžืฉื•ื›ืคืœ ื‘ื™ืŸ ื”ื ื’ื ื™ื ื•ื‘ืืžืช ืžื“ื™ ืคืขื ื›ืฉื‘ื™ืงืฉืชื™ ืœืขื“ื›ืŸ ืคื™ืฆ'ืจ ื‘ื ื’ืŸ ื”ื•ื™ื“ืื• ื” AI ืžื™ืžืฉ ืืช ื”ืฉื™ื ื•ื™ ืจืง ื‘ืื—ื“ ืžื”ื. ื”ืคืชืจื•ืŸ ื”ื™ื” ืœื”ื•ืกื™ืฃ ืงื•ื‘ืฅ ื˜ืงืกื˜ ืฉืžืกื‘ื™ืจ ืขืœ ืืจื›ื™ื˜ืงื˜ื•ืจืช ื”ื•ื™ื“ืื• ื‘ืžืขืจื›ืช, ืืคืฉืจ ืœืจืื•ืช ืื•ืชื• ื›ืืŸ: https://github.com/ynonp/langlets-rails/blob/main/docs/video-player.md ืื—ืจื™ ื”ืชื•ืกืคืช ื” AI ื›ื‘ืจ ื”ืฆืœื™ื— ืœื”ืชืžื•ื“ื“ ืขื ื”ืงื•ื“ ื”ืžืฉื•ื›ืคืœ ื•ืœืชืงืŸ ื‘ื›ืœ ื”ื ื’ื ื™ื ื’ื ื‘ืœื™ ืฉืืฆื™ื™ืŸ ืืช ื–ื” ื‘ืฆื•ืจื” ืžืคื•ืจืฉืช ื‘ืคืจื•ืžืคื˜. ืžืกืงื ื•ืช? ืœื“ืขืชื™ ื”ืœืงื— ืฉืœ ืกื ื“ื™ ืžืฅ ืขื“ื™ื™ืŸ ืจืœื•ื•ื ื˜ื™ ื•ืืคื™ืœื• ื”ืคืš ื™ื•ืชืจ ืจืœื•ื•ื ื˜ื™ ืžืื– ืฉื™ืœื•ื‘ AI ื‘ืชื”ืœื™ืš ื”ืคื™ืชื•ื—. ื›ืŸ ื›ืคืœ ืงื•ื“ ืžืขื•ื“ื“ ื™ื•ืชืจ ื›ืคืœ ืงื•ื“. ื›ืŸ ื” AI ื›ื•ืชื‘ ืงื•ื“ ื›ืœ ื›ืš ืžื”ืจ ืฉืืฃ ืื—ื“ ืืคื™ืœื• ืœื ืžืจื’ื™ืฉ ืฉืฆืจื™ืš ื™ื•ืชืจ ืงื•ื“ ื‘ืฉื‘ื™ืœ ืœืคืชื•ืจ ื‘ืขื™ื”. ืื‘ืœ - ืื ื—ื ื• ื›ืŸ ื ืจื’ื™ืฉ ื›ืฉื”ืคื•ื ืงืฆื™ื•ื ืืœื™ื•ืช ืฉืœ ื”ืžืขืจื›ืช ื ืฉื‘ืจืช ื•ืคื™ืฆ'ืจ ืœื ืคื•ืชืจ ืืช ื›ืœ ื”ื‘ืขื™ื”, ื‘ืขื–ืจืช ืงื‘ืฆื™ ืชื™ืขื•ื“ ืืคืฉืจ ืœื”ื™ืฉืืจ ืขื ืงื•ื“ ืžืฉื•ื›ืคืœ ื•ืœืงื‘ืœ ืชื•ืฆืื•ืช ื˜ื•ื‘ื•ืช ื•ื›ืฉื ืจืฆื” ืœื™ืฆื•ืจ ืื‘ืกื˜ืจืงืฆื™ื” ื”ืžืขื‘ืจ ืžืงื•ื“ ืžืฉื•ื›ืคืœ ืœืื‘ืกื˜ืจืงืฆื™ื” ื™ื”ื™ื” ืžืื•ื“ ืงืœ ื‘ื–ื›ื•ืช ืกื•ื›ืŸ ื”ืงื™ื“ื•ื“.

ToCode
1 420
print(result.output)
ื™ืฉ ืœื”ื ืชืžื™ื›ื” ืžืœืื” ื‘ Server Side Tools ื›ืžื• ื—ื™ืคื•ืฉ ื‘ืจืฉืช ืฉืœ OpenAI ื•ืฉืœื™ื˜ื” ืขืœ ืžื™ื“ืช ื”ื—ืฉื™ื‘ื”:
from pydantic_ai import Agent
from pydantic_ai.capabilities import Thinking, WebSearch
agent = Agent(
    'anthropic:claude-opus-4-6',
    instructions='You are a research assistant. Be thorough and cite sources.',
    capabilities=[
        Thinking(effort='high'),
        WebSearch(local='duckduckgo'),
    ],
)
ืกืš ื”ื›ืœ ื”ืกืคืจื™ื” ืžืื•ื“ ื›ื™ืคื™ืช - ื“ื‘ืจื™ื ืฉืœื ื ื›ื ืกื• ืคื” ืœืจืฉื™ืžื” ืื‘ืœ ืฉื•ื•ื™ื ืื–ื›ื•ืจ ื”ื ื”ื—ื™ื‘ื•ืจ ืœืžืขืจื›ืช ื”ืœื•ื’ื™ื ืฉืœื”ื logfire (ื‘ืžืงื•ื ื–ืืช ืฉืœ OpenAI), ืชืžื™ื›ื” ื‘ MCP, ืชืžื™ื›ื” ืžื•ื‘ื ื™ืช ื‘ื‘ื“ื™ืงื•ืช ืขื TestModel ื•ืžืžืฉืง Web Interface ืžื‘ื•ืกืก ืฆ'ื˜ ื›ื“ื™ ืœื ืกื•ืช ืืช ื”ืกื•ื›ืŸ ืฉืœื›ื. ืื ืื”ื‘ืชื ืืช OpenAI Agents SDK ืฉื•ื•ื” ืžืื•ื“ ืœื ืกื•ืช ืืช Pydantic AI.

ToCode
1 420
๐Ÿ“Œ ืฉืœื•ืฉื” ื“ื‘ืจื™ื ืฉืื”ื‘ืชื™ ื‘ืžื™ื•ื—ื“ ื‘ Pydantic AI ืกืคืจื™ื™ืช ืคื™ืชื•ื— ื”ืกื•ื›ื ื™ื Pydantic AI ื”ื™ื ืžืฉื‘ ืจื•ื— ืžืจืขื ืŸ ืฉืœ ืคืฉื˜ื•ืช. ื”ื™ื ืžื–ื›ื™ืจื” ืืช OpenAI Agents SDK ื”ืื”ื•ื‘ื” ืขืœื™ื™ ืจืง ื‘ืœื™ ื”ื—ื™ื‘ื•ืจ ืœ OpenAI ื•ืขื ื”ืจื‘ื” ื™ื•ืชืจ ืฉืœื™ื˜ื” ื‘ืคืจืžื˜ืจื™ื ืฉืœ ื”ืžื•ื“ืœื™ื. ื”ืขื‘ื•ื“ื” ืื™ืชื” ื‘ื”ื—ืœื˜ ื™ื›ื•ืœื” ืœื”ืจื’ื™ืฉ ื›ืžื• ืžื™ืฉื”ื• ืฉื”ื‘ื™ืŸ ืžื” ืฉ OpenAI ื ื™ืกื• ืœืขืฉื•ืช ืขื Agents SDK ื•ืคืฉื•ื˜ ื”ืžืฉื™ืš ืขื ื–ื”. ืืคืฉืจ ืœืงืจื•ื ืืช ื”ืชื™ืขื•ื“ ื”ืžืœื ื•ื“ื•ื’ืžืื•ืช ืฉืœื”ื ื›ืืŸ: https://pydantic.dev/docs/ai/overview/ ื•ื”ื ื” ืฉืœื•ืฉื” ื“ื‘ืจื™ื ืฉืื”ื‘ืชื™ ื‘ืžื™ื•ื—ื“ ื‘ืกืคืจื™ื”. โœ ืชื™ืขื•ื“ ืžืœื ื•ื™ื“ื™ื“ื•ืชื™ ืœืกื•ื›ืŸ ื‘ 2026 ื”ื“ืจื™ืฉื” ื”ืจืืฉื•ื ื” ืฉืœื™ ืžืกืคืจื™ื™ืช ืงื•ื“ ื”ื™ื ืฉืืคืฉืจ ื™ื”ื™ื” ืœืขื‘ื•ื“ ืื™ืชื” ื‘ืงืœื•ืช ืžืชื•ืš ืกื•ื›ืŸ ืงื™ื“ื•ื“. ื”ื‘ืขื™ื” ืฉืœ OpenAI Agents SDK ื”ื™ื ืฉืืฃ ืื—ื“ ืœื ืžืฉืชืžืฉ ื‘ืงื•ื“ืงืก ื•ื”ื ืœื ืจื•ืฆื™ื ืœืงื“ื ืืช ืงืœื•ื“ ืงื•ื“. ื”ืชืฉื•ื‘ื” ืฉืœื”ื ืœืžื™ ืฉื‘ื™ืงืฉื• Agent Skill ื”ื™ืชื”:
Thanks for writing in. Our current recommendation is to use codex for loading and utilizing agent skills because the codex layer already has a robust mechanism for it. We prefer to avoid reinventing the wheel for now.
ืคื™ื“ื ื˜ื™ืง ืœื ืฆืจื™ื›ื™ื ืืช ื”ืคื•ื–ื™ืฆื™ื” ื•ืœื›ืŸ ื‘ืขืžื•ื“ ื”ืชื™ืขื•ื“ ื”ืจืืฉื™ ื”ื ืฉื™ืœื‘ื• ืžื“ืจื™ืš ืื™ืš ืœื”ืชืงื™ืŸ ืืช ื”ืกืงื™ืœ ืœื›ืœ ื”ืกื•ื›ื ื™ื. ืื—ืจื™ ื”ื”ืชืงื ื” ื›ืฉื”ืคืขืœืชื™ ืงืœื•ื“ ืงื•ื“ ื•ื‘ื™ืงืฉืชื™ ืกื•ื›ืŸ ืจืืฉื•ืŸ ื”ืžื™ืžื•ืฉ ื”ื™ื” ืžื™ื™ื“ื™. โœ ืžื ื’ื ื•ืŸ Fallback ืžื•ื“ืœื™ื ืœื ืชืžื™ื“ ื™ืขื ื• ืืช ื”ืชืฉื•ื‘ื” ืœื” ืื ื—ื ื• ืžืฆืคื™ื - ื–ื” ื™ื›ื•ืœ ืœื”ื™ื•ืช ื”ืžื•ื“ืœ ืขืฆืžื• ืฉื˜ื•ืขื”, ื›ืฉืœื•ืŸ ื‘ื”ืคืขืœืช ื›ืœื™, ืชื•ื›ืŸ ืœื ื”ื•ืœื ืื• ืืคื™ืœื• ืชืฉื•ื‘ื” ืฉืœื ืงืฉื•ืจื” ืœืžื” ืฉืฉืืœื ื•. ืžื ื’ื ื•ืŸ Fallback Model ืฉืœ ืคื™ื“ื ื˜ื™ืง ืžืกืคืง ื“ืจืš ืงืœื” ื•ืžื“ื•ื™ืงืช ืœื–ื”ื•ืช ื•ืœื˜ืคืœ ื‘ืžืงืจื™ื ื›ืืœื”. ื”ืชื™ืขื•ื“ ื›ืืŸ: https://pydantic.dev/docs/ai/models/overview/#fallback-model ื•ื‘ื’ื“ื•ืœ ื–ื” ื ืจืื” ื›ืš:
from pydantic_ai.exceptions import ModelAPIError
from pydantic_ai.models.fallback import FallbackModel
from fallback_on_native_tool import anthropic_model, google_model, web_fetch_failed
fallback_model = FallbackModel(
    google_model,
    anthropic_model,
    fallback_on=[
        ModelAPIError,  # Exception type
        lambda exc: 'rate limit' in str(exc).lower(),  # Exception handler (untyped lambda)
        web_fetch_failed,  # Response handler (auto-detected via type hint)
    ],
)
ืžื’ื“ื™ืจื™ื ืืช ื”ืžืขื‘ืจ ื•ื”ืชื ืื™ื ื‘ืžืงื•ื ืื—ื“ ื•ืขื•ื‘ื“ื™ื ืขื ื”ืžื•ื“ืœ ืจื’ื™ืœ ื‘ื›ืœ ืฉืืจ ื”ืชื•ื›ื ื™ืช. ื‘ื“ื•ื’ืžื” ืฉื”ื“ื‘ืงืชื™ ืื ื”ืžื•ื“ืœ ืฉืœ ื’ื•ื’ืœ ืœื ืžืฆืœื™ื— ืœืขื ื•ืช ืขืœ ื”ื‘ืงืฉื” ื™ืฉ ืœืขื‘ื•ืจ ืœืžื•ื“ืœ ืฉืœ ืื ื˜ืจื•ืคื™ืง ื•ื™ืฉ 3 ืžื ื’ื ื•ื ื™ ื›ืฉืœื•ืŸ, ืื• ืฉื”ืžื•ื“ืœ ื–ื•ืจืง ืฉื’ื™ืื” ืžืกื•ื’ ModelAPIError, ืื• ืฉื”ืžื•ื“ืœ ื–ื•ืจืง ืฉื’ื™ืื” ืขื ื”ื˜ืงืกื˜ rate limit ืื• ืฉื”ืชืฉื•ื‘ื” ืฉืœ ื”ืžื•ื“ืœ ื›ื•ืœืœืช ื›ืฉืœื•ืŸ ื‘ื”ืจืฆืช ื›ืœื™. โœ ื’ืžื™ืฉื•ืช ื‘ืžื•ื“ืœื™ื ื•ืฉืœื™ื˜ื” ื‘ื›ืœ ื”ืคืจืžื˜ืจื™ื ื–ื” ืคื™ืฆ'ืจ ืฉืžืื•ื“ ื”ื™ื” ื—ืกืจ ืœื™ ื‘ OpenAI Agents SDK ืฉื ื”ื™ืชื” ื”ืขื“ืคื” ื‘ืจื•ืจื” ืœืžื•ื“ืœื™ื ืฉืœ OpenAI. ืคื™ื“ื ื˜ื™ืง ืœื ืจืง ืฉืžืืคืฉืจื™ื ืœื™ ืœื‘ื—ื•ืจ ื›ืœ ืกืคืง ืืœื ืฉืืคืฉืจ ื’ื ืœืฉืœื•ื˜ ื‘ืคืจืžื˜ืจื™ื ื”ืกืคืฆื™ืคื™ื™ื ืฉืœ ื”ืžื•ื“ืœ. ืœื“ื•ื’ืžื” ืขื OpenAI ืืคืฉืจ ืœื”ืชื—ื‘ืจ ืœ Responses API ืฉืœื”ื ืื‘ืœ ื’ื ืœ Chat API, ื•ื’ื ืœืคืจื•ื‘ื™ื™ื“ืจื™ื ื”ืกื™ื ื™ื ืœื“ื•ื’ืžื”:
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.alibaba import AlibabaProvider
model = OpenAIChatModel(
    'qwen-max',
    provider=AlibabaProvider(
        api_key='your-api-key',
        base_url='https://dashscope.aliyuncs.com/compatible-mode/v1',  # China region
    ),
)
agent = Agent(model)
...
ื‘ืื ื˜ืจื•ืคื™ืง ื™ืฉ ืืคืฉืจื•ืช ืœื”ืฉืชืžืฉ ื‘ืžื ื’ื ื•ืŸ ื” Cache System Instructions ืฉืœื”ื ื›ื“ื™ ืœื—ืกื•ืš ื˜ื•ืงื ื™ื:
from datetime import date

from pydantic_ai import Agent, RunContext
from pydantic_ai.models.anthropic import AnthropicModelSettings

agent = Agent(
  'anthropic:claude-sonnet-4-6',
  deps_type=str,
  instructions='You are a helpful customer service agent. Follow company policy.',  
  model_settings=AnthropicModelSettings(
      anthropic_cache_instructions=True,  
  ),
)


@agent.instructions
def dynamic_context(ctx: RunContext[str]) -> str:  
  return f"Customer name: {ctx.deps}. Today's date: {date.today()}."


result = agent.run_sync('What is your return policy?', deps='Alice')
print(result.output)
ื•ืืคื™ืœื• ื™ืฉ ืืคืฉืจื•ืช ืœื”ื’ื“ื™ืจ Cache Breakpoints ื™ื“ื ื™ืช. ืœื’ื•ื’ืœ ืืคืฉืจ ืœื”ืขื‘ื™ืจ ื•ื™ื“ืื• ืžื™ื•ื˜ื™ื•ื‘ ืฉื•ื‘ ืœืคื™ ื”ืคื•ืจืžื˜ ืฉืœ ื’'ืžื ื™:
from pydantic_ai import Agent, VideoUrl
from pydantic_ai.models.google import GoogleModel
agent = Agent(GoogleModel('gemini-3-flash-preview'))
result = agent.run_sync(
    [
        'What is this video about?',
        VideoUrl(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ'),
    ]
)

ToCode
1 420
๐Ÿ“Œ ืžืชื™ ื ื•ื›ืœ ืœื”ืคืกื™ืง ืœืงืจื•ื ืืช ื”ืงื•ื“? ื”ื”ื‘ื˜ื—ื” ืฉืœ Spec Driven Development ื”ื™ื ืคืฉื•ื˜ื” - ื‘ืžืงื•ื ืœื›ืชื•ื‘ ื•ืœืงืจื•ื ืงื•ื“ ื ืขื‘ื•ืจ ืœื›ืชื•ื‘ ื•ืœืงืจื•ื ืื™ืคื™ื•ื ื™ื. ื‘ืžืืžืจ ืืจื•ืš ื‘ื ื•ืฉื ืจืื™ืชื™ ืืช ื”ื”ืžืœืฆื” ื”ื‘ืื”:
Donโ€™t kill the code reviews; just move the human checkpoint upstream to reviewing intent, specs, plans, constraints, and acceptance criteria. Code is actually the least important part of the reviews.
ืื™ืŸ ืกืคืง ืฉื”ืชืขืฉื™ื™ื” ื•ื’ื ื”ืžืคืชื—ื™ื ืขืฆืžื ืจื•ืฆื™ื ืœื”ื’ื™ืข ืœืฉื. ื”ืจื‘ื” ื™ื•ืชืจ ืžืขื ื™ื™ืŸ ืœืชื›ื ืŸ ืืจื›ื™ื˜ืงื˜ื•ืจืช ืžืขืจื›ืช ื•ืœืฉื—ืง ืขื ืื™ืœื•ืฆื™ื ืžืืฉืจ ืœืงื•ื“ื“ ืœื•ืœืื•ืช ื•ืœื”ื™ื–ื›ืจ ื‘ืฉืžื•ืช ืžื“ื•ื™ืงื™ื ืฉืœ ืคื•ื ืงืฆื™ื•ืช. ื•ืขื“ื™ื™ืŸ ืื ื™ ื—ื•ืฉื‘ ืฉื˜ื›ื ื™ืช ืื ื—ื ื• ืขื•ื“ ืœื ืฉื. ืืœื” ื”ืกื™ื‘ื•ืช ื‘ื’ืœืœืŸ ืื ื™ ืขื“ื™ื™ืŸ ืงื•ืจื ืืช ื”ืงื•ื“: 1. ืกื•ื›ืŸ ืงื™ื“ื•ื“ ืœื ืชืžื™ื“ ืžื™ื™ืฆืจ ืืช ื”ืงื•ื“ ื‘ืื™ืคื™ื•ืŸ - ื–ืืช ืœื“ืขืชื™ ื”ื‘ืขื™ื” ื”ื›ื™ ืžืฉืžืขื•ืชื™ืช ืขื SDD. ืฉื™ื ื•ื™ ืงื˜ืŸ ื‘ืงื•ื“ ื™ื›ื•ืœ ืœื’ืจื•ื ืœืžืขืจื›ืช ืœื”ืชื ื”ื’ ืื—ืจืช ืžืžื” ืฉื”ืชื›ื•ื•ื ืชื™ ื‘ืื™ืคื™ื•ืŸ, ื•ื‘ืœื™ ืœืงืจื•ื ืืช ื”ืงื•ื“ ืื™ืŸ ืœื™ ืื™ืš ืœื“ืขืช ืขืœ ื”ื‘ืขื™ื”. (ืœื ืงืœ ืœื‘ื“ื•ืง 100% ืžื”ืคื•ื ืงืฆื™ื•ื ืืœื™ื•ืช ื‘ืžืขืจื›ืช ืžืขื ื™ื™ื ืช). 2. ืื™ืคื™ื•ื ื™ื ืœื ืชืžื™ื“ ืžื“ื•ื™ืงื™ื - ืื•ืœื™ ืขื ื”ืฉื ื™ื ื ืœืžื“ ืœื›ืชื•ื‘ ืืคื™ื•ื ื™ื ื™ื•ืชืจ ืžื“ื•ื™ืงื™ื. ื‘ื™ื ืชื™ื™ื ืื ื™ ืจื•ืื” ื”ืจื‘ื” ืคืขืžื™ื ืฉืื ื™ ื›ื•ืชื‘ ืื™ืคื™ื•ืŸ ืฉื ืจืื” ืœื™ ืžืื•ื“ ืžื“ื•ื™ืง ืื‘ืœ ื›ืฉื”ื•ื ื”ื•ืคืš ืœืงื•ื“ ืื ื™ ืžื’ืœื” ืฉืคืกืคืกืชื™ ืžืงืจื™ื ื—ืฉื•ื‘ื™ื. ื–ื” ืœื ืžืฉื”ื• ืฉื”ื™ื™ืชื™ ืจื•ืื” ื‘ืœื™ ืœืงืจื•ื ืืช ื”ืงื•ื“ ืฉื ื•ืฆืจ. ื”ืงื•ื“ ื‘ืขืฆื ืžืžืงื“ ื•ืžื—ื–ืง ืืช ื”ืืคื™ื•ืŸ. ื“ื•ื’ืžื” ืงื˜ื ื” ืž langlets - ื‘ื™ืงืฉืชื™ ืžื”ืกื•ื›ืŸ ืคื™ืฆ'ืจ ืฉื›ืฉืœื•ื—ืฆื™ื ืขืœ ืžื™ืœื” ื‘ื˜ืงืกื˜ ื™ืงืคื•ืฅ ืคื•ืคืืค ืขื ื”ืชืจื’ื•ื ืฉืœื”. ื”ืกื•ื›ืŸ ื”ื•ืกื™ืฃ onclick ืขืœ ื”ืžื™ืœื” ืื‘ืœ ื‘ื’ืœืœ ืฉืžื“ื•ื‘ืจ ื‘ JavaScript ืจื’ื™ืœ (ืœื ืจื™ืืงื˜) ื‘ืขืžื•ื“ ืฉื”ื›ื™ืœ ื”ืจื‘ื” ื˜ืงืกื˜ ื ื•ืฆืจื• ื”ืžื•ืŸ Event Handlers. ืœื›ืœ ืžื™ืœื” ื”ื™ื” ืืช ื” onclick ืฉืœื”. ื›ืžื•ื‘ืŸ ืฉื™ื›ื•ืœืชื™ ืœื›ืชื•ื‘ ื‘ืื™ืคื™ื•ืŸ ืœื™ื™ืฆืจ ืจืง Event Listener ืื—ื“ ืขืœ ื”ืงื•ื ื˜ื™ื™ื ืจ. ืœื ื—ืฉื‘ืชื™ ืขืœ ื–ื” ื›ืฉื›ืชื‘ืชื™ ืืช ื”ืื™ืคื™ื•ืŸ. ืื•ืœื™ ื’ื ื™ื›ื•ืœืชื™ ืœืฉื™ื ืœื‘ ืœื‘ืขื™ื” ื›ืฉื”ืกืชื›ืœืชื™ ืขืœ ื”ืืคืœื™ืงืฆื™ื” ืขื•ื‘ื“ืช ืื‘ืœ ื‘ื“ืฃ ื”ื‘ื“ื™ืงื” ืฉืœื™ ืœื ื”ื™ื” ืžืกืคื™ืง ื˜ืงืกื˜ ื‘ืฉื‘ื™ืœ ืœื’ืจื•ื ืœืขื•ืžืก. ื”ืขื•ืžืก ื ื•ืฆืจ ืจืง ื‘ื“ืฃ ืืจื•ืš ื‘ืžื™ื•ื—ื“ ืฉื ืคืชื— ืžืชื•ืš ื“ืคื“ืคืŸ ืžื•ื˜ืžืข ืžืชื•ืš ืืคืœื™ืงืฆื™ื”. ื‘ืงืจื™ืืช ื”ืงื•ื“ ืจื•ืื™ื ืžื™ื“ ืืช ื”ื˜ืขื•ืช ื•ืืคืฉืจ ืœื”ื—ืœื™ื˜ ืžื” ืœืขืฉื•ืช ืื™ืชื”. ื‘ืœื™ ืงืจื™ืื” ืฉืœ ื”ืงื•ื“ ืฆืจื™ืš ืœื”ืชืžื•ื“ื“ ืขื ืžืฉืชืžืฉื™ื ืฉื‘ืกื™ื˜ื•ืืฆื™ื” ืžืกื•ื™ืžืช ื”ืžืขืจื›ืช ืœื ืขื•ื‘ื“ืช ืœื”ื ื‘ืœื™ ืœื”ื‘ื™ืŸ ืœืžื”. ื™ื›ื•ืœ ืœื”ื™ื•ืช ืฉื‘ืขื•ื“ ื›ืžื” ืฉื ื™ื ื”ืžื•ื“ืœื™ื ื™ื”ื™ื• ื›ืœ ื›ืš ื˜ื•ื‘ื™ื ืฉืœื ื ืฆื˜ืจืš ืœืงืจื•ื ืืช ื”ืงื•ื“. ื›ืจื’ืข ืื ื™ ืœื ืจื•ืื” ืื™ืš ื–ื” ื™ืงืจื”. ืงืจื™ืืช ื”ืงื•ื“ ื”ื™ื ืขื“ื™ื™ืŸ ื”ื“ืจืš ื”ื˜ื•ื‘ื” ื‘ื™ื•ืชืจ ืฉื™ืฉ ืœื™ ืœื”ื‘ื™ืŸ ืืช ื”ืžืขืจื›ืช. ืฉืืœื” ืฉื—ื•ื–ืจืช ื‘ื”ืงืฉืจ ื”ื–ื” ื”ื™ื ืขืœ ื”ื”ื‘ื“ืœ ื‘ื™ืŸ ืงืจื™ืืช ืงื•ื“ ืฉืœ AI ืœืงืจื™ืืช ืงื•ื“ ืฉืœ ืงื•ืžืคื™ื™ืœืจ. ืœืžื” ื—ืฉื•ื‘ ืœืงืจื•ื ืืช ื”ืงื•ื“ ืฉ AI ืžื™ื™ืฆืจ ื‘ืขื•ื“ ืฉืื™ืŸ ืฆื•ืจืš ืœืงืจื•ื ืืช ืงื•ื“ ื”ืžื›ื•ื ื” ืฉื”ืงื•ืžืคื™ื™ืœืจ ืžื™ื™ืฆืจ? ื”ืชืฉื•ื‘ื” ืขื•ื ื” ืœื ื• ื‘ื“ื™ื•ืง ืขืœ ื”ืฉืืœื” ื‘ื›ื•ืชืจืช. ืžืชื™ ื ื•ื›ืœ ืœื”ืคืกื™ืง ืœืงืจื•ื ืงื•ื“? ื›ืฉื›ื‘ืจ ืœื ื ืฆื˜ืจืš. ื›ืฉื ื•ื›ืœ ืœืงื‘ืœ ื”ื‘ื ื” ืžืœืื” ืฉืœ ื”ืžืขืจื›ืช ืจืง ืžืงืจื™ืืช ื”ืื™ืคื™ื•ื ื™ื ื•ื”ืชื™ืขื•ื“ ืฉื›ื•ืชื‘ ื”ืกื•ื›ืŸ. ื‘ื™ื ืชื™ื™ื ืื ื—ื ื• ืœื ืฉื.

ToCode
1 420
๐Ÿ“Œ ื”ืงืคื™ืฆื” ื”ื‘ืื” ื‘ื™ืŸ 2015 ืœ 2018 ืœื™ืžื“ืชื™ ืงื•ืจืกื™ื ื‘ืคื™ืชื•ื— Web ื• Mobile Web. ืœืžืจื•ืช ืฉืื ื’ื•ืœืจ ื™ืฆืื” ืœืฉื•ืง ื›ื‘ืจ ื‘ 2010 ื•ืจื™ืืงื˜ ื‘ 2013, ืจืง ื‘ืื–ื•ืจ 2015 ื”ื˜ื›ื ื•ืœื•ื’ื™ื•ืช ื”ืืœื” ื”ื‘ืฉื™ืœื• ื•ืฉื™ื ื• ืืช ืฉื•ืง ื”ืขื‘ื•ื“ื”. ื‘ืื•ืชืŸ ืฉื ื™ื ืคื’ืฉืชื™ ื”ืžื•ืŸ ืžืคืชื—ื™ PHP ื• jQuery ืฉื™ื“ืขื• ื”ืจื‘ื” ื™ื•ืชืจ ืžืžื ื™ ืขืœ ื“ืคื“ืคื ื™ื ื•ื‘ืžื™ื•ื—ื“ ืขืœ ื“ืคื“ืคื ื™ื ื™ืฉื ื™ื ื•ื‘ื›ืœ ื–ืืช ื”ืชืงืฉื• ืœืžืฆื•ื ืขื‘ื•ื“ื”. ื‘ืื•ืชื• ื”ื–ืžืŸ ื—ื‘ืจื•ืช ื”ืฉืงื™ืขื• ืžืืžืฆื™ื ืื“ื™ืจื™ื ื‘ื’ื™ื•ืก ืžืคืชื—ื™ Front End. ื›ื•ืœื ืฉืืœื• ืืช ื›ื•ืœื ืžื™ ืžื›ื™ืจ ื•ื™ื›ื•ืœ ืœื”ืžืœื™ืฅ ืขืœ ืžืคืชื—ื™ื, ืืคื™ืœื• ื‘ื•ื’ืจื™ ืงื•ืจืกื™ื ื˜ืจื™ื™ื ืžืฆืื• ืขื‘ื•ื“ื” ื™ื—ืกื™ืช ื‘ืงืœื•ืช. ื›ื•ืœื ื—ื•ืฅ ืžืื ืฉื™ ื” PHP ื•ื” jQuery. ืจืง ืœืจืฉื•ื ืืช ื”ืžื™ืœื™ื ื”ืืœื” ื‘ืงื•ืจื•ืช ื”ื—ื™ื™ื ื”ื™ื” ื™ื›ื•ืœ ืœืขืœื•ืช ืœืš ื‘ืคืกื™ืœื” ืžืจืื™ื•ื ื•ืช. ืžื™ืฉื”ื• ื”ื™ื” ื™ื›ื•ืœ ืœื—ืฉื•ื‘ ืฉืžื“ื•ื‘ืจ ื‘ืื™ื–ื• ื”ืชื ื’ื“ื•ืช ืฉืœ ืื•ืชื ืื ืฉื™ PHP ืœื˜ื›ื ื•ืœื•ื’ื™ื” ื”ื—ื“ืฉื” ืื‘ืœ ื”ืืžืช ื™ื•ืชืจ ืžื•ืจื›ื‘ืช. ื”ื‘ืขื™ื” ืฉืœ ืื•ืชื ืžืคืชื—ื™ื ืœืžืฆื•ื ืขื‘ื•ื“ื” ื”ื™ืชื” ืฉื’ื ื›ืฉื”ื ืœืžื“ื• ืืช ื”ื›ืœื™ื ื”ื—ื“ืฉื™ื ื”ื ื”ืžืฉื™ื›ื• ืœื”ืฉืชืžืฉ ื‘ื”ื ื‘ืื•ืชื” ื’ื™ืฉื” ืฉืœ ื”ื›ืœื™ื ื”ื™ืฉื ื™ื. ื–ื” ืœื ื”ืชื—ื‘ื™ืจ ื”ืฉื•ื ื” ืฉื”ื™ื” ืงืฉื” ืืœื ื”ื”ืชืจื’ืœื•ืช ืœืฉื™ื˜ืช ื”ืขื‘ื•ื“ื” - ืœื—ื™ืคื•ืฉ ื—ื‘ื™ืœื•ืช ืžื•ื›ื ื•ืช ื‘ npm, ืœืžื™ืžื•ืฉ ืงื•ื“ ื’ื ื›ืฉื”ื•ื ืœื ื ืจืื” ืื•ืชื• ื“ื‘ืจ ืื• ืืคื™ืœื• ืขื•ื‘ื“ ืขืœ ื›ืœ ื”ื“ืคื“ืคื ื™ื, ืœื”ืชืžืงื“ื•ืช ื‘ื‘ื™ืฆื•ืขื™ื ื›ื™ ืขื›ืฉื™ื• ื–ื” ืืคืฉืจื™. ื•ืขื›ืฉื™ื• ืื ื—ื ื• ืขืœ ืกืฃ ืงืคื™ืฆื” ื ื•ืกืคืช ื•ื›ืœ ืจืขื™ื“ืช ืื“ืžื” ื›ื–ื• ืžื‘ื™ืื” ืื™ืชื” ืฉื™ื ื•ื™ื™ื, ืคื™ื˜ื•ืจื™ื, ืงื™ื“ื•ืžื™ื ื•ืชื™ืื•ืจื™ื•ืช ืฉืžืฉืชื ื•ืช ื—ื“ืฉื•ืช ืœื‘ืงืจื™ื. ืœืžืจื•ืช ืฉื–ื” ื ืจืื” ื›ืื™ืœื• ืื ื—ื ื• ืจืง ืจื•ืฆื™ื ืœืจื•ืฅ ืžื”ืจ ื•ืœื“ืœื•ื•ืจ ืขื•ื“ ืคื™ืฆ'ืจื™ื, ื”ืกื™ืคื•ืจ ืฉืœ ื” AI ื”ื•ื ื™ื•ืชืจ ืžื•ืจื›ื‘: 1. ื”ืžืคืชื—ื™ื ืฉืœ ื”ืขืชื™ื“ ื™ืฉื™ืžื• ื“ื’ืฉ ืขืœ ืคื™ืชื•ื— ืชืฉืชื™ื•ืช ื—ื–ืงื•ืช ื•ื™ืกื•ื“ื•ืช ื—ื–ืงื™ื ืฉื™ื•ื›ืœื• ืœืืคืฉืจ ืœ AI ืœื‘ื ื•ืช ืคื™ืฆ'ืจื™ื ื•ืœืฉื ื•ืช ื“ื‘ืจื™ื ืžื”ืจ. 2. ื”ืžืคืชื—ื™ื ืฉืœ ื”ืขืชื™ื“ ื™ื”ื™ื• ื”ืจื‘ื” ื™ื•ืชืจ ื˜ื•ื‘ื™ื ื‘ืœืงืจื•ื ืงื•ื“ ื•ื™ื”ื™ื• ื”ืจื‘ื” ื™ื•ืชืจ ืจื’ื™ืฉื™ื ื›ืฉื”ืงื•ื“ ืœื ืชื•ืื ืœืชื‘ื ื™ื•ืช ื•ืœ Best Practices ืฉื”ื ื”ื›ืชื™ื‘ื•. 3. ื”ืžืคืชื—ื™ื ืฉืœ ื”ืขืชื™ื“ ื™ื ื”ืœื• ืžืขืจื›ื•ืช ืฉื‘ื•ื ื•ืช ืžืขืจื›ื•ืช ื•ื™ืฆื˜ืจื›ื• ืœื ื˜ืจ ืืช ื”ืฉื™ื ื•ื™ื™ื ื‘ืงื•ื“ ื•ืื™ืจื•ืขื™ื ื‘ืœื•ื’ื™ื ื‘ื–ืžืŸ ืืžืช. 4. ื”ืžืคืชื—ื™ื ืฉืœ ื”ืขืชื™ื“ ื™ืฆื˜ืจื›ื• ืœืกื ื›ืจืŸ ื•ืœื‘ืฆืข ืื•ืคื˜ื™ืžื™ื–ืฆื™ื” ืœืฆื•ื•ืชื™ื ืฉืœ ืกื•ื›ื ื™ื ืชื•ืš ืฉื™ืคื•ืจ ืื™ื›ื•ืช ื”ืงื•ื“, ืžื”ื™ืจื•ืช ื”ืคื™ืชื•ื— ื•ืฆืžืฆื•ื ืขืœื•ื™ื•ืช. ื›ืŸ ื–ืืช ื”ื ื“ืกื”. ืฉืœื ื ื˜ืขื” - ื‘ื ื™ื’ื•ื“ ืœืจื•ืฉื ืฉืื•ืœื™ ื”ื™ื” ื‘ืื•ืชื” ืชืงื•ืคื” ื•ืœืกื˜ืจืื•ื˜ื™ืคื™ื ืขืงื‘ ืคืจืฉื™ื•ืช ื›ืžื• leftpad, ืื ืฉื™ ื”ืคืจื•ื ื˜ืื ื“ ืœื "ื”ืชืงื™ื ื• ื›ืœ ื—ื‘ื™ืœื” ืž npm ื‘ืœื™ ืœื—ืฉื•ื‘", ื™ื“ืขื• ืœื›ืชื•ื‘ ืงื•ื“ ื’ื ื‘ืขืฆืžื ื•ืœืžืขืฉื” ื”ืฉืงื™ืขื• ื”ืžื•ืŸ ืžืืžืฅ ื‘ื›ืชื™ื‘ืช ืงื•ื“, ืคืฉื•ื˜ ืงื•ื“ ืื—ืจ ืžื–ื” ืฉื›ืชื‘ื• ืื ืฉื™ ื” PHP ืฉื‘ืื• ืœืคื ื™ื”ื. ื’ื ื”ื™ื•ื ื‘ืขื‘ื•ื“ื” ืขื AI ื‘ืฉื‘ื™ืœ ืœื”ืชืงื“ื ืขืœื™ื ื• ืœื”ื‘ื™ืŸ ืื™ืš ืœื”ืฉืชืžืฉ ื‘ืžื™ื•ืžื ื•ืช ื•ื‘ื™ื“ืข ืฉืœื ื• ื•ืœืฉืœื‘ ื‘ื™ื ื• ืœื‘ื™ืŸ ื”ื›ืœื™ื ื”ื—ื“ืฉื™ื. ื‘ืกื•ืฃ ื”ืงืคื™ืฆื” ืžืขืจื›ื•ืช ืชื•ื›ื ื” ื•ืฆื•ื•ืชื™ ืคื™ืชื•ื— ื™ืจืื• ืื—ืจืช ืžืžื” ืฉื”ื ื ืจืื™ื ื”ื™ื•ื. ื”ืžืขื‘ืจ ืœ FrontEnd ื”ื•ืฆื™ื ืื•ืชื ื• ืžื”ืžื•ื ื•ืœื™ื˜, ืคืชื— ืืช ื”ื“ืœืช ืœืคื™ืชื•ื— Micro Services ื•ื‘ืžื™ื“ื” ืจื‘ื” ืœืชืฉืชื™ื•ืช ืขื ืŸ. ืืฃ ืื—ื“ ืœื ื™ื•ื“ืข ืื™ืš ื™ืจืื” ื”ืคื™ืชื•ื— ื‘ืขืชื™ื“ ื•ืื™ื–ื” ืžื™ื•ืžื ื•ื™ื•ืช ื ืฆื˜ืจืš, ืžื” ืฉื‘ื˜ื•ื— ื”ื•ื ืฉื”ื“ืจืš ื”ื™ื ืœื ืœื”ื‘ื™ืŸ ืื™ืš ืœื”ืฉืชืžืฉ ื‘ื›ืœื™ื ื”ื—ื“ืฉื™ื ื›ื“ื™ ืœืขืฉื•ืช ืืช ืื•ืชื• ื“ื‘ืจ ืฉืขืฉื™ืช ืขื“ ืขื›ืฉื™ื•. ื”ื“ืจืš ืงื“ื™ืžื” ื”ื™ื ืœื”ืฉืชืžืฉ ื‘ื›ืœื™ื ื”ื—ื“ืฉื™ื ื•ื‘ืืžืฆืขื•ืชื ืœื’ืœื•ืช ืจืขื™ื•ื ื•ืช ื—ื“ืฉื™ื ืฉืื™ ืืคืฉืจ ื”ื™ื” ืœืžืžืฉ ืงื•ื“ื.