fix: preset base-url auto-fill, bootstrap ACP docs, friendlier errors
CI / check (pull_request) Successful in 2m26s
CI / check (pull_request) Successful in 2m26s
- #106: uwf setup --provider <preset> now auto-fills --base-url - #107: bootstrap documents hermes ACP dependency (pip install hermes-agent[acp]) - #107: verify step uses inline hello.yaml instead of missing examples/eval-simple.yaml - #108: workflow name mismatch error suggests how to fix (rename file or change YAML name) Fixes #106, Fixes #107, Fixes #108
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
"@united-workforce/cli": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: preset provider base-url auto-fill, bootstrap ACP docs, friendlier name mismatch error
|
||||||
|
|
||||||
|
- `uwf setup --provider dashscope` now auto-fills `--base-url` from preset list (#106)
|
||||||
|
- Bootstrap guide documents uwf-hermes ACP dependency (`pip install hermes-agent[acp]`) (#107)
|
||||||
|
- Bootstrap verify step uses inline workflow instead of missing `examples/eval-simple.yaml` (#107)
|
||||||
|
- Workflow filename mismatch error now suggests how to fix it (#108)
|
||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
cmdPromptUsage,
|
cmdPromptUsage,
|
||||||
cmdPromptWorkflowAuthoring,
|
cmdPromptWorkflowAuthoring,
|
||||||
} from "./commands/prompt.js";
|
} from "./commands/prompt.js";
|
||||||
import { cmdSetup, cmdSetupInteractive } from "./commands/setup.js";
|
import { cmdSetup, cmdSetupInteractive, resolvePresetBaseUrl } from "./commands/setup.js";
|
||||||
import { cmdStepFork, cmdStepList, cmdStepRead, cmdStepShow } from "./commands/step.js";
|
import { cmdStepFork, cmdStepList, cmdStepRead, cmdStepShow } from "./commands/step.js";
|
||||||
import {
|
import {
|
||||||
cmdThreadCancel,
|
cmdThreadCancel,
|
||||||
@@ -558,10 +558,14 @@ program
|
|||||||
}) => {
|
}) => {
|
||||||
const storageRoot = resolveStorageRoot();
|
const storageRoot = resolveStorageRoot();
|
||||||
runAction(async () => {
|
runAction(async () => {
|
||||||
if (opts.provider && opts.baseUrl && opts.apiKey && opts.model) {
|
// Resolve preset base-url when provider is known but --base-url is omitted
|
||||||
|
const resolvedBaseUrl =
|
||||||
|
opts.baseUrl ??
|
||||||
|
(opts.provider !== undefined ? resolvePresetBaseUrl(opts.provider) : null);
|
||||||
|
if (opts.provider && resolvedBaseUrl && opts.apiKey && opts.model) {
|
||||||
const result = await cmdSetup({
|
const result = await cmdSetup({
|
||||||
provider: opts.provider,
|
provider: opts.provider,
|
||||||
baseUrl: opts.baseUrl,
|
baseUrl: resolvedBaseUrl,
|
||||||
apiKey: opts.apiKey,
|
apiKey: opts.apiKey,
|
||||||
model: opts.model,
|
model: opts.model,
|
||||||
agent: opts.agent ?? undefined,
|
agent: opts.agent ?? undefined,
|
||||||
@@ -572,7 +576,7 @@ program
|
|||||||
await cmdSetupInteractive(storageRoot);
|
await cmdSetupInteractive(storageRoot);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Non-interactive setup requires all of: --provider, --base-url, --api-key, --model",
|
"Non-interactive setup requires: --provider, --api-key, --model (--base-url is optional for preset providers)",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ Install an agent adapter (at least one is required):
|
|||||||
| uwf-claude-code | \`npm install -g @united-workforce/agent-claude-code\` | When using Claude Code CLI directly |
|
| uwf-claude-code | \`npm install -g @united-workforce/agent-claude-code\` | When using Claude Code CLI directly |
|
||||||
| uwf-builtin | \`npm install -g @united-workforce/agent-builtin\` | Lightweight built-in agent (no external dependency) |
|
| uwf-builtin | \`npm install -g @united-workforce/agent-builtin\` | Lightweight built-in agent (no external dependency) |
|
||||||
|
|
||||||
|
**uwf-hermes** also requires the Hermes ACP plugin. After installing \`hermes-agent\`, run:
|
||||||
|
\`\`\`bash
|
||||||
|
pip install hermes-agent[acp] # or: pip install -e .[acp] if installed from source
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
Verify the adapter is installed: \`uwf-hermes --version\` (or whichever you chose).
|
Verify the adapter is installed: \`uwf-hermes --version\` (or whichever you chose).
|
||||||
|
|
||||||
### Step 2 — Configure provider and model
|
### Step 2 — Configure provider and model
|
||||||
@@ -81,20 +86,43 @@ Verify skills are installed by listing them (e.g. \`skills_list()\`) and confirm
|
|||||||
|
|
||||||
### Step 4 — Verify end-to-end
|
### Step 4 — Verify end-to-end
|
||||||
|
|
||||||
Run a quick smoke test with the built-in eval workflow:
|
Create a minimal workflow file to test your setup:
|
||||||
|
|
||||||
\`\`\`bash
|
\`\`\`bash
|
||||||
# Start a thread with the example workflow
|
cat > /tmp/hello.yaml << 'YAML'
|
||||||
uwf thread start examples/eval-simple.yaml -p "Hello, test run"
|
name: hello
|
||||||
|
description: Minimal smoke test
|
||||||
|
roles:
|
||||||
|
greeter:
|
||||||
|
description: "Greet the user"
|
||||||
|
goal: "Respond with a friendly greeting"
|
||||||
|
capabilities: []
|
||||||
|
procedure: "Write a short greeting based on the prompt."
|
||||||
|
output: "A greeting message."
|
||||||
|
frontmatter:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
$status: { enum: [done] }
|
||||||
|
message: { type: string }
|
||||||
|
required: [$status, message]
|
||||||
|
graph:
|
||||||
|
$START:
|
||||||
|
new: { role: greeter, prompt: "Say hello to the user." }
|
||||||
|
resume: { role: greeter, prompt: "Greet the user again." }
|
||||||
|
greeter:
|
||||||
|
done: { role: "$END", prompt: "Done." }
|
||||||
|
YAML
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
# Execute one step
|
Then run:
|
||||||
|
|
||||||
|
\`\`\`bash
|
||||||
|
uwf thread start /tmp/hello.yaml -p "Hello, world!"
|
||||||
uwf thread exec <thread-id>
|
uwf thread exec <thread-id>
|
||||||
|
|
||||||
# Check result
|
|
||||||
uwf thread show <thread-id>
|
uwf thread show <thread-id>
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
If the thread reaches \`$END\` or produces output, the setup is working.
|
If the thread reaches \`$END\` with status \`completed\`, the setup is working.
|
||||||
|
|
||||||
## Scenario B: Upgrade from Previous Version
|
## Scenario B: Upgrade from Previous Version
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,12 @@ const PRESET_PROVIDERS = [
|
|||||||
{ name: "ollama", label: "Ollama (local)", baseUrl: "http://localhost:11434/v1" },
|
{ name: "ollama", label: "Ollama (local)", baseUrl: "http://localhost:11434/v1" },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
/** Look up the base URL for a preset provider name. Returns null if not a preset. */
|
||||||
|
export function resolvePresetBaseUrl(providerName: string): string | null {
|
||||||
|
const preset = PRESET_PROVIDERS.find((p) => p.name === providerName);
|
||||||
|
return preset !== undefined ? preset.baseUrl : null;
|
||||||
|
}
|
||||||
|
|
||||||
type SetupArgs = {
|
type SetupArgs = {
|
||||||
provider: string;
|
provider: string;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ export function checkWorkflowFilenameConsistency(
|
|||||||
): string | null {
|
): string | null {
|
||||||
const expected = workflowNameFromPath(filePath);
|
const expected = workflowNameFromPath(filePath);
|
||||||
if (payload.name !== expected) {
|
if (payload.name !== expected) {
|
||||||
return `workflow name mismatch: file "${basename(filePath)}" implies name "${expected}" but YAML declares name "${payload.name}"`;
|
return `workflow name mismatch: file "${basename(filePath)}" implies name "${expected}" but YAML declares name "${payload.name}". Either rename the file to "${payload.name}.yaml" or change the YAML \`name\` field to "${expected}"`;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user