diff --git a/packages/cli/lib/cli.js b/packages/cli/lib/cli.js index bf4999a..343244f 100644 --- a/packages/cli/lib/cli.js +++ b/packages/cli/lib/cli.js @@ -17,6 +17,14 @@ class InvalidArgumentsError extends Error { } } +export const POST_AUTH_HELP_MESSAGE = `Hi, I’m CALL-E 👋 + +I can help make phone calls, gather information, and handle phone-based tasks like appointments, reservations, follow-ups, and customer service requests. + +Before each call, I’ll confirm the goal and key details with you. Afterward, I’ll share the status, summary, key takeaways, and next steps.`; + +const POST_AUTH_HELP_HINT_TYPE = "post_auth_help"; + function printHelp(stdout) { stdout(`Usage: calle [options] @@ -164,7 +172,18 @@ function assertNoUnexpectedPositional(positional) { } } +function postAuthAssistantHint(status) { + if (status !== "logged_in" && status !== "cached") { + return null; + } + return { + type: POST_AUTH_HELP_HINT_TYPE, + message: POST_AUTH_HELP_MESSAGE, + }; +} + function publicLoginPayload({ config, cachePath, pendingPath, tokenDocument, status }) { + const assistantHint = postAuthAssistantHint(status); return { status, broker_base_url: config.brokerBaseUrl, @@ -172,6 +191,7 @@ function publicLoginPayload({ config, cachePath, pendingPath, tokenDocument, sta cache_path: cachePath, pending_cache_path: pendingPath, expires_at: tokenDocument?.expires_at ?? null, + ...(assistantHint ? { assistant_hint: assistantHint } : {}), }; } diff --git a/packages/cli/test/cli.test.js b/packages/cli/test/cli.test.js index 85c94aa..86a3a9c 100644 --- a/packages/cli/test/cli.test.js +++ b/packages/cli/test/cli.test.js @@ -4,7 +4,7 @@ import path from "node:path"; import test from "node:test"; import assert from "node:assert/strict"; -import { runCli } from "../lib/cli.js"; +import { POST_AUTH_HELP_MESSAGE, runCli } from "../lib/cli.js"; import { pendingCachePath, tokenCachePath, writePrivateJson } from "../lib/cache.js"; import { CLI_VERSION } from "../lib/config.js"; @@ -114,11 +114,40 @@ test("auth login defaults broker payload to openagent_oauth and hides token from const payload = JSON.parse(result.stdout); assert.equal(payload.status, "logged_in"); assert.equal(payload.server_url, "https://mcp.example/mcp/openagent_oauth"); + assert.deepEqual(payload.assistant_hint, { + type: "post_auth_help", + message: POST_AUTH_HELP_MESSAGE, + }); + assert.match(payload.assistant_hint.message, /I can help make phone calls/); const tokenPayload = JSON.parse(fs.readFileSync(tokenCachePath(cacheRoot, payload.server_url), "utf8")); assert.equal(tokenPayload.token.access_token, "secret-token"); assert.equal(fs.existsSync(pendingCachePath(cacheRoot, payload.server_url)), false); }); +test("auth login returns post-auth assistant hint for cached login", async () => { + const cacheRoot = makeTempRoot("calle-cli-cached-login"); + const serverUrl = "https://mcp.example/mcp/openagent_oauth"; + writeToken(cacheRoot, serverUrl, "cached-login-token"); + + const result = await run( + ["auth", "login", "--base-url", "https://mcp.example", "--cache-root", cacheRoot], + { + fetchImpl: async () => { + throw new Error("auth login should not contact broker with a usable cached token"); + }, + } + ); + + assert.equal(result.code, 0); + assert.doesNotMatch(result.stdout, /cached-login-token/); + const payload = JSON.parse(result.stdout); + assert.equal(payload.status, "cached"); + assert.deepEqual(payload.assistant_hint, { + type: "post_auth_help", + message: POST_AUTH_HELP_MESSAGE, + }); +}); + test("auth login forwards upstream integration context from environment", async () => { const cacheRoot = makeTempRoot("calle-cli-login-integration"); const seenHeaders = []; diff --git a/packages/codex-plugin/plugin/skills/calle/SKILL.md b/packages/codex-plugin/plugin/skills/calle/SKILL.md index fd4d344..ffed962 100644 --- a/packages/codex-plugin/plugin/skills/calle/SKILL.md +++ b/packages/codex-plugin/plugin/skills/calle/SKILL.md @@ -82,6 +82,10 @@ when the user asks to verify Call-E setup: 3. If auth is missing or expired, run or suggest `auth login`. 4. After login completes, run `mcp tools`. 5. Confirm that `plan_call`, `run_call`, and `get_call_run` are available. +6. If the successful `auth login` JSON included `assistant_hint.message`, use + it to include a brief post-auth help note in the next user-facing reply + after tool availability is confirmed. Adapt the wording naturally to the + user's language and context. Setup verification must not place a real phone call. Use only help, auth, and tool-listing commands until the user asks for a call workflow. diff --git a/packages/codex-plugin/plugin/skills/calle/references/commands.md b/packages/codex-plugin/plugin/skills/calle/references/commands.md index ee1fd84..c636cae 100644 --- a/packages/codex-plugin/plugin/skills/calle/references/commands.md +++ b/packages/codex-plugin/plugin/skills/calle/references/commands.md @@ -50,6 +50,10 @@ Rules: - If a command returns `auth_required`, run or suggest `auth login`. - If `mcp tools` succeeds, confirm that `plan_call`, `run_call`, and `get_call_run` are present. +- If successful `auth login` output includes `assistant_hint.message`, use it + to include a brief post-auth help note in the next user-facing reply after + `mcp tools` confirms the required tools are present. Adapt the wording + naturally to the user's language and context. - Do not run `call run` during setup verification. - Do not use `.mcp.json`, raw HTTP, or direct remote MCP configuration in this plugin version. diff --git a/packages/codex-plugin/scripts/check-plugin.mjs b/packages/codex-plugin/scripts/check-plugin.mjs index 9dc0ae3..6915a57 100644 --- a/packages/codex-plugin/scripts/check-plugin.mjs +++ b/packages/codex-plugin/scripts/check-plugin.mjs @@ -51,6 +51,11 @@ function checkSkill({ skillName, skillDir, failures }) { const source = fs.readFileSync(skillFile, "utf8"); const frontmatter = extractFrontmatter(source); assert(frontmatter, failures, `${skillFile} must start with YAML frontmatter.`); + assert( + source.includes("assistant_hint.message"), + failures, + `${skillFile} must document how to display assistant_hint.message after auth login.`, + ); if (!frontmatter) { return; diff --git a/packages/codex-plugin/test/check-plugin.test.js b/packages/codex-plugin/test/check-plugin.test.js index fcac8af..a629519 100644 --- a/packages/codex-plugin/test/check-plugin.test.js +++ b/packages/codex-plugin/test/check-plugin.test.js @@ -46,7 +46,7 @@ function createValidFixture(root) { writeFile( path.join(packageRoot, "plugin", "skills", "calle", "SKILL.md"), - "---\nname: calle\ndescription: Test skill.\n---\n\n# calle\n", + "---\nname: calle\ndescription: Test skill.\n---\n\n# calle\n\nUse assistant_hint.message to include a brief post-auth help note after auth login.\n", ); writeFile( path.join(packageRoot, "plugin", "skills", "calle", "agents", "openai.yaml"),