@tansr/sdk 0.3.0 → 0.4.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.
Files changed (3) hide show
  1. package/dist/index.d.ts +163 -75
  2. package/dist/index.js +200 -30
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -5644,8 +5644,9 @@ declare const TansrConfigSchema: z.ZodObject<{
5644
5644
  * TANSR_CLASSIFIER_TIGHTEN_OUTSIDE_AUTO / TANSR_CLASSIFIER_BUDGET 保留为
5645
5645
  * 最高优先覆盖(逐键接管)。仅 user/managed 层被尊重(T-K0:分类器属
5646
5646
  * 用户/企业的信任与成本决策,项目层声明整段忽略+示警)。
5647
- * 刻意不进配置:TANSR_CLASSIFIER_ALLOW_UNQUALIFIED(资格越过)——
5648
- * break-glass 性质,进配置文件即可分发可持久,恒 env-only
5647
+ * 史注:TANSR_CLASSIFIER_ALLOW_UNQUALIFIED(资格越过)曾刻意不进配置
5648
+ * (break-glass 性质恒 env-only),已随 UAA P4-C2 整体退役(2026-08-30,
5649
+ * 任命即授照后无「未达资格」可越)。
5649
5650
  */
5650
5651
  classifier: z.ZodOptional<z.ZodObject<{
5651
5652
  enabled: z.ZodOptional<z.ZodBoolean>;
@@ -7021,15 +7022,6 @@ interface PermissionClassifierConfig {
7021
7022
  classifier: PermissionClassifier;
7022
7023
  /** 咨询超时(毫秒),缺省 DEFAULT_CLASSIFIER_TIMEOUT_MS;超时维持 ask */
7023
7024
  timeoutMs?: number;
7024
- /**
7025
- * safe→allow 裁决人资格位(T-K12 止血,05 §10.2/INV-5)。
7026
- *
7027
- * @deprecated T-K23c 起由 resolveQualificationTier 三级档位解析闭包取代
7028
- * (16 §4.5);仅供过渡期测试。解析闭包缺席时按 `true→'high'` /
7029
- * `false|缺省→'none'` 派生;闭包在场时本位被忽略。W1 收口卡
7030
- * (T-K23g)将其移出生产装配路径。
7031
- */
7032
- qualifiedForAllow?: boolean;
7033
7025
  /**
7034
7026
  * 三级资格档动态解析闭包(T-K23c,16 §4.5):返回当前生效档
7035
7027
  * (= min(授格档, 天花板, 会话覆盖),合成在装配层)。引擎**每次咨询
@@ -10095,6 +10087,50 @@ interface Tool<Args = unknown> {
10095
10087
  execute(args: Args, ctx: ToolContext): Promise<ToolResult>;
10096
10088
  }
10097
10089
 
10090
+ /**
10091
+ * T-D6 — 会话待办台账(内存态,不做持久化)。
10092
+ *
10093
+ * 设计要点:
10094
+ * - `TodoItem` 形状与 protocol `plan.todo.updated` 事件的 items 对齐
10095
+ * (id/content/status 三字段;status 在事件侧是宽松 string,本侧收窄为枚举);
10096
+ * - 依赖注入:`onChange` 由工厂(内核会话装配处)注入,store 本身不发事件、
10097
+ * 不落盘——外部在回调里接线 `plan.todo.updated` 事件与(未来的)持久化;
10098
+ * - 所有对外暴露的数组/对象均为副本,防止调用方或回调持引用后污染内部状态。
10099
+ */
10100
+ /** 待办状态全集(as const 元组,供 zod enum 与类型共用一份事实源) */
10101
+ declare const TODO_STATUSES: readonly ["pending", "in_progress", "completed", "cancelled"];
10102
+ type TodoStatus = (typeof TODO_STATUSES)[number];
10103
+ interface TodoItem {
10104
+ id: string;
10105
+ content: string;
10106
+ status: TodoStatus;
10107
+ }
10108
+ /**
10109
+ * merge 输入:按 id 定位,已知 id 只覆盖给定字段(未给字段保留原值);
10110
+ * 未知 id 追加为新项,此时 content 与 status 必须齐全(TodoWrite 工具
10111
+ * 的 schema 恒为全量,不会触发缺字段路径;此约束仅防御其他内部调用方)。
10112
+ */
10113
+ type TodoPatch = {
10114
+ id: string;
10115
+ } & Partial<Omit<TodoItem, 'id'>>;
10116
+ interface TodoStoreOptions {
10117
+ /** 变更回调:replace/merge 每次调用后触发一次,载荷为变更后完整列表的独立副本 */
10118
+ onChange?: (items: TodoItem[]) => void;
10119
+ }
10120
+ declare class TodoStore {
10121
+ #private;
10122
+ constructor(options?: TodoStoreOptions);
10123
+ /** 当前列表(副本;修改返回值不影响内部状态) */
10124
+ list(): TodoItem[];
10125
+ /** 全量替换(含替换为空 = 清空台账),返回变更后快照 */
10126
+ replace(items: readonly TodoItem[]): TodoItem[];
10127
+ /**
10128
+ * 按 id 合并:已知 id 原位覆盖给定字段;未知 id 按提交顺序追加到尾部。
10129
+ * 返回变更后快照。未知 id 缺 content/status 视为调用方契约错误,抛 TypeError。
10130
+ */
10131
+ merge(patches: readonly TodoPatch[]): TodoItem[];
10132
+ }
10133
+
10098
10134
  /**
10099
10135
  * T-C1 — 测试用顺序工具执行器(ToolExecutor 的最小实现)。
10100
10136
  *
@@ -10591,9 +10627,9 @@ declare class PermissionEngine {
10591
10627
  /**
10592
10628
  * 生效资格档解析(T-K23c,16 §4.5):解析闭包在场即**现算**(装配层合成
10593
10629
  * min(entry, ceiling, override);闭包抛错 → 'none',词表外脏值由
10594
- * softenRadiusAllows 安全查表兜底——T-INV-B 一切异常朝严);闭包缺席时
10595
- * @deprecated 布尔位派生 `true→'high'/false|缺省→'none'`(W1 过渡
10596
- * 兼容,16 §4.5;收口见 T-K23g)。
10630
+ * softenRadiusAllows 安全查表兜底——T-INV-B 一切异常朝严);闭包缺席
10631
+ * 'none'(无任命即无软化面;@deprecated 布尔位 qualifiedForAllow
10632
+ * 已随 P4-C3 拆除,2026-08-30)。
10597
10633
  */
10598
10634
  private resolveClassifierTier;
10599
10635
  /**
@@ -10828,50 +10864,6 @@ type OnToolDecision = (record: ToolDecisionRecord) => void;
10828
10864
  */
10829
10865
  type CaptureFileCheckpoints = (paths: readonly string[]) => Promise<void> | void;
10830
10866
 
10831
- /**
10832
- * T-D6 — 会话待办台账(内存态,不做持久化)。
10833
- *
10834
- * 设计要点:
10835
- * - `TodoItem` 形状与 protocol `plan.todo.updated` 事件的 items 对齐
10836
- * (id/content/status 三字段;status 在事件侧是宽松 string,本侧收窄为枚举);
10837
- * - 依赖注入:`onChange` 由工厂(内核会话装配处)注入,store 本身不发事件、
10838
- * 不落盘——外部在回调里接线 `plan.todo.updated` 事件与(未来的)持久化;
10839
- * - 所有对外暴露的数组/对象均为副本,防止调用方或回调持引用后污染内部状态。
10840
- */
10841
- /** 待办状态全集(as const 元组,供 zod enum 与类型共用一份事实源) */
10842
- declare const TODO_STATUSES: readonly ["pending", "in_progress", "completed", "cancelled"];
10843
- type TodoStatus = (typeof TODO_STATUSES)[number];
10844
- interface TodoItem {
10845
- id: string;
10846
- content: string;
10847
- status: TodoStatus;
10848
- }
10849
- /**
10850
- * merge 输入:按 id 定位,已知 id 只覆盖给定字段(未给字段保留原值);
10851
- * 未知 id 追加为新项,此时 content 与 status 必须齐全(TodoWrite 工具
10852
- * 的 schema 恒为全量,不会触发缺字段路径;此约束仅防御其他内部调用方)。
10853
- */
10854
- type TodoPatch = {
10855
- id: string;
10856
- } & Partial<Omit<TodoItem, 'id'>>;
10857
- interface TodoStoreOptions {
10858
- /** 变更回调:replace/merge 每次调用后触发一次,载荷为变更后完整列表的独立副本 */
10859
- onChange?: (items: TodoItem[]) => void;
10860
- }
10861
- declare class TodoStore {
10862
- #private;
10863
- constructor(options?: TodoStoreOptions);
10864
- /** 当前列表(副本;修改返回值不影响内部状态) */
10865
- list(): TodoItem[];
10866
- /** 全量替换(含替换为空 = 清空台账),返回变更后快照 */
10867
- replace(items: readonly TodoItem[]): TodoItem[];
10868
- /**
10869
- * 按 id 合并:已知 id 原位覆盖给定字段;未知 id 按提交顺序追加到尾部。
10870
- * 返回变更后快照。未知 id 缺 content/status 视为调用方契约错误,抛 TypeError。
10871
- */
10872
- merge(patches: readonly TodoPatch[]): TodoItem[];
10873
- }
10874
-
10875
10867
  /**
10876
10868
  * T-D6 — 交互通道抽象:AskUser 工具与表面层之间的依赖注入缝。
10877
10869
  *
@@ -15542,22 +15534,79 @@ interface AppBundleModel {
15542
15534
  capabilities: Record<string, unknown>;
15543
15535
  contextWindow: number | null;
15544
15536
  }
15537
+ /**
15538
+ * 图像模型受理约束(bundle platformModels.imageGen 行 constraints 加法键,
15539
+ * 2026-09-01;网关侧单源 = /t1 运行时校验档同一 classify 词表)。工具描述
15540
+ * 逐模型拼注——智能体首发即中,不再靠拒收错误试错(用户实测连环拒收后追加)。
15541
+ */
15542
+ interface ImageModelConstraints {
15543
+ /** false = 模型定档分辨率,size 在场即拒。 */
15544
+ size: boolean;
15545
+ seed: boolean;
15546
+ negativePrompt: boolean;
15547
+ /** 单请求张数帽(n 超帽由网关钳)。 */
15548
+ maxImages: number;
15549
+ /** 富输入 imageUrls 受理域(null = 纯文生行,在场即拒)。 */
15550
+ imageInput: {
15551
+ min: number;
15552
+ max: number;
15553
+ urlOk: boolean;
15554
+ b64Ok: boolean;
15555
+ } | null;
15556
+ /** false = 动词行(引用既有任务),prompt 在场即拒。 */
15557
+ promptRequired: boolean;
15558
+ /** 动词行必携 action{taskId,actionId}。 */
15559
+ actionRequired?: boolean;
15560
+ }
15561
+ /** 视频模型受理约束(同上镜像;时长域/首帧受理/比例域是实测三大拒收源)。 */
15562
+ interface VideoModelConstraints {
15563
+ durations: {
15564
+ kind: 'set';
15565
+ values: number[];
15566
+ defaultSec: number;
15567
+ } | {
15568
+ kind: 'range';
15569
+ min: number;
15570
+ max: number;
15571
+ defaultSec: number;
15572
+ };
15573
+ /** 比例词形域(null = ratio 在场即拒;键缺席 = 透传上游,域未实录)。 */
15574
+ ratio?: string[] | null;
15575
+ negativePrompt: boolean;
15576
+ seed: boolean;
15577
+ /** 首帧图受理域(required = i2v 专用行必携 imageUrls;null = 纯文生行在场即拒)。 */
15578
+ imageInput: {
15579
+ required: boolean;
15580
+ max: number;
15581
+ urlOk: boolean;
15582
+ b64Ok: boolean;
15583
+ } | null;
15584
+ audioInput: boolean;
15585
+ }
15545
15586
  /**
15546
15587
  * 授权媒体模型条目(S-G1 媒体池化顺位取用,用户拍板 2026-08-30):`model` =
15547
15588
  * canonical handle(/t1/imagegen、/t1/videogen 的 model 位可直用)。网关契约
15548
- * 恒不下发价格/成本/供应商内部信息,本形态即全量。
15589
+ * 恒不下发价格/成本/供应商内部信息。constraints 加法键(2026-09-01)按 kind
15590
+ * 特化(下方两型);条目级容错:缺席/坏形状 = undefined(旧 api 回落通用
15591
+ * 描述,恒不臆造受理面)。
15549
15592
  */
15550
15593
  interface AppBundleMediaModel {
15551
15594
  model: string;
15552
15595
  displayName: string;
15553
15596
  }
15597
+ interface AppBundleImageModel extends AppBundleMediaModel {
15598
+ constraints?: ImageModelConstraints;
15599
+ }
15600
+ interface AppBundleVideoModel extends AppBundleMediaModel {
15601
+ constraints?: VideoModelConstraints;
15602
+ }
15554
15603
  /**
15555
15604
  * 授权媒体模型集(bundle platformModels 段):序 = 平台收敛稳定序,**顺位第一
15556
15605
  * 即工具/网关 model 缺省时的生效模型**;空数组 = 平台未配置(如实,恒不猜名)。
15557
15606
  */
15558
15607
  interface AppBundlePlatformModels {
15559
- imageGen: AppBundleMediaModel[];
15560
- videoGen: AppBundleMediaModel[];
15608
+ imageGen: AppBundleImageModel[];
15609
+ videoGen: AppBundleVideoModel[];
15561
15610
  }
15562
15611
  /** bundle-for-app 的 SDK 消费子集 */
15563
15612
  interface AppBundle {
@@ -16539,6 +16588,15 @@ declare function assemblePlatformModel(options: AssemblePlatformModelOptions): P
16539
16588
 
16540
16589
  /** 生成张数 wire 帽(与网关 TwpImagegenRequestSchema 同值;超模型帽由网关再钳)。 */
16541
16590
  declare const IMAGEGEN_TOOL_MAX_N = 4;
16591
+ /**
16592
+ * 客户端硬超时缺省(毫秒;kernel Tool.timeoutMs 位)= 服务端生成预算 120s
16593
+ * (tansr-api IMAGEGEN_DEFAULT_TIMEOUT_MS,解出层全模型恒用此值——含 classic
16594
+ * 万相异步任务与 mj_task midjourney 任务轮询长径)+ 60s 余量(videogen 同口径:
16595
+ * 请求上行/网关前置/响应回传)。kernel 统一档同为 120s、对服务端预算零余量——
16596
+ * 任务径跑满预算时客户端恒先掐(同 videogen 的有扣无产形态,窗口更短),故
16597
+ * 显式声明盖过。
16598
+ */
16599
+ declare const IMAGEGEN_TOOL_TIMEOUT_MS = 180000;
16542
16600
  declare const ImageGenArgsSchema: z.ZodObject<{
16543
16601
  model: z.ZodOptional<z.ZodString>;
16544
16602
  prompt: z.ZodEffects<z.ZodString, string, string>;
@@ -16546,20 +16604,23 @@ declare const ImageGenArgsSchema: z.ZodObject<{
16546
16604
  size: z.ZodOptional<z.ZodString>;
16547
16605
  n: z.ZodOptional<z.ZodNumber>;
16548
16606
  seed: z.ZodOptional<z.ZodNumber>;
16607
+ imageUrls: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
16549
16608
  }, "strip", z.ZodTypeAny, {
16550
16609
  prompt: string;
16551
16610
  model?: string | undefined;
16552
16611
  size?: string | undefined;
16553
16612
  n?: number | undefined;
16554
- negativePrompt?: string | undefined;
16555
16613
  seed?: number | undefined;
16614
+ negativePrompt?: string | undefined;
16615
+ imageUrls?: string[] | undefined;
16556
16616
  }, {
16557
16617
  prompt: string;
16558
16618
  model?: string | undefined;
16559
16619
  size?: string | undefined;
16560
16620
  n?: number | undefined;
16561
- negativePrompt?: string | undefined;
16562
16621
  seed?: number | undefined;
16622
+ negativePrompt?: string | undefined;
16623
+ imageUrls?: string[] | undefined;
16563
16624
  }>;
16564
16625
  type ImageGenArgs = z.infer<typeof ImageGenArgsSchema>;
16565
16626
  /** 表面层渲染用结构化数据(ToolResult.data;错误时携错误码)。 */
@@ -16581,11 +16642,18 @@ interface CreateImageGenToolOptions {
16581
16642
  fetchImpl?: typeof fetch;
16582
16643
  /**
16583
16644
  * 授权图像模型集(S-G1;bundle platformModels.imageGen,装配循环自取):
16584
- * 工具描述自列(顺位第一 = model 缺省生效模型);空数组 = 平台未配置
16585
- * (描述如实注明,恒不猜名);缺席 = 集未知(注入档直构/旧径),描述回落
16586
- * 通用指引。
16645
+ * 工具描述自列(顺位第一 = model 缺省生效模型),constraints 在场时逐模型
16646
+ * 拼受理约束注记(2026-09-01——size/富输入/动词行,智能体首发即中);
16647
+ * 空数组 = 平台未配置(描述如实注明,恒不猜名);缺席 = 集未知(注入档
16648
+ * 直构/旧径),描述回落通用指引。
16649
+ */
16650
+ models?: readonly AppBundleImageModel[];
16651
+ /**
16652
+ * 客户端硬超时覆盖(毫秒;透传 kernel Tool.timeoutMs)。缺省
16653
+ * IMAGEGEN_TOOL_TIMEOUT_MS(服务端 120s 预算 + 60s 余量)——恒不回落
16654
+ * kernel 120s 统一档(与服务端预算零余量,任务轮询径必先掐)。
16587
16655
  */
16588
- models?: readonly AppBundleMediaModel[];
16656
+ timeoutMs?: number;
16589
16657
  }
16590
16658
  /**
16591
16659
  * 环3 平台图像生成工具(kernel Tool 形态;name 'ImageGen' 沿 kernel PascalCase
@@ -16614,6 +16682,16 @@ declare function createImageGenTool(options: CreateImageGenToolOptions): Tool<Im
16614
16682
 
16615
16683
  /** 时长 wire 帽(秒;与网关 TwpVideogenRequestSchema 同值;超模型帽由网关再钳)。 */
16616
16684
  declare const VIDEOGEN_TOOL_MAX_DURATION = 30;
16685
+ /**
16686
+ * 客户端硬超时缺省(毫秒;kernel Tool.timeoutMs 位)= 服务端轮询预算 600s
16687
+ * (tansr-api VIDEOGEN_DEFAULT_TIMEOUT_MS,解出层全模型恒用此值)+ 60s 余量
16688
+ * (请求上行/网关前置[认证/限流/配额/预扣]/响应回传)。/t1/videogen 系服务端
16689
+ * 同步长等——客户端必须等到服务端先出结论(成功或 upstream_timeout 退款),
16690
+ * 恒不先掐:客户端先超时会复现「服务端成功结算而智能体无产出」的有扣无产
16691
+ * (2026-09-01 定谳:kling-v3 实测 122-185s,kernel 120s 缺省档下结构性必超时,
16692
+ * 三笔 ¥2.40 计 ¥7.20 有扣无产)。
16693
+ */
16694
+ declare const VIDEOGEN_TOOL_TIMEOUT_MS = 660000;
16617
16695
  declare const VideoGenArgsSchema: z.ZodObject<{
16618
16696
  model: z.ZodOptional<z.ZodString>;
16619
16697
  prompt: z.ZodEffects<z.ZodString, string, string>;
@@ -16621,20 +16699,23 @@ declare const VideoGenArgsSchema: z.ZodObject<{
16621
16699
  duration: z.ZodOptional<z.ZodNumber>;
16622
16700
  ratio: z.ZodOptional<z.ZodString>;
16623
16701
  seed: z.ZodOptional<z.ZodNumber>;
16702
+ imageUrls: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
16624
16703
  }, "strip", z.ZodTypeAny, {
16625
16704
  prompt: string;
16626
16705
  model?: string | undefined;
16627
16706
  duration?: number | undefined;
16628
- negativePrompt?: string | undefined;
16629
16707
  seed?: number | undefined;
16708
+ negativePrompt?: string | undefined;
16630
16709
  ratio?: string | undefined;
16710
+ imageUrls?: string[] | undefined;
16631
16711
  }, {
16632
16712
  prompt: string;
16633
16713
  model?: string | undefined;
16634
16714
  duration?: number | undefined;
16635
- negativePrompt?: string | undefined;
16636
16715
  seed?: number | undefined;
16716
+ negativePrompt?: string | undefined;
16637
16717
  ratio?: string | undefined;
16718
+ imageUrls?: string[] | undefined;
16638
16719
  }>;
16639
16720
  type VideoGenArgs = z.infer<typeof VideoGenArgsSchema>;
16640
16721
  /** 表面层渲染用结构化数据(ToolResult.data;错误时携错误码)。 */
@@ -16658,11 +16739,18 @@ interface CreateVideoGenToolOptions {
16658
16739
  fetchImpl?: typeof fetch;
16659
16740
  /**
16660
16741
  * 授权视频模型集(S-G1;bundle platformModels.videoGen,装配循环自取):
16661
- * 工具描述自列(顺位第一 = model 缺省生效模型);空数组 = 平台未配置
16662
- * (描述如实注明,恒不猜名);缺席 = 集未知(注入档直构/旧径),描述回落
16663
- * 通用指引。
16742
+ * 工具描述自列(顺位第一 = model 缺省生效模型),constraints 在场时逐模型
16743
+ * 拼受理约束注记(2026-09-01——时长域/i2v 首帧/比例域,实测三大拒收源
16744
+ * 前置进描述);空数组 = 平台未配置(如实注明恒不猜名);缺席 = 集未知
16745
+ * (注入档直构/旧径),描述回落通用指引。
16664
16746
  */
16665
- models?: readonly AppBundleMediaModel[];
16747
+ models?: readonly AppBundleVideoModel[];
16748
+ /**
16749
+ * 客户端硬超时覆盖(毫秒;透传 kernel Tool.timeoutMs)。缺省
16750
+ * VIDEOGEN_TOOL_TIMEOUT_MS(服务端 600s 预算 + 60s 余量)——恒不回落
16751
+ * kernel 120s 统一档(视频生成分钟级,120s 帽结构性必超时)。
16752
+ */
16753
+ timeoutMs?: number;
16666
16754
  }
16667
16755
  /**
16668
16756
  * 环3 平台视频生成工具(kernel Tool 形态;name 'VideoGen' 沿 kernel PascalCase
@@ -16738,5 +16826,5 @@ declare function attachSdkTaskTool(toolset: SdkToolsetRef, config: AttachSdkTask
16738
16826
  */
16739
16827
  declare function subagentModelResolverOf(registry: ProviderRegistry | null): SubagentModelResolver | undefined;
16740
16828
 
16741
- export { APP_SDK_CONTRACT_VERSION, APP_TOKEN_PLACEHOLDER_ENV, AgentSession, AppCapabilitiesSchema, AppTokenRequestSchema, AppTokenResponseSchema, DEFAULT_APP_CAPABILITIES, DEFAULT_MAX_TOKENS, DEFAULT_MAX_TURNS, EndUserIdSchema, HEADER_APP_TOKEN, IMAGEGEN_TOOL_MAX_N, ImageGenArgsSchema, McpHost, OUTPUT_TAIL_MAX_CHARS, PLATFORM_SEARCH_PROVIDER_NAME, QueueChannel, SequentialToolExecutor, TANSR_PROVIDER_ID, TOOL_GUIDE_LABEL, TansrSdkError, UnavailableChannel, VIDEOGEN_TOOL_MAX_DURATION, VideoGenArgsSchema, accumulateUsage, appBundleRegistryConfig, appendUserMessage, assembleManagedModel, assemblePlatformModel, assembleSdkSkills, assembleTooling, attachSdkMcp, attachSdkTaskTool, buildClientFromRegistry, buildSdkToolSet, buildToolGuideSegment, createAppTokenFetch, createFileSessionStore, createImageGenTool, createMcpHost, createNarrator, createPlatformSearchProvider, createSdkPermissionGate, createSession, createSessionView, createVideoGenTool, defineSkill, defineTool, initialSessionViewState, markSourceFailure, parseAppBundle, providerSwitchedBody, query, reduceSessionView, resolveBuiltinSelection, resolveInitialMessages, resolvePlatformSelection, runAgent, subagentModelResolverOf, toToolDef, viewStateFromHistory };
16742
- export type { ActiveToolStatus, Answer, AppBundle, AppBundleMediaModel, AppBundleModel, AppBundlePlatformModels, AppCapabilities, AppTokenRequest, AppTokenResponse, AskUserCallback, AssembleManagedModelOptions, AssemblePlatformModelOptions, AssembleToolingOptions, AssembledManagedModel, AssembledPlatformModel, AssembledSkills, AssembledTooling, AttachSdkTaskToolConfig, BuildSdkToolSetOptions, BuiltinToolName, Capability, CompactNowOptions, CompactNowResult, ConfigDiagnostic, CreateFileSessionStoreOptions, CreateImageGenToolOptions, CreatePlatformSearchProviderOptions, CreateSdkPermissionGateOptions, CreateSessionOptions, CreateVideoGenToolOptions, DecisionSource, DefineSkillOptions, DefineToolOptions, DefinedSkill, DefinedTool, ErrorView, EventBody, EventEnvelope, GateDecision, HistoryCommitMeta, HookOutcomeStatus, IRBlock, IRErrorKind, IRMessage, IRRequest, IRRole, IRStreamEvent, IRSystemSegment, IRToolContent, IRToolDef, IRToolResultBlock, IRUsage, ImageGenArgs, ImageGenData, Integrity, JournalKind, JournalRecord, KernelEvent, KernelState, LoadConfigOptions, LoadedConfig, ManagedQueryOptions, McpClientEvent, McpConnectFactory, McpConnection, McpEventObserver, McpHostOptions, McpServerConfig, McpSessionOption, ModelCallOptions, ModelClient, Narrator, NarratorOptions, NarratorVerbosity, PermissionDecision, PermissionGate, PermissionMode, PermissionOptions, PermissionRules, PlatformCapabilityName, PlatformToolContext, Pricing, PromptCachingMode, PromptChannel, ProposedToolCall, ProtocolKind, ProviderProfile, QueryCompactionOptions, QueryCounters, QueryHandle, QueryOptions, QueryResult, Question, QuestionOption, ResolvedModel, RunAgentOptions, SdkErrorCode, SdkSkillsOptions, SdkToolSet, SdkToolsOptions, SdkToolsetRef, SequentialToolHandler, SequentialToolResult, SessionEventSource, SessionRecord, SessionRecordMeta, SessionStore, SessionStoreCommitMeta, SessionStoreCreateInit, SessionView, SessionViewReducerState, SessionViewSource, SessionViewState, SessionViewStatus, SetModelBinding, SkillsFileSystem, TansrConfig, TerminalReason, TodoView, Tool, ToolCallPartStatus, ToolCallView, ToolContext, ToolErrorType, ToolExecutionContext, ToolExecutionOutcome, ToolExecutor, ToolExecutorYield, ToolParameterSpec, ToolResult, ToolResultContent, UIMessage, UIMessagePart, UITextPart, UIThinkingPart, UIToolCallPart, UsageView, VideoGenArgs, VideoGenData, Visibility };
16829
+ export { APP_SDK_CONTRACT_VERSION, APP_TOKEN_PLACEHOLDER_ENV, AgentSession, AppCapabilitiesSchema, AppTokenRequestSchema, AppTokenResponseSchema, DEFAULT_APP_CAPABILITIES, DEFAULT_MAX_TOKENS, DEFAULT_MAX_TURNS, EndUserIdSchema, HEADER_APP_TOKEN, IMAGEGEN_TOOL_MAX_N, IMAGEGEN_TOOL_TIMEOUT_MS, ImageGenArgsSchema, McpHost, OUTPUT_TAIL_MAX_CHARS, PLATFORM_SEARCH_PROVIDER_NAME, QueueChannel, SequentialToolExecutor, TANSR_PROVIDER_ID, TOOL_GUIDE_LABEL, TansrSdkError, UnavailableChannel, VIDEOGEN_TOOL_MAX_DURATION, VIDEOGEN_TOOL_TIMEOUT_MS, VideoGenArgsSchema, accumulateUsage, appBundleRegistryConfig, appendUserMessage, assembleManagedModel, assemblePlatformModel, assembleSdkSkills, assembleTooling, attachSdkMcp, attachSdkTaskTool, buildClientFromRegistry, buildSdkToolSet, buildToolGuideSegment, createAppTokenFetch, createFileSessionStore, createImageGenTool, createMcpHost, createNarrator, createPlatformSearchProvider, createSdkPermissionGate, createSession, createSessionView, createVideoGenTool, defineSkill, defineTool, initialSessionViewState, markSourceFailure, parseAppBundle, providerSwitchedBody, query, reduceSessionView, resolveBuiltinSelection, resolveInitialMessages, resolvePlatformSelection, runAgent, subagentModelResolverOf, toToolDef, viewStateFromHistory };
16830
+ export type { ActiveToolStatus, Answer, AppBundle, AppBundleImageModel, AppBundleMediaModel, AppBundleModel, AppBundlePlatformModels, AppBundleVideoModel, AppCapabilities, AppTokenRequest, AppTokenResponse, AskUserCallback, AssembleManagedModelOptions, AssemblePlatformModelOptions, AssembleToolingOptions, AssembledManagedModel, AssembledPlatformModel, AssembledSkills, AssembledTooling, AttachSdkTaskToolConfig, BuildSdkToolSetOptions, BuiltinToolName, Capability, CompactNowOptions, CompactNowResult, ConfigDiagnostic, CreateFileSessionStoreOptions, CreateImageGenToolOptions, CreatePlatformSearchProviderOptions, CreateSdkPermissionGateOptions, CreateSessionOptions, CreateVideoGenToolOptions, DecisionSource, DefineSkillOptions, DefineToolOptions, DefinedSkill, DefinedTool, ErrorView, EventBody, EventEnvelope, GateDecision, HistoryCommitMeta, HookOutcomeStatus, IRBlock, IRErrorKind, IRMessage, IRRequest, IRRole, IRStreamEvent, IRSystemSegment, IRToolContent, IRToolDef, IRToolResultBlock, IRUsage, ImageGenArgs, ImageGenData, ImageModelConstraints, Integrity, JournalKind, JournalRecord, KernelEvent, KernelState, LoadConfigOptions, LoadedConfig, ManagedQueryOptions, McpClientEvent, McpConnectFactory, McpConnection, McpEventObserver, McpHostOptions, McpServerConfig, McpSessionOption, ModelCallOptions, ModelClient, Narrator, NarratorOptions, NarratorVerbosity, PermissionDecision, PermissionGate, PermissionMode, PermissionOptions, PermissionRules, PlatformCapabilityName, PlatformToolContext, Pricing, PromptCachingMode, PromptChannel, ProposedToolCall, ProtocolKind, ProviderProfile, QueryCompactionOptions, QueryCounters, QueryHandle, QueryOptions, QueryResult, Question, QuestionOption, ResolvedModel, RunAgentOptions, SdkErrorCode, SdkSkillsOptions, SdkToolSet, SdkToolsOptions, SdkToolsetRef, SequentialToolHandler, SequentialToolResult, SessionEventSource, SessionRecord, SessionRecordMeta, SessionStore, SessionStoreCommitMeta, SessionStoreCreateInit, SessionView, SessionViewReducerState, SessionViewSource, SessionViewState, SessionViewStatus, SetModelBinding, SkillsFileSystem, TansrConfig, TerminalReason, TodoView, Tool, ToolCallPartStatus, ToolCallView, ToolContext, ToolErrorType, ToolExecutionContext, ToolExecutionOutcome, ToolExecutor, ToolExecutorYield, ToolParameterSpec, ToolResult, ToolResultContent, UIMessage, UIMessagePart, UITextPart, UIThinkingPart, UIToolCallPart, UsageView, VideoGenArgs, VideoGenData, VideoModelConstraints, Visibility };
package/dist/index.js CHANGED
@@ -1455,8 +1455,9 @@ var PermissionsSectionSchema = z5.object({
1455
1455
  * TANSR_CLASSIFIER_TIGHTEN_OUTSIDE_AUTO / TANSR_CLASSIFIER_BUDGET 保留为
1456
1456
  * 最高优先覆盖(逐键接管)。仅 user/managed 层被尊重(T-K0:分类器属
1457
1457
  * 用户/企业的信任与成本决策,项目层声明整段忽略+示警)。
1458
- * 刻意不进配置:TANSR_CLASSIFIER_ALLOW_UNQUALIFIED(资格越过)——
1459
- * break-glass 性质,进配置文件即可分发可持久,恒 env-only
1458
+ * 史注:TANSR_CLASSIFIER_ALLOW_UNQUALIFIED(资格越过)曾刻意不进配置
1459
+ * (break-glass 性质恒 env-only),已随 UAA P4-C2 整体退役(2026-08-30,
1460
+ * 任命即授照后无「未达资格」可越)。
1460
1461
  */
1461
1462
  classifier: z5.object({
1462
1463
  enabled: z5.boolean().optional(),
@@ -11984,14 +11985,14 @@ var PermissionEngine = class {
11984
11985
  /**
11985
11986
  * 生效资格档解析(T-K23c,16 §4.5):解析闭包在场即**现算**(装配层合成
11986
11987
  * min(entry, ceiling, override);闭包抛错 → 'none',词表外脏值由
11987
- * softenRadiusAllows 安全查表兜底——T-INV-B 一切异常朝严);闭包缺席时
11988
- * @deprecated 布尔位派生 `true→'high'/false|缺省→'none'`(W1 过渡
11989
- * 兼容,16 §4.5;收口见 T-K23g)。
11988
+ * softenRadiusAllows 安全查表兜底——T-INV-B 一切异常朝严);闭包缺席
11989
+ * 'none'(无任命即无软化面;@deprecated 布尔位 qualifiedForAllow
11990
+ * 已随 P4-C3 拆除,2026-08-30)。
11990
11991
  */
11991
11992
  resolveClassifierTier(config) {
11992
11993
  const resolve2 = config.resolveQualificationTier;
11993
11994
  if (resolve2 === void 0) {
11994
- return config.qualifiedForAllow === true ? "high" : "none";
11995
+ return "none";
11995
11996
  }
11996
11997
  try {
11997
11998
  return resolve2();
@@ -12964,6 +12965,47 @@ function buildDecisionRecord(params) {
12964
12965
  }
12965
12966
 
12966
12967
  // ../kernel/src/tools/dispatch/dispatching-tool-executor.ts
12968
+ function suggestToolName(attempted, registered) {
12969
+ const norm = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
12970
+ const a = norm(attempted);
12971
+ if (a === "") return null;
12972
+ let prefixHit = null;
12973
+ let levHit = null;
12974
+ let levBest = 3;
12975
+ for (const name of registered) {
12976
+ const n = norm(name);
12977
+ if (n === a) return name;
12978
+ if (prefixHit === null && Math.min(n.length, a.length) >= 4 && (n.startsWith(a) || a.startsWith(n))) {
12979
+ prefixHit = name;
12980
+ }
12981
+ const d = boundedLevenshtein(a, n, 2);
12982
+ if (d !== null && d < levBest) {
12983
+ levBest = d;
12984
+ levHit = name;
12985
+ }
12986
+ }
12987
+ return prefixHit ?? levHit;
12988
+ }
12989
+ function boundedLevenshtein(a, b, cap) {
12990
+ if (Math.abs(a.length - b.length) > cap) return null;
12991
+ let prev = Array.from({ length: b.length + 1 }, (_, j) => j);
12992
+ for (let i = 1; i <= a.length; i++) {
12993
+ const cur = [i, ...Array.from({ length: b.length }, () => 0)];
12994
+ let rowMin = i;
12995
+ for (let j = 1; j <= b.length; j++) {
12996
+ cur[j] = Math.min(
12997
+ prev[j] + 1,
12998
+ cur[j - 1] + 1,
12999
+ prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)
13000
+ );
13001
+ rowMin = Math.min(rowMin, cur[j]);
13002
+ }
13003
+ if (rowMin > cap) return null;
13004
+ prev = cur;
13005
+ }
13006
+ const d = prev[b.length];
13007
+ return d <= cap ? d : null;
13008
+ }
12967
13009
  var DEFAULT_MAX_CONCURRENCY = 8;
12968
13010
  var DEFAULT_TIMEOUT_MS = 12e4;
12969
13011
  var unsafeNoGateConstruction = false;
@@ -13163,7 +13205,8 @@ var DispatchingToolExecutor = class {
13163
13205
  const tool = this.#registry.get(call.name);
13164
13206
  if (tool === void 0) {
13165
13207
  const registered = this.#registry.names();
13166
- const message = `Unknown tool "${call.name}". ` + (registered.length > 0 ? `Available tools: ${registered.join(", ")}.` : "No tools are registered.");
13208
+ const suggested = suggestToolName(call.name, registered);
13209
+ const message = `Unknown tool "${call.name}". ` + (suggested !== null ? `Did you mean "${suggested}"? ` : "") + (registered.length > 0 ? `Available tools: ${registered.join(", ")}.` : "No tools are registered.");
13167
13210
  yield {
13168
13211
  t: "event",
13169
13212
  body: { type: "tool.failed", toolCallId: call.id, errorType: "unknown_tool", message }
@@ -30808,17 +30851,23 @@ var AppQuotaSchema = z41.object({
30808
30851
  // src/platform/imagegen-tool.ts
30809
30852
  import { z as z42 } from "zod";
30810
30853
  var IMAGEGEN_TOOL_MAX_N = 4;
30854
+ var IMAGEGEN_TOOL_TIMEOUT_MS = 18e4;
30811
30855
  var ImageGenArgsSchema = z42.object({
30812
30856
  // S-G1(媒体池化顺位取用):Optional——缺席即不发 model 位,网关按授权集顺位
30813
30857
  // 第一生效(与 bundle platformModels.imageGen 首行恒同);点名限集内(工具描述自列)。
30814
30858
  model: z42.string().min(1).optional().describe(
30815
- "Image model name from the authorized set listed in this tool description. Omit to use the default (the first authorized model)."
30859
+ "Image model name from the authorized set listed in this tool description. Omit to use the default (the first authorized model) when the user did not ask for a specific model. Never omit or swap this field as a workaround when the user named a model that is not in the set — tell the user and let them choose first."
30816
30860
  ),
30817
30861
  prompt: z42.string().refine((s) => s.trim().length > 0, { message: "prompt must be a non-empty string" }).describe("Positive prompt describing the desired image content, style and composition."),
30818
30862
  negativePrompt: z42.string().min(1).max(500).optional().describe("Negative prompt: content to keep out of the image."),
30819
30863
  size: z42.string().regex(/^\d{2,5}\*\d{2,5}$/, { message: "size must look like '1024*1024' (width*height)" }).optional().describe("Output resolution as 'width*height' (for example '1024*1024'; defaults to the model's default)."),
30820
30864
  n: z42.number().int().min(1).max(IMAGEGEN_TOOL_MAX_N).optional().describe(`Number of images to generate (default 1, max ${IMAGEGEN_TOOL_MAX_N}; each image is billed).`),
30821
- seed: z42.number().int().min(0).max(2147483647).optional().describe("Random seed for relatively stable output (defaults to a random seed upstream).")
30865
+ seed: z42.number().int().min(0).max(2147483647).optional().describe("Random seed for relatively stable output (defaults to a random seed upstream)."),
30866
+ // 媒体二批富输入位(2026-09-01;网关 TwpImagegenRequestSchema 同帽 1..14):
30867
+ // 受理域随模型(工具描述逐模型注明;不受理的模型在场即 bad_request)。
30868
+ imageUrls: z42.array(z42.string().min(1)).min(1).max(14).optional().describe(
30869
+ "Input images for image editing or reference-conditioned generation (public http(s) URLs or data:image/*;base64 URIs). Only pass this for models whose bracketed note in this description lists imageUrls support; other models reject it."
30870
+ )
30822
30871
  });
30823
30872
  function errorResult13(text, model, errorCode2) {
30824
30873
  const data = { model, images: [], imageCount: 0, ...errorCode2 !== void 0 ? { errorCode: errorCode2 } : {} };
@@ -30832,7 +30881,7 @@ function hintOf(code) {
30832
30881
  return " Image generation is not configured on this platform yet; tell the user instead of retrying.";
30833
30882
  }
30834
30883
  if (code === "model_not_authorized") {
30835
- return " Use an image model name that this app is authorized for.";
30884
+ return ` The requested model is not in the authorized image model set of this app. Do not silently retry with another model or without "model" — tell the user, show the authorized image models from this tool's description, and let the user choose.`;
30836
30885
  }
30837
30886
  if (code === "imagegen_quota_exceeded") {
30838
30887
  return " The daily image quota for this account is exhausted; retry after the daily reset (UTC+8).";
@@ -30842,6 +30891,25 @@ function hintOf(code) {
30842
30891
  }
30843
30892
  return "";
30844
30893
  }
30894
+ function imageModelNote(m) {
30895
+ const label = m.displayName !== m.model ? `${m.model} (${m.displayName})` : m.model;
30896
+ const c = m.constraints;
30897
+ if (c === void 0) return label;
30898
+ const notes = [];
30899
+ if (!c.promptRequired) {
30900
+ notes.push("task-action model, NOT usable via this tool — pick another model");
30901
+ }
30902
+ if (!c.size) notes.push("fixed output size — do not pass size");
30903
+ if (c.imageInput !== null) {
30904
+ const forms = c.imageInput.urlOk && c.imageInput.b64Ok ? "URL or base64 data URI" : c.imageInput.urlOk ? "URL only" : "base64 data URI only";
30905
+ const count = c.imageInput.min > 0 ? `requires ${c.imageInput.min === c.imageInput.max ? String(c.imageInput.min) : `${c.imageInput.min}-${c.imageInput.max}`} input image(s)` : `accepts up to ${c.imageInput.max} reference image(s)`;
30906
+ notes.push(`${count} via imageUrls (${forms})`);
30907
+ }
30908
+ if (!c.seed) notes.push("no seed");
30909
+ if (!c.negativePrompt) notes.push("no negativePrompt");
30910
+ if (c.maxImages === 1) notes.push("single image per call (n=1)");
30911
+ return notes.length > 0 ? `${label} [${notes.join("; ")}]` : label;
30912
+ }
30845
30913
  function authorizedModelsNote(models) {
30846
30914
  if (models === void 0) {
30847
30915
  return ' Omit "model" to use the app default, or ask the app developer for authorized model names.';
@@ -30849,8 +30917,8 @@ function authorizedModelsNote(models) {
30849
30917
  if (models.length === 0) {
30850
30918
  return " The platform has no image model configured for this app yet — tell the user instead of retrying or guessing model names.";
30851
30919
  }
30852
- const listed = models.map((m) => m.displayName !== m.model ? `${m.model} (${m.displayName})` : m.model).join(", ");
30853
- return ` Authorized image models (omit "model" to use the first as default): ${listed}.`;
30920
+ const listed = models.map((m) => `- ${imageModelNote(m)}`).join("\n");
30921
+ return ' Authorized image models — the first is the default when "model" is omitted; bracketed notes are hard per-model constraints enforced by the platform (violating them fails the call):\n' + listed + '\nIf the user names a model outside this list (including a video model asked to make images), do not silently omit "model" or substitute another model — tell the user, show this list, and let them choose.';
30854
30922
  }
30855
30923
  function createImageGenTool(options) {
30856
30924
  const base = options.baseUrl.replace(/\/+$/, "");
@@ -30858,11 +30926,14 @@ function createImageGenTool(options) {
30858
30926
  const token = options.token;
30859
30927
  return {
30860
30928
  name: "ImageGen",
30861
- description: "Generates images from a text prompt via the tansr platform (ring-3 hosted capability; the platform calls the image provider and bills the app per generated image). Returns image URLs that stay valid for roughly 24 hours — surface them to the user promptly. Requires the app to have the imageGen platform capability enabled." + authorizedModelsNote(options.models),
30862
- shortDescription: "Generate images from a prompt via the tansr platform (billed per image). Args: model?, prompt, negativePrompt?, size?, n?, seed?.",
30929
+ description: "Generates images from a text prompt via the tansr platform (ring-3 hosted capability; the platform calls the image provider and bills the app per generated image). Some models run as polled tasks and can take a minute or two — client-side wait cap is ~3 minutes. Returns image URLs that stay valid for roughly 24 hours — surface them to the user promptly. Requires the app to have the imageGen platform capability enabled." + authorizedModelsNote(options.models),
30930
+ shortDescription: "Generate images from a prompt via the tansr platform (billed per image). Args: model?, prompt, negativePrompt?, size?, n?, seed?, imageUrls?.",
30863
30931
  inputSchema: ImageGenArgsSchema,
30864
30932
  isReadOnly: false,
30865
30933
  isConcurrencySafe: false,
30934
+ // 2026-09-01 定谳修(videogen 同批):服务端预算 120s 与 kernel 120s 缺省档
30935
+ // 零余量,classic/mj_task 任务轮询径跑满预算时客户端恒先掐——声明 180s 盖过。
30936
+ timeoutMs: options.timeoutMs ?? IMAGEGEN_TOOL_TIMEOUT_MS,
30866
30937
  async execute(args, ctx) {
30867
30938
  const modelRef = args.model ?? "(default)";
30868
30939
  if (ctx.signal.aborted) {
@@ -30874,7 +30945,8 @@ function createImageGenTool(options) {
30874
30945
  ...args.negativePrompt !== void 0 ? { negativePrompt: args.negativePrompt } : {},
30875
30946
  ...args.size !== void 0 ? { size: args.size } : {},
30876
30947
  ...args.n !== void 0 ? { n: args.n } : {},
30877
- ...args.seed !== void 0 ? { seed: args.seed } : {}
30948
+ ...args.seed !== void 0 ? { seed: args.seed } : {},
30949
+ ...args.imageUrls !== void 0 ? { imageUrls: args.imageUrls } : {}
30878
30950
  };
30879
30951
  let response;
30880
30952
  try {
@@ -30926,19 +30998,26 @@ function createImageGenTool(options) {
30926
30998
  // src/platform/videogen-tool.ts
30927
30999
  import { z as z43 } from "zod";
30928
31000
  var VIDEOGEN_TOOL_MAX_DURATION = 30;
31001
+ var VIDEOGEN_TOOL_TIMEOUT_MS = 66e4;
30929
31002
  var VideoGenArgsSchema = z43.object({
30930
31003
  // S-G1(媒体池化顺位取用):Optional——缺席即不发 model 位,网关按授权集顺位
30931
31004
  // 第一生效(与 bundle platformModels.videoGen 首行恒同);点名限集内(工具描述自列)。
30932
31005
  model: z43.string().min(1).optional().describe(
30933
- "Video model name from the authorized set listed in this tool description. Omit to use the default (the first authorized model)."
31006
+ "Video model name from the authorized set listed in this tool description. Omit to use the default (the first authorized model) when the user did not ask for a specific model. Never omit or swap this field as a workaround when the user named a model that is not in the set — tell the user and let them choose first."
30934
31007
  ),
30935
31008
  prompt: z43.string().refine((s) => s.trim().length > 0, { message: "prompt must be a non-empty string" }).describe("Positive prompt describing the desired video content, motion, style and camera work."),
30936
31009
  negativePrompt: z43.string().min(1).max(500).optional().describe("Negative prompt: content to keep out of the video."),
30937
31010
  duration: z43.number().int().min(2).max(VIDEOGEN_TOOL_MAX_DURATION).optional().describe(
30938
- `Video duration in seconds (default 5, max ${VIDEOGEN_TOOL_MAX_DURATION}; billing is per second — longer costs more).`
31011
+ "Video duration in seconds (billing is per second — longer costs more). Models accept only the durations listed in their bracketed note; omit to use the model default."
30939
31012
  ),
30940
31013
  ratio: z43.string().regex(/^(adaptive|\d{1,2}:\d{1,2})$/, { message: "ratio must look like '16:9' (or 'adaptive' where supported)" }).optional().describe("Aspect ratio such as '16:9', '9:16' or '1:1' (defaults to the model's default)."),
30941
- seed: z43.number().int().min(0).max(2147483647).optional().describe("Random seed for relatively stable output (defaults to a random seed upstream).")
31014
+ seed: z43.number().int().min(0).max(2147483647).optional().describe("Random seed for relatively stable output (defaults to a random seed upstream)."),
31015
+ // 媒体二批富输入位(2026-09-01;网关 TwpVideogenRequestSchema 同帽 1..2):
31016
+ // i2v 首帧(seedance 支持首帧+尾帧两张);受理域随模型(描述逐模型注明,
31017
+ // i2v 专用行缺席即拒、纯文生行在场即拒)。
31018
+ imageUrls: z43.array(z43.string().min(1)).min(1).max(2).optional().describe(
31019
+ 'First-frame image(s) for image-to-video generation (public http(s) URL or data:image/*;base64 URI). REQUIRED for models marked "image-to-video ONLY" in this description (generate or obtain an image first, e.g. via the ImageGen tool); rejected by text-to-video-only models.'
31020
+ )
30942
31021
  });
30943
31022
  function errorResult14(text, model, errorCode2) {
30944
31023
  const data = {
@@ -30958,7 +31037,7 @@ function hintOf2(code) {
30958
31037
  return " Video generation is not configured on this platform yet; tell the user instead of retrying.";
30959
31038
  }
30960
31039
  if (code === "model_not_authorized") {
30961
- return " Use a video model name that this app is authorized for.";
31040
+ return ` The requested model is not in the authorized video model set of this app. Do not silently retry with another model or without "model" — tell the user, show the authorized video models from this tool's description, and let the user choose.`;
30962
31041
  }
30963
31042
  if (code === "videogen_quota_exceeded") {
30964
31043
  return " The daily video-seconds quota for this account is exhausted; retry after the daily reset (UTC+8).";
@@ -30966,8 +31045,34 @@ function hintOf2(code) {
30966
31045
  if (code === "insufficient_balance") {
30967
31046
  return " The app account balance is insufficient; the app developer needs to top up.";
30968
31047
  }
31048
+ if (code === "upstream_error") {
31049
+ return " The video provider failed to execute the task. If imageUrls was passed, the provider may be unable to fetch that image host — retry with an image from a different image model or another public URL.";
31050
+ }
30969
31051
  return "";
30970
31052
  }
31053
+ function videoModelNote(m) {
31054
+ const label = m.displayName !== m.model ? `${m.model} (${m.displayName})` : m.model;
31055
+ const c = m.constraints;
31056
+ if (c === void 0) return label;
31057
+ const notes = [];
31058
+ const d = c.durations;
31059
+ notes.push(
31060
+ d.kind === "set" ? `duration ${d.values.join("|")}s ONLY (default ${d.defaultSec}s)` : `duration ${d.min}-${d.max}s (default ${d.defaultSec}s)`
31061
+ );
31062
+ if (c.imageInput === null) {
31063
+ notes.push("text-to-video only — rejects imageUrls");
31064
+ } else {
31065
+ const forms = c.imageInput.urlOk && c.imageInput.b64Ok ? "URL or base64 data URI" : c.imageInput.urlOk ? "URL only" : "base64 data URI only";
31066
+ notes.push(
31067
+ c.imageInput.required ? `image-to-video ONLY — first-frame image via imageUrls is REQUIRED (${forms})` : `optional first-frame image via imageUrls (${forms})`
31068
+ );
31069
+ }
31070
+ if (c.ratio === null) notes.push("no ratio");
31071
+ else if (c.ratio !== void 0) notes.push(`ratio ${c.ratio.join("|")}`);
31072
+ if (!c.seed) notes.push("no seed");
31073
+ if (!c.negativePrompt) notes.push("no negativePrompt");
31074
+ return `${label} [${notes.join("; ")}]`;
31075
+ }
30971
31076
  function authorizedModelsNote2(models) {
30972
31077
  if (models === void 0) {
30973
31078
  return ' Omit "model" to use the app default, or ask the app developer for authorized model names.';
@@ -30975,8 +31080,8 @@ function authorizedModelsNote2(models) {
30975
31080
  if (models.length === 0) {
30976
31081
  return " The platform has no video model configured for this app yet — tell the user instead of retrying or guessing model names.";
30977
31082
  }
30978
- const listed = models.map((m) => m.displayName !== m.model ? `${m.model} (${m.displayName})` : m.model).join(", ");
30979
- return ` Authorized video models (omit "model" to use the first as default): ${listed}.`;
31083
+ const listed = models.map((m) => `- ${videoModelNote(m)}`).join("\n");
31084
+ return ' Authorized video models — the first is the default when "model" is omitted; bracketed notes are hard per-model constraints enforced by the platform (violating them fails the call):\n' + listed + '\nIf the user names a model outside this list (including an image model asked to make videos), do not silently omit "model" or substitute another model — tell the user, show this list, and let them choose.';
30980
31085
  }
30981
31086
  function createVideoGenTool(options) {
30982
31087
  const base = options.baseUrl.replace(/\/+$/, "");
@@ -30984,11 +31089,15 @@ function createVideoGenTool(options) {
30984
31089
  const token = options.token;
30985
31090
  return {
30986
31091
  name: "VideoGen",
30987
- description: "Generates a short video from a text prompt via the tansr platform (ring-3 hosted capability; the platform calls the video provider and bills the app per second of generated video). Generation is a long-running task (often minutes). Returns a video URL that stays valid for roughly 24 hours — surface it to the user promptly. Requires the app to have the videoGen platform capability enabled." + authorizedModelsNote2(options.models),
30988
- shortDescription: "Generate a video from a prompt via the tansr platform (billed per second). Args: model?, prompt, negativePrompt?, duration?, ratio?, seed?.",
31092
+ description: "Generates a short video from a text prompt via the tansr platform (ring-3 hosted capability; the platform calls the video provider and bills the app per second of generated video). Generation is a long-running task (often minutes). This call waits for the result — client-side wait cap is ~11 minutes; do not abort or retry early. Returns a video URL that stays valid for roughly 24 hours — surface it to the user promptly. Requires the app to have the videoGen platform capability enabled." + authorizedModelsNote2(options.models),
31093
+ shortDescription: "Generate a video from a prompt via the tansr platform (billed per second). Args: model?, prompt, negativePrompt?, duration?, ratio?, seed?, imageUrls?.",
30989
31094
  inputSchema: VideoGenArgsSchema,
30990
31095
  isReadOnly: false,
30991
31096
  isConcurrencySafe: false,
31097
+ // 2026-09-01 定谳修:/t1/videogen 系服务端同步长等(600s 轮询预算),kernel
31098
+ // 120s 缺省档下分钟级任务结构性必超时且有扣无产——工具级声明盖过缺省档
31099
+ // (kernel 全局档恒不动;dispatching-tool-executor timeoutMs>0 即生效)。
31100
+ timeoutMs: options.timeoutMs ?? VIDEOGEN_TOOL_TIMEOUT_MS,
30992
31101
  async execute(args, ctx) {
30993
31102
  const modelRef = args.model ?? "(default)";
30994
31103
  if (ctx.signal.aborted) {
@@ -31000,7 +31109,8 @@ function createVideoGenTool(options) {
31000
31109
  ...args.negativePrompt !== void 0 ? { negativePrompt: args.negativePrompt } : {},
31001
31110
  ...args.duration !== void 0 ? { duration: args.duration } : {},
31002
31111
  ...args.ratio !== void 0 ? { ratio: args.ratio } : {},
31003
- ...args.seed !== void 0 ? { seed: args.seed } : {}
31112
+ ...args.seed !== void 0 ? { seed: args.seed } : {},
31113
+ ...args.imageUrls !== void 0 ? { imageUrls: args.imageUrls } : {}
31004
31114
  };
31005
31115
  let response;
31006
31116
  try {
@@ -31516,14 +31626,72 @@ function parseModel(raw) {
31516
31626
  contextWindow: typeof raw.contextWindow === "number" ? raw.contextWindow : null
31517
31627
  };
31518
31628
  }
31519
- function parseMediaModels(raw) {
31629
+ function parseMediaImageInput(raw, flagKey) {
31630
+ if (raw === null) return null;
31631
+ if (!isRecord8(raw)) return false;
31632
+ const flag = raw[flagKey];
31633
+ if (flagKey === "min" ? typeof flag !== "number" : typeof flag !== "boolean") return false;
31634
+ if (typeof raw.max !== "number" || typeof raw.urlOk !== "boolean" || typeof raw.b64Ok !== "boolean") return false;
31635
+ return { flag, max: raw.max, urlOk: raw.urlOk, b64Ok: raw.b64Ok };
31636
+ }
31637
+ function parseImageConstraints(raw) {
31638
+ if (!isRecord8(raw)) return void 0;
31639
+ if (typeof raw.size !== "boolean" || typeof raw.seed !== "boolean" || typeof raw.negativePrompt !== "boolean" || typeof raw.maxImages !== "number" || typeof raw.promptRequired !== "boolean") {
31640
+ return void 0;
31641
+ }
31642
+ const input = parseMediaImageInput(raw.imageInput, "min");
31643
+ if (input === false) return void 0;
31644
+ return {
31645
+ size: raw.size,
31646
+ seed: raw.seed,
31647
+ negativePrompt: raw.negativePrompt,
31648
+ maxImages: raw.maxImages,
31649
+ imageInput: input === null ? null : { min: input.flag, max: input.max, urlOk: input.urlOk, b64Ok: input.b64Ok },
31650
+ promptRequired: raw.promptRequired,
31651
+ ...raw.actionRequired === true ? { actionRequired: true } : {}
31652
+ };
31653
+ }
31654
+ function parseVideoConstraints(raw) {
31655
+ if (!isRecord8(raw)) return void 0;
31656
+ const d = raw.durations;
31657
+ let durations = null;
31658
+ if (isRecord8(d) && typeof d.defaultSec === "number") {
31659
+ if (d.kind === "set" && Array.isArray(d.values) && d.values.every((v) => typeof v === "number")) {
31660
+ durations = { kind: "set", values: [...d.values], defaultSec: d.defaultSec };
31661
+ } else if (d.kind === "range" && typeof d.min === "number" && typeof d.max === "number") {
31662
+ durations = { kind: "range", min: d.min, max: d.max, defaultSec: d.defaultSec };
31663
+ }
31664
+ }
31665
+ if (durations === null) return void 0;
31666
+ if (typeof raw.negativePrompt !== "boolean" || typeof raw.seed !== "boolean" || typeof raw.audioInput !== "boolean") {
31667
+ return void 0;
31668
+ }
31669
+ const input = parseMediaImageInput(raw.imageInput, "required");
31670
+ if (input === false) return void 0;
31671
+ let ratio;
31672
+ if (raw.ratio === void 0) ratio = void 0;
31673
+ else if (raw.ratio === null) ratio = null;
31674
+ else if (Array.isArray(raw.ratio) && raw.ratio.every((r) => typeof r === "string")) ratio = [...raw.ratio];
31675
+ else return void 0;
31676
+ return {
31677
+ durations,
31678
+ ...ratio !== void 0 ? { ratio } : {},
31679
+ negativePrompt: raw.negativePrompt,
31680
+ seed: raw.seed,
31681
+ imageInput: input === null ? null : { required: input.flag, max: input.max, urlOk: input.urlOk, b64Ok: input.b64Ok },
31682
+ audioInput: raw.audioInput
31683
+ };
31684
+ }
31685
+ function parseMediaModels(raw, parseConstraints) {
31520
31686
  if (!Array.isArray(raw)) return [];
31521
31687
  const out = [];
31522
31688
  for (const item of raw) {
31523
31689
  if (!isRecord8(item) || typeof item.model !== "string" || item.model === "") continue;
31690
+ const constraints = item.constraints === void 0 ? void 0 : parseConstraints(item.constraints);
31524
31691
  out.push({
31525
31692
  model: item.model,
31526
- displayName: typeof item.displayName === "string" && item.displayName !== "" ? item.displayName : item.model
31693
+ displayName: typeof item.displayName === "string" && item.displayName !== "" ? item.displayName : item.model,
31694
+ ...constraints !== void 0 ? { constraints } : {}
31527
31695
  });
31528
31696
  }
31529
31697
  return out;
@@ -31544,8 +31712,8 @@ function parseAppBundle(raw) {
31544
31712
  aliases,
31545
31713
  capabilities: parsedCaps.success ? parsedCaps.data : DEFAULT_APP_CAPABILITIES,
31546
31714
  platformModels: {
31547
- imageGen: parseMediaModels(mediaRaw.imageGen),
31548
- videoGen: parseMediaModels(mediaRaw.videoGen)
31715
+ imageGen: parseMediaModels(mediaRaw.imageGen, parseImageConstraints),
31716
+ videoGen: parseMediaModels(mediaRaw.videoGen, parseVideoConstraints)
31549
31717
  }
31550
31718
  };
31551
31719
  }
@@ -31891,7 +32059,7 @@ function toolCallIds(message) {
31891
32059
  function toolResultIds(message) {
31892
32060
  return message.blocks.flatMap((b) => b.t === "tool_result" ? [b.callId] : []);
31893
32061
  }
31894
- function repairHistoryPairing(messages) {
32062
+ function repairHistoryPairing2(messages) {
31895
32063
  const open4 = /* @__PURE__ */ new Set();
31896
32064
  let cleanEnd = 0;
31897
32065
  for (let i = 0; i < messages.length; i++) {
@@ -32250,7 +32418,7 @@ async function createSession(options = {}) {
32250
32418
  `createSession: session "${options.resume.sessionId}" was not found in the given store; list() the store or create a fresh session instead.`
32251
32419
  );
32252
32420
  }
32253
- initialMessages = repairHistoryPairing(record.messages).messages;
32421
+ initialMessages = repairHistoryPairing2(record.messages).messages;
32254
32422
  }
32255
32423
  const platformSessionId = tokenTier ? ulid() : void 0;
32256
32424
  let sessionRef = null;
@@ -33540,6 +33708,7 @@ export {
33540
33708
  EndUserIdSchema,
33541
33709
  HEADER_APP_TOKEN,
33542
33710
  IMAGEGEN_TOOL_MAX_N,
33711
+ IMAGEGEN_TOOL_TIMEOUT_MS,
33543
33712
  ImageGenArgsSchema,
33544
33713
  McpHost,
33545
33714
  OUTPUT_TAIL_MAX_CHARS,
@@ -33551,6 +33720,7 @@ export {
33551
33720
  TansrSdkError,
33552
33721
  UnavailableChannel,
33553
33722
  VIDEOGEN_TOOL_MAX_DURATION,
33723
+ VIDEOGEN_TOOL_TIMEOUT_MS,
33554
33724
  VideoGenArgsSchema,
33555
33725
  accumulateUsage,
33556
33726
  appBundleRegistryConfig,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tansr/sdk",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Tansr public TypeScript SDK: headless agent API (query / createSession / runAgent) + pure protocol type re-exports (public, MIT).",
5
5
  "license": "MIT",
6
6
  "type": "module",