""" このコードは以下のコードをLinear.appに対応させたものです。公式のコードではありません。 https://github.com/huggingface/huggingface_hub/blob/main/src/huggingface_hub/_webhooks_server.py https://github.com/huggingface/huggingface_hub/blob/main/src/huggingface_hub/_webhooks_payload.py まだ、Issue Objectのごく一部しか対応してません。 https://studio.apollographql.com/public/Linear-API/variant/current/schema/reference/objects/Issue .envファイルに、api_key = linear-api-key および、webhook_secret = linear-webhook-secretの設定が必要です。 ローカルは起動ごとにURLが変わるので、起動時にLinear-APIでURLを更新しています。 target_webhook_label(デフォルト値はGradio)で指定したラベルのwebhookを実行時に上書きます。 gradio,fastapi,pydanticをあらかじめインストールしておく必要があります。 .envにlinear api_keyおよび、linear-webhook secretを記述する必要があります。 また、このExampleはUpdateのみなので、最初にラベルGradioでWebhookを作っておいてください。 ** Linear.app 対応部分の著作権表示 ** # Copyright 2025-present, Akihito Miyazaki # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ** Hugging Face Hub ライブラリのライセンス表示 ** # Copyright 2023-present, the HuggingFace Inc. team. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. このコードには Hugging Face Hub ライブラリの一部が含まれており、Apache License, Version 2.0 の下でライセンスされています。 ライセンスの全文は以下から確認できます: http://www.apache.org/licenses/LICENSE-2.0 """ import os from pprint import pprint import gradio as gr from smolagents import CodeAgent, HfApiModel from linear_api_utils import execute_query from gradio_webhook_server import WebhooksServer from gradio_webhook_payload import WebhookPayload from sleep_per_last_token_model import SleepPerLastTokenModelLiteLLM def get_env_value(key, is_value_error_on_null=True): value = os.getenv(key) if value is None: from dotenv import load_dotenv load_dotenv() value = os.getenv(key) if is_value_error_on_null and value is None: raise ValueError(f"Need {key} on secret or .env(If running on local)") return value # SETTINGS LINEAR_ISSUE_LABEL = "huggingface-public" # only show issue with this label,I added for demo you can remove this LINEAR_WEBHOOK_LABEL = "Huggingface" # you have to create in linear before run script # set secret key on Space setting or .env(local) # hf_token = get_env_value("HF_TOKEN") groq_api_key = get_env_value("GROQ_API_KEY") api_key = get_env_value("LINEAR_API_KEY") webhook_key = get_env_value("LINEAR_WEBHOOK_KEY") if api_key is None: raise ValueError("Need LINEAR_API_KEY on secret") if webhook_key is None: raise ValueError("Need LINEAR_WEBHOOK_KEY on secret") webhook_query_text = """ query { webhooks{ nodes { id label url } } } """ target_webhook_label = LINEAR_WEBHOOK_LABEL # filter not working,set manual target_webhook_id = None result = execute_query("webhook", webhook_query_text, api_key) for webhook in result["data"]["webhooks"]["nodes"]: if target_webhook_label == webhook["label"]: target_webhook_id = webhook["id"] app = None model = SleepPerLastTokenModelLiteLLM( max_tokens=100, temperature=0.5, model_id="groq/llama3-8b-8192", api_base="https://api.groq.com/openai/v1/", api_key=groq_api_key, ) """ model = HfApiModel( max_tokens=100, temperature=0.5, model_id="google/gemma-2-2b-it", custom_role_conversions=None, token=hf_token, ) """ agent = CodeAgent( model=model, tools=[], ## add your tools here (don't remove final answer) max_steps=1, verbosity_level=1, grammar=None, planning_interval=None, name=None, description=None, ) def update(): result = agent.run(f"how to solve this issue:{app.text}") return app.text, result with gr.Blocks() as ui: gr.HTML("""
This is Demo of Direct Webhook-triggered AIAgen
it's still just simple code,sadly you have to click to show updates.
Imagine an agent, responding instantly.
Technically Gradio have no way to update without action
I'm confused by Hugging Face's new pricing system. I'm worried about potentially massive inference API bills, so I switched to Groq.
I believe my use of the Groq API is currently compliant with Hugging Face's Content Policy.
If you have any questions, please disable the Space or contact me before taking any action against my account. Thank you for your understanding.
""") with gr.Row(): issue_box = gr.Textbox(label="Issue") output_box = gr.Textbox(label="出力") bt = gr.Button("Ask AI") bt.click(update, outputs=[issue_box, output_box]) app = WebhooksServer( ui=ui, webhook_secret=webhook_key, # loaded by load_api_key ) app.text = "nothing" @app.add_webhook("/linear_webhook") async def updated(payload: WebhookPayload): pprint(payload.dict(), indent=4) data = payload.dict()["data"] has_label = True if LINEAR_ISSUE_LABEL: has_label = False for label in data["labels"]: if label["name"] == LINEAR_ISSUE_LABEL: has_label = True if has_label: text = data["description"] app.text = text return {"message": "ok"} def webhook_update(url): webhook_update_text = """ mutation { webhookUpdate( id: "%s" input:{ url:"%s" } ) { success } } """ % (target_webhook_id, url) result = execute_query("webhook_update", webhook_update_text, api_key) app.launch(webhook_update=webhook_update)