@anthropic-ai/sdk 0.119.0 → 0.121.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/helpers/beta/environments.d.mts +5 -4
- package/helpers/beta/environments.d.mts.map +1 -1
- package/helpers/beta/environments.d.ts +5 -4
- package/helpers/beta/environments.d.ts.map +1 -1
- package/helpers/beta/environments.js +5 -4
- package/helpers/beta/environments.js.map +1 -1
- package/helpers/beta/environments.mjs +5 -4
- package/helpers/beta/environments.mjs.map +1 -1
- package/helpers/beta/standard-schema.d.mts +45 -0
- package/helpers/beta/standard-schema.d.mts.map +1 -0
- package/helpers/beta/standard-schema.d.ts +45 -0
- package/helpers/beta/standard-schema.d.ts.map +1 -0
- package/helpers/beta/standard-schema.js +58 -0
- package/helpers/beta/standard-schema.js.map +1 -0
- package/helpers/beta/standard-schema.mjs +54 -0
- package/helpers/beta/standard-schema.mjs.map +1 -0
- package/internal/detect-platform.js +1 -1
- package/internal/detect-platform.js.map +1 -1
- package/internal/detect-platform.mjs +1 -1
- package/internal/detect-platform.mjs.map +1 -1
- package/internal/file-store.d.mts +136 -0
- package/internal/file-store.d.mts.map +1 -0
- package/internal/file-store.d.ts +136 -0
- package/internal/file-store.d.ts.map +1 -0
- package/internal/file-store.js +531 -0
- package/internal/file-store.js.map +1 -0
- package/internal/file-store.mjs +523 -0
- package/internal/file-store.mjs.map +1 -0
- package/internal/utils/values.d.mts +6 -0
- package/internal/utils/values.d.mts.map +1 -1
- package/internal/utils/values.d.ts +6 -0
- package/internal/utils/values.d.ts.map +1 -1
- package/internal/utils/values.js +7 -0
- package/internal/utils/values.js.map +1 -1
- package/internal/utils/values.mjs +6 -0
- package/internal/utils/values.mjs.map +1 -1
- package/lib/BetaMessageStream.d.mts.map +1 -1
- package/lib/BetaMessageStream.d.ts.map +1 -1
- package/lib/BetaMessageStream.js +3 -4
- package/lib/BetaMessageStream.js.map +1 -1
- package/lib/BetaMessageStream.mjs +1 -2
- package/lib/BetaMessageStream.mjs.map +1 -1
- package/lib/MessageStream.d.mts.map +1 -1
- package/lib/MessageStream.d.ts.map +1 -1
- package/lib/MessageStream.js +3 -4
- package/lib/MessageStream.js.map +1 -1
- package/lib/MessageStream.mjs +1 -2
- package/lib/MessageStream.mjs.map +1 -1
- package/lib/environments/poller.d.mts +6 -0
- package/lib/environments/poller.d.mts.map +1 -1
- package/lib/environments/poller.d.ts +6 -0
- package/lib/environments/poller.d.ts.map +1 -1
- package/lib/environments/poller.js +46 -1
- package/lib/environments/poller.js.map +1 -1
- package/lib/environments/poller.mjs +46 -1
- package/lib/environments/poller.mjs.map +1 -1
- package/lib/environments/worker.d.mts +89 -12
- package/lib/environments/worker.d.mts.map +1 -1
- package/lib/environments/worker.d.ts +89 -12
- package/lib/environments/worker.d.ts.map +1 -1
- package/lib/environments/worker.js +336 -67
- package/lib/environments/worker.js.map +1 -1
- package/lib/environments/worker.mjs +336 -68
- package/lib/environments/worker.mjs.map +1 -1
- package/lib/sessions/accumulate.d.mts.map +1 -1
- package/lib/sessions/accumulate.d.ts.map +1 -1
- package/lib/sessions/accumulate.js +3 -4
- package/lib/sessions/accumulate.js.map +1 -1
- package/lib/sessions/accumulate.mjs +1 -2
- package/lib/sessions/accumulate.mjs.map +1 -1
- package/lib/standard-schema.d.mts +131 -0
- package/lib/standard-schema.d.mts.map +1 -0
- package/lib/standard-schema.d.ts +131 -0
- package/lib/standard-schema.d.ts.map +1 -0
- package/lib/standard-schema.js +45 -0
- package/lib/standard-schema.js.map +1 -0
- package/lib/standard-schema.mjs +41 -0
- package/lib/standard-schema.mjs.map +1 -0
- package/lib/tools/BetaToolRunner.d.mts.map +1 -1
- package/lib/tools/BetaToolRunner.d.ts.map +1 -1
- package/lib/tools/BetaToolRunner.js +35 -6
- package/lib/tools/BetaToolRunner.js.map +1 -1
- package/lib/tools/BetaToolRunner.mjs +35 -6
- package/lib/tools/BetaToolRunner.mjs.map +1 -1
- package/package.json +2 -11
- package/resources/beta/agents/agents.d.mts +322 -27
- package/resources/beta/agents/agents.d.mts.map +1 -1
- package/resources/beta/agents/agents.d.ts +322 -27
- package/resources/beta/agents/agents.d.ts.map +1 -1
- package/resources/beta/agents/agents.js.map +1 -1
- package/resources/beta/agents/agents.mjs.map +1 -1
- package/resources/beta/agents/index.d.mts +1 -1
- package/resources/beta/agents/index.d.mts.map +1 -1
- package/resources/beta/agents/index.d.ts +1 -1
- package/resources/beta/agents/index.d.ts.map +1 -1
- package/resources/beta/agents/index.js.map +1 -1
- package/resources/beta/agents/index.mjs.map +1 -1
- package/resources/beta/beta.d.mts +7 -3
- package/resources/beta/beta.d.mts.map +1 -1
- package/resources/beta/beta.d.ts +7 -3
- package/resources/beta/beta.d.ts.map +1 -1
- package/resources/beta/beta.js +4 -0
- package/resources/beta/beta.js.map +1 -1
- package/resources/beta/beta.mjs +4 -0
- package/resources/beta/beta.mjs.map +1 -1
- package/resources/beta/environments/environments.d.mts +8 -1
- package/resources/beta/environments/environments.d.mts.map +1 -1
- package/resources/beta/environments/environments.d.ts +8 -1
- package/resources/beta/environments/environments.d.ts.map +1 -1
- package/resources/beta/environments/environments.js.map +1 -1
- package/resources/beta/environments/environments.mjs.map +1 -1
- package/resources/beta/environments/work.d.mts +5 -1
- package/resources/beta/environments/work.d.mts.map +1 -1
- package/resources/beta/environments/work.d.ts +5 -1
- package/resources/beta/environments/work.d.ts.map +1 -1
- package/resources/beta/environments/work.js +0 -17
- package/resources/beta/environments/work.js.map +1 -1
- package/resources/beta/environments/work.mjs +0 -17
- package/resources/beta/environments/work.mjs.map +1 -1
- package/resources/beta/index.d.mts +2 -1
- package/resources/beta/index.d.mts.map +1 -1
- package/resources/beta/index.d.ts +2 -1
- package/resources/beta/index.d.ts.map +1 -1
- package/resources/beta/index.js +11 -9
- package/resources/beta/index.js.map +1 -1
- package/resources/beta/index.mjs +1 -0
- package/resources/beta/index.mjs.map +1 -1
- package/resources/beta/memory-stores/memories.d.mts +6 -5
- package/resources/beta/memory-stores/memories.d.mts.map +1 -1
- package/resources/beta/memory-stores/memories.d.ts +6 -5
- package/resources/beta/memory-stores/memories.d.ts.map +1 -1
- package/resources/beta/memory-stores/memory-versions.d.mts +8 -5
- package/resources/beta/memory-stores/memory-versions.d.mts.map +1 -1
- package/resources/beta/memory-stores/memory-versions.d.ts +8 -5
- package/resources/beta/memory-stores/memory-versions.d.ts.map +1 -1
- package/resources/beta/messages/messages.d.mts +51 -9
- package/resources/beta/messages/messages.d.mts.map +1 -1
- package/resources/beta/messages/messages.d.ts +51 -9
- package/resources/beta/messages/messages.d.ts.map +1 -1
- package/resources/beta/messages/messages.js.map +1 -1
- package/resources/beta/messages/messages.mjs.map +1 -1
- package/resources/beta/organization/api-keys.d.mts +177 -0
- package/resources/beta/organization/api-keys.d.mts.map +1 -0
- package/resources/beta/organization/api-keys.d.ts +177 -0
- package/resources/beta/organization/api-keys.d.ts.map +1 -0
- package/resources/beta/organization/api-keys.js +56 -0
- package/resources/beta/organization/api-keys.js.map +1 -0
- package/resources/beta/organization/api-keys.mjs +52 -0
- package/resources/beta/organization/api-keys.mjs.map +1 -0
- package/resources/beta/organization/external-keys.d.mts +269 -0
- package/resources/beta/organization/external-keys.d.mts.map +1 -0
- package/resources/beta/organization/external-keys.d.ts +269 -0
- package/resources/beta/organization/external-keys.d.ts.map +1 -0
- package/resources/beta/organization/external-keys.js +119 -0
- package/resources/beta/organization/external-keys.js.map +1 -0
- package/resources/beta/organization/external-keys.mjs +115 -0
- package/resources/beta/organization/external-keys.mjs.map +1 -0
- package/resources/beta/organization/federation/federation.d.mts +14 -0
- package/resources/beta/organization/federation/federation.d.mts.map +1 -0
- package/resources/beta/organization/federation/federation.d.ts +14 -0
- package/resources/beta/organization/federation/federation.d.ts.map +1 -0
- package/resources/beta/organization/federation/federation.js +21 -0
- package/resources/beta/organization/federation/federation.js.map +1 -0
- package/resources/beta/organization/federation/federation.mjs +16 -0
- package/resources/beta/organization/federation/federation.mjs.map +1 -0
- package/resources/beta/organization/federation/index.d.mts +4 -0
- package/resources/beta/organization/federation/index.d.mts.map +1 -0
- package/resources/beta/organization/federation/index.d.ts +4 -0
- package/resources/beta/organization/federation/index.d.ts.map +1 -0
- package/resources/beta/organization/federation/index.js +11 -0
- package/resources/beta/organization/federation/index.js.map +1 -0
- package/resources/beta/organization/federation/index.mjs +5 -0
- package/resources/beta/organization/federation/index.mjs.map +1 -0
- package/resources/beta/organization/federation/issuers.d.mts +353 -0
- package/resources/beta/organization/federation/issuers.d.mts.map +1 -0
- package/resources/beta/organization/federation/issuers.d.ts +353 -0
- package/resources/beta/organization/federation/issuers.d.ts.map +1 -0
- package/resources/beta/organization/federation/issuers.js +169 -0
- package/resources/beta/organization/federation/issuers.js.map +1 -0
- package/resources/beta/organization/federation/issuers.mjs +165 -0
- package/resources/beta/organization/federation/issuers.mjs.map +1 -0
- package/resources/beta/organization/federation/rules/index.d.mts +3 -0
- package/resources/beta/organization/federation/rules/index.d.mts.map +1 -0
- package/resources/beta/organization/federation/rules/index.d.ts +3 -0
- package/resources/beta/organization/federation/rules/index.d.ts.map +1 -0
- package/resources/beta/organization/federation/rules/index.js +9 -0
- package/resources/beta/organization/federation/rules/index.js.map +1 -0
- package/resources/beta/organization/federation/rules/index.mjs +4 -0
- package/resources/beta/organization/federation/rules/index.mjs.map +1 -0
- package/resources/beta/organization/federation/rules/rules.d.mts +468 -0
- package/resources/beta/organization/federation/rules/rules.d.mts.map +1 -0
- package/resources/beta/organization/federation/rules/rules.d.ts +468 -0
- package/resources/beta/organization/federation/rules/rules.d.ts.map +1 -0
- package/resources/beta/organization/federation/rules/rules.js +198 -0
- package/resources/beta/organization/federation/rules/rules.js.map +1 -0
- package/resources/beta/organization/federation/rules/rules.mjs +193 -0
- package/resources/beta/organization/federation/rules/rules.mjs.map +1 -0
- package/resources/beta/organization/federation/rules/workspaces.d.mts +124 -0
- package/resources/beta/organization/federation/rules/workspaces.d.mts.map +1 -0
- package/resources/beta/organization/federation/rules/workspaces.d.ts +124 -0
- package/resources/beta/organization/federation/rules/workspaces.d.ts.map +1 -0
- package/resources/beta/organization/federation/rules/workspaces.js +114 -0
- package/resources/beta/organization/federation/rules/workspaces.js.map +1 -0
- package/resources/beta/organization/federation/rules/workspaces.mjs +110 -0
- package/resources/beta/organization/federation/rules/workspaces.mjs.map +1 -0
- package/resources/beta/organization/federation/rules.d.mts +2 -0
- package/resources/beta/organization/federation/rules.d.mts.map +1 -0
- package/resources/beta/organization/federation/rules.d.ts +2 -0
- package/resources/beta/organization/federation/rules.d.ts.map +1 -0
- package/resources/beta/organization/federation/rules.js +6 -0
- package/resources/beta/organization/federation/rules.js.map +1 -0
- package/resources/beta/organization/federation/rules.mjs +3 -0
- package/resources/beta/organization/federation/rules.mjs.map +1 -0
- package/resources/beta/organization/federation.d.mts +2 -0
- package/resources/beta/organization/federation.d.mts.map +1 -0
- package/resources/beta/organization/federation.d.ts +2 -0
- package/resources/beta/organization/federation.d.ts.map +1 -0
- package/resources/beta/organization/federation.js +6 -0
- package/resources/beta/organization/federation.js.map +1 -0
- package/resources/beta/organization/federation.mjs +3 -0
- package/resources/beta/organization/federation.mjs.map +1 -0
- package/resources/beta/organization/index.d.mts +10 -0
- package/resources/beta/organization/index.d.mts.map +1 -0
- package/resources/beta/organization/index.d.ts +10 -0
- package/resources/beta/organization/index.d.ts.map +1 -0
- package/resources/beta/organization/index.js +23 -0
- package/resources/beta/organization/index.js.map +1 -0
- package/resources/beta/organization/index.mjs +11 -0
- package/resources/beta/organization/index.mjs.map +1 -0
- package/resources/beta/organization/invites.d.mts +162 -0
- package/resources/beta/organization/invites.d.mts.map +1 -0
- package/resources/beta/organization/invites.d.ts +162 -0
- package/resources/beta/organization/invites.d.ts.map +1 -0
- package/resources/beta/organization/invites.js +76 -0
- package/resources/beta/organization/invites.js.map +1 -0
- package/resources/beta/organization/invites.mjs +72 -0
- package/resources/beta/organization/invites.mjs.map +1 -0
- package/resources/beta/organization/organization.d.mts +69 -0
- package/resources/beta/organization/organization.d.mts.map +1 -0
- package/resources/beta/organization/organization.d.ts +69 -0
- package/resources/beta/organization/organization.d.ts.map +1 -0
- package/resources/beta/organization/organization.js +58 -0
- package/resources/beta/organization/organization.js.map +1 -0
- package/resources/beta/organization/organization.mjs +53 -0
- package/resources/beta/organization/organization.mjs.map +1 -0
- package/resources/beta/organization/rate-limits.d.mts +78 -0
- package/resources/beta/organization/rate-limits.d.mts.map +1 -0
- package/resources/beta/organization/rate-limits.d.ts +78 -0
- package/resources/beta/organization/rate-limits.d.ts.map +1 -0
- package/resources/beta/organization/rate-limits.js +32 -0
- package/resources/beta/organization/rate-limits.js.map +1 -0
- package/resources/beta/organization/rate-limits.mjs +28 -0
- package/resources/beta/organization/rate-limits.mjs.map +1 -0
- package/resources/beta/organization/service-accounts/index.d.mts +3 -0
- package/resources/beta/organization/service-accounts/index.d.mts.map +1 -0
- package/resources/beta/organization/service-accounts/index.d.ts +3 -0
- package/resources/beta/organization/service-accounts/index.d.ts.map +1 -0
- package/resources/beta/organization/service-accounts/index.js +9 -0
- package/resources/beta/organization/service-accounts/index.js.map +1 -0
- package/resources/beta/organization/service-accounts/index.mjs +4 -0
- package/resources/beta/organization/service-accounts/index.mjs.map +1 -0
- package/resources/beta/organization/service-accounts/service-accounts.d.mts +258 -0
- package/resources/beta/organization/service-accounts/service-accounts.d.mts.map +1 -0
- package/resources/beta/organization/service-accounts/service-accounts.d.ts +258 -0
- package/resources/beta/organization/service-accounts/service-accounts.d.ts.map +1 -0
- package/resources/beta/organization/service-accounts/service-accounts.js +174 -0
- package/resources/beta/organization/service-accounts/service-accounts.js.map +1 -0
- package/resources/beta/organization/service-accounts/service-accounts.mjs +169 -0
- package/resources/beta/organization/service-accounts/service-accounts.mjs.map +1 -0
- package/resources/beta/organization/service-accounts/workspaces.d.mts +141 -0
- package/resources/beta/organization/service-accounts/workspaces.d.mts.map +1 -0
- package/resources/beta/organization/service-accounts/workspaces.d.ts +141 -0
- package/resources/beta/organization/service-accounts/workspaces.d.ts.map +1 -0
- package/resources/beta/organization/service-accounts/workspaces.js +125 -0
- package/resources/beta/organization/service-accounts/workspaces.js.map +1 -0
- package/resources/beta/organization/service-accounts/workspaces.mjs +121 -0
- package/resources/beta/organization/service-accounts/workspaces.mjs.map +1 -0
- package/resources/beta/organization/service-accounts.d.mts +2 -0
- package/resources/beta/organization/service-accounts.d.mts.map +1 -0
- package/resources/beta/organization/service-accounts.d.ts +2 -0
- package/resources/beta/organization/service-accounts.d.ts.map +1 -0
- package/resources/beta/organization/service-accounts.js +6 -0
- package/resources/beta/organization/service-accounts.js.map +1 -0
- package/resources/beta/organization/service-accounts.mjs +3 -0
- package/resources/beta/organization/service-accounts.mjs.map +1 -0
- package/resources/beta/organization/users.d.mts +124 -0
- package/resources/beta/organization/users.d.mts.map +1 -0
- package/resources/beta/organization/users.d.ts +124 -0
- package/resources/beta/organization/users.d.ts.map +1 -0
- package/resources/beta/organization/users.js +67 -0
- package/resources/beta/organization/users.js.map +1 -0
- package/resources/beta/organization/users.mjs +63 -0
- package/resources/beta/organization/users.mjs.map +1 -0
- package/resources/beta/organization/workspaces/index.d.mts +5 -0
- package/resources/beta/organization/workspaces/index.d.mts.map +1 -0
- package/resources/beta/organization/workspaces/index.d.ts +5 -0
- package/resources/beta/organization/workspaces/index.d.ts.map +1 -0
- package/resources/beta/organization/workspaces/index.js +13 -0
- package/resources/beta/organization/workspaces/index.js.map +1 -0
- package/resources/beta/organization/workspaces/index.mjs +6 -0
- package/resources/beta/organization/workspaces/index.mjs.map +1 -0
- package/resources/beta/organization/workspaces/members.d.mts +135 -0
- package/resources/beta/organization/workspaces/members.d.mts.map +1 -0
- package/resources/beta/organization/workspaces/members.d.ts +135 -0
- package/resources/beta/organization/workspaces/members.d.ts.map +1 -0
- package/resources/beta/organization/workspaces/members.js +102 -0
- package/resources/beta/organization/workspaces/members.js.map +1 -0
- package/resources/beta/organization/workspaces/members.mjs +98 -0
- package/resources/beta/organization/workspaces/members.mjs.map +1 -0
- package/resources/beta/organization/workspaces/rate-limits.d.mts +84 -0
- package/resources/beta/organization/workspaces/rate-limits.d.mts.map +1 -0
- package/resources/beta/organization/workspaces/rate-limits.d.ts +84 -0
- package/resources/beta/organization/workspaces/rate-limits.d.ts.map +1 -0
- package/resources/beta/organization/workspaces/rate-limits.js +35 -0
- package/resources/beta/organization/workspaces/rate-limits.js.map +1 -0
- package/resources/beta/organization/workspaces/rate-limits.mjs +31 -0
- package/resources/beta/organization/workspaces/rate-limits.mjs.map +1 -0
- package/resources/beta/organization/workspaces/service-accounts.d.mts +210 -0
- package/resources/beta/organization/workspaces/service-accounts.d.mts.map +1 -0
- package/resources/beta/organization/workspaces/service-accounts.d.ts +210 -0
- package/resources/beta/organization/workspaces/service-accounts.d.ts.map +1 -0
- package/resources/beta/organization/workspaces/service-accounts.js +189 -0
- package/resources/beta/organization/workspaces/service-accounts.js.map +1 -0
- package/resources/beta/organization/workspaces/service-accounts.mjs +185 -0
- package/resources/beta/organization/workspaces/service-accounts.mjs.map +1 -0
- package/resources/beta/organization/workspaces/workspaces.d.mts +287 -0
- package/resources/beta/organization/workspaces/workspaces.d.mts.map +1 -0
- package/resources/beta/organization/workspaces/workspaces.d.ts +287 -0
- package/resources/beta/organization/workspaces/workspaces.d.ts.map +1 -0
- package/resources/beta/organization/workspaces/workspaces.js +112 -0
- package/resources/beta/organization/workspaces/workspaces.js.map +1 -0
- package/resources/beta/organization/workspaces/workspaces.mjs +107 -0
- package/resources/beta/organization/workspaces/workspaces.mjs.map +1 -0
- package/resources/beta/organization/workspaces.d.mts +2 -0
- package/resources/beta/organization/workspaces.d.mts.map +1 -0
- package/resources/beta/organization/workspaces.d.ts +2 -0
- package/resources/beta/organization/workspaces.d.ts.map +1 -0
- package/resources/beta/organization/workspaces.js +6 -0
- package/resources/beta/organization/workspaces.js.map +1 -0
- package/resources/beta/organization/workspaces.mjs +3 -0
- package/resources/beta/organization/workspaces.mjs.map +1 -0
- package/resources/beta/organization.d.mts +2 -0
- package/resources/beta/organization.d.mts.map +1 -0
- package/resources/beta/organization.d.ts +2 -0
- package/resources/beta/organization.d.ts.map +1 -0
- package/resources/beta/organization.js +6 -0
- package/resources/beta/organization.js.map +1 -0
- package/resources/beta/organization.mjs +3 -0
- package/resources/beta/organization.mjs.map +1 -0
- package/resources/beta/sessions/threads/threads.d.mts +2 -1
- package/resources/beta/sessions/threads/threads.d.mts.map +1 -1
- package/resources/beta/sessions/threads/threads.d.ts +2 -1
- package/resources/beta/sessions/threads/threads.d.ts.map +1 -1
- package/resources/beta/sessions/threads/threads.js.map +1 -1
- package/resources/beta/sessions/threads/threads.mjs.map +1 -1
- package/resources/messages/messages.d.mts +1 -1
- package/resources/messages/messages.d.ts +1 -1
- package/src/helpers/beta/environments.ts +5 -4
- package/src/helpers/beta/standard-schema.ts +99 -0
- package/src/internal/detect-platform.ts +1 -1
- package/src/internal/file-store.ts +550 -0
- package/src/internal/utils/values.ts +7 -0
- package/src/lib/BetaMessageStream.ts +1 -3
- package/src/lib/MessageStream.ts +1 -3
- package/src/lib/environments/poller.ts +47 -1
- package/src/lib/environments/worker.ts +419 -79
- package/src/lib/sessions/accumulate.ts +1 -3
- package/src/lib/standard-schema.ts +209 -0
- package/src/lib/tools/BetaToolRunner.ts +38 -6
- package/src/resources/beta/agents/agents.ts +435 -30
- package/src/resources/beta/agents/index.ts +17 -0
- package/src/resources/beta/beta.ts +52 -1
- package/src/resources/beta/environments/environments.ts +8 -1
- package/src/resources/beta/environments/work.ts +7 -0
- package/src/resources/beta/index.ts +18 -0
- package/src/resources/beta/memory-stores/memories.ts +6 -5
- package/src/resources/beta/memory-stores/memory-versions.ts +8 -5
- package/src/resources/beta/messages/messages.ts +51 -9
- package/src/resources/beta/organization/api-keys.ts +231 -0
- package/src/resources/beta/organization/external-keys.ts +362 -0
- package/src/resources/beta/organization/federation/federation.ts +71 -0
- package/src/resources/beta/organization/federation/index.ts +31 -0
- package/src/resources/beta/organization/federation/issuers.ts +486 -0
- package/src/resources/beta/organization/federation/rules/index.ts +23 -0
- package/src/resources/beta/organization/federation/rules/rules.ts +624 -0
- package/src/resources/beta/organization/federation/rules/workspaces.ts +196 -0
- package/src/resources/beta/organization/federation/rules.ts +3 -0
- package/src/resources/beta/organization/federation.ts +3 -0
- package/src/resources/beta/organization/index.ts +83 -0
- package/src/resources/beta/organization/invites.ts +207 -0
- package/src/resources/beta/organization/organization.ts +245 -0
- package/src/resources/beta/organization/rate-limits.ts +105 -0
- package/src/resources/beta/organization/service-accounts/index.ts +21 -0
- package/src/resources/beta/organization/service-accounts/service-accounts.ts +389 -0
- package/src/resources/beta/organization/service-accounts/workspaces.ts +217 -0
- package/src/resources/beta/organization/service-accounts.ts +3 -0
- package/src/resources/beta/organization/users.ts +163 -0
- package/src/resources/beta/organization/workspaces/index.ts +43 -0
- package/src/resources/beta/organization/workspaces/members.ts +209 -0
- package/src/resources/beta/organization/workspaces/rate-limits.ts +114 -0
- package/src/resources/beta/organization/workspaces/service-accounts.ts +325 -0
- package/src/resources/beta/organization/workspaces/workspaces.ts +434 -0
- package/src/resources/beta/organization/workspaces.ts +3 -0
- package/src/resources/beta/organization.ts +3 -0
- package/src/resources/beta/sessions/threads/threads.ts +2 -1
- package/src/resources/messages/messages.ts +1 -1
- package/src/tools/agent-toolset/fs-util.ts +40 -24
- package/src/tools/agent-toolset/memories.ts +1017 -0
- package/src/tools/agent-toolset/node.browser.ts +69 -1
- package/src/tools/agent-toolset/node.ts +143 -57
- package/src/tools/agent-toolset/skills.ts +29 -9
- package/src/tools/agent-toolset/sync-interval.ts +30 -0
- package/src/version.ts +1 -1
- package/tools/agent-toolset/fs-util.d.mts +23 -10
- package/tools/agent-toolset/fs-util.d.mts.map +1 -1
- package/tools/agent-toolset/fs-util.d.ts +23 -10
- package/tools/agent-toolset/fs-util.d.ts.map +1 -1
- package/tools/agent-toolset/fs-util.js +40 -25
- package/tools/agent-toolset/fs-util.js.map +1 -1
- package/tools/agent-toolset/fs-util.mjs +38 -25
- package/tools/agent-toolset/fs-util.mjs.map +1 -1
- package/tools/agent-toolset/memories.d.mts +173 -0
- package/tools/agent-toolset/memories.d.mts.map +1 -0
- package/tools/agent-toolset/memories.d.ts +173 -0
- package/tools/agent-toolset/memories.d.ts.map +1 -0
- package/tools/agent-toolset/memories.js +902 -0
- package/tools/agent-toolset/memories.js.map +1 -0
- package/tools/agent-toolset/memories.mjs +895 -0
- package/tools/agent-toolset/memories.mjs.map +1 -0
- package/tools/agent-toolset/node.browser.d.mts +32 -1
- package/tools/agent-toolset/node.browser.d.mts.map +1 -1
- package/tools/agent-toolset/node.browser.d.ts +32 -1
- package/tools/agent-toolset/node.browser.d.ts.map +1 -1
- package/tools/agent-toolset/node.browser.js +59 -1
- package/tools/agent-toolset/node.browser.js.map +1 -1
- package/tools/agent-toolset/node.browser.mjs +54 -0
- package/tools/agent-toolset/node.browser.mjs.map +1 -1
- package/tools/agent-toolset/node.d.mts +56 -24
- package/tools/agent-toolset/node.d.mts.map +1 -1
- package/tools/agent-toolset/node.d.ts +56 -24
- package/tools/agent-toolset/node.d.ts.map +1 -1
- package/tools/agent-toolset/node.js +83 -44
- package/tools/agent-toolset/node.js.map +1 -1
- package/tools/agent-toolset/node.mjs +77 -44
- package/tools/agent-toolset/node.mjs.map +1 -1
- package/tools/agent-toolset/skills.d.mts +16 -7
- package/tools/agent-toolset/skills.d.mts.map +1 -1
- package/tools/agent-toolset/skills.d.ts +16 -7
- package/tools/agent-toolset/skills.d.ts.map +1 -1
- package/tools/agent-toolset/skills.js +27 -9
- package/tools/agent-toolset/skills.js.map +1 -1
- package/tools/agent-toolset/skills.mjs +27 -9
- package/tools/agent-toolset/skills.mjs.map +1 -1
- package/tools/agent-toolset/sync-interval.d.mts +19 -0
- package/tools/agent-toolset/sync-interval.d.mts.map +1 -0
- package/tools/agent-toolset/sync-interval.d.ts +19 -0
- package/tools/agent-toolset/sync-interval.d.ts.map +1 -0
- package/tools/agent-toolset/sync-interval.js +29 -0
- package/tools/agent-toolset/sync-interval.js.map +1 -0
- package/tools/agent-toolset/sync-interval.mjs +25 -0
- package/tools/agent-toolset/sync-interval.mjs.map +1 -0
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `FileStore` — one confined folder; a relative path cannot escape it.
|
|
3
|
+
*
|
|
4
|
+
* Beta scope: symlinks are refused or skipped wherever the store meets them,
|
|
5
|
+
* but there is no hardening against a process racing the store's own
|
|
6
|
+
* syscalls; fsync durability, non-POSIX hosts, and read-size caps are out of
|
|
7
|
+
* scope.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import * as fsp from 'node:fs/promises';
|
|
11
|
+
import * as path from 'node:path';
|
|
12
|
+
import { constants as C } from 'node:fs';
|
|
13
|
+
import type { BigIntStats, Dirent } from 'node:fs';
|
|
14
|
+
import type * as util from 'node:util';
|
|
15
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
16
|
+
import { encodeUTF8 } from './utils/bytes';
|
|
17
|
+
|
|
18
|
+
// Owner-only regardless of umask: the store holds downloaded user/model content.
|
|
19
|
+
const OWNER_ONLY_DIR_MODE = 0o700;
|
|
20
|
+
const OWNER_ONLY_FILE_MODE = 0o600;
|
|
21
|
+
const OWNER_ONLY_EXEC_MODE = 0o700;
|
|
22
|
+
|
|
23
|
+
// 0 where the platform lacks them; `open` refuses such platforms.
|
|
24
|
+
const O_NOFOLLOW: number = (C as { O_NOFOLLOW?: number }).O_NOFOLLOW ?? 0;
|
|
25
|
+
const O_NONBLOCK: number = (C as { O_NONBLOCK?: number }).O_NONBLOCK ?? 0;
|
|
26
|
+
|
|
27
|
+
/** A refused operation — input the store will not act on. OS errors propagate with their `.code`. */
|
|
28
|
+
export class FileStoreError extends Error {
|
|
29
|
+
static readonly ESCAPES_ROOT = 'escapes the store root';
|
|
30
|
+
static readonly IS_A_SYMLINK = 'is a symlink';
|
|
31
|
+
static readonly NOT_A_FILE = 'is not a regular file';
|
|
32
|
+
static readonly NOT_A_DIRECTORY = 'is not a directory';
|
|
33
|
+
static readonly NOT_UTF8 = 'is not valid utf-8';
|
|
34
|
+
static readonly MOVE_DESTINATION_EXISTS = 'already exists';
|
|
35
|
+
|
|
36
|
+
readonly reason: string;
|
|
37
|
+
readonly relPath: string;
|
|
38
|
+
|
|
39
|
+
constructor(reason: string, relPath: string) {
|
|
40
|
+
super(`path ${JSON.stringify(relPath)} ${reason}`);
|
|
41
|
+
this.name = 'FileStoreError';
|
|
42
|
+
this.reason = reason;
|
|
43
|
+
this.relPath = relPath;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The store's resolved root, and what {@link FileStore.dispose} will do to it.
|
|
49
|
+
*
|
|
50
|
+
* `removedOnDispose` is true when `open` found no root, so `dispose` removes
|
|
51
|
+
* it. A root that was already there is someone else's — a pre-seeded mount, a
|
|
52
|
+
* caller's workdir — and is kept.
|
|
53
|
+
*/
|
|
54
|
+
export type Root = { path: string; removedOnDispose: boolean };
|
|
55
|
+
|
|
56
|
+
/** Options for {@link FileStore.open} / {@link openFileStore}. */
|
|
57
|
+
export interface OpenFileStoreOptions {
|
|
58
|
+
/**
|
|
59
|
+
* Restrict the store to valid UTF-8 (default `false`): a `put` of binary
|
|
60
|
+
* bytes and a `get` of a binary file are refused with
|
|
61
|
+
* {@link FileStoreError}, so a caller that decodes what `get` returns can
|
|
62
|
+
* never hit a decode error.
|
|
63
|
+
*/
|
|
64
|
+
utf8?: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Resolve `root`; creates nothing — only {@link FileStore.createRoot} makes the folder. */
|
|
68
|
+
export async function openFileStore(root: string, opts?: OpenFileStoreOptions): Promise<FileStore> {
|
|
69
|
+
return FileStore.open(root, opts);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* True for a path usable verbatim as a store location: absolute, with no `..`
|
|
74
|
+
* components. Paths are judged in POSIX terms — they are wire values naming
|
|
75
|
+
* locations inside a POSIX container, not host-native paths.
|
|
76
|
+
*/
|
|
77
|
+
export function isPathLegal(p: string): boolean {
|
|
78
|
+
return p.startsWith('/') && !p.split('/').includes('..');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** One hashed file version: the stat identity it had, and its sha. */
|
|
82
|
+
type Hashed = {
|
|
83
|
+
mtimeNs: bigint;
|
|
84
|
+
// Userspace cannot set ctime, so writers that preserve mtimes
|
|
85
|
+
// (`rsync -t`, `cp -p`) still miss the cache.
|
|
86
|
+
ctimeNs: bigint;
|
|
87
|
+
size: bigint;
|
|
88
|
+
sha: string;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* One confined folder of regular files.
|
|
93
|
+
*
|
|
94
|
+
* Every `relPath` is relative to the root (a leading `/` also means the root)
|
|
95
|
+
* and refused with {@link FileStoreError} when it escapes. The store holds
|
|
96
|
+
* regular files only: symlinks are refused on read and skipped by listings —
|
|
97
|
+
* {@link findSymlinks} reports them. A `relPath` resolving to the root itself
|
|
98
|
+
* is banned by this interface: `put` and `get` refuse it, `move` and `remove`
|
|
99
|
+
* do nothing. A store opened with `utf8: true` refuses binary content the
|
|
100
|
+
* same way — on `put` of such bytes and on `get` of such a file. Only
|
|
101
|
+
* {@link createRoot} makes the root: writes create directories below it,
|
|
102
|
+
* never the root itself, so a root removed while the store is open stays
|
|
103
|
+
* removed and the write fails with `ENOENT`.
|
|
104
|
+
*/
|
|
105
|
+
export class FileStore {
|
|
106
|
+
private readonly rootPath: string;
|
|
107
|
+
/** True ⇒ this open created the root, so {@link dispose} removes it. */
|
|
108
|
+
private readonly removedOnDispose: boolean;
|
|
109
|
+
/** Set iff the store refuses non-UTF-8 content; {@link requireUtf8} decodes against it, on both put and get. */
|
|
110
|
+
private readonly decoder: util.TextDecoder | undefined;
|
|
111
|
+
/** `hashtree`'s advisory cache; every hit re-validates against a fresh stat. */
|
|
112
|
+
private readonly hashes = new Map<string, Hashed>();
|
|
113
|
+
|
|
114
|
+
static isPathLegal = isPathLegal;
|
|
115
|
+
|
|
116
|
+
/** @internal — use {@link FileStore.open} / {@link openFileStore}. */
|
|
117
|
+
constructor(root: string, removedOnDispose: boolean, utf8Only: boolean = false) {
|
|
118
|
+
this.rootPath = root;
|
|
119
|
+
this.removedOnDispose = removedOnDispose;
|
|
120
|
+
this.decoder = utf8Only ? new TextDecoder('utf-8', { fatal: true }) : undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Resolve `root`; creates nothing — only {@link createRoot} makes the folder. */
|
|
124
|
+
static async open(root: string, opts?: OpenFileStoreOptions): Promise<FileStore> {
|
|
125
|
+
// A deployment condition, not refused caller input — hence not FileStoreError.
|
|
126
|
+
if (!platformSupported()) {
|
|
127
|
+
throw new Error('FileStore requires O_NOFOLLOW support on this platform');
|
|
128
|
+
}
|
|
129
|
+
let removedOnDispose = false;
|
|
130
|
+
try {
|
|
131
|
+
// lstat, not a follow-and-swallow existence check: following symlinks or
|
|
132
|
+
// swallowing permission errors would mark a real directory ours to
|
|
133
|
+
// delete on dispose.
|
|
134
|
+
await fsp.lstat(root);
|
|
135
|
+
} catch (e) {
|
|
136
|
+
if ((e as NodeJS.ErrnoException).code !== 'ENOENT') throw e;
|
|
137
|
+
removedOnDispose = true;
|
|
138
|
+
}
|
|
139
|
+
return new FileStore(path.resolve(root), removedOnDispose, opts?.utf8 ?? false);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Create the root directory and any missing ancestors; already existing is fine. */
|
|
143
|
+
async createRoot(): Promise<void> {
|
|
144
|
+
await makeDirAndAncestors(this.rootPath);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** The resolved root, and what {@link dispose} will do to it. */
|
|
148
|
+
root(): Root {
|
|
149
|
+
return { path: this.rootPath, removedOnDispose: this.removedOnDispose };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Remove the root iff `open` created it; pre-existing roots are kept.
|
|
154
|
+
*
|
|
155
|
+
* Wired to `Symbol.asyncDispose` at runtime when the host provides it, so
|
|
156
|
+
* `await using` works on engines with explicit resource management.
|
|
157
|
+
*/
|
|
158
|
+
async dispose(): Promise<void> {
|
|
159
|
+
if (!this.removedOnDispose) return;
|
|
160
|
+
await fsp.rm(this.rootPath, { recursive: true, force: true });
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Write `data` (`string` UTF-8 or bytes) atomically to the file at `relPath`.
|
|
165
|
+
*
|
|
166
|
+
* Missing directories below the root are created; a missing root is not —
|
|
167
|
+
* the write fails with `ENOENT`.
|
|
168
|
+
*/
|
|
169
|
+
async put(relPath: string, data: string | Uint8Array, opts?: { executable?: boolean }): Promise<void> {
|
|
170
|
+
// "dir/." names a directory just like a trailing "/".
|
|
171
|
+
const tail = relPath.replace(/\\/g, '/');
|
|
172
|
+
if (tail.endsWith('/') || tail.endsWith('/.') || tail === '' || tail === '.') {
|
|
173
|
+
throw new FileStoreError(FileStoreError.NOT_A_FILE, relPath);
|
|
174
|
+
}
|
|
175
|
+
const dest = this.resolveUnderRoot(relPath);
|
|
176
|
+
const payload = typeof data === 'string' ? encodeUTF8(data) : data;
|
|
177
|
+
this.requireUtf8(relPath, payload);
|
|
178
|
+
await makeDirsBelowRoot(this.rootPath, path.dirname(dest));
|
|
179
|
+
await replaceViaTemp(dest, payload, opts?.executable ?? false);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** The file's bytes; `null` when absent. */
|
|
183
|
+
async get(relPath: string): Promise<Uint8Array | null> {
|
|
184
|
+
const dest = this.resolveUnderRoot(relPath);
|
|
185
|
+
let handle: fsp.FileHandle;
|
|
186
|
+
try {
|
|
187
|
+
handle = await openRegularFile(relPath, dest);
|
|
188
|
+
} catch (e) {
|
|
189
|
+
if ((e as NodeJS.ErrnoException).code === 'ENOENT') return null;
|
|
190
|
+
throw e;
|
|
191
|
+
}
|
|
192
|
+
let data: Uint8Array;
|
|
193
|
+
try {
|
|
194
|
+
const buf = await handle.readFile();
|
|
195
|
+
data = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
196
|
+
} finally {
|
|
197
|
+
await handle.close();
|
|
198
|
+
}
|
|
199
|
+
this.requireUtf8(relPath, data);
|
|
200
|
+
return data;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** The relative path of every file under the directory `under`. */
|
|
204
|
+
async ls(under: string = '/'): Promise<Set<string>> {
|
|
205
|
+
const base = this.resolveUnderRoot(under);
|
|
206
|
+
return new Set((await filenamesInDir(this.rootPath, under, base)).map(([rel]) => rel));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Every symlink under `under` — listings skip them and reads refuse them,
|
|
211
|
+
* so a caller that must know they exist asks here.
|
|
212
|
+
*/
|
|
213
|
+
async findSymlinks(under: string = '/'): Promise<Set<string>> {
|
|
214
|
+
const base = this.resolveUnderRoot(under);
|
|
215
|
+
return symlinksInDir(this.rootPath, under, base);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* `{relPath: sha256Hex}` of every file under the directory `under`.
|
|
220
|
+
*
|
|
221
|
+
* Unchanged files — same size, mtime, and ctime since the last call —
|
|
222
|
+
* reuse their recorded hash instead of being re-read.
|
|
223
|
+
*/
|
|
224
|
+
async hashtree(under: string = '/'): Promise<Record<string, string>> {
|
|
225
|
+
const base = this.resolveUnderRoot(under);
|
|
226
|
+
const walkStartNs = _internals.nowNs();
|
|
227
|
+
// Null prototype so a file named `__proto__` (or `constructor`) is an
|
|
228
|
+
// ordinary own key instead of a silent prototype write / inherited read.
|
|
229
|
+
const out: Record<string, string> = Object.create(null);
|
|
230
|
+
for (const [rel, full] of await filenamesInDir(this.rootPath, under, base)) {
|
|
231
|
+
const sha = await this.hashViaCache(rel, full, walkStartNs);
|
|
232
|
+
if (sha !== null) out[rel] = sha;
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** One file's sha256; `null` when absent. Shares {@link hashtree}'s cache. */
|
|
238
|
+
async hashFile(relPath: string): Promise<string | null> {
|
|
239
|
+
const dest = this.resolveUnderRoot(relPath);
|
|
240
|
+
let st: BigIntStats;
|
|
241
|
+
try {
|
|
242
|
+
st = await fsp.lstat(dest, { bigint: true });
|
|
243
|
+
} catch (e) {
|
|
244
|
+
if ((e as NodeJS.ErrnoException).code === 'ENOENT') return null;
|
|
245
|
+
throw e;
|
|
246
|
+
}
|
|
247
|
+
if (st.isSymbolicLink()) throw new FileStoreError(FileStoreError.IS_A_SYMLINK, relPath);
|
|
248
|
+
if (!st.isFile()) throw new FileStoreError(FileStoreError.NOT_A_FILE, relPath);
|
|
249
|
+
const rel = path.relative(this.rootPath, dest).split(path.sep).join('/');
|
|
250
|
+
return this.hashViaCache(rel, dest, _internals.nowNs());
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Rename `src` to `dst`; an existing `dst` is refused. The banned store
|
|
255
|
+
* root as either end does nothing.
|
|
256
|
+
*/
|
|
257
|
+
async move(src: string, dst: string): Promise<void> {
|
|
258
|
+
const s = this.resolveUnderRoot(src);
|
|
259
|
+
const d = this.resolveUnderRoot(dst);
|
|
260
|
+
if (s === this.rootPath || d === this.rootPath) return;
|
|
261
|
+
// stat, not lstat: a dangling symlink at dst reads as absent and is
|
|
262
|
+
// atomically replaced by the rename, like any other rename target.
|
|
263
|
+
const dstExists = await fsp.stat(d).then(
|
|
264
|
+
() => true,
|
|
265
|
+
() => false,
|
|
266
|
+
);
|
|
267
|
+
if (dstExists) throw new FileStoreError(FileStoreError.MOVE_DESTINATION_EXISTS, dst);
|
|
268
|
+
await makeDirsBelowRoot(this.rootPath, path.dirname(d));
|
|
269
|
+
await fsp.rename(s, d);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Delete a file or subtree; absent — and the banned store root — do nothing. */
|
|
273
|
+
async remove(relPath: string): Promise<void> {
|
|
274
|
+
const dest = this.resolveUnderRoot(relPath);
|
|
275
|
+
if (dest === this.rootPath) return;
|
|
276
|
+
let st: BigIntStats;
|
|
277
|
+
try {
|
|
278
|
+
// lstat: a dangling symlink must still be unlinked.
|
|
279
|
+
st = await fsp.lstat(dest, { bigint: true });
|
|
280
|
+
} catch (e) {
|
|
281
|
+
if ((e as NodeJS.ErrnoException).code === 'ENOENT') return;
|
|
282
|
+
throw e;
|
|
283
|
+
}
|
|
284
|
+
if (st.isDirectory()) {
|
|
285
|
+
await fsp.rm(dest, { recursive: true, force: true });
|
|
286
|
+
} else {
|
|
287
|
+
try {
|
|
288
|
+
await fsp.unlink(dest);
|
|
289
|
+
} catch (e) {
|
|
290
|
+
if ((e as NodeJS.ErrnoException).code !== 'ENOENT') throw e;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
private resolveUnderRoot(relPath: string): string {
|
|
296
|
+
const norm = relPath.replace(/\\/g, '/').replace(/^\/+/, '');
|
|
297
|
+
const parts = norm.split('/').filter((p) => p !== '' && p !== '.');
|
|
298
|
+
if (path.posix.isAbsolute(norm) || parts.includes('..')) {
|
|
299
|
+
throw new FileStoreError(FileStoreError.ESCAPES_ROOT, relPath);
|
|
300
|
+
}
|
|
301
|
+
return parts.length === 0 ? this.rootPath : path.join(this.rootPath, ...parts);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
private requireUtf8(relPath: string, data: Uint8Array): void {
|
|
305
|
+
if (!this.decoder) return;
|
|
306
|
+
try {
|
|
307
|
+
this.decoder.decode(data);
|
|
308
|
+
} catch {
|
|
309
|
+
throw new FileStoreError(FileStoreError.NOT_UTF8, relPath);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
private async hashViaCache(rel: string, full: string, walkStartNs: bigint): Promise<string | null> {
|
|
314
|
+
let st: BigIntStats;
|
|
315
|
+
try {
|
|
316
|
+
st = await fsp.lstat(full, { bigint: true });
|
|
317
|
+
} catch (e) {
|
|
318
|
+
if ((e as NodeJS.ErrnoException).code === 'ENOENT') return null; // vanished since the walk: not in this snapshot
|
|
319
|
+
throw e;
|
|
320
|
+
}
|
|
321
|
+
if (!st.isFile()) return null;
|
|
322
|
+
const cached = this.hashes.get(rel);
|
|
323
|
+
let sha: string;
|
|
324
|
+
if (cached !== undefined && unchangedSinceHashed(cached, st)) {
|
|
325
|
+
sha = cached.sha;
|
|
326
|
+
} else {
|
|
327
|
+
try {
|
|
328
|
+
sha = await _internals.hashFile(full);
|
|
329
|
+
} catch (e) {
|
|
330
|
+
const code = (e as NodeJS.ErrnoException).code;
|
|
331
|
+
if (code === 'ENOENT' || e instanceof FileStoreError) return null;
|
|
332
|
+
// FreeBSD reports EMLINK rather than ELOOP for O_NOFOLLOW.
|
|
333
|
+
if (code === 'ELOOP' || code === 'EMLINK') return null;
|
|
334
|
+
throw e;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (oldEnoughToCache(st, walkStartNs)) {
|
|
338
|
+
this.hashes.set(rel, { mtimeNs: st.mtimeNs, ctimeNs: st.ctimeNs, size: st.size, sha });
|
|
339
|
+
}
|
|
340
|
+
return sha;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function platformSupported(): boolean {
|
|
345
|
+
return O_NOFOLLOW !== 0;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
async function makeDirAndAncestors(dir: string): Promise<void> {
|
|
349
|
+
const missing: string[] = [];
|
|
350
|
+
let current = dir;
|
|
351
|
+
for (;;) {
|
|
352
|
+
try {
|
|
353
|
+
await fsp.stat(current);
|
|
354
|
+
break;
|
|
355
|
+
} catch (e) {
|
|
356
|
+
const code = (e as NodeJS.ErrnoException).code;
|
|
357
|
+
if (code !== 'ENOENT' && code !== 'ENOTDIR' && code !== 'ELOOP') throw e;
|
|
358
|
+
}
|
|
359
|
+
missing.push(current);
|
|
360
|
+
const parent = path.dirname(current);
|
|
361
|
+
if (parent === current) break;
|
|
362
|
+
current = parent;
|
|
363
|
+
}
|
|
364
|
+
for (const directory of missing.reverse()) {
|
|
365
|
+
try {
|
|
366
|
+
await fsp.mkdir(directory, { mode: OWNER_ONLY_DIR_MODE });
|
|
367
|
+
} catch (e) {
|
|
368
|
+
if ((e as NodeJS.ErrnoException).code !== 'EEXIST') throw e;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
async function makeDirsBelowRoot(root: string, dir: string): Promise<void> {
|
|
374
|
+
// Never the root itself: only createRoot() makes it, so a write racing an
|
|
375
|
+
// rm -rf of the folder fails with ENOENT instead of re-creating it.
|
|
376
|
+
const below = path.relative(root, dir);
|
|
377
|
+
if (below === '') return;
|
|
378
|
+
let current = root;
|
|
379
|
+
for (const part of below.split(path.sep)) {
|
|
380
|
+
current = path.join(current, part);
|
|
381
|
+
try {
|
|
382
|
+
await fsp.mkdir(current, { mode: OWNER_ONLY_DIR_MODE });
|
|
383
|
+
} catch (e) {
|
|
384
|
+
if ((e as NodeJS.ErrnoException).code !== 'EEXIST') throw e;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async function replaceViaTemp(dest: string, data: Uint8Array, isExecutable: boolean): Promise<void> {
|
|
390
|
+
const mode = isExecutable ? OWNER_ONLY_EXEC_MODE : OWNER_ONLY_FILE_MODE;
|
|
391
|
+
const tmp = path.join(path.dirname(dest), `.fs-${randomBytes(8).toString('hex')}.tmp`);
|
|
392
|
+
let handle: fsp.FileHandle | undefined;
|
|
393
|
+
try {
|
|
394
|
+
handle = await fsp.open(tmp, C.O_WRONLY | C.O_CREAT | C.O_EXCL | O_NOFOLLOW, mode);
|
|
395
|
+
await handle.writeFile(data);
|
|
396
|
+
await handle.close();
|
|
397
|
+
handle = undefined;
|
|
398
|
+
await fsp.rename(tmp, dest);
|
|
399
|
+
} catch (err) {
|
|
400
|
+
// Best-effort temp cleanup; never mask the original error.
|
|
401
|
+
if (handle) await handle.close().catch(() => {});
|
|
402
|
+
await fsp.unlink(tmp).catch(() => {});
|
|
403
|
+
throw err;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
async function openRegularFile(relPath: string, dest: string): Promise<fsp.FileHandle> {
|
|
408
|
+
// O_NONBLOCK: a FIFO fails the fstat check below instead of blocking the open.
|
|
409
|
+
let handle: fsp.FileHandle;
|
|
410
|
+
try {
|
|
411
|
+
handle = await fsp.open(dest, C.O_RDONLY | O_NOFOLLOW | O_NONBLOCK);
|
|
412
|
+
} catch (e) {
|
|
413
|
+
// FreeBSD reports EMLINK rather than ELOOP for O_NOFOLLOW.
|
|
414
|
+
const code = (e as NodeJS.ErrnoException).code;
|
|
415
|
+
if (code === 'ELOOP' || code === 'EMLINK') {
|
|
416
|
+
throw new FileStoreError(FileStoreError.IS_A_SYMLINK, relPath);
|
|
417
|
+
}
|
|
418
|
+
throw e;
|
|
419
|
+
}
|
|
420
|
+
try {
|
|
421
|
+
const st = await handle.stat();
|
|
422
|
+
if (!st.isFile()) throw new FileStoreError(FileStoreError.NOT_A_FILE, relPath);
|
|
423
|
+
} catch (e) {
|
|
424
|
+
await handle.close().catch(() => {});
|
|
425
|
+
throw e;
|
|
426
|
+
}
|
|
427
|
+
return handle;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/** sha256 of a file's contents, streamed — constant memory on any file size. */
|
|
431
|
+
async function hashFile(full: string): Promise<string> {
|
|
432
|
+
const digest = createHash('sha256');
|
|
433
|
+
const handle = await openRegularFile(path.basename(full), full);
|
|
434
|
+
const buf = new Uint8Array(1024 * 1024);
|
|
435
|
+
try {
|
|
436
|
+
for (;;) {
|
|
437
|
+
const { bytesRead } = await handle.read(buf, 0, buf.length);
|
|
438
|
+
if (bytesRead === 0) break;
|
|
439
|
+
digest.update(buf.subarray(0, bytesRead));
|
|
440
|
+
}
|
|
441
|
+
} finally {
|
|
442
|
+
await handle.close();
|
|
443
|
+
}
|
|
444
|
+
return digest.digest('hex');
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* `[rel, path]` for every regular file under the directory `base`; an absent
|
|
449
|
+
* `base` is empty, a present non-directory is refused. The walk never
|
|
450
|
+
* descends symlinked directories.
|
|
451
|
+
*/
|
|
452
|
+
async function filenamesInDir(root: string, under: string, base: string): Promise<[string, string][]> {
|
|
453
|
+
if (!(await requireDir(under, base))) return [];
|
|
454
|
+
const out: [string, string][] = [];
|
|
455
|
+
await walk(base, (full, entry) => {
|
|
456
|
+
if (entry.isFile()) out.push([path.relative(root, full).split(path.sep).join('/'), full]);
|
|
457
|
+
});
|
|
458
|
+
out.sort();
|
|
459
|
+
return out;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
async function symlinksInDir(root: string, under: string, base: string): Promise<Set<string>> {
|
|
463
|
+
const relOf = (full: string) => path.relative(root, full).split(path.sep).join('/');
|
|
464
|
+
let st: BigIntStats;
|
|
465
|
+
try {
|
|
466
|
+
st = await fsp.lstat(base, { bigint: true });
|
|
467
|
+
} catch (e) {
|
|
468
|
+
const code = (e as NodeJS.ErrnoException).code;
|
|
469
|
+
if (code === 'ENOENT' || code === 'ENOTDIR') return new Set();
|
|
470
|
+
throw e;
|
|
471
|
+
}
|
|
472
|
+
if (st.isSymbolicLink()) return new Set([relOf(base)]);
|
|
473
|
+
if (!st.isDirectory()) throw new FileStoreError(FileStoreError.NOT_A_DIRECTORY, under);
|
|
474
|
+
const out = new Set<string>();
|
|
475
|
+
// Symlinks to directories are reported, never descended, like the rest.
|
|
476
|
+
await walk(base, (full, entry) => {
|
|
477
|
+
if (entry.isSymbolicLink()) out.add(relOf(full));
|
|
478
|
+
});
|
|
479
|
+
return out;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/** `false` when `base` is absent, refused when present but not a directory. */
|
|
483
|
+
async function requireDir(under: string, base: string): Promise<boolean> {
|
|
484
|
+
let st: BigIntStats;
|
|
485
|
+
try {
|
|
486
|
+
st = await fsp.lstat(base, { bigint: true });
|
|
487
|
+
} catch (e) {
|
|
488
|
+
// Absent — including "under a file" (ENOTDIR) — is an empty listing.
|
|
489
|
+
const code = (e as NodeJS.ErrnoException).code;
|
|
490
|
+
if (code === 'ENOENT' || code === 'ENOTDIR') return false;
|
|
491
|
+
throw e;
|
|
492
|
+
}
|
|
493
|
+
if (!st.isDirectory()) throw new FileStoreError(FileStoreError.NOT_A_DIRECTORY, under);
|
|
494
|
+
return true;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/** Visit every entry under `base` without descending symlinked directories. */
|
|
498
|
+
async function walk(base: string, visit: (full: string, entry: Dirent) => void): Promise<void> {
|
|
499
|
+
const stack: string[] = [base];
|
|
500
|
+
while (stack.length) {
|
|
501
|
+
const dir = stack.pop()!;
|
|
502
|
+
let entries: Dirent[];
|
|
503
|
+
try {
|
|
504
|
+
entries = await fsp.readdir(dir, { withFileTypes: true });
|
|
505
|
+
} catch (e) {
|
|
506
|
+
if ((e as NodeJS.ErrnoException).code === 'ENOENT') continue; // a listing is a snapshot, not a lock
|
|
507
|
+
throw e;
|
|
508
|
+
}
|
|
509
|
+
for (const entry of entries) {
|
|
510
|
+
const full = path.join(dir, entry.name);
|
|
511
|
+
visit(full, entry);
|
|
512
|
+
if (entry.isDirectory() && !entry.isSymbolicLink()) stack.push(full);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function unchangedSinceHashed(cached: Hashed, st: BigIntStats): boolean {
|
|
518
|
+
return st.mtimeNs === cached.mtimeNs && st.ctimeNs === cached.ctimeNs && st.size === cached.size;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
function oldEnoughToCache(st: BigIntStats, walkStartNs: bigint): boolean {
|
|
522
|
+
const newestNs = st.mtimeNs > st.ctimeNs ? st.mtimeNs : st.ctimeNs;
|
|
523
|
+
return newestNs < walkStartNs - _internals.timestampTrustMarginNs;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Filesystems stamp times with coarse clocks, so a rewrite shortly after a
|
|
527
|
+
// hashed write can reuse the exact stamps. Files younger than the margin are
|
|
528
|
+
// simply re-hashed next walk.
|
|
529
|
+
const TIMESTAMP_TRUST_MARGIN_NS = 2_000_000_000n;
|
|
530
|
+
|
|
531
|
+
/** Test seam — the hasher, the trust margin, and the walk clock. @internal */
|
|
532
|
+
export const _internals = {
|
|
533
|
+
hashFile,
|
|
534
|
+
timestampTrustMarginNs: TIMESTAMP_TRUST_MARGIN_NS,
|
|
535
|
+
nowNs: (): bigint => BigInt(Date.now()) * 1_000_000n,
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
export const LocalFileStore = FileStore;
|
|
539
|
+
|
|
540
|
+
// Wire `Symbol.asyncDispose` at runtime when the host provides it — the
|
|
541
|
+
// repo's tsconfig targets ES2020 so the type-level `AsyncDisposable` lib is
|
|
542
|
+
// not available, but `await using` callers on newer engines still work.
|
|
543
|
+
const asyncDispose = (Symbol as { asyncDispose?: symbol }).asyncDispose;
|
|
544
|
+
if (asyncDispose) {
|
|
545
|
+
Object.defineProperty(FileStore.prototype, asyncDispose, {
|
|
546
|
+
value: FileStore.prototype.dispose,
|
|
547
|
+
configurable: true,
|
|
548
|
+
writable: true,
|
|
549
|
+
});
|
|
550
|
+
}
|
|
@@ -110,3 +110,10 @@ export const pop = <T extends Record<string, any>, K extends string>(obj: T, key
|
|
|
110
110
|
delete obj[key];
|
|
111
111
|
return value;
|
|
112
112
|
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Compile-time exhaustiveness check: passing a value here only type-checks once every
|
|
116
|
+
* member of its union has been handled. Does nothing at runtime, so unknown values from a
|
|
117
|
+
* newer API version fall through instead of throwing.
|
|
118
|
+
*/
|
|
119
|
+
export function checkNever(_value: never): void {}
|
|
@@ -2,6 +2,7 @@ import { STAINLESS_HELPER_METHOD_HEADER } from '../internal/stainless-helper-hea
|
|
|
2
2
|
import type { Logger } from '../client';
|
|
3
3
|
import { AnthropicError, APIUserAbortError } from '../error';
|
|
4
4
|
import { isAbortError } from '../internal/errors';
|
|
5
|
+
import { checkNever } from '../internal/utils/values';
|
|
5
6
|
import { type RequestOptions } from '../internal/request-options';
|
|
6
7
|
import {
|
|
7
8
|
type BetaContentBlock,
|
|
@@ -798,6 +799,3 @@ export class BetaMessageStream<ParsedT = null> implements AsyncIterable<BetaMess
|
|
|
798
799
|
return stream.toReadableStream();
|
|
799
800
|
}
|
|
800
801
|
}
|
|
801
|
-
|
|
802
|
-
// used to ensure exhaustive case matching without throwing a runtime error
|
|
803
|
-
function checkNever(x: never) {}
|
package/src/lib/MessageStream.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { STAINLESS_HELPER_METHOD_HEADER } from '../internal/stainless-helper-header';
|
|
2
2
|
import { isAbortError } from '../internal/errors';
|
|
3
|
+
import { checkNever } from '../internal/utils/values';
|
|
3
4
|
import { AnthropicError, APIUserAbortError } from '../error';
|
|
4
5
|
import {
|
|
5
6
|
type ContentBlock,
|
|
@@ -750,6 +751,3 @@ export class MessageStream<ParsedT = null> implements AsyncIterable<MessageStrea
|
|
|
750
751
|
return stream.toReadableStream();
|
|
751
752
|
}
|
|
752
753
|
}
|
|
753
|
-
|
|
754
|
-
// used to ensure exhaustive case matching without throwing a runtime error
|
|
755
|
-
function checkNever(x: never) {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AnthropicError } from '../../core/error';
|
|
2
2
|
import type { Anthropic } from '../../client';
|
|
3
3
|
import type { BetaSelfHostedWork } from '../../resources/beta/environments/work';
|
|
4
|
-
import { loggerFor } from '../../internal/utils/log';
|
|
4
|
+
import { loggerFor, type Logger } from '../../internal/utils/log';
|
|
5
5
|
import { sleep } from '../../internal/utils/sleep';
|
|
6
6
|
import { uuid4 } from '../../internal/utils/uuid';
|
|
7
7
|
import { linkAbort } from '../../internal/utils/abort';
|
|
@@ -22,6 +22,7 @@ export { is4xx, isFatal4xx, isStatus, jitter } from '../../internal/utils/backof
|
|
|
22
22
|
export const POLL_BLOCK_MS = 999;
|
|
23
23
|
const POLL_BACKOFF_BASE_MS = 1000;
|
|
24
24
|
const POLL_BACKOFF_CAP_MS = 60_000;
|
|
25
|
+
const IDLE_REPORT_INTERVAL_MS = 300_000;
|
|
25
26
|
|
|
26
27
|
export interface WorkPollerOptions {
|
|
27
28
|
client: Anthropic;
|
|
@@ -82,6 +83,12 @@ export interface WorkPollerOptions {
|
|
|
82
83
|
* each item, yields the {@link BetaSelfHostedWork} item, and posts `stop` after
|
|
83
84
|
* the consumer's loop body returns (or when the consumer `break`s).
|
|
84
85
|
*
|
|
86
|
+
* A yielded item may carry a per-item `secret` payload (populated only by the
|
|
87
|
+
* poll response); the poller passes it through untouched — consumers such as
|
|
88
|
+
* {@link EnvironmentWorker} extract the sessions token it carries and prefer
|
|
89
|
+
* that over the environment key for the item's downstream calls. Treat it as
|
|
90
|
+
* opaque and never log it.
|
|
91
|
+
*
|
|
85
92
|
* @example
|
|
86
93
|
* ```ts
|
|
87
94
|
* for await (const work of client.beta.environments.work.poller({
|
|
@@ -152,6 +159,7 @@ export class WorkPoller implements AsyncIterable<BetaSelfHostedWork> {
|
|
|
152
159
|
component: 'work-poller',
|
|
153
160
|
environment_id: this.environmentId,
|
|
154
161
|
});
|
|
162
|
+
const idle = new IdleLog(log, this.environmentId);
|
|
155
163
|
|
|
156
164
|
try {
|
|
157
165
|
let attempt = 0;
|
|
@@ -189,9 +197,11 @@ export class WorkPoller implements AsyncIterable<BetaSelfHostedWork> {
|
|
|
189
197
|
if (work == null) {
|
|
190
198
|
// Queue empty: either return now (drain) or wait and poll again.
|
|
191
199
|
if (this.#drain) return;
|
|
200
|
+
idle.onEmptyPoll();
|
|
192
201
|
await sleep(jitter(1000, 3000), this.#controller.signal);
|
|
193
202
|
continue;
|
|
194
203
|
}
|
|
204
|
+
idle.onClaim();
|
|
195
205
|
log.info('claimed work', {
|
|
196
206
|
component: 'work-poller',
|
|
197
207
|
environment_id: this.environmentId,
|
|
@@ -242,6 +252,42 @@ export function backoff(attempt: number): number {
|
|
|
242
252
|
return expBackoff(attempt, POLL_BACKOFF_BASE_MS, POLL_BACKOFF_CAP_MS);
|
|
243
253
|
}
|
|
244
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Keeps an idle poll loop visible in the logs without an INFO line per poll:
|
|
257
|
+
* the first empty poll after start-up or after a claim logs at INFO and later
|
|
258
|
+
* ones at DEBUG, with an INFO reminder every `IDLE_REPORT_INTERVAL_MS` while
|
|
259
|
+
* the loop stays idle.
|
|
260
|
+
*/
|
|
261
|
+
class IdleLog {
|
|
262
|
+
readonly #log: Logger;
|
|
263
|
+
readonly #environmentId: string;
|
|
264
|
+
#idleSince: number | undefined;
|
|
265
|
+
#lastReport = 0;
|
|
266
|
+
|
|
267
|
+
constructor(log: Logger, environmentId: string) {
|
|
268
|
+
this.#log = log;
|
|
269
|
+
this.#environmentId = environmentId;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
onEmptyPoll(): void {
|
|
273
|
+
const now = Date.now();
|
|
274
|
+
const fields = { component: 'work-poller', environment_id: this.#environmentId };
|
|
275
|
+
if (this.#idleSince === undefined) {
|
|
276
|
+
this.#idleSince = this.#lastReport = now;
|
|
277
|
+
this.#log.info('idle; polling for work', fields);
|
|
278
|
+
} else if (now - this.#lastReport >= IDLE_REPORT_INTERVAL_MS) {
|
|
279
|
+
this.#lastReport = now;
|
|
280
|
+
this.#log.info(`still polling; idle for ${Math.round((now - this.#idleSince) / 1000)}s`, fields);
|
|
281
|
+
} else {
|
|
282
|
+
this.#log.debug('poll returned no work', fields);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
onClaim(): void {
|
|
287
|
+
this.#idleSince = undefined;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
245
291
|
function defaultWorkerId(): string {
|
|
246
292
|
// The API documents the worker id as a *unique* identifier for Redis consumer
|
|
247
293
|
// groups, so the fallback must be unique even when several pollers share a
|