feat(base,learn,todo): the operator's assistants, and the instance's privacy page (ADR 0021, step 2)
The server half of the assistants (points 4 to 8, D27 to D46): the operator sets language models in deploy/assistants.env, grants them to people with limits, and the module forwards their questions with the operator's key, counting what each used, never what was asked. - assistantsFrom: ASSISTANTS, ASSISTANT_ID_KEY, ASSISTANT_<ID>_NAME, _PROTOCOL (anthropic, openai, openai-responses), _BASE_URL, _MODEL, _KEY, _IMAGES, _PRICE_INPUT and _PRICE_OUTPUT (per million tokens), ASSISTANT_CURRENCY, ASSISTANT_OWN_KEYS; anything unusable stops the server as it starts, naming the variable. - The assistant endpoint (identified): offered, agree (D40), ask as a Serverpod stream (D35): the text as the model writes it, then the whole turn, sent once the request is counted; figures, the caller's own. Checked in order: at most 2 questions on their way per person (tooManyAtOnce), the grant, the agreement, limits in the pricing's unit now (limitOutdated), the month's and the day's limits (with when they reset, UTC), the question (malformed, imagesNotRead, tooLarge past 400,000 characters, an image over 3,932,160 bytes or more than 20 images); output capped at 16,384 tokens. Each request carries the person's opaque ID (HMAC-SHA256 under ASSISTANT_ID_KEY, D30). Once sent, the provider's reply is read to its end even if the app cancels, and counted on a session of its own; a provider's failure is logged by kind and status, told as providerKey, providerBusy (with its wait), providerRefused or providerFailed. - The assistantOperator endpoint (identified and operator, on the register): setUp, grants, grant (assistantNotSet, invalidLimit, notFound), revoke, figures of a UTC month. - Tables assistant_grant and assistant_figures (per person, assistant and UTC day), in the module's, Learn's and Todo's migrations. The daily pruning keeps this month and the two before (forgetOldAssistantFigures, D41); deletePerson deletes both. A member offers no assistant (D43). - instance.basics() gains assistantOwnKeys. - /privacy (D39, addPrivacyPageRoute, on the register's web server, before the profile pages' route): made from the instance's settings, English or German, no JavaScript: who may sign up, where the data and backups are, what the module keeps (the account, sessions, IP addresses, the server's log), the host's privacyPagePoints (Learn's: studysets synced, private ones encrypted on the devices with what stays readable, what is published, dictionary lookups, the learner count), each assistant with its model and host, what goes and what is counted, and whether personal keys are allowed. Never a key. Tests: 70 on the assistants (grants, limits, refusals in order, streaming, cancelling, counting, concurrency, the operator's denials, deletion, pruning), 19 on the settings, 8 on the privacy page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
038aca5439
commit
dbae802915
90 changed files with 56851 additions and 33 deletions
|
|
@ -0,0 +1,150 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:halkyon_base_client/src/protocol/protocol.dart' as _iwgbpyo5;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import '../assistant/assistant_message.dart' as _irryv85c;
|
||||
import '../assistant/assistant_stop.dart' as _is7w56fp;
|
||||
|
||||
/// A piece of an assistant's answer, as it streams (Halkyon Learn's ADR
|
||||
/// 0021, D35): text as the model writes it, then the whole turn.
|
||||
abstract class AssistantAnswer
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantAnswer._({
|
||||
this.delta,
|
||||
this.message,
|
||||
this.stop,
|
||||
this.inputTokens,
|
||||
this.outputTokens,
|
||||
});
|
||||
|
||||
factory AssistantAnswer({
|
||||
String? delta,
|
||||
_irryv85c.AssistantMessage? message,
|
||||
_is7w56fp.AssistantStop? stop,
|
||||
int? inputTokens,
|
||||
int? outputTokens,
|
||||
}) = _AssistantAnswerImpl;
|
||||
|
||||
factory AssistantAnswer.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return AssistantAnswer(
|
||||
delta: jsonSerialization['delta'] as String?,
|
||||
message: jsonSerialization['message'] == null
|
||||
? null
|
||||
: _iwgbpyo5.Protocol().deserialize<_irryv85c.AssistantMessage>(
|
||||
jsonSerialization['message'],
|
||||
),
|
||||
stop: jsonSerialization['stop'] == null
|
||||
? null
|
||||
: _is7w56fp.AssistantStop.fromJson(
|
||||
(jsonSerialization['stop'] as String),
|
||||
),
|
||||
inputTokens: jsonSerialization['inputTokens'] as int?,
|
||||
outputTokens: jsonSerialization['outputTokens'] as int?,
|
||||
);
|
||||
}
|
||||
|
||||
/// More of the text; null in the last piece.
|
||||
String? delta;
|
||||
|
||||
/// The model's whole turn, to be sent back with the next question; only
|
||||
/// in the last piece.
|
||||
_irryv85c.AssistantMessage? message;
|
||||
|
||||
/// Why it stopped; only in the last piece.
|
||||
_is7w56fp.AssistantStop? stop;
|
||||
|
||||
/// The input tokens counted; only in the last piece.
|
||||
int? inputTokens;
|
||||
|
||||
/// The output tokens counted; only in the last piece.
|
||||
int? outputTokens;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantAnswer]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantAnswer copyWith({
|
||||
String? delta,
|
||||
_irryv85c.AssistantMessage? message,
|
||||
_is7w56fp.AssistantStop? stop,
|
||||
int? inputTokens,
|
||||
int? outputTokens,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantAnswer',
|
||||
if (delta != null) 'delta': delta,
|
||||
if (message != null) 'message': message?.toJson(),
|
||||
if (stop != null) 'stop': stop?.toJson(),
|
||||
if (inputTokens != null) 'inputTokens': inputTokens,
|
||||
if (outputTokens != null) 'outputTokens': outputTokens,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantAnswer',
|
||||
if (delta != null) 'delta': delta,
|
||||
if (message != null) 'message': message?.toJsonForProtocol(),
|
||||
if (stop != null) 'stop': stop?.toJson(),
|
||||
if (inputTokens != null) 'inputTokens': inputTokens,
|
||||
if (outputTokens != null) 'outputTokens': outputTokens,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _AssistantAnswerImpl extends AssistantAnswer {
|
||||
_AssistantAnswerImpl({
|
||||
String? delta,
|
||||
_irryv85c.AssistantMessage? message,
|
||||
_is7w56fp.AssistantStop? stop,
|
||||
int? inputTokens,
|
||||
int? outputTokens,
|
||||
}) : super._(
|
||||
delta: delta,
|
||||
message: message,
|
||||
stop: stop,
|
||||
inputTokens: inputTokens,
|
||||
outputTokens: outputTokens,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantAnswer]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantAnswer copyWith({
|
||||
Object? delta = _Undefined,
|
||||
Object? message = _Undefined,
|
||||
Object? stop = _Undefined,
|
||||
Object? inputTokens = _Undefined,
|
||||
Object? outputTokens = _Undefined,
|
||||
}) {
|
||||
return AssistantAnswer(
|
||||
delta: delta is String? ? delta : this.delta,
|
||||
message: message is _irryv85c.AssistantMessage?
|
||||
? message
|
||||
: this.message?.copyWith(),
|
||||
stop: stop is _is7w56fp.AssistantStop? ? stop : this.stop,
|
||||
inputTokens: inputTokens is int? ? inputTokens : this.inputTokens,
|
||||
outputTokens: outputTokens is int? ? outputTokens : this.outputTokens,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import '../assistant/assistant_limit_unit.dart' as _il94nvme;
|
||||
|
||||
/// A grant as the operator sees it (Halkyon Learn's ADR 0021, point 6).
|
||||
abstract class AssistantGrantOverview
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantGrantOverview._({
|
||||
required this.account,
|
||||
this.handle,
|
||||
required this.assistant,
|
||||
required this.assistantSet,
|
||||
required this.grantedAt,
|
||||
required this.limitUnit,
|
||||
this.dailyLimit,
|
||||
this.monthlyLimit,
|
||||
this.agreedAt,
|
||||
required this.outdated,
|
||||
});
|
||||
|
||||
factory AssistantGrantOverview({
|
||||
required _isc.UuidValue account,
|
||||
String? handle,
|
||||
required String assistant,
|
||||
required bool assistantSet,
|
||||
required DateTime grantedAt,
|
||||
required _il94nvme.AssistantLimitUnit limitUnit,
|
||||
int? dailyLimit,
|
||||
int? monthlyLimit,
|
||||
DateTime? agreedAt,
|
||||
required bool outdated,
|
||||
}) = _AssistantGrantOverviewImpl;
|
||||
|
||||
factory AssistantGrantOverview.fromJson(
|
||||
Map<String, dynamic> jsonSerialization,
|
||||
) {
|
||||
return AssistantGrantOverview(
|
||||
account: _isc.UuidValueJsonExtension.fromJson(
|
||||
jsonSerialization['account'],
|
||||
),
|
||||
handle: jsonSerialization['handle'] as String?,
|
||||
assistant: jsonSerialization['assistant'] as String,
|
||||
assistantSet: _isc.BoolJsonExtension.fromJson(
|
||||
jsonSerialization['assistantSet'],
|
||||
),
|
||||
grantedAt: _isc.DateTimeJsonExtension.fromJson(
|
||||
jsonSerialization['grantedAt'],
|
||||
),
|
||||
limitUnit: _il94nvme.AssistantLimitUnit.fromJson(
|
||||
(jsonSerialization['limitUnit'] as String),
|
||||
),
|
||||
dailyLimit: jsonSerialization['dailyLimit'] as int?,
|
||||
monthlyLimit: jsonSerialization['monthlyLimit'] as int?,
|
||||
agreedAt: jsonSerialization['agreedAt'] == null
|
||||
? null
|
||||
: _isc.DateTimeJsonExtension.fromJson(jsonSerialization['agreedAt']),
|
||||
outdated: _isc.BoolJsonExtension.fromJson(jsonSerialization['outdated']),
|
||||
);
|
||||
}
|
||||
|
||||
/// The person's account.
|
||||
_isc.UuidValue account;
|
||||
|
||||
/// Their handle; null for an account without one.
|
||||
String? handle;
|
||||
|
||||
/// The assistant's ID.
|
||||
String assistant;
|
||||
|
||||
/// Whether the instance still sets that assistant (D44).
|
||||
bool assistantSet;
|
||||
|
||||
/// When it was granted, or its limits last changed.
|
||||
DateTime grantedAt;
|
||||
|
||||
/// What its limits count.
|
||||
_il94nvme.AssistantLimitUnit limitUnit;
|
||||
|
||||
/// The most a UTC day may use; null for none.
|
||||
int? dailyLimit;
|
||||
|
||||
/// The most a UTC month may use; null for none.
|
||||
int? monthlyLimit;
|
||||
|
||||
/// When the person agreed to the assistant's provider as it is now;
|
||||
/// null until they have.
|
||||
DateTime? agreedAt;
|
||||
|
||||
/// Whether the limits count what the assistant counts no more, as its
|
||||
/// prices came or went.
|
||||
bool outdated;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantGrantOverview]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantGrantOverview copyWith({
|
||||
_isc.UuidValue? account,
|
||||
String? handle,
|
||||
String? assistant,
|
||||
bool? assistantSet,
|
||||
DateTime? grantedAt,
|
||||
_il94nvme.AssistantLimitUnit? limitUnit,
|
||||
int? dailyLimit,
|
||||
int? monthlyLimit,
|
||||
DateTime? agreedAt,
|
||||
bool? outdated,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantGrantOverview',
|
||||
'account': account.toJson(),
|
||||
if (handle != null) 'handle': handle,
|
||||
'assistant': assistant,
|
||||
'assistantSet': assistantSet,
|
||||
'grantedAt': grantedAt.toJson(),
|
||||
'limitUnit': limitUnit.toJson(),
|
||||
if (dailyLimit != null) 'dailyLimit': dailyLimit,
|
||||
if (monthlyLimit != null) 'monthlyLimit': monthlyLimit,
|
||||
if (agreedAt != null) 'agreedAt': agreedAt?.toJson(),
|
||||
'outdated': outdated,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantGrantOverview',
|
||||
'account': account.toJson(),
|
||||
if (handle != null) 'handle': handle,
|
||||
'assistant': assistant,
|
||||
'assistantSet': assistantSet,
|
||||
'grantedAt': grantedAt.toJson(),
|
||||
'limitUnit': limitUnit.toJson(),
|
||||
if (dailyLimit != null) 'dailyLimit': dailyLimit,
|
||||
if (monthlyLimit != null) 'monthlyLimit': monthlyLimit,
|
||||
if (agreedAt != null) 'agreedAt': agreedAt?.toJson(),
|
||||
'outdated': outdated,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _AssistantGrantOverviewImpl extends AssistantGrantOverview {
|
||||
_AssistantGrantOverviewImpl({
|
||||
required _isc.UuidValue account,
|
||||
String? handle,
|
||||
required String assistant,
|
||||
required bool assistantSet,
|
||||
required DateTime grantedAt,
|
||||
required _il94nvme.AssistantLimitUnit limitUnit,
|
||||
int? dailyLimit,
|
||||
int? monthlyLimit,
|
||||
DateTime? agreedAt,
|
||||
required bool outdated,
|
||||
}) : super._(
|
||||
account: account,
|
||||
handle: handle,
|
||||
assistant: assistant,
|
||||
assistantSet: assistantSet,
|
||||
grantedAt: grantedAt,
|
||||
limitUnit: limitUnit,
|
||||
dailyLimit: dailyLimit,
|
||||
monthlyLimit: monthlyLimit,
|
||||
agreedAt: agreedAt,
|
||||
outdated: outdated,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantGrantOverview]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantGrantOverview copyWith({
|
||||
_isc.UuidValue? account,
|
||||
Object? handle = _Undefined,
|
||||
String? assistant,
|
||||
bool? assistantSet,
|
||||
DateTime? grantedAt,
|
||||
_il94nvme.AssistantLimitUnit? limitUnit,
|
||||
Object? dailyLimit = _Undefined,
|
||||
Object? monthlyLimit = _Undefined,
|
||||
Object? agreedAt = _Undefined,
|
||||
bool? outdated,
|
||||
}) {
|
||||
return AssistantGrantOverview(
|
||||
account: account ?? this.account,
|
||||
handle: handle is String? ? handle : this.handle,
|
||||
assistant: assistant ?? this.assistant,
|
||||
assistantSet: assistantSet ?? this.assistantSet,
|
||||
grantedAt: grantedAt ?? this.grantedAt,
|
||||
limitUnit: limitUnit ?? this.limitUnit,
|
||||
dailyLimit: dailyLimit is int? ? dailyLimit : this.dailyLimit,
|
||||
monthlyLimit: monthlyLimit is int? ? monthlyLimit : this.monthlyLimit,
|
||||
agreedAt: agreedAt is DateTime? ? agreedAt : this.agreedAt,
|
||||
outdated: outdated ?? this.outdated,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// An assistant as the operator set it (Halkyon Learn's ADR 0021, point
|
||||
/// 4), without its key: what their screen of grants shows.
|
||||
abstract class AssistantInfo
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantInfo._({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.protocol,
|
||||
required this.host,
|
||||
required this.model,
|
||||
required this.images,
|
||||
this.priceInput,
|
||||
this.priceOutput,
|
||||
});
|
||||
|
||||
factory AssistantInfo({
|
||||
required String id,
|
||||
required String name,
|
||||
required String protocol,
|
||||
required String host,
|
||||
required String model,
|
||||
required bool images,
|
||||
double? priceInput,
|
||||
double? priceOutput,
|
||||
}) = _AssistantInfoImpl;
|
||||
|
||||
factory AssistantInfo.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return AssistantInfo(
|
||||
id: jsonSerialization['id'] as String,
|
||||
name: jsonSerialization['name'] as String,
|
||||
protocol: jsonSerialization['protocol'] as String,
|
||||
host: jsonSerialization['host'] as String,
|
||||
model: jsonSerialization['model'] as String,
|
||||
images: _isc.BoolJsonExtension.fromJson(jsonSerialization['images']),
|
||||
priceInput: (jsonSerialization['priceInput'] as num?)?.toDouble(),
|
||||
priceOutput: (jsonSerialization['priceOutput'] as num?)?.toDouble(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Its ID.
|
||||
String id;
|
||||
|
||||
/// The name people see.
|
||||
String name;
|
||||
|
||||
/// Its protocol.
|
||||
String protocol;
|
||||
|
||||
/// The provider's host.
|
||||
String host;
|
||||
|
||||
/// The model.
|
||||
String model;
|
||||
|
||||
/// Whether it reads images.
|
||||
bool images;
|
||||
|
||||
/// Its price per million input tokens; null where it has none, so its
|
||||
/// limits count tokens.
|
||||
double? priceInput;
|
||||
|
||||
/// Its price per million output tokens.
|
||||
double? priceOutput;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantInfo]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantInfo copyWith({
|
||||
String? id,
|
||||
String? name,
|
||||
String? protocol,
|
||||
String? host,
|
||||
String? model,
|
||||
bool? images,
|
||||
double? priceInput,
|
||||
double? priceOutput,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantInfo',
|
||||
'id': id,
|
||||
'name': name,
|
||||
'protocol': protocol,
|
||||
'host': host,
|
||||
'model': model,
|
||||
'images': images,
|
||||
if (priceInput != null) 'priceInput': priceInput,
|
||||
if (priceOutput != null) 'priceOutput': priceOutput,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantInfo',
|
||||
'id': id,
|
||||
'name': name,
|
||||
'protocol': protocol,
|
||||
'host': host,
|
||||
'model': model,
|
||||
'images': images,
|
||||
if (priceInput != null) 'priceInput': priceInput,
|
||||
if (priceOutput != null) 'priceOutput': priceOutput,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _AssistantInfoImpl extends AssistantInfo {
|
||||
_AssistantInfoImpl({
|
||||
required String id,
|
||||
required String name,
|
||||
required String protocol,
|
||||
required String host,
|
||||
required String model,
|
||||
required bool images,
|
||||
double? priceInput,
|
||||
double? priceOutput,
|
||||
}) : super._(
|
||||
id: id,
|
||||
name: name,
|
||||
protocol: protocol,
|
||||
host: host,
|
||||
model: model,
|
||||
images: images,
|
||||
priceInput: priceInput,
|
||||
priceOutput: priceOutput,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantInfo]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantInfo copyWith({
|
||||
String? id,
|
||||
String? name,
|
||||
String? protocol,
|
||||
String? host,
|
||||
String? model,
|
||||
bool? images,
|
||||
Object? priceInput = _Undefined,
|
||||
Object? priceOutput = _Undefined,
|
||||
}) {
|
||||
return AssistantInfo(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
protocol: protocol ?? this.protocol,
|
||||
host: host ?? this.host,
|
||||
model: model ?? this.model,
|
||||
images: images ?? this.images,
|
||||
priceInput: priceInput is double? ? priceInput : this.priceInput,
|
||||
priceOutput: priceOutput is double? ? priceOutput : this.priceOutput,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// What a grant's limits count (Halkyon Learn's ADR 0021, point 8).
|
||||
enum AssistantLimitUnit implements _isc.SerializableModel {
|
||||
/// The cost, in millionths of the instance's currency, at the prices
|
||||
/// the operator set.
|
||||
costMicros,
|
||||
|
||||
/// Input and output tokens together, where the operator set no prices.
|
||||
tokens;
|
||||
|
||||
static AssistantLimitUnit fromJson(String name) {
|
||||
switch (name) {
|
||||
case 'costMicros':
|
||||
return AssistantLimitUnit.costMicros;
|
||||
case 'tokens':
|
||||
return AssistantLimitUnit.tokens;
|
||||
default:
|
||||
throw ArgumentError(
|
||||
'Value "$name" cannot be converted to "AssistantLimitUnit"',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson() => name;
|
||||
|
||||
@override
|
||||
String toString() => name;
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:halkyon_base_client/src/protocol/protocol.dart' as _iwgbpyo5;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import '../assistant/assistant_part.dart' as _ijm4wwsu;
|
||||
import '../assistant/assistant_role.dart' as _i5olt3ik;
|
||||
|
||||
/// A turn of a conversation with an assistant.
|
||||
abstract class AssistantMessage
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantMessage._({
|
||||
required this.role,
|
||||
required this.parts,
|
||||
});
|
||||
|
||||
factory AssistantMessage({
|
||||
required _i5olt3ik.AssistantRole role,
|
||||
required List<_ijm4wwsu.AssistantPart> parts,
|
||||
}) = _AssistantMessageImpl;
|
||||
|
||||
factory AssistantMessage.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return AssistantMessage(
|
||||
role: _i5olt3ik.AssistantRole.fromJson(
|
||||
(jsonSerialization['role'] as String),
|
||||
),
|
||||
parts: _iwgbpyo5.Protocol().deserialize<List<_ijm4wwsu.AssistantPart>>(
|
||||
jsonSerialization['parts'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Who said it.
|
||||
_i5olt3ik.AssistantRole role;
|
||||
|
||||
/// What it holds, in order.
|
||||
List<_ijm4wwsu.AssistantPart> parts;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantMessage]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantMessage copyWith({
|
||||
_i5olt3ik.AssistantRole? role,
|
||||
List<_ijm4wwsu.AssistantPart>? parts,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantMessage',
|
||||
'role': role.toJson(),
|
||||
'parts': parts.toJson(valueToJson: (v) => v.toJson()),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantMessage',
|
||||
'role': role.toJson(),
|
||||
'parts': parts.toJson(valueToJson: (v) => v.toJsonForProtocol()),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _AssistantMessageImpl extends AssistantMessage {
|
||||
_AssistantMessageImpl({
|
||||
required _i5olt3ik.AssistantRole role,
|
||||
required List<_ijm4wwsu.AssistantPart> parts,
|
||||
}) : super._(
|
||||
role: role,
|
||||
parts: parts,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantMessage]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantMessage copyWith({
|
||||
_i5olt3ik.AssistantRole? role,
|
||||
List<_ijm4wwsu.AssistantPart>? parts,
|
||||
}) {
|
||||
return AssistantMessage(
|
||||
role: role ?? this.role,
|
||||
parts: parts ?? this.parts.map((e0) => e0.copyWith()).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// What one person used of one assistant in one UTC month (Halkyon
|
||||
/// Learn's ADR 0021, D3 and point 8): the operator sees everyone's, a
|
||||
/// person their own; never what was asked.
|
||||
abstract class AssistantMonthFigures
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantMonthFigures._({
|
||||
required this.account,
|
||||
this.handle,
|
||||
required this.assistant,
|
||||
required this.month,
|
||||
required this.requests,
|
||||
required this.inputTokens,
|
||||
required this.outputTokens,
|
||||
required this.costMicros,
|
||||
});
|
||||
|
||||
factory AssistantMonthFigures({
|
||||
required _isc.UuidValue account,
|
||||
String? handle,
|
||||
required String assistant,
|
||||
required DateTime month,
|
||||
required int requests,
|
||||
required int inputTokens,
|
||||
required int outputTokens,
|
||||
required int costMicros,
|
||||
}) = _AssistantMonthFiguresImpl;
|
||||
|
||||
factory AssistantMonthFigures.fromJson(
|
||||
Map<String, dynamic> jsonSerialization,
|
||||
) {
|
||||
return AssistantMonthFigures(
|
||||
account: _isc.UuidValueJsonExtension.fromJson(
|
||||
jsonSerialization['account'],
|
||||
),
|
||||
handle: jsonSerialization['handle'] as String?,
|
||||
assistant: jsonSerialization['assistant'] as String,
|
||||
month: _isc.DateTimeJsonExtension.fromJson(jsonSerialization['month']),
|
||||
requests: jsonSerialization['requests'] as int,
|
||||
inputTokens: jsonSerialization['inputTokens'] as int,
|
||||
outputTokens: jsonSerialization['outputTokens'] as int,
|
||||
costMicros: jsonSerialization['costMicros'] as int,
|
||||
);
|
||||
}
|
||||
|
||||
/// The person's account.
|
||||
_isc.UuidValue account;
|
||||
|
||||
/// Their handle; null for an account without one, or in a person's own.
|
||||
String? handle;
|
||||
|
||||
/// The assistant's ID.
|
||||
String assistant;
|
||||
|
||||
/// The month, at midnight UTC of its first day.
|
||||
DateTime month;
|
||||
|
||||
/// The requests forwarded.
|
||||
int requests;
|
||||
|
||||
/// The input tokens counted.
|
||||
int inputTokens;
|
||||
|
||||
/// The output tokens counted.
|
||||
int outputTokens;
|
||||
|
||||
/// What they cost, in millionths of the currency; 0 for an assistant
|
||||
/// without prices.
|
||||
int costMicros;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantMonthFigures]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantMonthFigures copyWith({
|
||||
_isc.UuidValue? account,
|
||||
String? handle,
|
||||
String? assistant,
|
||||
DateTime? month,
|
||||
int? requests,
|
||||
int? inputTokens,
|
||||
int? outputTokens,
|
||||
int? costMicros,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantMonthFigures',
|
||||
'account': account.toJson(),
|
||||
if (handle != null) 'handle': handle,
|
||||
'assistant': assistant,
|
||||
'month': month.toJson(),
|
||||
'requests': requests,
|
||||
'inputTokens': inputTokens,
|
||||
'outputTokens': outputTokens,
|
||||
'costMicros': costMicros,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantMonthFigures',
|
||||
'account': account.toJson(),
|
||||
if (handle != null) 'handle': handle,
|
||||
'assistant': assistant,
|
||||
'month': month.toJson(),
|
||||
'requests': requests,
|
||||
'inputTokens': inputTokens,
|
||||
'outputTokens': outputTokens,
|
||||
'costMicros': costMicros,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _AssistantMonthFiguresImpl extends AssistantMonthFigures {
|
||||
_AssistantMonthFiguresImpl({
|
||||
required _isc.UuidValue account,
|
||||
String? handle,
|
||||
required String assistant,
|
||||
required DateTime month,
|
||||
required int requests,
|
||||
required int inputTokens,
|
||||
required int outputTokens,
|
||||
required int costMicros,
|
||||
}) : super._(
|
||||
account: account,
|
||||
handle: handle,
|
||||
assistant: assistant,
|
||||
month: month,
|
||||
requests: requests,
|
||||
inputTokens: inputTokens,
|
||||
outputTokens: outputTokens,
|
||||
costMicros: costMicros,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantMonthFigures]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantMonthFigures copyWith({
|
||||
_isc.UuidValue? account,
|
||||
Object? handle = _Undefined,
|
||||
String? assistant,
|
||||
DateTime? month,
|
||||
int? requests,
|
||||
int? inputTokens,
|
||||
int? outputTokens,
|
||||
int? costMicros,
|
||||
}) {
|
||||
return AssistantMonthFigures(
|
||||
account: account ?? this.account,
|
||||
handle: handle is String? ? handle : this.handle,
|
||||
assistant: assistant ?? this.assistant,
|
||||
month: month ?? this.month,
|
||||
requests: requests ?? this.requests,
|
||||
inputTokens: inputTokens ?? this.inputTokens,
|
||||
outputTokens: outputTokens ?? this.outputTokens,
|
||||
costMicros: costMicros ?? this.costMicros,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import '../assistant/assistant_limit_unit.dart' as _il94nvme;
|
||||
|
||||
/// An assistant granted to the person who asks (Halkyon Learn's ADR 0021,
|
||||
/// point 6 and D27): what it is, what goes where, and how much is left.
|
||||
abstract class AssistantOffer
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantOffer._({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.protocol,
|
||||
required this.host,
|
||||
required this.model,
|
||||
required this.images,
|
||||
this.agreedAt,
|
||||
required this.limitUnit,
|
||||
this.dailyLimit,
|
||||
this.monthlyLimit,
|
||||
required this.usedToday,
|
||||
required this.usedThisMonth,
|
||||
required this.outdated,
|
||||
});
|
||||
|
||||
factory AssistantOffer({
|
||||
required String id,
|
||||
required String name,
|
||||
required String protocol,
|
||||
required String host,
|
||||
required String model,
|
||||
required bool images,
|
||||
DateTime? agreedAt,
|
||||
required _il94nvme.AssistantLimitUnit limitUnit,
|
||||
int? dailyLimit,
|
||||
int? monthlyLimit,
|
||||
required int usedToday,
|
||||
required int usedThisMonth,
|
||||
required bool outdated,
|
||||
}) = _AssistantOfferImpl;
|
||||
|
||||
factory AssistantOffer.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return AssistantOffer(
|
||||
id: jsonSerialization['id'] as String,
|
||||
name: jsonSerialization['name'] as String,
|
||||
protocol: jsonSerialization['protocol'] as String,
|
||||
host: jsonSerialization['host'] as String,
|
||||
model: jsonSerialization['model'] as String,
|
||||
images: _isc.BoolJsonExtension.fromJson(jsonSerialization['images']),
|
||||
agreedAt: jsonSerialization['agreedAt'] == null
|
||||
? null
|
||||
: _isc.DateTimeJsonExtension.fromJson(jsonSerialization['agreedAt']),
|
||||
limitUnit: _il94nvme.AssistantLimitUnit.fromJson(
|
||||
(jsonSerialization['limitUnit'] as String),
|
||||
),
|
||||
dailyLimit: jsonSerialization['dailyLimit'] as int?,
|
||||
monthlyLimit: jsonSerialization['monthlyLimit'] as int?,
|
||||
usedToday: jsonSerialization['usedToday'] as int,
|
||||
usedThisMonth: jsonSerialization['usedThisMonth'] as int,
|
||||
outdated: _isc.BoolJsonExtension.fromJson(jsonSerialization['outdated']),
|
||||
);
|
||||
}
|
||||
|
||||
/// Its ID, which a question names.
|
||||
String id;
|
||||
|
||||
/// The name people see.
|
||||
String name;
|
||||
|
||||
/// Its protocol (`anthropic`, `openai`, `openai-responses`).
|
||||
String protocol;
|
||||
|
||||
/// The provider's host, where what is asked goes (`api.anthropic.com`).
|
||||
String host;
|
||||
|
||||
/// The model.
|
||||
String model;
|
||||
|
||||
/// Whether it reads images (D12).
|
||||
bool images;
|
||||
|
||||
/// When the person agreed; null until they have, or since it moved to
|
||||
/// another provider: then they are asked first (D40).
|
||||
DateTime? agreedAt;
|
||||
|
||||
/// What its limits count.
|
||||
_il94nvme.AssistantLimitUnit limitUnit;
|
||||
|
||||
/// The most a UTC day may use; null for none.
|
||||
int? dailyLimit;
|
||||
|
||||
/// The most a UTC month may use; null for none.
|
||||
int? monthlyLimit;
|
||||
|
||||
/// What this UTC day used so far, in [limitUnit].
|
||||
int usedToday;
|
||||
|
||||
/// What this UTC month used so far, in [limitUnit].
|
||||
int usedThisMonth;
|
||||
|
||||
/// Whether the grant holds no more until the operator sets its limits
|
||||
/// again, as the assistant's prices came or went.
|
||||
bool outdated;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantOffer]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantOffer copyWith({
|
||||
String? id,
|
||||
String? name,
|
||||
String? protocol,
|
||||
String? host,
|
||||
String? model,
|
||||
bool? images,
|
||||
DateTime? agreedAt,
|
||||
_il94nvme.AssistantLimitUnit? limitUnit,
|
||||
int? dailyLimit,
|
||||
int? monthlyLimit,
|
||||
int? usedToday,
|
||||
int? usedThisMonth,
|
||||
bool? outdated,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantOffer',
|
||||
'id': id,
|
||||
'name': name,
|
||||
'protocol': protocol,
|
||||
'host': host,
|
||||
'model': model,
|
||||
'images': images,
|
||||
if (agreedAt != null) 'agreedAt': agreedAt?.toJson(),
|
||||
'limitUnit': limitUnit.toJson(),
|
||||
if (dailyLimit != null) 'dailyLimit': dailyLimit,
|
||||
if (monthlyLimit != null) 'monthlyLimit': monthlyLimit,
|
||||
'usedToday': usedToday,
|
||||
'usedThisMonth': usedThisMonth,
|
||||
'outdated': outdated,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantOffer',
|
||||
'id': id,
|
||||
'name': name,
|
||||
'protocol': protocol,
|
||||
'host': host,
|
||||
'model': model,
|
||||
'images': images,
|
||||
if (agreedAt != null) 'agreedAt': agreedAt?.toJson(),
|
||||
'limitUnit': limitUnit.toJson(),
|
||||
if (dailyLimit != null) 'dailyLimit': dailyLimit,
|
||||
if (monthlyLimit != null) 'monthlyLimit': monthlyLimit,
|
||||
'usedToday': usedToday,
|
||||
'usedThisMonth': usedThisMonth,
|
||||
'outdated': outdated,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _AssistantOfferImpl extends AssistantOffer {
|
||||
_AssistantOfferImpl({
|
||||
required String id,
|
||||
required String name,
|
||||
required String protocol,
|
||||
required String host,
|
||||
required String model,
|
||||
required bool images,
|
||||
DateTime? agreedAt,
|
||||
required _il94nvme.AssistantLimitUnit limitUnit,
|
||||
int? dailyLimit,
|
||||
int? monthlyLimit,
|
||||
required int usedToday,
|
||||
required int usedThisMonth,
|
||||
required bool outdated,
|
||||
}) : super._(
|
||||
id: id,
|
||||
name: name,
|
||||
protocol: protocol,
|
||||
host: host,
|
||||
model: model,
|
||||
images: images,
|
||||
agreedAt: agreedAt,
|
||||
limitUnit: limitUnit,
|
||||
dailyLimit: dailyLimit,
|
||||
monthlyLimit: monthlyLimit,
|
||||
usedToday: usedToday,
|
||||
usedThisMonth: usedThisMonth,
|
||||
outdated: outdated,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantOffer]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantOffer copyWith({
|
||||
String? id,
|
||||
String? name,
|
||||
String? protocol,
|
||||
String? host,
|
||||
String? model,
|
||||
bool? images,
|
||||
Object? agreedAt = _Undefined,
|
||||
_il94nvme.AssistantLimitUnit? limitUnit,
|
||||
Object? dailyLimit = _Undefined,
|
||||
Object? monthlyLimit = _Undefined,
|
||||
int? usedToday,
|
||||
int? usedThisMonth,
|
||||
bool? outdated,
|
||||
}) {
|
||||
return AssistantOffer(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
protocol: protocol ?? this.protocol,
|
||||
host: host ?? this.host,
|
||||
model: model ?? this.model,
|
||||
images: images ?? this.images,
|
||||
agreedAt: agreedAt is DateTime? ? agreedAt : this.agreedAt,
|
||||
limitUnit: limitUnit ?? this.limitUnit,
|
||||
dailyLimit: dailyLimit is int? ? dailyLimit : this.dailyLimit,
|
||||
monthlyLimit: monthlyLimit is int? ? monthlyLimit : this.monthlyLimit,
|
||||
usedToday: usedToday ?? this.usedToday,
|
||||
usedThisMonth: usedThisMonth ?? this.usedThisMonth,
|
||||
outdated: outdated ?? this.outdated,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:typed_data' as _idt;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import '../assistant/assistant_part_kind.dart' as _i3armmew;
|
||||
|
||||
/// A part of a turn: one class for every kind, so a turn is a plain list.
|
||||
abstract class AssistantPart
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantPart._({
|
||||
required this.kind,
|
||||
this.text,
|
||||
this.mediaType,
|
||||
this.bytes,
|
||||
this.callId,
|
||||
this.name,
|
||||
this.json,
|
||||
this.extra,
|
||||
this.isError,
|
||||
this.protocol,
|
||||
});
|
||||
|
||||
factory AssistantPart({
|
||||
required _i3armmew.AssistantPartKind kind,
|
||||
String? text,
|
||||
String? mediaType,
|
||||
_idt.ByteData? bytes,
|
||||
String? callId,
|
||||
String? name,
|
||||
String? json,
|
||||
String? extra,
|
||||
bool? isError,
|
||||
String? protocol,
|
||||
}) = _AssistantPartImpl;
|
||||
|
||||
factory AssistantPart.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return AssistantPart(
|
||||
kind: _i3armmew.AssistantPartKind.fromJson(
|
||||
(jsonSerialization['kind'] as String),
|
||||
),
|
||||
text: jsonSerialization['text'] as String?,
|
||||
mediaType: jsonSerialization['mediaType'] as String?,
|
||||
bytes: jsonSerialization['bytes'] == null
|
||||
? null
|
||||
: _isc.ByteDataJsonExtension.fromJson(jsonSerialization['bytes']),
|
||||
callId: jsonSerialization['callId'] as String?,
|
||||
name: jsonSerialization['name'] as String?,
|
||||
json: jsonSerialization['json'] as String?,
|
||||
extra: jsonSerialization['extra'] as String?,
|
||||
isError: jsonSerialization['isError'] == null
|
||||
? null
|
||||
: _isc.BoolJsonExtension.fromJson(jsonSerialization['isError']),
|
||||
protocol: jsonSerialization['protocol'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
/// What it is, and so which fields it has.
|
||||
_i3armmew.AssistantPartKind kind;
|
||||
|
||||
/// A text's text, or a tool's result.
|
||||
String? text;
|
||||
|
||||
/// An image's type (`image/png`).
|
||||
String? mediaType;
|
||||
|
||||
/// An image's bytes.
|
||||
_idt.ByteData? bytes;
|
||||
|
||||
/// A tool call's ID, or the call a result answers.
|
||||
String? callId;
|
||||
|
||||
/// A tool call's tool.
|
||||
String? name;
|
||||
|
||||
/// A tool call's input, or a provider's block, as JSON.
|
||||
String? json;
|
||||
|
||||
/// What the provider wants back with a text of the model's or a tool
|
||||
/// call, as JSON; null for nothing.
|
||||
String? extra;
|
||||
|
||||
/// Whether a tool's result says it failed.
|
||||
bool? isError;
|
||||
|
||||
/// A provider's block's protocol.
|
||||
String? protocol;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantPart]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantPart copyWith({
|
||||
_i3armmew.AssistantPartKind? kind,
|
||||
String? text,
|
||||
String? mediaType,
|
||||
_idt.ByteData? bytes,
|
||||
String? callId,
|
||||
String? name,
|
||||
String? json,
|
||||
String? extra,
|
||||
bool? isError,
|
||||
String? protocol,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantPart',
|
||||
'kind': kind.toJson(),
|
||||
if (text != null) 'text': text,
|
||||
if (mediaType != null) 'mediaType': mediaType,
|
||||
if (bytes != null) 'bytes': bytes?.toJson(),
|
||||
if (callId != null) 'callId': callId,
|
||||
if (name != null) 'name': name,
|
||||
if (json != null) 'json': json,
|
||||
if (extra != null) 'extra': extra,
|
||||
if (isError != null) 'isError': isError,
|
||||
if (protocol != null) 'protocol': protocol,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantPart',
|
||||
'kind': kind.toJson(),
|
||||
if (text != null) 'text': text,
|
||||
if (mediaType != null) 'mediaType': mediaType,
|
||||
if (bytes != null) 'bytes': bytes?.toJson(),
|
||||
if (callId != null) 'callId': callId,
|
||||
if (name != null) 'name': name,
|
||||
if (json != null) 'json': json,
|
||||
if (extra != null) 'extra': extra,
|
||||
if (isError != null) 'isError': isError,
|
||||
if (protocol != null) 'protocol': protocol,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _AssistantPartImpl extends AssistantPart {
|
||||
_AssistantPartImpl({
|
||||
required _i3armmew.AssistantPartKind kind,
|
||||
String? text,
|
||||
String? mediaType,
|
||||
_idt.ByteData? bytes,
|
||||
String? callId,
|
||||
String? name,
|
||||
String? json,
|
||||
String? extra,
|
||||
bool? isError,
|
||||
String? protocol,
|
||||
}) : super._(
|
||||
kind: kind,
|
||||
text: text,
|
||||
mediaType: mediaType,
|
||||
bytes: bytes,
|
||||
callId: callId,
|
||||
name: name,
|
||||
json: json,
|
||||
extra: extra,
|
||||
isError: isError,
|
||||
protocol: protocol,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantPart]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantPart copyWith({
|
||||
_i3armmew.AssistantPartKind? kind,
|
||||
Object? text = _Undefined,
|
||||
Object? mediaType = _Undefined,
|
||||
Object? bytes = _Undefined,
|
||||
Object? callId = _Undefined,
|
||||
Object? name = _Undefined,
|
||||
Object? json = _Undefined,
|
||||
Object? extra = _Undefined,
|
||||
Object? isError = _Undefined,
|
||||
Object? protocol = _Undefined,
|
||||
}) {
|
||||
return AssistantPart(
|
||||
kind: kind ?? this.kind,
|
||||
text: text is String? ? text : this.text,
|
||||
mediaType: mediaType is String? ? mediaType : this.mediaType,
|
||||
bytes: bytes is _idt.ByteData? ? bytes : this.bytes?.clone(),
|
||||
callId: callId is String? ? callId : this.callId,
|
||||
name: name is String? ? name : this.name,
|
||||
json: json is String? ? json : this.json,
|
||||
extra: extra is String? ? extra : this.extra,
|
||||
isError: isError is bool? ? isError : this.isError,
|
||||
protocol: protocol is String? ? protocol : this.protocol,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// What a part of a turn is.
|
||||
enum AssistantPartKind implements _isc.SerializableModel {
|
||||
/// Text ([AssistantPart.text]; in the model's turn, what the provider
|
||||
/// wants back with it in [AssistantPart.extra]).
|
||||
text,
|
||||
|
||||
/// An image ([AssistantPart.mediaType], [AssistantPart.bytes]).
|
||||
image,
|
||||
|
||||
/// A call of a tool ([AssistantPart.callId], [AssistantPart.name], its
|
||||
/// input as JSON in [AssistantPart.json], what the provider wants back
|
||||
/// with it in [AssistantPart.extra]).
|
||||
toolCall,
|
||||
|
||||
/// A tool's result ([AssistantPart.callId], [AssistantPart.text],
|
||||
/// [AssistantPart.isError]).
|
||||
toolResult,
|
||||
|
||||
/// A block only the provider reads ([AssistantPart.protocol], the block
|
||||
/// as JSON in [AssistantPart.json]), sent back to it unchanged.
|
||||
providerBlock;
|
||||
|
||||
static AssistantPartKind fromJson(String name) {
|
||||
switch (name) {
|
||||
case 'text':
|
||||
return AssistantPartKind.text;
|
||||
case 'image':
|
||||
return AssistantPartKind.image;
|
||||
case 'toolCall':
|
||||
return AssistantPartKind.toolCall;
|
||||
case 'toolResult':
|
||||
return AssistantPartKind.toolResult;
|
||||
case 'providerBlock':
|
||||
return AssistantPartKind.providerBlock;
|
||||
default:
|
||||
throw ArgumentError(
|
||||
'Value "$name" cannot be converted to "AssistantPartKind"',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson() => name;
|
||||
|
||||
@override
|
||||
String toString() => name;
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:halkyon_base_client/src/protocol/protocol.dart' as _iwgbpyo5;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import '../assistant/assistant_message.dart' as _irryv85c;
|
||||
import '../assistant/assistant_tool.dart' as _ienotap4;
|
||||
|
||||
/// What the app asks an operator's assistant (Halkyon Learn's ADR 0021,
|
||||
/// point 7): the whole conversation each time, as the instance keeps none.
|
||||
abstract class AssistantQuestion
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantQuestion._({
|
||||
required this.assistant,
|
||||
required this.system,
|
||||
required this.messages,
|
||||
required this.tools,
|
||||
required this.maxOutputTokens,
|
||||
});
|
||||
|
||||
factory AssistantQuestion({
|
||||
required String assistant,
|
||||
required String system,
|
||||
required List<_irryv85c.AssistantMessage> messages,
|
||||
required List<_ienotap4.AssistantTool> tools,
|
||||
required int maxOutputTokens,
|
||||
}) = _AssistantQuestionImpl;
|
||||
|
||||
factory AssistantQuestion.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return AssistantQuestion(
|
||||
assistant: jsonSerialization['assistant'] as String,
|
||||
system: jsonSerialization['system'] as String,
|
||||
messages: _iwgbpyo5.Protocol()
|
||||
.deserialize<List<_irryv85c.AssistantMessage>>(
|
||||
jsonSerialization['messages'],
|
||||
),
|
||||
tools: _iwgbpyo5.Protocol().deserialize<List<_ienotap4.AssistantTool>>(
|
||||
jsonSerialization['tools'],
|
||||
),
|
||||
maxOutputTokens: jsonSerialization['maxOutputTokens'] as int,
|
||||
);
|
||||
}
|
||||
|
||||
/// The assistant's ID.
|
||||
String assistant;
|
||||
|
||||
/// What the model is told first; empty for nothing.
|
||||
String system;
|
||||
|
||||
/// The conversation, ending with the person's turn.
|
||||
List<_irryv85c.AssistantMessage> messages;
|
||||
|
||||
/// The tools it may call.
|
||||
List<_ienotap4.AssistantTool> tools;
|
||||
|
||||
/// The ceiling on the answer's tokens, the instance's own ceiling at
|
||||
/// most.
|
||||
int maxOutputTokens;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantQuestion]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantQuestion copyWith({
|
||||
String? assistant,
|
||||
String? system,
|
||||
List<_irryv85c.AssistantMessage>? messages,
|
||||
List<_ienotap4.AssistantTool>? tools,
|
||||
int? maxOutputTokens,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantQuestion',
|
||||
'assistant': assistant,
|
||||
'system': system,
|
||||
'messages': messages.toJson(valueToJson: (v) => v.toJson()),
|
||||
'tools': tools.toJson(valueToJson: (v) => v.toJson()),
|
||||
'maxOutputTokens': maxOutputTokens,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantQuestion',
|
||||
'assistant': assistant,
|
||||
'system': system,
|
||||
'messages': messages.toJson(valueToJson: (v) => v.toJsonForProtocol()),
|
||||
'tools': tools.toJson(valueToJson: (v) => v.toJsonForProtocol()),
|
||||
'maxOutputTokens': maxOutputTokens,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _AssistantQuestionImpl extends AssistantQuestion {
|
||||
_AssistantQuestionImpl({
|
||||
required String assistant,
|
||||
required String system,
|
||||
required List<_irryv85c.AssistantMessage> messages,
|
||||
required List<_ienotap4.AssistantTool> tools,
|
||||
required int maxOutputTokens,
|
||||
}) : super._(
|
||||
assistant: assistant,
|
||||
system: system,
|
||||
messages: messages,
|
||||
tools: tools,
|
||||
maxOutputTokens: maxOutputTokens,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantQuestion]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantQuestion copyWith({
|
||||
String? assistant,
|
||||
String? system,
|
||||
List<_irryv85c.AssistantMessage>? messages,
|
||||
List<_ienotap4.AssistantTool>? tools,
|
||||
int? maxOutputTokens,
|
||||
}) {
|
||||
return AssistantQuestion(
|
||||
assistant: assistant ?? this.assistant,
|
||||
system: system ?? this.system,
|
||||
messages: messages ?? this.messages.map((e0) => e0.copyWith()).toList(),
|
||||
tools: tools ?? this.tools.map((e0) => e0.copyWith()).toList(),
|
||||
maxOutputTokens: maxOutputTokens ?? this.maxOutputTokens,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// Why an assistant refused, or failed (Halkyon Learn's ADR 0021).
|
||||
enum AssistantRefusal implements _isc.SerializableModel {
|
||||
/// The person has no grant of it, or the instance doesn't set it (any
|
||||
/// more), or this service offers no assistant (D43).
|
||||
notGranted,
|
||||
|
||||
/// The person hasn't agreed to what goes where, or it moved to another
|
||||
/// provider since (D40).
|
||||
notAgreed,
|
||||
|
||||
/// A day's or a month's limit is reached;
|
||||
/// [AssistantRefusedException.resetsAt] says when it resets.
|
||||
limitReached,
|
||||
|
||||
/// The grant's limits count what the assistant counts no more, as its
|
||||
/// prices came or went: the operator sets them again.
|
||||
limitOutdated,
|
||||
|
||||
/// The question holds an image, and the assistant reads none.
|
||||
imagesNotRead,
|
||||
|
||||
/// The question can't be sent: a turn out of place, or a tool call's
|
||||
/// JSON unreadable.
|
||||
malformed,
|
||||
|
||||
/// The question is larger than the instance forwards: its text, or an
|
||||
/// image.
|
||||
tooLarge,
|
||||
|
||||
/// The person has as many questions on their way as they may at once.
|
||||
tooManyAtOnce,
|
||||
|
||||
/// The provider refuses the instance's key or its account.
|
||||
providerKey,
|
||||
|
||||
/// The provider is busy or overloaded for now;
|
||||
/// [AssistantRefusedException.retryAfterSeconds] may say for how long.
|
||||
providerBusy,
|
||||
|
||||
/// The provider refused the question: too long for the model, say.
|
||||
providerRefused,
|
||||
|
||||
/// The provider failed, couldn't be reached, or answered unreadably.
|
||||
providerFailed;
|
||||
|
||||
static AssistantRefusal fromJson(String name) {
|
||||
switch (name) {
|
||||
case 'notGranted':
|
||||
return AssistantRefusal.notGranted;
|
||||
case 'notAgreed':
|
||||
return AssistantRefusal.notAgreed;
|
||||
case 'limitReached':
|
||||
return AssistantRefusal.limitReached;
|
||||
case 'limitOutdated':
|
||||
return AssistantRefusal.limitOutdated;
|
||||
case 'imagesNotRead':
|
||||
return AssistantRefusal.imagesNotRead;
|
||||
case 'malformed':
|
||||
return AssistantRefusal.malformed;
|
||||
case 'tooLarge':
|
||||
return AssistantRefusal.tooLarge;
|
||||
case 'tooManyAtOnce':
|
||||
return AssistantRefusal.tooManyAtOnce;
|
||||
case 'providerKey':
|
||||
return AssistantRefusal.providerKey;
|
||||
case 'providerBusy':
|
||||
return AssistantRefusal.providerBusy;
|
||||
case 'providerRefused':
|
||||
return AssistantRefusal.providerRefused;
|
||||
case 'providerFailed':
|
||||
return AssistantRefusal.providerFailed;
|
||||
default:
|
||||
throw ArgumentError(
|
||||
'Value "$name" cannot be converted to "AssistantRefusal"',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson() => name;
|
||||
|
||||
@override
|
||||
String toString() => name;
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import '../assistant/assistant_refusal.dart' as _ilkzkcy6;
|
||||
|
||||
/// An assistant refused a question, or failed on it.
|
||||
abstract class AssistantRefusedException
|
||||
implements
|
||||
_isc.SerializableException,
|
||||
_isc.SerializableModel,
|
||||
_isc.ProtocolSerialization {
|
||||
AssistantRefusedException._({
|
||||
required this.refusal,
|
||||
this.resetsAt,
|
||||
this.retryAfterSeconds,
|
||||
});
|
||||
|
||||
factory AssistantRefusedException({
|
||||
required _ilkzkcy6.AssistantRefusal refusal,
|
||||
DateTime? resetsAt,
|
||||
int? retryAfterSeconds,
|
||||
}) = _AssistantRefusedExceptionImpl;
|
||||
|
||||
factory AssistantRefusedException.fromJson(
|
||||
Map<String, dynamic> jsonSerialization,
|
||||
) {
|
||||
return AssistantRefusedException(
|
||||
refusal: _ilkzkcy6.AssistantRefusal.fromJson(
|
||||
(jsonSerialization['refusal'] as String),
|
||||
),
|
||||
resetsAt: jsonSerialization['resetsAt'] == null
|
||||
? null
|
||||
: _isc.DateTimeJsonExtension.fromJson(jsonSerialization['resetsAt']),
|
||||
retryAfterSeconds: jsonSerialization['retryAfterSeconds'] as int?,
|
||||
);
|
||||
}
|
||||
|
||||
/// Why.
|
||||
_ilkzkcy6.AssistantRefusal refusal;
|
||||
|
||||
/// When the limit reached resets (UTC midnight, or the first of next
|
||||
/// month); only for [AssistantRefusal.limitReached].
|
||||
DateTime? resetsAt;
|
||||
|
||||
/// How long the provider asks to wait, in seconds, where it says.
|
||||
int? retryAfterSeconds;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantRefusedException]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantRefusedException copyWith({
|
||||
_ilkzkcy6.AssistantRefusal? refusal,
|
||||
DateTime? resetsAt,
|
||||
int? retryAfterSeconds,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantRefusedException',
|
||||
'refusal': refusal.toJson(),
|
||||
if (resetsAt != null) 'resetsAt': resetsAt?.toJson(),
|
||||
if (retryAfterSeconds != null) 'retryAfterSeconds': retryAfterSeconds,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantRefusedException',
|
||||
'refusal': refusal.toJson(),
|
||||
if (resetsAt != null) 'resetsAt': resetsAt?.toJson(),
|
||||
if (retryAfterSeconds != null) 'retryAfterSeconds': retryAfterSeconds,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AssistantRefusedException(refusal: $refusal, resetsAt: $resetsAt, retryAfterSeconds: $retryAfterSeconds)';
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _AssistantRefusedExceptionImpl extends AssistantRefusedException {
|
||||
_AssistantRefusedExceptionImpl({
|
||||
required _ilkzkcy6.AssistantRefusal refusal,
|
||||
DateTime? resetsAt,
|
||||
int? retryAfterSeconds,
|
||||
}) : super._(
|
||||
refusal: refusal,
|
||||
resetsAt: resetsAt,
|
||||
retryAfterSeconds: retryAfterSeconds,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantRefusedException]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantRefusedException copyWith({
|
||||
_ilkzkcy6.AssistantRefusal? refusal,
|
||||
Object? resetsAt = _Undefined,
|
||||
Object? retryAfterSeconds = _Undefined,
|
||||
}) {
|
||||
return AssistantRefusedException(
|
||||
refusal: refusal ?? this.refusal,
|
||||
resetsAt: resetsAt is DateTime? ? resetsAt : this.resetsAt,
|
||||
retryAfterSeconds: retryAfterSeconds is int?
|
||||
? retryAfterSeconds
|
||||
: this.retryAfterSeconds,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// Who said a turn of a conversation with an assistant.
|
||||
enum AssistantRole implements _isc.SerializableModel {
|
||||
/// The person, with the tools' results their app adds.
|
||||
user,
|
||||
|
||||
/// The model.
|
||||
assistant;
|
||||
|
||||
static AssistantRole fromJson(String name) {
|
||||
switch (name) {
|
||||
case 'user':
|
||||
return AssistantRole.user;
|
||||
case 'assistant':
|
||||
return AssistantRole.assistant;
|
||||
default:
|
||||
throw ArgumentError(
|
||||
'Value "$name" cannot be converted to "AssistantRole"',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson() => name;
|
||||
|
||||
@override
|
||||
String toString() => name;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// Why the model stopped.
|
||||
enum AssistantStop implements _isc.SerializableModel {
|
||||
/// It finished its answer.
|
||||
end,
|
||||
|
||||
/// It reached the ceiling on tokens, or the model's context.
|
||||
maxTokens,
|
||||
|
||||
/// It calls tools, whose results the app sends in the next question.
|
||||
toolCalls,
|
||||
|
||||
/// It declined, or the provider's filter stopped it.
|
||||
refused,
|
||||
|
||||
/// Something else.
|
||||
other;
|
||||
|
||||
static AssistantStop fromJson(String name) {
|
||||
switch (name) {
|
||||
case 'end':
|
||||
return AssistantStop.end;
|
||||
case 'maxTokens':
|
||||
return AssistantStop.maxTokens;
|
||||
case 'toolCalls':
|
||||
return AssistantStop.toolCalls;
|
||||
case 'refused':
|
||||
return AssistantStop.refused;
|
||||
case 'other':
|
||||
return AssistantStop.other;
|
||||
default:
|
||||
throw ArgumentError(
|
||||
'Value "$name" cannot be converted to "AssistantStop"',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson() => name;
|
||||
|
||||
@override
|
||||
String toString() => name;
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// A tool the model may call, which the app runs (Halkyon Learn's ADR
|
||||
/// 0021, point 7).
|
||||
abstract class AssistantTool
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantTool._({
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.inputSchema,
|
||||
});
|
||||
|
||||
factory AssistantTool({
|
||||
required String name,
|
||||
required String description,
|
||||
required String inputSchema,
|
||||
}) = _AssistantToolImpl;
|
||||
|
||||
factory AssistantTool.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return AssistantTool(
|
||||
name: jsonSerialization['name'] as String,
|
||||
description: jsonSerialization['description'] as String,
|
||||
inputSchema: jsonSerialization['inputSchema'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
/// Its name.
|
||||
String name;
|
||||
|
||||
/// What it does, for the model.
|
||||
String description;
|
||||
|
||||
/// Its input, as a JSON Schema of an object, as JSON.
|
||||
String inputSchema;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantTool]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantTool copyWith({
|
||||
String? name,
|
||||
String? description,
|
||||
String? inputSchema,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantTool',
|
||||
'name': name,
|
||||
'description': description,
|
||||
'inputSchema': inputSchema,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantTool',
|
||||
'name': name,
|
||||
'description': description,
|
||||
'inputSchema': inputSchema,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _AssistantToolImpl extends AssistantTool {
|
||||
_AssistantToolImpl({
|
||||
required String name,
|
||||
required String description,
|
||||
required String inputSchema,
|
||||
}) : super._(
|
||||
name: name,
|
||||
description: description,
|
||||
inputSchema: inputSchema,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantTool]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantTool copyWith({
|
||||
String? name,
|
||||
String? description,
|
||||
String? inputSchema,
|
||||
}) {
|
||||
return AssistantTool(
|
||||
name: name ?? this.name,
|
||||
description: description ?? this.description,
|
||||
inputSchema: inputSchema ?? this.inputSchema,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:halkyon_base_client/src/protocol/protocol.dart' as _iwgbpyo5;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import '../assistant/assistant_offer.dart' as _ify4died;
|
||||
|
||||
/// What an instance offers the person who asks, of assistants (Halkyon
|
||||
/// Learn's ADR 0021): those granted to them, and whether they may add their
|
||||
/// own keys.
|
||||
abstract class AssistantsOffered
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantsOffered._({
|
||||
required this.assistants,
|
||||
required this.ownKeys,
|
||||
required this.currency,
|
||||
});
|
||||
|
||||
factory AssistantsOffered({
|
||||
required List<_ify4died.AssistantOffer> assistants,
|
||||
required bool ownKeys,
|
||||
required String currency,
|
||||
}) = _AssistantsOfferedImpl;
|
||||
|
||||
factory AssistantsOffered.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return AssistantsOffered(
|
||||
assistants: _iwgbpyo5.Protocol()
|
||||
.deserialize<List<_ify4died.AssistantOffer>>(
|
||||
jsonSerialization['assistants'],
|
||||
),
|
||||
ownKeys: _isc.BoolJsonExtension.fromJson(jsonSerialization['ownKeys']),
|
||||
currency: jsonSerialization['currency'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
/// The assistants granted to them that are set, in the operator's order.
|
||||
List<_ify4died.AssistantOffer> assistants;
|
||||
|
||||
/// Whether they may add their own keys here (D5, D6).
|
||||
bool ownKeys;
|
||||
|
||||
/// The currency costs are in (ISO 4217).
|
||||
String currency;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantsOffered]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantsOffered copyWith({
|
||||
List<_ify4died.AssistantOffer>? assistants,
|
||||
bool? ownKeys,
|
||||
String? currency,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantsOffered',
|
||||
'assistants': assistants.toJson(valueToJson: (v) => v.toJson()),
|
||||
'ownKeys': ownKeys,
|
||||
'currency': currency,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantsOffered',
|
||||
'assistants': assistants.toJson(
|
||||
valueToJson: (v) => v.toJsonForProtocol(),
|
||||
),
|
||||
'ownKeys': ownKeys,
|
||||
'currency': currency,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _AssistantsOfferedImpl extends AssistantsOffered {
|
||||
_AssistantsOfferedImpl({
|
||||
required List<_ify4died.AssistantOffer> assistants,
|
||||
required bool ownKeys,
|
||||
required String currency,
|
||||
}) : super._(
|
||||
assistants: assistants,
|
||||
ownKeys: ownKeys,
|
||||
currency: currency,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantsOffered]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantsOffered copyWith({
|
||||
List<_ify4died.AssistantOffer>? assistants,
|
||||
bool? ownKeys,
|
||||
String? currency,
|
||||
}) {
|
||||
return AssistantsOffered(
|
||||
assistants:
|
||||
assistants ?? this.assistants.map((e0) => e0.copyWith()).toList(),
|
||||
ownKeys: ownKeys ?? this.ownKeys,
|
||||
currency: currency ?? this.currency,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:halkyon_base_client/src/protocol/protocol.dart' as _iwgbpyo5;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import '../assistant/assistant_info.dart' as _iuj14wfe;
|
||||
|
||||
/// The assistants an instance's operator set (Halkyon Learn's ADR 0021):
|
||||
/// what they grant from.
|
||||
abstract class AssistantsSetUp
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
AssistantsSetUp._({
|
||||
required this.assistants,
|
||||
required this.currency,
|
||||
required this.ownKeys,
|
||||
});
|
||||
|
||||
factory AssistantsSetUp({
|
||||
required List<_iuj14wfe.AssistantInfo> assistants,
|
||||
required String currency,
|
||||
required bool ownKeys,
|
||||
}) = _AssistantsSetUpImpl;
|
||||
|
||||
factory AssistantsSetUp.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return AssistantsSetUp(
|
||||
assistants: _iwgbpyo5.Protocol()
|
||||
.deserialize<List<_iuj14wfe.AssistantInfo>>(
|
||||
jsonSerialization['assistants'],
|
||||
),
|
||||
currency: jsonSerialization['currency'] as String,
|
||||
ownKeys: _isc.BoolJsonExtension.fromJson(jsonSerialization['ownKeys']),
|
||||
);
|
||||
}
|
||||
|
||||
/// Each assistant, in the order set.
|
||||
List<_iuj14wfe.AssistantInfo> assistants;
|
||||
|
||||
/// The currency of the prices and costs (ISO 4217).
|
||||
String currency;
|
||||
|
||||
/// Whether people may add their own keys.
|
||||
bool ownKeys;
|
||||
|
||||
/// Returns a shallow copy of this [AssistantsSetUp]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
AssistantsSetUp copyWith({
|
||||
List<_iuj14wfe.AssistantInfo>? assistants,
|
||||
String? currency,
|
||||
bool? ownKeys,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantsSetUp',
|
||||
'assistants': assistants.toJson(valueToJson: (v) => v.toJson()),
|
||||
'currency': currency,
|
||||
'ownKeys': ownKeys,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.AssistantsSetUp',
|
||||
'assistants': assistants.toJson(
|
||||
valueToJson: (v) => v.toJsonForProtocol(),
|
||||
),
|
||||
'currency': currency,
|
||||
'ownKeys': ownKeys,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _AssistantsSetUpImpl extends AssistantsSetUp {
|
||||
_AssistantsSetUpImpl({
|
||||
required List<_iuj14wfe.AssistantInfo> assistants,
|
||||
required String currency,
|
||||
required bool ownKeys,
|
||||
}) : super._(
|
||||
assistants: assistants,
|
||||
currency: currency,
|
||||
ownKeys: ownKeys,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [AssistantsSetUp]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
AssistantsSetUp copyWith({
|
||||
List<_iuj14wfe.AssistantInfo>? assistants,
|
||||
String? currency,
|
||||
bool? ownKeys,
|
||||
}) {
|
||||
return AssistantsSetUp(
|
||||
assistants:
|
||||
assistants ?? this.assistants.map((e0) => e0.copyWith()).toList(),
|
||||
currency: currency ?? this.currency,
|
||||
ownKeys: ownKeys ?? this.ownKeys,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,18 @@ import 'dart:async' as _ida;
|
|||
import 'dart:typed_data' as _idt;
|
||||
import 'package:halkyon_base_client/src/protocol/admission/waiting_state.dart'
|
||||
as _i1sx1z35;
|
||||
import 'package:halkyon_base_client/src/protocol/assistant/assistant_answer.dart'
|
||||
as _il9lgl6t;
|
||||
import 'package:halkyon_base_client/src/protocol/assistant/assistant_grant_overview.dart'
|
||||
as _iddnouvb;
|
||||
import 'package:halkyon_base_client/src/protocol/assistant/assistant_month_figures.dart'
|
||||
as _igllc81w;
|
||||
import 'package:halkyon_base_client/src/protocol/assistant/assistant_question.dart'
|
||||
as _imspm6kl;
|
||||
import 'package:halkyon_base_client/src/protocol/assistant/assistants_offered.dart'
|
||||
as _ig7pm61n;
|
||||
import 'package:halkyon_base_client/src/protocol/assistant/assistants_set_up.dart'
|
||||
as _ie204iej;
|
||||
import 'package:halkyon_base_client/src/protocol/auth/email_code_purpose.dart'
|
||||
as _i6rtanuw;
|
||||
import 'package:halkyon_base_client/src/protocol/auth/sign_in_ways.dart'
|
||||
|
|
@ -109,6 +121,140 @@ class EndpointWaiting extends _isc.EndpointRef {
|
|||
);
|
||||
}
|
||||
|
||||
/// The operator's assistants as a person uses them (Halkyon Learn's ADR
|
||||
/// 0021, points 6 to 9): those granted to them, their agreement, their
|
||||
/// questions with the answers streamed (D35), and their own figures.
|
||||
/// Refusals are `AssistantRefusedException`s.
|
||||
/// {@category Endpoint}
|
||||
class EndpointAssistant extends _isc.EndpointRef {
|
||||
EndpointAssistant(_isc.EndpointCaller caller) : super(caller);
|
||||
|
||||
@override
|
||||
String get name => 'halkyon_base.assistant';
|
||||
|
||||
/// The assistants granted to the caller that are set, with what goes
|
||||
/// where and what is left of their limits, and whether they may add their
|
||||
/// own keys; none on a member (D43).
|
||||
_ida.Future<_ig7pm61n.AssistantsOffered> offered() =>
|
||||
caller.callServerEndpoint<_ig7pm61n.AssistantsOffered>(
|
||||
'halkyon_base.assistant',
|
||||
'offered',
|
||||
{},
|
||||
);
|
||||
|
||||
/// The caller agrees to what goes where with [assistant], its provider as
|
||||
/// it is now (D40); refused without a grant of it
|
||||
/// (`AssistantRefusal.notGranted`).
|
||||
_ida.Future<void> agree({required String assistant}) =>
|
||||
caller.callServerEndpoint<void>(
|
||||
'halkyon_base.assistant',
|
||||
'agree',
|
||||
{'assistant': assistant},
|
||||
);
|
||||
|
||||
/// Forwards [question] to its assistant and streams the answer: the text
|
||||
/// as the model writes it, then the whole turn with what was counted.
|
||||
/// Refused before anything goes without a grant, an agreement or room
|
||||
/// within the limits, for a question that can't be sent, and with more
|
||||
/// than `maxQuestionsAtOnce` on their way; then for the provider's
|
||||
/// failure. Cancelled, the answer is still read to its end and counted.
|
||||
_ida.Stream<_il9lgl6t.AssistantAnswer> ask({
|
||||
required _imspm6kl.AssistantQuestion question,
|
||||
}) =>
|
||||
caller.callStreamingServerEndpoint<
|
||||
_ida.Stream<_il9lgl6t.AssistantAnswer>,
|
||||
_il9lgl6t.AssistantAnswer
|
||||
>(
|
||||
'halkyon_base.assistant',
|
||||
'ask',
|
||||
{'question': question},
|
||||
{},
|
||||
);
|
||||
|
||||
/// The caller's own figures, month by month, the latest first.
|
||||
_ida.Future<List<_igllc81w.AssistantMonthFigures>> figures() =>
|
||||
caller.callServerEndpoint<List<_igllc81w.AssistantMonthFigures>>(
|
||||
'halkyon_base.assistant',
|
||||
'figures',
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
/// The operator's assistants as the operator grants them (Halkyon Learn's
|
||||
/// ADR 0021, points 6 and 8): the assistants set, the grants with their
|
||||
/// limits, and everyone's figures, never what was asked. The operator's
|
||||
/// scope only the register's sessions carry. Refusals are
|
||||
/// `OperatorRefusedException`s.
|
||||
/// {@category Endpoint}
|
||||
class EndpointAssistantOperator extends _isc.EndpointRef {
|
||||
EndpointAssistantOperator(_isc.EndpointCaller caller) : super(caller);
|
||||
|
||||
@override
|
||||
String get name => 'halkyon_base.assistantOperator';
|
||||
|
||||
/// The assistants set in `deploy/assistants.env`, without their keys.
|
||||
_ida.Future<_ie204iej.AssistantsSetUp> setUp() =>
|
||||
caller.callServerEndpoint<_ie204iej.AssistantsSetUp>(
|
||||
'halkyon_base.assistantOperator',
|
||||
'setUp',
|
||||
{},
|
||||
);
|
||||
|
||||
/// Every grant, by handle.
|
||||
_ida.Future<List<_iddnouvb.AssistantGrantOverview>> grants() =>
|
||||
caller.callServerEndpoint<List<_iddnouvb.AssistantGrantOverview>>(
|
||||
'halkyon_base.assistantOperator',
|
||||
'grants',
|
||||
{},
|
||||
);
|
||||
|
||||
/// Grants [account] [assistant] with [dailyLimit] and [monthlyLimit] (null:
|
||||
/// none), in the unit of its pricing; granted already, the limits change
|
||||
/// and the agreement stays. Refused for an assistant not set
|
||||
/// (`OperatorRefusal.assistantNotSet`), a limit below 0
|
||||
/// (`OperatorRefusal.invalidLimit`) and an account unknown
|
||||
/// (`OperatorRefusal.notFound`).
|
||||
_ida.Future<void> grant({
|
||||
required _isc.UuidValue account,
|
||||
required String assistant,
|
||||
required int? dailyLimit,
|
||||
required int? monthlyLimit,
|
||||
}) => caller.callServerEndpoint<void>(
|
||||
'halkyon_base.assistantOperator',
|
||||
'grant',
|
||||
{
|
||||
'account': account,
|
||||
'assistant': assistant,
|
||||
'dailyLimit': dailyLimit,
|
||||
'monthlyLimit': monthlyLimit,
|
||||
},
|
||||
);
|
||||
|
||||
/// Takes [assistant] back from [account]; refused where it isn't granted
|
||||
/// (`OperatorRefusal.notFound`).
|
||||
_ida.Future<void> revoke({
|
||||
required _isc.UuidValue account,
|
||||
required String assistant,
|
||||
}) => caller.callServerEndpoint<void>(
|
||||
'halkyon_base.assistantOperator',
|
||||
'revoke',
|
||||
{
|
||||
'account': account,
|
||||
'assistant': assistant,
|
||||
},
|
||||
);
|
||||
|
||||
/// Everyone's figures of the UTC month [month] is in, per person and
|
||||
/// assistant.
|
||||
_ida.Future<List<_igllc81w.AssistantMonthFigures>> figures({
|
||||
required DateTime month,
|
||||
}) => caller.callServerEndpoint<List<_igllc81w.AssistantMonthFigures>>(
|
||||
'halkyon_base.assistantOperator',
|
||||
'figures',
|
||||
{'month': month},
|
||||
);
|
||||
}
|
||||
|
||||
/// The signed-in person's account.
|
||||
/// {@category Endpoint}
|
||||
class EndpointAccount extends _isc.EndpointRef {
|
||||
|
|
@ -207,8 +353,9 @@ class EndpointInstance extends _isc.EndpointRef {
|
|||
/// ADR 0016), password sign-in where the register holds its keys,
|
||||
/// SimpleLogin where the register has the instance's SimpleLogin app
|
||||
/// (ADR 0020), each as its operator offers it, who may make an account
|
||||
/// (Halkyon Learn's ADR 0021, the register's operator's word), where its
|
||||
/// source is, the oldest app build it works with, and where it keeps
|
||||
/// (Halkyon Learn's ADR 0021, the register's operator's word), whether
|
||||
/// people may add assistants of their own keys (none on a member, D43),
|
||||
/// where its source is, the oldest app build it works with, and where it keeps
|
||||
/// people's data and its backups.
|
||||
_ida.Future<_isnyur2i.InstanceBasics> basics() =>
|
||||
caller.callServerEndpoint<_isnyur2i.InstanceBasics>(
|
||||
|
|
@ -1195,6 +1342,8 @@ class EndpointSimpleLogin extends _isc.EndpointRef {
|
|||
class Caller extends _isc.ModuleEndpointCaller {
|
||||
Caller(_isc.ServerpodClientShared client) : super(client) {
|
||||
waiting = EndpointWaiting(this);
|
||||
assistant = EndpointAssistant(this);
|
||||
assistantOperator = EndpointAssistantOperator(this);
|
||||
account = EndpointAccount(this);
|
||||
emailCode = EndpointEmailCode(this);
|
||||
instance = EndpointInstance(this);
|
||||
|
|
@ -1211,6 +1360,10 @@ class Caller extends _isc.ModuleEndpointCaller {
|
|||
|
||||
late final EndpointWaiting waiting;
|
||||
|
||||
late final EndpointAssistant assistant;
|
||||
|
||||
late final EndpointAssistantOperator assistantOperator;
|
||||
|
||||
late final EndpointAccount account;
|
||||
|
||||
late final EndpointEmailCode emailCode;
|
||||
|
|
@ -1238,6 +1391,8 @@ class Caller extends _isc.ModuleEndpointCaller {
|
|||
@override
|
||||
Map<String, _isc.EndpointRef> get endpointRefLookup => {
|
||||
'halkyon_base.waiting': waiting,
|
||||
'halkyon_base.assistant': assistant,
|
||||
'halkyon_base.assistantOperator': assistantOperator,
|
||||
'halkyon_base.account': account,
|
||||
'halkyon_base.emailCode': emailCode,
|
||||
'halkyon_base.instance': instance,
|
||||
|
|
|
|||
|
|
@ -29,9 +29,11 @@ abstract class InstanceBasics
|
|||
bool? passwordSignIn,
|
||||
bool? simpleLogin,
|
||||
_iypagcol.SignUpMode? signUp,
|
||||
bool? assistantOwnKeys,
|
||||
}) : passwordSignIn = passwordSignIn ?? false,
|
||||
simpleLogin = simpleLogin ?? false,
|
||||
signUp = signUp ?? _iypagcol.SignUpMode.open;
|
||||
signUp = signUp ?? _iypagcol.SignUpMode.open,
|
||||
assistantOwnKeys = assistantOwnKeys ?? false;
|
||||
|
||||
factory InstanceBasics({
|
||||
required String app,
|
||||
|
|
@ -43,6 +45,7 @@ abstract class InstanceBasics
|
|||
bool? passwordSignIn,
|
||||
bool? simpleLogin,
|
||||
_iypagcol.SignUpMode? signUp,
|
||||
bool? assistantOwnKeys,
|
||||
}) = _InstanceBasicsImpl;
|
||||
|
||||
factory InstanceBasics.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
|
|
@ -68,6 +71,11 @@ abstract class InstanceBasics
|
|||
: _iypagcol.SignUpMode.fromJson(
|
||||
(jsonSerialization['signUp'] as String),
|
||||
),
|
||||
assistantOwnKeys: jsonSerialization['assistantOwnKeys'] == null
|
||||
? null
|
||||
: _isc.BoolJsonExtension.fromJson(
|
||||
jsonSerialization['assistantOwnKeys'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -110,6 +118,12 @@ abstract class InstanceBasics
|
|||
/// nothing.
|
||||
_iypagcol.SignUpMode signUp;
|
||||
|
||||
/// Whether people may add assistants of their own, with their own keys,
|
||||
/// which the app then calls directly (Halkyon Learn's ADR 0021, D5 and
|
||||
/// D6): the operator's word (ASSISTANT_OWN_KEYS); false on a member
|
||||
/// service, which offers no assistant yet (D43).
|
||||
bool assistantOwnKeys;
|
||||
|
||||
/// Returns a shallow copy of this [InstanceBasics]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
|
|
@ -123,6 +137,7 @@ abstract class InstanceBasics
|
|||
bool? passwordSignIn,
|
||||
bool? simpleLogin,
|
||||
_iypagcol.SignUpMode? signUp,
|
||||
bool? assistantOwnKeys,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
|
|
@ -137,6 +152,7 @@ abstract class InstanceBasics
|
|||
'passwordSignIn': passwordSignIn,
|
||||
'simpleLogin': simpleLogin,
|
||||
'signUp': signUp.toJson(),
|
||||
'assistantOwnKeys': assistantOwnKeys,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -153,6 +169,7 @@ abstract class InstanceBasics
|
|||
'passwordSignIn': passwordSignIn,
|
||||
'simpleLogin': simpleLogin,
|
||||
'signUp': signUp.toJson(),
|
||||
'assistantOwnKeys': assistantOwnKeys,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -175,6 +192,7 @@ class _InstanceBasicsImpl extends InstanceBasics {
|
|||
bool? passwordSignIn,
|
||||
bool? simpleLogin,
|
||||
_iypagcol.SignUpMode? signUp,
|
||||
bool? assistantOwnKeys,
|
||||
}) : super._(
|
||||
app: app,
|
||||
emailSignIn: emailSignIn,
|
||||
|
|
@ -185,6 +203,7 @@ class _InstanceBasicsImpl extends InstanceBasics {
|
|||
passwordSignIn: passwordSignIn,
|
||||
simpleLogin: simpleLogin,
|
||||
signUp: signUp,
|
||||
assistantOwnKeys: assistantOwnKeys,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [InstanceBasics]
|
||||
|
|
@ -201,6 +220,7 @@ class _InstanceBasicsImpl extends InstanceBasics {
|
|||
bool? passwordSignIn,
|
||||
bool? simpleLogin,
|
||||
_iypagcol.SignUpMode? signUp,
|
||||
bool? assistantOwnKeys,
|
||||
}) {
|
||||
return InstanceBasics(
|
||||
app: app ?? this.app,
|
||||
|
|
@ -214,6 +234,7 @@ class _InstanceBasicsImpl extends InstanceBasics {
|
|||
passwordSignIn: passwordSignIn ?? this.passwordSignIn,
|
||||
simpleLogin: simpleLogin ?? this.simpleLogin,
|
||||
signUp: signUp ?? this.signUp,
|
||||
assistantOwnKeys: assistantOwnKeys ?? this.assistantOwnKeys,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,14 @@ enum OperatorRefusal implements _isc.SerializableModel {
|
|||
isOperator,
|
||||
|
||||
/// The last operator keeps the role.
|
||||
lastOperator;
|
||||
lastOperator,
|
||||
|
||||
/// No assistant of that ID is set (`deploy/assistants.env`), so none is
|
||||
/// granted (Halkyon Learn's ADR 0021, D44).
|
||||
assistantNotSet,
|
||||
|
||||
/// A limit below 0.
|
||||
invalidLimit;
|
||||
|
||||
static OperatorRefusal fromJson(String name) {
|
||||
switch (name) {
|
||||
|
|
@ -33,6 +40,10 @@ enum OperatorRefusal implements _isc.SerializableModel {
|
|||
return OperatorRefusal.isOperator;
|
||||
case 'lastOperator':
|
||||
return OperatorRefusal.lastOperator;
|
||||
case 'assistantNotSet':
|
||||
return OperatorRefusal.assistantNotSet;
|
||||
case 'invalidLimit':
|
||||
return OperatorRefusal.invalidLimit;
|
||||
default:
|
||||
throw ArgumentError(
|
||||
'Value "$name" cannot be converted to "OperatorRefusal"',
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue