今日已更新 84 条资讯 | 累计 37635 条内容
关于我们

标签:#pens

找到 2267 篇相关文章

AI 资讯

AgentStack MCP: one deterministic reasoning stack for AI agents (simulate + decide + compute)

The fourth in a suite of deterministic MCP servers for AI agents — and the one that ties the first three together. Over the last stretch I shipped three focused, deterministic MCP servers: ScenarioSim — what-if / scenario simulation DecisionMatrix — multi-criteria decision analysis PrecisionCalc — exact finance / business math They're great on their own, but agents kept needing all three in the same task — and installing three servers, juggling three keys, and hand-gluing their outputs is friction. So here's AgentStack MCP : one endpoint, one key, all three — plus composite tools that chain them. simulate → decide → compute { "mcpServers" : { "agentstack" : { "type" : "http" , "url" : "https://agentstack-mcp.pages.dev/mcp" } } } Free tier: no key, 20 calls/day. The tools are namespaced so an agent always knows which engine it's calling: sim_* — ScenarioSim (run, sensitivity, break-even, compare, templates) decide_* — DecisionMatrix (decide, score, sensitivity, compare_two, methods) calc_* — PrecisionCalc (metrics, currency, NPV, IRR, loan, depreciation, …) The part that's actually new: composite tools These chain the engines to do reasoning no single server can , deterministically end-to-end: evaluate_options_with_scenarios (simulate → decide) — project each option as its own scenario, then rank the outcomes against weighted criteria: { "name" : "evaluate_options_with_scenarios" , "arguments" : { "template" : "saas_growth" , "horizon" : 12 , "options" : [ { "name" : "Aggressive" , "inputs" : { "new_customers_per_period" : 60 , "churn_rate" : 0.05 } }, { "name" : "Lean" , "inputs" : { "new_customers_per_period" : 20 , "churn_rate" : 0.02 } } ], "criteria" : [ { "metric" : "ending_mrr" , "weight" : 3 , "direction" : "benefit" }, { "metric" : "total_churned_customers" , "weight" : 1 , "direction" : "cost" } ] } } plan_to_valuation (simulate → compute) — project a plan, then value its cash-flow line: NPV, IRR, undiscounted total. stress_test_decision (simulate × decide)

2026-08-11 原文 →
产品设计

Forms, payloads, and live inputs in Fitz LiveViews

TL;DR — Events in Fitz LiveViews carry data three ways: a click payload ( data-flv-value-* ) tags a button with the value it should send; a form submit ( data-flv-submit ) reads the form's named inputs; and a live value ( @input / @change ) delivers a control's current value in payload["value"] . All three land in the same place — a payload map your handler reads. This post builds a live name list (add / remove / count) that runs both server-rendered and as WebAssembly. (Part 3 of the FitzLiveViews series.) Parts 1 and 2 covered the pitch and the counter. A counter only reads +1 / -1 — no data flows in . Real UIs take input: text, selections, form fields. Here's how that data reaches your handlers. The payload Every event handler has a payload in scope — a Map<Str, Str> . The three mechanisms below all fill it; your handler reads it with payload["key"] (guard with payload.has("key") ): 1. Click payload — a button that carries a value Tag any element with data-flv-value-<key>="{expr}" , and when a data-flv-click on it (or an ancestor) fires, that value rides along: <button data-flv-click= "remove" data-flv-value-item= "{it}" > × </button> event remove () { if ( payload . has ( " item " )) { let target = payload [ " item " ] names = names . filter ( fn ( it ) => it != target ) } } The delete button knows which row it is because the row's value is stamped on it. No IDs threaded through a callback, no closure capture. 2. Form submit — the whole form at once data-flv-submit="handler" on a <form> reads each named input into the payload on submit; data-flv-clear resets a field afterward: <form data-flv-submit= "add" > <input name= "item" placeholder= "Add a name" data-flv-clear /> <button type= "submit" > Add </button> </form> event add () { if ( payload . has ( " item " )) { let n = payload [ " item " ] if ( n != "" ) { names . push ( n ) } } } payload["item"] is the input's value at submit time. No preventDefault , no FormData , no fetch . 3. Live value — @input / @chang

2026-08-11 原文 →
AI 资讯

Multi-Agent AI vs. Single AI Models: Which One Will Power the Enterprise?

Introduction: The Enterprise AI Architecture Question Enterprise AI is entering a new phase. The first wave was about putting large language models into applications. The second wave focused on Retrieval-Augmented Generation (RAG), enterprise search, copilots, and AI assistants. Now, enterprises are asking a more fundamental question: What should the architecture behind enterprise AI actually look like? Should one powerful AI system receive a business problem, access the required tools, reason through the workflow, and deliver the answer? Or should the work be divided among multiple specialized AI agents—each responsible for a specific function—with an orchestrator coordinating the entire process? This is the debate between single-agent AI and multi-agent AI. And the answer is more nuanced than “more agents are better.” A single agent can be remarkably effective when the workflow is focused, sequential, and supported by the right tools and context. Multi-agent architectures become attractive when work can be decomposed into independent streams, when specialized expertise is required, or when the scale of the problem exceeds what one agent can efficiently manage. Recent research on agent architectures highlights exactly these trade-offs: capability versus reliability, autonomy versus controllability, and accuracy versus latency and cost. The real enterprise question, therefore, is not: “How many AI agents should we deploy?” It is: “What architecture best matches the complexity of the business problem?” What Is a Single-Agent AI Architecture? A single-agent architecture typically consists of one AI agent powered by a foundation model, connected to enterprise data, tools, APIs, memory, and business systems. The agent receives a goal and determines how to accomplish it. A simplified architecture looks like: User Request → AI Agent → Reasoning → Tools/Data → Action → Result For example, imagine an employee asks: “Why did yesterday's sales decline in the western region?”

2026-08-11 原文 →
AI 资讯

Parallel Coding Agents Need Handoffs, Not More Terminals

The concrete problem Running two or three coding-agent sessions is easy. Knowing when their work is safe to combine is not. One session changes an API while another writes regression tests against the old shape. A third investigates a production failure and quietly edits the same configuration file. Git worktrees prevent immediate filesystem collisions, but they do not explain task dependencies, transfer assumptions, or warn that two agents are solving incompatible versions of the problem. The developer becomes a human message bus: checking terminals, copying commit IDs, repeating context, and deciding which session should wait. The more capable each agent becomes, the less useful a wall of terminal panes is as a coordination interface. The current signal Claude Code now supports messaging between sessions on the same machine. Its documentation describes session discovery, plain-text messages, and a local messaging socket. Agent view separately exposes background-session state, worktrees, pull-request status, and a JSON listing suitable for scripts. Hooks can observe tool input and block a tool call before execution. That does not prove demand for a new product. It does create a concrete implementation moment: the primitives for handoffs and visibility exist, while dependency ownership and conflict negotiation remain a workflow problem. In RayTally's bounded Hacker News snapshot at August 9, 00:33 UTC, the cross-session messaging discussion had 50 points and 26 comments and ranked 18th. Those numbers describe that historical observation only; they are not user counts, market validation, or a prediction of lasting interest. A product direction: a control desk for handoffs The useful product is not another chat window. It is a small local control desk that makes each session declare four things: its goal, worktree, files it expects to touch, and the result another session is waiting for. When the API session finishes, the testing session should receive a compact hando

2026-08-11 原文 →
AI 资讯

How We Built an IoT Platform That Handles 30 Million Concurrent Connections — With a Team of 10

How We Built an IoT Platform That Handles 30 Million Concurrent Connections — With a Team of 10 DGIOT is an open-source industrial IoT platform. We run 928 gateways across 16 oil fields, process 652 million data points, and maintain 99.9999% uptime. Here's the architecture that makes it possible. The Problem In 2021, we got a call from Daqing Oil Field — China's largest oil producer. They had a problem: 928 industrial gateways from different vendors 114,809 sensor points speaking 15 different protocols Data collection every 10 minutes (they needed seconds) 15-30 minute end-to-end latency (they needed <3 seconds) False alarm rate above 20% The existing system was a patchwork of vendor-specific tools, each with its own database, UI, and authentication. Operators had to log into 8 different systems just to check if a pump was overheating. They asked: "Can you unify this?" What We Built DGIOT is an Erlang/OTP-based platform that acts as a universal translator for industrial protocols. Think of it as a Rosetta Stone for machines. Modbus ─┐ OPC UA ─┤ MQTT ──┼──→ Unified Pipeline ──→ TDengine ──→ Dashboard IEC104 ─┤ A11 ──┘ The key insight: industrial protocols are just state machines . Once you model each protocol as a gen_statem FSM in Erlang, you can handle hundreds of them concurrently with almost zero overhead. The Architecture: DLAS We designed a four-layer architecture that separates concerns cleanly: Layer 1: DATA — Ingestion Parse Server (23 classes) handles device metadata, user auth, tenant isolation TDengine stores 652M time-series data points with 10:1 compression EMQX handles MQTT message routing at 1M+ msg/sec Mnesia/ETS provides in-memory caching for hot data Layer 2: LOGIC — Ontology Engine This is our secret weapon. We built a 252-entity OWL ontology that models industrial equipment: Pump ⊑ Equipment ⊓ ∃ hasPart.Bearing ⊓ ∃ measures.Pressure Bearing ⊑ Component ⊓ ∃ hasFailureMode.Overheat Overheat → triggers ( Alert ) ∧ reduces ( RemainingLife , 0.8 ) The

2026-08-11 原文 →
AI 资讯

What you save when project context stops repeating

Qarinah compiles a compact, cited project-memory pack instead of asking every new coding-agent session to replay the entire available history. The published estimate Across six committed software-task fixtures, the full-history baseline contained 442,113 portable estimated input-context tokens . The Qarinah path used 5,682 . Every required target was still directly covered in the top five results. That is: 436,431 fewer estimated input-context tokens; 98.71% less repeated context; and a 77.81:1 baseline-to-pack ratio. The ratio is not a claim that every provider bill drops by 98.71%, or that an agent session lasts 77.81 times longer. It measures the compared input-context volume in the published six-fixture estimate. What the same token rate would cost The table applies four flat, uncached input-token rates to the same two token estimates. It is arithmetic, not a provider invoice. Flat uncached input rate Full-history baseline Qarinah pack Estimated saving $1 / million tokens $0.442113 $0.005682 $0.436431 $3 / million tokens $1.326339 $0.017046 $1.309293 $5 / million tokens $2.210565 $0.028410 $2.182155 $15 / million tokens $6.631695 $0.085230 $6.546465 The calculation is: estimated tokens / 1,000,000 x flat input rate It deliberately excludes provider-native tokenization, caching, output tokens, reasoning tokens, tool calls, retrieval, hosting, and fixed fees. Real cost depends on the provider, model, cache behavior, context composition, and how often the same history would otherwise be resent. Why the pack remains useful Compression only matters if the next task can still find its evidence. The benchmark checks both volume and retrieval coverage: every required target had to be directly present in the top five. Qarinah preserves the source event ID and content hash for selected context, so a later agent receives a bounded handoff that can be inspected instead of an opaque story. Qarinah also passed 380 of 380 deterministic file-specific exact and typo-tolerant que

2026-08-11 原文 →
开发者

Download Multiple Files as a ZIP in React — Including Multi-GB Archives

A “Download all as ZIP” button in React starts simple. A production version also needs progress, cancellation, retry, useful errors, and a plan for archives that are too large for browser memory. In this tutorial, we’ll use Eazip , an open-source ZIP toolkit for JavaScript and React. Its React package gives you a hook for starting ZIP jobs and a ready-made tray for showing their status. Everyday files can be zipped entirely in the browser. When the same feature needs to handle multi-GB archives or thousands of remote URLs, it can move the job to Eazip Cloud without adding any backend code. Install the React package npm install @eazip/react @eazip/react requires React 18 or later. It includes the core ZIP engine, so you do not need to install another Eazip package. Build a working ZIP download component This component lets a user select several files and download them as one ZIP: import { useState } from ' react ' ; import { EazipTray , useEazip } from ' @eazip/react ' ; export function FileZipDownload () { const [ files , setFiles ] = useState < File [] > ([]); const zip = useEazip (); return ( < section > < label > Files to download < input type = "file" multiple onChange = { ( event ) => setFiles ( Array . from ( event . currentTarget . files ?? [])) } /> </ label > < button type = "button" disabled = { files . length === 0 || zip . isBusy } onClick = { () => zip . download ({ files , zipName : ' selected-files.zip ' , }) } > Download { files . length || '' } files as ZIP </ button > < EazipTray /> </ section > ); } There are three Eazip pieces in this example: useEazip() gives the component its download commands and current task. zip.download() starts the ZIP job and returns immediately. <EazipTray /> shows progress, cancel, retry, partial results, errors, and the completed download. No provider or CSS import is required. What happens to the selected files? Without a strategy option, Eazip uses its Local strategy. The selected File objects stay on the user’s devi

2026-08-11 原文 →
AI 资讯

Your terragrunt (or terraform) plan is 4,000 lines. Only two of them matter.

You know the ritual. terragrunt run --all -- plan Then you scroll. Past forty units of Refreshing state… . Past the ninth identical count instance. Past a tags_all.LastModified that changes on every single run because your CI stamps a timestamp into it. Somewhere in there are the two lines you actually needed to see — probably the # forces replacement on a database. You scroll back up. You lose it. You pipe it to a file and grep for must be replaced . You approve anyway, because it's 6pm. I got tired of that, so I wrote tgsieve . What it does It runs the plan for you, reads the structured output instead of the prose, throws away the noise you declared as noise, collapses everything that repeats, and prints what's left. DESTROY / REPLACE (1) envs/prod/a ± aws_db_instance.main engine_version "14.7" → "15.3" forces replacement UPDATE (5) 5 units envs/dev/a, envs/dev/b, envs/prod/a, +2 more ~ null_resource.pin triggers.region "eu-central-1" → "us-west-2" SUMMARY ±1 replace ~5 update severity: 1 high, 5 medium hid 214 attributes across 3 rules (--explain to see them) That's five units of a real terragrunt plan — the same run terraform prints as several hundred lines. The report nests three deep — where , then what , then which fields : UPDATE (5) envs/prod/c ← the unit, said once ~ aws_s3_bucket.this ← the resource tags_all.entity "tgb" → "tgc" ← the attributes that changed A change that's identical across units replaces the directory with the set it covers, so the first column always answers the same question: where . It doesn't scrape text This matters, because the obvious implementation is fragile garbage. You might reach for terragrunt run --all -- plan -json . It doesn't work: terragrunt forwards terraform's own NDJSON straight through, so lines from units running in parallel interleave with no way to tell them apart. So tgsieve asks terragrunt for machine-readable artifacts and reads those: What Flag it passes What it gets per-unit plans --json-out-dir one tfplan.j

2026-08-11 原文 →
AI 资讯

The bug report that never left the browser

This is a submission for DEV's Summer Bug Smash: Clear the Lineup powered by Sentry . There's a shape of bug I've learned to distrust: the one where the safety net is bolted to the thing it's supposed to catch. I was reading Element Web's reporting code looking for something worth fixing when I hit a function that builds the whole Sentry payload as a single object literal — with two await calls sitting inside it. One of them asks the crypto layer for diagnostics. Optional diagnostics. Nice-to-have detail on a report that is already complete without them. I stopped there, because I could already see how that sentence ends. If the optional thing rejects, the object never exists. If the object never exists, there is no capture call. And the same pattern was waiting one directory over, in the rageshake path. The subsystem being diagnosed could prevent the diagnostic report from leaving the browser. Somebody decides to tell you what broke, and the broken part gets a veto. One deliberate press of a button, both explicit channels gone: the rageshake bundle and the manual Sentry event. I measured it at the boundary that actually counts — a real Sentry Browser SDK with a local, network-free transport. Under the same synthetic failure: zero serialized events before the fix, exactly one after. Same synthetic crypto rejection Before After collectBugReport(): rejected report completed with available diagnostics Sentry envelopes: 0 Sentry events: 1 unrelated context families: retained auxiliary error message or stack: absent Project Overview Element Web is the web client behind Element, a Matrix-based communication app. Its bug-report dialog can send two independent things: a rageshake bundle — logs and diagnostics packed into multipart form data and posted to a configured endpoint — and, when Sentry is configured, a single manually captured Sentry event. Both are explicit. Nothing leaves the browser unless a person opens that dialog and submits it. That framing shaped every deci

2026-08-11 原文 →
AI 资讯

Starting a Linux Group in a Region Where None Existed

A few months ago I got properly bitten by the Linux bug. Ubuntu became my daily driver, I started digging into terminal tools way past the point of “practical necessity,” and I got obsessed with an idea that wouldn’t leave me alone: old hardware doesn’t have to die just because it’s old. I work as an on-site IT coordinator, handling day-to-day IT operations for an industrial company. Between that and years of general sysadmin work, I’ve watched a lot of perfectly usable machines get pulled out of service and shipped off as e-waste — not because they were broken, but because someone decided they were “too old” for whatever OS they were running. A Core 2 Duo with a fresh SSD and a lightweight distro can still be a genuinely useful computer.That gap between “technically obsolete” and “actually still works great” is where a lot of my curiosity lives right now. The gap I kept running into The more I looked into the Norwegian Linux scene, the more I found — Skolelinux/Debian Edu has deep roots here, NUUG (Norwegian Unix User Group) has been active for decades, and there’s a project called PC-Aid that collects, wipes, and reinstalls Debian Edu on used PCs, then sends them to schoolchildren in Ukraine. It’s been running for a few years now, quietly doing real, tangible good. I wanted in. But when I looked for any of this activity near me — Sunnmøre, a district on Norway’s west coast (in Møre og Romsdal county, home to the town of Ålesund) — there was nothing. No local NUUG chapter, no meetup, no group. Just… a gap. (If you’re not from Norway, don’t worry, most Norwegians would need a map for this too.) So instead of waiting for someone else to fill it, I started SLUG — Sunnmøre Linux User Group. Reaching out, awkwardly, like you do Starting a group is the easy part. Getting it to mean anything is harder. So I did the obvious thing: I found people who’d actually been part of PC-Aid and reached out. First was someone who’d been active in the project early on. I sent a message

2026-08-11 原文 →