@byfriends/sdk 0.2.3 → 0.2.5
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/dist/index.d.mts +7 -1
- package/dist/index.mjs +26 -10
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -393,6 +393,7 @@ export declare type BackgroundConfig = z.infer<typeof BackgroundConfigSchema>;
|
|
|
393
393
|
|
|
394
394
|
declare const BackgroundConfigSchema: z.ZodObject<{
|
|
395
395
|
maxRunningTasks: z.ZodOptional<z.ZodNumber>;
|
|
396
|
+
maxConcurrentSubagents: z.ZodOptional<z.ZodNumber>;
|
|
396
397
|
keepAliveOnExit: z.ZodOptional<z.ZodBoolean>;
|
|
397
398
|
killGracePeriodMs: z.ZodOptional<z.ZodNumber>;
|
|
398
399
|
agentTaskTimeoutS: z.ZodOptional<z.ZodNumber>;
|
|
@@ -1217,6 +1218,7 @@ declare const ByfConfigPatchSchema: z.ZodObject<{
|
|
|
1217
1218
|
}, z.core.$strip>>;
|
|
1218
1219
|
background: z.ZodOptional<z.ZodObject<{
|
|
1219
1220
|
maxRunningTasks: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
1221
|
+
maxConcurrentSubagents: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
1220
1222
|
keepAliveOnExit: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
|
|
1221
1223
|
killGracePeriodMs: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
1222
1224
|
agentTaskTimeoutS: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -1354,6 +1356,7 @@ declare const ByfConfigSchema: z.ZodObject<{
|
|
|
1354
1356
|
}, z.core.$strip>>;
|
|
1355
1357
|
background: z.ZodOptional<z.ZodObject<{
|
|
1356
1358
|
maxRunningTasks: z.ZodOptional<z.ZodNumber>;
|
|
1359
|
+
maxConcurrentSubagents: z.ZodOptional<z.ZodNumber>;
|
|
1357
1360
|
keepAliveOnExit: z.ZodOptional<z.ZodBoolean>;
|
|
1358
1361
|
killGracePeriodMs: z.ZodOptional<z.ZodNumber>;
|
|
1359
1362
|
agentTaskTimeoutS: z.ZodOptional<z.ZodNumber>;
|
|
@@ -4384,10 +4387,13 @@ declare class SessionSubagentHost {
|
|
|
4384
4387
|
private readonly ownerAgentId;
|
|
4385
4388
|
readonly backgroundTaskTimeoutMs?: number | undefined;
|
|
4386
4389
|
private readonly activeChildren;
|
|
4387
|
-
|
|
4390
|
+
/** Maximum concurrent subagents; exposed for testing and config diagnostics. */
|
|
4391
|
+
readonly maxConcurrentSubagents: number;
|
|
4392
|
+
constructor(session: Session_2, ownerAgentId: string, backgroundTaskTimeoutMs?: number | undefined, maxConcurrentSubagents?: number | undefined);
|
|
4388
4393
|
spawn(profileName: string, options: RunSubagentOptions): Promise<SubagentHandle>;
|
|
4389
4394
|
resume(agentId: string, options: RunSubagentOptions): Promise<SubagentHandle>;
|
|
4390
4395
|
cancelAll(): void;
|
|
4396
|
+
private assertCanSpawn;
|
|
4391
4397
|
getProfileName(agentId: string): string | undefined;
|
|
4392
4398
|
private resolveProfile;
|
|
4393
4399
|
private runChild;
|
package/dist/index.mjs
CHANGED
|
@@ -56166,7 +56166,7 @@ var agent_background_disabled_default = "Background agent execution is disabled
|
|
|
56166
56166
|
var agent_background_enabled_default = "When `run_in_background=true`, the subagent runs detached from this turn. The completion arrives in a later turn as a synthetic user-role message containing its result — you do not need to poll, sleep, or check on its progress. Continue with other work or respond to the user. Never fabricate or predict what the result will say.\n\nFor a background task, when `timeout` is omitted it falls back to the operator-configured background timeout, if one is set. If the operator has not configured a background timeout, an omitted `timeout` means the task runs with no time limit.\n";
|
|
56167
56167
|
//#endregion
|
|
56168
56168
|
//#region ../agent-core/src/tools/builtin/collaboration/agent.md
|
|
56169
|
-
var agent_default = "Launch a subagent to handle a task. The subagent starts with zero context — it has not seen this conversation. Brief it with the goal, what you already know, and exact paths or commands.\n\n- When the task continues earlier work a subagent already did, prefer resuming that agent (pass its `resume` id) over spawning a fresh instance.\n- A subagent's result is only visible to you, not to the user. Summarize the relevant parts yourself when the user needs to see them.\n- Skip delegation for trivial work you can do directly — reading a known file, searching a small set of files, or any one-step task.\n- Once a subagent is running, do not redo its searches or reads in parallel, and do not abandon it midway and finish the job manually.\n";
|
|
56169
|
+
var agent_default = "Launch a subagent to handle a task. The subagent starts with zero context — it has not seen this conversation. Brief it with the goal, what you already know, and exact paths or commands.\n\n- When the task continues earlier work a subagent already did, prefer resuming that agent (pass its `resume` id) over spawning a fresh instance.\n- A subagent's result is only visible to you, not to the user. Summarize the relevant parts yourself when the user needs to see them.\n- Skip delegation for trivial work you can do directly — reading a known file, searching a small set of files, or any one-step task.\n- Once a subagent is running, do not redo its searches or reads in parallel, and do not abandon it midway and finish the job manually.\n- There is a concurrency limit on parallel subagents. If the limit is reached, wait for a running subagent to complete before launching another.\n";
|
|
56170
56170
|
//#endregion
|
|
56171
56171
|
//#region ../agent-core/src/tools/builtin/collaboration/agent.ts
|
|
56172
56172
|
/**
|
|
@@ -70841,7 +70841,7 @@ var SkillManager = class {
|
|
|
70841
70841
|
const skill = this.registry.getSkill(input.name);
|
|
70842
70842
|
if (skill === void 0) throw new ByfError(ErrorCodes.SKILL_NOT_FOUND, `Skill "${input.name}" was not found`);
|
|
70843
70843
|
if (!isUserActivatableSkillType(skill.metadata.type)) throw new ByfError(ErrorCodes.SKILL_TYPE_UNSUPPORTED, `Skill "${skill.name}" cannot be activated by the user`);
|
|
70844
|
-
|
|
70844
|
+
const origin = {
|
|
70845
70845
|
kind: "skill_activation",
|
|
70846
70846
|
activationId: randomUUID(),
|
|
70847
70847
|
skillName: skill.name,
|
|
@@ -70850,10 +70850,13 @@ var SkillManager = class {
|
|
|
70850
70850
|
skillPath: skill.path,
|
|
70851
70851
|
skillSource: skill.source,
|
|
70852
70852
|
skillArgs: input.args
|
|
70853
|
-
}
|
|
70853
|
+
};
|
|
70854
|
+
const skillContent = this.registry.renderSkillPrompt(skill, input.args ?? "");
|
|
70855
|
+
this.recordActivation(origin, [{
|
|
70854
70856
|
type: "text",
|
|
70855
|
-
text:
|
|
70857
|
+
text: skillContent
|
|
70856
70858
|
}]);
|
|
70859
|
+
this.agent.context.appendSystemReminder(`<byf-skill-loaded name="${skill.name}">\n${skillContent}\n</byf-skill-loaded>`, origin);
|
|
70857
70860
|
}
|
|
70858
70861
|
recordActivation(origin, input) {
|
|
70859
70862
|
this.agent.emitEvent({
|
|
@@ -78851,9 +78854,8 @@ function createChatStreamingCallbacks(deps) {
|
|
|
78851
78854
|
* enforcement, usage aggregation, optional continuation after non-tool stops,
|
|
78852
78855
|
* and final `TurnResult` mapping. One-step execution lives in `turn-step.ts`.
|
|
78853
78856
|
*/
|
|
78854
|
-
const DEFAULT_MAX_STEPS = 1e3;
|
|
78855
78857
|
async function runTurn(input) {
|
|
78856
|
-
const { turnId, signal, llm, buildMessages, dispatchEvent, tools, hooks, log, maxSteps
|
|
78858
|
+
const { turnId, signal, llm, buildMessages, dispatchEvent, tools, hooks, log, maxSteps, maxRetryAttempts } = input;
|
|
78857
78859
|
let usage = emptyUsage();
|
|
78858
78860
|
let steps = 0;
|
|
78859
78861
|
let stopReason = "end_turn";
|
|
@@ -78864,7 +78866,7 @@ async function runTurn(input) {
|
|
|
78864
78866
|
try {
|
|
78865
78867
|
while (true) {
|
|
78866
78868
|
signal.throwIfAborted();
|
|
78867
|
-
if (steps >= maxSteps) throw createMaxStepsExceededError(maxSteps);
|
|
78869
|
+
if (maxSteps !== void 0 && steps >= maxSteps) throw createMaxStepsExceededError(maxSteps);
|
|
78868
78870
|
steps += 1;
|
|
78869
78871
|
activeStep = steps;
|
|
78870
78872
|
const stepResult = await executeLoopStep({
|
|
@@ -84517,7 +84519,7 @@ var Agent = class {
|
|
|
84517
84519
|
this.usage = new UsageRecorder(this);
|
|
84518
84520
|
this.tools = new ToolManager(this);
|
|
84519
84521
|
this.background = new BackgroundManager(this, {
|
|
84520
|
-
maxRunningTasks: config.backgroundMaxRunningTasks,
|
|
84522
|
+
maxRunningTasks: config.backgroundMaxRunningTasks ?? 10,
|
|
84521
84523
|
sessionDir: config.backgroundSessionDir
|
|
84522
84524
|
});
|
|
84523
84525
|
this.replayBuilder = new ReplayBuilder(this);
|
|
@@ -84889,6 +84891,7 @@ const LoopControlSchema = z.object({
|
|
|
84889
84891
|
});
|
|
84890
84892
|
const BackgroundConfigSchema = z.object({
|
|
84891
84893
|
maxRunningTasks: z.number().int().min(1).optional(),
|
|
84894
|
+
maxConcurrentSubagents: z.number().int().min(1).optional(),
|
|
84892
84895
|
keepAliveOnExit: z.boolean().optional(),
|
|
84893
84896
|
killGracePeriodMs: z.number().int().min(0).optional(),
|
|
84894
84897
|
agentTaskTimeoutS: z.number().int().min(1).optional(),
|
|
@@ -89035,18 +89038,27 @@ const SUMMARY_MAX_LENGTH = 8e3;
|
|
|
89035
89038
|
const SUMMARY_CONTINUATION_ATTEMPTS = 1;
|
|
89036
89039
|
const HOOK_TEXT_PREVIEW_LENGTH = 500;
|
|
89037
89040
|
const SUBAGENT_MAX_TOKENS_ERROR = "Subagent turn failed before completing its final summary: reason=max_tokens";
|
|
89041
|
+
/**
|
|
89042
|
+
* Maximum number of concurrently running subagents per parent.
|
|
89043
|
+
* Prevents cascading subagent proliferation that exhausts LLM bandwidth.
|
|
89044
|
+
*/
|
|
89045
|
+
const DEFAULT_MAX_CONCURRENT_SUBAGENTS = 5;
|
|
89038
89046
|
var SessionSubagentHost = class {
|
|
89039
89047
|
session;
|
|
89040
89048
|
ownerAgentId;
|
|
89041
89049
|
backgroundTaskTimeoutMs;
|
|
89042
89050
|
activeChildren = /* @__PURE__ */ new Map();
|
|
89043
|
-
|
|
89051
|
+
/** Maximum concurrent subagents; exposed for testing and config diagnostics. */
|
|
89052
|
+
maxConcurrentSubagents;
|
|
89053
|
+
constructor(session, ownerAgentId, backgroundTaskTimeoutMs, maxConcurrentSubagents = void 0) {
|
|
89044
89054
|
this.session = session;
|
|
89045
89055
|
this.ownerAgentId = ownerAgentId;
|
|
89046
89056
|
this.backgroundTaskTimeoutMs = backgroundTaskTimeoutMs;
|
|
89057
|
+
this.maxConcurrentSubagents = maxConcurrentSubagents ?? DEFAULT_MAX_CONCURRENT_SUBAGENTS;
|
|
89047
89058
|
}
|
|
89048
89059
|
async spawn(profileName, options) {
|
|
89049
89060
|
options.signal.throwIfAborted();
|
|
89061
|
+
this.assertCanSpawn();
|
|
89050
89062
|
const parent = this.session.agents.get(this.ownerAgentId);
|
|
89051
89063
|
if (parent === void 0) throw new Error(`Parent agent "${this.ownerAgentId}" was not found`);
|
|
89052
89064
|
const profile = this.resolveProfile(parent, profileName);
|
|
@@ -89076,6 +89088,7 @@ var SessionSubagentHost = class {
|
|
|
89076
89088
|
}
|
|
89077
89089
|
async resume(agentId, options) {
|
|
89078
89090
|
options.signal.throwIfAborted();
|
|
89091
|
+
this.assertCanSpawn();
|
|
89079
89092
|
const parent = this.session.agents.get(this.ownerAgentId);
|
|
89080
89093
|
if (parent === void 0) throw new Error(`Parent agent "${this.ownerAgentId}" was not found`);
|
|
89081
89094
|
const child = this.session.agents.get(agentId);
|
|
@@ -89114,6 +89127,9 @@ var SessionSubagentHost = class {
|
|
|
89114
89127
|
child.controller.abort();
|
|
89115
89128
|
}
|
|
89116
89129
|
}
|
|
89130
|
+
assertCanSpawn() {
|
|
89131
|
+
if (this.activeChildren.size >= this.maxConcurrentSubagents) throw new Error(`Too many concurrent subagents (${this.activeChildren.size} running, maximum ${this.maxConcurrentSubagents}).`);
|
|
89132
|
+
}
|
|
89117
89133
|
getProfileName(agentId) {
|
|
89118
89134
|
const metadata = this.session.metadata.agents[agentId];
|
|
89119
89135
|
if (metadata?.type !== "sub" || metadata.parentAgentId !== this.ownerAgentId) return;
|
|
@@ -89511,7 +89527,7 @@ var Session$1 = class {
|
|
|
89511
89527
|
providerManager: this.config.providerManager,
|
|
89512
89528
|
sessionId: this.config.id,
|
|
89513
89529
|
hookEngine: config.hookEngine ?? this.hookEngine,
|
|
89514
|
-
subagentHost: config.subagentHost ?? new SessionSubagentHost(this, id, this.backgroundTaskTimeoutMs()),
|
|
89530
|
+
subagentHost: config.subagentHost ?? new SessionSubagentHost(this, id, this.backgroundTaskTimeoutMs(), this.config.background?.maxConcurrentSubagents),
|
|
89515
89531
|
mcp: this.mcp,
|
|
89516
89532
|
backgroundMaxRunningTasks: this.config.background?.maxRunningTasks,
|
|
89517
89533
|
backgroundSessionDir: homedir,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@byfriends/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Public TypeScript SDK for BYF agents and sessions",
|
|
5
5
|
"license": "Proprietary",
|
|
6
6
|
"author": "ByronFinn",
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/yazl": "^2.4.6",
|
|
52
|
-
"@byfriends/
|
|
52
|
+
"@byfriends/agent-core": "^0.2.5",
|
|
53
53
|
"@byfriends/oauth": "^0.1.1",
|
|
54
|
-
"@byfriends/
|
|
55
|
-
"@byfriends/
|
|
54
|
+
"@byfriends/kosong": "^0.2.2",
|
|
55
|
+
"@byfriends/kaos": "^0.2.2"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "tsdown && pnpm run build:dts",
|