@@ -30,8 +30,8 @@ create() {
30
30
set -e
31
31
32
32
if [[" ${TASK_NAME} " == $( jq -r' .name' <<< " ${task_json}" ) ]]; then
33
- # TODO(Cian): Send PROMPT to the agent in the existingworkspace.
34
- echo " Task \" ${TASK_NAME} \" already exists. "
33
+ echo " Task \" ${TASK_NAME} \" already exists. Sending prompt to existingtask. "
34
+ prompt
35
35
exit 0
36
36
fi
37
37
@@ -67,193 +67,55 @@ ssh_config() {
67
67
}
68
68
69
69
prompt () {
70
- requiredenvs CODER_URL CODER_SESSION_TOKEN TASK_NAME APP_SLUG PROMPT
71
-
72
- wait_agentapi_stable
73
-
74
- username=$( curl \
75
- --fail \
76
- --header" Coder-Session-Token:${CODER_SESSION_TOKEN} " \
77
- --location \
78
- --show-error \
79
- --silent \
80
- " ${CODER_URL} /api/v2/users/me" | jq -r' .username' )
81
-
82
- payload=" {
83
- \" content\" :\" ${PROMPT} \" ,
84
- \" type\" :\" user\"
85
- }"
86
-
87
- response=$( curl \
88
- --data-raw" ${payload} " \
89
- --fail \
90
- --header" Content-Type: application/json" \
91
- --header" Coder-Session-Token:${CODER_SESSION_TOKEN} " \
92
- --location \
93
- --request POST \
94
- --show-error \
95
- --silent \
96
- " ${CODER_URL} /@${username} /${TASK_NAME} /apps/${APP_SLUG} /message" | jq -r' .ok' )
97
- if [[" ${response} " != " true" ]]; then
98
- echo " Failed to send prompt"
99
- exit 1
100
- fi
70
+ requiredenvs CODER_URL CODER_SESSION_TOKEN TASK_NAME PROMPT
101
71
102
- # Wait for agentapi to process the response and return the last agent message
103
- wait_agentapi_stable
72
+ ${CODER_BIN} \
73
+ --url" ${CODER_URL} " \
74
+ --token" ${CODER_SESSION_TOKEN} " \
75
+ exp tasks status" ${TASK_NAME} " \
76
+ --watch> /dev/null
104
77
105
- CODER_USERNAME=" ${username} " last_message
78
+ ${CODER_BIN} \
79
+ --url" ${CODER_URL} " \
80
+ --token" ${CODER_SESSION_TOKEN} " \
81
+ exp tasks send" ${TASK_NAME} " \
82
+ --stdin \
83
+ <<< " ${PROMPT}"
84
+
85
+ ${CODER_BIN} \
86
+ --url" ${CODER_URL} " \
87
+ --token" ${CODER_SESSION_TOKEN} " \
88
+ exp tasks status" ${TASK_NAME} " \
89
+ --watch> /dev/null
90
+
91
+ last_message
106
92
}
107
93
108
94
last_message () {
109
- requiredenvs CODER_URL CODER_SESSION_TOKEN CODER_USERNAME TASK_NAME APP_SLUG PROMPT
110
- last_msg=$( curl \
111
- --fail \
112
- --header" Content-Type: application/json" \
113
- --header" Coder-Session-Token:${CODER_SESSION_TOKEN} " \
114
- --location \
115
- --show-error \
116
- --silent \
117
- " ${CODER_URL} /@${CODER_USERNAME} /${TASK_NAME} /apps/${APP_SLUG} /messages" |
118
- jq -r' last(.messages[] | select(.role=="agent") | [.])' )
95
+ requiredenvs CODER_URL CODER_SESSION_TOKEN TASK_NAME PROMPT
119
96
97
+ last_msg_json=$(
98
+ ${CODER_BIN} \
99
+ --url" ${CODER_URL} " \
100
+ --token" ${CODER_SESSION_TOKEN} " \
101
+ exp tasks logs" ${TASK_NAME} " \
102
+ --output json
103
+ )
104
+ last_output_msg=$( jq -r' last(.[] | select(.type=="output")) | .content' <<< " ${last_msg_json}" )
105
+ # HACK: agentapi currently doesn't split multiple messages, so you can end up with tool
106
+ # call responses in the output.
107
+ last_msg=$( tac<<< " ${last_output_msg}" | sed' /^● /q' | tr -d' ●' | tac)
120
108
echo " ${last_msg} "
121
109
}
122
110
123
111
wait_agentapi_stable () {
124
- requiredenvs CODER_URL CODER_SESSION_TOKEN TASK_NAME APP_SLUG
125
- username=$( curl \
126
- --fail \
127
- --header" Coder-Session-Token:${CODER_SESSION_TOKEN} " \
128
- --location \
129
- --show-error \
130
- --silent \
131
- " ${CODER_URL} /api/v2/users/me" | jq -r' .username' )
132
-
133
- for attempt in {1..120}; do
134
- # First wait for task to start
135
- set +o pipefail
136
- task_status=$( " ${CODER_BIN} " \
137
- --url" ${CODER_URL} " \
138
- --token" ${CODER_SESSION_TOKEN} " \
139
- exp tasks status" ${TASK_NAME} " \
140
- --output json|
141
- jq -r' .status' )
142
- set -o pipefail
143
- echo " Task status is${task_status} "
144
- if [[" ${task_status} " == " running" ]]; then
145
- echo " Task is running"
146
- break
147
- fi
148
- echo " Waiting for task status to be running (attempt${attempt} /120)"
149
- sleep 5
150
- done
151
-
152
- for attempt in {1..120}; do
153
- # Workspace agent must be healthy
154
- set +o pipefail
155
- healthy=$( " ${CODER_BIN} " \
156
- --url" ${CODER_URL} " \
157
- --token" ${CODER_SESSION_TOKEN} " \
158
- exp tasks status" ${TASK_NAME} " \
159
- --output json|
160
- jq -r' .workspace_agent_health.healthy' )
161
- set -o pipefail
162
- if [[" ${healthy} " == " true" ]]; then
163
- echo " Workspace agent is healthy"
164
- break
165
- fi
166
- echo " Workspace agent not yet healthy (attempt${attempt} /120)"
167
- sleep 5
168
- done
169
-
170
- for attempt in {1..120}; do
171
- # AgentAPI application should not be 404'ing
172
- agentapi_app_status_code=$( curl \
173
- --header" Content-Type: application/json" \
174
- --header" Coder-Session-Token:${CODER_SESSION_TOKEN} " \
175
- --location \
176
- --request GET \
177
- --show-error \
178
- --silent \
179
- --output /dev/null \
180
- --write-out' %{http_code}' \
181
- " ${CODER_URL} /@${username} /${TASK_NAME} /apps/${APP_SLUG} /status" )
182
- echo " Workspace app${APP_SLUG} returned${agentapi_app_status_code} "
183
- if [[" ${agentapi_app_status_code} " == " 200" ]]; then
184
- echo " AgentAPI is running"
185
- break
186
- fi
187
- echo " AgentAPI not yet running (attempt${attempt} /120)"
188
- sleep 5
189
- done
190
-
191
- for attempt in {1..120}; do
192
- # AgentAPI must be stable
193
- set +o pipefail
194
- agentapi_status=$( curl \
195
- --header" Content-Type: application/json" \
196
- --header" Coder-Session-Token:${CODER_SESSION_TOKEN} " \
197
- --location \
198
- --request GET \
199
- --show-error \
200
- --silent \
201
- " ${CODER_URL} /@${username} /${TASK_NAME} /apps/${APP_SLUG} /status" | jq -r' .status' )
202
- set -o pipefail
203
- if [[" ${agentapi_status} " == " stable" ]]; then
204
- echo " AgentAPI stable"
205
- break
206
- fi
207
- echo " Waiting for AgentAPI to report stable status (attempt${attempt} /120)"
208
- sleep 5
209
- done
210
-
211
- # At this point the task is running, the workspace agent is healthy,
212
- # the AgentAPI app is running and the AgentAPI reports stable status.
213
- # Now we wait for the Task Agent to report 'idle', 'complete', or 'failure'.
214
- for attempt in {1..120}; do
215
- task_json=$( ${CODER_BIN} \
216
- --url" ${CODER_URL} " \
217
- --token" ${CODER_SESSION_TOKEN} " \
218
- exp tasks status" ${TASK_NAME} " \
219
- --output json)
220
- set +o pipefail
221
- current_state=$( jq -r' .current_state.state' <<< " ${task_json}" )
222
- current_message=$( jq -r' .current_state.message' <<< " ${task_json}" )
223
- set -o pipefail
224
-
225
- # The current_state or current_message may be null if the Task Agent
226
- # has not yet reported its status.
227
- if [[-z " ${current_state} " ]]|| [[-z " ${current_message} " ]]; then
228
- echo " Waiting for Task Agent to report state (attempt${attempt} /120)"
229
- sleep 5
230
- continue
231
- fi
232
- break
233
- done
234
-
235
- # Finally, wait for the Task Agent to report 'idle', 'complete', or 'failure'. This is unbounded, as we don't know how long the agent will take.
236
- while true ; do
237
- task_json=$( ${CODER_BIN} \
238
- --url" ${CODER_URL} " \
239
- --token" ${CODER_SESSION_TOKEN} " \
240
- exp tasks status" ${TASK_NAME} " \
241
- --output json)
242
- set +o pipefail
243
-
244
- current_state=$( jq -r' .current_state.state' <<< " ${task_json}" )
245
- current_message=$( jq -r' .current_state.message' <<< " ${task_json}" )
246
- set -o pipefail
247
- if [[" ${current_state} " == " working" ]]; then
248
- echo " Task Agent is${current_state} and reports:\" ${current_message} \" "
249
- echo " Waiting for Task Agent to report idle state (attempt${attempt} /120)"
250
- sleep 5
251
- continue
252
- else
253
- echo " Task Agent is${current_state} and reports:\" ${current_message} \" "
254
- break
255
- fi
256
- done
112
+ requiredenvs CODER_URL CODER_SESSION_TOKEN TASK_NAME
113
+
114
+ ${CODER_BIN} \
115
+ --url" ${CODER_URL} " \
116
+ --token" ${CODER_SESSION_TOKEN} " \
117
+ exp tasks status" ${TASK_NAME} " \
118
+ --watch
257
119
}
258
120
259
121
archive () {
@@ -287,7 +149,7 @@ archive() {
287
149
}
288
150
289
151
summary () {
290
- requiredenvs CODER_URL CODER_SESSION_TOKEN TASK_NAME APP_SLUG
152
+ requiredenvs CODER_URL CODER_SESSION_TOKEN TASK_NAME
291
153
ssh_config
292
154
293
155
# We want the heredoc to be expanded locally and not remotely.