Skip to content
Open
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
48 changes: 33 additions & 15 deletions src/handlers/harness/create/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,77 +16,95 @@ import { JsonRendererKey } from "../../../tui";
import { InputValidationError } from "../../../errors";
import { parameterHelp } from "../parameterHelp.tsx";

const CONFIGURATION = "Configuration:";
const AGENT = "Agent:";
const COMPUTE = "Compute environment:";
const ACCESS = "Access:";
const LIMITS = "Limits:";

export const createCreateHarnessHandler = (core: Core) =>
createHandler({
name: "create",
description: "create a harness",
flags: [
flag("name", "the name of the harness", z.string().optional(), { help: parameterHelp.name }),
flag("name", "the name of the harness", z.string().optional(), {
group: CONFIGURATION,
}),
flag(
"execution-role-arn",
"IAM role the harness assumes; a default role is created when omitted",
z.string().optional(),
{ help: parameterHelp.executionRoleArn },
{ group: CONFIGURATION },
),
flag("tags", "tags to apply (JSON object of key/value strings)", z.string().optional(), {
help: parameterHelp.tags,
group: CONFIGURATION,
}),
flag("system-prompt", "the agent's system prompt", z.string().optional(), {
help: parameterHelp.systemPrompt,
group: AGENT,
}),
flag("model", "model configuration (JSON HarnessModelConfiguration)", z.string().optional(), {
help: parameterHelp.model,
group: AGENT,
}),
flag("tools", "tools available to the agent (JSON HarnessTool[])", z.string().optional(), {
help: parameterHelp.tools,
group: AGENT,
}),
flag("skills", "skills available to the agent (JSON HarnessSkill[])", z.string().optional(), {
help: parameterHelp.skills,
group: AGENT,
}),
flag(
"allowed-tools",
"tool allowlist patterns (e.g. * or @serverName/toolName)",
z.array(z.string()).optional(),
{ help: parameterHelp.allowedTools },
{ help: parameterHelp.allowedTools, group: AGENT },
),
flag(
"memory",
"memory configuration (JSON HarnessMemoryConfiguration)",
z.string().optional(),
{ help: parameterHelp.memory },
{ help: parameterHelp.memory, group: AGENT },
),
flag(
"truncation",
"context truncation configuration (JSON HarnessTruncationConfiguration)",
z.string().optional(),
{ help: parameterHelp.truncation },
{ help: parameterHelp.truncation, group: AGENT },
),
flag(
"environment",
"compute environment configuration (JSON HarnessEnvironmentProviderRequest)",
z.string().optional(),
{ help: parameterHelp.environment },
{ help: parameterHelp.environment, group: COMPUTE },
),
flag(
"environment-artifact",
"environment artifact, e.g. a container image (JSON HarnessEnvironmentArtifact)",
z.string().optional(),
{ help: parameterHelp.environmentArtifact },
{ help: parameterHelp.environmentArtifact, group: COMPUTE },
),
flag(
"environment-variables",
"environment variables (JSON object of key/value strings)",
z.string().optional(),
{ help: parameterHelp.environmentVariables },
{ help: parameterHelp.environmentVariables, group: COMPUTE },
),
flag(
"authorizer-configuration",
"inbound authorizer configuration (JSON AuthorizerConfiguration)",
z.string().optional(),
{ help: parameterHelp.authorizerConfiguration },
{ help: parameterHelp.authorizerConfiguration, group: ACCESS },
),
flag("max-iterations", "max agent loop iterations per invocation", z.number().optional()),
flag("max-tokens", "max total output tokens per invocation", z.number().optional()),
flag("timeout-seconds", "max duration in seconds per invocation", z.number().optional()),
flag("tags", "tags to apply (JSON object of key/value strings)", z.string().optional(), {
help: parameterHelp.tags,
flag("max-iterations", "max agent loop iterations per invocation", z.number().optional(), {
group: LIMITS,
}),
flag("max-tokens", "max total output tokens per invocation", z.number().optional(), {
group: LIMITS,
}),
flag("timeout-seconds", "max duration in seconds per invocation", z.number().optional(), {
group: LIMITS,
}),
],
handle: async (ctx, flags) => {
Expand Down
8 changes: 6 additions & 2 deletions src/handlers/harness/logs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ import { createLogsHandler } from "../../observability/logs";
import type { Core } from "../../types";
import { coreOptsFromCtx } from "../../utils";

const LOG_SOURCE = "Log source:";

const harnessFlags = [
flag("id", "the ID of the harness", z.string().min(1).max(48)),
flag("qualifier", "the harness endpoint qualifier", z.string().min(1).optional()),
flag("id", "the ID of the harness", z.string().min(1).max(48), { group: LOG_SOURCE }),
flag("qualifier", "the harness endpoint qualifier", z.string().min(1).optional(), {
group: LOG_SOURCE,
}),
] as const;

export const createHarnessLogsHandler = (core: Core, io: AppIO) =>
Expand Down
26 changes: 0 additions & 26 deletions src/handlers/harness/parameterHelp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,6 @@
// enclosing object, not on the command line.

export const parameterHelp = {
name: `(string)
The name of the harness. Must start with a letter and contain only
alphanumeric characters and underscores.

Pattern: [a-zA-Z][a-zA-Z0-9_]{0,39}`,

executionRoleArn: `(string)
The ARN of the IAM role the harness assumes when running. The role must
trust bedrock-agentcore.amazonaws.com and have permissions for the services
the agent needs (Bedrock model invocation, CloudWatch Logs, built-in tools,
memory, ...).

When omitted, the CLI provisions a default per-harness role named
AgentCoreHarness-<name> with the baseline policy and uses it.

Example:
--execution-role-arn arn:aws:iam::123456789012:role/MyHarnessRole`,

systemPrompt: `(string)
The system prompt that defines the agent's behavior and instructions. The
CLI wraps the string into the API's content-block list ([{"text": ...}])
for you.

Example:
--system-prompt 'You are a concise research assistant.'`,

model: `(JSON: tagged union object)
The model configuration for the harness. Supports Amazon Bedrock, OpenAI,
Google Gemini, and LiteLLM providers. Exactly one of the following top-level
Expand Down
45 changes: 32 additions & 13 deletions src/handlers/harness/update/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,87 +24,106 @@ function updated<T>(value: T | undefined, clear: boolean): { optionalValue?: T }
return value !== undefined ? { optionalValue: value } : undefined;
}

const AGENT = "Agent:";
const COMPUTE = "Compute environment:";
const ACCESS = "Access:";
const LIMITS = "Limits:";

export const createUpdateHarnessHandler = (core: Core) =>
createHandler({
name: "update",
description: "update a harness (creates a new version)",
flags: [
flag("id", "the ID of the harness to update", z.string().max(48).optional()),
flag("id", "the ID of the harness to update", z.string().max(48).optional(), {
group: "Target:",
}),
flag("execution-role-arn", "IAM role the harness assumes", z.string().optional(), {
help: parameterHelp.executionRoleArn,
group: "Configuration:",
}),
flag("system-prompt", "the agent's system prompt", z.string().optional(), {
help: parameterHelp.systemPrompt,
group: AGENT,
}),
flag("model", "model configuration (JSON HarnessModelConfiguration)", z.string().optional(), {
help: parameterHelp.model,
group: AGENT,
}),
flag("tools", "tools available to the agent (JSON HarnessTool[])", z.string().optional(), {
help: parameterHelp.tools,
group: AGENT,
}),
flag("skills", "skills available to the agent (JSON HarnessSkill[])", z.string().optional(), {
help: parameterHelp.skills,
group: AGENT,
}),
flag(
"allowed-tools",
"tool allowlist patterns (e.g. * or @serverName/toolName)",
z.array(z.string()).optional(),
{ help: parameterHelp.allowedTools },
{ help: parameterHelp.allowedTools, group: AGENT },
),
flag(
"memory",
"memory configuration (JSON HarnessMemoryConfiguration)",
z.string().optional(),
{ help: parameterHelp.memory },
{ help: parameterHelp.memory, group: AGENT },
),
flag(
"clear-memory",
"clear the memory configuration (pass true)",
z.enum(["true", "false"]).optional(),
{ group: AGENT },
),
flag(
"truncation",
"context truncation configuration (JSON HarnessTruncationConfiguration)",
z.string().optional(),
{ help: parameterHelp.truncation },
{ help: parameterHelp.truncation, group: AGENT },
),
flag(
"environment",
"compute environment configuration (JSON HarnessEnvironmentProviderRequest)",
z.string().optional(),
{ help: parameterHelp.environment },
{ help: parameterHelp.environment, group: COMPUTE },
),
flag(
"environment-artifact",
"environment artifact, e.g. a container image (JSON HarnessEnvironmentArtifact)",
z.string().optional(),
{ help: parameterHelp.environmentArtifact },
{ help: parameterHelp.environmentArtifact, group: COMPUTE },
),
flag(
"clear-environment-artifact",
"clear the environment artifact (pass true)",
z.enum(["true", "false"]).optional(),
{ group: COMPUTE },
),
flag(
"environment-variables",
"environment variables (JSON object; replaces all existing)",
z.string().optional(),
{ help: parameterHelp.environmentVariables },
{ help: parameterHelp.environmentVariables, group: COMPUTE },
),
flag(
"authorizer-configuration",
"inbound authorizer configuration (JSON AuthorizerConfiguration)",
z.string().optional(),
{ help: parameterHelp.authorizerConfiguration },
{ help: parameterHelp.authorizerConfiguration, group: ACCESS },
),
flag(
"clear-authorizer-configuration",
"clear the authorizer configuration (pass true)",
z.enum(["true", "false"]).optional(),
{ group: ACCESS },
),
flag("max-iterations", "max agent loop iterations per invocation", z.number().optional()),
flag("max-tokens", "max total output tokens per invocation", z.number().optional()),
flag("timeout-seconds", "max duration in seconds per invocation", z.number().optional()),
flag("max-iterations", "max agent loop iterations per invocation", z.number().optional(), {
group: LIMITS,
}),
flag("max-tokens", "max total output tokens per invocation", z.number().optional(), {
group: LIMITS,
}),
flag("timeout-seconds", "max duration in seconds per invocation", z.number().optional(), {
group: LIMITS,
}),
],
handle: async (ctx, flags) => {
// Required at runtime but declared optional so that a bare
Expand Down
14 changes: 11 additions & 3 deletions src/handlers/observability/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,32 @@ const levelSchema = z
)
.optional();

const TIME_WINDOW = "Time window:";
const FILTERING = "Filtering:";

const logFlags = [
flag(
"since",
'search window start: "5m", "1h", ISO 8601, epoch ms, or "now"',
z.string().min(1).optional(),
{ group: TIME_WINDOW },
),
flag(
"until",
'search window end: "5m", "1h", ISO 8601, epoch ms, or "now"',
z.string().min(1).optional(),
{ group: TIME_WINDOW },
),
flag("tail", "tail new log records", z.boolean().default(false)),
flag("level", `filter by log level (${LOG_LEVELS.join(", ")})`, levelSchema),
flag("query", "CloudWatch Logs filter pattern", z.string().optional()),
flag("tail", "tail new log records", z.boolean().default(false), { group: TIME_WINDOW }),
flag("level", `filter by log level (${LOG_LEVELS.join(", ")})`, levelSchema, {
group: FILTERING,
}),
flag("query", "CloudWatch Logs filter pattern", z.string().optional(), { group: FILTERING }),
flag(
"limit",
"maximum number of log records to return in search mode",
z.number().int().positive().optional(),
{ group: FILTERING },
),
] as const;

Expand Down
Loading
Loading