@suwujs/king-ai 0.2.0
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 +96 -0
- package/dist/src/agent-config-validation.d.ts +9 -0
- package/dist/src/agent-config-validation.js +30 -0
- package/dist/src/api.d.ts +4 -0
- package/dist/src/api.js +48 -0
- package/dist/src/attachments.d.ts +45 -0
- package/dist/src/attachments.js +322 -0
- package/dist/src/cli.d.ts +20 -0
- package/dist/src/cli.js +1697 -0
- package/dist/src/config.d.ts +3 -0
- package/dist/src/config.js +20 -0
- package/dist/src/cron.d.ts +11 -0
- package/dist/src/cron.js +65 -0
- package/dist/src/daemon.d.ts +36 -0
- package/dist/src/daemon.js +373 -0
- package/dist/src/engine.d.ts +32 -0
- package/dist/src/engine.js +1014 -0
- package/dist/src/heartbeat.d.ts +18 -0
- package/dist/src/heartbeat.js +28 -0
- package/dist/src/host-api.d.ts +40 -0
- package/dist/src/host-api.js +59 -0
- package/dist/src/host-control.d.ts +48 -0
- package/dist/src/host-control.js +1279 -0
- package/dist/src/host-export.d.ts +50 -0
- package/dist/src/host-export.js +187 -0
- package/dist/src/host-feedback.d.ts +78 -0
- package/dist/src/host-feedback.js +178 -0
- package/dist/src/host-home.d.ts +13 -0
- package/dist/src/host-home.js +54 -0
- package/dist/src/host-ledger.d.ts +261 -0
- package/dist/src/host-ledger.js +554 -0
- package/dist/src/host-loop-events.d.ts +69 -0
- package/dist/src/host-loop-events.js +288 -0
- package/dist/src/host-permission.d.ts +36 -0
- package/dist/src/host-permission.js +180 -0
- package/dist/src/host-policy.d.ts +15 -0
- package/dist/src/host-policy.js +36 -0
- package/dist/src/host-run-executor.d.ts +13 -0
- package/dist/src/host-run-executor.js +221 -0
- package/dist/src/host-run-heartbeat.d.ts +40 -0
- package/dist/src/host-run-heartbeat.js +103 -0
- package/dist/src/host-run-layout.d.ts +17 -0
- package/dist/src/host-run-layout.js +387 -0
- package/dist/src/host-run-meta.d.ts +41 -0
- package/dist/src/host-run-meta.js +115 -0
- package/dist/src/host-run-spec.d.ts +149 -0
- package/dist/src/host-run-spec.js +465 -0
- package/dist/src/host-runs.d.ts +77 -0
- package/dist/src/host-runs.js +195 -0
- package/dist/src/host-sdk.d.ts +412 -0
- package/dist/src/host-sdk.js +628 -0
- package/dist/src/host-server.d.ts +26 -0
- package/dist/src/host-server.js +921 -0
- package/dist/src/host-timeline.d.ts +24 -0
- package/dist/src/host-timeline.js +161 -0
- package/dist/src/jsonl.d.ts +13 -0
- package/dist/src/jsonl.js +47 -0
- package/dist/src/lifecycle.d.ts +5 -0
- package/dist/src/lifecycle.js +18 -0
- package/dist/src/message-routing.d.ts +32 -0
- package/dist/src/message-routing.js +119 -0
- package/dist/src/paths.d.ts +19 -0
- package/dist/src/paths.js +26 -0
- package/dist/src/project-profile.d.ts +49 -0
- package/dist/src/project-profile.js +356 -0
- package/dist/src/remediation.d.ts +14 -0
- package/dist/src/remediation.js +114 -0
- package/dist/src/remote-devices.d.ts +41 -0
- package/dist/src/remote-devices.js +156 -0
- package/dist/src/remote-diagnostics.d.ts +39 -0
- package/dist/src/remote-diagnostics.js +199 -0
- package/dist/src/remote-ssh.d.ts +39 -0
- package/dist/src/remote-ssh.js +129 -0
- package/dist/src/run-stream.d.ts +57 -0
- package/dist/src/run-stream.js +119 -0
- package/dist/src/runner.d.ts +131 -0
- package/dist/src/runner.js +1161 -0
- package/dist/src/runtime-data.d.ts +68 -0
- package/dist/src/runtime-data.js +172 -0
- package/dist/src/service.d.ts +114 -0
- package/dist/src/service.js +631 -0
- package/dist/src/shared-skills.d.ts +26 -0
- package/dist/src/shared-skills.js +85 -0
- package/dist/src/shim.d.ts +1 -0
- package/dist/src/shim.js +64 -0
- package/dist/src/skill-check.d.ts +17 -0
- package/dist/src/skill-check.js +158 -0
- package/dist/src/sse.d.ts +9 -0
- package/dist/src/sse.js +36 -0
- package/dist/src/team-routing.d.ts +55 -0
- package/dist/src/team-routing.js +131 -0
- package/dist/src/team-workflow.d.ts +78 -0
- package/dist/src/team-workflow.js +253 -0
- package/dist/src/text.d.ts +7 -0
- package/dist/src/text.js +27 -0
- package/dist/src/types.d.ts +98 -0
- package/dist/src/types.js +1 -0
- package/dist/src/usage.d.ts +116 -0
- package/dist/src/usage.js +350 -0
- package/dist/src/workspace.d.ts +9 -0
- package/dist/src/workspace.js +56 -0
- package/dist/src/worktree.d.ts +47 -0
- package/dist/src/worktree.js +201 -0
- package/package.json +63 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
export const KING_AI_ROLE_TEMPLATES = [
|
|
2
|
+
{
|
|
3
|
+
id: "planner",
|
|
4
|
+
name: "Planner",
|
|
5
|
+
responsibility: "Break ambiguous goals into ordered work, assign owners, track dependencies, and decide when human input is needed.",
|
|
6
|
+
defaultRoutingMode: "one-of-us",
|
|
7
|
+
capabilityHints: ["planning", "triage", "coordination"]
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
id: "builder",
|
|
11
|
+
name: "Builder",
|
|
12
|
+
responsibility: "Implement assigned product, code, document, or analysis changes and report exact artifacts produced.",
|
|
13
|
+
defaultRoutingMode: "one-of-us",
|
|
14
|
+
capabilityHints: ["implementation", "code", "docs"]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: "reviewer",
|
|
18
|
+
name: "Reviewer",
|
|
19
|
+
responsibility: "Review scope, risks, correctness, and acceptance evidence before work is marked done.",
|
|
20
|
+
defaultRoutingMode: "review-required",
|
|
21
|
+
capabilityHints: ["review", "quality", "risk"]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "tester",
|
|
25
|
+
name: "Tester",
|
|
26
|
+
responsibility: "Design and run verification, regression, and release-readiness checks with reproducible commands.",
|
|
27
|
+
defaultRoutingMode: "review-required",
|
|
28
|
+
capabilityHints: ["testing", "verification", "regression"]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "ops",
|
|
32
|
+
name: "Ops",
|
|
33
|
+
responsibility: "Handle environment, queue, release, deployment, audit, and operational safety work.",
|
|
34
|
+
defaultRoutingMode: "human-decision",
|
|
35
|
+
capabilityHints: ["ops", "release", "deployment", "audit"]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: "researcher",
|
|
39
|
+
name: "Researcher",
|
|
40
|
+
responsibility: "Collect evidence, compare options, preserve source quality, and turn findings into structured artifacts.",
|
|
41
|
+
defaultRoutingMode: "each",
|
|
42
|
+
capabilityHints: ["research", "evidence", "analysis"]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "doc-writer",
|
|
46
|
+
name: "Doc Writer",
|
|
47
|
+
responsibility: "Turn verified decisions and artifacts into user-facing documentation, release notes, and briefs.",
|
|
48
|
+
defaultRoutingMode: "one-of-us",
|
|
49
|
+
capabilityHints: ["documentation", "release-notes", "summary"]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "summarizer",
|
|
53
|
+
name: "Summarizer",
|
|
54
|
+
responsibility: "Close loops with concise status, residual risks, decisions, and artifact links.",
|
|
55
|
+
defaultRoutingMode: "one-of-us",
|
|
56
|
+
capabilityHints: ["summary", "handoff", "status"]
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
export function defaultTeamSpec(id = "default-team", name = "Default Team") {
|
|
60
|
+
const role = (template, overrides = {}) => {
|
|
61
|
+
const base = roleTemplateById(template);
|
|
62
|
+
return {
|
|
63
|
+
id: overrides.id ?? template,
|
|
64
|
+
template,
|
|
65
|
+
responsibility: overrides.responsibility ?? base.responsibility,
|
|
66
|
+
capabilities: overrides.capabilities ?? base.capabilityHints,
|
|
67
|
+
handoffPolicy: overrides.handoffPolicy ?? {
|
|
68
|
+
mode: base.defaultRoutingMode,
|
|
69
|
+
reviewerRole: template === "builder" ? "reviewer" : undefined,
|
|
70
|
+
escalation: template === "ops" ? "human" : "coordinator",
|
|
71
|
+
acceptanceRequired: template === "builder" || template === "reviewer" || template === "tester"
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
return {
|
|
76
|
+
id,
|
|
77
|
+
name,
|
|
78
|
+
roles: [
|
|
79
|
+
role("planner"),
|
|
80
|
+
role("builder"),
|
|
81
|
+
role("reviewer"),
|
|
82
|
+
role("tester"),
|
|
83
|
+
role("ops"),
|
|
84
|
+
role("researcher"),
|
|
85
|
+
role("doc-writer"),
|
|
86
|
+
role("summarizer")
|
|
87
|
+
],
|
|
88
|
+
routingPolicy: {
|
|
89
|
+
defaultMode: "one-of-us",
|
|
90
|
+
capabilityFirst: true,
|
|
91
|
+
reviewRequiredFor: ["code", "release", "ops", "external"],
|
|
92
|
+
humanDecisionFor: ["production-deploy", "scope-change", "spend", "security-risk"]
|
|
93
|
+
},
|
|
94
|
+
permissionPolicy: {
|
|
95
|
+
defaultDecision: "deny",
|
|
96
|
+
rules: [
|
|
97
|
+
{ role: "planner", allow: ["assign-task", "claim-task", "create-artifact", "create-decision", "close-task", "change-scope", "view-audit", "manage-queue", "view-cost"], requireHumanDecision: ["change-scope"] },
|
|
98
|
+
{ role: "builder", allow: ["claim-task", "create-artifact"], requireReviewBy: "reviewer" },
|
|
99
|
+
{ role: "reviewer", allow: ["claim-task", "create-artifact", "create-decision", "approve-decision", "close-task", "view-audit", "view-cost"] },
|
|
100
|
+
{ role: "tester", allow: ["claim-task", "create-artifact", "create-decision", "view-audit"] },
|
|
101
|
+
{ role: "ops", allow: ["claim-task", "create-artifact", "create-decision", "approve-decision", "deploy-release", "view-audit", "manage-queue", "view-cost"], requireHumanDecision: ["deploy-release"] },
|
|
102
|
+
{ role: "researcher", allow: ["claim-task", "create-artifact", "view-audit"] },
|
|
103
|
+
{ role: "doc-writer", allow: ["claim-task", "create-artifact", "view-audit"] },
|
|
104
|
+
{ role: "summarizer", allow: ["claim-task", "create-artifact", "view-audit"] }
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export function checkTeamPermission(team, role, action) {
|
|
110
|
+
const normalizedRole = normalizeTeamRoleId(role);
|
|
111
|
+
const rule = team.permissionPolicy.rules.find((entry) => entry.role === normalizedRole);
|
|
112
|
+
if (!rule || !rule.allow.includes(action))
|
|
113
|
+
return { decision: "deny" };
|
|
114
|
+
if (rule.requireHumanDecision?.includes(action))
|
|
115
|
+
return { decision: "human-decision", rule };
|
|
116
|
+
return { decision: "allow", rule };
|
|
117
|
+
}
|
|
118
|
+
export function normalizeTeamRoleId(role) {
|
|
119
|
+
const value = role.trim();
|
|
120
|
+
const aliases = {
|
|
121
|
+
ceo: "planner",
|
|
122
|
+
"king-ai-ceo": "planner",
|
|
123
|
+
cto: "reviewer",
|
|
124
|
+
dev: "builder",
|
|
125
|
+
devops: "ops",
|
|
126
|
+
feedback: "researcher",
|
|
127
|
+
marketing: "doc-writer",
|
|
128
|
+
docs: "doc-writer"
|
|
129
|
+
};
|
|
130
|
+
return aliases[value] ?? value;
|
|
131
|
+
}
|
|
132
|
+
export function roleTemplateForAgent(agent) {
|
|
133
|
+
const text = `${agent.id ?? ""} ${agent.name ?? ""} ${agent.role ?? ""}`.toLowerCase();
|
|
134
|
+
const explicit = text.match(/role template:\s*([a-z-]+)/)?.[1];
|
|
135
|
+
if (explicit && isRoleTemplateId(explicit))
|
|
136
|
+
return explicit;
|
|
137
|
+
if (agent.id === "dev")
|
|
138
|
+
return "builder";
|
|
139
|
+
if (agent.id === "reviewer")
|
|
140
|
+
return "reviewer";
|
|
141
|
+
if (agent.id === "king-ai-ceo")
|
|
142
|
+
return "planner";
|
|
143
|
+
if (text.includes("tester"))
|
|
144
|
+
return "tester";
|
|
145
|
+
if (text.includes("doc-writer") || text.includes("doc writer") || text.includes("documentation"))
|
|
146
|
+
return "doc-writer";
|
|
147
|
+
if (text.includes("ops") || text.includes("devops") || text.includes("release"))
|
|
148
|
+
return "ops";
|
|
149
|
+
if (text.includes("researcher") || text.includes("research"))
|
|
150
|
+
return "researcher";
|
|
151
|
+
if (text.includes("reviewer"))
|
|
152
|
+
return "reviewer";
|
|
153
|
+
if (text.includes("builder") || text.includes("implement"))
|
|
154
|
+
return "builder";
|
|
155
|
+
if (text.includes("planner") || text.includes("ceo") || text.includes("coordinate"))
|
|
156
|
+
return "planner";
|
|
157
|
+
return "builder";
|
|
158
|
+
}
|
|
159
|
+
export function requiredCapabilitiesForText(text) {
|
|
160
|
+
const value = text.toLowerCase();
|
|
161
|
+
if (/\b(test|verify|verification|regression|qa)\b/.test(value))
|
|
162
|
+
return ["testing", "verification"];
|
|
163
|
+
if (/\b(release|deploy|queue|approval|audit|ops)\b/.test(value))
|
|
164
|
+
return ["ops", "release", "audit"];
|
|
165
|
+
if (/\b(research|compare|brief|market|source|evidence)\b/.test(value))
|
|
166
|
+
return ["research", "evidence"];
|
|
167
|
+
if (/\b(doc|docs|readme|release note|write|summary)\b/.test(value))
|
|
168
|
+
return ["documentation", "summary"];
|
|
169
|
+
return ["implementation", "code"];
|
|
170
|
+
}
|
|
171
|
+
export function roleTemplateById(id) {
|
|
172
|
+
const template = KING_AI_ROLE_TEMPLATES.find((entry) => entry.id === id);
|
|
173
|
+
if (!template)
|
|
174
|
+
throw new Error(`unknown role template: ${id}`);
|
|
175
|
+
return template;
|
|
176
|
+
}
|
|
177
|
+
function isRoleTemplateId(value) {
|
|
178
|
+
return KING_AI_ROLE_TEMPLATES.some((template) => template.id === value);
|
|
179
|
+
}
|
|
180
|
+
export function scenarioTemplate(id) {
|
|
181
|
+
const team = defaultTeamSpec(`${id}-team`, `${titleCase(id)} Team`);
|
|
182
|
+
const commonAcceptance = [
|
|
183
|
+
"Every task has an owner role and acceptance evidence.",
|
|
184
|
+
"Review-required work has a reviewer role before completion.",
|
|
185
|
+
"Human decisions are represented as decision workflow objects."
|
|
186
|
+
];
|
|
187
|
+
const scenarios = {
|
|
188
|
+
"repo-takeover": {
|
|
189
|
+
id,
|
|
190
|
+
name: "Repo Takeover",
|
|
191
|
+
goal: "Understand a repository, establish safe operating boundaries, and produce a takeover-ready plan.",
|
|
192
|
+
team,
|
|
193
|
+
acceptance: [...commonAcceptance, "Repository structure, build/test commands, and risk areas are captured."],
|
|
194
|
+
tasks: [
|
|
195
|
+
{ title: "Map repository structure and ownership boundaries", ownerRole: "researcher", reviewerRole: "planner", acceptance: ["Key modules and commands are documented."] },
|
|
196
|
+
{ title: "Create takeover backlog and capsule boundaries", ownerRole: "planner", reviewerRole: "reviewer", dependsOn: ["task-1"], acceptance: ["Backlog has ordered tasks and scoped capsules."] },
|
|
197
|
+
{ title: "Verify build and test entrypoints", ownerRole: "tester", reviewerRole: "ops", dependsOn: ["task-1"], acceptance: ["Verification commands and failures are recorded."] }
|
|
198
|
+
]
|
|
199
|
+
},
|
|
200
|
+
"bug-investigation": {
|
|
201
|
+
id,
|
|
202
|
+
name: "Bug Investigation",
|
|
203
|
+
goal: "Find root cause, propose a focused fix, verify behavior, and produce a concise incident artifact.",
|
|
204
|
+
team,
|
|
205
|
+
acceptance: [...commonAcceptance, "Root cause is linked to code/runtime evidence."],
|
|
206
|
+
tasks: [
|
|
207
|
+
{ title: "Reproduce and isolate symptom", ownerRole: "tester", reviewerRole: "researcher", acceptance: ["Reproduction or strongest available evidence is recorded."] },
|
|
208
|
+
{ title: "Trace root cause and candidate fix", ownerRole: "builder", reviewerRole: "reviewer", dependsOn: ["task-1"], acceptance: ["Cause and changed files are identified."] },
|
|
209
|
+
{ title: "Verify fix and summarize residual risk", ownerRole: "reviewer", reviewerRole: "planner", dependsOn: ["task-2"], acceptance: ["Regression evidence and risk summary are recorded."] }
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
"product-design": {
|
|
213
|
+
id,
|
|
214
|
+
name: "Product Design",
|
|
215
|
+
goal: "Turn a product idea into roles, user flows, acceptance criteria, and implementation-ready artifacts.",
|
|
216
|
+
team,
|
|
217
|
+
acceptance: [...commonAcceptance, "Design decisions are explicit and unresolved choices are escalated."],
|
|
218
|
+
tasks: [
|
|
219
|
+
{ title: "Research user goals and competing workflows", ownerRole: "researcher", reviewerRole: "planner", acceptance: ["Insights and assumptions are captured."] },
|
|
220
|
+
{ title: "Define user flow and acceptance criteria", ownerRole: "planner", reviewerRole: "reviewer", dependsOn: ["task-1"], acceptance: ["Flow, scope, and non-goals are written."] },
|
|
221
|
+
{ title: "Draft implementation-facing design artifact", ownerRole: "doc-writer", reviewerRole: "builder", dependsOn: ["task-2"], acceptance: ["Artifact is ready for build planning."] }
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
"release-check": {
|
|
225
|
+
id,
|
|
226
|
+
name: "Release Check",
|
|
227
|
+
goal: "Validate readiness for release with testing, risk review, approvals, and release notes.",
|
|
228
|
+
team,
|
|
229
|
+
acceptance: [...commonAcceptance, "Release decision is represented as an approval or decision object."],
|
|
230
|
+
tasks: [
|
|
231
|
+
{ title: "Run release verification checklist", ownerRole: "tester", reviewerRole: "ops", acceptance: ["Commands, pass/fail state, and gaps are recorded."] },
|
|
232
|
+
{ title: "Review operational and regression risk", ownerRole: "reviewer", reviewerRole: "ops", dependsOn: ["task-1"], acceptance: ["Risks and mitigations are recorded."] },
|
|
233
|
+
{ title: "Prepare release notes and human decision", ownerRole: "doc-writer", reviewerRole: "planner", dependsOn: ["task-2"], acceptance: ["Release notes and approval question exist."] }
|
|
234
|
+
]
|
|
235
|
+
},
|
|
236
|
+
"research-brief": {
|
|
237
|
+
id,
|
|
238
|
+
name: "Research Brief",
|
|
239
|
+
goal: "Produce a sourced, confidence-scored brief with decisions, artifacts, and follow-up tasks.",
|
|
240
|
+
team,
|
|
241
|
+
acceptance: [...commonAcceptance, "Claims include source quality and confidence."],
|
|
242
|
+
tasks: [
|
|
243
|
+
{ title: "Collect evidence and competing viewpoints", ownerRole: "researcher", reviewerRole: "reviewer", acceptance: ["Artifacts include source and confidence."] },
|
|
244
|
+
{ title: "Synthesize brief and recommendations", ownerRole: "doc-writer", reviewerRole: "planner", dependsOn: ["task-1"], acceptance: ["Brief includes recommendation and caveats."] },
|
|
245
|
+
{ title: "Record decision points and follow-up tasks", ownerRole: "planner", reviewerRole: "reviewer", dependsOn: ["task-2"], acceptance: ["Open decisions and next tasks are explicit."] }
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
return scenarios[id];
|
|
250
|
+
}
|
|
251
|
+
function titleCase(value) {
|
|
252
|
+
return value.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
253
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const ANSI_RE: RegExp;
|
|
2
|
+
export declare function stripLoneSurrogates(s: string): string;
|
|
3
|
+
export declare function cleanLine(line: string): string;
|
|
4
|
+
export declare function concise(text: string, max?: number): string;
|
|
5
|
+
export declare function hashText(text: string): string;
|
|
6
|
+
export declare function isRateLimited(text: string): boolean;
|
|
7
|
+
export declare function authFailureHint(engine: string, detail: string): string;
|
package/dist/src/text.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { engineRemediationAdvice, formatRemediationAdvice } from "./remediation.js";
|
|
2
|
+
export const ANSI_RE = /\x1B\[[0-?]*[ -/]*[@-~]/g;
|
|
3
|
+
export function stripLoneSurrogates(s) {
|
|
4
|
+
return s
|
|
5
|
+
.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])/g, "")
|
|
6
|
+
.replace(/(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
7
|
+
}
|
|
8
|
+
export function cleanLine(line) {
|
|
9
|
+
return line.replace(ANSI_RE, "").replace(/\r/g, "").trim();
|
|
10
|
+
}
|
|
11
|
+
export function concise(text, max = 900) {
|
|
12
|
+
return cleanLine(text).slice(0, max);
|
|
13
|
+
}
|
|
14
|
+
export function hashText(text) {
|
|
15
|
+
let hash = 0x811c9dc5;
|
|
16
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
17
|
+
hash ^= text.charCodeAt(i);
|
|
18
|
+
hash = Math.imul(hash, 0x01000193) >>> 0;
|
|
19
|
+
}
|
|
20
|
+
return hash.toString(16).padStart(8, "0").slice(0, 8);
|
|
21
|
+
}
|
|
22
|
+
export function isRateLimited(text) {
|
|
23
|
+
return /\b(429|503)\b|too many requests|rate.?limit|\bquota\b|resource_exhausted|usage limit|session limit|overloaded|insufficient_quota|service (temporarily )?unavailable/i.test(text);
|
|
24
|
+
}
|
|
25
|
+
export function authFailureHint(engine, detail) {
|
|
26
|
+
return formatRemediationAdvice(engineRemediationAdvice(engine, detail));
|
|
27
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export type EngineId = "claude" | "codex";
|
|
2
|
+
export type AgentLifecycle = "on-demand" | "24/7" | "idle_cached" | "disabled";
|
|
3
|
+
export interface ComputerConfig {
|
|
4
|
+
serverUrl: string;
|
|
5
|
+
computerId: string;
|
|
6
|
+
deviceToken: string;
|
|
7
|
+
tenantId?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface AgentConfig {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
role?: string;
|
|
13
|
+
engine?: EngineId;
|
|
14
|
+
model?: string;
|
|
15
|
+
fastModel?: string;
|
|
16
|
+
lifecycle?: AgentLifecycle;
|
|
17
|
+
}
|
|
18
|
+
export interface RuntimeRun {
|
|
19
|
+
runId?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface TriageVerdict {
|
|
22
|
+
actionable: boolean;
|
|
23
|
+
reason?: string;
|
|
24
|
+
promptNote?: string;
|
|
25
|
+
source?: string;
|
|
26
|
+
responseMode?: "me" | "each" | "one-of-us";
|
|
27
|
+
routeHint?: "ignore" | "monitor" | "respond" | "steer";
|
|
28
|
+
priority?: "normal" | "steer" | "urgent";
|
|
29
|
+
}
|
|
30
|
+
export interface EngineUsage {
|
|
31
|
+
input_tokens?: number;
|
|
32
|
+
cache_read_input_tokens?: number;
|
|
33
|
+
output_tokens?: number;
|
|
34
|
+
}
|
|
35
|
+
export interface EngineResult {
|
|
36
|
+
exitCode: number;
|
|
37
|
+
error?: string;
|
|
38
|
+
sessionId?: string | null;
|
|
39
|
+
usage?: EngineUsage;
|
|
40
|
+
model?: string | null;
|
|
41
|
+
}
|
|
42
|
+
export interface EngineTurnOptions {
|
|
43
|
+
imagePaths?: string[];
|
|
44
|
+
}
|
|
45
|
+
export interface EngineSession {
|
|
46
|
+
readonly alive: boolean;
|
|
47
|
+
readonly sessionId: string | null;
|
|
48
|
+
readonly carriesStandingPrompt: boolean;
|
|
49
|
+
send(prompt: string, options?: EngineTurnOptions): Promise<EngineResult>;
|
|
50
|
+
steer(text: string): void;
|
|
51
|
+
stop(): void;
|
|
52
|
+
}
|
|
53
|
+
export interface EngineRunArgs {
|
|
54
|
+
home: string;
|
|
55
|
+
prompt: string;
|
|
56
|
+
env: NodeJS.ProcessEnv;
|
|
57
|
+
model?: string;
|
|
58
|
+
fastModel?: string;
|
|
59
|
+
resumeSessionId?: string | null;
|
|
60
|
+
standingPrompt?: string;
|
|
61
|
+
imagePaths?: string[];
|
|
62
|
+
signal: AbortSignal;
|
|
63
|
+
onLog: (line: string) => void;
|
|
64
|
+
}
|
|
65
|
+
export interface EngineProbeArgs {
|
|
66
|
+
cwd: string;
|
|
67
|
+
env: NodeJS.ProcessEnv;
|
|
68
|
+
tier: "small" | "big";
|
|
69
|
+
signal: AbortSignal;
|
|
70
|
+
}
|
|
71
|
+
export interface EngineClassifyArgs {
|
|
72
|
+
cwd: string;
|
|
73
|
+
prompt: string;
|
|
74
|
+
env: NodeJS.ProcessEnv;
|
|
75
|
+
model?: string;
|
|
76
|
+
signal: AbortSignal;
|
|
77
|
+
onLog?: (line: string) => void;
|
|
78
|
+
}
|
|
79
|
+
export interface EngineAdapter {
|
|
80
|
+
id: EngineId;
|
|
81
|
+
bin: string;
|
|
82
|
+
seedHome(home: string, persona: {
|
|
83
|
+
id: string;
|
|
84
|
+
name: string;
|
|
85
|
+
role?: string;
|
|
86
|
+
}): Promise<void>;
|
|
87
|
+
classify(args: EngineClassifyArgs): Promise<{
|
|
88
|
+
text: string;
|
|
89
|
+
error?: string;
|
|
90
|
+
usage?: EngineUsage;
|
|
91
|
+
}>;
|
|
92
|
+
probe(args: EngineProbeArgs): Promise<{
|
|
93
|
+
text: string;
|
|
94
|
+
error?: string;
|
|
95
|
+
}>;
|
|
96
|
+
run(args: EngineRunArgs): Promise<EngineResult>;
|
|
97
|
+
startSession?(args: Omit<EngineRunArgs, "prompt" | "signal">): EngineSession | null;
|
|
98
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export interface UsageTotals {
|
|
2
|
+
inputTokens: number;
|
|
3
|
+
cacheReadInputTokens: number;
|
|
4
|
+
outputTokens: number;
|
|
5
|
+
totalTokens: number;
|
|
6
|
+
}
|
|
7
|
+
export interface UsagePricingRule {
|
|
8
|
+
key: string;
|
|
9
|
+
currency: string;
|
|
10
|
+
inputPerMillionTokens?: number;
|
|
11
|
+
cacheReadInputPerMillionTokens?: number;
|
|
12
|
+
outputPerMillionTokens?: number;
|
|
13
|
+
source?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface UsageCostSummary {
|
|
16
|
+
amount: number;
|
|
17
|
+
currency: string;
|
|
18
|
+
inputCost: number;
|
|
19
|
+
cacheReadInputCost: number;
|
|
20
|
+
outputCost: number;
|
|
21
|
+
pricedTokens: number;
|
|
22
|
+
unpricedTokens: number;
|
|
23
|
+
pricingKeys: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface AgentRunStats extends UsageTotals {
|
|
26
|
+
turns: number;
|
|
27
|
+
completed: number;
|
|
28
|
+
failed: number;
|
|
29
|
+
lastRunAt?: string;
|
|
30
|
+
lastDurationMs?: number;
|
|
31
|
+
lastStatus?: "completed" | "failed";
|
|
32
|
+
lastModel?: string | null;
|
|
33
|
+
}
|
|
34
|
+
export interface TokenBudgetCheck {
|
|
35
|
+
budget: number;
|
|
36
|
+
used: number;
|
|
37
|
+
remaining: number;
|
|
38
|
+
warning: boolean;
|
|
39
|
+
exceeded: boolean;
|
|
40
|
+
state: "ok" | "warning" | "exceeded";
|
|
41
|
+
}
|
|
42
|
+
export interface UsageAgentInput {
|
|
43
|
+
id: string;
|
|
44
|
+
name?: string;
|
|
45
|
+
engine: string;
|
|
46
|
+
model?: string | null;
|
|
47
|
+
runStats?: AgentRunStats;
|
|
48
|
+
tokenBudget?: TokenBudgetCheck;
|
|
49
|
+
}
|
|
50
|
+
export interface UsageGroupSummary extends UsageTotals {
|
|
51
|
+
key: string;
|
|
52
|
+
turns: number;
|
|
53
|
+
completed: number;
|
|
54
|
+
failed: number;
|
|
55
|
+
agents: number;
|
|
56
|
+
cost?: UsageCostSummary;
|
|
57
|
+
}
|
|
58
|
+
export interface UsageAgentSummary extends UsageGroupSummary {
|
|
59
|
+
id: string;
|
|
60
|
+
name?: string;
|
|
61
|
+
engine: string;
|
|
62
|
+
model?: string | null;
|
|
63
|
+
lastRunAt?: string;
|
|
64
|
+
lastStatus?: "completed" | "failed";
|
|
65
|
+
tokenBudget?: TokenBudgetCheck;
|
|
66
|
+
cost?: UsageCostSummary;
|
|
67
|
+
}
|
|
68
|
+
export interface UsageSummary extends UsageTotals {
|
|
69
|
+
agents: UsageAgentSummary[];
|
|
70
|
+
byEngine: UsageGroupSummary[];
|
|
71
|
+
byModel: UsageGroupSummary[];
|
|
72
|
+
turns: number;
|
|
73
|
+
completed: number;
|
|
74
|
+
failed: number;
|
|
75
|
+
budget?: TokenBudgetCheck;
|
|
76
|
+
cost?: UsageCostSummary;
|
|
77
|
+
}
|
|
78
|
+
export interface UsageExpenseRow extends UsageTotals {
|
|
79
|
+
agentId: string;
|
|
80
|
+
agentName?: string;
|
|
81
|
+
engine: string;
|
|
82
|
+
model: string;
|
|
83
|
+
turns: number;
|
|
84
|
+
completed: number;
|
|
85
|
+
failed: number;
|
|
86
|
+
currency: string;
|
|
87
|
+
amount: number;
|
|
88
|
+
inputCost: number;
|
|
89
|
+
cacheReadInputCost: number;
|
|
90
|
+
outputCost: number;
|
|
91
|
+
pricedTokens: number;
|
|
92
|
+
unpricedTokens: number;
|
|
93
|
+
pricingKeys: string[];
|
|
94
|
+
lastRunAt?: string;
|
|
95
|
+
lastStatus?: "completed" | "failed";
|
|
96
|
+
}
|
|
97
|
+
export declare function normalizeEngineUsage(usage: unknown): UsageTotals;
|
|
98
|
+
export declare function emptyAgentRunStats(): AgentRunStats;
|
|
99
|
+
export declare function recordAgentRunStats(current: AgentRunStats, args: {
|
|
100
|
+
status: "completed" | "failed";
|
|
101
|
+
usage?: unknown;
|
|
102
|
+
durationMs: number;
|
|
103
|
+
model?: string | null;
|
|
104
|
+
at?: string;
|
|
105
|
+
}): AgentRunStats;
|
|
106
|
+
export declare function formatAgentRunStats(stats?: AgentRunStats): string;
|
|
107
|
+
export declare function tokenBudgetFromEnv(env?: NodeJS.ProcessEnv): number | null;
|
|
108
|
+
export declare function usagePricingFromEnv(env?: NodeJS.ProcessEnv): UsagePricingRule[];
|
|
109
|
+
export declare function normalizeUsagePricing(value: unknown): UsagePricingRule[];
|
|
110
|
+
export declare function estimateUsageCost(totals: UsageTotals, pricing?: UsagePricingRule | null): UsageCostSummary | undefined;
|
|
111
|
+
export declare function checkTokenBudget(stats: AgentRunStats | undefined, budget: number | null | undefined): TokenBudgetCheck | undefined;
|
|
112
|
+
export declare function formatTokenBudgetCheck(check?: TokenBudgetCheck): string;
|
|
113
|
+
export declare function summarizeAgentUsage(agents?: UsageAgentInput[], budget?: number | null | undefined, pricingRules?: UsagePricingRule[]): UsageSummary;
|
|
114
|
+
export declare function formatUsageSummary(summary: UsageSummary): string;
|
|
115
|
+
export declare function listUsageExpenses(summary: UsageSummary): UsageExpenseRow[];
|
|
116
|
+
export declare function formatUsageExpenses(rows: UsageExpenseRow[]): string;
|