For me at least, an AI "produces" when it makes meaningful decisions. Do if you found the data, understood it, chose how you wanted it presented, but got the AI to write the code that generated the actual graph, then the scope of AI decision making is relatively small - it's reasonable to say that you produced that graph (with AI assistance). But if you got the AI to find some data that supported your article and present it as a graph, then it's making pretty much all the decisions there - which data set to use, how to graph it, even which parts of the article to support with that data. That's an AI-produced graph, for me at least.
I mean, presumably at some level you are using the search API - it's just a programmatic interface into the same underlying database calls. I don't know if Kagi web search uses the public API directly or if they share an underlying internal API, but I imagine there's not a lot of difference on Kagi's end.
The big difference is that API usage can be scaled up way quicker than web page hits and scraping can be, which is an understandable concern if you're trying to price your service for human usage and not for bots hammering away as fast as they can. But judicious use of rate limits could help here - have a subscribers API tier that allows only a relatively low volume of calls and do standard API pricing for all requests beyond that.
That said, I'm sure there are complexities here that I'm missing that make this easier to say than to do.
I think the point is that it would be nice if people who are already paying for human-driven searches could also get an API key included in that plan.
Right now, API usage is only available using a PAYG credit system, even if you've already got a subscription. But giving subscription users an allotment of free credits that covers light API usage would be nice - I could plug it into my agent of choice for casual chats or exploration, while still having to buy credits for more extreme or production usage.
It would be nice indeed, but it's a bit like wanting to share a gym subscription when you're not using it. The economics would fall apart if everyone used 100% of their subscription, unless sharing was priced in from the beginning.
The city transport system where I live has a subscription pass you can buy that is normally tied to a single person. However, if you pay a little bit extra you make the ticket transferable, and even let someone else travel with you for free on weekends and in the evenings. Like you say, they've presumably priced in the extra usage there that comes from it being transferable, or from the extra travellers, but also put limits on how much leeway you have to abuse the system.
I'm imagining rate limits that would prevent the user from making many more API calls than they would have made searches anyway. If you want unlimited 24/7 searches, you can pay for the credits directly, but if you just want to partially replace your existing search habits with e.g. interactive agent sessions, then that would be fine.
A more specific example would be how Anthropic allow certain Claude subscriptions to get free API credits, with some restrictions on the age of the account and with the number of credits being limited.
I think there is a workable solution here, although I can imagine that figuring out the details (how many credits to offer, what sort of limits, how to price the whole thing, etc) is complicated enough that Kagi have decided it's not worth the effort for the small number of users for whom this feature would be useful. And generally I'm very satisfied with Kagi, so I'm not complaining here or trying to suggest that this is something that they should be expected to offer. It would just be nice!
What if the usage were shared between the two and a single API search used more of your quota than a UI search? There's no reason the economics can't line up.
e.g. if you expect the average user to use 50% of the search quota / month through the UI, but 100% through the API, then you make the quota shared between the two but double the effect of usage from the API.
That would work if the average user with Search + API used the same "amount" (Costs to Kagi) as the average account using Search only. If it nets out to a higher cost, Kagi is making less out of the same subscription amount.
Especially if the API induces demand.
(Don't shoot the messenger, just trying to explain why it makes sense that they're not doing this)
I think the only way to make it not harmful to their finances would be if they lowered the cap (even for human use) to where heavy users and API users alike ended up paying 'overages' constantly. Everybody who has studied consumer behavior generally finds that people hate overage charges to an irrational extent[1] so that would be a terrible move compared to just saying "API users, you've got to pay extra, sorry."
[1] Meaning, they are more satisfied with an 'unlimited' or just way-more-than-you'll-ever-need option, even when it costs them more when averaged over even a few months. I'm not saying this makes you an irrational person -- I have the same illogical feelings myself.
That's not really illogical, it's just because many companies use the fine print to fleece customers that are slightly above the limit. Think Ryanair. Or mobile roaming.
This is why unlimited or at least a service stop instead of overage is highly preferable. It's the reason I only use prepaid mobile plans too so they can never overcharge me (and it's cheaper than a contract too)
Firstly, the cost of fixing a bug once you know it exists is usually minimal compared to the cost of discovering that bug. This is the inverse of medicine, where the cost of testing (at least in terms of health outcomes for the patient) is typically minimal compared to the cost of treatment.
Secondly, if you have an asymptomatic illness, this does not typically make you more vulnerable (hence why it's asymptomatic). Like you say, you typically only die of one thing, so if you know the patient won't die of a particular diagnosis because something else is more likely to kill them, then it might not be worth making that diagnosis. But for software, you can be simultaneously vulnerable to lots of things at once, and any of these vulnerabilities can be the one to "kill" you. Some vulnerabilities may be easier to find and exploit (or do more damage) but in principle any active vulnerability can be exploited.
Thirdly, having multiple vulnerabilities makes software more vulnerable overall, because those vulnerabilities can potentially be chained together to create more serious exploits than each vulnerability would have represented on its own. To a certain extent this can be true in medicine as well, but generally it isn't.
Fourthly, we can't cure death (yet?) but we can cure all the vulnerabilities that we've found so far. There is no known upper bound on the lifespan of a piece of software, and we know that older code tends to have fewer bugs in that newer code, presumably because those bugs have been fixed over time. This is different from health issues, where a given condition may be chronic or terminal and therefore at a certain point there's nothing you can do to fix it.
Finally, ultimately in healthcare it's your body, and your decision was to what you do with it (assuming you can find a doctor willing to do what you want). If you have a condition and you want it cured, even if it is completely benign and will have no impact on your life whatsoever, then you can do that. (Again, assuming you have the resources and the condition is curable). But a software vulnerability does not affect you as the developer of the software, it instead affects your users/clients/customers. Therefore there are different dynamics in play. If I sell you a tool and I know it could be vulnerable, but I don't try and find out what those vulnerabilities are, then you're ultimately the one on the hook when all your data gets deleted or leaked.
> Firstly, the cost of fixing a bug once you know it exists is usually minimal compared to the cost of discovering that bug.
Boy, I wish!
> Like you say, you typically only die of one thing, so if you know the patient won't die of a particular diagnosis because something else is more likely to kill them, then it might not be worth making that diagnosis.
You can't know someone didn't die of X until after they died, that's the entire point of this dilemma.
It is generally easy to fix a bug that has already be found and can be reproduced (has been diagnosed, so to speak) than to find that bug in the first place. That's one of the reasons that LLM security scanning has become so important recently: it massively reduces the cost of finding those vulnerabilities.
As to your second point, you don't know exactly what a person will die of, but you can make statically sound estimates. You generally won't test unlikely potential causes of death (either because the chance of a positive result is too small, or because you know there are other, more serious conditions). But once a vulnerability is known, it is infinitely reproducible, which means the chance of the vulnerability being "fatal" (assuming the conditions exist for it to be exploited) is essentially 1.
The other flaw in the analogy is that in medicine, the patient chooses to do the tests on themselves. But in software security, there is an adversarial attacker as well as the "doctor" trying to defend the software. And in general, if the defender can find a vulnerability, they must assume that an attacker could already have found the same vulnerability (because the attacker and defender have largely the same tools and information at their disposal, especially in open source contexts), in which case, as discussed previously, that vulnerability also needs to be assumed to be fatal.
The word "generally" contains a lot of assumptions in that first sentence. I can think of a couple of scenarios where fixing a bug can absolutely spiral. There are even cases where the far better outcome is to leave a bug in place now that it is known.
But I'm not blaming the voter for not supporting me. I'm blaming the voter for supporting the person that they supported.
Sure, I might be selling poop in a bag, and maybe nobody wants that. I can't blame people for not buying things they don't want. But the guy next to me is selling the Handmaid's Tale But In Real Life, and people are queuing up round the block to buy it. Those people looked at all the options -including abstaining and not buying anything at all - and still made a decision. They have to take ownership of that decision.
From the perspective of the Democrats, sure, self-reflection is necessary to figure out what went wrong. They should go and do that. But from the perspective of someone voting for Trump, no, you don't get to use that excuse. You looked at an admittedly very limited field of options and voted for the guy who was backed by a group who had literally written a manifesto on overturning the US constitution, the guy who boasted about his ability to sexually assault women, the guy who had already had a full term and caused tremendous damage with it, the guy who had spent four years complaining about rigged elections and threatening to do something about it, the guy who supported an attempted insurrection and promised to pardon the people who were involved, etc etc etc.
Stop blaming other people here - if you voted for Trump, it was perfectly clear what you were getting, and you still made that decision. That's on you.
> But I'm not blaming the voter for not supporting me. I'm blaming the voter for supporting the person that they supported.
You're getting hung up. What the fuck good does any of that do? Tell me.
> Sure, I might be selling poop in a bag, and maybe nobody wants that. I can't blame people for not buying things they don't want. But the guy next to me is selling the Handmaid's Tale But In Real Life, and people are queuing up round the block to buy it. Those people looked at all the options -including abstaining and not buying anything at all - and still made a decision.
The point I was making with the poop-selling example is: you need to get outside your own head and your own biases. I don't think you're doing that. You're doubling down, making excuses for your side.
> They have to take ownership of that decision.
Sure, that would make you feel good, but it ain't going to happen. Quit tripping over it and move on.
If I were a Democrat or a part of the DNC, then sure, introspection would be very important. But I'm not — I'm not even American, I'm watching from the sidelines trying to figure out what on earth has gone wrong and how I prevent it happening again in my own country.
The answer to Trump cannot be "the Democrats needed to try harder", because if democracy relies on one side never slipping up while the other side can do whatever they like, then of course that system is going to collapse eventually. We have to look at the deeper causes. And one of the most fundamental causes here is that a lot of people in the US looked at a man who openly promised a multi-pronged attack on the constitutional basis of the United States and said "yes, that's the man for me". If your analysis of the 2024 election doesn't include that point, then it's a flawed analysis.
> - packages in workspaces can be used as dependencies without compilation (node's type stripping doesn't support this)
Node does support this! Although it may depend on exactly you link the packages within a workspace — I use `pnpm` and it Just Works™. Because NodeJS looks at the resolved symlink to decide whether a project is in `node_modules` or not, if the symlink resolves to a package in the workspace, then NodeJS will do type stripping as normal.
In fairness, the documentation is very unspecific about this, so I just had to try it out and see what happens, but it does work.
I think NodeJS also has coverage these days, although I could be wrong there.
That could well be the case, I think I switched our monorepo over to as-node-native-as-possible at some point this year, possible after April or so. But I don't have the codebase at hand unfortunately, so I can't be more exact.
I do wish some of this stuff would be documented better. I find Node's documentation to be some of the worst for never being able to answer the specific question I have when I'm reading it — IIRC I was also unsure whether the type stripping thing would work for a monorepo, and the closest confirmation I could find online was a comment in a PR somewhere that implied it ought to work, but nothing more specific.
If anyone is reading this and sees compatibility as their primary reason for staying with a Chromium browser: I have been using Firefox as my main browser for many years now, and I can count on one hand the number of times where I've been hit by compatibility issues.
The big one is anything to do with video calling — things often work but not as well, or you can voice call but not use video, or something like that. Most of the time the call works well enough, or I use a native app anyway, in which case this isn't a problem, but I suspect this is the thing people are most likely to run into in practice.
The other one is WebUSB, which is useful for certain tools that flash hardware (e.g. keyboards) from the browser. This is rarer, but I still have Chrome around so I can still use these tools. And mostly there's another option anyway, it's just that WebUSB makes things more convenient.
I have heard people complain about Cloudflare, but I've never noticed this. I suspect this is less to do with Chrome/Firefox, and more to do with privacy settings that Firefox makes more accessible. But again, I've never had an issue with Cloudflare myself, so I can't say much about this.
Other than that, I genuinely can't think of the last time I wanted to use a website but couldn't because of Firefox. And even in the above situations, it's rare that I actually run into issues, it's just something I'm aware of as a possible cause if something happens. Most of the time things work perfectly well.
Same but for Safari. I use it as my daily driver and rarely get issues related to unsupported APIs. Everything seems to work fine, the only issues I ever hit are related to the Apple VPN.
Accessibility certainly requires a content-first approach, I agree with you there. If you view each part of an application solely in terms of what it looks like to a sighted user, it's easy to miss the subtleties of what the underlying structure ought to be.
But when you start layering on the presentation, you're still generally binding that presentation layer tightly to the current content. If you, for example, were to restructure the links in the Zen Garden footer for some reason, most of the styles would break because they're bound to the current structure of the content. The separation you talk about only exists in one direction.
By comparison, when I talk about separation and decoupling in terms of code, I mean that there is a single, explicit, and tight API that acts as a clear boundary between two units. By explicit, I mean that I've designed the units specifically so that they expose this API - this is almost exactly the opposite of what I should be doing with content and presentation, as you point out! By tight, I mean that the API is as minimal as I can make it - two units interacting via an API need to understand nothing of each other except that API, and that API is as small as possible.
None of that is happening when it comes to the interaction between content and presentation. The content is not explicit - I'm actively trying to write the content for the design, which precludes making it an explicit API surface. Nor is the content tight - again, I want to build the content without worrying about how I will layer the design on top, and I don't want to limit myself to just a small surface area here.
So to me, it makes sense to see the content and presentation as being coupled together, even if that coupling ideally goes in one direction only. And if two systems are coupled together, it makes sense to do that explicitly by co-locating those systems. Therefore, I tend to prefer systems like Tailwind that let me apply the presentation layer directly in the content layer. (In practice, I mostly prefer other tools that still let me write real CSS syntax, but Tailwind is pretty damn convenient a lot of the time.)
As an aside, talking about accessibility, I'd forgotten how inaccessible some of the Zen Garden designs are with their addition of extra content in the presentation layer alone.
> For the first eval, I tried giving agents the zstd RFC (plus errata) and telling them to implement a complete zstd decoder (agents are stuck in a container without internet access). The tests were not given to agents. For something with the surface area of zstd, it's not really reasonable to expect that the tests cover every possible case. For example, even though zstd is a fairly well-tested piece of software, I once found a data corruption bug in zstd. The test suite isn't intended to find extreme corner cases that might be lurking for years and is instead intended to check various cases that can "easily" be derived from the RFC that should work.
So basically, the agents were given the zstd RFC, told to implement a decoder, and also told to use a particular testing strategy (or not, for the control runs).
The question "for which functions/modules/classes should I write tests?" and the question "how do I structure my functions/modules/classes?" are very closely related questions, which I think is what the other comment was getting at.
That follows largely from what you're saying though, so I think the two of you agree, you're just coming at the same thing from different perspectives. Like you say, you want to avoid/manage coupling tests to implementation details, and typically the best way to do that is to bundle a significant, testable chunk of code into a single module, define a clear public interface to that module, and then test that interface. The internals of that module are then free to change, but the test interface should stay the same.
But the corollary of that is that you can't just design your modules independently of your tests, you need to design them so that they are testable. Which is why the previous comment links testing to code architecture/design.
Regarding dependencies like that, the best situation is where you can either:
(a) design a module so that the dependency is injected with a clear interface (not just "here's an instance of libredis.rs" but "here's a series of callbacks for saving data, those callbacks might save to Redis, but they might be in-memory only, or they might save everything to the blockchain, either way it doesn't matter").
(b) just spin up an instance of Redis and test directly against that — it should be quick enough, and there's plenty of ways to ensure that the tests don't affect each other even while accessing a shared resource.
reply