Skip to content
Draft
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
15 changes: 15 additions & 0 deletions .github/workflows/pull_reqeust.default.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
on: [pull_request]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5
- uses: astral-sh/setup-uv@v7
- run: uv sync
- env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

DST_ISSUE_NUMBER: 13
run: uv run chat-from-github-issue
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/.python-version
/uv.lock

/Makefile
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,34 @@
# prototype
For fast prototyping!

## What?

- Type some ideas into some "Github Issue"
- Trigger Github Actions Workflow via ``issue_comment``
- e.g. ``hey, alex {PROMPT}``
- e.g. ``alex, {PROMPT}``
- The workflow convert the main description and all comments into a Chat history

## Probeles to Solve

1. How to test workflows?
- Espeically workflows with ``issue_comment`` trigger
Copy link
Owner Author

Choose a reason for hiding this comment

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

사내에서 개인 인프라 구축하다가 겪었던 문제 😭

일단 현재 생각나는 방안은 context를 .json으로 저장한 다음에 이용하는 방식으로 workflow를 작성하고, workflow 자체를 테스트 할 때는 사전에 준비된 fixture (repo에 commit 하거나 혹은 gist를 통해서 전달하거나)를 이용해서 테스트를 하면 되지 않을까? 싶긴하다.

Copy link
Owner Author

Choose a reason for hiding this comment

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

issue_comment workflow에서 알아내야 하는 정보

  • issue.number


## References

- LLM Provider
- Ollama (in use)
- https://github.com/ollama/ollama-python
- Gemini (candidate)
- https://ai.google.dev/gemini-api/docs
Copy link
Owner Author

Choose a reason for hiding this comment

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

Gemini의 Multi-turn Chat API을 잠시 살펴봤는데, 세션 자체를 API 뒤에서 유지하는 형태인 것 같다.

해서 ollama와 같은 방식을 사용은 어렵다.

아니면,, 매번 새로운 chat을 만드는 방법이 있긴한데 🤔

- Github Actions
- https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows
- https://docs.github.com/en/actions/concepts/runners/self-hosted-runners
- https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/add-runners
- https://docs.github.com/en/actions/reference/runners/self-hosted-runners

### How to Run Linters?

```
uv run pre-commit run -a -c pre-commit-config.yaml
```
11 changes: 11 additions & 0 deletions pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
repos:
- repo: https://github.com/rhysd/actionlint.git
rev: v1.6.26 # Use the latest stable version of actionlint
hooks:
- id: actionlint
name: Lint GitHub Actions workflows
entry: actionlint
language: golang
types: ["yaml"]
files: ^\.github/workflows/
args: ["-color"] # Optional: Add arguments like -color for colored output
25 changes: 25 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[project]
name = "chat-from-github-issue"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
authors = [
{ name = "Jonghyun Park", email = "parjong@gmail.com" }
]
requires-python = "==3.14.*"
dependencies = [
"ollama==0.6.1",
"pygithub==2.8.1",
]

[project.scripts]
chat-from-github-issue = "chat_from_github_issue:main"

[build-system]
requires = ["uv_build>=0.9.3,<0.10.0"]
build-backend = "uv_build"

[dependency-groups]
dev = [
"pre-commit==4.3.0",
]
101 changes: 101 additions & 0 deletions src/chat_from_github_issue/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Based on https://pygithub.readthedocs.io/en/v2.8.1/introduction.html
from github import Github
from github import Auth as GithubAuth
from ollama import chat
from ollama import ChatResponse

from os import environ
from pprint import pprint

def chat_message_of_(comment):
# comment.body: str
# comment.author_association = OWNER
# | ...
# | NONE (for github-action bot account
# when tested from Github Enterprise
# comment.reactions: dict
# ^ Can be used to make a recap on close (persistent memory)
role = 'user' if comment.author_association != 'NONE' else 'assistant'
return { 'role': role, 'content': comment.body }
# def/ END

def make_response_for_(messages):
if 'CI' in environ:
sample = """Hello! I'm Alex, your friendly AI assistant here to help you with whatever you need! 😊"""
return sample
# if/ END
Copy link
Owner Author

Choose a reason for hiding this comment

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

일단은 CI 통합까지 진행해보기 위해서 간단한 샘플 답변을 하드코딩해두었다.


# References
# - https://apidog.com/blog/how-to-use-ollama/
args = {}

args['model'] = 'qwen3:1.7b' # To run LLM onNVIDIA GeForce GTX 1650 (4GB VRAM)
args['messages'] = messages
args['options'] = { 'num_ctx': 8 * 1024 } # Q. How to adjust this number?

response: ChatResponse = chat(**args)

return response.message.content
# def/ END

def main() -> None:
# NOTE Caller SHOULD set 'GITHUB_TOKEN' before (even for Github Actions)
auth = GithubAuth.Token(environ['GITHUB_TOKEN'])
g = Github(auth=auth)

param = {}

param['src_issue_number'] = '13'

repository: str = 'parjong/prototype'
src_issue_number: int = 13

repo = g.get_repo(repository)
issue = repo.get_issue(number=src_issue_number)

messages = []

# System Prompt
messages += [ { 'role': 'system', 'content': 'You are alex, a kind assistant' } ]

# Chat History
# Q. How to treat the main description?
#
# - As system prompt?
# - As chat history?
messages += [ { 'role': 'user', 'content': issue.body } ]
messages += [ chat_message_of_(comment) for comment in issue.get_comments() ]
Copy link
Owner Author

Choose a reason for hiding this comment

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

근데, Chat GPT의 경우 단일 사용자와 에이전트와의 대화인데... Github Issue에는 다중 사용자가 올 수 있는데 이걸 구분할 방법이 있나?

"role" 만으로는 정보가 좀 부족한 것 같은데 🤔


print('Messages:')
pprint(messages)

response = make_response_for_(messages)

print('Response:')
print(response)

if 'DST_ISSUE_NUMBER' in environ:
dst_issue_number = int(environ['DST_ISSUE_NUMBER'])
issue = repo.get_issue(number=dst_issue_number)
issue.create_comment(response)

# NOTE Possible to remove How to remove
#
# Variable | How?
# --- | ---
# repository | Use 'GITHUB_REPOSITORY' environment variable
# issue_number | Use action event context
# | (e.g. github.context.issue.number for 'issue_comment' trigger)
#
# From [1]

# NOTE. System Design Pros/Cons
#
# - Pros: Minimal infrastructure
# - Cons: Redundant re-computation (cannot reuse the KV from existing turns)
# def/ END

# References
#
# [1] https://docs.github.com/en/actions/reference/workflowsu-and-actions/variables
# [2] https://pygithub.readthedocs.io/en/v2.8.1/examples.html