后端前端协同办公即时通讯企业应用CRMAI Agent人工智能【免费下载链接】macroMacro is a unified workspace for teams: email, chat, docs, tasks, agents, calls, and CRM — -linked together with shared AI memory.项目地址https://gitcode.com/GitHub_Trending/macro3/macro点击查看免费下载在 Macro 的 Agent 会话体系中当一条 prompt 或 compact 在某个 turn 运行期间被提交时它不会立刻执行而是进入会话的服务端队列等待该 turn 结束。EditQueuedActionData正是描述在派发之前改写这条排队 prompt这一操作的请求类型别名——它把 HTTP 方法、路径模板、路径参数与请求体绑定在同一个类型里。本文以 SDK 类型文档为骨架结合agent_session路由层、agent_harness队列实现与 SDK 封装完整讲清这个类型每个字段的含义、服务端的真实行为边界以及可复制的调用方式。类型定义一个请求的完整形状类型文档给出的定义非常紧凑type EditQueuedActionData { body: EditQueuedActionRequest; path: { action_id: string; session_id: string }; query?: never; url: /agent-sessions/{session_id}/queue/{action_id}; }对应源文档EditQueuedActionData。这个形状是 orval 从 OpenAPI 规范生成的请求参数聚合类型它不是响应体也不是领域模型而是对一次 HTTP 调用的全部输入的静态描述。理解它的关键在于四个字段的职责划分。字段类型必填含义bodyEditQueuedActionRequest是请求体仅包含新的 prompt 文本path.action_idstring是该 action 被受理时获得的 IDpath.session_idstring是所属 agent session 的 IDquery?never否显式声明该接口没有查询参数never表示不可传任何 queryurl/agent-sessions/{session_id}/queue/{action_id}—路径模板两个占位符由path填充query?: never是一个值得注意的生成细节它不是可选参数为空而是类型层面禁止任何查询参数配合url字符串一起让调用方在编译期就锁死了请求形态。url字面量同时承担了这是 PUT 到资源地址的语义提示——虽然在类型里没有出现 HTTP 方法方法由 SDK 生成代码固定。两个路径参数在源文档中分别带有说明action_id是 ID the action was accepted under该 action 被受理时所用的 IDsession_id是 ID of the agent session。注意前者不是消息 ID也不是 turn ID只有当 action 真正派发后这个 ID 才会等价于折叠消息上的requestId——这一点在 SDK 的高层封装注释中有明确表述。请求体为什么不接受空白字符串EditQueuedActionData的body指向 EditQueuedActionRequest其定义为type EditQueuedActionRequest { /** The new raw prompt text, replacing the old wholesale. Never blank */ prompt: string; }前端生成的接口定义 editQueuedActionRequest.ts 进一步给出了约束export interface EditQueuedActionRequest { /** * The new raw prompt text, replacing the old wholesale. Never blank: a * prompt with nothing to say is a removal, and there is an endpoint for * that. * minLength 1 */ prompt: string; }三个语义要点整体替换replace wholesale不是追加、不是 diff 合并。传入的prompt会完整取代队列条目的原文本。不接受空白minLength 1只是第一道防线服务端还会对trim()之后的空串做二次判断直接拒绝。想清空就等于想删除文档注释直白地指出把 prompt 改成空内容在语义上是移除而移除有专门的接口DELETE同一路径对应 RemoveQueuedActionData。换而言之EditQueuedActionData只描述改写而不描述删除或插队。删除与插队分别由同一路径的DELETE和.../steer端点承担三者共享同一组路径参数。HTTP 契约方法、路径与状态码路由注册在 crates/agent_session/src/inbound/axum_router.rs.route( /{session_id}/queue, get(get_agent_session_queue_handler::R, Access, Auth), ) .route( /{session_id}/queue/{action_id}, put(edit_queued_action_handler::R, Access, Auth) .delete(remove_queued_action_handler::R, Access, Auth), ) .route( /{session_id}/queue/{action_id}/steer, post(steer_queued_action_handler::R, Access, Auth), )可以看到PUT /{session_id}/queue/{action_id}与DELETE共用同一个路径这正是 REST 语义下的修改与删除steer则在末尾多出一段子路径。OpenAPI 处理器 编辑接口定义 声明了响应集合落在类型层就是 EditQueuedActionResponses 与 EditQueuedActionErrors。编译期可见的错误集合为{ 401: string; 403: string; 404: string; 422: string; 500: string }。状态码来源错误触发条件204 No Content无编辑成功响应体为空401鉴权失败调用方未通过 Macro 授权校验403Forbidden无编辑权限或 Harness 调用方并非该会话的托管者或沙箱编码会话的非员工操作404QueuedControlNotFound该 action 已派发、已被移除或从未入队422EmptyQueuedPrompt/QueuedControlNotEditable新文本 trim 后为空或目标条目本身不携带文本如compact500其他领域/内部错误持久化失败等成功分支返回StatusCode::NO_CONTENT这解释了为什么类型是204: void——调用方拿不到更新后的对象只能依赖本地状态或重新拉取队列。一个值得记录的实现细节错误映射表把Archived映射为409 CONFLICT错误映射但409并未出现在EditQueuedActionErrors的生成结果中。从源码结构看这是生成类型与运行时行为之间的一处缝隙集成方在编写兜底分支时应当把未列举的 4xx/5xx 也纳入通用错误处理。服务端处理链路从 handler 到队列EditQueuedActionData的字段最终会在 handler 里被逐一对上。核心实现在 edit_queued_action_handlerpub async fn edit_queued_action_handlerR, Access, Auth( _access: AgentSessionAccessLevelExtractorEditAccessLevel, Access, Auth, State(state): StateAgentSessionControlStateR, Access, Auth, caller: MacroAuthorizationExtractorAuth, UserBotOrHarness, Path((session_id, action_id)): Path(Uuid, Uuid), Json(request): JsonEditQueuedActionRequest, ) - ResultStatusCode, AgentSessionApiError { let session_id AgentSessionId::new_from_uuid(session_id); ensure_harness_serves_session(caller.authorization, state.recipient.as_ref(), session_id) .await?; if request.prompt.trim().is_empty() { return Err(AgentSessionError::EmptyQueuedPrompt.into()); } ... }可以把这段代码与类型字段一一对应path.session_id、path.action_id→Path((session_id, action_id)): Path(Uuid, Uuid)。两个参数在类型层是string落到服务端被解析为Uuid因此非法 UUID 会在反序列化阶段就失败。body→Json(request): JsonEditQueuedActionRequest。query?: never→ handler 签名里根本没有Query...提取器协议层面无从携带查询参数。几个容易被忽略的守卫权限级别是编辑级AgentSessionAccessLevelExtractorEditAccessLevel, ...。读取队列只需要查看权限而改写需要编辑权限——能看不等于能改。Harness 只能操作自己服务的会话ensure_harness_serves_session 会比对recipient.session_harness(session_id)与调用方自身的harness_id。仅凭代表某个用户不足以驱动别人托管的会话。空白文本提前拒绝prompt.trim().is_empty()直接返回EmptyQueuedPrompt对应422。随后 handler 从授权信息里取出实际操作人并下发给接收方let actor caller.authorization.acting_user() .map(|user| user.macro_user_id.clone()); state.recipient.edit_queued_control( session_id, AgentActionId::from_uuid(action_id), request.prompt, actor, ).await?;注意actor是Option用户直连时是Some由 bot 代表无人操作时可能是None。这个字段会一路传到队列条目上并成为派发时被记录的操作人。端口层能力声明edit_queued_control在端口 trait 中的文档注释crates/agent_session/src/domain/ports.rs把行为边界写得很明确已派发 →QueuedControlNotFound不携带文本的排队动作 →QueuedControlNotEditableactor的判定与发送使用同一套门禁谁不能给会话发 prompt谁就不能改写它即将被喂进去的内容。这解释了为什么编辑接口复用EditAccessLevel编辑队列条目在权限模型上等价于发送 prompt而不是等价于修改一条历史消息。Harness 层命令化与持久化agent_harness侧把编辑包装成一条HarnessCommand::EditQueued命令crates/agent_harness/src/domain/service/lifecycle.rs确保同一会话的所有变更都在会话自己的命令通道上串行执行。真正的落地在 queue.rsHarnessCommand::EditQueued { action_id, prompt, actor } { queue_result( self.queues.edit_prompt(session_id, action_id, prompt, actor), session_id, )?; self.persist_or_rollback(session_id).await?; self.publish_queue(session_id).await; Ok(CommandOutcome::Completed) }三步走改内存 → 落盘失败则回滚重载→ 广播队列变更。persist_or_rollback的实现queue.rs在写库失败时会尝试reload_queue然后返回错误避免内存与持久层出现分叉publish_queue则发出AgentSessionQueueChanged事件让订阅端刷新队列快照。内存队列的编辑语义在 edit_prompt 中pub fn edit_prompt( self, session: AgentSessionId, action_id: AgentActionId, prompt: String, actor: OptionMacroUserIdStrstatic, ) - Result(), QueueError { let mut queue self.queues.get_mut(session).ok_or(QueueError::NotFound)?; let entry queue .iter_mut() .find(|entry| entry.action_id action_id) .ok_or(QueueError::NotFound)?; match mut entry.action { AgentAction::Prompt(action) { action.prompt prompt; entry.actor actor; Ok(()) } AgentAction::SetModel(_) | AgentAction::SetConfigOption(_) | AgentAction::Compact | AgentAction::Stop | AgentAction::RespondElicitation(_) | AgentAction::RespondToPermission(_) Err(QueueError::NotEditable), } }由此可以确认四条确定性行为原地更新条目保留位置与 ID文档注释原文为 The entry keeps its place and its id编辑不会改变它在队列中的顺序也不会生成新的action_id。只对prompt生效Compact、SetModel、SetConfigOption、Stop、权限回应、elicitation 回应全部返回NotEditable映射为422。这也解释了QueuedActionDto.kind的说明——只有占用 turn 的动作才会入队而其中只有prompt携带可改写文本。操作人被替换为编辑者entry.actor actor。注释写得很直接改写文本的人才是派发时被播报与记日志的人不能让别人替他背下他没写过的字。附件不受影响正文替换只作用于文本DTO 中attachments的注释明确写着 Kept through an edit, which replaces the text alone。门禁前置检查在命令真正执行前queue.rs 的分派前置检查还会做两件事HarnessCommand::Deliver(DeliverAction { actor, .. }) | HarnessCommand::EditQueued { actor, .. } | HarnessCommand::RemoveQueued { actor, .. } | HarnessCommand::SteerQueued { actor, .. } { let session self.sessions.get_session(session_id).await?; if session.is_archived { return Err(AgentSessionError::Archived(session_id).into()); } if AgentKind::of(session.bot_id) AgentKind::SandboxedCoder !actor.as_ref().is_some_and(is_macro_staff) { return Err(AgentSessionError::Forbidden.into()); } }即归档会话不可编辑沙箱编码类会话的队列改写仅限员工。注释解释了原因——被编辑的条目稍后会以原身份派发改写 Daytona 会话即将执行的内容与直接给它发 prompt 是同一级别的权限。另外队列本身有容量上限QUEUE_CAP 50queue.rs满队列返回ControlQueueFull同样映射为422。编辑已有条目不会增加条目数因此不触及该上限但在设计批量入队逻辑时应当把它考虑进去。SDK 调用从生成客户端到高层封装底层生成的editQueuedActionEditQueuedActionData直接对应生成 SDK 中的方法packages/sdk/generated/agent-harness/sdk.gen.tspublic editQueuedActionThrowOnError extends boolean false( options: OptionsEditQueuedActionData, ThrowOnError, ): RequestResultEditQueuedActionResponses, EditQueuedActionErrors, ThrowOnError { return (options.client ?? this.client).put EditQueuedActionResponses, EditQueuedActionErrors, ThrowOnError ({ url: /agent-sessions/{session_id}/queue/{action_id}, ...options, headers: { Content-Type: application/json, ...options.headers } }); }三点可从代码直接读出方法固定为put与url模板共同构成完整调用自动带上Content-Type: application/json返回类型把响应与错误集合都参数化配合ThrowOnError决定是抛异常还是把错误放进返回值。因为响应是204EditQueuedActionResponse的类型定义为EditQueuedActionResponses[keyof EditQueuedActionResponses]即voidEditQueuedActionError同理是错误集合的值联合类型。高层QueuedAction.edit()手写 path 参数容易出错SDK 提供了面向对象封装 queued-action.tsasync edit(prompt: string): Promisethis { unwrap( await this.client.agentHarness.editQueuedAction({ path: { session_id: this.sessionId, action_id: this.actionId }, body: { prompt }, }), ); this.dto { ...this.dto, prompt }; return this; }这段实现有两个设计点值得学习本地回填由于服务端返回204没有响应体可读封装直接把新prompt合入本地 DTO使action.prompt立即反映最新值。可链式返回this允许await action.edit(...).then(a a.steer())这类连续操作。QueuedAction的获取方式只有一种——从队列快照构造。类注释说明了原因没有单条 action 的GET只有队列列表接口因此它采用 wrap whatever DTO the caller already has 的模式与CrmComment包装列表记录同构而不是按 ID 懒加载。对应的高层入口是 AgentSession.queue()async queue(): PromiseQueuedAction[] { const { entries } unwrap( await this.client.agentHarness.getAgentSessionQueue({ path: { session_id: this.id }, }), ); return entries.map((entry) QueuedAction.from(this.client, this.id, entry)); }端到端示例排队、改写、插队与移除下面这段示例仅使用仓库中已确认存在的 SDK 入口展示一次完整的排队 → 编辑 → 插队 / 移除流程。它依赖MacroClient中挂载的agentHarness客户端与AgentSession实体。import type { MacroClient } from ./packages/sdk/src/utils/client; import type { AgentSession } from ./packages/sdk/src/entities/agent-sessions/agent-session; // session: 已加载的 AgentSession export async function editWhileRunning( client: MacroClient, session: AgentSession, ) { // 1. 在一个 turn 运行中提交会被排进服务端队列 const accepted await session.prompt(请把刚才的重构补上单元测试); // accepted.status 为 queued 时action_id 就是后续编辑所需的 id // 2. 读取队列快照包装成可操作句柄 const queued await session.queue(); // 3. 找到目标条目kind prompt 才可编辑 const target queued.find((a) a.actionId accepted.action_id); if (!target) return; // 已派发或已被移除 // 4. 整体替换文本附件保留位置与 id 不变 await target.edit(请把刚才的重构补上单元测试并覆盖空输入分支); // 5. 可选插队到队首并打断当前 turn或直接移除 // await target.steer(); // await target.remove(); }几个与类型定义强相关的注意点accepted.action_id来自控制接口的返回它是被受理时的 ID也是path.action_id的唯一正确来源不要用消息 ID 或本地生成的 UUID 替代。若target.kind compact编辑会稳定得到422 QueuedControlNotEditable应在客户端提前分支处理。若条目已经派发find会失败服务端也会返回404。这属于正常的竞态不应视为异常路径。与相邻操作的对比编辑、移除、插队同一路径族下的三个操作在类型与语义上形成互补关系操作类型别名方法/路径是否携带 body关键效果编辑EditQueuedActionDataPUT /agent-sessions/{session_id}/queue/{action_id}是{ prompt }原地替换文本保留位置与 ID移除RemoveQueuedActionDataDELETE同路径否body?: never派发前彻底删除插队SteerQueuedActionDataPOST .../{action_id}/steer否body?: never移到队首并在当前 turn 结束时优先派发三者的query都是neverpath结构完全一致只有body与url尾部不同。这种严格的对称性让代码生成与前端封装都能保持统一。steer的额外语义来自 端口文档与路由注释它会把条目前移并在有 turn 在飞时取消该 turn使这条动作在当前 turn 结束后立刻派发。相比之下edit绝不影响调度顺序——它只改字不排队。测试证据行为不是推测队列编辑的核心承诺在集成测试中被逐条钉死。crates/agent_harness/src/domain/service/test.rs 中的queued_prompts_are_editable_and_removable_until_dispatch覆盖了完整生命周期service.edit_queued_control( id, second.action_id, second, rewritten.to_owned(), Some(staff_sender()), ).await .expect(a waiting prompt is editable); assert_eq!( rewritten.actor.as_ref(), Some(staff_sender()), an edit is attributed to the editor, not the original queuer );断言the edit lands because dispatch is where the text is read进一步说明了一个重要机制文本是在派发时刻才被读取的所以排队期间的编辑一定生效不存在写进某个快照后再也改不动的问题。测试后半段验证了派发即消失let error service .remove_queued_control(id, second.action_id, Some(sender())) .await .expect_err(a dispatched prompt is not removable); assert!(matches!(error, AgentSessionError::QueuedControlNotFound));对已派发条目做移除或编辑都得到QueuedControlNotFound最终在 HTTP 层表现为404——这与EditQueuedActionErrors中的404说明 Already dispatched or never queued 完全对应。工程实践建议结合类型定义与服务端实现落地时可以遵循以下判断不要用编辑实现清空prompt.trim()为空会被拒为422正确做法是调用remove()。类型层已经通过注释把这条规则写进了文档。编辑前先确认kindcompact与各类控制动作不可编辑。用QueuedActionDto.kind或高层封装的kindgetter 做前置判断可以避免无意义的往返。404是常态而非故障turn 结束时队列会自然派发前端拿着旧快照做编辑必然可能撞上404。建议把它当作条目已达标的幂等信号刷新队列而不是弹错误。失败后重新同步服务端在持久化失败时会回滚内存并从存储重载此时客户端应当重新session.queue()获取权威快照而不是相信本地的乐观更新。权限口径按发送对待编辑使用EditAccessLevel并且对沙箱编码会话额外要求员工身份。为外部提供能力时不要给出比发送 prompt 更宽的授权。注意409未在类型中列举归档会话会触发409 CONFLICT但生成错误集合里没有它。兜底分支应覆盖未知 4xx/5xx。小结EditQueuedActionData看似只是一个自动生成的类型别名但它把三层事实压缩在四个字段里url与path锁定了对某个会话队列中某条动作的原地修改body明确了整体替换、不可为空、只管文本query?: never则宣告这个接口不接受任何过滤或开关参数。服务端链路进一步验证了这些语义——EditAccessLevel权限、Harness 托管校验、空白拒绝、只对prompt生效、操作人易主、附件保留、位置与 ID 不变、派发即失联404。相关阅读可从类型文档本身出发配合 EditQueuedActionRequest、QueuedActionDto 与 QueuedAction 类文档 形成完整认知再对照 axum_router.rs、queue.rs 与 queued-action.ts 查看每一层实现。赞分享后端前端协同办公即时通讯企业应用CRMAI Agent人工智能【免费下载链接】macroMacro is a unified workspace for teams: email, chat, docs, tasks, agents, calls, and CRM — -linked together with shared AI memory.项目地址https://gitcode.com/GitHub_Trending/macro3/macro点击查看免费下载相关推荐Macro Agent Harness SDK 类型解析GetSessionReviewResponse 与 Session Review 接口Macro Agent Harness SDK 类型解析GetSessionReviewResponse 与 Session Review 接口 本文围绕 M后端前端协同办公即时通讯企业应用CRMAI Agent人工智能Macro Agent Harness 队列编辑接口详解EditQueuedActionResponses 的 204 语义、契约与实现链路Macro Agent Harness 队列编辑接口详解EditQueuedActionResponses 的 204 语义、契约与实现链路 在 Macro后端前端协同办公即时通讯企业应用CRMAI Agent人工智能Macro Agent Harness SDK 类型解析GetAgentSessionQueueResponse 与会话动作队列 APIMacro Agent Harness SDK 类型解析GetAgentSessionQueueResponse 与会话动作队列 API GetAgentSe后端前端协同办公即时通讯企业应用CRMAI Agent人工智能上一篇WarcraftHelper终极指南三步解决魔兽争霸3所有兼容性问题下一篇城通网盘解析工具终极指南3步获取高速直连下载链接创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
我花了两周才肯承认:这款免费开源的Windows时间追踪工具,把摸鱼时间算得明明白白 我花了两周才肯承认:这款免费开源的Windows时间追踪工具,把摸鱼时间算得明明白白 【免费下载链接】Tai 👻 在Windows上统计软件使用时长和网站浏览时长 项目地址: https://gitcode.com/GitHub_Trending/ta/Tai
上周三下午我盯着屏幕发… · 2026/11/1 1:37:17
不装数据库,三条命令跑起网站:Grav CMS从克隆到上线完整指南 不装数据库,三条命令跑起网站:Grav CMS从克隆到上线完整指南 【免费下载链接】grav Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS powered by PHP, Markdown, Twig, and Symfony 项目地址: https://gitcode.com/gh_mi… · 2026/11/1 1:36:17
HTML学习总结 created: 2026-06-13 tags: [html, css, 总结]
HTML 学习总结(从零到能面试)
一、基础概念
HTML 是什么?
全称 HyperText Markup Language(超文本标记语言)不是编程语言,是标记语言——给内容贴标签三个… · 2026/11/3 0:18:12
Linux网络套接字编程基础与实战 1. Linux网络套接字基础概念网络套接字(Socket)是Linux系统网络编程的核心概念,它本质上是一个通信端点,就像我们日常生活中使用的电话插座一样。在Linux系统中,套接字用一个整数来标识,这个整数称为套接字描述符,类似… · 2026/11/3 13:38:30
14个免费AI通道聚合网关:自动路由与健康检查实战 1. 为什么要把 14 个免费通道塞进一个入口 第一次看到"14 个免费通道并成 1 个入口"这个说法,我脑子里蹦出来的不是"哇好厉害",而是"这不是自找麻烦吗"。免费模型这东西,单拎出来哪个都能用,为什么… · 2026/11/3 13:38:30
Buzz工具:轻量级HTTP压测实战指南 我无法根据当前输入生成符合要求的博文。原因在于:您提供的输入内容中,项目标题仅为“buzz”,且后续所有字段(项目正文、关键词、摘要描述)均为空或未提供有效信息。同时,“相关热搜词”与“最新网络热词”… · 2026/11/3 13:38:30
ISTQB-CT-AI大纲:AI测试工程师的标准化质量保障指南 简介:本资源是ISTQB官方发布的《认证测试工程师—人工智能测试大纲》(CT-AI-1.0-CN-1.0)中文版PDF文档,面向AI测试工程师、质量保障人员及希望系统掌握AI系统验证方法的专业人士,解决当前AI模型可解释性弱、质量特征难… · 2026/11/3 13:38:30
AI-Infra-Guard实战:AI基础设施技能扫描与Docker部署避坑指南 AI-Infra-Guard 这名字最初给我的感觉,是那种“包装得很唬人,实际不痛不痒”的监控工具——AI 基础设施守护,听上去像是大厂内部平台才会有的东西。但真正部署完、跑完一轮技能扫描之后,我得承认它确实解决了一个很现实的问题&… · 2026/11/3 13:38:30
团体标准制定全流程解析与参编实践指南 1. 团体标准的基本概念与价值 在标准化工作领域,团体标准(Group Standard)是指由社会团体按照自行规定的标准制定程序制定并发布,供团体成员或社会自愿采用的标准。与国家标准、行业标准等政府主导的标准体系相比,团体… · 2026/11/3 13:37:28
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46