process-gpt-agent-sdk


Nameprocess-gpt-agent-sdk JSON
Version 0.4.9 PyPI version JSON
download
home_pageNone
SummarySupabase 기반 이벤트/작업 폴링으로 A2A AgentExecutor를 실행하는 SDK
upload_time2025-10-15 09:30:53
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT
keywords agent a2a supabase workflow sdk processgpt
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 📘 ProcessGPT Agent SDK – README

## 1. 이게 뭐하는 건가요?
이 SDK는 **ProcessGPT 에이전트 서버**를 만들 때 필요한 **공통 기능**을 제공합니다.  

- DB에서 **작업(todo) 폴링** → 처리할 일감 가져오기  
- **컨텍스트 준비** (사용자 정보, 폼 정의, MCP 설정 등 자동으로 조회)  
- 다양한 **에이전트 오케스트레이션(A2A)** 과 호환  
- **이벤트(Event) 전송 규격 통일화** → 결과를 DB에 안전하게 저장  

👉 쉽게 말하면: **여러 종류의 AI 에이전트를 같은 규칙으로 실행/저장/호출할 수 있게 해주는 통합 SDK** 입니다.  

---

## 2. 아키텍처 다이어그램
```mermaid
flowchart TD
    subgraph DB[Postgres/Supabase]
        T[todolist]:::db
        E[events]:::db
    end

    subgraph SDK
        P[Polling\n(fetch_pending_task)] --> C[Context 준비\n(fetch_context_bundle 등)]
        C --> X[Executor\n(MinimalExecutor)]
        X -->|TaskStatusUpdateEvent| E
        X -->|TaskArtifactUpdateEvent| T
    end

    classDef db fill=#f2f2f2,stroke=#333,stroke-width=1px;
```

- **todolist**: 각 작업(Task)의 진행 상태, 결과물 저장  
- **events**: 실행 중간에 발생한 이벤트 로그 저장  
- SDK는 두 테이블을 자동으로 연결해 줍니다.  

---

## 3. A2A 타입과 이벤트 종류

### A2A 타입 (2가지)
| A2A 타입 | 설명 | 매칭 테이블 |
|----------|------|-------------|
| **TaskStatusUpdateEvent** | 작업 상태 업데이트 | `events` 테이블 |
| **TaskArtifactUpdateEvent** | 작업 결과물 업데이트 | `todolist` 테이블 |

### Event Type (4가지)
| Event Type | Python 클래스 | 저장 테이블 | 설명 |
|------------|---------------|-------------|------|
| **task_started** | `TaskStatusUpdateEvent` | `events` | 작업 시작 상태 |
| **task_working** | `TaskStatusUpdateEvent` | `events` | 작업 진행 중 상태 |
| **task_completed** | `TaskArtifactUpdateEvent` | `todolist` | 작업 완료 및 결과물 저장 |
| **task_error** | `TaskStatusUpdateEvent` | `events` | 작업 오류 발생 |

👉 **A2A 타입 2가지**가 핵심이며, 각각 `events`와 `todolist` 테이블에 매칭됩니다. **Event Type 4가지**로 세부 상태를 구분합니다.

---

## 4. 미니멀 예제 (기본 사용법)

### minimal_executor.py
```python
class MinimalExecutor(AgentExecutor):
    async def execute(self, context: RequestContext, event_queue: EventQueue):
        # 1) 입력 가져오기
        query = context.get_user_input()
        print("User Query:", query)

        # 2) 상태 이벤트 (events 테이블 저장)
        payload = {"demo": "hello world"}
        event_queue.enqueue_event(
            TaskStatusUpdateEvent(
                status={
                    "state": TaskState.working,
                    "message": new_agent_text_message(
                        json.dumps(payload, ensure_ascii=False),  # ⚠️ str() 쓰지말고 반드시 json.dumps!
                        context.get_context_data()["row"]["proc_inst_id"],
                        context.get_context_data()["row"]["id"],
                    ),
                },
                contextId=context.get_context_data()["row"]["proc_inst_id"],
                taskId=context.get_context_data()["row"]["id"],
                metadata={"crew_type": "action", "event_type": "task_started"},
            )
        )

        # 3) 최종 아티팩트 이벤트 (todolist 테이블 저장)
        artifact = new_text_artifact(
            name="result",
            description="Demo Result",
            text=json.dumps(payload, ensure_ascii=False),  # ⚠️ 여기서도 str() 금지!
        )
        event_queue.enqueue_event(
            TaskArtifactUpdateEvent(
                artifact=artifact,
                lastChunk=True,
                contextId=context.get_context_data()["row"]["proc_inst_id"],
                taskId=context.get_context_data()["row"]["id"],
            )
        )
```

### minimal_server.py
```python
async def main():
    load_dotenv()
    server = ProcessGPTAgentServer(
        agent_executor=MinimalExecutor(),
        agent_type="crewai-action"  # 오케스트레이터 타입
    )
    await server.run()
```

👉 실행하면 SDK가 자동으로:
1. DB에서 작업 하나 가져오기 (`fetch_pending_task`)  
2. 컨텍스트 준비 (폼/유저/MCP 조회)  
3. Executor 실행 → 이벤트/결과 DB에 저장  

---

## 5. ⚠️ JSON 직렬화 주의 (str() 절대 금지)

반드시 `json.dumps()`로 직렬화해야 합니다.  

- ❌ 이렇게 하면 안됨:
  ```python
  text = str({"key": "value"})  # Python dict string → JSON 아님
  ```
  DB에 `"'{key: value}'"` 꼴로 문자열 저장됨 → 파싱 실패

- ✅ 이렇게 해야 함:
  ```python
  text = json.dumps({"key": "value"}, ensure_ascii=False)
  ```
  DB에 `{"key": "value"}` JSON 저장됨 → 파싱 성공

👉 **SDK는 내부에서 `json.loads`로 재파싱**하기 때문에, 표준 JSON 문자열이 아니면 무조건 문자열로만 남습니다.  

---

## 6. 요약
- 이 SDK는 **ProcessGPT Agent**를 표준 규격으로 실행/저장/호출하는 공통 레이어  
- 작업 → 컨텍스트 준비 → Executor 실행 → 이벤트 저장 전체를 자동화  
- **A2A 타입 2가지**: `TaskStatusUpdateEvent`, `TaskArtifactUpdateEvent`  
- **Event Type 4가지**: `task_started`, `task_working`, `task_completed`, `task_error`  
- **DB 매핑**:  
  - `TaskStatusUpdateEvent` → `events` 테이블  
  - `TaskArtifactUpdateEvent` → `todolist` 테이블  
- ⚠️ **str() 대신 무조건 `json.dumps` 사용!**



## 7. 버전업
- ./release.sh 버전
- 오류 발생시 : python -m ensurepip --upgrade

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "process-gpt-agent-sdk",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "agent, a2a, supabase, workflow, sdk, processgpt",
    "author": null,
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/b7/bd/2f63cfc742303ceb08cf9089ce04c4c4f5fc6f388747073c1dc52060adae/process_gpt_agent_sdk-0.4.9.tar.gz",
    "platform": null,
    "description": "# \ud83d\udcd8 ProcessGPT Agent SDK \u2013 README\r\n\r\n## 1. \uc774\uac8c \ubb50\ud558\ub294 \uac74\uac00\uc694?\r\n\uc774 SDK\ub294 **ProcessGPT \uc5d0\uc774\uc804\ud2b8 \uc11c\ubc84**\ub97c \ub9cc\ub4e4 \ub54c \ud544\uc694\ud55c **\uacf5\ud1b5 \uae30\ub2a5**\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4.  \r\n\r\n- DB\uc5d0\uc11c **\uc791\uc5c5(todo) \ud3f4\ub9c1** \u2192 \ucc98\ub9ac\ud560 \uc77c\uac10 \uac00\uc838\uc624\uae30  \r\n- **\ucee8\ud14d\uc2a4\ud2b8 \uc900\ube44** (\uc0ac\uc6a9\uc790 \uc815\ubcf4, \ud3fc \uc815\uc758, MCP \uc124\uc815 \ub4f1 \uc790\ub3d9\uc73c\ub85c \uc870\ud68c)  \r\n- \ub2e4\uc591\ud55c **\uc5d0\uc774\uc804\ud2b8 \uc624\ucf00\uc2a4\ud2b8\ub808\uc774\uc158(A2A)** \uacfc \ud638\ud658  \r\n- **\uc774\ubca4\ud2b8(Event) \uc804\uc1a1 \uaddc\uaca9 \ud1b5\uc77c\ud654** \u2192 \uacb0\uacfc\ub97c DB\uc5d0 \uc548\uc804\ud558\uac8c \uc800\uc7a5  \r\n\r\n\ud83d\udc49 \uc27d\uac8c \ub9d0\ud558\uba74: **\uc5ec\ub7ec \uc885\ub958\uc758 AI \uc5d0\uc774\uc804\ud2b8\ub97c \uac19\uc740 \uaddc\uce59\uc73c\ub85c \uc2e4\ud589/\uc800\uc7a5/\ud638\ucd9c\ud560 \uc218 \uc788\uac8c \ud574\uc8fc\ub294 \ud1b5\ud569 SDK** \uc785\ub2c8\ub2e4.  \r\n\r\n---\r\n\r\n## 2. \uc544\ud0a4\ud14d\ucc98 \ub2e4\uc774\uc5b4\uadf8\ub7a8\r\n```mermaid\r\nflowchart TD\r\n    subgraph DB[Postgres/Supabase]\r\n        T[todolist]:::db\r\n        E[events]:::db\r\n    end\r\n\r\n    subgraph SDK\r\n        P[Polling\\n(fetch_pending_task)] --> C[Context \uc900\ube44\\n(fetch_context_bundle \ub4f1)]\r\n        C --> X[Executor\\n(MinimalExecutor)]\r\n        X -->|TaskStatusUpdateEvent| E\r\n        X -->|TaskArtifactUpdateEvent| T\r\n    end\r\n\r\n    classDef db fill=#f2f2f2,stroke=#333,stroke-width=1px;\r\n```\r\n\r\n- **todolist**: \uac01 \uc791\uc5c5(Task)\uc758 \uc9c4\ud589 \uc0c1\ud0dc, \uacb0\uacfc\ubb3c \uc800\uc7a5  \r\n- **events**: \uc2e4\ud589 \uc911\uac04\uc5d0 \ubc1c\uc0dd\ud55c \uc774\ubca4\ud2b8 \ub85c\uadf8 \uc800\uc7a5  \r\n- SDK\ub294 \ub450 \ud14c\uc774\ube14\uc744 \uc790\ub3d9\uc73c\ub85c \uc5f0\uacb0\ud574 \uc90d\ub2c8\ub2e4.  \r\n\r\n---\r\n\r\n## 3. A2A \ud0c0\uc785\uacfc \uc774\ubca4\ud2b8 \uc885\ub958\r\n\r\n### A2A \ud0c0\uc785 (2\uac00\uc9c0)\r\n| A2A \ud0c0\uc785 | \uc124\uba85 | \ub9e4\uce6d \ud14c\uc774\ube14 |\r\n|----------|------|-------------|\r\n| **TaskStatusUpdateEvent** | \uc791\uc5c5 \uc0c1\ud0dc \uc5c5\ub370\uc774\ud2b8 | `events` \ud14c\uc774\ube14 |\r\n| **TaskArtifactUpdateEvent** | \uc791\uc5c5 \uacb0\uacfc\ubb3c \uc5c5\ub370\uc774\ud2b8 | `todolist` \ud14c\uc774\ube14 |\r\n\r\n### Event Type (4\uac00\uc9c0)\r\n| Event Type | Python \ud074\ub798\uc2a4 | \uc800\uc7a5 \ud14c\uc774\ube14 | \uc124\uba85 |\r\n|------------|---------------|-------------|------|\r\n| **task_started** | `TaskStatusUpdateEvent` | `events` | \uc791\uc5c5 \uc2dc\uc791 \uc0c1\ud0dc |\r\n| **task_working** | `TaskStatusUpdateEvent` | `events` | \uc791\uc5c5 \uc9c4\ud589 \uc911 \uc0c1\ud0dc |\r\n| **task_completed** | `TaskArtifactUpdateEvent` | `todolist` | \uc791\uc5c5 \uc644\ub8cc \ubc0f \uacb0\uacfc\ubb3c \uc800\uc7a5 |\r\n| **task_error** | `TaskStatusUpdateEvent` | `events` | \uc791\uc5c5 \uc624\ub958 \ubc1c\uc0dd |\r\n\r\n\ud83d\udc49 **A2A \ud0c0\uc785 2\uac00\uc9c0**\uac00 \ud575\uc2ec\uc774\uba70, \uac01\uac01 `events`\uc640 `todolist` \ud14c\uc774\ube14\uc5d0 \ub9e4\uce6d\ub429\ub2c8\ub2e4. **Event Type 4\uac00\uc9c0**\ub85c \uc138\ubd80 \uc0c1\ud0dc\ub97c \uad6c\ubd84\ud569\ub2c8\ub2e4.\r\n\r\n---\r\n\r\n## 4. \ubbf8\ub2c8\uba40 \uc608\uc81c (\uae30\ubcf8 \uc0ac\uc6a9\ubc95)\r\n\r\n### minimal_executor.py\r\n```python\r\nclass MinimalExecutor(AgentExecutor):\r\n    async def execute(self, context: RequestContext, event_queue: EventQueue):\r\n        # 1) \uc785\ub825 \uac00\uc838\uc624\uae30\r\n        query = context.get_user_input()\r\n        print(\"User Query:\", query)\r\n\r\n        # 2) \uc0c1\ud0dc \uc774\ubca4\ud2b8 (events \ud14c\uc774\ube14 \uc800\uc7a5)\r\n        payload = {\"demo\": \"hello world\"}\r\n        event_queue.enqueue_event(\r\n            TaskStatusUpdateEvent(\r\n                status={\r\n                    \"state\": TaskState.working,\r\n                    \"message\": new_agent_text_message(\r\n                        json.dumps(payload, ensure_ascii=False),  # \u26a0\ufe0f str() \uc4f0\uc9c0\ub9d0\uace0 \ubc18\ub4dc\uc2dc json.dumps!\r\n                        context.get_context_data()[\"row\"][\"proc_inst_id\"],\r\n                        context.get_context_data()[\"row\"][\"id\"],\r\n                    ),\r\n                },\r\n                contextId=context.get_context_data()[\"row\"][\"proc_inst_id\"],\r\n                taskId=context.get_context_data()[\"row\"][\"id\"],\r\n                metadata={\"crew_type\": \"action\", \"event_type\": \"task_started\"},\r\n            )\r\n        )\r\n\r\n        # 3) \ucd5c\uc885 \uc544\ud2f0\ud329\ud2b8 \uc774\ubca4\ud2b8 (todolist \ud14c\uc774\ube14 \uc800\uc7a5)\r\n        artifact = new_text_artifact(\r\n            name=\"result\",\r\n            description=\"Demo Result\",\r\n            text=json.dumps(payload, ensure_ascii=False),  # \u26a0\ufe0f \uc5ec\uae30\uc11c\ub3c4 str() \uae08\uc9c0!\r\n        )\r\n        event_queue.enqueue_event(\r\n            TaskArtifactUpdateEvent(\r\n                artifact=artifact,\r\n                lastChunk=True,\r\n                contextId=context.get_context_data()[\"row\"][\"proc_inst_id\"],\r\n                taskId=context.get_context_data()[\"row\"][\"id\"],\r\n            )\r\n        )\r\n```\r\n\r\n### minimal_server.py\r\n```python\r\nasync def main():\r\n    load_dotenv()\r\n    server = ProcessGPTAgentServer(\r\n        agent_executor=MinimalExecutor(),\r\n        agent_type=\"crewai-action\"  # \uc624\ucf00\uc2a4\ud2b8\ub808\uc774\ud130 \ud0c0\uc785\r\n    )\r\n    await server.run()\r\n```\r\n\r\n\ud83d\udc49 \uc2e4\ud589\ud558\uba74 SDK\uac00 \uc790\ub3d9\uc73c\ub85c:\r\n1. DB\uc5d0\uc11c \uc791\uc5c5 \ud558\ub098 \uac00\uc838\uc624\uae30 (`fetch_pending_task`)  \r\n2. \ucee8\ud14d\uc2a4\ud2b8 \uc900\ube44 (\ud3fc/\uc720\uc800/MCP \uc870\ud68c)  \r\n3. Executor \uc2e4\ud589 \u2192 \uc774\ubca4\ud2b8/\uacb0\uacfc DB\uc5d0 \uc800\uc7a5  \r\n\r\n---\r\n\r\n## 5. \u26a0\ufe0f JSON \uc9c1\ub82c\ud654 \uc8fc\uc758 (str() \uc808\ub300 \uae08\uc9c0)\r\n\r\n\ubc18\ub4dc\uc2dc `json.dumps()`\ub85c \uc9c1\ub82c\ud654\ud574\uc57c \ud569\ub2c8\ub2e4.  \r\n\r\n- \u274c \uc774\ub807\uac8c \ud558\uba74 \uc548\ub428:\r\n  ```python\r\n  text = str({\"key\": \"value\"})  # Python dict string \u2192 JSON \uc544\ub2d8\r\n  ```\r\n  DB\uc5d0 `\"'{key: value}'\"` \uaf34\ub85c \ubb38\uc790\uc5f4 \uc800\uc7a5\ub428 \u2192 \ud30c\uc2f1 \uc2e4\ud328\r\n\r\n- \u2705 \uc774\ub807\uac8c \ud574\uc57c \ud568:\r\n  ```python\r\n  text = json.dumps({\"key\": \"value\"}, ensure_ascii=False)\r\n  ```\r\n  DB\uc5d0 `{\"key\": \"value\"}` JSON \uc800\uc7a5\ub428 \u2192 \ud30c\uc2f1 \uc131\uacf5\r\n\r\n\ud83d\udc49 **SDK\ub294 \ub0b4\ubd80\uc5d0\uc11c `json.loads`\ub85c \uc7ac\ud30c\uc2f1**\ud558\uae30 \ub54c\ubb38\uc5d0, \ud45c\uc900 JSON \ubb38\uc790\uc5f4\uc774 \uc544\ub2c8\uba74 \ubb34\uc870\uac74 \ubb38\uc790\uc5f4\ub85c\ub9cc \ub0a8\uc2b5\ub2c8\ub2e4.  \r\n\r\n---\r\n\r\n## 6. \uc694\uc57d\r\n- \uc774 SDK\ub294 **ProcessGPT Agent**\ub97c \ud45c\uc900 \uaddc\uaca9\uc73c\ub85c \uc2e4\ud589/\uc800\uc7a5/\ud638\ucd9c\ud558\ub294 \uacf5\ud1b5 \ub808\uc774\uc5b4  \r\n- \uc791\uc5c5 \u2192 \ucee8\ud14d\uc2a4\ud2b8 \uc900\ube44 \u2192 Executor \uc2e4\ud589 \u2192 \uc774\ubca4\ud2b8 \uc800\uc7a5 \uc804\uccb4\ub97c \uc790\ub3d9\ud654  \r\n- **A2A \ud0c0\uc785 2\uac00\uc9c0**: `TaskStatusUpdateEvent`, `TaskArtifactUpdateEvent`  \r\n- **Event Type 4\uac00\uc9c0**: `task_started`, `task_working`, `task_completed`, `task_error`  \r\n- **DB \ub9e4\ud551**:  \r\n  - `TaskStatusUpdateEvent` \u2192 `events` \ud14c\uc774\ube14  \r\n  - `TaskArtifactUpdateEvent` \u2192 `todolist` \ud14c\uc774\ube14  \r\n- \u26a0\ufe0f **str() \ub300\uc2e0 \ubb34\uc870\uac74 `json.dumps` \uc0ac\uc6a9!**\r\n\r\n\r\n\r\n## 7. \ubc84\uc804\uc5c5\r\n- ./release.sh \ubc84\uc804\r\n- \uc624\ub958 \ubc1c\uc0dd\uc2dc : python -m ensurepip --upgrade\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Supabase \uae30\ubc18 \uc774\ubca4\ud2b8/\uc791\uc5c5 \ud3f4\ub9c1\uc73c\ub85c A2A AgentExecutor\ub97c \uc2e4\ud589\ud558\ub294 SDK",
    "version": "0.4.9",
    "project_urls": {
        "Homepage": "https://github.com/your-org/process-gpt-agent-sdk",
        "Issues": "https://github.com/your-org/process-gpt-agent-sdk/issues"
    },
    "split_keywords": [
        "agent",
        " a2a",
        " supabase",
        " workflow",
        " sdk",
        " processgpt"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "60e8a06ce8a57a718a967fc253e916302f5f438a6f82bba8905636eb81ce0a92",
                "md5": "15bc3995753fd57197dd94033f459272",
                "sha256": "34f69b71107455c11fb46bbe9a198344655590428f97f4f61812bbb28cf92849"
            },
            "downloads": -1,
            "filename": "process_gpt_agent_sdk-0.4.9-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "15bc3995753fd57197dd94033f459272",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 19986,
            "upload_time": "2025-10-15T09:30:52",
            "upload_time_iso_8601": "2025-10-15T09:30:52.013272Z",
            "url": "https://files.pythonhosted.org/packages/60/e8/a06ce8a57a718a967fc253e916302f5f438a6f82bba8905636eb81ce0a92/process_gpt_agent_sdk-0.4.9-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b7bd2f63cfc742303ceb08cf9089ce04c4c4f5fc6f388747073c1dc52060adae",
                "md5": "75ff970220359c499e2fdec65f2b6bd4",
                "sha256": "d7e23206cb5ade9d708cc91b724b4822218c6dca5dffe6b36cea2331753d38ae"
            },
            "downloads": -1,
            "filename": "process_gpt_agent_sdk-0.4.9.tar.gz",
            "has_sig": false,
            "md5_digest": "75ff970220359c499e2fdec65f2b6bd4",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 17843,
            "upload_time": "2025-10-15T09:30:53",
            "upload_time_iso_8601": "2025-10-15T09:30:53.021476Z",
            "url": "https://files.pythonhosted.org/packages/b7/bd/2f63cfc742303ceb08cf9089ce04c4c4f5fc6f388747073c1dc52060adae/process_gpt_agent_sdk-0.4.9.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-15 09:30:53",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "your-org",
    "github_project": "process-gpt-agent-sdk",
    "github_not_found": true,
    "lcname": "process-gpt-agent-sdk"
}
        
Elapsed time: 1.06730s