@roll-agent/core 0.19.0 → 0.21.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/dist/cli/chat/ink/app.d.ts +4 -4
- package/dist/cli/chat/ink/app.js +1 -1
- package/dist/cli/chat/ink/banner-view.d.ts +3 -4
- package/dist/cli/chat/ink/commands.d.ts +4 -12
- package/dist/cli/chat/ink/commands.js +1 -1
- package/dist/cli/chat/ink/confirm-select.d.ts +3 -1
- package/dist/cli/chat/ink/confirm-select.js +1 -1
- package/dist/cli/chat/ink/history-from-messages.js +1 -1
- package/dist/cli/chat/ink/history-item.js +1 -1
- package/dist/cli/chat/ink/input-history.d.ts +2 -0
- package/dist/cli/chat/ink/input-history.js +1 -0
- package/dist/cli/chat/ink/layout.d.ts +13 -0
- package/dist/cli/chat/ink/layout.js +1 -0
- package/dist/cli/chat/ink/line-buffer.d.ts +8 -0
- package/dist/cli/chat/ink/line-buffer.js +1 -1
- package/dist/cli/chat/ink/live-region.d.ts +2 -0
- package/dist/cli/chat/ink/live-region.js +1 -1
- package/dist/cli/chat/ink/mouse-input.d.ts +9 -0
- package/dist/cli/chat/ink/mouse-input.js +1 -0
- package/dist/cli/chat/ink/reasoning-block.d.ts +4 -0
- package/dist/cli/chat/ink/reasoning-block.js +1 -0
- package/dist/cli/chat/ink/run-ink-repl.d.ts +2 -2
- package/dist/cli/chat/ink/run-ink-repl.js +1 -1
- package/dist/cli/chat/ink/slash-popup.d.ts +3 -1
- package/dist/cli/chat/ink/slash-popup.js +1 -1
- package/dist/cli/chat/ink/spinner.d.ts +3 -1
- package/dist/cli/chat/ink/spinner.js +1 -1
- package/dist/cli/chat/ink/state.d.ts +26 -3
- package/dist/cli/chat/ink/state.js +1 -1
- package/dist/cli/chat/ink/status-line.d.ts +3 -2
- package/dist/cli/chat/ink/status-line.js +1 -1
- package/dist/cli/chat/ink/terminal-output.d.ts +6 -0
- package/dist/cli/chat/ink/terminal-output.js +1 -0
- package/dist/cli/chat/ink/text-prompt.d.ts +7 -1
- package/dist/cli/chat/ink/text-prompt.js +1 -1
- package/dist/cli/chat/ink/transcript-viewport.d.ts +22 -0
- package/dist/cli/chat/ink/transcript-viewport.js +1 -0
- package/dist/cli/chat/ink/turn-activity.d.ts +19 -0
- package/dist/cli/chat/ink/turn-activity.js +1 -0
- package/dist/cli/chat/ink/turn-status-line.d.ts +15 -0
- package/dist/cli/chat/ink/turn-status-line.js +1 -0
- package/dist/cli/chat/ink/use-session.js +1 -1
- package/dist/cli/chat/screen-mode.d.ts +66 -0
- package/dist/cli/chat/screen-mode.js +1 -0
- package/dist/cli/commands/browser-stop.d.ts +4 -4
- package/dist/cli/commands/chat.d.ts +33 -1
- package/dist/cli/commands/chat.js +1 -1
- package/dist/cli/commands/config.js +1 -1
- package/dist/cli/utils/chat-renderer.js +1 -1
- package/dist/cli/utils/current-cli-shim.d.ts +14 -0
- package/dist/cli/utils/current-cli-shim.js +1 -0
- package/dist/cli/utils/debug-format.d.ts +4 -0
- package/dist/cli/utils/debug-format.js +1 -0
- package/dist/config/application-service.js +1 -1
- package/dist/config/defaults.d.ts +2 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/guidance.d.ts +38 -4
- package/dist/config/guidance.js +1 -1
- package/dist/config/schema.d.ts +136 -67
- package/dist/config/schema.js +1 -1
- package/dist/llm/providers.d.ts +6 -4
- package/dist/llm/providers.js +1 -1
- package/dist/registry/install.js +1 -1
- package/dist/skills/invocation.d.ts +27 -0
- package/dist/skills/invocation.js +1 -0
- package/dist/types/chat.d.ts +3 -0
- package/package.json +3 -2
package/dist/config/schema.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as e}from"zod";const t=["zhipin","yupao"],n=["managed-cdp","remote-cdp","existing-session"],o=["chrome","chromium","msedge"],i=["guarded","auto","deny"],a=["auto","confirm","deny"],r=["summarize","truncate"],s=e.string().trim().regex(/^#[\da-fA-F]{6}$/,"profileColor must be a hex RGB color such as #2563EB").transform(e=>e.toUpperCase());export const browserWindowBoundsSchema=e.object({x:e.number().int().optional(),y:e.number().int().optional(),width:e.number().int().positive().optional(),height:e.number().int().positive().optional()});export const providerConfigSchema=e.object({apiKey:e.string(),baseUrl:e.string().optional()});export const llmConfigSchema=e.object({defaultProvider:e.string(),defaultModel:e.string(),providers:e.record(e.string(),providerConfigSchema)});export const askConfigSchema=e.object({llmModel:e.string().optional(),confirmThreshold:e.number().optional()});export const runtimeApprovalConfigSchema=e.object({default:e.enum(i).default("guarded"),overrides:e.record(e.string(),e.enum(a)).default({})});export const runtimeCompactionConfigSchema=e.object({enabled:e.boolean().default(!0),strategy:e.enum(r).default("summarize"),threshold:e.number().min(.1).max(.95).default(.75),keepRecentTurns:e.number().int().min(1).default(4),keepRecentTokens:e.number().int().min(1).default(32e3)});export const
|
|
1
|
+
import{z as e}from"zod";const t=["zhipin","yupao"],n=["managed-cdp","remote-cdp","existing-session"],o=["chrome","chromium","msedge"],i=["guarded","auto","deny"],a=["auto","confirm","deny"],r=["summarize","truncate"];export const runtimeThinkingLevels=["off","low","medium","high"];export const CHAT_SCREEN_MODES=["auto","fullscreen","inline"];const s=e.string().trim().regex(/^#[\da-fA-F]{6}$/,"profileColor must be a hex RGB color such as #2563EB").transform(e=>e.toUpperCase());export const browserWindowBoundsSchema=e.object({x:e.number().int().optional(),y:e.number().int().optional(),width:e.number().int().positive().optional(),height:e.number().int().positive().optional()});export const providerConfigSchema=e.object({apiKey:e.string(),baseUrl:e.string().optional()});export const llmConfigSchema=e.object({defaultProvider:e.string(),defaultModel:e.string(),providers:e.record(e.string(),providerConfigSchema)});export const askConfigSchema=e.object({llmModel:e.string().optional(),confirmThreshold:e.number().optional()});export const chatScreenModeSchema=e.enum(CHAT_SCREEN_MODES);export const chatConfigSchema=e.object({screenMode:chatScreenModeSchema.default("auto")});export const runtimeApprovalConfigSchema=e.object({default:e.enum(i).default("guarded"),overrides:e.record(e.string(),e.enum(a)).default({})});export const runtimeCompactionConfigSchema=e.object({enabled:e.boolean().default(!0),strategy:e.enum(r).default("summarize"),timeoutMs:e.number().int().min(1e4).max(6e5).default(12e4),thinkingLevel:e.enum(runtimeThinkingLevels).optional(),maxOutputTokens:e.number().int().min(2048).max(32768).default(8192),threshold:e.number().min(.1).max(.95).default(.75),keepRecentTurns:e.number().int().min(1).default(4),keepRecentTokens:e.number().int().min(1).default(32e3)});export const runtimeShellSessionConfigSchema=e.object({enabled:e.boolean().default(!1),maxSessions:e.number().int().min(1).max(64).default(8),defaultYieldMs:e.number().int().min(250).max(3e4).default(1e4),maxOutputTokens:e.number().int().min(256).default(1e4)});export const runtimeShellConfigSchema=e.object({enabled:e.boolean().default(!1),autoApproveSafe:e.boolean().default(!0),defaultTimeoutMs:e.number().int().min(1e3).max(6e5).default(1e4),maxTimeoutMs:e.number().int().min(1e3).max(6e5).default(6e5),maxCaptureBytes:e.number().int().min(16384).default(1048576),maxModelOutputChars:e.number().int().min(1e3).default(16e3),session:runtimeShellSessionConfigSchema.default({})});export const runtimeConfigSchema=e.object({provider:e.string().optional(),model:e.string().optional(),maxSteps:e.number().int().min(1).default(80),turnTimeoutMs:e.number().int().min(1e4).default(3e5),threadsDir:e.string().default("~/.roll-agent/threads"),contextWindow:e.number().int().min(1).optional(),thinkingLevel:e.enum(runtimeThinkingLevels).default("medium"),approval:runtimeApprovalConfigSchema.default({}),compaction:runtimeCompactionConfigSchema.default({}),shell:runtimeShellConfigSchema.default({})});export const skillsConfigSchema=e.object({dirs:e.array(e.string().trim().min(1)).default([])});export const agentsConfigSchema=e.object({dataDir:e.string(),env:e.record(e.string(),e.record(e.string(),e.string())).optional()});export const installConfigSchema=e.object({registry:e.string().trim().url().optional(),fetchRetries:e.number().int().min(0).max(10).default(3),preferOffline:e.boolean().default(!1),networkTimeoutMs:e.number().int().min(1e4).default(12e4)});export const browserInstanceConfigSchema=e.object({platform:e.enum(t).optional(),mode:e.enum(n).default("managed-cdp"),headless:e.boolean().optional(),cdpUrl:e.string().optional(),cdpHost:e.string().default("127.0.0.1"),cdpPort:e.number().int().min(1).max(65535).optional(),channel:e.enum(o).default("chrome"),executablePath:e.string().optional(),userDataDir:e.string().trim().min(1),sessionsDir:e.string().trim().min(1).optional(),args:e.array(e.string()).optional(),profileName:e.string().trim().min(1).optional(),profileColor:s.optional(),windowBounds:browserWindowBoundsSchema.optional(),trackingAgentId:e.string().trim().min(1).optional()}).superRefine((t,n)=>{"managed-cdp"===t.mode&&void 0===t.cdpPort&&n.addIssue({code:e.ZodIssueCode.custom,path:["cdpPort"],message:"managed-cdp browser instance requires cdpPort"}),"remote-cdp"!==t.mode&&"existing-session"!==t.mode||void 0!==t.cdpUrl||n.addIssue({code:e.ZodIssueCode.custom,path:["cdpUrl"],message:`${t.mode} browser instance requires cdpUrl`})});export const browserConfigSchema=e.object({defaultInstance:e.string().trim().min(1).optional(),instances:e.record(e.string(),browserInstanceConfigSchema).default({})}).superRefine((t,n)=>{const o=Object.entries(t.instances);void 0!==t.defaultInstance&&void 0===t.instances[t.defaultInstance]&&n.addIssue({code:e.ZodIssueCode.custom,path:["defaultInstance"],message:`defaultInstance "${t.defaultInstance}" is not declared in browser.instances`});const i=new Map,a=new Map;for(const[t,r]of o){if(void 0!==r.cdpPort){const o=i.get(r.cdpPort);void 0!==o?n.addIssue({code:e.ZodIssueCode.custom,path:["instances",t,"cdpPort"],message:`cdpPort ${String(r.cdpPort)} is already used by browser instance "${o}"`}):i.set(r.cdpPort,t)}const o=a.get(r.userDataDir);void 0!==o?n.addIssue({code:e.ZodIssueCode.custom,path:["instances",t,"userDataDir"],message:`userDataDir is already used by browser instance "${o}"`}):a.set(r.userDataDir,t)}});export const rollConfigSchema=e.object({llm:llmConfigSchema,ask:askConfigSchema,chat:chatConfigSchema.default({}),runtime:runtimeConfigSchema.default({}),skills:skillsConfigSchema.default({}),agents:agentsConfigSchema,install:installConfigSchema.default({}),browser:browserConfigSchema.default({})});
|
package/dist/llm/providers.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type { LanguageModelV4, SharedV4ProviderOptions } from "@ai-sdk/provider";
|
|
1
|
+
import type { LanguageModelV4, LanguageModelV4CallOptions, SharedV4ProviderOptions } from "@ai-sdk/provider";
|
|
2
2
|
import { runtimeThinkingLevels } from "../config/schema.ts";
|
|
3
3
|
export type ThinkingLevel = (typeof runtimeThinkingLevels)[number];
|
|
4
|
+
export type UnifiedReasoning = NonNullable<LanguageModelV4CallOptions["reasoning"]>;
|
|
4
5
|
export declare function thinkingProviderOptions(providerName: string, modelName: string, level: ThinkingLevel): SharedV4ProviderOptions | undefined;
|
|
5
6
|
/**
|
|
6
7
|
* 根据 provider 名称创建 AI SDK LanguageModel 实例。
|
|
7
8
|
*
|
|
8
|
-
* 支持: anthropic, openai, deepseek, qwen
|
|
9
|
+
* 支持: anthropic, openai, deepseek, qwen, xai
|
|
9
10
|
*/
|
|
10
11
|
export declare function createProviderModel(providerName: string, modelName: string, apiKey: string, baseURL?: string): LanguageModelV4;
|
|
11
12
|
/** generateText 调用目的 */
|
|
@@ -13,6 +14,7 @@ export type LLMCallPurpose = "structured-output" | "text" | "sampling" | "chat";
|
|
|
13
14
|
/** resolveLLMCall 的返回值 */
|
|
14
15
|
export interface ResolvedLLMCall {
|
|
15
16
|
readonly model: LanguageModelV4;
|
|
17
|
+
readonly reasoning?: UnifiedReasoning;
|
|
16
18
|
readonly providerOptions?: SharedV4ProviderOptions;
|
|
17
19
|
}
|
|
18
20
|
/**
|
|
@@ -27,8 +29,8 @@ export declare function toSamplingConnectOptions(call: ResolvedLLMCall | undefin
|
|
|
27
29
|
/**
|
|
28
30
|
* 按 provider + 调用目的解析 generateText 的完整调用上下文。
|
|
29
31
|
*
|
|
30
|
-
* structured-output
|
|
31
|
-
* 因为阿里云 thinking mode 不支持 structured output
|
|
32
|
+
* structured-output 场景优先使用 AI SDK 顶层 reasoning 统一语义;qwen 是例外,
|
|
33
|
+
* 因为阿里云 thinking mode 不支持 structured output,必须通过 providerOptions 强制关闭。
|
|
32
34
|
*
|
|
33
35
|
* chat 与 sampling 场景下都是纯文本 generateText 调用,复用同一套
|
|
34
36
|
* thinkingProviderOptions 映射注入 reasoning/thinking effort。
|
package/dist/llm/providers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createAlibaba as e}from"@ai-sdk/alibaba";import{createAnthropic as
|
|
1
|
+
import{createAlibaba as e}from"@ai-sdk/alibaba";import{createAnthropic as n}from"@ai-sdk/anthropic";import{createOpenAI as o}from"@ai-sdk/openai";import{createDeepSeek as i}from"@ai-sdk/deepseek";import{createXai as t}from"@ai-sdk/xai";import{runtimeThinkingLevels as r}from"../config/schema.js";const a={low:2048,medium:8192,high:16384},s=["gpt-5.1","gpt-5.2","gpt-5.3","gpt-5.4","gpt-5.5"],p=["o1","o3","o4-mini"],u="grok-4.20",f="-multi-agent";function d(e){return s.some(n=>e.startsWith(n))}function c(e){return p.some(n=>e.startsWith(n))||e.startsWith("gpt-5")&&!e.startsWith("gpt-5-chat")}function l(e){const n=/^claude-[a-z]+-(\d+)(?:-(\d+))?(?:\b|-)/.exec(e),o=n?.[1];if(!o)return!1;const i=Number(o),t=n?.[2],r=void 0!==t&&t.length<=2?Number(t):0;return i>4||4===i&&r>=6}function m(e){return"grok-3"===e||"grok-4-1"===e||e.includes("-non-reasoning")}function g(e){return!h(e)}function h(e){return e.startsWith(u)&&!e.includes(f)}function b(e){return"grok-4.5"===e||e.includes(f)||h(e)&&!m(e)}export function thinkingProviderOptions(e,n,o){if("openai"===e)return"off"===o?d(n)?{openai:{reasoningEffort:"none"}}:void 0:{openai:{reasoningEffort:o}};if("anthropic"===e)return"off"===o?{anthropic:{thinking:{type:"disabled"}}}:l(n)?{anthropic:{thinking:{type:"adaptive"},effort:o}}:{anthropic:{thinking:{type:"enabled",budgetTokens:a[o]}}};if("qwen"===e)return"off"===o?{alibaba:{enableThinking:!1}}:{alibaba:{enableThinking:!0,thinkingBudget:a[o]}};if("xai"===e){if(m(n))return;return g(n)?"off"===o?{xai:{reasoningEffort:"none"}}:{xai:{reasoningEffort:o,reasoningSummary:"auto"}}:"off"===o?void 0:{xai:{reasoningSummary:"auto"}}}return"deepseek"===e?{deepseek:{thinking:{type:"off"===o?"disabled":"enabled"}}}:void 0}const k="https://dashscope.aliyuncs.com/compatible-mode/v1",v={anthropic:(e,{apiKey:o,baseURL:i})=>n({apiKey:o,...i?{baseURL:i}:{}})(e),openai:(e,{apiKey:n,baseURL:i})=>o({apiKey:n,...i?{baseURL:i}:{}})(e),deepseek:(e,{apiKey:n,baseURL:o})=>i({apiKey:n,...o?{baseURL:o}:{}})(e),qwen:(n,{apiKey:o,baseURL:i})=>e({apiKey:o,baseURL:i??k})(n),xai:(e,{apiKey:n,baseURL:o})=>t({apiKey:n,...o?{baseURL:o}:{}})(e)};export function createProviderModel(e,n,o,i){const t=v[e];if(!t){const n=Object.keys(v).join(", ");throw new Error(`Unknown LLM provider "${e}". Supported: ${n}`)}return t(n,{apiKey:o,baseURL:i})}function y(e){return"off"===e?"none":e}function w(e,n,o){if("openai"===e){if(!c(n))return;if("off"!==o)return y(o);if(d(n))return"none";throw new Error(`OpenAI model "${n}" cannot disable reasoning for structured output; set runtime.compaction.thinking-level to low or higher`)}if("xai"===e){if(m(n))return;if(h(n)){if("off"===o)throw new Error(`xAI model "${n}" cannot disable reasoning for structured output; set runtime.compaction.thinking-level to low or higher`);return}if("off"===o&&b(n))throw new Error(`xAI model "${n}" cannot disable reasoning for structured output; set runtime.compaction.thinking-level to low or higher`)}return y(o)}export function toSamplingConnectOptions(e){return e?{samplingModel:e.model,...e.providerOptions?{samplingProviderOptions:e.providerOptions}:{}}:{}}export function resolveLLMCall(e,n,o,i,t,r="medium"){const a=createProviderModel(e,n,o,t);if("structured-output"===i){if("qwen"===e)return{model:a,providerOptions:{alibaba:{enableThinking:!1}}};const o=w(e,n,r);return o?{model:a,reasoning:o}:{model:a}}if("chat"===i||"sampling"===i){const o=thinkingProviderOptions(e,n,r);return"openai"===e&&t?{model:a,providerOptions:{...o??{},openai:{...o?.openai??{},store:!1}}}:o?{model:a,providerOptions:o}:{model:a}}return{model:a}}
|
package/dist/registry/install.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as
|
|
1
|
+
import{randomUUID as e}from"node:crypto";import{existsSync as t,lstatSync as r,mkdirSync as s,readFileSync as n,rmSync as a,statSync as i,writeFileSync as o}from"node:fs";import{basename as l,dirname as c,resolve as m}from"node:path";import{buildNpmRetryPolicy as g,formatPackageManagerError as p,npmInstallNetworkArgs as k,runPackageManagerWithRetry as u}from"../cli/utils/package-manager.js";import{inspectAgentEnvRequirements as f}from"../config/helpers.js";import{discoverAgent as d}from"./discovery.js";import{startAgent as y,stopAgentGracefully as h,waitForAgentReady as w}from"./process-manager.js";import{runAgentSetup as $}from"./runtime-setup.js";import{parsePackageName as v,readInstalledPackageManifest as S,resolveInstalledPackageRoot as D,sanitizeInstallId as A}from"./source.js";import{AgentStore as C}from"./store.js";export const INSTALL_AGENT_STEPS=["resolve","download","discover","setup","register","start"];const P=".install.lock";function T(e){return k({...e.registry?{registry:e.registry}:{},fetchRetries:e.fetchRetries,preferOffline:e.preferOffline})}function j(e){return e.startsWith("git@")||e.startsWith("git+")||e.startsWith("github:")||e.startsWith("gitlab:")||e.startsWith("bitbucket:")||e.endsWith(".git")}function B(e){const r=m(e);return t(r)&&i(r).isDirectory()}function b(e){return e instanceof Error?e.message:String(e)}function E(e,t){return"object"==typeof e&&null!==e&&"code"in e&&e.code===t}function N(e,t){try{e({type:"warn",message:t})}catch{}}function R(e){return m(c(e),`.${l(e)}${P}`)}function I(e,t){o(e,`${JSON.stringify(t)}\n`,{encoding:"utf8",flag:"wx",mode:384})}function O(e){try{const t=JSON.parse(n(e,"utf8"));return"object"==typeof t&&null!==t&&"token"in t&&"string"==typeof t.token?t.token:void 0}catch{return}}function x(e,r){const s=O(e.lockPath);if(void 0!==s)if(s===e.markerToken)try{a(e.lockPath)}catch(t){N(r,`清理安装锁失败: ${e.lockPath}(${b(t)})`)}else N(r,`安装锁已被其他任务替换,未执行清理: ${e.lockPath}`);else t(e.lockPath)&&N(r,`安装锁内容无法验证,未自动删除: ${e.lockPath}`)}function L(t,n){const a=e(),i=R(t),o=c(t);try{s(o,{recursive:!0}),I(i,{token:a,pid:process.pid,startedAt:(new Date).toISOString()})}catch(e){return{ok:!1,failure:{ok:!1,step:"resolve",message:E(e,"EEXIST")?`Agent 安装任务正在使用锁文件: ${i}。请先检查锁文件中的 pid,确认对应安装进程已结束后再手动删除该锁文件并重试;Roll 不会自动抢占疑似 stale lock。`:`无法创建 Agent 安装锁: ${b(e)}`}}}let l;try{l=r(t)}catch(e){if(!E(e,"ENOENT"))return x({installDir:t,lockPath:i,markerToken:a},n),{ok:!1,failure:{ok:!1,step:"resolve",message:`无法检查 Agent 安装目录: ${b(e)}`}}}if(void 0!==l)return l.isSymbolicLink()?(x({installDir:t,lockPath:i,markerToken:a},n),{ok:!1,failure:{ok:!1,step:"resolve",message:`Agent 安装目录不能是符号链接: ${t}`}}):l.isDirectory()?{ok:!0,workspace:{installDir:t,lockPath:i,markerToken:a,createdByInvocation:!1}}:(x({installDir:t,lockPath:i,markerToken:a},n),{ok:!1,failure:{ok:!1,step:"resolve",message:`Agent 安装路径已存在但不是目录: ${t}`}});try{s(t)}catch(e){return x({installDir:t,lockPath:i,markerToken:a},n),{ok:!1,failure:{ok:!1,step:"resolve",message:`无法创建 Agent 安装目录: ${b(e)}`}}}return{ok:!0,workspace:{installDir:t,lockPath:i,markerToken:a,createdByInvocation:!0}}}function M(e,t){if(e.createdByInvocation)if(O(e.lockPath)===e.markerToken)try{a(e.installDir,{recursive:!0,force:!0})}catch(r){N(t,`清理未完成的安装目录失败: ${e.installDir}(${b(r)})`)}else N(t,`安装目录锁不再属于当前任务,未删除目录: ${e.installDir}`)}function W(e){return e.source?.type??"unknown"}function G(e,t,r){return{ok:!1,step:"register",message:`Agent "${e}" 已通过 ${t} 来源注册。为避免覆盖本地/Git Agent,默认不会替换为 npm 安装。请先运行 \`roll agent remove ${e}\`,或确认风险后使用 \`roll agent install ${r} --force\`。`,retryCommand:`roll agent install ${r} --force`}}function J(e,t){return void 0!==e&&"installed-package"!==e.source?.type&&!t}export async function installAgent(e,r){const s=r.report??(()=>{}),n=r.collaborators??{},a=n.runInstall??u,i=n.discover??d,o=n.runSetup??$,l=n.start??y,c=n.waitReady??w,k=n.stopGracefully??h,P=n.resolvePackageRoot??D,E=n.readManifest??S,{packageSpec:N}=e,R=e.autoStart??!0,I=e.replaceExisting??!1;if(j(N))return{ok:!1,step:"resolve",message:`Git URL 请使用 \`roll agent add ${N}\` 注册,不要使用 \`roll agent install\``};if(B(N))return{ok:!1,step:"resolve",message:`本地源码目录请使用 \`roll agent add ${N}\` 注册,不要使用 \`roll agent install\``};const O=v(N),_=m(r.agentsConfig.dataDir,"installed",A(O)),q=r.store??new C(r.agentsConfig.dataDir),K=e.expectedSkillName,U=K?q.findByName(K):void 0;if(U&&J(U,I))return G(U.skill.name,W(U),N);const V=L(_,s);if(!V.ok)return V.failure;const X=V.workspace;try{r.installConfig.registry&&s({type:"info",message:`使用 npm registry: ${r.installConfig.registry}(roll.config.yaml install.registry)`}),s({type:"step",step:"download",message:`安装 ${N}...`});const n={command:"npm",args:["install","--prefix",_,N,...T(r.installConfig)]};try{await a(n,{timeout:r.installConfig.networkTimeoutMs},{...g(r.installConfig.fetchRetries),onRetry:({attempt:e,delayMs:t})=>{s({type:"retry",attempt:e,delayMs:t})}})}catch(e){return M(X,s),{ok:!1,step:"download",message:`安装失败: ${p(n,e)}`}}let m,u,d;try{m=P(_,O)}catch(e){throw M(X,s),e}if(!t(m))return M(X,s),{ok:!1,step:"discover",message:`安装完成但未找到包目录: ${m}`};try{u=E(m)}catch(e){throw M(X,s),e}s({type:"step",step:"discover",message:"解析已安装 Agent 的 SKILL.md..."});try{d=i(m)}catch(e){return M(X,s),{ok:!1,step:"discover",message:b(e)}}const y={skill:d.skill,transport:d.transport,runtime:d.runtime,installPath:m,registeredAt:(new Date).toISOString(),status:"idle",source:{type:"installed-package",packageName:u?.name??O,packageSpec:N,installDir:_,...u?.version?{installedVersion:u.version}:{}},...d.skillBody.length>0?{skillBody:d.skillBody}:{}},h=q.findByName(d.skill.name);if(h&&J(h,I))return M(X,s),G(d.skill.name,W(h),N);let w;"core-managed"===y.runtime.ownership&&y.runtime.setup?.playwright&&!e.skipBrowserSetup&&s({type:"info",message:`即将安装浏览器运行时 (${y.runtime.setup.playwright.browsers.join(", ")}),这可能需要一些时间...`});try{w=await o(y,{skipBrowserSetup:e.skipBrowserSetup??!1})}catch(e){throw M(X,s),e}w.ok&&!w.skipped?s({type:"success",message:w.message}):w.ok&&s({type:"info",message:w.message});const $="core-managed"===h?.runtime.ownership&&"online"===h.status;try{if("installed-package"===h?.source?.type||h&&I){if("installed-package"!==h.source?.type){const e=h.source?.type??"unknown";s({type:"info",message:`Agent "${d.skill.name}" 已通过 ${e} 来源注册,将替换为 npm 安装`})}if(!q.replace(h.skill.name,y))throw new Error(`Agent "${h.skill.name}" 在安装期间已被移除,请重试`)}else q.add(y)}catch(e){return M(X,s),{ok:!1,step:"register",message:b(e)}}if(!w.ok)return $&&await k(r.agentsConfig.dataDir,y.skill.name).catch(()=>{}),q.updateStatus(d.skill.name,"error"),{ok:!1,step:"setup",message:w.message,...w.retryCommand?{retryCommand:w.retryCommand}:{}};const v=f(y.skill.name,d.skill.env,r.agentsConfig.env),S=v?.missingRequired??[];let D=!1;const A="core-managed"===y.runtime.ownership&&R,C=A&&0===S.length;if($&&!C&&(await k(r.agentsConfig.dataDir,y.skill.name).catch(()=>{}),q.updateStatus(y.skill.name,"idle")),A)if(S.length>0)s({type:"warn",message:`Agent "${y.skill.name}" 缺少必填环境变量(${S.map(e=>e.name).join(", ")}),暂不启动。配置后运行 \`roll agent start ${y.skill.name}\` 启动`});else{let e=!1;try{$&&await k(r.agentsConfig.dataDir,y.skill.name),q.updateStatus(y.skill.name,"starting"),l(y,r.agentsConfig.dataDir,r.getStartEnv(y.skill.name)),e=!0,await c(y,{startupTimeoutMs:15e3,probeTimeoutMs:2e3}),q.updateStatus(y.skill.name,"online"),D=!0}catch(t){return e&&await k(r.agentsConfig.dataDir,y.skill.name).catch(()=>{}),q.updateStatus(y.skill.name,"error"),{ok:!1,step:"start",message:`Agent "${d.skill.name}" 已安装,但自动启动失败:${b(t)}`}}}return{ok:!0,agent:y,envReport:v,started:D}}finally{x(X,s)}}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface SkillInvocationSummary {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly description: string;
|
|
4
|
+
readonly source: string;
|
|
5
|
+
}
|
|
6
|
+
export interface SkillInvocation {
|
|
7
|
+
readonly skills: readonly SkillInvocationSummary[];
|
|
8
|
+
readonly prompt: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const SKILL_INVOCATION_PARSE_KINDS: {
|
|
11
|
+
readonly none: "none";
|
|
12
|
+
readonly valid: "valid";
|
|
13
|
+
readonly unknown: "unknown";
|
|
14
|
+
};
|
|
15
|
+
export type SkillInvocationParseResult = {
|
|
16
|
+
readonly kind: typeof SKILL_INVOCATION_PARSE_KINDS.none;
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: typeof SKILL_INVOCATION_PARSE_KINDS.valid;
|
|
19
|
+
readonly invocation: SkillInvocation;
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: typeof SKILL_INVOCATION_PARSE_KINDS.unknown;
|
|
22
|
+
readonly token: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function findSkillBySlashName(token: string, skills: readonly SkillInvocationSummary[]): SkillInvocationSummary | undefined;
|
|
25
|
+
/** Parses one or more known leading /skill tokens without rewriting the user's request. */
|
|
26
|
+
export declare function parseSkillInvocationResult(input: string, skills: readonly SkillInvocationSummary[]): SkillInvocationParseResult;
|
|
27
|
+
export declare function parseSkillInvocation(input: string, skills: readonly SkillInvocationSummary[]): SkillInvocation | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SKILL_INVOCATION_PARSE_KINDS={none:"none",valid:"valid",unknown:"unknown"};export function findSkillBySlashName(n,o){const t=n.toLowerCase();return o.find(n=>`/${n.name}`.toLowerCase()===t)}export function parseSkillInvocationResult(n,o){let t=n.trimStart();const e=[],i=new Set;for(;;){const n=/^(\/\S+)(\s*)/.exec(t);if(!n)break;const a=findSkillBySlashName(n[1]??"",o);if(!a)return{kind:SKILL_INVOCATION_PARSE_KINDS.unknown,token:n[1]??""};const S=a.name.toLowerCase();i.has(S)||(e.push(a),i.add(S)),t=t.slice(n[0].length)}return 0===e.length?{kind:SKILL_INVOCATION_PARSE_KINDS.none}:{kind:SKILL_INVOCATION_PARSE_KINDS.valid,invocation:{skills:e,prompt:t.trim()}}}export function parseSkillInvocation(n,o){const t=parseSkillInvocationResult(n,o);return t.kind===SKILL_INVOCATION_PARSE_KINDS.valid?t.invocation:void 0}
|
package/dist/types/chat.d.ts
CHANGED
|
@@ -23,6 +23,9 @@ export interface ChatCompactionSummary {
|
|
|
23
23
|
readonly kept: number;
|
|
24
24
|
readonly truncatedTools?: number;
|
|
25
25
|
readonly beforeInputTokens?: number;
|
|
26
|
+
readonly checkpointId?: string;
|
|
27
|
+
readonly checkpointGeneration?: number;
|
|
28
|
+
readonly checkpointSummaryStatus?: "valid" | "fallback" | "skipped";
|
|
26
29
|
}
|
|
27
30
|
export interface ChatInputRequirement {
|
|
28
31
|
readonly name: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@roll-agent/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"@ai-sdk/deepseek": "^3.0.2",
|
|
69
69
|
"@ai-sdk/openai": "^4.0.4",
|
|
70
70
|
"@ai-sdk/provider": "^4.0.1",
|
|
71
|
+
"@ai-sdk/xai": "4.0.12",
|
|
71
72
|
"@clack/prompts": "1.4.0",
|
|
72
73
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
73
74
|
"ai": "^7.0.9",
|
|
@@ -84,7 +85,7 @@
|
|
|
84
85
|
"string-width": "8.2.1",
|
|
85
86
|
"yaml": "^2.7.0",
|
|
86
87
|
"zod": "^3.25.76",
|
|
87
|
-
"@roll-agent/runtime": "0.
|
|
88
|
+
"@roll-agent/runtime": "0.8.0"
|
|
88
89
|
},
|
|
89
90
|
"devDependencies": {
|
|
90
91
|
"@tailwindcss/vite": "4.3.2",
|