Skip to content

Commit c4a6da1

Browse files
authored
feat: add options for URL and token (#57)
If the URL option is passed, then the SDK will behave the same as if the GPTSCRIPT_URL env var is set. Signed-off-by: Donnie Adams <[email protected]>
1 parent 97baa66 commit c4a6da1

File tree

3 files changed

+40
-42
lines changed

3 files changed

+40
-42
lines changed

gptscript/gptscript.py

+16-33
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@
33
import platform
44
from subprocess import Popen, PIPE
55
from sys import executable
6-
from time import sleep
76
from typing import Any, Callable, Awaitable, List
87

9-
import requests
10-
118
from gptscript.confirm import AuthResponse
129
from gptscript.credentials import Credential, to_credential
1310
from gptscript.frame import RunFrame, CallFrame, PromptFrame, Program
@@ -22,25 +19,23 @@ class GPTScript:
2219
__gptscript_count = 0
2320
__server_url = ""
2421
__process: Popen = None
25-
__server_ready: bool = False
2622

2723
def __init__(self, opts: GlobalOptions = None):
2824
if opts is None:
2925
opts = GlobalOptions()
3026
self.opts = opts
3127

28+
start_sdk = GPTScript.__process is None and GPTScript.__server_url == "" and self.opts.URL == ""
3229
GPTScript.__gptscript_count += 1
33-
3430
if GPTScript.__server_url == "":
35-
GPTScript.__server_url = os.environ.get("GPTSCRIPT_URL", "http://127.0.0.1:0")
36-
if not (GPTScript.__server_url.startswith("http://") or GPTScript.__server_url.startswith("https://")):
37-
GPTScript.__server_url = f"http://{GPTScript.__server_url}"
31+
GPTScript.__server_url = os.environ.get("GPTSCRIPT_URL", "")
32+
start_sdk = start_sdk and GPTScript.__server_url == ""
3833

39-
if GPTScript.__gptscript_count == 1 and os.environ.get("GPTSCRIPT_URL", "") == "":
34+
if start_sdk:
4035
self.opts.toEnv()
4136

4237
GPTScript.__process = Popen(
43-
[_get_command(), "--listen-address", GPTScript.__server_url.removeprefix("http://"), "sdkserver"],
38+
[_get_command(), "sys.sdkserver", "--listen-address", "127.0.0.1:0"],
4439
stdin=PIPE,
4540
stdout=PIPE,
4641
stderr=PIPE,
@@ -53,35 +48,25 @@ def __init__(self, opts: GlobalOptions = None):
5348
if "=" in GPTScript.__server_url:
5449
GPTScript.__server_url = GPTScript.__server_url.split("=")[1]
5550

56-
self.opts.Env.append("GPTSCRIPT_URL=" + GPTScript.__server_url)
57-
self._server_url = GPTScript.__server_url
58-
if not (self._server_url.startswith("http://") or self._server_url.startswith("https://")):
59-
self._server_url = f"http://{self._server_url}"
60-
self._wait_for_gptscript()
61-
62-
def _wait_for_gptscript(self):
63-
if not GPTScript.__server_ready:
64-
for _ in range(0, 20):
65-
try:
66-
resp = requests.get(self._server_url + "/healthz")
67-
if resp.status_code == 200:
68-
GPTScript.__server_ready = True
69-
return
70-
except requests.exceptions.ConnectionError:
71-
pass
51+
if self.opts.URL == "":
52+
self.opts.URL = GPTScript.__server_url
53+
if not (self.opts.URL.startswith("http://") or self.opts.URL.startswith("https://")):
54+
self.opts.URL = f"http://{self.opts.URL}"
7255

73-
sleep(1)
56+
self.opts.Env.append("GPTSCRIPT_URL=" + self.opts.URL)
7457

75-
raise Exception("Failed to start gptscript")
58+
if self.opts.Token == "":
59+
self.opts.Token = os.environ.get("GPTSCRIPT_TOKEN", "")
60+
if self.opts.Token != "":
61+
self.opts.Env.append("GPTSCRIPT_TOKEN=" + self.opts.Token)
7662

7763
def close(self):
7864
GPTScript.__gptscript_count -= 1
7965
if GPTScript.__gptscript_count == 0 and GPTScript.__process is not None:
8066
GPTScript.__process.stdin.close()
8167
GPTScript.__process.wait()
82-
GPTScript.__server_ready = False
8368
GPTScript.__process = None
84-
self._server_url = ""
69+
self.opts = None
8570

8671
def evaluate(
8772
self,
@@ -94,7 +79,6 @@ def evaluate(
9479
"evaluate",
9580
tool,
9681
opts.merge_global_opts(self.opts),
97-
self._server_url,
9882
event_handlers=event_handlers,
9983
).next_chat(opts.input)
10084

@@ -108,7 +92,6 @@ def run(
10892
"run",
10993
tool_path,
11094
opts.merge_global_opts(self.opts),
111-
self._server_url,
11295
event_handlers=event_handlers,
11396
).next_chat(opts.input)
11497

@@ -165,7 +148,7 @@ async def prompt(self, resp: PromptResponse):
165148
await self._run_basic_command("prompt-response/" + resp.id, resp.responses)
166149

167150
async def _run_basic_command(self, sub_command: str, request_body: Any = None):
168-
run = RunBasicCommand(sub_command, request_body, self._server_url)
151+
run = RunBasicCommand(sub_command, request_body, self.opts.URL, self.opts.Token)
169152

170153
run.next_chat()
171154

gptscript/opts.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@
55
class GlobalOptions:
66
def __init__(
77
self,
8+
url: str = "",
9+
token: str = "",
810
apiKey: str = "",
911
baseURL: str = "",
1012
defaultModelProvider: str = "",
1113
defaultModel: str = "",
1214
cacheDir: str = "",
1315
env: Mapping[str, str] = None,
1416
):
17+
self.URL = url
18+
self.Token = token
1519
self.APIKey = apiKey
1620
self.BaseURL = baseURL
1721
self.DefaultModel = defaultModel
@@ -25,7 +29,9 @@ def __init__(
2529
def merge(self, other: Self) -> Self:
2630
cp = self.__class__()
2731
if other is None:
28-
return cp
32+
return self
33+
cp.URL = other.URL if other.URL != "" else self.URL
34+
cp.Token = other.Token if other.Token != "" else self.Token
2935
cp.APIKey = other.APIKey if other.APIKey != "" else self.APIKey
3036
cp.BaseURL = other.BaseURL if other.BaseURL != "" else self.BaseURL
3137
cp.DefaultModel = other.DefaultModel if other.DefaultModel != "" else self.DefaultModel
@@ -62,13 +68,15 @@ def __init__(self,
6268
location: str = "",
6369
env: list[str] = None,
6470
forceSequential: bool = False,
71+
url: str = "",
72+
token: str = "",
6573
apiKey: str = "",
6674
baseURL: str = "",
6775
defaultModelProvider: str = "",
6876
defaultModel: str = "",
6977
cacheDir: str = "",
7078
):
71-
super().__init__(apiKey, baseURL, defaultModelProvider, defaultModel, cacheDir)
79+
super().__init__(url, token, apiKey, baseURL, defaultModelProvider, defaultModel, cacheDir)
7280
self.input = input
7381
self.disableCache = disableCache
7482
self.subTool = subTool

gptscript/run.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@
1010

1111

1212
class Run:
13-
def __init__(self, subCommand: str, tools: Union[ToolDef | list[ToolDef] | str], opts: Options, gptscriptURL: str,
13+
def __init__(self, subCommand: str, tools: Union[ToolDef | list[ToolDef] | str], opts: Options,
1414
event_handlers: list[Callable[[Self, CallFrame | RunFrame | PromptFrame], Awaitable[None]]] = None):
1515
self.requestPath = subCommand
1616
self.tools = tools
17-
self.gptscriptURL = gptscriptURL
1817
self.event_handlers = event_handlers
1918
self.opts = opts
2019
if self.opts is None:
@@ -78,8 +77,7 @@ def next_chat(self, input: str = "") -> Self:
7877

7978
run = self
8079
if run.state != RunState.Creating:
81-
run = type(self)(self.requestPath, self.tools, self.opts, self.gptscriptURL,
82-
event_handlers=self.event_handlers)
80+
run = type(self)(self.requestPath, self.tools, self.opts, event_handlers=self.event_handlers)
8381

8482
if self.chatState and self._state == RunState.Continue:
8583
# Only update the chat state if the previous run didn't error.
@@ -120,7 +118,16 @@ async def _request(self, tool: Any):
120118
async with httpx.AsyncClient(timeout=httpx.Timeout(15 * 60.0)) as client:
121119
method = "GET" if tool is None else "POST"
122120

123-
async with client.stream(method, self.gptscriptURL + "/" + self.requestPath, json=tool) as resp:
121+
headers = None
122+
if self.opts.Token:
123+
headers = {"Authorization": f"Bearer {self.opts.Token}"}
124+
125+
async with client.stream(
126+
method,
127+
self.opts.URL + "/" + self.requestPath,
128+
json=tool,
129+
headers=headers,
130+
) as resp:
124131
self._resp = resp
125132
self._state = RunState.Running
126133
done = True
@@ -203,8 +210,8 @@ async def aclose(self):
203210

204211

205212
class RunBasicCommand(Run):
206-
def __init__(self, subCommand: str, request_body: Any, gptscriptURL: str):
207-
super().__init__(subCommand, "", Options(), gptscriptURL)
213+
def __init__(self, subCommand: str, request_body: Any, gptscriptURL: str, gptscriptToken: str):
214+
super().__init__(subCommand, "", Options(url=gptscriptURL, token=gptscriptToken))
208215
self.request_body = request_body
209216

210217
def next_chat(self, input: str = "") -> Self:

0 commit comments

Comments
 (0)