Compare commits
1 Commits
main
...
cat/goose-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d589162d4 |
@ -30,6 +30,10 @@ module "goose" {
|
|||||||
|
|
||||||
The `codercom/oss-dogfood:latest` container image can be used for testing on container-based workspaces.
|
The `codercom/oss-dogfood:latest` container image can be used for testing on container-based workspaces.
|
||||||
|
|
||||||
|
### Session Resumption Behavior
|
||||||
|
|
||||||
|
By default, Goose automatically resumes workspace-specific sessions when your workspace restarts. Sessions are named `task-{workspace_name}`, ensuring each workspace maintains its own conversation history. If no session exists (first start), your task prompt will run normally. To disable this and always start fresh, set `continue = false`.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### Run in the background and report tasks
|
### Run in the background and report tasks
|
||||||
|
|||||||
@ -291,4 +291,92 @@ describe("goose", async () => {
|
|||||||
expect(agentapiMockOutput).toMatch(/AGENTAPI_CHAT_BASE_PATH=$/m);
|
expect(agentapiMockOutput).toMatch(/AGENTAPI_CHAT_BASE_PATH=$/m);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("session management", async () => {
|
||||||
|
test("session-name-new", async () => {
|
||||||
|
const { id } = await setup({
|
||||||
|
agentapiMockScript: await loadTestFile(
|
||||||
|
import.meta.dir,
|
||||||
|
"agentapi-mock-print-args.js",
|
||||||
|
),
|
||||||
|
moduleVariables: {
|
||||||
|
session_name: "my-custom-session",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await execModuleScript(id);
|
||||||
|
|
||||||
|
const agentapiMockOutput = await readFileContainer(id, agentapiStartLog);
|
||||||
|
expect(agentapiMockOutput).toContain("Session name: my-custom-session");
|
||||||
|
expect(agentapiMockOutput).toContain("Starting new named session: my-custom-session");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("session-name-resume", async () => {
|
||||||
|
const { id } = await setup({
|
||||||
|
agentapiMockScript: await loadTestFile(
|
||||||
|
import.meta.dir,
|
||||||
|
"agentapi-mock-print-args.js",
|
||||||
|
),
|
||||||
|
moduleVariables: {
|
||||||
|
session_name: "existing-session",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await execContainer(id, [
|
||||||
|
"bash",
|
||||||
|
"-c",
|
||||||
|
dedent`
|
||||||
|
cat > /usr/bin/goose <<'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
if [ "$1" = "session" ] && [ "$2" = "list" ] && [ "$3" = "--format" ] && [ "$4" = "json" ]; then
|
||||||
|
echo '[{"id":"test123","name":"existing-session"}]'
|
||||||
|
else
|
||||||
|
echo "goose mock"
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
chmod +x /usr/bin/goose
|
||||||
|
`,
|
||||||
|
]);
|
||||||
|
|
||||||
|
await execModuleScript(id);
|
||||||
|
|
||||||
|
const agentapiMockOutput = await readFileContainer(id, agentapiStartLog);
|
||||||
|
expect(agentapiMockOutput).toContain("Resuming session by name: existing-session");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("default-session-name", async () => {
|
||||||
|
const { id } = await setup({
|
||||||
|
agentapiMockScript: await loadTestFile(
|
||||||
|
import.meta.dir,
|
||||||
|
"agentapi-mock-print-args.js",
|
||||||
|
),
|
||||||
|
moduleVariables: {
|
||||||
|
continue: "true",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await execModuleScript(id);
|
||||||
|
|
||||||
|
const agentapiMockOutput = await readFileContainer(id, agentapiStartLog);
|
||||||
|
expect(agentapiMockOutput).toContain("Session name: task-");
|
||||||
|
expect(agentapiMockOutput).toContain("Starting new session:");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("continue-disabled", async () => {
|
||||||
|
const { id } = await setup({
|
||||||
|
agentapiMockScript: await loadTestFile(
|
||||||
|
import.meta.dir,
|
||||||
|
"agentapi-mock-print-args.js",
|
||||||
|
),
|
||||||
|
moduleVariables: {
|
||||||
|
continue: "false",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await execModuleScript(id);
|
||||||
|
|
||||||
|
const agentapiMockOutput = await readFileContainer(id, agentapiStartLog);
|
||||||
|
expect(agentapiMockOutput).toContain("Continue disabled, starting fresh session");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -100,8 +100,21 @@ variable "additional_extensions" {
|
|||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "session_name" {
|
||||||
|
type = string
|
||||||
|
description = "Name for the Goose session. If empty, uses 'task-{workspace_name}' for automatic workspace-specific session naming."
|
||||||
|
default = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "continue" {
|
||||||
|
type = bool
|
||||||
|
description = "Automatically continue existing sessions on workspace restart. When true, resumes session by name if it exists, otherwise starts new named session. When false, always starts fresh."
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
app_slug = "goose"
|
app_slug = "goose"
|
||||||
|
default_session_name = "task-${data.coder_workspace.me.name}"
|
||||||
base_extensions = <<-EOT
|
base_extensions = <<-EOT
|
||||||
coder:
|
coder:
|
||||||
args:
|
args:
|
||||||
@ -156,8 +169,20 @@ module "agentapi" {
|
|||||||
agentapi_subdomain = var.subdomain
|
agentapi_subdomain = var.subdomain
|
||||||
pre_install_script = var.pre_install_script
|
pre_install_script = var.pre_install_script
|
||||||
post_install_script = var.post_install_script
|
post_install_script = var.post_install_script
|
||||||
start_script = local.start_script
|
|
||||||
folder = local.folder
|
folder = local.folder
|
||||||
|
start_script = <<-EOT
|
||||||
|
#!/bin/bash
|
||||||
|
set -o errexit
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
echo -n '${base64encode(local.start_script)}' | base64 -d > /tmp/start.sh
|
||||||
|
chmod +x /tmp/start.sh
|
||||||
|
|
||||||
|
ARG_SESSION_NAME='${var.session_name}' \
|
||||||
|
ARG_DEFAULT_SESSION_NAME='${local.default_session_name}' \
|
||||||
|
ARG_CONTINUE='${var.continue}' \
|
||||||
|
/tmp/start.sh
|
||||||
|
EOT
|
||||||
install_script = <<-EOT
|
install_script = <<-EOT
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -o errexit
|
set -o errexit
|
||||||
|
|||||||
105
registry/coder/modules/goose/main.tftest.hcl
Normal file
105
registry/coder/modules/goose/main.tftest.hcl
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
run "test_goose_basic" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
variables {
|
||||||
|
agent_id = "test-agent-123"
|
||||||
|
goose_provider = "anthropic"
|
||||||
|
goose_model = "claude-3-5-sonnet-latest"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = var.goose_provider == "anthropic"
|
||||||
|
error_message = "Goose provider variable should be set correctly"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = var.goose_model == "claude-3-5-sonnet-latest"
|
||||||
|
error_message = "Goose model variable should be set correctly"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = var.install_goose == true
|
||||||
|
error_message = "Install goose should default to true"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = var.install_agentapi == true
|
||||||
|
error_message = "Install agentapi should default to true"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = var.continue == true
|
||||||
|
error_message = "Continue should default to true"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
run "test_goose_with_session_name" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
variables {
|
||||||
|
agent_id = "test-agent-456"
|
||||||
|
goose_provider = "anthropic"
|
||||||
|
goose_model = "claude-3-5-sonnet-latest"
|
||||||
|
session_name = "my-custom-session"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = var.session_name == "my-custom-session"
|
||||||
|
error_message = "Session name should be set to my-custom-session"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run "test_goose_continue_disabled" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
variables {
|
||||||
|
agent_id = "test-agent-789"
|
||||||
|
goose_provider = "anthropic"
|
||||||
|
goose_model = "claude-3-5-sonnet-latest"
|
||||||
|
continue = false
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = var.continue == false
|
||||||
|
error_message = "Continue should be set to false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run "test_goose_default_session_name" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
variables {
|
||||||
|
agent_id = "test-agent-101"
|
||||||
|
goose_provider = "anthropic"
|
||||||
|
goose_model = "claude-3-5-sonnet-latest"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = length(regexall("task-", local.default_session_name)) > 0
|
||||||
|
error_message = "Default session name should contain task- prefix"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run "test_goose_with_additional_extensions" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
variables {
|
||||||
|
agent_id = "test-agent-202"
|
||||||
|
goose_provider = "anthropic"
|
||||||
|
goose_model = "claude-3-5-sonnet-latest"
|
||||||
|
additional_extensions = <<-EOT
|
||||||
|
custom-extension:
|
||||||
|
enabled: true
|
||||||
|
name: custom
|
||||||
|
timeout: 300
|
||||||
|
type: builtin
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = var.additional_extensions != null
|
||||||
|
error_message = "Additional extensions should be set"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -16,19 +16,51 @@ else
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# this must be kept up to date with main.tf
|
|
||||||
MODULE_DIR="$HOME/.goose-module"
|
MODULE_DIR="$HOME/.goose-module"
|
||||||
mkdir -p "$MODULE_DIR"
|
mkdir -p "$MODULE_DIR"
|
||||||
|
|
||||||
if [ ! -z "$GOOSE_TASK_PROMPT" ]; then
|
ARG_SESSION_NAME=${ARG_SESSION_NAME:-}
|
||||||
echo "Starting with a prompt"
|
ARG_DEFAULT_SESSION_NAME=${ARG_DEFAULT_SESSION_NAME:-}
|
||||||
|
ARG_CONTINUE=${ARG_CONTINUE:-true}
|
||||||
|
|
||||||
|
if [ -n "$ARG_SESSION_NAME" ]; then
|
||||||
|
SESSION_NAME="$ARG_SESSION_NAME"
|
||||||
|
else
|
||||||
|
SESSION_NAME="$ARG_DEFAULT_SESSION_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Session name: $SESSION_NAME"
|
||||||
|
|
||||||
|
session_name_exists() {
|
||||||
|
local name=$1
|
||||||
|
"$GOOSE_CMD" session list --format json 2>/dev/null | grep -q "\"name\":[[:space:]]*\"$name\""
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$ARG_CONTINUE" = "true" ]; then
|
||||||
|
if session_name_exists "$SESSION_NAME"; then
|
||||||
|
echo "Resuming session: $SESSION_NAME"
|
||||||
|
GOOSE_ARGS=(session --resume --name "$SESSION_NAME")
|
||||||
|
else
|
||||||
|
echo "Starting new session: $SESSION_NAME"
|
||||||
|
if [ -n "$GOOSE_TASK_PROMPT" ]; then
|
||||||
|
PROMPT="Review your goosehints. Every step of the way, report tasks to Coder with proper descriptions and statuses. Your task at hand: $GOOSE_TASK_PROMPT"
|
||||||
|
PROMPT_FILE="$MODULE_DIR/prompt.txt"
|
||||||
|
echo -n "$PROMPT" > "$PROMPT_FILE"
|
||||||
|
GOOSE_ARGS=(run --interactive --name "$SESSION_NAME" --instructions "$PROMPT_FILE")
|
||||||
|
else
|
||||||
|
GOOSE_ARGS=(session --name "$SESSION_NAME")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Continue disabled, starting fresh session"
|
||||||
|
if [ -n "$GOOSE_TASK_PROMPT" ]; then
|
||||||
PROMPT="Review your goosehints. Every step of the way, report tasks to Coder with proper descriptions and statuses. Your task at hand: $GOOSE_TASK_PROMPT"
|
PROMPT="Review your goosehints. Every step of the way, report tasks to Coder with proper descriptions and statuses. Your task at hand: $GOOSE_TASK_PROMPT"
|
||||||
PROMPT_FILE="$MODULE_DIR/prompt.txt"
|
PROMPT_FILE="$MODULE_DIR/prompt.txt"
|
||||||
echo -n "$PROMPT" > "$PROMPT_FILE"
|
echo -n "$PROMPT" > "$PROMPT_FILE"
|
||||||
GOOSE_ARGS=(run --interactive --instructions "$PROMPT_FILE")
|
GOOSE_ARGS=(run --interactive --instructions "$PROMPT_FILE")
|
||||||
else
|
else
|
||||||
echo "Starting without a prompt"
|
GOOSE_ARGS=(session)
|
||||||
GOOSE_ARGS=()
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
agentapi server --term-width 67 --term-height 1190 -- \
|
agentapi server --term-width 67 --term-height 1190 -- \
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user