@wiro-ai/wiro-mcp 1.4.1 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -15
- package/dist/client.d.ts +19 -6
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +44 -27
- package/dist/client.js.map +1 -1
- package/dist/instructions.d.ts.map +1 -1
- package/dist/instructions.js +7 -4
- package/dist/instructions.js.map +1 -1
- package/dist/playbooks.d.ts.map +1 -1
- package/dist/playbooks.js +46 -35
- package/dist/playbooks.js.map +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +3 -2
- package/dist/prompts.js.map +1 -1
- package/dist/tools/apply-agent-skills.d.ts.map +1 -1
- package/dist/tools/apply-agent-skills.js +458 -109
- package/dist/tools/apply-agent-skills.js.map +1 -1
- package/dist/tools/bind-agent-project.d.ts +4 -0
- package/dist/tools/bind-agent-project.d.ts.map +1 -0
- package/dist/tools/bind-agent-project.js +405 -0
- package/dist/tools/bind-agent-project.js.map +1 -0
- package/dist/tools/cancel-agent-message.d.ts.map +1 -1
- package/dist/tools/cancel-agent-message.js +6 -3
- package/dist/tools/cancel-agent-message.js.map +1 -1
- package/dist/tools/cancel-task.js +3 -3
- package/dist/tools/cancel-task.js.map +1 -1
- package/dist/tools/clone-workflow.d.ts.map +1 -1
- package/dist/tools/clone-workflow.js +5 -4
- package/dist/tools/clone-workflow.js.map +1 -1
- package/dist/tools/connect-agent-oauth.d.ts.map +1 -1
- package/dist/tools/connect-agent-oauth.js +161 -40
- package/dist/tools/connect-agent-oauth.js.map +1 -1
- package/dist/tools/control-agent.d.ts.map +1 -1
- package/dist/tools/control-agent.js +109 -36
- package/dist/tools/control-agent.js.map +1 -1
- package/dist/tools/create-workflow.d.ts +3 -0
- package/dist/tools/create-workflow.d.ts.map +1 -1
- package/dist/tools/create-workflow.js +12 -11
- package/dist/tools/create-workflow.js.map +1 -1
- package/dist/tools/delete-agent-session.d.ts.map +1 -1
- package/dist/tools/delete-agent-session.js +18 -12
- package/dist/tools/delete-agent-session.js.map +1 -1
- package/dist/tools/delete-agent.d.ts.map +1 -1
- package/dist/tools/delete-agent.js +12 -9
- package/dist/tools/delete-agent.js.map +1 -1
- package/dist/tools/delete-workflow.d.ts.map +1 -1
- package/dist/tools/delete-workflow.js +5 -4
- package/dist/tools/delete-workflow.js.map +1 -1
- package/dist/tools/deploy-agent.d.ts.map +1 -1
- package/dist/tools/deploy-agent.js +239 -46
- package/dist/tools/deploy-agent.js.map +1 -1
- package/dist/tools/disconnect-agent-oauth.d.ts.map +1 -1
- package/dist/tools/disconnect-agent-oauth.js +32 -12
- package/dist/tools/disconnect-agent-oauth.js.map +1 -1
- package/dist/tools/get-account.d.ts.map +1 -1
- package/dist/tools/get-account.js +148 -42
- package/dist/tools/get-account.js.map +1 -1
- package/dist/tools/get-agent-activity.d.ts.map +1 -1
- package/dist/tools/get-agent-activity.js +185 -35
- package/dist/tools/get-agent-activity.js.map +1 -1
- package/dist/tools/get-agent-conversation.d.ts.map +1 -1
- package/dist/tools/get-agent-conversation.js +57 -35
- package/dist/tools/get-agent-conversation.js.map +1 -1
- package/dist/tools/get-agent-message.d.ts.map +1 -1
- package/dist/tools/get-agent-message.js +6 -4
- package/dist/tools/get-agent-message.js.map +1 -1
- package/dist/tools/get-agent-template.d.ts.map +1 -1
- package/dist/tools/get-agent-template.js +13 -17
- package/dist/tools/get-agent-template.js.map +1 -1
- package/dist/tools/get-model-schema.js +3 -3
- package/dist/tools/get-model-schema.js.map +1 -1
- package/dist/tools/get-my-agent.d.ts.map +1 -1
- package/dist/tools/get-my-agent.js +13 -8
- package/dist/tools/get-my-agent.js.map +1 -1
- package/dist/tools/get-playbook.d.ts.map +1 -1
- package/dist/tools/get-playbook.js +3 -2
- package/dist/tools/get-playbook.js.map +1 -1
- package/dist/tools/get-task-price.js +3 -3
- package/dist/tools/get-task-price.js.map +1 -1
- package/dist/tools/get-task.js +3 -3
- package/dist/tools/get-task.js.map +1 -1
- package/dist/tools/get-workflow.d.ts.map +1 -1
- package/dist/tools/get-workflow.js +38 -19
- package/dist/tools/get-workflow.js.map +1 -1
- package/dist/tools/index.d.ts +3 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/kill-task.js +3 -3
- package/dist/tools/kill-task.js.map +1 -1
- package/dist/tools/list-agent-skills.d.ts.map +1 -1
- package/dist/tools/list-agent-skills.js +11 -8
- package/dist/tools/list-agent-skills.js.map +1 -1
- package/dist/tools/list-agent-templates.js +4 -4
- package/dist/tools/list-agent-templates.js.map +1 -1
- package/dist/tools/list-my-agents.d.ts.map +1 -1
- package/dist/tools/list-my-agents.js +11 -8
- package/dist/tools/list-my-agents.js.map +1 -1
- package/dist/tools/list-projects.d.ts +4 -0
- package/dist/tools/list-projects.d.ts.map +1 -0
- package/dist/tools/list-projects.js +141 -0
- package/dist/tools/list-projects.js.map +1 -0
- package/dist/tools/list-studio-results.js +3 -3
- package/dist/tools/list-studio-results.js.map +1 -1
- package/dist/tools/list-tasks.js +3 -3
- package/dist/tools/list-tasks.js.map +1 -1
- package/dist/tools/list-workflow-runs.d.ts.map +1 -1
- package/dist/tools/list-workflow-runs.js +6 -4
- package/dist/tools/list-workflow-runs.js.map +1 -1
- package/dist/tools/list-workflows.d.ts.map +1 -1
- package/dist/tools/list-workflows.js +7 -6
- package/dist/tools/list-workflows.js.map +1 -1
- package/dist/tools/manage-agent-billing.d.ts.map +1 -1
- package/dist/tools/manage-agent-billing.js +207 -59
- package/dist/tools/manage-agent-billing.js.map +1 -1
- package/dist/tools/manage-agent-custom-skill.d.ts.map +1 -1
- package/dist/tools/manage-agent-custom-skill.js +119 -15
- package/dist/tools/manage-agent-custom-skill.js.map +1 -1
- package/dist/tools/recommend-model.js +3 -3
- package/dist/tools/recommend-model.js.map +1 -1
- package/dist/tools/resume-workflow-run.d.ts.map +1 -1
- package/dist/tools/resume-workflow-run.js +3 -2
- package/dist/tools/resume-workflow-run.js.map +1 -1
- package/dist/tools/run-model.js +3 -3
- package/dist/tools/run-model.js.map +1 -1
- package/dist/tools/run-workflow.d.ts.map +1 -1
- package/dist/tools/run-workflow.js +3 -2
- package/dist/tools/run-workflow.js.map +1 -1
- package/dist/tools/save-workflow-from-agent.d.ts.map +1 -1
- package/dist/tools/save-workflow-from-agent.js +17 -12
- package/dist/tools/save-workflow-from-agent.js.map +1 -1
- package/dist/tools/schemas.d.ts +32 -26
- package/dist/tools/schemas.d.ts.map +1 -1
- package/dist/tools/schemas.js +67 -0
- package/dist/tools/schemas.js.map +1 -1
- package/dist/tools/search-docs.js +3 -3
- package/dist/tools/search-docs.js.map +1 -1
- package/dist/tools/search-models.js +3 -3
- package/dist/tools/search-models.js.map +1 -1
- package/dist/tools/send-agent-message.d.ts.map +1 -1
- package/dist/tools/send-agent-message.js +30 -9
- package/dist/tools/send-agent-message.js.map +1 -1
- package/dist/tools/set-agent-credentials.d.ts.map +1 -1
- package/dist/tools/set-agent-credentials.js +55 -61
- package/dist/tools/set-agent-credentials.js.map +1 -1
- package/dist/tools/update-agent.d.ts.map +1 -1
- package/dist/tools/update-agent.js +59 -20
- package/dist/tools/update-agent.js.map +1 -1
- package/dist/tools/update-workflow.d.ts +199 -0
- package/dist/tools/update-workflow.d.ts.map +1 -1
- package/dist/tools/update-workflow.js +20 -7
- package/dist/tools/update-workflow.js.map +1 -1
- package/dist/tools/upload-file.js +3 -3
- package/dist/tools/upload-file.js.map +1 -1
- package/dist/tools/wait-for-task.js +3 -3
- package/dist/tools/wait-for-task.js.map +1 -1
- package/dist/tools/wait-for-workflow-run.d.ts +3 -3
- package/dist/tools/wait-for-workflow-run.d.ts.map +1 -1
- package/dist/tools/wait-for-workflow-run.js +7 -6
- package/dist/tools/wait-for-workflow-run.js.map +1 -1
- package/dist/utils/agent-catalog.d.ts +59 -0
- package/dist/utils/agent-catalog.d.ts.map +1 -1
- package/dist/utils/agent-catalog.js +28 -7
- package/dist/utils/agent-catalog.js.map +1 -1
- package/dist/utils/agent-config.d.ts +172 -9
- package/dist/utils/agent-config.d.ts.map +1 -1
- package/dist/utils/agent-config.js +416 -60
- package/dist/utils/agent-config.js.map +1 -1
- package/dist/utils/agent-message.d.ts +36 -14
- package/dist/utils/agent-message.d.ts.map +1 -1
- package/dist/utils/agent-message.js +92 -26
- package/dist/utils/agent-message.js.map +1 -1
- package/dist/utils/agent-targets.d.ts +7 -3
- package/dist/utils/agent-targets.d.ts.map +1 -1
- package/dist/utils/agent-targets.js +35 -23
- package/dist/utils/agent-targets.js.map +1 -1
- package/dist/utils/agent-turns.d.ts +19 -12
- package/dist/utils/agent-turns.d.ts.map +1 -1
- package/dist/utils/agent-turns.js +97 -15
- package/dist/utils/agent-turns.js.map +1 -1
- package/dist/utils/api.d.ts +6 -0
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/api.js +22 -1
- package/dist/utils/api.js.map +1 -1
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +7 -13
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/json-schema-dialect.d.ts.map +1 -1
- package/dist/utils/json-schema-dialect.js +4 -0
- package/dist/utils/json-schema-dialect.js.map +1 -1
- package/dist/utils/media.d.ts +8 -0
- package/dist/utils/media.d.ts.map +1 -1
- package/dist/utils/media.js +29 -0
- package/dist/utils/media.js.map +1 -1
- package/dist/utils/poll.d.ts +5 -2
- package/dist/utils/poll.d.ts.map +1 -1
- package/dist/utils/poll.js +10 -9
- package/dist/utils/poll.js.map +1 -1
- package/dist/utils/quoted-text.d.ts +28 -0
- package/dist/utils/quoted-text.d.ts.map +1 -0
- package/dist/utils/quoted-text.js +64 -0
- package/dist/utils/quoted-text.js.map +1 -0
- package/dist/utils/studio-runs.d.ts.map +1 -1
- package/dist/utils/studio-runs.js +7 -4
- package/dist/utils/studio-runs.js.map +1 -1
- package/dist/utils/user-agent.d.ts +197 -29
- package/dist/utils/user-agent.d.ts.map +1 -1
- package/dist/utils/user-agent.js +314 -48
- package/dist/utils/user-agent.js.map +1 -1
- package/dist/utils/wiro-project.d.ts +45 -0
- package/dist/utils/wiro-project.d.ts.map +1 -0
- package/dist/utils/wiro-project.js +66 -0
- package/dist/utils/wiro-project.js.map +1 -0
- package/dist/utils/workflow-save.d.ts +22 -1
- package/dist/utils/workflow-save.d.ts.map +1 -1
- package/dist/utils/workflow-save.js +122 -24
- package/dist/utils/workflow-save.js.map +1 -1
- package/dist/utils/workflow.d.ts +26 -13
- package/dist/utils/workflow.d.ts.map +1 -1
- package/dist/utils/workflow.js +51 -20
- package/dist/utils/workflow.js.map +1 -1
- package/dist/utils/workspace.d.ts +30 -4
- package/dist/utils/workspace.d.ts.map +1 -1
- package/dist/utils/workspace.js +95 -12
- package/dist/utils/workspace.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { ApiResultError, asString, errorResult, errorText, isPlainObject, requireApiSuccess, toNumber, unixToIso, } from '../utils/api.js';
|
|
4
|
-
import { workspaceHint } from '../utils/agent-config.js';
|
|
4
|
+
import { daysLeftText, readPlanChange, underOneDayLeft, workspaceHint } from '../utils/agent-config.js';
|
|
5
5
|
import { DEFAULT_WAIT_SECONDS } from '../utils/poll.js';
|
|
6
6
|
import { isPlainTeamMember, teamAgentBillingRefused } from '../utils/workspace.js';
|
|
7
|
-
import { AMOUNT_TOLERANCE_USD, agentDashboardUrl, agentSummarySchema, asTier, chargeRoute, formatAgentSummaryLines, formatCredits, formatUsd, outcomeUnknown, readAgentDetail, roundUsd, sameAmount, toAgentDetail, toAgentSummary, } from '../utils/user-agent.js';
|
|
8
|
-
import { nextActionSchema } from './schemas.js';
|
|
7
|
+
import { AMOUNT_TOLERANCE_USD, WALLET_NOT_READ_NOTE, agentDashboardUrl, agentSummarySchema, asTier, chargeRoute, formatAgentSummaryLines, formatCredits, formatUsd, isTransitionalStatus, isWalletNotRead, outcomeUnknown, readAgentDetail, roundUsd, sameAmount, toAgentDetail, toAgentSummary, } from '../utils/user-agent.js';
|
|
8
|
+
import { nextActionSchema, strictInput } from './schemas.js';
|
|
9
9
|
const ACTIONS = ['subscribe', 'upgrade_to_pro', 'cancel', 'renew', 'buy_credits'];
|
|
10
10
|
const quoteSchema = z.object({
|
|
11
11
|
chargeNowUsd: z.number().nullable(),
|
|
@@ -13,6 +13,8 @@ const quoteSchema = z.object({
|
|
|
13
13
|
maxChargeUsd: z.number().optional(),
|
|
14
14
|
recurringUsd: z.number().nullable().optional(),
|
|
15
15
|
monthlyCredits: z.number().nullable().optional(),
|
|
16
|
+
creditsNow: z.number().optional()
|
|
17
|
+
.describe('upgrade_to_pro: the credits this period gains now, below 0 when it loses them. monthlyCredits is what every renewal gives.'),
|
|
16
18
|
creditsAdded: z.number().optional(),
|
|
17
19
|
paidFrom: z.enum(['personal_wallet', 'team_wallet', 'card']),
|
|
18
20
|
tier: z.enum(['starter', 'pro']).optional(),
|
|
@@ -22,6 +24,8 @@ const resultSchema = z.object({
|
|
|
22
24
|
chargedUsd: z.number().nullable().optional(),
|
|
23
25
|
monthlyPriceUsd: z.number().optional(),
|
|
24
26
|
monthlyCredits: z.number().optional(),
|
|
27
|
+
creditsNow: z.number().optional()
|
|
28
|
+
.describe('upgrade_to_pro: the credits this period gained with it, below 0 when it lost them. monthlyCredits is what every renewal gives.'),
|
|
25
29
|
creditsAdded: z.number().optional(),
|
|
26
30
|
tier: z.string().optional(),
|
|
27
31
|
previousTier: z.string().optional(),
|
|
@@ -46,20 +50,114 @@ function waitAction(guid, reason) {
|
|
|
46
50
|
reason,
|
|
47
51
|
};
|
|
48
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* The wait after an upgrade, a pack or a renewal, which keep a running agent up:
|
|
55
|
+
* only an agent on its way, one that was stopping (it starts again) or one queued
|
|
56
|
+
* or starting, is worth waiting for.
|
|
57
|
+
*/
|
|
58
|
+
function waitIfStarting(agent) {
|
|
59
|
+
return isTransitionalStatus(agent.status)
|
|
60
|
+
? waitAction(agent.guid, 'Wait until the agent is running.')
|
|
61
|
+
: undefined;
|
|
62
|
+
}
|
|
63
|
+
/** After a renewal, Wiro queues a stopped or failed agent; a running one keeps running. */
|
|
64
|
+
function renewWait(agent) {
|
|
65
|
+
if (agent.status === 0 || agent.status === 5)
|
|
66
|
+
return waitAction(agent.guid, 'Wait until the agent is running again.');
|
|
67
|
+
return waitIfStarting(agent);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A new plan queues a stopped or failed agent, and one waiting for setup; a
|
|
71
|
+
* running one keeps running, and one that was stopping starts again. An agent
|
|
72
|
+
* without a plan runs only while extra credits last.
|
|
73
|
+
*/
|
|
74
|
+
function subscribeStarts(status) {
|
|
75
|
+
return status !== 4;
|
|
76
|
+
}
|
|
77
|
+
function subscribeQuoteNote(status) {
|
|
78
|
+
switch (status) {
|
|
79
|
+
case 4:
|
|
80
|
+
return 'The agent keeps running: a new plan does not restart it.';
|
|
81
|
+
case 3:
|
|
82
|
+
return 'The agent is starting, and a new plan does not restart it.';
|
|
83
|
+
case 1:
|
|
84
|
+
return 'The agent is stopping, and it starts again right after the payment.';
|
|
85
|
+
case 2:
|
|
86
|
+
return 'The agent is already queued to start.';
|
|
87
|
+
default:
|
|
88
|
+
return 'The agent is queued to start right after the payment.';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function subscribeWait(agent) {
|
|
92
|
+
return subscribeStarts(agent.status) ? waitAction(agent.guid, 'Wait until the agent is running.') : undefined;
|
|
93
|
+
}
|
|
94
|
+
/** What an upgrade does to this period's credits. An allowance above Pro's is cut to Pro's for the time left. */
|
|
95
|
+
function upgradeCreditsText(creditsNow, renewal, done) {
|
|
96
|
+
if (creditsNow > 0) {
|
|
97
|
+
return `${formatCredits(creditsNow)} credits ${done ? 'came with it' : 'come now'} for the rest of this period${renewal}. `;
|
|
98
|
+
}
|
|
99
|
+
if (creditsNow < 0)
|
|
100
|
+
return `This period ${done ? 'lost' : 'loses'} ${formatCredits(-creditsNow)} credits for the time left${renewal}. `;
|
|
101
|
+
return `This period ${done ? 'kept' : 'keeps'} the credits it ${done ? 'had' : 'has'}${renewal}. `;
|
|
102
|
+
}
|
|
103
|
+
/** What a change to the plan does to the agent: a running one keeps running, and one that was stopping starts again. */
|
|
104
|
+
function planChangeAgentNote(status, what, quote = false) {
|
|
105
|
+
switch (status) {
|
|
106
|
+
case 4:
|
|
107
|
+
return `The agent keeps running: ${what} does not restart it.`;
|
|
108
|
+
case 3:
|
|
109
|
+
return `The agent is starting, and ${what} does not restart it.`;
|
|
110
|
+
case 1:
|
|
111
|
+
return quote
|
|
112
|
+
? 'The agent is stopping; if it is still stopping when the payment goes through, it starts again.'
|
|
113
|
+
: 'The agent was stopping, and it starts again.';
|
|
114
|
+
case 2:
|
|
115
|
+
return 'The agent is queued to start.';
|
|
116
|
+
case 6:
|
|
117
|
+
return 'The agent still needs setup; the credits are there once it starts.';
|
|
118
|
+
case 0:
|
|
119
|
+
return 'The agent is stopped; the credits are there when it starts.';
|
|
120
|
+
case 5:
|
|
121
|
+
return 'The agent stopped with an error; the credits are there when it starts.';
|
|
122
|
+
default:
|
|
123
|
+
return 'The credits are there when the agent starts.';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The Pro price of this agent and what moving to it does today, as Wiro works it
|
|
128
|
+
* out on the plan the agent has now. null when it cannot be read: the quote then
|
|
129
|
+
* falls back to the Pro price the agent shows and to the most the upgrade can charge.
|
|
130
|
+
*/
|
|
131
|
+
async function readProPreview(client, guid, signal) {
|
|
132
|
+
try {
|
|
133
|
+
const body = requireApiSuccess(await client.post('/UserAgent/PricingPreview', { useragentguid: guid, tier: 'pro' }, signal), 'The Pro price could not be read.');
|
|
134
|
+
const priceUsd = toNumber(body.totalPriceUsd);
|
|
135
|
+
const monthlyCredits = toNumber(body.totalMonthlyCredits);
|
|
136
|
+
return {
|
|
137
|
+
price: priceUsd !== null && monthlyCredits !== null ? { priceUsd, monthlyCredits } : null,
|
|
138
|
+
change: readPlanChange(body.planChange),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
if (signal.aborted)
|
|
143
|
+
throw error;
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
49
147
|
function tierName(tier) {
|
|
50
148
|
return tier === 'pro' ? 'Pro' : 'Starter';
|
|
51
149
|
}
|
|
52
|
-
/** The amount a confirmed call charges now, or null when it charges nothing. */
|
|
150
|
+
/** The amount a confirmed call charges now, or at most when that is worked out only then; null when it charges nothing. */
|
|
53
151
|
function chargeOf(quote) {
|
|
54
|
-
const amount = quote?.chargeNowUsd ?? null;
|
|
152
|
+
const amount = quote?.chargeNowUsd ?? quote?.maxChargeUsd ?? null;
|
|
55
153
|
return amount !== null && amount > 0 ? amount : null;
|
|
56
154
|
}
|
|
57
155
|
/**
|
|
58
156
|
* The amount the user approves with confirm_charge_usd, or null when the
|
|
59
|
-
* call charges nothing.
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
157
|
+
* call charges nothing. An upgrade is approved at the most it can charge: the
|
|
158
|
+
* amount Wiro works out for a wallet plan, which only shrinks as the period
|
|
159
|
+
* runs on, or the full price difference when Wiro works the amount out only
|
|
160
|
+
* at the upgrade.
|
|
63
161
|
*/
|
|
64
162
|
function approvalAmountOf(action, quote) {
|
|
65
163
|
if (action !== 'upgrade_to_pro')
|
|
@@ -96,7 +194,7 @@ function changedLead(action, amount, approved, callerRequestId) {
|
|
|
96
194
|
}
|
|
97
195
|
return `${changed} Nothing was charged. Show the new amount to the user and ask again.`;
|
|
98
196
|
}
|
|
99
|
-
function planFor(client, action, agent, raw, input) {
|
|
197
|
+
async function planFor(client, action, agent, raw, input, signal) {
|
|
100
198
|
const guid = agent.guid;
|
|
101
199
|
const active = raw?.status === 'active';
|
|
102
200
|
const prepaid = raw?.provider === 'prepaid';
|
|
@@ -130,7 +228,7 @@ function planFor(client, action, agent, raw, input) {
|
|
|
130
228
|
tier,
|
|
131
229
|
},
|
|
132
230
|
message: `Subscribe on ${tierName(tier)}: ${formatUsd(price.priceUsd)} now from ${wallet}, then every 30 days until the plan is cancelled, with ${formatCredits(price.monthlyCredits)} credits per month. `
|
|
133
|
-
+
|
|
231
|
+
+ subscribeQuoteNote(agent.status)
|
|
134
232
|
+ (missing.length > 0
|
|
135
233
|
? ` Missing credentials (${missing.map(item => item.title).join(', ')}) can be added afterwards; until then the skills that need them fail.`
|
|
136
234
|
: ''),
|
|
@@ -144,9 +242,10 @@ function planFor(client, action, agent, raw, input) {
|
|
|
144
242
|
const credits = toNumber(body.monthlycredits) ?? price.monthlyCredits;
|
|
145
243
|
return {
|
|
146
244
|
outcome: 'done',
|
|
147
|
-
message: `Subscribed on ${tierName(tier)} and charged ${formatUsd(charged)} from ${wallet}. The plan renews every 30 days until it is cancelled.
|
|
245
|
+
message: `Subscribed on ${tierName(tier)} and charged ${formatUsd(charged)} from ${wallet}. The plan renews every 30 days until it is cancelled. `
|
|
246
|
+
+ (subscribeStarts(agent.status) ? 'The agent is starting.' : 'The agent keeps running: a new plan does not restart it.'),
|
|
148
247
|
result: { chargedUsd: charged, monthlyPriceUsd: charged, monthlyCredits: credits, tier },
|
|
149
|
-
nextAction:
|
|
248
|
+
nextAction: subscribeWait(agent),
|
|
150
249
|
};
|
|
151
250
|
},
|
|
152
251
|
};
|
|
@@ -177,10 +276,10 @@ function planFor(client, action, agent, raw, input) {
|
|
|
177
276
|
if (!cancelled) {
|
|
178
277
|
return { outcome: 'not_needed', message: 'The plan is active and renews by itself. Nothing to do.' };
|
|
179
278
|
}
|
|
180
|
-
const amount = agent.
|
|
279
|
+
const amount = agent.monthlyPriceUsd || agent.subscription?.amountUsd;
|
|
181
280
|
return {
|
|
182
281
|
outcome: 'quote',
|
|
183
|
-
quote: { chargeNowUsd: 0, estimated: false, recurringUsd: amount, monthlyCredits: agent.credits.monthly, paidFrom },
|
|
282
|
+
quote: { chargeNowUsd: 0, estimated: false, recurringUsd: amount, monthlyCredits: agent.credits.renewal ?? agent.credits.monthly, paidFrom },
|
|
184
283
|
message: `Undo the cancellation: nothing is charged now. The plan then renews from ${wallet} for ${formatUsd(amount)} after ${periodEnd} and every 30 days after that until it is cancelled.`,
|
|
185
284
|
confirmReason: 'Ask the user to confirm first: the plan will charge the wallet again at each renewal.',
|
|
186
285
|
perform: async (signal) => {
|
|
@@ -240,7 +339,7 @@ function planFor(client, action, agent, raw, input) {
|
|
|
240
339
|
...(credits !== null ? { monthlyCredits: credits } : {}),
|
|
241
340
|
renewal: 'renewed',
|
|
242
341
|
},
|
|
243
|
-
nextAction:
|
|
342
|
+
nextAction: renewWait(agent),
|
|
244
343
|
};
|
|
245
344
|
},
|
|
246
345
|
};
|
|
@@ -258,16 +357,17 @@ function planFor(client, action, agent, raw, input) {
|
|
|
258
357
|
};
|
|
259
358
|
};
|
|
260
359
|
if (!prepaid) {
|
|
261
|
-
|
|
360
|
+
// A plan moving to wallet billing has no cancel in the dashboard either: it can be cancelled once the wallet bills it.
|
|
361
|
+
if (raw?.nextprovider === 'prepaid') {
|
|
262
362
|
return {
|
|
263
363
|
outcome: 'refused',
|
|
264
|
-
message: `
|
|
364
|
+
message: `A switch to wallet billing is already scheduled for this plan, so it cannot be cancelled now. After ${periodEnd} it is billed from the wallet, and action cancel then stops its renewals.`,
|
|
265
365
|
};
|
|
266
366
|
}
|
|
267
|
-
if (
|
|
367
|
+
if (agent.workspace === 'personal') {
|
|
268
368
|
return {
|
|
269
369
|
outcome: 'refused',
|
|
270
|
-
message:
|
|
370
|
+
message: `This plan is billed by card. Card plans are cancelled from the dashboard: ${agent.dashboardUrl}`,
|
|
271
371
|
};
|
|
272
372
|
}
|
|
273
373
|
if (agent.subscription?.cancelAtPeriodEnd) {
|
|
@@ -294,6 +394,14 @@ function planFor(client, action, agent, raw, input) {
|
|
|
294
394
|
}
|
|
295
395
|
case 'upgrade_to_pro': {
|
|
296
396
|
if (!active) {
|
|
397
|
+
// A Pro plan that ended comes back at its own price with renew. Subscribe takes today's price.
|
|
398
|
+
if (agent.tier === 'pro' && raw?.status === 'expired' && prepaid) {
|
|
399
|
+
return {
|
|
400
|
+
outcome: 'refused',
|
|
401
|
+
message: 'This agent is already on Pro, and its plan has ended. Action renew brings the plan back at its own price; subscribe starts a new plan at today\'s price.',
|
|
402
|
+
nextAction: billingCall(guid, 'renew'),
|
|
403
|
+
};
|
|
404
|
+
}
|
|
297
405
|
return {
|
|
298
406
|
outcome: 'refused',
|
|
299
407
|
message: 'Upgrading needs an active plan. Use action subscribe with tier pro instead.',
|
|
@@ -305,32 +413,42 @@ function planFor(client, action, agent, raw, input) {
|
|
|
305
413
|
// No checkout pages are opened for card plans: the user pays them in the dashboard.
|
|
306
414
|
if (route === 'card')
|
|
307
415
|
return { outcome: 'refused', message: cardPlan('upgrade it to Pro') };
|
|
308
|
-
const
|
|
416
|
+
const preview = await readProPreview(client, guid, signal);
|
|
417
|
+
const pro = preview?.price ?? agent.pricing?.pro;
|
|
309
418
|
if (!pro)
|
|
310
419
|
throw new Error('The Pro price of this agent is not available right now. Try again later.');
|
|
311
|
-
const ending = `The plan is cancelled, so it ends about a day after ${periodEnd} and does not renew at the Pro price; this charge covers only the
|
|
312
|
-
const current = agent.monthlyPriceUsd
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
const
|
|
318
|
-
const
|
|
420
|
+
const ending = `The plan is cancelled, so it ends about a day after ${periodEnd} and does not renew at the Pro price; this charge covers only the time left. To keep the plan, undo the cancellation first with action renew.`;
|
|
421
|
+
const current = agent.monthlyPriceUsd || agent.subscription?.amountUsd || 0;
|
|
422
|
+
const fullDifference = roundUsd(Math.max(0, pro.priceUsd - current));
|
|
423
|
+
// A wallet plan pays the amount Wiro works out on it now. A card plan moving to wallet billing is
|
|
424
|
+
// charged from the wallet for the time left of its card period, which Wiro works out at the upgrade.
|
|
425
|
+
const change = preview?.change?.wallet ? preview.change : null;
|
|
426
|
+
const exact = change?.chargeNowUsd ?? null;
|
|
427
|
+
const renewalCredits = change?.creditsFromRenewal ?? pro.monthlyCredits;
|
|
428
|
+
const creditsNow = change?.creditsNow ?? null;
|
|
429
|
+
const days = daysLeftText(change?.secondsLeft ?? null);
|
|
430
|
+
const money = exact !== null
|
|
431
|
+
? `Upgrade to Pro: ${formatUsd(exact)} now from ${wallet} for the rest of this period`
|
|
432
|
+
+ `${exact > 0 && underOneDayLeft(change?.secondsLeft ?? null) ? ', at the one-day minimum' : days ? ` (${days})` : ''}. `
|
|
433
|
+
: `Upgrade to Pro: the difference for the rest of this period is taken from ${wallet} now. Wiro works it out from the time left when the upgrade is applied, and it is never more than ${formatUsd(fullDifference)}, so that is the amount to approve. `;
|
|
434
|
+
const credits = creditsNow !== null
|
|
435
|
+
? upgradeCreditsText(creditsNow, cancelled ? '' : `, and every renewal gives ${formatCredits(renewalCredits)}`, false)
|
|
436
|
+
: `The added credits come for the time left in this period${cancelled ? '' : `, and every renewal gives ${formatCredits(renewalCredits)}`}. `;
|
|
319
437
|
return {
|
|
320
438
|
outcome: 'quote',
|
|
321
439
|
quote: {
|
|
322
|
-
chargeNowUsd:
|
|
323
|
-
estimated:
|
|
324
|
-
maxChargeUsd:
|
|
440
|
+
chargeNowUsd: exact,
|
|
441
|
+
estimated: exact === null,
|
|
442
|
+
maxChargeUsd: exact ?? fullDifference,
|
|
325
443
|
recurringUsd: cancelled ? null : pro.priceUsd,
|
|
326
|
-
monthlyCredits:
|
|
444
|
+
monthlyCredits: renewalCredits,
|
|
445
|
+
...(creditsNow !== null ? { creditsNow } : {}),
|
|
327
446
|
paidFrom,
|
|
328
447
|
tier: 'pro',
|
|
329
448
|
},
|
|
330
|
-
message:
|
|
331
|
-
+ `Wiro works out the exact amount from the real length of the billing period, and it is never more than ${formatUsd(maxCharge)}, so that is the amount to approve. `
|
|
449
|
+
message: money + credits
|
|
332
450
|
+ (cancelled ? `${ending} ` : `From the next renewal the plan costs ${formatUsd(pro.priceUsd)} every 30 days. `)
|
|
333
|
-
+
|
|
451
|
+
+ `${planChangeAgentNote(agent.status, 'the upgrade', true)} To go back to Starter later, cancel, let the plan end, then subscribe to Starter.`,
|
|
334
452
|
perform: async (signal) => {
|
|
335
453
|
const body = requireApiSuccess(await client.post('/UserAgent/UpgradeTier', { guid, targetTier: 'pro' }, signal), 'The plan could not be upgraded.');
|
|
336
454
|
if (asString(body.url)) {
|
|
@@ -339,23 +457,28 @@ function planFor(client, action, agent, raw, input) {
|
|
|
339
457
|
}
|
|
340
458
|
const charged = toNumber(body.proratedCharge);
|
|
341
459
|
const newPrice = toNumber(body.newPriceUsd) ?? pro.priceUsd;
|
|
342
|
-
const
|
|
460
|
+
const fromRenewal = toNumber(body.creditsFromRenewal) ?? toNumber(body.newMonthlyCredits) ?? renewalCredits;
|
|
461
|
+
const came = toNumber(body.creditsNow);
|
|
343
462
|
const previousTier = asString(body.previousTier);
|
|
344
463
|
return {
|
|
345
464
|
outcome: 'done',
|
|
346
465
|
message: `Upgraded to Pro and charged ${formatUsd(charged ?? 0)} from ${wallet}. `
|
|
466
|
+
+ (came !== null
|
|
467
|
+
? upgradeCreditsText(came, cancelled ? '' : `, and every renewal gives ${formatCredits(fromRenewal)}`, true)
|
|
468
|
+
: '')
|
|
347
469
|
+ (cancelled
|
|
348
470
|
? `The plan is still cancelled and ends about a day after ${periodEnd}; action renew undoes the cancellation. `
|
|
349
471
|
: `The plan now costs ${formatUsd(newPrice)} every 30 days. `)
|
|
350
|
-
+
|
|
472
|
+
+ planChangeAgentNote(agent.status, 'the upgrade'),
|
|
351
473
|
result: {
|
|
352
474
|
chargedUsd: charged,
|
|
353
475
|
monthlyPriceUsd: newPrice,
|
|
354
|
-
monthlyCredits:
|
|
476
|
+
monthlyCredits: fromRenewal,
|
|
477
|
+
...(came !== null ? { creditsNow: came } : {}),
|
|
355
478
|
tier: 'pro',
|
|
356
479
|
...(previousTier ? { previousTier } : {}),
|
|
357
480
|
},
|
|
358
|
-
nextAction:
|
|
481
|
+
nextAction: waitIfStarting(agent),
|
|
359
482
|
};
|
|
360
483
|
},
|
|
361
484
|
};
|
|
@@ -378,6 +501,7 @@ function planFor(client, action, agent, raw, input) {
|
|
|
378
501
|
if (!input.pack) {
|
|
379
502
|
return {
|
|
380
503
|
outcome: 'refused',
|
|
504
|
+
...(packs.length > 0 ? { heading: 'Available packs' } : {}),
|
|
381
505
|
message: packs.length > 0 ? `Choose a pack: ${packList}.` : 'No extra credit packs are available for this agent yet.',
|
|
382
506
|
...(packs[0] ? { nextAction: billingCall(guid, 'buy_credits', { pack: packs[0].pack }) } : {}),
|
|
383
507
|
};
|
|
@@ -392,7 +516,7 @@ function planFor(client, action, agent, raw, input) {
|
|
|
392
516
|
return {
|
|
393
517
|
outcome: 'quote',
|
|
394
518
|
quote: { chargeNowUsd: chosen.priceUsd, estimated: false, creditsAdded: chosen.credits, paidFrom, pack: chosen.pack },
|
|
395
|
-
message: `Buy the ${chosen.pack} pack: ${formatUsd(chosen.priceUsd)} now from ${wallet} for ${formatCredits(chosen.credits)} extra credits, added at once. Extra credits are used after the monthly credits
|
|
519
|
+
message: `Buy the ${chosen.pack} pack: ${formatUsd(chosen.priceUsd)} now from ${wallet} for ${formatCredits(chosen.credits)} extra credits, added at once. Extra credits are used after the monthly credits, do not reset each month and end 6 months (180 days) after purchase. ${planChangeAgentNote(agent.status, 'a credit pack', true)} This is a one-time charge.`,
|
|
396
520
|
perform: async (signal) => {
|
|
397
521
|
const body = requireApiSuccess(await client.post('/UserAgent/CreateExtraCreditCheckout', {
|
|
398
522
|
useragentguid: guid,
|
|
@@ -403,9 +527,9 @@ function planFor(client, action, agent, raw, input) {
|
|
|
403
527
|
return { outcome: 'refused', message: cardPlan('buy the pack') };
|
|
404
528
|
return {
|
|
405
529
|
outcome: 'done',
|
|
406
|
-
message: `Bought the ${chosen.pack} pack: ${formatCredits(chosen.credits)} credits for ${formatUsd(chosen.priceUsd)} from ${wallet}. The credits are added
|
|
530
|
+
message: `Bought the ${chosen.pack} pack: ${formatCredits(chosen.credits)} credits for ${formatUsd(chosen.priceUsd)} from ${wallet}. The credits are added. ${planChangeAgentNote(agent.status, 'a credit pack')}`,
|
|
407
531
|
result: { chargedUsd: chosen.priceUsd, creditsAdded: chosen.credits },
|
|
408
|
-
nextAction:
|
|
532
|
+
nextAction: waitIfStarting(agent),
|
|
409
533
|
};
|
|
410
534
|
},
|
|
411
535
|
};
|
|
@@ -464,7 +588,6 @@ async function observeOpenOutcome(client, action, before, quote, requestId, sent
|
|
|
464
588
|
}
|
|
465
589
|
const after = toAgentDetail(row);
|
|
466
590
|
const charged = chargeOf(quote);
|
|
467
|
-
const restart = waitAction(before.guid, 'Wait until the agent is running again.');
|
|
468
591
|
switch (action) {
|
|
469
592
|
case 'subscribe':
|
|
470
593
|
return after.subscription?.status === 'active'
|
|
@@ -473,7 +596,7 @@ async function observeOpenOutcome(client, action, before, quote, requestId, sent
|
|
|
473
596
|
row,
|
|
474
597
|
text: 'The agent now has an active plan, so the payment went through. Do not subscribe again.',
|
|
475
598
|
result: { chargedUsd: charged, ...(quote?.tier ? { tier: quote.tier } : {}) },
|
|
476
|
-
nextAction:
|
|
599
|
+
nextAction: subscribeWait(before),
|
|
477
600
|
}
|
|
478
601
|
: { happened: false, text: 'The agent shows no active plan yet. Check get_my_agent again in a minute and the wallet balance with get_account before trying again; if the plan is still not active but the balance changed, contact Wiro support.' };
|
|
479
602
|
case 'renew':
|
|
@@ -483,7 +606,7 @@ async function observeOpenOutcome(client, action, before, quote, requestId, sent
|
|
|
483
606
|
row,
|
|
484
607
|
text: 'The plan is active again, so the renewal went through. Do not renew it again.',
|
|
485
608
|
result: { chargedUsd: charged, renewal: 'renewed' },
|
|
486
|
-
nextAction:
|
|
609
|
+
nextAction: renewWait(before),
|
|
487
610
|
}
|
|
488
611
|
: { happened: false, text: 'The plan still shows as expired. Check get_my_agent again in a minute and the wallet balance with get_account before renewing again; if the plan is still expired but the balance changed, contact Wiro support.' };
|
|
489
612
|
case 'upgrade_to_pro': {
|
|
@@ -493,7 +616,7 @@ async function observeOpenOutcome(client, action, before, quote, requestId, sent
|
|
|
493
616
|
row,
|
|
494
617
|
text: `The agent is on Pro now, so the upgrade went through. Do not upgrade again. The prorated charge is not shown, and it is at most ${formatUsd(quote?.maxChargeUsd)}.`,
|
|
495
618
|
result: { chargedUsd: null, tier: 'pro' },
|
|
496
|
-
nextAction:
|
|
619
|
+
nextAction: waitIfStarting(before),
|
|
497
620
|
};
|
|
498
621
|
}
|
|
499
622
|
const proPrice = before.pricing?.pro.priceUsd;
|
|
@@ -516,7 +639,7 @@ async function observeOpenOutcome(client, action, before, quote, requestId, sent
|
|
|
516
639
|
row,
|
|
517
640
|
text: `The agent's extra credits rose by ${formatCredits(rose)}, so the purchase went through. Do not buy it again.`,
|
|
518
641
|
result: bought,
|
|
519
|
-
nextAction:
|
|
642
|
+
nextAction: waitIfStarting(before),
|
|
520
643
|
};
|
|
521
644
|
}
|
|
522
645
|
const fresh = await freshPackShows(client, before.guid, credits, sentAtMs, signal);
|
|
@@ -541,8 +664,15 @@ async function observeOpenOutcome(client, action, before, quote, requestId, sent
|
|
|
541
664
|
return { happened: false, text: '' };
|
|
542
665
|
}
|
|
543
666
|
}
|
|
544
|
-
|
|
667
|
+
// Code 104: another payment from the same wallet, or another change to the agent's plan, was going through.
|
|
668
|
+
const BUSY_NOTE = 'Nothing was charged or changed, and it is not a low balance. Offer to try again in a minute.';
|
|
669
|
+
function annotateKnownRefusal(error, requestId) {
|
|
545
670
|
const text = error.message;
|
|
671
|
+
if (error.codes.some(code => Number(code) === 104)) {
|
|
672
|
+
return new Error(`${text}\n\n${BUSY_NOTE}${requestId ? ` To try again, repeat the call with request_id "${requestId}"; that request id never charges twice.` : ''}`);
|
|
673
|
+
}
|
|
674
|
+
if (isWalletNotRead(error))
|
|
675
|
+
return new Error(`${text}\n\n${WALLET_NOT_READ_NOTE}`);
|
|
546
676
|
if (/insufficient wallet balance/i.test(text)) {
|
|
547
677
|
return new Error(`${text}\n\nNothing was charged. Funds are added at https://wiro.ai/panel/wallet/deposit/credit-card (for a team project, select that team in the dashboard first); once the user has added them and says yes, try again. get_account shows the balance.`);
|
|
548
678
|
}
|
|
@@ -560,19 +690,23 @@ export function registerManageAgentBilling(server, client) {
|
|
|
560
690
|
description: 'Pay for, renew, upgrade or cancel a deployed agent\'s plan, or buy extra credits. Charges '
|
|
561
691
|
+ 'come from the Wiro wallet of the agent\'s workspace (the team wallet for a team agent); the connected '
|
|
562
692
|
+ 'project must belong to that same workspace. Every call without confirm: true only returns what will happen '
|
|
563
|
-
+ 'and the amount (for
|
|
693
|
+
+ 'and the amount (for an upgrade, the prorated amount Wiro works out, or the most it can charge when '
|
|
694
|
+
+ 'that is worked out only at the upgrade). Show it to the user, get '
|
|
564
695
|
+ 'their approval, then repeat the call with confirm: true and confirm_charge_usd set to the quoted '
|
|
565
|
-
+ 'amount (for an upgrade,
|
|
696
|
+
+ 'amount (for an upgrade, quote.maxChargeUsd); if the price changed in between, nothing is charged and a '
|
|
566
697
|
+ 'new quote comes back. Never repeat a confirmed charge that failed or timed out without checking '
|
|
567
698
|
+ 'get_my_agent first. '
|
|
568
699
|
+ 'subscribe starts a plan for an agent without one; renew undoes a cancellation or renews an expired '
|
|
569
700
|
+ 'wallet plan; upgrade_to_pro charges the prorated difference now; buy_credits adds a credit pack '
|
|
570
|
-
+ '(Pro only); cancel stops renewals with no refund. Plans renew every 30 days until cancelled.
|
|
701
|
+
+ '(Pro only); cancel stops renewals with no refund. Plans renew every 30 days until cancelled. Renewals, '
|
|
702
|
+
+ 'upgrades and packs leave a running agent running. An '
|
|
571
703
|
+ 'agent whose plan is billed by card is upgraded and topped up in the Wiro dashboard, and a personal '
|
|
572
|
-
+ 'card plan is cancelled there; the tool returns the link and charges nothing.
|
|
704
|
+
+ 'card plan is cancelled there; the tool returns the link and charges nothing. A card plan that is moving to '
|
|
705
|
+
+ 'wallet billing pays upgrade_to_pro and buy_credits from the wallet, and cancel works once the wallet bills it. '
|
|
706
|
+
+ 'On a team agent only a team '
|
|
573
707
|
+ 'admin, the organization\'s owner or the person who deployed the agent can pay for it or change its plan; '
|
|
574
708
|
+ 'other members are refused and nothing is charged.',
|
|
575
|
-
inputSchema: {
|
|
709
|
+
inputSchema: strictInput({
|
|
576
710
|
agent_guid: z.string().min(1).max(100)
|
|
577
711
|
.describe('The deployed agent\'s guid, from list_my_agents or deploy_agent.'),
|
|
578
712
|
action: z.enum(ACTIONS)
|
|
@@ -587,7 +721,7 @@ export function registerManageAgentBilling(server, client) {
|
|
|
587
721
|
.describe('With confirm: true, the amount the user approved, from the quote\'s nextAction (quote.chargeNowUsd, or quote.maxChargeUsd for upgrade_to_pro). Required for every action that charges: subscribe, upgrade_to_pro, buy_credits and renewing an expired plan. If a fresh quote no longer matches it, nothing is charged and the new quote is returned. For upgrade_to_pro it is the most the user agreed to pay now.'),
|
|
588
722
|
confirm: z.boolean().default(false)
|
|
589
723
|
.describe('false returns only the quote. true performs the action. Set it only after the user approved it.'),
|
|
590
|
-
},
|
|
724
|
+
}),
|
|
591
725
|
outputSchema: {
|
|
592
726
|
action: z.enum(ACTIONS),
|
|
593
727
|
agentGuid: z.string(),
|
|
@@ -618,7 +752,7 @@ export function registerManageAgentBilling(server, client) {
|
|
|
618
752
|
const summary = toAgentSummary(payload.agentRow);
|
|
619
753
|
const summaryLines = formatAgentSummaryLines(summary, plainMember);
|
|
620
754
|
const dashboardUrl = before?.dashboardUrl ?? agentDashboardUrl(guid);
|
|
621
|
-
const heading = {
|
|
755
|
+
const heading = payload.heading ?? {
|
|
622
756
|
quote: 'Quote (nothing done yet)',
|
|
623
757
|
done: 'Done',
|
|
624
758
|
not_needed: 'Nothing to do',
|
|
@@ -657,9 +791,9 @@ export function registerManageAgentBilling(server, client) {
|
|
|
657
791
|
before = agent;
|
|
658
792
|
plainMember = await isPlainTeamMember(client, row, extra.signal);
|
|
659
793
|
const raw = isPlainObject(row.subscription) ? row.subscription : null;
|
|
660
|
-
plan = planFor(client, action, agent, raw, { tier, pack, requestId: requestId ?? '' });
|
|
794
|
+
plan = await planFor(client, action, agent, raw, { tier, pack, requestId: requestId ?? '' }, extra.signal);
|
|
661
795
|
if (plan.outcome !== 'quote' || !plan.perform) {
|
|
662
|
-
return respond({ outcome: plan.outcome, message: plan.message, nextAction: plan.nextAction, agentRow: row });
|
|
796
|
+
return respond({ outcome: plan.outcome, heading: plan.heading, message: plan.message, nextAction: plan.nextAction, agentRow: row });
|
|
663
797
|
}
|
|
664
798
|
// A team member without admin rights can still be the person who
|
|
665
799
|
// deployed the agent, who may pay for it, so Wiro is asked before a quote.
|
|
@@ -728,6 +862,20 @@ export function registerManageAgentBilling(server, client) {
|
|
|
728
862
|
agentRow: after,
|
|
729
863
|
});
|
|
730
864
|
}
|
|
865
|
+
// A repeat adds no credits. A new pack can add none only when an older
|
|
866
|
+
// pack ends at the same moment with at least as many left, so an answer
|
|
867
|
+
// with no growth says only what holds in both cases.
|
|
868
|
+
if (fresh && extraAfter <= extraBefore) {
|
|
869
|
+
return respond({
|
|
870
|
+
outcome: 'done',
|
|
871
|
+
heading: 'Pack in place',
|
|
872
|
+
message: `The ${plan.quote?.pack} pack is in place: ${formatCredits(credits)} credits for ${formatUsd(plan.quote?.chargeNowUsd)} from ${agent.workspace === 'team' ? 'the team wallet' : 'the personal wallet'}. This request id is charged only once. The agent's extra credits did not grow in this call, so if the id had already completed in an earlier call, nothing new was bought or charged now. ${planChangeAgentNote(agent.status, 'a credit pack')} For another pack, get a new quote without request_id.`,
|
|
873
|
+
quote: plan.quote,
|
|
874
|
+
result: { chargedUsd: null },
|
|
875
|
+
nextAction: performed.nextAction,
|
|
876
|
+
agentRow: after,
|
|
877
|
+
});
|
|
878
|
+
}
|
|
731
879
|
return respond({
|
|
732
880
|
outcome: 'done',
|
|
733
881
|
message: fresh
|
|
@@ -780,7 +928,7 @@ export function registerManageAgentBilling(server, client) {
|
|
|
780
928
|
return errorResult(new Error(`${text}\n\nThe request was sent and the answer does not show whether it went through. ${observed.text} ${retry}`));
|
|
781
929
|
}
|
|
782
930
|
if (error instanceof ApiResultError)
|
|
783
|
-
return errorResult(annotateKnownRefusal(error));
|
|
931
|
+
return errorResult(annotateKnownRefusal(error, sentAtMs > 0 ? requestId : undefined));
|
|
784
932
|
return errorResult(error);
|
|
785
933
|
}
|
|
786
934
|
});
|